朝日新聞2006年6月9日パズル横丁解答

プログラムの実行結果は以下の通り。

いち, いち
に, に
よん, よん
ろく, ろく
ろくじゅう, ろくしゆう
ろくじゅういち, ろくしゆういち
ろくじゅうに, ろくしゆうに
ろくじゅうよん, ろくしゆうよん
ろくじゅうろく, ろくしゆうろく
ろっぴゃく, ろつひやく
ろっぴゃくいち, ろつひやくいち
ろっぴゃくに, ろつひやくに
ろっぴゃくよん, ろつひやくよん
ろっぴゃくろく, ろつひやくろく
ろっぴゃくろくじゅう, ろつひやくろくしゆう
ろっぴゃくろくじゅういち, ろつひやくろくしゆういち
ろっぴゃくろくじゅうに, ろつひやくろくしゆうに
ろっぴゃくろくじゅうよん, ろつひやくろくしゆうよん
ろっぴゃくろくじゅうろく, ろつひやくろくしゆうろく
Find ろっぴゃくろくじゅうろく , ろつひやくろくしゆうろく
3.125 秒

666が辞書の一番後ろに来ます。

プログラムのソースは以下の通り。

#include "puzutl.h"

cstring yomi[][4] = {
  { ""        , ""              , ""              , ""},
  { "いち"    , "じゅう"        , "ひゃく"        , "いっせん"},
  { "に"      , "にじゅう"      , "にひゃく"      , "にせん"},
  { "さん"    , "さんじゅう"    , "さんびゃく"    , "さんぜん"},
  { "よん"    , "よんじゅう"    , "よんひゃく"    , "よんせん"},
  { "ご"      , "ごじゅう"      , "ごひゃく"      , "ごせん"},
  { "ろく"    , "ろくじゅう"    , "ろっぴゃく"    , "ろくせん"},
  { "なな"    , "ななじゅう"    , "ななひゃく"    , "ななせん"},
  { "はち"    , "はちじゅう"    , "はっぴゃく"    , "はっせん"},
  { "きゅう"  , "きゅうじゅう"  , "きゅうひゃく"  , "きゅうせん"},
};

void make_yomi( astring s, int val, int keta) 
{
  if( val < 0) return;
  if( keta==0) {
    //strcpy( s, "★");
    return;
  }
  if( keta< 10) {
    strcpy( s, yomi[val][0]);
  }
  else if( keta< 100) {
    // 57:ごじゅう なな
    strcpy( s, yomi[val/10][1]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%10, keta/10);
  }
  else if( keta< 1000) {
    // 857:はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/100][2]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%100, keta/10);
  }
  else if( keta< 10000) {
    // 4857:よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/1000][3]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%1000, keta/10);
  }
  else if( keta< 100000) {
    // 94857:きゅうまん よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/10000][0]);
    strcat( s, "まん");
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%10000, keta/10);
  }
  else if( keta< 1000000) {
    // 394857:さんじゅう きゅうまん よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/100000][1]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%100000, keta/10);
  }
  else if( keta< 10000000) {
    // 2394857:にひゃく さんじゅう きゅうまん よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/1000000][2]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%1000000, keta/10);
  }
  else if( keta< 100000000) {
    // 12394857:せん にひゃく さんじゅう きゅうまん よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/10000000][3]);
    //strcat( s, "◆");
    make_yomi( s+strlen(s), val%10000000, keta/10);
  }
  else if( keta< 1000000000) {
    // 612394857:ろくおく せん にひゃく さんじゅう きゅうまん よんせん はっぴゃく ごじゅう なな
    strcpy( s, yomi[val/100000000][0]);
    strcat( s, "おく");
    //strcat( s, "◆");
    int v = val%100000000;
    if( v/10000 == 0) make_yomi( s+strlen(s), v%10000, keta/100000); // 万を飛ばす,これをしないと「さんおくまん」とかになる。
    else              make_yomi( s+strlen(s), val%100000000, keta/10);
  }
}

void make_yomi( astring s, int val)
{
  make_yomi( s, val, val);
}

void conv_yomi( astring s1, cstring s0)
{
  static jap jchr_a  = firstjap( "ぁ");
  static jap jchr_n  = firstjap( "ん");
  //                   ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん 
  static cstring kana="ああいいううええおおかかききくくけけここささししすすせせそそたたちちつつつててととなにぬねのはははひひひふふふへへへほほほまみむめもやゆゆゆよよらりるれろわわゐゑをん";
  jap           jchr;
  while( (jchr=getjap(s0)) != NIL) {
    if( jchr >= jchr_a && jchr <= jchr_n) {
      jchr      = firstjap( kana+(jchr-jchr_a)*sizeof(jap));
    }
    putjap( s1, jchr);
  }
  *s1 = NIL;
}

int main( int argc, cstring argv[])
{
  char buf[128], buf0[128], buf1[128], buforg[128];
  buf0[0] = buforg[0] = NIL;
  ProcTime      pt;
  for( int i=1; i<= 1000000; i++) {
    make_yomi( buf, i);
    conv_yomi( buf1, buf);
    if( strcmp( buf1, buf0) > 0) {
      ps( "%s, %s\n", buf, buf1);
      strcpy( buf0, buf1);
      strcpy( buforg, buf);
    }
  }
  pt.end();
  ps( "Find %s , %s\n", buforg, buf0);
  ps( "%g 秒\n", pt.sec());
  return    0;
}