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

プログラミング

はいどーもー
乙pyです。

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

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

皆さん

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

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

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


動画解説はこちら


初めの問題

有名中学の入試問題.022


まずは3桁の整数ABCを試行するとします

for abc in range(100,1000):


整数BCAと整数CABはそれぞれ
整数ABCを文字として扱って
インデックスを用いるとうまく抜き出すことができます。

整数BCAはABCの3/4倍
整数CABはBCAの3/4倍

ということは
整数CABはABCの9/16倍になりますね。

整数ABCと他の二つの数値の比較で
答えを求められます。

答えを求めるプログラムは次のようになりました。

for abc in range(100,1000):
    x = str(abc)
    bca = int(x[1]+x[2]+x[0])
    cab = int(x[2]+x[0]+x[1])
    if abc * 3//4==bca and abc*9//16==cab:
        print(abc)

この場合の答えは二つ出るようですね。


次の問題
有名中学の入試問題.021


5つの異なる偶数という条件だけだと
組み合わせは無限にあります。

まずは試行範囲を決めないといけないというところが
ポイントです。

できるだけ試行する組み合わせを減らしてあげないと
探索が厳しくなります。

幸い問題には
この試行範囲を減らすためのヒントが載っていました。
・5つの数の平均は61.6
・最も大きいのを除いた4つの平均は60.5
・最も小さいのを除いた4つの平均は63

ということは偶数の組み合わせとしては
X1 X2 X3 X4 X5 の平均は61.6
X1 X2 X3 X4      の平均は60.5
     X2 X3 X4 X5 の平均は63

ということなので
5つの平均 * 5 から それぞれの平均 * 4
で最小値と最大値が求められます。
x1 = int(61.6*5) - int(63*4)
x5 = int(61.6*5) - int(60.5*4)
すると
X1 , X5 は56と66になりました。

最大と最小が決まるので
それ以外の3つの偶数X2,X3,X4は
最大最小の間の偶数
58 , 60 , 62 , 64  4つに絞られます。

あとはこれを組み合わせとして
4つの中から3つ選び
X1とX5を足して
5つの偶数の平均が61.6になれば
正解になるかと思います。


正解を求めるプログラムは・・・
import itertools
x1 = int(61.6*5) - int(63*4)
x5 = int(61.6*5) - int(60.5*4)
for i in list(itertools.combinations((58,60,62,64),3)):
    if sum((x1,x5)+ i)/5==61.6:
        print(i)

組み合わせは
itertools.conbinations(リスト,組み合わせの数)
で求められます。

順列と違い、順番は考えないので
4つの偶数の中から3つを選ぶ方法は
4通りしかありません。

X1,X5まで分かってしまっているので
正直なところ
プログラムで解く意味がない問題になってしまいました。

プログラムを書く方が速いか
自力で解く方が速いのか

どちらが速く解けるか
ギリギリのラインの問題を
やってみたいですね。

はいどーもー
乙pyです。

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

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

皆さん

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

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

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


動画解説はこちら



さて最初の問題は
有名中学の入試問題.024

2桁と4桁の整数同士の結果を問う問題なので
試行回数が増えますね。

変数a と x の2重ループになるという考えで進みました。

整数aとxをかけると119868
整数aの10と1の位を0に置き換えたものを
変数bすると

求める数の条件は
a * x == 119868
かつ
b * x == 117600
になりますね。

あとは複数出たaの中から
最大の整数を求めれば終了です。


答えは次のようなプログラムになりました。
r = []
for a in range(1000,10000):
    for x in range(10,100):
        b = int(str(a)[0:2] +'00')
        if a * x == 119868 and b * x == 117600:
                r.append(a)
                print(a,x)
print(max(r))



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


数字の穴埋め問題ですね

さて
整数ABCDEF に6をかけると
整数DEFABC になるという問題

普通に解くなら少しづつ試す感じになりますが
プログラムは力技で解いていきます。

6桁分の整数を全部条件に当てはめて解いてみます。

for i in range(100000,1000000):

そして
その変数 i を6桁のABCDEFと仮定して
それに6をかけてDEFABCになれば
正解が導き出せるわけです。

