レッスン71
Pythonで数字のパズルを解いてみよう⌗
パズルのルール⌗
- 「A」という4ケタの数字と、「B」という5ケタの数字があります。
- 「B」は「A」の2倍です。つまり、「A」を2つ合わせると「B」になります。
- 「A」と「B」に使われている数字を全部集めると、1から9までの数字が1つずつ出てきます。
ルール3を満たす数には、例えば、こんな組み合わせがあります。
- 例1: A=1834, B=29567
- AとBを合わせると「183429567」になります。
- この中に「1、2、3、4、5、6、7、8、9」が全部1つずつ入っています。
他にも例として
- 例2: A=7462, B=14924
- 例3: A=3478, B=95612
このパズルの答えをPythonを使って全部見つけてみましょう。
解き方を2つ説明します。
解き方(その1):Aを一つずつ試してみよう⌗
最初の解き方は、4ケタの数字「A」を、1000から9999まで全部試してみる方法です。
ステップ1:AとBを表示してみよう⌗
まず、Aの候補を1000から9999まで順番に作って、それぞれのAについてBを計算してみましょう。
Pythonのプログラムの中の、「#」で始まる部分は説明なので、書かなくてもプログラムは動きます。
print("--- ステップ1: AとBを表示してみよう ---")
# Aは1000から9999までなので、range(1000, 10000)と書きます。
# range(1000, 10000)は、1000から始まって9999で終わります。10000は含まれないんだ。
for A in range(1000, 10000):
B = A * 2 # BはAの2倍なので、Aに2をかけるよ。
print(f"A: {A}, B: {B}") # AとBを画面に出してみよう。
このプログラムを実行すると、たくさんのAとBの組み合わせが表示されるはずです。
ステップ2:Bが5ケタの数字か確認しよう⌗
パズルのルールでは、Bは5ケタの数字でしたね。ステップ1で表示されたBの中には、4ケタや6ケタのBもあるかもしれません。5ケタじゃないBはパズルのルールに合わないから、次のAを試すようにプログラムを直しましょう。
print("\n--- ステップ2: Bが5ケタか確認しよう ---")
for A in range(1000, 10000):
B = A * 2
# Bが5ケタの数字かどうかは、Bが10000以上で、かつ100000未満かどうかで調べられます。
if 10000 <= B < 100000:
print(f"A: {A}, B: {B} (Bは5ケタなのでOK!)")
これで、Bが5ケタの組み合わせだけが表示されるようになりました。
ステップ3:AとBの数字をくっつけてCを作ろう⌗
次に、AとBの数字を全部くっつけて「C」という一つの大きな数字の並びを作ってみましょう。ただし、数字のままくっつけることはできないので、一度「文字」に変えてからくっつけます。
print("\n--- ステップ3: AとBをくっつけてCを作ろう ---")
for A in range(1000, 10000):
B = A * 2
if 10000 <= B < 100000:
# AとBを文字(文字列)に変えるよ。
str_A = str(A)
str_B = str(B)
C = str_A + str_B # 文字列のAとBを足すと、くっつくんだ!
print(f"A: {A}, B: {B}, C: {C}") # Cを表示してみよう。
Cには、AとBの数字が並んだ文字列が入っているはずです。
ステップ4:Cに1から9の数字が1つずつあるか確認しよう⌗
最後に、Cの中に1から9の数字がすべて1つずつあるかを確認します。これには「セット(set)」という便利な機能を使います。セットは、数字や文字の「集まり」を作ってくれるもので、同じものは一つにまとめてくれます。
1から9までの数字のセットと、Cの数字のセットが同じなら、パズルの答えが見つかったことになります!
print("\n--- ステップ4: 1から9の数字が1つずつあるか確認しよう ---")
# パズルで使ってほしい数字の集まりを「正しいセット」として準備しておこう。
correct_digits_set = set('123456789')
for A in range(1000, 10000):
B = A * 2
if 10000 <= B < 100000:
str_A = str(A)
str_B = str(B)
C = str_A + str_B
# Cの中の数字のセットを作るよ。
C_digits_set = set(C)
# 正しいセットとCのセットが同じか調べるよ。
if C_digits_set == correct_digits_set:
print(f"見つけたよ! A = {A}, B = {B}")
これで、このパズルの答えが全部見つかるはずです!
解き方(その2):数字の並び替えから探してみよう⌗
もう一つの解き方は、1から9までの数字を色々な順番に並べ替えてみて、そこからAとBを作る方法です。
この方法では、「順列(じゅんれつ)」というものを使います。順列とは、いくつかのものを順番に並べたものです。例えば、1, 2, 3の順列は「123」「132」「213」「231」「312」「321」などがあります。
ステップ1:1から9の数字のリストと順列を作ろう⌗
まず、1から9までの数字をリストに入れて、そこから色々な順列を作ってみましょう。順列を作るには、itertools
という特別な道具を使います。
import itertools # itertoolsという道具を使えるようにするよ
print("--- ステップ1: 1から9の数字のリストと順列を作ろう ---")
# 1から9までの数字のリストを作るよ。でも、順列を作るために「文字」にしておこう。
digits = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
# digitsからすべての順列を作るよ。
# permutations(digits)は、digitsのすべての文字を並べ替えたものを作ってくれるんだ。
print("たくさんの順列が作られるよ!例えばこんな感じ:")
for p in itertools.permutations(digits):
print(p)
プログラムを実行すると、数字がバラバラに並んだものがたくさん表示されるはずです。
ステップ2:順列をA用とB用に分けよう⌗
次に、作った順列を、Aを作るための4つの数字と、Bを作るための5つの数字に分けましょう。
import itertools
print("\n--- ステップ2: 順列をA用とB用に分けよう ---")
digits = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
count = 0
for p in itertools.permutations(digits):
# pは例えば ('1', '2', '3', '4', '5', '6', '7', '8', '9') のようになっているよ。
# 最初の4つをAの文字のリストにするよ。
A_chars = p[0:4] # 0番目から3番目まで(合計4つ)
# 残りの5つをBの文字のリストにするよ。
B_chars = p[4:9] # 4番目から8番目まで(合計5つ)
print(f"順列: {''.join(p)}, Aの文字: {''.join(A_chars)}, Bの文字: {''.join(B_chars)}")
これで、それぞれの順列が、Aになる部分とBになる部分に分けられたのがわかります。
‘’.join()という命令は、リストやタプルの要素を結合して文字列にするものです。
ステップ3:AとBの数字を作って表示しよう⌗
Aの文字とBの文字ができたので、今度はそれらを数字に戻して、AとBを表示してみましょう。
import itertools
print("\n--- ステップ3: AとBの数字を作って表示しよう ---")
digits = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
count = 0
for p in itertools.permutations(digits):
A_chars = p[0:4]
B_chars = p[4:9]
# 文字のリストを一つの文字にして、それを数字(整数)に変えるよ。
A = int(''.join(A_chars))
B = int(''.join(B_chars))
print(f"順列: {''.join(p)}, A: {A}, B: {B}")
これで、それぞれの順列から作られたAとBの数字が表示されるようになりました。
ステップ4:BがAの2倍か確認しよう⌗
最後に、AとBが作れたら、BがAの2倍になっているか確認するだけです。もし「B == A * 2」が正しければ、それがパズルの答えになります。
import itertools
print("\n--- ステップ4: BがAの2倍か確認しよう ---")
digits = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
print("パズルの答えを見つけているよ!")
found_count = 0
for p in itertools.permutations(digits):
A_chars = p[0:4]
B_chars = p[4:9]
A = int(''.join(A_chars))
B = int(''.join(B_chars))
# BがAの2倍かどうかをチェック!
if B == A * 2:
print(f"見つけたよ! A = {A}, B = {B}")
found_count += 1
if found_count == 0:
print("ごめんね、この解き方では答えが見つからなかったみたい。")
else:
print(f"合計で {found_count} 個の答えが見つかったよ!")