プログラミング素人のはてなブログ

プログラミングも電気回路も専門外の技術屋の末端が勉強したことや作品をアウトプットするブログ。コードに間違いなど見つけられたら、気軽にコメントください。 C#、Python3、ラズパイなど。

シカクいアタマでプログラミング

通勤電車でよく見かけるのが日能研の額面広告ですが、これは、中学校入試の問題またはその改題が出ています。
大体の問題(特に数学・算数)はこのブログの記事を理解できるぐらいのプログラマの方々なら暗算でも解けると思います。

しかし、ここではあえてプログラマとして線形探索で解いてみます。
f:id:s51517765:20181126222230p:plain

読み取れる問題のポイントは、
①1~6の重複しない整数で生成された整数である
②上から2桁を見たとき2の倍数で、上から3桁をみたとき3の倍数で、上から4桁が4の倍数で、上から5桁が5の倍数で、上から6桁が6の倍数である

これに加えて、
③最小値は123456
④最大値は654321
という条件が分かります。

プログラミングするということはforでloopを回しながら、123456から654321の数で、①と②を満たす組を見つければよいことになります。

やろうとしていることは簡単に見えますが、実は関数が用意されてない(見つけられなかっただけかもしれませんが)やっかいなアルゴリズムでした。

任意の整数から1桁ずつに分解する

割り算の商を使う方法や、文字列としてスライスしていく方法があるようですが、ここでは上の桁から数字を増やしていって対象と比較する方法をとりました。

max = 654321
min = 123456
d1, d2, d3, d4, d5, d6 = 0, 0, 0, 0, 0, 0

for i in range(min, max+1):
    for j in range(1,7):
        if i < j * pow(10, 5):
            break
        d1 = j

    for j in range(1,7):
        if i - d1 * pow(10, 5) < j * pow(10, 4):
            break
        d2 = j

    for j in range(1,7):
        if i - d1 * pow(10, 5) - d2 * pow(10, 4) < j * pow(10, 3):
            break
        d3 = j

    for j in range(1,7):
        if i - d1 * pow(10, 5) - d2 * pow(10, 4) - d3 * pow(10, 3) < j * pow(10, 2):
            break
        d4 = j

    for j in range(1,7):
        if i - d1 * pow(10, 5) - d2 * pow(10, 4) - d3 * pow(10, 3) - d4 * pow(10, 2) < j * pow(10, 1):
            break
        d5 = j

    for j in range(1,7):
        if i - d1 * pow(10, 5) - d2 * pow(10, 4) - d3 * pow(10, 3) - d4 * pow(10, 2) - d5 * pow(10, 1) < j * pow(10, 0):
            break
        d6 = j

この数字が重複なく構成できるかどうか判断

数字をリストに追加していき、重複がないことを確認

list = [] #リストの初期化
list.append(d1)
    if d2 not in list: #d2がリストになければ
        list.append(d2)
        if d3 not in list: #d3がリストになければ(以下同)
            list.append(d3)
            if d4 not in list:
                list.append(d4)
                if d5 not in list:
                    list.append(d5)
                    if d6 not in list:
                        list.append(d6)

この数字の上から●桁が倍数の規定に合うかどうか判断

 if (d1 * pow(10, 1) + d2 * pow(10, 0)) % 2 == 0: #最初の2桁が2の倍数(以下同)
     if (d1 * pow(10, 2) + d2 * pow(10, 1) + d3 * pow(10, 0)) % 3 == 0: 
          if (d1 * pow(10, 3) + d2 * pow(10, 2) + d3 * pow(10, 1) + d4 * pow(10, 0)) % 4 == 0:
              if (d1 * pow(10, 4) + d2 * pow(10, 3) + d3 * pow(10, 2) + d4 * pow(10, 1) + d5 * pow(10, 0)) % 5 == 0:
                  if (d1 * pow(10, 5) + d2 * pow(10, 4) + d3 * pow(10, 3) + d4 * pow(10, 2) + d5 * pow(10, 1) + d6 * pow(10, 0)) % 6 == 0:
                       print(i)

答え

123654
321654

github.com