乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

プログラミング


はい
またまた 数字のトリビアをPythonで検証してみました。

解説動画はこちら




最初のトリビアは
数字のトリビア.007

割るときれいな数字がでる組み合わせです。

コードは
print(1/81)
print(1/891)
print(1/8991)
print(1/89991)
print(1/8181)
print(1/818181)

0.012345679012345678
0.001122334455667789
0.00011122233344455567
1.1112222333344445e-05
0.0001222344456667889
1.2222234444456666e-06

以外ときれいに並びますねー
Pythonのデフォルトでは桁数がそんなに多く出せ無いので
こんな感じになってしまいます。


次は
数字のトリビア.008

またまた割り算のトリビアですが
これはデフォルトでは桁が足り無いので
正確な小数点の計算をするためのライブラリを用います。

decimal

コードは
import decimal

decimal.getcontext().prec = 1000
a = decimal.Decimal(10000)
b = decimal.Decimal(9801)
print(a / b)
結果は・・・
1.02030405060708091011121314151617181920
2122232425262728293031323334353637383940
4142434445464748495051525354555657585960
6162636465666768697071727374757677787980
818283848586878889909192939495969799000
・・・
1から一つづつ数字が増えていく結果になります。

おしい
97までは並んだのに

というかこれを発見した人
絶対ヒマ人でしょ

こんな計算
いつやるの?


・・
・・・

ひまでしょ!!

はい。

お次は
数字のトリビア.009

なんか良くわかりませんが上記の操作をすると
必ず同じ数字に戻るんだそうです。
なんか不思議ですね
for i in range(100,1000):
    a2 = int(str(i)*2)
    a3 = a2//7
    a4 = a3//11
    a5 = a4//13
    print(i,a5)



トリは
数字のトリビア.010

ゾロ目以外の4桁の数字で
数字を大きい順に並び替えたものから
数字を小さい順に並び替えたものを引く。

それをまた同じ操作をしていくと・・・

6174になるんだそう。

検証したコードはこちらに。

まずは上記の操作をする関数kapを作ります。
6174になるまで再帰します。

def kap(i):
    ma = sorted([a for a in str(i)],reverse=True)
    mi  = sorted([a for a in str(i)])
    m  = int(''.join(ma)) - int(''.join(mi))
    if m ==6174:
        return m
    else:
        return kap(m)
for i in range(1000,10000):
    if str(i)[0]==str(i)[1]==str(i)[2]==str(i)[3]:
        continue
    else:
        try:
            m = kap(i)
            print(i,m)
        except:
            print(i,'X')

あとはゾロ目は除いて
4桁の数字を検証。

だいたいは
6174になるようですね。
一部は再帰が終わらずエラーになってしまいました。


このように
最大に並べ替えたものから最小に並べ替えたものを引いた答えが
元と同じになるような数をカプレカ数と言うのだそうで。

なかなか面白い数字ですね。

また次回もお楽しみに!!

数字にまつわるトリビアを
Pythonで検証してみました。


解説動画はこちら




まず始めのトリビアは

数字のトリビア.002

はい、1回折れれば厚さが二倍になるということで
検証したコードがこちら
moon = 0.08 * (2 ** 43)
print('{}万キロ'.format(moon/10/100/1000/10000))
70.368744177664万キロ

飛んでもないですね
43乗すれば月まで届きそうですね

折れればですが

花山薫のピンチ力をもってしても
無理そうな問題です

お次が
数字のトリビア.003
コードは
for i in range(1,10):
    print('3912657840 / {0} '.format(i) , 3912657840%i)

3912657840 / 1 0
3912657840 / 2 0
3912657840 / 3 0
3912657840 / 4 0
3912657840 / 5 0
3912657840 / 6 0
3912657840 / 7 0
3912657840 / 8 0
3912657840 / 9 0

余りがないということは割り切れている
ということで、きれいに割り切れました。

お次は
数字のトリビア.004

これまた割り切り問題ですね

コードは
まずこの9つの数字を使った順列を求めます。
import itertools
seq = ['1','2','3','4','5','6','7','8','9']
per = list(itertools.permutations(seq))
print(len(per))
362880

この順列と同じだけ検証して
合っていれば+1カウントします。

結果は・・
count = 0
for tmp in itertools.permutations(seq):
    num = int(''.join(tmp))
    if num % 3 == 0:
        count+=1
print(count)
362880

