diff --git a/Day18/python/solution1.py b/Day18/python/solution1.py index 3c2323b..f42d01c 100644 --- a/Day18/python/solution1.py +++ b/Day18/python/solution1.py @@ -1,7 +1,7 @@ def parse_instructions(file_path): """Parse instructions from the given file.""" try: - with open(file_path, 'r') as file: + with open(file_path, "r") as file: instructions = [line.strip().split() for line in file.readlines()] print(f"Parsed {len(instructions)} instructions from {file_path}") return instructions @@ -9,16 +9,18 @@ def parse_instructions(file_path): print(f"Error reading file {file_path}: {e}") raise + def apply_instruction(grid, position, direction, steps): """Apply a single instruction to the grid and update the position.""" - deltas = {'U': (0, -1), 'D': (0, 1), 'L': (-1, 0), 'R': (1, 0)} + deltas = {"U": (0, -1), "D": (0, 1), "L": (-1, 0), "R": (1, 0)} dx, dy = deltas[direction] for _ in range(steps): position = (position[0] + dx, position[1] + dy) grid.add(position) - #print(f"Moved {direction} to {position}") + # print(f"Moved {direction} to {position}") return position + def create_path(instructions): """Create the path based on the instructions.""" grid = set() @@ -29,29 +31,37 @@ def create_path(instructions): direction, steps = instruction[0], int(instruction[1]) print(f"Applying instruction: {direction} {steps}") position = apply_instruction(grid, position, direction, steps) - + return grid + def flood_fill(grid, bounds): """Perform flood-fill to find cells outside the path.""" filled = set() - to_fill = [(bounds[0], y) for y in range(bounds[2], bounds[3] + 1)] \ - + [(bounds[1], y) for y in range(bounds[2], bounds[3] + 1)] \ - + [(x, bounds[2]) for x in range(bounds[0], bounds[1] + 1)] \ - + [(x, bounds[3]) for x in range(bounds[0], bounds[1] + 1)] + to_fill = ( + [(bounds[0], y) for y in range(bounds[2], bounds[3] + 1)] + + [(bounds[1], y) for y in range(bounds[2], bounds[3] + 1)] + + [(x, bounds[2]) for x in range(bounds[0], bounds[1] + 1)] + + [(x, bounds[3]) for x in range(bounds[0], bounds[1] + 1)] + ) while to_fill: x, y = to_fill.pop() if (x, y) in filled or (x, y) in grid: continue filled.add((x, y)) - if x > bounds[0]: to_fill.append((x - 1, y)) - if x < bounds[1]: to_fill.append((x + 1, y)) - if y > bounds[2]: to_fill.append((x, y - 1)) - if y < bounds[3]: to_fill.append((x, y + 1)) + if x > bounds[0]: + to_fill.append((x - 1, y)) + if x < bounds[1]: + to_fill.append((x + 1, y)) + if y > bounds[2]: + to_fill.append((x, y - 1)) + if y < bounds[3]: + to_fill.append((x, y + 1)) return filled + def calculate_area(grid): """Calculate the area inside the loop.""" min_x = min(grid, key=lambda x: x[0])[0] @@ -66,6 +76,7 @@ def calculate_area(grid): return inside_area + def run_test(test_file): """Run the algorithm with test input.""" try: @@ -79,6 +90,7 @@ def run_test(test_file): print(f"Assertion Error: {e}") return False + def main(): """Main function to run the puzzle solution.""" test_file = "../test.txt" @@ -97,5 +109,6 @@ def main(): else: print("Test failed. Halting execution.") + if __name__ == "__main__": - main() \ No newline at end of file + main() diff --git a/Day18/python/solution2.py b/Day18/python/solution2.py index 0f6f76c..5af275a 100644 --- a/Day18/python/solution2.py +++ b/Day18/python/solution2.py @@ -1,7 +1,7 @@ def parse_instructions(file_path): """Parse instructions from the given file.""" try: - with open(file_path, 'r') as file: + with open(file_path, "r") as file: lines = file.read().splitlines() print(f"Parsed {len(lines)} instructions from {file_path}") return lines @@ -9,6 +9,7 @@ def parse_instructions(file_path): print(f"Error reading file {file_path}: {e}") raise + def calculate_area(lines): """Calculate the area inside the loop defined by the instructions.""" DIRECTIONS = [(0, 1), (1, 0), (0, -1), (-1, 0)] @@ -24,18 +25,29 @@ def calculate_area(lines): row, column = points[-1] points.append((row + dr * steps, column + dc * steps)) - area = abs( - sum(x1 * y2 - x2 * y1 for (x1, y1), (x2, y2) in zip(points, points[1:] + points[:1])) - ) // 2 + boundary // 2 + 1 + area = ( + abs( + sum( + x1 * y2 - x2 * y1 + for (x1, y1), (x2, y2) in zip(points, points[1:] + points[:1]) + ) + ) + // 2 + + boundary // 2 + + 1 + ) return area + def run_test(test_file, expected_result): """Run the algorithm with test input and compare with the expected result.""" try: lines = parse_instructions(test_file) calculated_area = calculate_area(lines) - assert calculated_area == expected_result, f"Test failed, expected {expected_result}, got {calculated_area}" + assert ( + calculated_area == expected_result + ), f"Test failed, expected {expected_result}, got {calculated_area}" print(f"Test passed, area: {calculated_area}") except AssertionError as e: print(e) @@ -44,11 +56,14 @@ def run_test(test_file, expected_result): print(f"Error during test execution: {e}") raise + def main(): """Main function to run the puzzle solution.""" test_file = "../test.txt" input_file = "../input.txt" - expected_test_area = 952408144115 # Replace with the correct expected area for the test + expected_test_area = ( + 952408144115 # Replace with the correct expected area for the test + ) # Run test try: @@ -61,5 +76,6 @@ def main(): except Exception as e: print(f"Execution halted due to error: {e}") + if __name__ == "__main__": main() diff --git a/Day18/rust/Cargo.toml b/Day18/rust/Cargo.toml new file mode 100644 index 0000000..1ec6963 --- /dev/null +++ b/Day18/rust/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rust" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/Day18/rust/src/main.rs b/Day18/rust/src/main.rs new file mode 100644 index 0000000..1a3cd6e --- /dev/null +++ b/Day18/rust/src/main.rs @@ -0,0 +1,73 @@ +use std::fs::File; +use std::io::{self, BufRead}; + +fn parse_instructions(file_path: &str) -> io::Result> { + let file = File::open(file_path)?; + let lines = io::BufReader::new(file).lines(); + let instructions: Vec = lines.collect::>()?; + println!( + "Parsed {} instructions from {}", + instructions.len(), + file_path + ); + Ok(instructions) +} + +fn calculate_area(lines: &Vec) -> i64 { + let directions: Vec<(i64, i64)> = vec![(0, 1), (1, 0), (0, -1), (-1, 0)]; + let mut points: Vec<(i64, i64)> = vec![(0, 0)]; + let mut boundary = 0; + + for line in lines { + if line.is_empty() { + continue; + } + + if let Some(color) = line.split(' ').last() { + let instructions = &color[2..color.len() - 1]; + let direction_index = + i64::from_str_radix(&instructions[instructions.len() - 1..], 16).unwrap(); + let (dr, dc) = directions[direction_index as usize]; + let steps = i64::from_str_radix(&instructions[..instructions.len() - 1], 16).unwrap(); + boundary += steps; + let (row, column) = points.last().unwrap(); + points.push((row + dr * steps, column + dc * steps)); + } + } + + let mut area = 0; + for i in 0..points.len() { + let (x1, y1) = points[i]; + let (x2, y2) = points[(i + 1) % points.len()]; + area += x1 * y2 - x2 * y1; + } + + (area.abs() / 2) + (boundary / 2) + 1 +} + +fn run_test(test_file: &str, expected_result: i64) -> io::Result<()> { + let lines = parse_instructions(test_file)?; + let calculated_area = calculate_area(&lines); + assert_eq!(calculated_area, expected_result, "Test failed"); + println!("Test passed, area: {}", calculated_area); + Ok(()) +} + +fn main() { + let test_file = "../test.txt"; + let input_file = "../input.txt"; + let expected_test_area: i64 = 952408144115; // Replace with the correct expected area for the test + + if let Err(e) = run_test(test_file, expected_test_area) { + eprintln!("Execution halted due to error: {}", e); + return; + } + + match parse_instructions(input_file) { + Ok(lines) => { + let area = calculate_area(&lines); + println!("Puzzle result (area): {}", area); + } + Err(e) => eprintln!("Execution halted due to error: {}", e), + } +} diff --git a/Day18/ts/solution.ts b/Day18/ts/solution.ts index f8e942c..e619deb 100644 --- a/Day18/ts/solution.ts +++ b/Day18/ts/solution.ts @@ -14,7 +14,7 @@ function parseInstructions(filePath: string): string[] { function calculateArea(lines: string[]): number { const DIRECTIONS: [number, number][] = [[0, 1], [1, 0], [0, -1], [-1, 0]]; - let points: [number, number][] = [[0, 0]]; + const points: [number, number][] = [[0, 0]]; let boundary: number = 0; for (const line of lines) {