数値文字列にして、インデックスで各桁の数値を
変数a,b,c,d,e,fに置き換えます。

あとは条件に当てはまるかを
if文で書くだけです。

ABCDEFを求めるプログラムはこうなりました。

for i in range(100000,1000000):
    x =str(i)
    a,b,c,d,e,f = x[0],x[1],x[2],x[3],x[4],x[5]
    if i*6==int(d+e+f+a+b+c):
        print(x)
        break

DEFは末尾3桁をとれば良いですね。

プログラムで解く際には
試行回数が少ない方が効率が良いので
いかに試行回数を減らすことができるかも
ポイントになりますが

今回は力技でした。


はいどーもー
乙pyです。

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

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

皆さん

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

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

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


動画解説はこちら


初めの問題は
有名中学の入試問題.027


これは初学者の方々には難しいかもしれませんが
順列の問題です。

4つの異なる数字1 ,3 , [ ] ,9
この中から3つの数字を取り出して並べてできる
3桁の整数

これは4P3で24通りあるんですね。

この順列の求め方は実は
pythonだと非常に簡単に出来るんです。

まずはitertoolsをインポートします。
import itertools

このitertoolsを用いると
組み合わせや順列の結果を全部計算してくれます。

さてこの問題の場合は
4つの数値のうち、3つは固定されています。

あとは残る数値を変化させるようにして
試行していけば良いわけです。

なので試行する数値をリストに格納して
for文を書くということになります。

for x in [0,2,4,5,6,7,8]:


さて、順列の方ですが
itertools.permutations(リスト, 個数)
で作ることができます。

なのでfor文で送られる数値を使って
順列の元になる4つの数値を変数に格納します。

あとはこれを用いて順列を作ります。

次に
このライブラリを使って求められるものは
順列の結果が24個入ったリストが帰ってきます。

これはそのままでは3桁の整数になっていないので
この順列24個を3桁の数値に直します。

数値を文字にして連結して
また数値に戻すで3桁の数値にできます。

それを24回やって、一時的にリストに格納します。

問題の条件は平均が555ということなので
このリストに格納した3桁の整数を全部足しあわせたのを
個数24で割ってあげます。

この平均が555であれば
答えということになります。

プログラムはこうなりました。

for x in [0,2,4,5,6,7,8]:
    seq = (1,3,9,x)
    lis = []
    for i in list(itertools.permutations(seq,3)):
        s = int(''.join([str(i[0]),str(i[1]),str(i[2])]))
        lis.append(s)
    if sum(lis)//len(lis) == 555:
        print(x)
        break


順列、文字列操作、数値変換、平均を求めるなど
プログラムでの基本的な操作が
色々と組み合わさるので
プログラミング学習には良い問題ですね

お次は

有名中学の入試問題.025

問題が細かいですが
4桁の整数で条件に合うものが何個有るかを求めるという問題です。

ただし
100の位は0で固定なので
試行するのは千の位、10の位、1の位に絞られます。

次の条件は
10と1の位がひっくり返ってもそれぞれ
7で割れるというものです。

これは数字を文字に置き換えてあげることで
解くことができます。

4桁の整数と
その10の位と1の位がひっくり返ったものの
両方が7で割り切れれば条件に合致します。

という風にして、試行した分の結果を
リストに格納して、その個数が
回答になります。

プログラムだとこうなりました。

r = []
for x in range(1,10): # 1000の位
    for y in range(10): # 10の位
        for z in range(10): # 1の位
            a = '{x}0{y}{z}'.format(x=x,y=y,z=z)
            b = '{x}0{z}{y}'.format(x=x,y=y,z=z)
            if int(a)%7==0 and int(b)%7==0:
                r.append((a,b))
print(len(r))

文字列と数値の使い方は
プログラミングの基本のため
こういった問題を解くことで
プログラミングの基本が身について行くと思います。



はいどーもー
乙pyです。

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

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

皆さん

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

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


動画解説はこちら


 


まずはじめの問題は
有名中学の入試問題.002

これの解き方は非常に簡単です。

4つの整数のうち
基準になるのは a で
求める答えも a
a と他の整数b,c,dとの関係はそれぞれ