全部割り切れました。1-9全部使った9桁の数値は
みな3で割り切れます。

ちなみにこの数は絶対9の倍数になるので
必ず3では割り切れるようになっています。

次は
数字のトリビア.005


コードは
for i in range(1,10):
    print('12345679 * 9 * {0}'.format(i) , 12345679 * 9 * i)

12345679 * 9 * 1 111111111
12345679 * 9 * 2 222222222
12345679 * 9 * 3 333333333
12345679 * 9 * 4 444444444
12345679 * 9 * 5 555555555
12345679 * 9 * 6 666666666
12345679 * 9 * 7 777777777
12345679 * 9 * 8 888888888
12345679 * 9 * 9 999999999

結果は綺麗にそろいます。
元の数字は8だけ抜けてますけどね。

さて最後は
数字のトリビア.006


語呂合わせで
18782 + 18782

この結果は・・・・

37564

ということでした。
良く知られた数字の計算ですね。

また次回も数字のトリビアをお送りします。

週1でお世話になるサイゼリア

好きなメニューは
青豆の温サラダ

これがあるから
サイゼリアは止められない!!!!

そんなサイゼリアさんで
いつも話題に上がるのが

サイゼリアの間違い探し
難しすぎ問題


普段そんなに
間違い探しとかに気を取られないが

注文したメニューが来るまでは
考えちゃいますよねーー

そんな間違い探しを
プログラムの力で解いてみたい
という挑戦です。

動画はこちら




まずは
元の画像をサイゼリアさんの公式ページから
お借りしてきました。

間違い探し

saize201810

これが間違い探しの問題の画像です。

これは1200 x 578ピクセルのサイズでした。

これを
左右を同じサイズで切り取って
そのピクセルを比較すれば、
間違い探しの答えが浮かび上がるのではないか?

そう考えたわけです。

まずは
左右二つの画像に切り分けます。

Pythonでは画像を取り扱うライブラリもあるので
それが使えます。

まずはライブラリのインポート
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

