Last active
January 6, 2016 04:47
-
-
Save MaxMatti/8fcdb42709320adfb782 to your computer and use it in GitHub Desktop.
Uses multithreading to guess a "self-describing-number" (which is 6210001000). To build use "g++ -O3 -march=native -std=c++11 -l stdc++ -pthread findSelfDescribingNumber.cpp"
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
#include <stdio.h> | |
#include <thread> | |
#include <time.h> | |
void checkNumbers(int offset, int threadCount); | |
bool checkNumber(const int numbers[10]); | |
bool checkDigit(const int digit, const int numbers[10]); | |
int main(int argc, char** argv) { | |
int threadCount; | |
if (argc > 1) { | |
threadCount = std::stoi(argv[1]); | |
} else { | |
threadCount = 1; | |
} | |
timespec beginTime, endTime; | |
clock_t beginCPUTime, endCPUTime; | |
clock_gettime(CLOCK_MONOTONIC, &beginTime); | |
beginCPUTime = clock(); | |
std::thread threads[threadCount]; | |
for (int i = 0; i < threadCount; i++) { | |
threads[i] = std::thread(checkNumbers, i, threadCount); | |
} | |
for (int i = 0; i < threadCount; i++) { | |
threads[i].join(); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &endTime); | |
endCPUTime = clock(); | |
printf("Real time: %f seconds, ", (double) (endTime.tv_sec - beginTime.tv_sec) + (endTime.tv_nsec - beginTime.tv_nsec) / 1e9); | |
printf("this equals %f tries per second.\n", ((double) 1e19) / ((endTime.tv_nsec - beginTime.tv_nsec) + 1e9 * (endTime.tv_sec - beginTime.tv_sec))); | |
printf("CPU time: %f seconds, ", (double) (endCPUTime - beginCPUTime) / CLOCKS_PER_SEC); | |
printf("this equals %f tries per second per CPU.\n", (double) CLOCKS_PER_SEC / (endCPUTime - beginCPUTime) * 1e10); | |
return 0; | |
} | |
void checkNumbers(int offset, int threadCount) { | |
int numbers[10] = {0}; | |
for (numbers[0] = offset; numbers[0] < 10; numbers[0] += threadCount) { | |
for (numbers[1] = 0; numbers[1] < 10; numbers[1]++) { | |
for (numbers[2] = 0; numbers[2] < 10; numbers[2]++) { | |
for (numbers[3] = 0; numbers[3] < 10; numbers[3]++) { | |
for (numbers[4] = 0; numbers[4] < 10; numbers[4]++) { | |
for (numbers[5] = 0; numbers[5] < 10; numbers[5]++) { | |
for (numbers[6] = 0; numbers[6] < 10; numbers[6]++) { | |
for (numbers[7] = 0; numbers[7] < 10; numbers[7]++) { | |
for (numbers[8] = 0; numbers[8] < 10; numbers[8]++) { | |
for (numbers[9] = 0; numbers[9] < 10; numbers[9]++) { | |
if (numbers[0] + numbers[1] + numbers[2] + numbers[3] + numbers[4] + numbers[5] + numbers[6] + numbers[7] + numbers[8] + numbers[9] == 10) { | |
if (checkNumber(numbers)) { | |
printf("Found one: %d%d%d%d%d%d%d%d%d%d\n", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4], numbers[5], numbers[6], numbers[7], numbers[8], numbers[9]); | |
} else if (numbers[0] == 6 && numbers[1] == 2 && numbers[2] == 1 && numbers[3] == 0 && numbers[4] == 0 && numbers[5] == 0 && numbers[6] == 1 && numbers[7] == 0 && numbers[8] == 0 && numbers[9] == 0) { | |
printf("He doesn't like me!\n"); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
bool checkNumber(const int numbers[10]) { | |
for (int i = 0; i < 10; i++) { | |
if (checkDigit(i, numbers)) { | |
if (numbers[0] == 6 && numbers[1] == 2 && numbers[2] == 1 && numbers[3] == 0 && numbers[4] == 0 && numbers[5] == 0 && numbers[6] == 1 && numbers[7] == 0 && numbers[8] == 0 && numbers[9] == 0) { | |
printf("He doesn't like me at %d!\n", i); | |
} | |
return false; | |
} | |
} | |
return true; | |
} | |
bool checkDigit(const int digit, const int numbers[10]) { | |
int counter = 0; | |
for (int i = 0; i < 10; i++) { | |
if (numbers[i] == digit) { | |
counter++; | |
} | |
} | |
return counter != numbers[digit]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment