diff --git a/.gitignore b/.gitignore index b961508..19ed7c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ session_cookie.txt puzzle_text.md input.txt +Untitled-1.py # Byte-compiled / optimized / DLL files __pycache__/ @@ -162,3 +163,4 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + diff --git a/2024/04/part 1 solution.py b/2024/04/part 1 solution.py new file mode 100644 index 0000000..a5f10f9 --- /dev/null +++ b/2024/04/part 1 solution.py @@ -0,0 +1,69 @@ +testing = 0 +if not testing: + with open(r'2024/04\input.txt', 'r') as file: + input = file.read() +else: + input = '''....XXMAS. +.SAMXMS... +...S..A... +..A.A.MS.X +XMASAMX.MM +X.....XA.A +S.S.S.S.SS +.A.A.A.A.A +..M.M.M.MM +.X.X.XMASX''' + +# word search, +# allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words +# test input has 18 words + +def count_occurance(input, WORD = 'XMAS'): + rows = len(input) + cols = len(input[0]) + word_len = len(WORD) + directions = { + 'north': (0, -1), + 'north_east': (1, -1), + 'east': (1, 0), + 'south_east': (1, 1), + 'south': (0, 1), + 'south_west': (-1, 1), + 'west': (-1, 0), + 'north_west': (-1, -1), + } + + def am_i_still_in_grid(x,y): + 'Returns True if the coordinates are within the grid' + return 0 <= x < rows and 0 <= y < cols + + + def search_from(start_x, start_y, delta_x, delta_y): + """ + Check if the word can be found starting from (start_x, start_y) + in the direction specified by (delta_x, delta_y). + """ + for i in range(word_len): + # Calculate the new coordinates + new_x = start_x + i * delta_x + new_y = start_y + i * delta_y + + # Check if the new coordinates are within the grid and match the word + if not am_i_still_in_grid(new_x, new_y) or input[new_x][new_y] != WORD[i]: + return False + + # If all characters match, return True + return True + + word_count = 0 + for x in range(rows): + for y in range(cols): + for direction in directions.values(): + if search_from(x, y, direction[0], direction[1]): + word_count += 1 + + return word_count + +lines = input.split('\n') +print(count_occurance(lines)) + diff --git a/2024/04/part 2 solution.py b/2024/04/part 2 solution.py new file mode 100644 index 0000000..0f169a9 --- /dev/null +++ b/2024/04/part 2 solution.py @@ -0,0 +1,65 @@ +testing = 0 +if not testing: + with open(r'2024/04\input.txt', 'r') as file: + input = file.read() +else: + input = '''.M.S...... +..A..MSMS. +.M.S.MAA.. +..A.ASMSM. +.M.S.M.... +.......... +S.S.S.S.S. +.A.A.A.A.. +M.M.M.M.M. +..........''' + +# word search, +# allows words to be horizontal, vertical, diagonal, written backwards, or even overlapping other words +# test input has 18 words + +# part 2 calls for looking for 2x 'MAS' in the shape of an 'X' +# we can now ignore the NESW directions +# we should just check the diagonals of any 'A' we find +# if it has 2 'MAS' in the diagonals, we have a match + +# turn the input into a list of lists so we can grid reference it + +lines = input.split('\n') +grid = [list(line) for line in lines] +directions = { + 'north_east': (1, -1), + 'south_west': (-1, 1), + + 'south_east': (1, 1), + 'north_west': (-1, -1), +} +grid_x_len = len(grid[0]) +grid_y_len = len(grid) + +# print(grid) +xmas_count = 0 + +# search for 'A's +for y, row in enumerate(grid): + for x, cell in enumerate(row): + if cell != 'A': + continue + # we found an 'A', check diagonals for 'M' and 'S' + if not (0 <= x + 1 < grid_x_len and 0 <= y + 1 < grid_y_len and + 0 <= x - 1 < grid_x_len and 0 <= y - 1 < grid_y_len): + # we are at the edge of the grid, no need to check + continue + + # take the character from the diagonal, including the middle 'A' + + word_to_check = grid[y + 1][x + 1] + grid[y][x] + grid[y - 1][x - 1] + if word_to_check == 'MAS' or word_to_check == 'SAM': + # one diagonal has 'MAS', check the other + word_to_check = grid[y - 1][x + 1] + grid[y][x] + grid[y + 1][x - 1] + if word_to_check == 'MAS' or word_to_check == 'SAM': + xmas_count += 1 + #print(word_to_check) + + +print(xmas_count)