RSS

 

RSS


プログラム


nで割り切れる最小01十進数

  • いわいまさか
  • at 2015/1/29 12:36:36

元の問題としては
パズ懇神戸さん作の2015年の年賀問題
 27で割り切れる最小の01十進数を求めよ
 2015で割り切れる最小の01十進数を求めよ
というもの。
「01十進数」は0と1だけでできた十進数。

いわいはこれをC#のBigIntegerを使ったプログラムを書いて解いた。所要時間は短め。これはこれでめでたし。

そのプログラムを使って、27や2015だけでなく10000まで調べてみたら、
2439のときが解けなかった。理由はプログラムの作りが悪く、そして、探索が深すぎるためのメモリーオーバーフロー。

「この件」をパズル懇話会のMLで投稿したところ、パズ懇メンバー白川さんが、以下のようなプログラムを示してくれた。

>白川です。
>
>2439の時、解いてみました。
>
2439 * 00004100496519520340344449 
>  10001111011110110100111111
>以下がソースコードです
https://ideone.com/CiNF3n


そのコードは参照してもらうとそれでよろしい。
のだが、蛇足ながら、説明w

①大筋
 かける数を下の桁から決定していく。
 例えば、2439の場合であれば、
 下一桁目は 9*0=0 か 9*9=81 で0と1しかない。 

 掛け算の筆算的に書いて
■■■■■2439
×GFEDCBA
---------

 ABCDEFG・・・に当てはまる数を決定していく。ただし、ABC・・・それぞれに、候補が複数ある場合があるのでそれを探索していっている。

 Aが9だとすると

■■■■■2439
×■■■■■■B9
---------
■■■■21951  

1の位はOK。Bに関しては
2439×B+2195=の下一桁が0か1になるようなBをとる
この2195を白川プログラムではnextnumとしている。

Bを4と決めると
■■■■■2439
×■■■■■C49
---------
■■■119511

nextnum=1195 となる。

②プログラムの理解
tableが探索のための配列で、かつ記録をとる。
1桁解決した場合に未解決のnextnumが残り。
usedtableでnextnumの既出をチェック。(循環をふせぎ)
nextnumが1のときが終了条件で。(101とかも結局1にいきつくし、最小狙いでやるためには、これじゃないとだめ)
prevを記録しているので、復元できると。
もしも、答えがないときは、出力せずに終了。

③大局的な理解
nextnumを導入したところで、
問題が「分岐のある道の出口までの最短経路探索」になって。
最短経路=最小桁数ということ。

以上


  • コメント (0)
  • トラックバック (0)
トラックバックURL :
http://www.iwai-masaka.jp/tb.cgi/56152