2012年8月15日水曜日

Project Euler - Probrem 36

Project Euler(プロジェクト オイラー)の問題をpythonでやってみます。

出典:
Project Euler(日本語 翻訳サイト)
     ProjectEuler.net(英語サイト)

Problem 36

585 = 10010010012 (2進) は10進でも2進でも回文数である.
100万未満で10進でも2進でも回文数になるような数の総和を求めよ.
(注: 先頭に0を含めて回文にすることは許されない.)


-----

私の解答例は以下です。畳んでいます。
def g(s): return s==s[::-1]
def f(n): return [i for i in xrange(1, n, 2) if g(str(i)) and g(format(i, "b"))]

n=1000000
print sum(f(n))
 

二進数表記で先頭に0を含めて回文にしてはいけないとのことなので、
回文になったときの最後の桁も0ではいけないことになります。
二進数で最後の桁が1ということは、十進数では奇数ということになります。


2つの関数を使っています。

1.関数g(s)
・引数の文字列sが回文数かどうかを判定します。

・s==s[::-1]
 シーケンス[start:stop:step]です。stepが-1で逆順になります。
 これで文字列sとその逆順文字列が同じであるかをが判定しています。


2.関数f(n)
・十進数表記と二進数表記がともに回文数である奇数の十進数でのリストを返します。
・[i for i in xrange(1, n, 2) if g(str(i)) and g(format(i, "b"))]
 内包表記です。
 まずfor文で、1からnまでの整数を2つ飛び、つまり奇数だけ1つずつループ変数iに設定します。
 そして後ろのif文に渡し、条件に合った値のみfor文の前に送り、そのままリストにためます。
 

 条件部分は、奇数iを文字列にして回文判定した結果と、
 format文で奇数iを二進数変換して回文判定した結果をandで結び、
 両方とも回文数の場合に正とする、という意味です。
 
 なお、format文は第1引数の値を第2引数の書式にする文です。
 "b"の二進数表記のほかに、"d"が十進数、"o"が八進数、"x"が十六進数になります。
  

3.関数の外
・関数f()で問題に合う値のリストが戻ってくるので、sum関数でその合計を計算します。



解答はこのすぐ下の行です。文字の色を白にしてます。選択状態にすると見えます。
872187

0 件のコメント:

コメントを投稿