0
0

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.

【Python】カタカナ単語リストを使ってしりとりプログラムを作る

Last updated at Posted at 2023-04-15

指定した文字から始まり、「ン」で終わる単語で終了するしりとりの結果を表示するプログラムを実装していきます

今回、ルールは以下の通りとします

  1. 同じ単語を使ってはいけない
  2. 「ー(長音)」で終わる単語は長音を無視する
  3. 清音・濁音・半濁音は別の文字として扱う
  4. 小文字で終わる単語は大文字に変換して扱う(ャ→ヤ等)
  5. 指定した開始文字でしりとりが終了しない場合はその旨を表示する

※今回のしりとりでは、tango.txt というテキストファイルを使用しています
tango.txtのダウンロードはこちら

実装の概要

準備 tango.txtの中身をリストに変換しておく

  1. まず、最初の文字をカタカナで入力します
  2. tango.txtの中から、最初の文字が一致する単語を探します
  3. tango.txtの中の単語でしりとりをします
  4. 「ン」で終わる単語を見つけたらしりとりを終了します
  5. 入力したカタカナから始まり、「ン」で終わるしりとりの経過を出力します

それでは実装してみましょう

import copy
import re #正規表現のコンパイル

step = [] #しりとりの経過を入れるリスト

f = open('tango.txt', 'r') #tango.txtの読み込み
data = f.readlines() #リスト"data"にtango.txtの中身を格納
l1 = len(data) #"data"に含まれる要素の数をl1に代入

def trans(strj): #小文字を大文字に変換する関数
    moji = str.maketrans("ァィゥェォャッュョ", "アイウエオヤユツヨ")
    return strj.translate(moji)

def shiritori(start, i, j):
  while i<l1:
    #↓ もしdata内の単語の頭文字がstartと一致し、リストstepに含まれないとき
    if start == data[i][0] and data[i] not in step: 
       l2 = len(data[i]) - 1 #l2に単語の文字数を代入(-1は改行文字分)
       step.append(data[i]) #単語を"step"に追加
       j = i #(最後に)追加した要素のindex
       #print(step) ← しりとりの経過を見たいときに表示
       end = data[i][l2-1] #endに単語の最後の文字を代入
       if end == '': #'ン'で終わるときは1を返す
         return 1
       if end == '': #'ー'で終わるときは1つ前の文字をendに代入
         end = data[i][l2-2]
       if end in 'ァィゥェォャュッョ': #小文字で終わるときは変換の関数を呼び出して代入
         end = trans(end)
       start = end #最後の文字を最初の文字とする
       i = 0 #リストを一から探索するので再初期化
    else:
      i = i + 1 #頭文字が入力と一致しないときは次の要素へ移るのでi++

  if len(step) == 0: #該当するものがなく、リストstepが空の時
    return 0 #終了して0を返す
  else:
    pre = step[len(step) - 1] #preはリストstepに追加した最後の要素

  del step[-1:] #最後の要素をリストから取り出す
  #print(step) ← しりとりの経過を見たいときに表示

  if len(step) != 0: #リストが空でないとき
    #↓ リストdataに含まれるリストstepの最後の要素と同じもののindex(何番目の要素か)をsに代入
    s = data.index(step[len(step)-1])
    #↓ 最後の文字, 最後に入れて棄却された要素の次の要素のindex, 現時点のリストstepの最後の要素のindex
    fl = shiritori(pre[0], j+1, s)
  else:
    #現時点でstepに要素がないので、sは0に設定している
    fl = shiritori(pre[0], j+1, 0)
  return fl #戻る

print("最初の文字(カタカナ)を入力してください")
s = str(input()) #頭文字にしたいカタカナを標準入力
katakana = re.compile(r'[\u30A1-\u30F4]+') #'[\u30A1-\u30F4]+'はカタカナの範囲

if not re.fullmatch(katakana, s) or len(s)>1: #入力がカタカナでない,または二文字以上のとき
  print("エラー:カタカナ一文字で入力してください")

else: 
  flag = shiritori(s, 0, 0) #'ン'で終わるときは1,それ以外は0が代入される
  
  if flag == 0:
    print("",s,"」から始まるしりとりは「 ン 」で終わりません")
  else:
    Step = ''.join(step) #リスト"step"を文字列に変換
    Step = Step.split() #.split()で改行文字を削除し,リスト化
    print(Step) #結果を出力

最初に必要なモジュールのインポート、次にtango.txtの中身をリストに変換をしています。リストstepは、しりとりの経過を入れるリストなので、挙動を確認したいときは表示させてみてください。

実行結果

最初の文字(カタカナ)を入力してください
ス
['スポーツカー', 'カバー', 'バックミラー', 'ラッシュアワー', 'ワイシャツ', 'ツール', 'ルール', 'ルーズ', 'ズボン']

今回は「ス」を最初の文字に設定したのでスポーツカーからしりとりを始め、ズボンで終わりました。
関数shiritoriの挙動が少し分かりづらいですが、どんな動きをしているかコメントを見ながら追ってもらえるといいかなと思います。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?