第160回【Python】五目並べ(斜め)、五目並べ
現在取り組んでいるのは、paiza ラーニング問題集「B ランクレベルアップメニュー」になります。
はじめに
猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。
Python をゼロから勉強してみよう、のコーナー 160 回目です。
事前準備の段階で満足してしまう人がいます。その人は、事前準備が 9 割 5 分くらいで、本番前にやり切った感が出てしまいます。ちょっとでも狂いが生じたらそれでパニックになって、以降、何もできなくなります。もっと気持ちにゆとりを持つように伝えるのですが、理解してくれません。
それでは、今日も頑張ってみようと思います。
今回取り組む内容について
以下は、前回までに取り組んだ問題とまったく同じなので、飛ばします。
コードは数書いてナンボとかカッコつけたこと書いてましたが、あまりにも多いので挫折しました。
STEP: 1 文字列の出力
五目並べ(斜め) (paizaランク C 相当)
5行5列の五目並べの盤面が与えられます。
盤面の各マスには、"O"か"X"か"."が書かれています。
“O"と"X"は、それぞれプレイヤーの記号を表します。
同じ記号が斜めに連続で5つ並んでいれば、その記号のプレイヤーが勝者となります。
勝者の記号を1行で表示してください。
勝者がいない場合は、引き分けとして、"D"を表示してください。
s_1
s_2
s_3
s_4
s_5
期待する出力
勝者の記号を1行で表示してください。
勝者がいない場合は、引き分けとして、"D"を表示してください。
すべてのテストケースにおいて、以下の条件をみたします。
・sの文字数は5文字
・sに含まれる文字は"O"か"X"か"."のいずれか
・勝者が2人になる盤面が、与えられることはありません。
入力例
XXOXO
OXOXX
.OXXO
OXOO.
XXXXX
出力例
D
横、縦ときたら、もちろん、斜め。5 行 5 列だと、斜めに 5 つ揃うパターンは 2 つしかない。
Python
s = [input() for _ in range(5)]
res = 'D'
stone = s[0][0]
pat = [True,False]
for cond in pat:
if cond:
j = 0
j_diff = 1
else:
j = 4
j_diff = -1
stone = s[0][j]
cnt = 1
for i in range(1,5):
j += j_diff
if stone != '.' and stone == s[i][j]:
cnt += 1
if cnt == 5:
res = stone
break
print(res)
VBA
Sub tic_tac_toe_4()
Dim s(4)
res = "D"
For i = 0 To 4
s(i) = Cells(i + 1, 1)
Next
pat = Array(True, False)
For Each con In pat
If con Then
j = 1
j_diff = 1
Else
j = 5
j_diff = -1
End If
stone = Mid(s(0), j, 1)
cnt = 1
For i = 1 To 4
j = j + j_diff
If stone <> "." And stone = Mid(s(i), j, 1) Then
cnt = cnt + 1
End If
If cnt = 5 Then
res = stone
Exit For
End If
Next
Next
Debug.Print res
End Sub
五目並べ (paizaランク B 相当)
5行5列の五目並べの盤面が与えられます。
盤面の各マスには、"O"か"X"か"."が書かれています。
“O"と"X"は、それぞれプレイヤーの記号を表します。
同じ記号が縦か横か斜めに連続で5つ並んでいれば、その記号のプレイヤーが勝者となります。
勝者の記号を1行で表示してください。
勝者がいない場合は、引き分けとして、"D"を表示してください。
s_1
s_2
s_3
s_4
s_5
期待する出力
勝者の記号を1行で表示してください。
勝者がいない場合は、引き分けとして、"D"を表示してください。
すべてのテストケースにおいて、以下の条件をみたします。
・sの文字数は5文字
・sに含まれる文字は"O"か"X"か"."のいずれか
・勝者が2人になる盤面が、与えられることはありません。
入力例
XXOXO
OXOXX
OOOOO
OXOX.
XOXXO
出力例
O
ここまでの集大成。全パターンについて考える。
Python
s = [input() for _ in range(5)]
res = 'D'
def row():
for i in range(5):
stone = s[i][0]
cnt = 1
for j in range(1,5):
if stone != '.' and stone == s[i][j]:
cnt += 1
if cnt == 5:
return stone
return res
def column():
for i in range(5):
stone = s[0][i]
cnt = 1
for j in range(1,5):
if stone != '.' and stone == s[j][i]:
cnt += 1
if cnt == 5:
return stone
return res
def diagonal():
pat = [True,False]
for cond in pat:
if cond:
j = 0
j_diff = 1
else:
j = 4
j_diff = -1
stone = s[0][j]
cnt = 1
for i in range(1,5):
j += j_diff
if stone != '.' and stone == s[i][j]:
cnt += 1
if cnt == 5:
return stone
return res
row = row()
column = column()
diagonal = diagonal()
if row != 'D':
print(row)
elif column != 'D':
print(column)
else:
print(diagonal)
VBA
Sub tic_tac_toe_9()
Dim s(4)
For i = 0 To 4
s(i) = Cells(i + 1, 1)
Next
setRow = row(s)
setColum = colum(s)
setDiagonal = diagonal(s)
If setRow <> "D" Then
Debug.Print setRow
ElseIf setColum <> "D" Then
Debug.Print setColum
Else
Debug.Print setDiagonal
End If
End Sub
Private Function row(s) As String
row = "D"
For i = 0 To 4
stone = Mid(s(i), 1, 1)
cnt = 1
For j = 2 To 5
If stone <> "." And stone = Mid(s(i), j, 1) Then
cnt = cnt + 1
End If
If cnt = 5 Then
row = stone
Exit Function
End If
Next
Next
End Function
Private Function colum(s) As String
colum = "D"
For i = 1 To 5
stone = Mid(s(0), i, 1)
cnt = 1
For j = 1 To 4
If stone <> "." And stone = Mid(s(j), i, 1) Then
cnt = cnt + 1
End If
If cnt = 5 Then
colum = stone
Exit Function
End If
Next
Next
End Function
Private Function diagonal(s) As String
diagonal = "D"
pat = Array(True, False)
For Each con In pat
If con Then
j = 1
j_diff = 1
Else
j = 5
j_diff = -1
End If
stone = Mid(s(0), j, 1)
cnt = 1
For i = 1 To 4
j = j + j_diff
If stone <> "." And stone = Mid(s(i), j, 1) Then
cnt = cnt + 1
End If
If cnt = 5 Then
diagonal = stone
Exit Function
End If
Next
Next
End Function
最後に
本章の集大成的な? 最初は、横でも縦でも斜めでも、一旦 5 つを配列に入れてしまって、それと「OOOOO」と「XXXXX」を比較する方法とか考えたのですが、あまり応用性がないような気がして、この方法に落ち着きました。模範解答とは少し異なります。(模範解答が知りたい方は paiza へ・・・)
もっと少ない計算量で出来る方法はないか、考えてしまいます。似たようなことを繰り返しているので。比較対象が常に異なるので難しいか・・・。
引き続き、よろしくお願いいたします!
ディスカッション
コメント一覧
まだ、コメントがありません