-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3a01caf
commit db41f27
Showing
9 changed files
with
184 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#pragma once | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#ifdef _WIN32 | ||
#include <direct.h> | ||
#include <windows.h> | ||
#define PATH_SEPARATOR "\\" | ||
#else | ||
#include <libgen.h> | ||
#include <unistd.h> | ||
#define PATH_SEPARATOR "/" | ||
#endif | ||
|
||
char* get_parent_directory(char* path, const unsigned int levels) { | ||
#ifdef _WIN32 | ||
static char drive[_MAX_DRIVE]; | ||
static char dir[_MAX_DIR]; | ||
_splitpath(path, drive, dir, NULL, NULL); | ||
for (unsigned int i = 0; i < levels; ++i) { | ||
size_t len = strlen(dir); | ||
if (len > 1 && (dir[len - 1] == '\\' || dir[len - 1] == '/')) { | ||
dir[len - 1] = '\0'; | ||
} | ||
char* last_slash = strrchr(dir, '\\'); | ||
if (!last_slash) last_slash = strrchr(dir, '/'); | ||
if (last_slash) *last_slash = '\0'; | ||
} | ||
static char parent_dir[_MAX_PATH]; | ||
snprintf(parent_dir, sizeof(parent_dir), "%s%s", drive, dir); | ||
return parent_dir; | ||
#else | ||
char* dir = dirname(path); | ||
for (unsigned int i = 0; i < levels; ++i) { | ||
dir = dirname(dir); | ||
if (strcmp(dir, "/") == 0 || strcmp(dir, ".") == 0) { | ||
break; | ||
} | ||
} | ||
return dir; | ||
#endif | ||
} | ||
|
||
std::string get_data_file(const char *name) { | ||
const char* start = __FILE__; | ||
#ifdef _WIN32 | ||
char absolute_path[MAX_PATH]; | ||
if (!_fullpath(absolute_path, start, MAX_PATH)) { | ||
perror("_fullpath"); | ||
return NULL; | ||
} | ||
#else | ||
char* absolute_path = realpath(start, NULL); | ||
if (!absolute_path) { | ||
perror("realpath"); | ||
return NULL; | ||
} | ||
#endif | ||
char* parents_dir = get_parent_directory(absolute_path, 3); | ||
const size_t p_len = strlen(parents_dir), | ||
name_len = strlen(name); | ||
char *file_path = (char *)malloc(p_len + name_len + 8); | ||
memcpy(file_path, parents_dir, p_len); | ||
memcpy(file_path + p_len, PATH_SEPARATOR "_data" PATH_SEPARATOR, 7); | ||
memcpy(file_path + p_len + 7, name, name_len); | ||
file_path[p_len + name_len + 7] = 0; | ||
FILE* file = fopen(file_path, "r"); | ||
#ifndef _WIN32 | ||
free(absolute_path); | ||
#endif | ||
// free(parents_dir); | ||
free(file_path); | ||
if (!file) { | ||
perror("fopen"); | ||
return NULL; | ||
} | ||
|
||
fseek(file, 0, SEEK_END); | ||
size_t length = ftell(file); | ||
fseek(file, 0, SEEK_SET); | ||
|
||
char* buffer = (char*)malloc(length + 1); | ||
if (!buffer) { | ||
perror("malloc"); | ||
fclose(file); | ||
return NULL; | ||
} | ||
|
||
const size_t ret_code = fread(buffer, 1, length, file); | ||
if (ret_code != length) { | ||
if (feof(file)) | ||
printf("Error reading %s: unexpected end of file, read %llu of %llu bytes expected\n", name, (unsigned long long)ret_code, (unsigned long long)length); | ||
else if (ferror(file)) | ||
perror("Error reading data file"); | ||
} | ||
|
||
buffer[length] = 0; | ||
fclose(file); | ||
|
||
std::string ret(buffer); | ||
free(buffer); | ||
return ret; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Project Euler Problem 22 | ||
* | ||
* I know that this could be done faster with a traditional for loop, but I wanted | ||
* to see if iterators were reasonably possible in C, since it makes the prime | ||
* number infrastructure a lot easier to set up. | ||
* | ||
* Problem: | ||
* | ||
* If we list all the natural numbers below 10 that are multiples of 3 or 5, we | ||
* get 3, 5, 6 and 9. The sum of these multiples is 23. | ||
* | ||
* Find the sum of all the multiples of 3 or 5 below 1000. | ||
*/ | ||
#ifndef EULER_P0022 | ||
#define EULER_P0022 | ||
#include <iostream> | ||
#include <vector> | ||
#include <algorithm> | ||
#include "include/utils.h" | ||
|
||
unsigned long long p0022() { | ||
unsigned long long answer = 0; | ||
std::string fstring = get_data_file("p0022_names.txt"); | ||
const unsigned int name_count = 5163; | ||
std::vector<std::string> names(5163, ""); | ||
size_t idx = 0, i = 0, pi = 0; | ||
do { | ||
while (fstring[i] && fstring[i] != ',') | ||
i++; | ||
const size_t len = i - pi - 2; | ||
names[idx] = fstring.substr(pi + 1, len); | ||
idx++; | ||
pi = ++i; | ||
} while (fstring[i]); | ||
std::sort(names.begin(), names.end()); | ||
for (idx = 0; idx < name_count; idx++) { | ||
unsigned long score = 0; | ||
for (i = 0; names[idx][i]; i++) { | ||
score += names[idx][i] & 0x3F; | ||
} | ||
answer += score * (idx + 1); | ||
} | ||
return answer; | ||
} | ||
|
||
#ifndef UNITY_END | ||
int main(int argc, char const *argv[]) { | ||
std::cout << p0022() << std::endl; | ||
return 0; | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,24 @@ | ||
C++ Implementation of Problem 15 | ||
C++ Implementation of Problem 22 | ||
================================ | ||
|
||
View source code :source:`cplusplus/src/p0015.cpp` | ||
View source code :source:`cplusplus/src/p0022.cpp` | ||
|
||
Includes | ||
-------- | ||
|
||
- `math.h <./math.html>`__ | ||
- `utils.h <./utils.html>`__ | ||
|
||
Solution | ||
-------- | ||
|
||
.. cpp:function:: unsigned long long p0015() | ||
.. cpp:function:: unsigned long long p0022() | ||
|
||
.. cpp:function:: int main(int argc, char const *argv[]) | ||
|
||
.. note:: | ||
|
||
This function is only present in the Python test runner, or when compiling as a standalone program. | ||
|
||
.. literalinclude:: ../../cplusplus/src/p0015.cpp | ||
.. literalinclude:: ../../cplusplus/src/p0022.cpp | ||
:language: C++ | ||
:linenos: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
utils.h | ||
======= | ||
|
||
View source code :source:`cplusplus/src/include/utils.h` | ||
|
||
.. cpp:namespace-push:: utils | ||
.. cpp:function:: std::string get_data_file(const char *name) | ||
|
||
Return a character array containing the whole contents of a file found in _data. | ||
|
||
.. cpp:function:: char *get_parent_directory(const char *name, const unsigned int levels) | ||
|
||
.. cpp:namespace-pop:: | ||
|
||
.. literalinclude:: ../../cplusplus/src/include/utils.h | ||
:language: C++ | ||
:linenos: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters