1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

QuizKnockさんの「出題のない部屋」の正誤判定を作成してみた話

Posted at

イントロ

先日Quizknockさんの「出題のない部屋」を眺めていたら,どうやら正誤判定をプログラミングで判定していたようだ.今回はその判定プログラムを,pythonとQiitaの練習がてら作成してみたいと思う.

この記事はネタバレ満載なので,記事を見る前にぜひ以下の動画を見ていただきたい.

  • 本編
  • 解説編

問題

動画本編で出されていた問題は以下の通り.

以下に示すような3×3のボックスと,9つの文字がある.

boxempty.png

この文字たちをボックスの各マスに当てはめた時,縦(もしくは横,斜め)一列の文字を使って漢字を作れることがある.

例えば,一,木,イ が一列にそろっていれば 体 が作れる.

すべてのマスに文字を埋めたうえで,縦横斜め全ての列で同時に漢字を成立させると正解となる.

正解例

後で動作確認を行うために,ひとまず正解例を明らかにしておこう.

正解例
心 目 木
音 一 口
イ 八 十

縦一列は左から,億,具,枯
横一列は上から,想,暗,休
斜めは,体(/),志(\)

という風になって完成である.
もちろん,この組み合わせを回転させても,縦と横の列を反転させても正解.

設計と実装

では,ルールがわかったところで,実際にこのクイズの正誤判定を設計してみよう.

入力:
各文字の並び

処理:
文字の並びに対して成立漢字判定,および正誤判定.

出力:
成立している漢字を表示,正解不正解の表示.

(まあすでに動画を見ていると思うのでわかると思うが)一応補足する.
実際は箱に文字が書いてあり,その箱を棚に並べ,早押しボタンを押すことで回答とする.早押しボタンが押された段階で(おそらく裏側では)文字の並びを入力し,プログラムを実行する.すると,テレビ画面に,成立している漢字を連想するイラストを順に表示,最後に音で「正解」もしくは「不正解」を示していた.

今回は成立漢字判定も正誤判定も文字で行うこととする.

では実装してみよう.

hakonoheya.py
import hakonoheyafunk

print('1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 →')

a,b,c,d,e,f,g,h,i = input().split()

list = [[int(a),int(b),int(c)], [int(d),int(e),int(f)], [int(g),int(h),int(i)]]

hakonoheyafunk.list_all_explore(list)

名前が「ハコノヘヤ」になっているのはご容赦いただきたい.(出題のない部屋はすでにシリーズ化されていて,「シュツダイノナイヘヤ」という名前では区別できなくなるんだもん)

ここでやりたいのは,文字の並びを入力してもらい,それをlistに代入する.そして,後述するlist_all_explore関数でlistに対し正誤判定を行うということだ.このプログラムを実行すると,以下が表示される.

PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 →

入力する際は,各文字に対応している番号を1文字ずつスペース区切りで入力していくのだが,実際の並び方とターミナルへの入力の仕方,およびlist変数の対応は以下のとおりである.

PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 → A B C D E F G H I

boxtaiou.png

具体例を示すと,

PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 → 9 8 7 6 5 4 3 2 1

と入力したとき,以下の状態と同じであることを示す.

boxexp.png

続いて,list変数をもとに正誤判定するlist_all_explore関数のファイルを見てみよう.

hakonoheyafunc.py

import time

def list_all_explore(list):
    number = 8;
    #縦の調査
    for i in range(0,3):
        ex_list = sorted([list[0][i],list[1][i],list[2][i]])
        number = list_result(ex_list,number)
    #横斜めも同様,

    judge(number)

def list_result(list,number): #listに対して漢字が成立しているか判定
#後述

def judge(i): #正誤判定
#後述

list_all_exploreでは,listの縦,横,斜めの各列において,対象の要素をex_listに取り出してくることで,ex_listの組み合わせで漢字が成立しているかどうかを調べる.では実際にそれを実装しようではないか.

ん?

ここで一つ悩みが生じる.

ex_listの数字の並びの組み合わせ6通りあるやん…

そうなのだ,例えば,1:一,5:イ,7:木を用いて「体」という漢字を作るとき,ex_listの中身は,

1 5 7,1 7 5,5 1 7 ,5 7 1,7 1 5,7 5 1

という6通りの並び方が存在しうる.当然,いずれの組み合わせだったとしても「漢字が成立している」と判定しなければならない.ほかの漢字も然り.これでは,条件分岐を書くのが大変めんどくさくなる.さてどうしたものか.論理和で全通り書いてしまおうか.うーん.

あっ,

拾ってきた要素を小さい順に並べてみればよくね?

そう,こうすることで,

1 5 7,1 7 5,5 1 7 ,5 7 1,7 1 5,7 5 1

のいずれが来たとしても,「1 5 7」と一意に表すことができるではないか.
6通りだった並びが1通りに絞れるではないか!
ということで,私は高揚感にあふれながら,sorted関数を用いて3つの数字を小さい順に並べ替えた.それをex_listとし,漢字の成立判定をするlist_resultに渡している.

ではそのlist_resultを見てみよう.

hakonoheyafunk.py
def list_result(list,number):
    if(list == [4,5,6]):
        print('') 
        time.sleep(2)
        number = number - 1;
        return number;
#以下,「具」「枯」「想」「暗」「休」「体」「志」について同様.
    else:
    return number;

先ほどのex_listに対し,漢字が成立する組み合わせであれば,その漢字を出力する.

time.sleepは,動画本編と同じように,一気に表示させるのではなく,一つずつ(絵を)表示している状態を再現したかったため.

また,numberは最後の正誤判定に用いる.
numberはlist_all_exploreを見てもらうとわかるように最初8に初期化されている.漢字が成立するごとにnumberは1ずつ減少する.(成立していなければnumberをそのまま返す.これを忘れたがために30分無駄にしたのは内緒の話).最終的に漢字がすべての列で成立すればnumberは0,1つでも成立していなければ1以上の数字となる.すべての列で漢字判定が終わった後,numberを以下のjudgeに渡す.

hakonoheyafunk.py
def judge(number):
    if (number==0) : print('正解')
    else : print('不正解')

とくに説明は不要であろう.numberが0なら「正解」,そうでなければ「不正解」を表示するだけだ.

実行

ということで,実際に実行してみようと思う.

  • 漢字が1つも成立しておらず不正解の場合

以下を入力とする.
ex1q.jpg

PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 →
1 5 9 3 4 7 2 8 6
不正解

exp1.png
正しく動作できている.

  • 漢字が成立しているが不正解の場合
    以下を入力とする.
    ex2q.jpg
PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 →
1 2 4 3 6 7 5 8 9
暗
想
休
志
億
不正解

ex2.png

正しく動作できている.狙ってないが,たまたま右側に偏った.

  • 正解の場合

以下を入力とする.
ex3q.png

PS C:\Python\hakonoheya> python hakonoheya.py
1:一 2:口 3:目 4:音 5:イ 6:心 7:木 8:八 9:十 →
6 3 7 4 1 2 5 8 9
億
具
枯
想
暗
休
志
体
正解

ex3.png

正しく動作できている.

という風に実行することができた.
ただし,不正な入力に対する対処などは行っていない.

終わりに

Quizknock面白いんでぜひともチャンネル登録して観ていただきたい.
(ちなみに案件でも回し者でもございません.)

ソースリスト

最後に,省略してしまったhakonoheyafunk.pyの全文を上げておく.

hakonoheyafunk.py
import time

def list_all_explore(list):
    number = 8;
    #縦の調査
    for i in range(0,3):
        ex_list = sorted([list[0][i],list[1][i],list[2][i]])
        number = list_result(ex_list,number)

    #横の調査
    for i in range(0,3):
        ex_list = sorted([list[i][0],list[i][1],list[i][2]])
        number = list_result(ex_list,number)

    #左斜めの調査
    ex_list = sorted([list[0][0],list[1][1],list[2][2]])
    number = list_result(ex_list,number)

    #右斜めの調査
    ex_list = sorted([list[2][0],list[1][1],list[0][2]])
    number = list_result(ex_list,number)

    #正誤判定
    judge(number)

def list_result(list,number):
    if(list == [4,5,6]):
        print('') 
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [3,6,7]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [1,5,7]):
        print('')   
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [1,2,4]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [5,8,9]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [1,3,8]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [1,6,9]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    if(list == [2,7,9]):
        print('')
        time.sleep(2)
        number = number - 1;
        return number;
    else:
        return number;

def judge(i):
    if (i==0) : print('正解')
    else : print('不正解')
1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?