Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I was trying to find the syntax error in my code. I\'m doing a 8 puzzle problem

ID: 3727468 • Letter: I

Question

I was trying to find the syntax error in my code. I'm doing a 8 puzzle problem for my AI class. Would appreciate it greatly. Thank You.

import random
from collections
import deque namedtuple
from operator
import eq

class Puzzle (namedtuple("PuzzleField", ["board", "width", "zero_at"])):
"""
A class representing an '8 puzzle'.
-'board' should be a list of list with integer entries 0.
e.g. [[A,B,C], [D,E,F],[G,H,I]]
"""
__slots__=()
def __new__(cls, board, width, zero_at=None):
if
zero_at
is
None:
zero_at=board.index(0)
return
super().__new__(cls, board, width, zero_at)
def solved
(self):
return all
def actions(self):
at= self.zero_at
if
at >=self.width:
yield
self.move(at-self.width)
if
at+ self.width yield
self._move(at + self.width)
if
at self.width:
yield
self._move(at-1)
def fhuffle
(self):
"""
Makes a new puzzle with 700 different moves
"""
puzzle = self
for _ in
range(700):
puzzle=random.choice
return
puzzle

def _move(self, to):
"""
Return a new puzzle where 'zero_at' and 'to' tiles have been swapped.
NOTE: all moves should be 'actions' that have been executed
"""
a, b = min(self.zero_at, to), max(self.zero_at, to)
board = list(self.board)
board[a], board[b] = board[b], board[a]
return
Puzzle(tuple(board), self.width, to)
def pprint
(self):
for
i
in
range(0, len(self.board), self.width):
print(self.board[i:i+self.width])

class Node(namedtuple("NodeFields", ["puzzle", "parent"])):
"""
A class representing an Solver node
- 'puzzle' is a Puzzle instance
- 'parent' is the preceding node generated by the solver, if any
- 'action' is the action taken to produce puzzle, if any
"""
__slots__ = ()
def __new__(cls, puzzle, parent=None):
return
super().__new__(cls, puzzle, parent)
@property
def action
(self):
if
self.parent
is None:
return None

diff_to_action = {
+self.puzzle.width: 'D',
-self.puzzle.width: 'U',
+1: 'R',
-1: 'L',
}

return
diff_to_action[self.puzzle.zero_at - self.parent.puzzle.zero_at]
def path
(node):
"""
Reconstruct a path from to the root 'parent'
"""
seen = []
while
node
is not None:
seen.append(node)
node = node.parent
return
reversed(seen)

def solve
(start):
"""
Perform breadth first search and return a path
to the solution, if it exists (otherwise None).
"""
queue = deque([Node(start)])
seen = {start}
if
start.solved():
return
path(Node(start, None))
while
queue:
node = queue.pop()
for
move
in
node.puzzle.actions():
if
move.board
not in
seen:
if
move.solved():
return
path(Node(move, node))
queue.appendleft(Node(move, node))
seen.add(move.board)
def main():
board = A,B,C, D,E,F, G,H,I
puzzle = Puzzle(board, C)
puzzle = puzzle.shuffle()
p = solve(puzzle)
for
node
in
p:
print(node.action)
node.puzzle.pprint()
print()
if
__name__ == "__main__":
main()

Explanation / Answer

8 PUZZLE PROBLEM

import random

from collections import deque, namedtuple
from operator import eq


class Puzzle(namedtuple("PuzzleFields", ["board", "width", "zero_at"])):
"""
A class representing an '8-puzzle'.
- 'board' should be a square list of lists with integer entries 0...width²-1
e.g. [[1,2,3],[4,0,6],[7,5,8]]
"""
__slots__ = ()

def __new__(cls, board, width, zero_at=None):
if zero_at is None:
zero_at = board.index(0)

return super().__new__(cls, board, width, zero_at)

def solved(self):
"""
The puzzle is solved if the flattened board's numbers are in
increasing order from left to right and the '0' tile is in the
last position on the board
"""
# 0 is on board, so must be in last place
return all(map(eq, self.board, range(1, self.width**2)))

def actions(self):
"""
Return a list of 'move', 'action' pairs. 'move' can be called
to return a new puzzle that results in sliding the '0' tile in
the direction of 'action'.
"""
at = self.zero_at

if at >= self.width:
yield self._move(at - self.width)

if at + self.width < len(self.board):
yield self._move(at + self.width)

if at % self.width:
yield self._move(at - 1)

if (at + 1) % self.width:
yield self._move(at + 1)

def shuffle(self):
"""
Return a new puzzle that has been shuffled with 1000 random moves
"""
puzzle = self
for _ in range(1000):
puzzle = random.choice(list(puzzle.actions()))
return puzzle

def _move(self, to):
"""
Return a new puzzle where 'zero_at' and 'to' tiles have been swapped.
NOTE: all moves should be 'actions' that have been executed
"""
a, b = min(self.zero_at, to), max(self.zero_at, to)

board = list(self.board)
board[a], board[b] = board[b], board[a]

return Puzzle(tuple(board), self.width, to)

def pprint(self):
for i in range(0, len(self.board), self.width):
print(self.board[i:i+self.width])

class Node(namedtuple("NodeFields", ["puzzle", "parent"])):
"""
A class representing an Solver node
- 'puzzle' is a Puzzle instance
- 'parent' is the preceding node generated by the solver, if any
- 'action' is the action taken to produce puzzle, if any
"""
__slots__ = ()

def __new__(cls, puzzle, parent=None):
return super().__new__(cls, puzzle, parent)

@property
def action(self):
if self.parent is None:
return None

diff_to_action = {
+self.puzzle.width: 'D',
-self.puzzle.width: 'U',
+1: 'R',
-1: 'L',
}

return diff_to_action[self.puzzle.zero_at - self.parent.puzzle.zero_at]


def path(node):
"""
Reconstruct a path from to the root 'parent'
"""
seen = []
while node is not None:
seen.append(node)
node = node.parent
return reversed(seen)


def solve(start):
"""
Perform breadth first search and return a path
to the solution, if it exists (otherwise None).
"""
queue = deque([Node(start)])
seen = {start}

if start.solved():
return path(Node(start, None))

while queue:
node = queue.pop()

for move in node.puzzle.actions():
if move.board not in seen:
if move.solved():
return path(Node(move, node))

queue.appendleft(Node(move, node))
seen.add(move.board)


def main():
board = 1,2,3, 4,0,6, 7,5,8

puzzle = Puzzle(board, 3)
puzzle = puzzle.shuffle()
p = solve(puzzle)

for node in p:
print(node.action)
node.puzzle.pprint()
print()


if __name__ == "__main__":
main()

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote