kngenieの日記

日記だ。でもさすがに毎日は書けない。

頭の体操

古いネタで恐縮だが、
www.softantenna.com
という話があって。元ネタはRedditだそうなんだけど(Reddit見ない)。

面白いのは問題5で、ほとんどの人はこれだけをやって楽しんでいるのではないか。日本人はもともとこの種の数字遊びが好きで、切符の端に書かれた4つの整数を見るとあれこれいじって10にする、という頭の体操をやってしまう。以前Twitterでもこのネタが流れてきて、数字の間に文字はなんでも入れていいという話だったので、「√」だの「**」だの「%」だのを入れて幾つも作って投げた覚えがある。

で、問題5だが、Python 2で書くとこんな感じか...

from itertools import product

ops = [['', '+', '-']] * 8

for p in product(*ops):
  exp = ''.join('{}{}'.format(i+1, p[i]) for i in range(8))+'9'
  if eval(exp) == 100:
    print exp

実行してみたら(2年ぐらい前のMBP) 0.14秒程度であった。3**8=6561組み合わせぐらいだからこんなもんか。

evalを使っているのがちょっと卑怯っぽい。operatorでも使って書き直して見るか。

問題3は有名なエラトステネスの篩を書きなさい、という話なんだけど、以前これをエンジニアの採用テストに出したことがあって、けっこう痛い回答を書いてくる人がいることがわかった。

私の想定する回答はこんな感じであった:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('n', type=int, help='upper bound')

args = parser.parse_args()

sieve = list(range(1, args.n + 1))

for i in (n for n in sieve if n > 1):
    for j in range(i + i, args.n + 1, i):
        sieve[j - 1] = 0

for n in sieve:
    if n > 0: print(n)

コメントがないと今見てもさっぱりわからない :D。
argparseなんか使っちゃってるが、ここらへんをスっと書いてくるかどうかも見ていたりする。