結果
| 問題 |
No.228 ゆきこちゃんの 15 パズル
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-11-07 15:29:59 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 315 ms / 5,000 ms |
| コード長 | 4,104 bytes |
| コンパイル時間 | 329 ms |
| コンパイル使用メモリ | 13,056 KB |
| 実行使用メモリ | 11,392 KB |
| 最終ジャッジ日時 | 2024-07-20 23:15:43 |
| 合計ジャッジ時間 | 6,001 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 |
ソースコード
from copy import deepcopy
class Number:
def __init__(self, num: int, is_moved: bool) -> None:
self.num = num
self.is_moved = is_moved
class Board:
def __init__(self, numbers: list[list[Number]]) -> None:
self.board = numbers
def __str__(self) -> str:
str_ = []
for row in self.board:
str_.append(" ".join(map(lambda num_o: str(num_o.num), row)))
return "\n".join(str_)
def __eq__(self, __o: object) -> bool:
for s_row, o_row in zip(self.board, __o.board):
for s_num, o_num in zip(s_row, o_row):
if s_num.num != o_num.num:
return False
return True
def __ne__(self, __o: object) -> bool:
return not self.__eq__(__o)
def where_zero(self) -> tuple[int, int]:
for row_idx, row in enumerate(self.board):
try:
return (row_idx, list(map(lambda num: num.num, row)).index(0))
except ValueError:
continue
raise ValueError
def move_up(self):
zero_idx = self.where_zero()
if zero_idx[0] == 3:
return
if self.board[zero_idx[0]+1][zero_idx[1]].is_moved:
return
new_board = deepcopy(self)
new_board.board[zero_idx[0]][zero_idx[1]] = Number(
self.board[zero_idx[0]+1][zero_idx[1]].num, True)
new_board.board[zero_idx[0]+1][zero_idx[1]
] = Number(self.board[zero_idx[0]][zero_idx[1]].num, False)
return new_board
def move_down(self):
zero_idx = self.where_zero()
if zero_idx[0] == 0:
return
if self.board[zero_idx[0]-1][zero_idx[1]].is_moved:
return
new_board = deepcopy(self)
new_board.board[zero_idx[0]][zero_idx[1]] = Number(
self.board[zero_idx[0]-1][zero_idx[1]].num, True)
new_board.board[zero_idx[0]-1][zero_idx[1]
] = Number(self.board[zero_idx[0]][zero_idx[1]].num, False)
return new_board
def move_right(self):
zero_idx = self.where_zero()
if zero_idx[1] == 0:
return
if self.board[zero_idx[0]][zero_idx[1]-1].is_moved:
return
new_board = deepcopy(self)
new_board.board[zero_idx[0]][zero_idx[1]] = Number(
self.board[zero_idx[0]][zero_idx[1]-1].num, True)
new_board.board[zero_idx[0]][zero_idx[1]-1
] = Number(self.board[zero_idx[0]][zero_idx[1]].num, False)
return new_board
def move_left(self):
zero_idx = self.where_zero()
if zero_idx[1] == 3:
return
if self.board[zero_idx[0]][zero_idx[1]+1].is_moved:
return
new_board = deepcopy(self)
new_board.board[zero_idx[0]][zero_idx[1]] = Number(
self.board[zero_idx[0]][zero_idx[1]+1].num, True)
new_board.board[zero_idx[0]][zero_idx[1]+1
] = Number(self.board[zero_idx[0]][zero_idx[1]].num, False)
return new_board
def move_4dir(self):
candidate = [self.move_down(), self.move_left(),
self.move_right(), self.move_up()]
return list(filter(lambda elm: elm is not None, candidate))
def main():
target_board_nums = [list(map(int, input().split())) for _ in range(4)]
target_board = Board([list(map(lambda num: Number(
num, is_moved=False), target_board_num)) for target_board_num in target_board_nums])
init_board_nums = [list(range(init, init+4)) for init in range(1, 16, 4)]
init_board_nums[3][3] = 0
init_board = Board([list(map(lambda num: Number(
num, is_moved=False), init_board_num)) for init_board_num in init_board_nums])
stack = [init_board]
while stack:
current_board = stack.pop()
if current_board == target_board:
print("Yes")
return
stack.extend(current_board.move_4dir())
print("No")
if __name__ == "__main__":
main()