年子平方数の最初の21個を列挙する
2004年8月号 Cマガ電脳クラブ 第161回 年子平方数 ┌─────────────────────────────┐ │ 偶数桁の平方数(ある数を2乗してできる数)で、それぞれ同じ│ │桁数になるように左右半分に割ったとき、その2つの数が連続し│ │た2数になっているものを、「年子(としご)平方数」と呼ぶこと│ │にする。たとえば、 │ │ 8281(=91^2) │ │では81と82が連続した2数となっている。ただし、右半分と│ │左半分、どちらが大きくてもかまわない。ここでは正の整数のみ│ │を扱い、すなおに10進法で考える。 │ │ この「年子平方数」をほかにも見つけてほしいのだが、たくさ│ │んあるので、小さいほうから順に(上記の例を含めて)21番目ま│ │でをお答えいただきたい。 │ └─────────────────────────────┘ライブドアブログ(livedoor Blog)| 読みたいブログが見つかる
ujihisa が Haskell で実装したようなので、僕は釣られて Ruby で実装しました (リンク先ネタバレ注意)。
まずは実行結果。たまたま手元にあった Ruby 1.9 の r20750 を使いました。
$ time ~/ruby-r20750/bin/ruby toshigo.rb 1: 8281 2: 183184 3: 328329 4: 528529 5: 715716 6: 60996100 7: 82428241 8: 98029801 9: 1322413225 10: 4049540496 11: 106755106756 12: 453288453289 13: 538277538276 14: 998002998001 15: 20661152066116 16: 29752082975209 17: 2214532822145329 18: 2802768328027684 19: 7783702677837025 20: 9998000299980001 21: 110213248110213249 110213250 real 7m28.407s user 6m26.524s sys 0m3.877s
以下コード。
class Integer def square? r = Math.sqrt(self) i = r.to_i return self == i*i && r == i end end m = 0 n = 2 b = 10 inc = b + 1 x = n*b + n - 1 y = (n - 1)*b + n until m == 21 if x.square? m += 1 puts "#{m}: #{x}" end if y.square? m += 1 puts "#{m}: #{y}" end n += 1 if n == b b *= 10 inc = b + 1 x = n*b + n - 1 y = (n - 1)*b + n else x += inc y += inc end end p n