im = Image.open('saize201810.png')
rgb_im = im.convert('RGB’)
PILというライブラリで画像を取り込み
描画用にmatplotlibを使います。

matplotlibの画像を描画させるのに
numpyのarrayでなければならないので
numpyも読み込み

matplotlibを
インラインで表示させたいので指定します。

画像をとりこんだあとは
左右に切り分けます。
im1 = Image.new('RGB',(572,578))
im2 = Image.new('RGB',(572,578))

for x in range(0,572):
    for y in range(578):
        r,g,b = rgb_im.getpixel((x+28,y))
        im1.putpixel((x,y),(r,g,b))
        
for x in range(601,1173):
    for y in range(578):
        r,g,b = rgb_im.getpixel((x,y))
        im2.putpixel((x-601,y),(r,g,b))

plt.imshow(np.array(im1))
plt.imshow(np.array(im2))

左右に余白があり
マージンを取って取り込みます。
ピクセルのRGB値を取得して
新たな画像として生成します。

左側

saize1

右側
saize2

次に
この画像のピクセル同士を比較します。

この問題の左右がコピーされていて
ほぼ同じものであったなら
そのピクセルの違う部分が答えなのではないかと

im3 = Image.new('RGB',(572,578))

for x in range(572):
    for y in range(578):
        r1,g1,b1 = im1.getpixel((x,y))
        r2,g2,b2 = im2.getpixel((x,y))
        if r1!=r2 or g1!=g1 or b1!=b2:
            im3.putpixel((x,y),(r1,g1,b1))
        else:
            im3.putpixel((x,y),(0,0,0))

plt.imshow(np.array(im3))

左右のピクセルを比較した結果
違っていればそのピクセルを
合っていれば黒で答えを作りました。

結果は・・・・

saize3

なんか
いろいろ写っちゃってるやないかーーい


左右は全くの同じではなく
少し違いがあるか、ズレが生じているようで

単純なピクセルの比較では
答えの部分だけを出すのは難しいようです。

一応、違いが大きいところは
色が付いているので
着目すれば10個の答えは出そうですが

うまく、結果だけを出す
アルゴリズムを考えないと
くっきりした答えには
たどり着けないですねーーー

うーん
画像は奥が深い

ということで
皆さん
サイゼでガッツリ食べながら
この問題を解いてみましょう(笑)


はいどーもー
乙pyです。

暇なので受験シーズンだし
有名中学の算数の問題をプログラムで解けないかと
思ったりしたわけですね。

インターネットの
Googleで調べたんですが
そこで問題が難しそうな学校を見つけてしまったんですね。

皆さん

難しい中学校って知ってます?

自分は近所の中学校に行ったので
知らないんですけど
問題を解いてみたんですねー

というものの第八弾です。


動画解説はこちら



始めの問題
有名中学の入試問題.014


これも一瞬で解けます。
for i in range(1,20):
    st = '2' + '0'*i +'7'
    if int(st)%27==0 and int(st)%81!=0:
        print(st)
        break
先頭が2で末尾が7、間が0という
条件を充しつつ
27で割り切れて、81で割り切れないというものが
1つでも見つかった時点で
プログラムは終了です。

条件の書き方もそこまで難しくはないと思います。


次の問題は
有名中学の入試問題.013

まずは図を把握しろという
難問でした。

図のルールがわかれば
プログラムに落とし込むのは容易です。

要は日本語の問題ですね。
きちんと仕様を理解するというのが
問題のポイント(笑)です。

1のコードは
num = [1,2,3,4,5,6,7,8,9,10,11,12]
q1 = []
for i in range(1,6):
    q1 = num
    num = [num[0],num[6],num[1],num[7],num[2],num[8],num[3],num[9],num[4],num[10],num[5],num[11]]
print(q1)

1回目は入れ替えが起きないので
入れ替えが始まるのは2回目からですね

その分を考慮する必要があります。

一旦数字の並びは
リストに格納し、その並びを求めることとしました。

2のコードは
num  = [1,2,3,4,5,6,7,8,9,10,11,12]
num1 = [1,2,3,4,5,6,7,8,9,10,11,12]
q2 = 1
for i in range(1,13):
    q2 +=1
    print(i,num)
    num = [num[0],num[6],num[1],num[7],num[2],num[8],num[3],num[9],num[4],num[10],num[5],num[11]]
    if num == num1:
        print(q2)
        break

元の数値の並びを置いておき
入れ替えをするものと並びを比較してあげるだけの
シンプルなコードです。

12個しか数字がないので
元と同じになるのに
12回以上は入れ替えが起きないだろうと
試行回数は減らしています。

3のコードは
num = [1,2,3,4,5,6,7,8,9,10,11,12]

for i in range(2006-1):
    num = [num[0],num[6],num[1],num[7],num[2],num[8],num[3],num[9],num[4],num[10],num[5],num[11]]
print(num)

単にその回数実行してあげるだけ
ただし、その回数には注意が必要ですね。


図で考えると
すごく難しそう

でもプログラムはシンプル

そんな問題でした。

この問題の図を作るのに
一番時間が掛かるという・・・・

解くのは一瞬

はいどーもー
乙pyです。

暇なので受験シーズンだし
有名中学の算数の問題をプログラムで解けないかと
思ったりしたわけですね。

インターネットの
Googleで調べたんですが
そこで問題が難しそうな学校を見つけてしまったんですね。

皆さん

難しい中学校って知ってます?

自分は近所の中学校に行ったので
知らないんですけど
問題を解いてみたんですねー

というものの第七弾です。


動画解説はこちら



まず始めの問題は

有名中学の入試問題.004

整数を文字にして連結していき
そこに出てくる1の個数を数えればいいだけの
シンプルな問題です。

コードは

ans1=''
for i in range(1,101):
    ans1+=str(i)
print(len(ans1))
ans2=''
for i in range(1,1001):
    ans2+=str(i)
print(len(ans2))
print(ans2.count('1'))

100回だろうと、1000回だろうと
コードの量はほとんど変わりません。

次の問題


有名中学の入試問題.003

細胞B,T

それぞれ1秒毎に
BはBとT
TはBとB

個数としてはどちらも
2倍に増えていますねーー

ということは
8秒後には2 ** 8
倍になっていそうですね

あとはその配分がどうなっているかということ

動画では初めはB
その後BとTの時で処理を分けて増やし
最後にどうなったのかを出力するようにしました。

sells = ['b']
for i in range(8):
    tmp = []
    for sell in sells:
        if sell =='b':
            tmp+=['b','t']
        else:
            tmp+=['b','b']
    sells=tmp

print(sells.count('b'))
print(sells.count('t'))

当初の目論見通り
BとTで足すと256個でしたね。

TとTで

TT兄弟

なんちゃって


このページのトップヘ