再挑戦
先日のスクリプトを C でリライトしてみた。
いやはや C なんて何年振りだろう。
#include <stdio.h> #include <string.h> #include <time.h> #include <math.h> #define MAX_LENGTH 9 #define MIN_LENGTH 7 #define NO_MORE_REPEAT 2 void generate(char[]); int is_over_repeated(char[], int); void print_buff(char[]); void print_time(time_t); int count = 0; int logs = 0; FILE *fp; clock_t all_start_time; clock_t sub_start_time; int main(int argc, char *argv[]) { char buff[MAX_LENGTH + 1] = { '\0' }; all_start_time = clock(); sub_start_time = all_start_time; generate(buff); print_time(all_start_time); fclose(fp); return 0; } void generate(char buff[]) { int length = strlen(buff); int new_length = length + 1; char new_buff[MAX_LENGTH + 1] = { '\0' }; char c; if (length >= MAX_LENGTH) return; for (c = 'a'; c <= 'z'; c++) { strcpy(new_buff, buff); new_buff[length] = c; if (is_over_repeated(new_buff, length)) continue; if (new_length >= MIN_LENGTH) { print_buff(new_buff); } generate(new_buff); } } int is_over_repeated(char buff[], int length) { if (length < NO_MORE_REPEAT) return 0; if (buff[length] != buff[length - 1]) return 0; if (buff[length] != buff[length - 2]) return 0; return 1; } void print_buff(char buff[]) { char filename[16]; if (count % 100000000 == 0) { if (fp) { print_time(sub_start_time); fclose(fp); } sub_start_time = clock(); sprintf(filename, "result%03d.log", ++logs); fp = fopen(filename, "w"); } fprintf(fp, "%10d: %s\n", ++count, buff); } void print_time(time_t start_time) { double sec = (double)(clock() - start_time) / CLOCKS_PER_SEC; int hour = (int)sec / (60 * 60); int min = ((int)sec % (60 * 60)) / 60; double msec; sec = fmod(sec, 60.0); msec = fmod(sec, 1.0) * 100; fprintf(fp, "\n所要時間:"); if (hour > 0) fprintf(fp, " %d 時間", hour); if (min > 0) fprintf(fp, " %02d 分", min); fprintf(fp, " %02d 秒 %02d\n", (int)sec, (int)msec); }
$ gcc lama.c -o lama -D_FILE_OFFSET_BITS=64 -lm ↵ ./lama ↵
我が家の環境だと「-D_FILE_OFFSET_BITS=64」をつけないと「file size limit exceeded」で落ちる。
それにしても。当たり前の話だが C は Ruby よりも段違いに速い。Ruby が一千万件出力するのに 6 分半かかるのに対して、C は高々 1 分 20 秒程度で一億件出力である。
書きやすさで言えばもちろん Ruby に軍配があがるのだが、久々に C の威力を実感した思いだ。