Day 4: Ceres Search
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Python
Essentially I’m extracting strings from the word search and compare them to the desired value. For part one that means extracting from an X in eight directions. Because I’m reading from the central X outwards, I don’t need to reverse any of them.
Part two reads two strings in an X-shape around the coordinates of each X. The resulting strings are filtered down to include only “MAS” and “SAM”. If there are exactly two strings we found an X-MAS.
from pathlib import Path def parse_input(input: str) -> list[str]: return input.strip().splitlines() def extract_strings_one(m: int, n: int, haystack: list[str], l: int = 4) -> list[str]: result = [] # Right if m + l <= len(haystack[n]): result.append(haystack[n][m : m + l]) # Up-Right if m + l <= len(haystack[n]) and n > l - 2: result.append("".join([haystack[n - i][m + i] for i in range(l)])) # Up if n > l - 2: result.append("".join([haystack[n - i][m] for i in range(l)])) # Up-Left if m > l - 2 and n > l - 2: result.append("".join([haystack[n - i][m - i] for i in range(l)])) # Left if m > l - 2: result.append("".join([haystack[n][m - i] for i in range(l)])) # Down-Left if m > l - 2 and n + l <= len(haystack): result.append("".join([haystack[n + i][m - i] for i in range(l)])) # Down if n + l <= len(haystack): result.append("".join([haystack[n + i][m] for i in range(l)])) # Down-Right if m + l <= len(haystack[n]) and n + l <= len(haystack): result.append("".join([haystack[n + i][m + i] for i in range(l)])) return result def extract_strings_two(m: int, n: int, haystack: list[str], d: int = 1) -> list[str]: result = [] if 0 <= m - d and m + d < len(haystack[n]) and 0 <= n - d and n + d < len(haystack): result.append("".join([haystack[n + i][m + i] for i in range(-d, d + 1)])) result.append("".join([haystack[n - i][m + i] for i in range(-d, d + 1)])) return result def part_one(input: str) -> int: lines = parse_input(input) xmas_count = 0 for i, line in enumerate(lines): x = line.find("X", 0) while x != -1: xmas_count += len( list(filter(lambda s: s == "XMAS", extract_strings_one(x, i, lines))) ) x = line.find("X", x + 1) return xmas_count def part_two(input: str) -> int: lines = parse_input(input) x_mas_count = 0 for i, line in enumerate(lines[1:-1], 1): a = line.find("A", 0) while a != -1: if ( len( list( filter( lambda s: s in ("MAS", "SAM"), extract_strings_two(a, i, lines), ) ) ) == 2 ): x_mas_count += 1 a = line.find("A", a + 1) return x_mas_count if __name__ == "__main__": input = Path("input").read_text("utf-8") print(part_one(input)) print(part_two(input))