From 6550a9a5bc71300cf0a9427be23102e2d814b8b9 Mon Sep 17 00:00:00 2001 From: Jonathan Tsai Date: Wed, 1 Dec 2021 04:47:33 +0000 Subject: [PATCH] progress commit --- project_euler/python/082.py | 10 ++-- project_euler/python/083.py | 116 +++++++++++++++++++++++++++++++++++- 2 files changed, 121 insertions(+), 5 deletions(-) diff --git a/project_euler/python/082.py b/project_euler/python/082.py index c895c1c..c1e76fa 100644 --- a/project_euler/python/082.py +++ b/project_euler/python/082.py @@ -19,9 +19,11 @@ Solution by jontsai """ +# Python Standard Library Imports import copy from collections import namedtuple +# PE Solution Library Imports from utils import * @@ -152,7 +154,7 @@ def __init__(self): self.matrix = self.get_matrix() self.memo = [] - for i in xrange(self.NUM_ROWS): + for i in range(self.NUM_ROWS): self.memo.append([None] * 80) def get_matrix(self): @@ -169,7 +171,7 @@ def get_matrix(self): def solve(self): positions = [] - + for m in range(self.NUM_ROWS): n = 0 position = Position(self.matrix, m, n) @@ -179,7 +181,7 @@ def solve(self): # DFS using a stack while len(positions) > 0: - print len(positions), best_result_so_far.cumulative_sum if best_result_so_far else 0 + print(len(positions), best_result_so_far.cumulative_sum if best_result_so_far else 0) position = positions.pop() if position.is_finished: @@ -205,7 +207,7 @@ def main(): solution = Solution() answer = solution.solve() - print 'Expected: %s, Answer: %s' % (Solution.EXPECTED_ANSWER, answer) + print('Expected: %s, Answer: %s' % (Solution.EXPECTED_ANSWER, answer)) if __name__ == '__main__': diff --git a/project_euler/python/083.py b/project_euler/python/083.py index 78695a9..42ef22c 100755 --- a/project_euler/python/083.py +++ b/project_euler/python/083.py @@ -28,7 +28,120 @@ from utils import * -class Solution(object): +class Move(namedtuple('Move', 'row col')): + pass + + +MOVE_LEFT = Move(0, -1) +MOVE_RIGHT = Move(0, 1) +MOVE_UP = Move(-1, 0) +MOVE_DOWN = Move(1, 0) + + +class Position(object): + def __init__(self, matrix, m, n): + self.matrix = matrix + self.moves = [] + self.m = m + self.n = n + self.cumulative_sum = matrix[m][n] + + def clone(self): + """Returns a clone of this `Position` + """ + cloned_position = Position(self.matrix, self.m, self.n) + cloned_position.moves = copy.copy(self.moves) + cloned_position.cumulative_sum = self.cumulative_sum + return cloned_position + + @property + def is_finished(self): + return self.is_at_last_column + + @property + def is_at_first_column(self): + assert self.n >= 0 + return self.n == 0 + + @property + def is_at_last_column(self): + assert self.n >= 0 + return self.n + 1 == Solution.NUM_COLS + + @property + def is_at_top_row(self): + assert self.m >= 0 + return self.m == 0 + + @property + def is_at_bottom_row(self): + assert self.m >= 0 + return self.m + 1 == Solution.NUM_ROWS + + def get_next_positions(self): + """Returns a list of subsequent `Position`s after applying all eligible moves + """ + moves = self.get_eligible_moves() + + next_positions = [] + + for move in moves: + position = self.clone() + position.do_move(move) + next_positions.append(position) + + return next_positions + + def do_move(self, move): + """Applies `move` to this `Position` + """ + self.m += move.row + self.n += move.col + self.moves.append(move) + self.cumulative_sum += self.matrix[self.m][self.n] + + def get_eligible_moves(self): + """Returns a list of `Move`s that are eligible from this current position + """ + moves = [] + if self.is_at_first_column: + moves.append(MOVE_RIGHT) + + elif self.is_at_last_column: + # no more eligible moves + pass + + elif len(self.moves) > 0: + # RIGHT is always an eligble move before last column + moves.append(MOVE_RIGHT) + + # check UP and DOWN eligibility based on previous move + prev_move = self.moves[-1] + assert prev_move in (MOVE_LEFT, MOVE_RIGHT, MOVE_UP, MOVE_DOWN,) + + if prev_move == MOVE_RIGHT: + if not self.is_at_top_row: + moves.append(MOVE_UP) + + if not self.is_at_bottom_row: + moves.append(MOVE_DOWN) + + elif prev_move == MOVE_UP and not self.is_at_top_row: + moves.append(MOVE_UP) + + elif prev_move == MOVE_DOWN and not self.is_at_bottom_row: + moves.append(MOVE_DOWN) + + else: + pass + + else: + raise Exception('Illegal state -- empty moves but not in starting column') + + return moves + + +class SolutionNaive(object): EXPECTED_ANSWER = 2297 MATRIX_INPUT_FILE = 'p081_test_matrix.txt' NUM_ROWS = 5 @@ -117,6 +230,7 @@ def main(): # resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1)) # sys.setrecursionlimit(10**6) + # solution = SolutionNaive() solution = Solution() answer = solution.solve()