shiogi
http://homepage1.nifty.com/asagi/program/program01.html
なんか変にやる気がでたので書き直してみたら結果が違ってたヨ。
#!/usr/bin/ruby -Ku class Char attr_reader(:char_j) attr_reader(:char_e) attr_reader(:vowel) attr_reader(:consonant) def initialize(char_j, char_e, vowel, consonant) @char_j = char_j @char_e = char_e @vowel = vowel @consonant = consonant end end class CharTable TABLE = [nil] [ ['あ', 'a', 1, 0], ['い', 'i', 1, 0], ['う', 'u', 1, 0], ['え', 'e', 1, 0], ['お', 'o', 1, 0], ['か', 'ka', 1, 1], ['き', 'ki', 1, 1], ['く', 'ku', 1, 1], ['け', 'ke', 1, 1], ['こ', 'ko', 1, 1], ['さ', 'sa', 1, 1], ['し', 'shi', 1, 2], ['す', 'su', 1, 1], ['せ', 'se', 1, 1], ['そ', 'so', 1, 1], ['た', 'ta', 1, 1], ['ち', 'chi', 1, 2], ['つ', 'tsu', 1, 2], ['て', 'te', 1, 1], ['と', 'to', 1, 1], ['な', 'na', 1, 1], ['に', 'ni', 1, 1], ['ぬ', 'nu', 1, 1], ['ね', 'ne', 1, 1], ['の', 'no', 1, 1], ['は', 'ha', 1, 1], ['ひ', 'hi', 1, 1], ['ふ', 'fu', 1, 1], ['へ', 'he', 1, 1], ['ほ', 'ho', 1, 1], ['ま', 'ma', 1, 1], ['み', 'mi', 1, 1], ['む', 'mu', 1, 1], ['め', 'me', 1, 1], ['も', 'mo', 1, 1], ['や', 'ya', 1, 1], ['ゆ', 'yu', 1, 1], ['よ', 'yo', 1, 1], ['ら', 'ra', 1, 1], ['り', 'ri', 1, 1], ['る', 'ru', 1, 1], ['れ', 're', 1, 1], ['ろ', 'ro', 1, 1], ['わ', 'wa', 1, 1], ['を', 'o', 1, 0], ['ん', 'n', 0, 1], ].each do |data| TABLE << Char.new(*data) end def self.[](index) TABLE[index] end end class Name attr_accessor(:name) attr_accessor(:value) attr_accessor(:vowels) attr_accessor(:consonants) def initialize @name = "" @value = 0 @vowels = 0 @consonants = 0 end def add(index) result = self.dup char = CharTable[index] result.name += char.char_j result.value += index result.vowels += char.vowel result.consonants += char.consonant result end def to_s @name end end class Shiogi SUM_OF_VALUE = 134 VOWELS = 8 CONSONANTS = 7 MIN_INDEX = 1 MAX_INDEX = 46 def initialize @count = 0 end def main @log = open("result.log", "w") generate(Name.new, MIN_INDEX) @log.close end def generate(name, start_index) start_index.upto(MAX_INDEX) do |index| new_name = name.add(index) break if new_name.value > SUM_OF_VALUE next if new_name.vowels > VOWELS next if new_name.consonants > CONSONANTS if match?(new_name) print(new_name) break else generate(new_name, index) end end end def match?(name) return false unless name.value == SUM_OF_VALUE return false unless name.vowels == VOWELS return false unless name.consonants == CONSONANTS @count += 1 true end def print(name) @log.puts sprintf("\r%10d: %s", @count, "#{name}") @log.flush end end Shiogi.new.main
C でも書いてみたところ、両者の結果が一致したので多分こちらが正しい。
#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAX_LENGTH 30 #define MIN_INDEX 1 #define MAX_INDEX 46 #define SUM_OF_VALUE 134 #define MAX_VOWEL 8 #define MAX_CONSONANT 7 typedef struct { char name[MAX_LENGTH]; int value; int vowels; int consonants; } name_t; typedef struct { char *j; char *e; int vowel; int consonant; } char_t; char_t table[] = { { "", "", 0, 0}, {"あ", "a", 1, 0}, {"い", "i", 1, 0}, {"う", "u", 1, 0}, {"え", "e", 1, 0}, {"お", "o", 1, 0}, {"か", "ka", 1, 1}, {"き", "ki", 1, 1}, {"く", "ku", 1, 1}, {"け", "ke", 1, 1}, {"こ", "ko", 1, 1}, {"さ", "sa", 1, 1}, {"し", "shi", 1, 2}, {"す", "su", 1, 1}, {"せ", "se", 1, 1}, {"そ", "so", 1, 1}, {"た", "ta", 1, 1}, {"ち", "chi", 1, 2}, {"つ", "tsu", 1, 2}, {"て", "te", 1, 1}, {"と", "to", 1, 1}, {"な", "na", 1, 1}, {"に", "ni", 1, 1}, {"ぬ", "nu", 1, 1}, {"ね", "ne", 1, 1}, {"の", "no", 1, 1}, {"は", "ha", 1, 1}, {"ひ", "hi", 1, 1}, {"ふ", "fu", 1, 1}, {"へ", "he", 1, 1}, {"ほ", "ho", 1, 1}, {"ま", "ma", 1, 1}, {"み", "mi", 1, 1}, {"む", "mu", 1, 1}, {"め", "me", 1, 1}, {"も", "mo", 1, 1}, {"や", "ya", 1, 1}, {"ゆ", "yu", 1, 1}, {"よ", "yo", 1, 1}, {"ら", "ra", 1, 1}, {"り", "ri", 1, 1}, {"る", "ru", 1, 1}, {"れ", "re", 1, 1}, {"ろ", "ro", 1, 1}, {"わ", "wa", 1, 1}, {"を", "o", 1, 0}, {"ん", "n", 0, 1} }; void generate(name_t*, int); name_t* add(name_t*, int); int is_match(name_t*); void print_name(name_t*); void print_time(time_t); int count = 0; int lognum = 0; FILE *fp = NULL; clock_t start_time; int main(int argc, char *argv[]) { start_time = clock(); generate(NULL, MIN_INDEX); print_time(start_time); fclose(fp); return 0; } void generate(name_t *name, int start_index) { int index; name_t *new_name = NULL; for (index = start_index; index <= MAX_INDEX; index++) { if (new_name != NULL) free(new_name); new_name = add(name, index); if (new_name->value > SUM_OF_VALUE) break; if (new_name->vowels > MAX_VOWEL) continue; if (new_name->consonants > MAX_CONSONANT) continue; if (is_match(new_name)) { print_name(new_name); break; } else { generate(new_name, index); } } if (new_name != NULL) free(new_name); } name_t* add(name_t *name, int index) { name_t *new_name; new_name = malloc(sizeof(name_t)); if (name == NULL) { memset(new_name, 0x00, sizeof(name_t)); } else { memcpy(new_name, name, sizeof(name_t)); } strcat(new_name->name, table[index].j); new_name->value += index; new_name->vowels += table[index].vowel; new_name->consonants += table[index].consonant; return new_name; } int is_match(name_t *name) { if (name->value != SUM_OF_VALUE) return 0; if (name->vowels != MAX_VOWEL) return 0; if (name->consonants != MAX_CONSONANT) return 0; return 1; } void print_name(name_t *name) { if (fp == NULL) fp = fopen("result.log", "w"); fprintf(fp, "%10d: %s\n", ++count, name->name); } 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 -Wall shiogi.c -o shiogi -O4 ↵ ./shiogi ↵
しかしやはり C は速い。