技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

超久々に Python 弄ってた

AI 関連が実質 Python 一択で、数学系ライブラリもその表示も Python だとかなり揃ってたので、久々にやってみようとしてどハマりした記録。
何をしようとしたかというと、下記を Python で実装すればいいかなーとかとか漠然と考えてどハマりした。

プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問

プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問

どこにはまったかというと問題2。

問題内容は書籍を買うか、下記を見て欲しい。

white-azalea.hatenablog.jp

  1. Python だし、eval あるよねー使い方調べるついでに使って見るかー」
    → 9009 に * 突っ込むとしても 90*09 とかになるとダウンする。09 ってなんぞやー
  2. 「諦めて、* が必要な箇所で文字列区切って掛け算するか」
    → 変数タイポで 1h どハマり(実行時評価だから実行するまでわからないので単純なミスが見つからない)
  3. 「計算できたし正解を比較するか」
    → 久々にやってて問題文間違って覚えてて、「計算の前後で出た四桁数字が順不同で含まれてることじゃね?」と勘違いして実装。
    → 片方の文字列を1時づつ取り出して、もう片方に含まれるか?という判定をするが、122 - 124 でも true になる。
    → なら逆も比較したらええやんと思いきや、122 - 12 で結局OK判定になってしまう。
    → なので、片方の文字列を1時づつ取り出して、もう片方から1字づつ削除(immutable じゃなくて背中が痒く…)してみるも、 Java の String.replace 同様の replace メソッドを見つけたが、第3引数に指定がないと replaceAll 同等動作とか知らずにハマる。
    → 突破したら突破したで仕様違いに気づいて脱力…回文かよ…

で、色々やった挙句、こんな単純な問題に 3 時間も悩まされたという。

途中途中で Syntax error に悩まされたのもでかい。
TextMate2 を使っているが、やっぱ IDE なんかでリアルタイムに syntax チェックしてないとわからん。
加えて言えば、実行字型の為に、動かしてから死んでデバッグの後戻りがひどかった…

慣れの問題なのだろうか、例えば代入時に変数名が一時違った位でも、「新しい変数ができた」と認識されて平然と動いてしまう為、何が悪いか超追いかけづらかった…。

結局最後は全部関数にした…もう…関数型で…イイヨ。
たとえ…Python に… tail call recursive が実装されてなかったとしても…!

positions = [
    [1], [2], [3],
    [2, 1], [3, 2], [3, 1],
    [3, 2, 1]
]

def split(str, pos, stack):
    if len(pos) == 0:
        stack.append(str)
        return stack
    else:
        i = pos[0]
        stack.append(str[i:])
        return split(str[:i], pos[1:], stack)

from functools import reduce

def multiple(list):
    return reduce(lambda a,b: a * b, list)

def is_kaibun(left, right):
    return left == right[::-1]

for cur in range(1000, 9999):
    strCur = str(cur)
    for pos in positions:
        splitted = split(strCur, pos, [])
        result   = multiple(map(lambda v: int(v), splitted))
        if is_kaibun(strCur, str(result)):
            print(str(splitted) + " = " + str(result))
            print("success: " + strCur)