知恵袋の色玉の確率の問題をPythonで解いてみた。

 知恵袋で見つけた色玉の確率の問題( (1), (2) )を Python で解いてみました。(^_^;

 黒玉3個、赤玉4個、白玉5個が入っている袋から玉を1個ずつ取り出し、取り出した玉を順に横一列に12個すべて並べる。ただし、袋から個々の玉が取り出される確率は等しいものとする。
(1) どの赤玉も隣り合わない確率を求めよ。
(2) どの赤玉も隣り合わないとき、どの黒玉も隣り合わない条件付き確率を求めよ。

 ただし、検索したら、元の問題は 2023 年度の東大の入試問題のようなので、それを参考にして修正しておきました。

 確率は同じものでも区別して考えるの基本ですが、Python で 12 個の順列で回すのは、こちらの環境ではきついので、数学的な解法を取り入れて、次式のように考えてみました。
 {同じものでも区別する順列}
  ={同じものを区別しない順列}×{同じものを区別するとき積の法則から掛ける数}
 ここで、{同じものを区別しない順列}は、ふつう、{同じものを含む順列}のことです。
 また、この問題では、{同じものを区別するとき積の法則から掛ける数}= 5!×4!×3! ですが、確率計算で分母子にこの数が掛けられていて相殺するので、プログラムでは同じものを含む順列をカウントして計算しました。
 ちなみに、itertools.permutations は同じものを含む順列でも遅いので、sympy.utilities.iterables.multiset_permutations を用いましたが、これは、Gemini に教えてもらいました。Anaconda で一括インストールしていたら、たぶん入っているはずです。(^_^;

● balls_pro_1.py

# coding: UTF-8
# balls_pro_1.py

from sympy.utilities.iterables import multiset_permutations
from time import time
from math import gcd

def main():
    tm = time() # Timer Start
    P = 'BBBRRRRWWWWW'  # B:黒, R:赤, W:白
    cnt = cnt1 = cnt2 = 0
    for p in multiset_permutations(P):  # 同じものを含む順列
        cnt+=1              # 同じものを含む順列の総数をカウント
        s = ''.join(p)
##        print(s)
        if 'RR' not in s:
            cnt1+=1         # どの赤玉も隣り合わない場合の数をカウント
            if 'BB' not in s:
                cnt2+=1     # どの赤玉も隣り合わないとき、どの黒玉も隣り合わない場合の数をカウント

    g1 = gcd(cnt1, cnt)
    g2 = gcd(cnt2, cnt1)
    print(f'(1) {cnt1}/{cnt} = {cnt1//g1}/{cnt//g1}')
    print(f'(2) {cnt2}/{cnt1} = {cnt2//g2}/{cnt1//g2}')
    print(f"Runtime : {time()-tm:.3f} [sec]") # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

(1) 7056/27720 = 14/55
(2) 4326/7056 = 103/168
Runtime : 0.477 [sec]

※参考URL
Google Gemini
Iterables - SymPy 1.14.0 documentation
東京大学 理系 2023年度 第2問 解説 | なかけんの数学ノート
知恵袋の色玉の確率の問題をJavaで解いてみた。 - rscのブログ
知恵袋の色玉の確率の問題をJavaで解いてみた。(2) - rscのブログ
知恵袋で見つけた赤玉と白玉の組分けの問題をPythonで解いてみた。 - rscのブログ

シフトの割当て方の組合せの問題をPythonで解いてみた。

 知恵袋で見つけたシフトの割当て方の組合せの問題をPythonで解いてみました。(^_^;

 ある店でアルバイトをしている。A~Dの4人の専門学生とE,Fの2人の大学生は、午前、午後、夜間の3つの時間帯に分かれており、それぞれの時間帯のシフトに、A~Fのうち、1人以上が割当てられている。専門学生と大学生が同じ時間帯のシフトとならないようにするとき、シフトの割当て方は全部で何通りか。
 ただし、A~F全員がその日のシフトに、1回だけ割り当てられるものとする。
1. 24通り 2. 32通り 3. 40通り 4. 48通り 5. 56通り

 各人に、午前'A'、午後'P'、夜間'N'を割り当てて、{a,b,c,d,e,f}={'A','P','N'} の直積で回して、条件に合わないものをスキップしてカウントしました。表示は、xLookUps() 関数で、それぞれの時間帯別に集めてみました。

● shiftSchedule1.py

# coding: UTF-8
# shiftSchedule1.py

import itertools
from time import time

# リスト la の要素 x に対応するリスト lb の要素をリストですべて返す
def xLookUps(x, la, lb=None):   # lb を省略するとインデックスのリストを返す
    if lb is None: lb = range(len(la))
    return [b for a, b in zip(la, lb) if x == a]

def main():
    tm = time() # Timer Start
    N = 'ABCDEF'    # 人名
    P = 'APN'       # 午前,午後,夜間
    count = 0
    for p in itertools.product(P, repeat=6):
        a,b,c,d,e,f = p
        if p.count('A')*p.count('P')*p.count('N')==0: continue  # それぞれの時間帯に1人以上割当て
        if e in (a,b,c,d): continue     # 専門学生と大学生が同じ時間帯にならない
        if f in (a,b,c,d): continue     #  〃
        pass # チェックを潜り抜けたものだけをカウントして表示
        count += 1
##        print(','.join(p))
        ap = ''.join(xLookUps('A', p, N))   # 午前のシフトの人
        pp = ''.join(xLookUps('P', p, N))   # 午後のシフトの人
        np = ''.join(xLookUps('N', p, N))   # 夜間のシフトの人
        print(f"[{ap}|{pp}|{np}] ",end='' if count%6 else '\n')

    print(f"{count}通り")
    print(f"Runtime : {time()-tm:.3f} [sec]") # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

[ABCD|E|F] [ABCD|F|E] [ABC|D|EF] [ABC|EF|D] [ABD|C|EF] [AB|CD|EF] 
[ABD|EF|C] [AB|EF|CD] [ACD|B|EF] [AC|BD|EF] [AD|BC|EF] [A|BCD|EF] 
[ACD|EF|B] [AC|EF|BD] [AD|EF|BC] [A|EF|BCD] [BCD|A|EF] [BC|AD|EF] 
[BD|AC|EF] [B|ACD|EF] [CD|AB|EF] [C|ABD|EF] [D|ABC|EF] [E|ABCD|F] 
[F|ABCD|E] [EF|ABC|D] [EF|ABD|C] [EF|AB|CD] [EF|ACD|B] [EF|AC|BD] 
[EF|AD|BC] [EF|A|BCD] [BCD|EF|A] [BC|EF|AD] [BD|EF|AC] [B|EF|ACD] 
[EF|BCD|A] [EF|BC|AD] [EF|BD|AC] [EF|B|ACD] [CD|EF|AB] [C|EF|ABD] 
[EF|CD|AB] [EF|C|ABD] [D|EF|ABC] [EF|D|ABC] [E|F|ABCD] [F|E|ABCD] 
48通り
Runtime : 0.003 [sec]

※参考URL
組分け問題:異なるn個のものを異なるk組に分ける場合の数(0個の組なし) - rscのブログ
知恵袋で見つけた赤玉と白玉の組分けの問題をPythonで解いてみた。 - rscのブログ
知恵袋の判断推理の色玉の組分け問題をPythonで解いてみた。 - rscのブログ

Geminiが作った座席の位置関係の問題をPythonで解いてみた。

 Gemini が作った座席の位置関係の問題を Python で解いてみました。(^_^;

【問題】5人の座席位置
 A、B、C、D、Eの5人が、横一列に並んだ5つの座席(左から1番、2番、3番、4番、5番)に1人ずつ座っています。
 5人の座席の位置について、次のア~エのことが分かっているとき、確実にいえることとして正しいものを1つ選んでください。
【条件】
ア: Aの座席は、Cの座席よりも左側にある。
イ: Bの座席とDの座席は隣り合っている。
ウ: Eは端(1番または5番)の座席に座っている。
エ: 4番の座席に座っているのは、AでもBでもない。
【選択肢】
1.Eが5番のとき、Dは必ず3番である。
2.Aが3番のとき、BとDの座席番号は必ず3未満である。
3.Cは5番の座席に座っている。
4.Dは3番の座席に座っている。
5.Eは1番の座席に座っている。

 問題は、Geminiに作ってもらったのを少し改良しました。はじめ、「南向きに横一列に並んだ」となっていて、こちらから見た左右が逆になっているとのことで、条件アが「Aの座席は、Cの座席よりも右側にある。」となっていました。Gemini 曰く、ひっかけ問題のつもりだったそうですが、面倒なので変更しました。(^_^;
 それから、選択肢は、はじめ1と2も、「X は N 番の座席に座っている。」形式でしたが、プログラムを実行した結果、答えがなかったので、Gemini が自分で変更しました。
 Gemini にもプログラムを作ってもらいましたが、こちらの環境で実行した結果は、私のプログラムの結果と一致しました。ところが、Gemini が LLM で推論した結果が、選択肢1で、それに合わせてプログラムの実行結果をごまかし報告(ハルシネーション)しました。Gemini は、はじめに、問題を自分で解かせて、次に、Pythonで解いて検証させた結果が異なる( LLM の推論が間違っていて、プログラムの結果が正しい)場合、自分の推論結果に合わせて、ごまかし報告をする傾向があります。(^_^;
 ちなみに、getAns() 関数を zip() を使って作り直しました。(^_^;

● SeatGem1.py

# coding: UTF-8
# SeatGem1.py

import itertools
from time import time

# 論理包含Imp
def Imp(p,q):
    return not p or q

# 確実にいえる選択肢を得る
def getAns(ch, lb='12345'):
    return ','.join([l for c,l in zip(ch,lb) if c])

def main():
    tm = time() # Timer Start
    choices = [True]*5
    P = 'ABCDE'
    for p in itertools.permutations(P):
        a,b,c,d,e = [p.index(x)+1 for x in P]   # A~Eの座席番号
##        print(f"{p} {[a,b,c,d,e]}"); exit()
        if not (a < c)         : continue      # 条件ア
        if not (abs(b-d) == 1) : continue      # 条件イ
        if not (e     in (1,5)): continue      # 条件ウ
        if not (4 not in (a,b)): continue      # 条件エ
        pass # チェックを潜り抜けたものを表示
        print(','.join(p))
        pass # 選択肢のチェック
        choices[0] &= Imp(e == 5, d == 3)
        choices[1] &= Imp(a == 3, b < 3 and d < 3)
        choices[2] &= (c == 5)
        choices[3] &= (d == 3)
        choices[4] &= (e == 1)

    print(f'∴{getAns(choices)}')
    print(f"Runtime : {time()-tm:.3f} [sec]") # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

A,B,D,C,E
A,C,B,D,E
A,D,B,C,E
B,D,A,C,E
D,B,A,C,E
E,A,B,D,C
E,A,C,D,B
∴2
Runtime : 0.001 [sec]

※参考URL
Google Gemini
質問の座席の問題をPythonで解いてみた。 - rscのブログ
知恵袋の判断推理の座席の位置関係の問題をPythonで解いてみた。 - rscのブログ
判断推理の座席の位置関係の問題をPythonで解いてみた。 - rscのブログ
判断推理の座席の位置関係の問題をPythonで解いてみた。(2) - rscのブログ
判断推理の座席の位置関係の問題をPythonで解いてみた。(3) - rscのブログ

Best Music Mix 2021 - Shuffle Music Video HD - Melbourne Bounce

Best Music Mix 2021 - Shuffle Music Video HD - Melbourne Bounce Music Mix 2021

 ここに動画をはる予定でしたが、「動画を再生できません 他のウェブサイトでの再生は、動画の所有者によって無効にされています」とのことで、動画をはるのをやめました。

 曲のタイトル一覧を作ってみました。ほとんど再生数が億越えの曲ばかりです。初め、Geminiに頼んでみましたが、うまくいかなかったので、自分で作りました。やりかたは、文字起こしのとこの比較的長いフレーズを検索して出て来た曲を聞いて確認していきました。3曲目のは、長いのがなかったので、「all i need is / you're cute / my behavior / this will make him / i already oh」と断片を繋ぎ合わせて検索しました。文字起こしで、「i already oh」となっていたところは、「i already know」が正解でした。(^_^;

Alan Walker - Faded
Timbaland ft. OneRepublic - Apologize
SAINt JHN - Roses (Imanbek Remix)
David Guetta ft. Sia - Titanium
Camila Cabello - Havana ft. Young Thug
Twenty One Pilots - Heathens
Europe - The Final Countdown
Tove Lo - Habits (Stay High)
Alan Walker - Faded
Mike Posner - Please Don't Go
NF - Let You Down
DJ Snake ft. Justin Bieber - Let Me Love You
5 Seconds of Summer - Youngblood
Naughty Boy ft. Sam Smith - La La La
3 Doors Down - Here Without You
No Doubt - Don't Speak
Imagine Dragons - Radioactive
Maneskin - Beggin'
Flo Rida - Good Feeling
MIKA - Relax, Take It Easy
Surf Mesa - ily (i love you baby) ft. Emilee

人形の持ち主の論理パズルをPythonで解いてみた

 人形の持ち主の論理パズルをPythonで解いてみました。以前、Javaで書いたプログラムをPythonで書き直してみました。(^_^;

 P、Q、Rの3人が人形を2つずつ持っている。それらの6つの人形は(A~Fとする)は目の色がそれぞれ異なり(黒、茶、青、緑、橙、灰)、髪の色もそれぞれ異なっている(茶、橙、金、銀、黒、赤)。
 1.ある者はAと黒い目の人形の2つを持っていて、別の者はBと茶髪の人形の2つを持っている。また、さらに別の者は橙色の髪の人形(Eではない)と茶色の目の人形の2つを持っている。
 2.Cの髪は金髪で、Qがこの人形を持っている。
 3.青い目の人形の髪は銀色で、この人形を持っているのはR。
 4.ある者はDと緑の目の人形の2つを持っている。
 5.ある者は橙色の目の人形と黒髪の人形の2つを持っている。
 さて、6つの人形それぞれの目の色、髪の色、持ち主は?

 初め、枝刈りの条件チェックは、eye ループに書きましたが、高速化のために前に移せるものは出来るだけ前に移しました。
 Java から翻訳するとき、次の関数を使うことも考えましたが、「if not 条件: continue」で直感的にわかりやすく書き直してみました。

# リスト la の要素 x とリスト lb の要素 y にそれぞれ対応するリスト lc の要素が同じものか調べる
def isSame(lc, la, x, lb, y):
    z = getXof(lc, la, x)
    return z == getXof(lc, lb, y) if z is not None else False

 ちなみに、たとえば、getXof(DOLL, ownr, ~) のように、対応するものが2つあって関数になっていない場合は使えないことに注意しましょう。(^_^;

● DollPuzzle1.py

# coding: UTF-8
# DollPuzzle1.py

import itertools
from time import time

# 要素 x がリスト la の何番目にあるか(インデックス)を調べる
def getPos(la, x):
    return la.index(x) if x in la else -1

# リスト lb の要素 y に対応するリスト la の要素 x を求める
def getXof(la, lb, y):
    n = getPos(lb, y)
    return la[n] if n >= 0 else None

def main():
    DOLL = "ABCDEF"     # 人形(固定)
    OWNR = "PPQQRR"     # 持ち主
    EYES = "黒茶青緑橙灰"     # 目の色
    HAIR = "茶橙金銀黒赤"     # 髪の色

    tm = time() # Timer Start
    for ownr in set(itertools.permutations(OWNR)):  # 同じものを含む順列
        if not getXof(ownr, DOLL, 'C') == 'Q': continue # 条件2
        for hair in itertools.permutations(HAIR):
            if not getXof(ownr, DOLL, 'B') == getXof(ownr, hair, '茶'): continue # 条件1
            if not getXof(DOLL, hair, '茶') != 'B': continue                     # 条件1
            if not getXof(ownr, DOLL, 'A') != getXof(ownr, hair, '茶'): continue # 条件1
            if not getXof(ownr, DOLL, 'A') != getXof(ownr, hair, '橙'): continue # 条件1
            if not getXof(ownr, DOLL, 'B') != getXof(ownr, hair, '橙'): continue # 条件1
            if not getXof(DOLL, hair, '橙') != 'E': continue                     # 条件1
            if not getXof(DOLL, hair, '金') == 'C': continue                     # 条件2
            for eye in itertools.permutations(EYES):
                if not getXof(ownr, DOLL, 'A') == getXof(ownr, eye,  '黒'): continue # 条件1
                if not getXof(DOLL, eye,  '黒') != 'A': continue                     # 条件1
                if not getXof(ownr, hair, '橙') == getXof(ownr, eye,  '茶'): continue # 条件1
                if not getXof(DOLL, hair, '橙') != getXof(DOLL, eye,  '茶'): continue # 条件1
                if not getXof(ownr, DOLL, 'B') != getXof(ownr, eye,  '黒'): continue # 条件1
                if not getXof(DOLL, eye,  '青') == getXof(DOLL, hair, '銀'): continue # 条件3
                if not getXof(ownr, eye,  '青') == 'R': continue                     # 条件3
                if not getXof(ownr, DOLL, 'D') == getXof(ownr, eye,  '緑'): continue # 条件4
                if not getXof(DOLL, eye,  '緑') != 'D': continue                     # 条件4
                if not getXof(ownr, eye,  '橙') == getXof(ownr, hair, '黒'): continue # 条件5
                if not getXof(DOLL, eye,  '橙') != getXof(DOLL, hair, '黒'): continue # 条件5
                pass # チェックを潜り抜けたものを表示
                print(f"D: {DOLL}")
                print(f"O: {''.join(ownr)}")
                print(f"E: {''.join(eye )}")
                print(f"H: {''.join(hair)}")
                print()

    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

●実行結果

D: ABCDEF
O: RPQPRQ
E: 青緑茶橙黒灰
H: 銀黒金茶赤橙

Runtime : 0.338 [sec]

P.S.
 ちなみに、Excel の XLOOKUP() 関数もどきの lookUp() 関数を使って書き直すと次のようになります。getPos() 関数と getXof() 関数を一つにまとめて、XLOOKUP() 関数の引数の並び順に合わせました。getXof() 関数とは、引数の並びが逆になっているのに注意してください。実行結果は同じなので省略します。

● DollPuzzle1a.py

# coding: UTF-8
# DollPuzzle1a.py

import itertools
from time import time

# リスト la の要素 x に対応するリスト lb の要素を一つ返す
def lookUp(x,la,lb):
    n = la.index(x) if x in la else -1
    return lb[n] if n >= 0 else None

def main():
    DOLL = "ABCDEF"     # 人形(固定)
    OWNR = "PPQQRR"     # 持ち主
    EYES = "黒茶青緑橙灰"     # 目の色
    HAIR = "茶橙金銀黒赤"     # 髪の色

    tm = time() # Timer Start
    for ownr in set(itertools.permutations(OWNR)):  # 同じものを含む順列
        if not lookUp('C', DOLL, ownr) == 'Q': continue # 条件2
        for hair in itertools.permutations(HAIR):
            if not lookUp('B', DOLL, ownr) == lookUp('茶', hair, ownr): continue # 条件1
            if not lookUp('茶', hair, DOLL) != 'B': continue                     # 条件1
            if not lookUp('A', DOLL, ownr) != lookUp('茶', hair, ownr): continue # 条件1
            if not lookUp('A', DOLL, ownr) != lookUp('橙', hair, ownr): continue # 条件1
            if not lookUp('B', DOLL, ownr) != lookUp('橙', hair, ownr): continue # 条件1
            if not lookUp('橙', hair, DOLL) != 'E': continue                     # 条件1
            if not lookUp('金', hair, DOLL) == 'C': continue                     # 条件2
            for eye in itertools.permutations(EYES):
                if not lookUp('A', DOLL, ownr) == lookUp('黒', eye, ownr ): continue # 条件1
                if not lookUp('黒', eye,  DOLL) != 'A': continue                     # 条件1
                if not lookUp('橙', hair, ownr) == lookUp('茶', eye,  ownr): continue # 条件1
                if not lookUp('橙', hair, DOLL) != lookUp('茶', eye,  DOLL): continue # 条件1
                if not lookUp('B', DOLL, ownr) != lookUp('黒', eye,  ownr): continue # 条件1
                if not lookUp('青', eye,  DOLL) == lookUp('銀', hair, DOLL): continue # 条件3
                if not lookUp('青', eye,  ownr) == 'R': continue                     # 条件3
                if not lookUp('D', DOLL, ownr) == lookUp('緑', eye,  ownr): continue # 条件4
                if not lookUp('緑', eye,  DOLL) != 'D': continue                     # 条件4
                if not lookUp('橙', eye,  ownr) == lookUp('黒', hair, ownr): continue # 条件5
                if not lookUp('橙', eye,  DOLL) != lookUp('黒', hair, DOLL): continue # 条件5
                pass # チェックを潜り抜けたものを表示
                print(f"D: {DOLL}")
                print(f"O: {''.join(ownr)}")
                print(f"E: {''.join(eye )}")
                print(f"H: {''.join(hair)}")
                print()

    print("Runtime : %.3f [sec]"%(time()-tm))   # Timer Stop & Disp

if __name__ == '__main__':
    main()

※参考URL
人形の持ち主の論理パズルをJavaで解いてみた - rscのブログ