見出し画像

開成中学の算数の問題

今、中学入試についての本を書いているのですが、敵情視察といいましょうか、暇つぶしといいましょうか、開成中学の本年度の入試問題の最初の問題、を解きました。

数字 1, 2, 3, 4, 5, 6, 7, 8, 9 と四則演算の記号 +, -, ×, ÷ とカッコだけを用いて 2024 を作る式を1つ書きなさい。ただし、次の指示に従うこと。

  1. 1つの数字を2個以上使ってはいけません。

  2. 2個以上の数字を並べて2けた以上の数を作ってはいけません。

  3. できるだけ使う数字の個数が少なくなるようにしなさい。(使う数字の個数が少ない答えほど、高い得点を与えます。)

これに対して、私は、9×8×7×4+5+3という解答を思いつきましたが、使っている数字は6個です。もっと少ない個数で表せないか(もしそうならより高い得点になる)総当たり戦のプログラムを組んでやらせてみたところ、5個以下では表せないようです(間違っていたらご指摘ください)。出した答えはやはり6個で、2+4×7×8×9+6でした。9×8×7×4部分は共通しています。これを出すのに私の貧弱な環境では6分23.5秒かかりました。自慢するつもりはありませんが、私は1分程度で解答できました(あ、自慢か・・・)。ちなみに用いたコードも検証用に下に示しておきます。

import itertools
import operator

digits = [1, 2, 3, 4, 5, 6, 7, 8, 9]
operators = [operator.add, operator.sub, operator.mul, operator.truediv]  # 加減乗除
operator_symbols = ['+', '-', '*', '/']

def evaluate(expression):
    """式を評価して結果を返す。エラー処理は簡略化"""
    try:
        result = eval(expression)
        return result
    except (ZeroDivisionError, TypeError):
        return None


def find_solution(num_digits):
    """指定された数の数字を使って2024を作る式を探す"""
    for digits_combination in itertools.permutations(digits, num_digits):
        for operator_combination in itertools.product(operators, repeat=num_digits - 1):
            expression_str = str(digits_combination[0])
            for i in range(num_digits - 1):
                expression_str += operator_symbols[operators.index(operator_combination[i])] + str(digits_combination[i+1])

            result = evaluate(expression_str)
            if result == 2024:
                print(f"Solution found: {expression_str} = 2024")
                return True

    return False


for i in range(1, len(digits) + 1): #1個から9個まで試す。
    print(f"Trying with {i} digits...")
    if find_solution(i):
        break
    else:
      print("No solution found for this number of digits.")

これを利用される場合には、自己責任でお願いします。

この話は実はここで終わっていません。続きの記事をご覧ください!

いいなと思ったら応援しよう!