b = a + 1
c = b + 1
d = c + 1
と1つづつ増えています。

なのでaを基準にして全て変数に置き換えます。

aは基準の数値なので
試行する数値にするため for文の対象にします。

求める答えの条件は
a * b + b * c + c * d + d * a が2400ということなので
この条件に合致した場合に表示させるだけです。

プログラムはこのようになりました。
 for a in range(30):
    b=a+1
    c=b+1
    d=c+1
    if a*b+b*c+c*d+d*a==2400:
        print(a)
        break

非常に簡単ですね

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

17で割ると3余り、13で割ると7余る
これが出力する際の条件1つ目ですね

もう一つは3桁の整数で最大

なのでまずは3桁の整数のなかで上記の条件に当てはまるものを
全て探します。

探し出す数値を x とすると

for x in range(100,1000):

で3桁の整数を試行できます。

あとは最大値を求めるやり方ですが
条件に当てはまるものが複数でるため

それをリストに格納しておいて
その格納された数値の中で一番大きいものを求めます。

プログラムは
result = []
for x in range(100,1000):
    if x%17==3 and x%13==7:
        result.append(x)
print(max(result))

このようになりますね。
プログラミング初学者の方々には
こういった問題を解くのは非常に勉強になると
思いました。

引き続き
プログラムで入試問題を
解いていきたいと思います。

夢屋まさる氏の「パンケーキ食べたい」スクリプトを作ってみた

どーもー乙pyです。

非常に実用性のないプログラムを作成しました。

夢屋まさる氏のネタ

「パンケーキ食べたい」
を連呼するだけのGIF画像を生成するプログラムです。

使い方は簡単、ソースをコピーして
wish_eat_pancake関数を呼び出すだけ。

一応windowsとmacでフォントの場所が違うので
そこだけ指定が必要ですが・・・

ちょっとした説明を動画に




ソースを貼っておきますね。
In [7]:
from PIL import Image, ImageDraw, ImageFont

pancake_size = 12
img_size  = (320, 180)
img_base_color = (0, 0, 0)

# windows
# font_place = "C:\Windows\Fonts\meiryob.ttc"

# Mac 
font_place = '/System/Library/Fonts/AquaKana.ttc'

def pancake(images):
    for i in range(20):
        img =  Image.new('RGB',img_size, img_base_color)
        draw = ImageDraw.Draw(img)
        font = ImageFont.truetype(font_place, pancake_size+i)
        draw.text((10, 10), '\nパンケーキ食べたい!'  , 
                  fill=(255, 200 - i*4, 0), font=font)
        images.append(img)
    return images

def wish_eat_pancake(texts,gif_name):
    images = []
    for draw_text in texts:
        draw_text = '\n' + draw_text
        for c in range(3):
            images = pancake(images)
        for i in range(20):
            img =  Image.new('RGB',img_size, img_base_color)
            draw = ImageDraw.Draw(img)    
            if len(draw_text)>10:
                if len(draw_text)>=30:
                    draw_text = draw_text[0:30]
                draw_text = ''.join([ t+'\n' if e%10==0 and e>0 
                                     else t for e,t in enumerate(draw_text)])
            font_size = min(pancake_size + i , 29)
            font = ImageFont.truetype(font_place, font_size)
            draw.text((10, 10), draw_text , fill=(255, 200 - i*4, 0), font=font)
            images.append(img)
        
    images[0].save(gif_name ,save_all=True, 
                   append_images=images[1:], 
                   optimize=False, duration=16*len(texts), loop=0)
In []:
# フォントの場所を指定(font_place)

# 使い方 引数にリスト型で文言を指定、第二引数にファイル名

wish_eat_pancake
(['新宿はキタナイ','押上もキタナイ','蒲田はジゴク'] , 'wisheatpancake.gif')
In []:
# 実行後にGIFファイルが作られる

!
ls -ls
total 1456
   8 -rw-r--r--  1 ss  staff    3125  2  2 16:37 WishEatPancake.ipynb
1448 -rw-r--r--  1 ss  staff  738944  2  2 16:39 wisheatpancake.gif

                       wisheatpancake

このページのトップヘ