Skip to content

Instantly share code, notes, and snippets.

@MaxMatti
Last active January 6, 2016 04:47
Show Gist options
  • Save MaxMatti/8fcdb42709320adfb782 to your computer and use it in GitHub Desktop.
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"
#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