├── .gitignore ├── inputs ├── day11.txt ├── day21.txt ├── day17.txt ├── day08.txt ├── day10.txt ├── day24.txt ├── day14.txt ├── day06.txt ├── day09.txt ├── day03.txt └── day04.txt ├── .idea ├── .gitignore ├── vcs.xml ├── modules.xml └── aoc-2024.iml ├── Cargo.toml ├── src ├── main.rs ├── day01.rs ├── day03.rs ├── day19.rs ├── day02.rs ├── day10.rs ├── day18.rs ├── day17.rs ├── day07.rs ├── day25.rs ├── day23.rs ├── day09.rs ├── day22.rs ├── day04.rs ├── day08.rs ├── day06.rs ├── day11.rs ├── day05.rs ├── day14.rs ├── day24.rs ├── day12.rs ├── day16.rs ├── day20.rs ├── day13.rs ├── day21.rs └── day15.rs ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /inputs/day11.txt: -------------------------------------------------------------------------------- 1 | 554735 45401 8434 0 188 7487525 77 7 2 | -------------------------------------------------------------------------------- /inputs/day21.txt: -------------------------------------------------------------------------------- 1 | 671A 2 | 279A 3 | 083A 4 | 974A 5 | 386A 6 | -------------------------------------------------------------------------------- /inputs/day17.txt: -------------------------------------------------------------------------------- 1 | Register A: 64012472 2 | Register B: 0 3 | Register C: 0 4 | 5 | Program: 2,4,1,7,7,5,0,3,1,7,4,1,5,5,3,0 -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "aoc-2024" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | ahash = "0.8.11" 8 | glam = "0.29.2" 9 | itertools = "0.13.0" 10 | ndarray = "0.16.1" 11 | nom = "7.1.3" 12 | nom_locate = "4.2.0" 13 | pathfinding = "4.12.0" 14 | petgraph = "0.6.5" 15 | rayon = "1.10.0" 16 | regex = "1.11.1" 17 | -------------------------------------------------------------------------------- /.idea/aoc-2024.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | mod day01; 4 | mod day02; 5 | mod day03; 6 | mod day04; 7 | mod day05; 8 | mod day06; 9 | mod day07; 10 | mod day08; 11 | mod day09; 12 | mod day10; 13 | mod day11; 14 | mod day12; 15 | mod day13; 16 | mod day14; 17 | mod day15; 18 | mod day16; 19 | mod day17; 20 | mod day18; 21 | mod day19; 22 | mod day20; 23 | mod day21; 24 | mod day22; 25 | mod day23; 26 | mod day24; 27 | mod day25; 28 | 29 | fn main() { 30 | // day01::solution(); 31 | // day02::solution(); 32 | // day03::solution(); 33 | // day04::solution(); 34 | // day05::solution(); 35 | // day06::solution(); 36 | // day07::solution(); 37 | // day08::solution(); 38 | // day09::solution(); 39 | // day10::solution(); 40 | // day11::solution(); 41 | // day12::solution(); 42 | // day13::solution(); 43 | // day14::solution(); 44 | // day15::solution(); 45 | // day16::solution(); 46 | // day17::solution(); 47 | // day18::solution(); 48 | // day19::solution(); 49 | // day20::solution(); 50 | // day21::solution(); 51 | // day22::solution(); 52 | // day23::solution(); 53 | // day24::solution(); 54 | day25::solution(); 55 | } 56 | -------------------------------------------------------------------------------- /src/day01.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::str::FromStr; 3 | 4 | pub fn solution() { 5 | // A. 6 | let aoc_2024_01 = 7 | fs::read_to_string("./inputs/day01.txt").expect("Something went wrong reading the file"); 8 | let mut a = Vec::new(); 9 | let mut b = Vec::new(); 10 | 11 | for line in aoc_2024_01.lines() { 12 | // split by tab 13 | let mut parts = line.split_whitespace(); 14 | a.push(::from_str(parts.next().unwrap()).unwrap()); 15 | b.push(::from_str(parts.next().unwrap()).unwrap()); 16 | } 17 | 18 | // unstable sorting is faster, and we can use this because the inputs are integers 19 | a.sort_unstable(); 20 | b.sort_unstable(); 21 | 22 | // calculate the difference between the two arrays 23 | let diff = a 24 | .iter() 25 | .zip(&b) 26 | .map(|(a, b)| (a - b).abs()) 27 | .collect::>() 28 | .iter() 29 | .sum::(); 30 | println!("The difference is: {}", diff); 31 | 32 | // B. 33 | let sum = a 34 | .iter() 35 | .map(|x| x * b.iter().filter(|&y| x == y).count() as i32) 36 | .sum::(); 37 | 38 | println!("The sum of duplicates is: {}", sum); 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🎄 Advent of Code 2024 Solutions in Rust 2 | 3 | Welcome to our **Advent of Code 2024 (in Rust)** repository! 🎅✨ This project provides **daily solutions** for the [Advent of Code](https://adventofcode.com/) challenges, implemented in the Rust programming language. 4 | 5 | We update the repository **every day** with solutions for the latest puzzles. Whether you're learning Rust, solving puzzles, or looking for inspiration, we hope this repository proves useful to you. 6 | 7 | ## 📁 Directory Structure 8 | 9 | ```plaintext 10 | 📂 src/ 11 | ├── day01.rs # Solution for Day 1 12 | ├── day02.rs # Solution for Day 2 13 | ├── ... 14 | 📂 inputs/ 15 | ├── day01.txt # Input data for Day 1 16 | ├── day02.txt # Input data for Day 2 17 | ├── ... 18 | ``` 19 | 20 | - src/: Contains the Rust solution files for each day. 21 | - inputs/: Stores the input data used for the puzzles. 22 | 23 | 24 | ## 🚀 Usage 25 | 26 | 1. Clone the repository: 27 | 28 | ```bash 29 | git clone https://github.com/rust-dd/aoc-2024.git 30 | cd aoc-2024 31 | ``` 32 | 33 | 2. Update the repository daily to get the latest solutions: 34 | 35 | ```bash 36 | git pull 37 | ``` 38 | 39 | 40 | ## 🌟 Acknowledgements 41 | 42 | - Advent of Code by Eric Wastl for the incredible challenges. 43 | - The Rust community for their tools and support. 44 | 45 | --- 46 | 47 | 🎉 Happy Coding and enjoy solving puzzles with Rust! 🎄 48 | -------------------------------------------------------------------------------- /src/day03.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use regex::Regex; 4 | 5 | pub fn solution() { 6 | let aoc_2024_03 = 7 | fs::read_to_string("./inputs/day03.txt").expect("Something went wrong reading the file"); 8 | 9 | // A. 10 | let matching_regex = Regex::new(r"mul\((\d+),(\d+)\)").unwrap(); 11 | let caps = matching_regex.captures_iter(&aoc_2024_03); 12 | 13 | let mut sum = 0; 14 | for cap in caps { 15 | let first_value = cap.get(1).unwrap().as_str().parse::().unwrap(); 16 | let second_value = cap.get(2).unwrap().as_str().parse::().unwrap(); 17 | sum = sum + (first_value * second_value); 18 | } 19 | println!("Result: {}", sum); 20 | 21 | // B. 22 | let text_without_new_lines = aoc_2024_03.replace("\n", "to"); 23 | let regex_do_not_do = Regex::new(r"don't.*?(do\(\)|$)").unwrap(); 24 | let text_without_do_not_do = regex_do_not_do.replace_all(&text_without_new_lines, ""); 25 | let matching_regex = Regex::new(r"mul\((\d+),(\d+)\)").unwrap(); 26 | let caps = matching_regex.captures_iter(&text_without_do_not_do); 27 | let mut sum = 0; 28 | for cap in caps { 29 | let first_value = cap.get(1).unwrap().as_str().parse::().unwrap(); 30 | let second_value = cap.get(2).unwrap().as_str().parse::().unwrap(); 31 | sum = sum + (first_value * second_value); 32 | } 33 | 34 | println!("Result: {}", sum); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/day19.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::io::{self, BufRead}; 3 | use std::collections::HashMap; 4 | 5 | fn count_ways(onsen_part: &str, patterns: &[String], memo: &mut HashMap) -> u64 { 6 | if onsen_part.is_empty() { 7 | return 1; 8 | } 9 | 10 | if let Some(&count) = memo.get(onsen_part) { 11 | return count; 12 | } 13 | 14 | let mut total = 0; 15 | for pattern in patterns { 16 | if onsen_part.starts_with(pattern) { 17 | let remainder = &onsen_part[pattern.len()..]; 18 | total += count_ways(remainder, patterns, memo); 19 | } 20 | } 21 | memo.insert(onsen_part.to_string(), total); 22 | total 23 | } 24 | 25 | pub fn solution() { 26 | let file = fs::File::open("./inputs/day19.txt").expect("Failed to open file"); 27 | let reader = io::BufReader::new(file); 28 | let mut lines_iter = reader.lines().map(|line| line.expect("Failed to read line")); 29 | let towel_pattern_line = lines_iter.next().expect("No towel patterns found"); 30 | let towel_patterns: Vec = towel_pattern_line 31 | .split(',') 32 | .map(|s| s.trim().to_string()) 33 | .collect(); 34 | 35 | // blank line 36 | lines_iter.next(); 37 | 38 | let onsens: Vec = lines_iter.collect(); 39 | 40 | let mut total_match_count = 0u64; 41 | let mut onsen_count_that_can_match = 0u64; 42 | 43 | for onsen in &onsens { 44 | let mut memo: HashMap = HashMap::new(); 45 | let ways = count_ways(onsen, &towel_patterns, &mut memo); 46 | if ways > 0 { 47 | onsen_count_that_can_match += 1; 48 | total_match_count += ways; 49 | } 50 | } 51 | 52 | println!("Result A: {}", onsen_count_that_can_match); 53 | println!("Result B: {}", total_match_count); 54 | } -------------------------------------------------------------------------------- /src/day02.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | pub fn solution() { 4 | let aoc_2024_02 = 5 | fs::read_to_string("./inputs/day02.txt").expect("Something went wrong reading the file"); 6 | 7 | // A. 8 | let mut safe_reports_a = 0; 9 | let mut safe_reports = Vec::::new(); 10 | for (idx, line) in aoc_2024_02.lines().enumerate() { 11 | let numbers = line 12 | .split_whitespace() 13 | .map(|u| u.parse::().unwrap()) 14 | .collect::>(); 15 | let ascending = |a: &i8, b: &i8| *a < *b && *b <= (*a + 3); 16 | let descending = |a: &i8, b: &i8| *a > *b && *b >= (*a - 3); 17 | 18 | if numbers.is_sorted_by(ascending) || numbers.is_sorted_by(descending) { 19 | safe_reports_a = safe_reports_a + 1; 20 | 21 | // collect the indexes of the unsafe reports 22 | safe_reports.push(idx); 23 | } 24 | } 25 | println!("Number of safe reports is: {}", safe_reports_a); 26 | 27 | // B. 28 | let asc = |levels: &[i8]| { 29 | levels 30 | .windows(2) 31 | .all(|w| w[1] > w[0] && (1..=3).contains(&(w[1] - w[0]))) 32 | }; 33 | let desc = |levels: &[i8]| { 34 | levels 35 | .windows(2) 36 | .all(|w| w[1] < w[0] && (1..=3).contains(&(w[0] - w[1]))) 37 | }; 38 | 39 | let is_safe = |levels: &[i8]| -> bool { 40 | (asc(levels) || desc(levels)) 41 | || (0..levels.len()).any(|i| { 42 | let mut levels = levels.to_vec(); 43 | levels.remove(i); 44 | asc(&levels) || desc(&levels) 45 | }) 46 | }; 47 | 48 | let levels = aoc_2024_02 49 | .lines() 50 | .map(|line| { 51 | line.split_whitespace() 52 | .map(|u| u.parse::().unwrap()) 53 | .collect::>() 54 | }) 55 | .collect::>>(); 56 | 57 | let count = levels.into_iter().filter(|l| is_safe(l)).count(); 58 | println!("Number of safe reports is: {}", count); 59 | } 60 | -------------------------------------------------------------------------------- /src/day10.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::fs::File; 3 | use std::io::{self, BufRead}; 4 | 5 | pub fn solution() { 6 | let aoc_2024_10 = 7 | File::open("./inputs/day10.txt").expect("Something went wrong reading the file"); 8 | let grid = io::BufReader::new(aoc_2024_10) 9 | .lines() 10 | .filter_map(|line| line.ok()) 11 | .map(|line| { 12 | line.chars() 13 | .map(|c| c.to_digit(10).map(|d| d as usize).unwrap_or(99)) 14 | .collect::>() 15 | }) 16 | .collect::>>(); 17 | 18 | let rows = grid.len() as i32; 19 | let cols = grid[0].len() as i32; 20 | 21 | let zero_positions: Vec<(i32, i32)> = (0..rows) 22 | .flat_map(|i| (0..cols).map(move |j| (i, j))) 23 | .filter(|&(i, j)| grid[i as usize][j as usize] == 0) 24 | .collect(); 25 | 26 | let mut sum_of_scores = 0; 27 | let mut sum_of_ratings = 0; 28 | for (i, j) in zero_positions { 29 | let mut queue = Vec::new(); 30 | queue.push((0, (i, j))); 31 | let mut scores: HashSet<(i32, i32)> = HashSet::new(); 32 | let directions = [(-1, 0), (1, 0), (0, 1), (0, -1)]; 33 | while let Some((actual_value, (x, y))) = queue.pop() { 34 | let next_value = actual_value + 1; 35 | 36 | for &(dx, dy) in &directions { 37 | let next_x = x + dx; 38 | let next_y = y + dy; 39 | 40 | if let Some(actual_value) = get_value(&grid, rows, cols, next_x, next_y) { 41 | if actual_value == next_value { 42 | if actual_value == 9 { 43 | scores.insert((next_x, next_y)); 44 | sum_of_ratings += 1; 45 | } else { 46 | queue.push((next_value, (next_x, next_y))); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | sum_of_scores += scores.len(); 53 | } 54 | 55 | println!("matches a {}", sum_of_scores); 56 | println!("matches b {}", sum_of_ratings); 57 | } 58 | 59 | fn get_value(grid: &Vec>, rows: i32, cols: i32, r: i32, c: i32) -> Option { 60 | if r >= 0 && r < rows && c >= 0 && c < cols { 61 | Some(grid[r as usize][c as usize]) 62 | } else { 63 | None 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /inputs/day08.txt: -------------------------------------------------------------------------------- 1 | .................................................. 2 | .................................C................ 3 | .e..........7O.................................... 4 | .....................................z............ 5 | ......................t.........C.......k......... 6 | ............h................................9.... 7 | .............5.7....O.............9C.............. 8 | .......5.O................T....................... 9 | .............................o...c....z........... 10 | .hH...........e..7.............................w.. 11 | ......H...................c....3.T..5............. 12 | .....H........5..........B...........3..z..c...... 13 | ....6........H.........t.......................... 14 | ........O..................e........3............. 15 | ............e.........o..............9............ 16 | .........s.........o.............................. 17 | .......................k........4.....3..z.w...... 18 | ......s.................t..T.k............8....... 19 | .......s............................T.....w....... 20 | ..................................C.7............. 21 | .................................................. 22 | .........................t......b.w............... 23 | ............................X...................8. 24 | .............6..........k......................... 25 | ............................1................8.... 26 | ...............................8.................. 27 | ....h........................b.................... 28 | ............................................c..... 29 | ..J............................................... 30 | .....................................K............ 31 | ..............................x................... 32 | .................................................. 33 | ....2......0...................x...........1...... 34 | ...4.....0......................1b................ 35 | .............h......................K.jW.......... 36 | 6...........0...............W..................... 37 | .........6........B............................... 38 | .......2................B..........x........K..... 39 | .................................................. 40 | .................................G.......j........ 41 | ....................E............................. 42 | .......................................S...ZX..... 43 | .....4.......2...B........Wj.....S................ 44 | ..o...............2..................W....j....... 45 | .....................E..........S..........J...... 46 | ................E......................1.......... 47 | ......................G........K.........g........ 48 | ..............................G....J....S......... 49 | ...................G....................Z..Xg..... 50 | 4..................E..............J.g....X........ -------------------------------------------------------------------------------- /inputs/day10.txt: -------------------------------------------------------------------------------- 1 | 56760198543405456770107687012987873265430701234123 2 | 47891087612514320889298596543236982176321878985054 3 | 30932912503423411978321436760145453089490965076567 4 | 21043803498598502565450345897896334569584324105498 5 | 43256754387687643445601231056787276578675013212389 6 | 50105620896014553238782322348996189432106522301210 7 | 60234211205423469109695210567345023456987101232569 8 | 71454301312345678100556501051269010787832198543478 9 | 82365985407856743291447892340178732696949037643323 10 | 99878876556989856782332309650065341054658743252110 11 | 12389565445845698943221218761234456565789650167087 12 | 03458890330532787892100321052442787074656782108996 13 | 12766721221621056521098478934321692183245891210105 14 | 00875437876521245430167569035630013290194300121234 15 | 21980356985430130101456122128754324389980215432101 16 | 32341245234561221212340033439961015671271326990123 17 | 41239832101676678703121542345872343760362347887654 18 | 50146701098787569254035671096112654854454558943210 19 | 69655410889693452164549389987003569943003967656787 20 | 78789324989582543076678432176124578752112876545490 21 | 49670123476451001289986581065437669801198743454321 22 | 34565404560302654345677893034458954321034652345210 23 | 21670313401212701238766732123361056700125601216787 24 | 10781223304343870349676678901272341811098700305891 25 | 87690433210154901234587565078980110925643212456730 26 | 98521049873269100448996652169765223434756965569821 27 | 83430656794378234567385543258894304589807874321034 28 | 12345690185123247855434789043210113676212981012125 29 | 04396783276030110982329872178901923494345891234596 30 | 65287654896543225671012763561032876587436780989687 31 | 70132108987652334430101654432945214306525891078765 32 | 89945345456701498521012346547876305211014342569854 33 | 67876276789876567677890107236521456523210213410743 34 | 56940189678930438988743298101430567894765104323212 35 | 45434328509821321089654340122334567765894101298701 36 | 50125613410030012127763019831021998568903210345692 37 | 23498701322147897898892123742340867478912653210789 38 | 10567654213456786721089054654356789302801743105678 39 | 01678123402110995437658766789210676211010892234109 40 | 67569016567021874378941043212101245432346781103201 41 | 58454323898134565632332456701234306011015490321232 42 | 49323454234012906701454327890965412102367305410147 43 | 31012365125643812898765410378876543233458216568758 44 | 21009876034756763019034101269989100146569325679669 45 | 21898745129829654323129654352123299656478012784578 46 | 30743231065018760563238765543034788798329983693056 47 | 45656189654323011056769894672145632347012674212147 48 | 01218088745896522349850123283034701456981065100238 49 | 14309893236787631438943210190129892123672578921109 50 | 25456782101896540127654301012010181034543465433212 51 | -------------------------------------------------------------------------------- /src/day18.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use std::fs; 3 | use std::io::{self, BufRead}; 4 | 5 | const GRID_SIZE: usize = 71; 6 | const NUM_ROWS: usize = 1024; 7 | 8 | type Point = (usize, usize); 9 | 10 | fn bfs(grid: &[[char; GRID_SIZE]; GRID_SIZE]) -> (bool, usize) { 11 | let directions: [(isize, isize); 4] = [(0, 1), (1, 0), (0, -1), (-1, 0)]; 12 | let mut queue = VecDeque::new(); 13 | let mut visited = [[false; GRID_SIZE]; GRID_SIZE]; 14 | let mut path_length = 0; 15 | 16 | queue.push_back((0, 0, vec![(0,0)])); 17 | visited[0][0] = true; 18 | 19 | while let Some((x, y, path)) = queue.pop_front() { 20 | if (x, y) == (GRID_SIZE - 1, GRID_SIZE - 1) { 21 | path_length = path.len() -1; 22 | return (true, path_length); 23 | } 24 | 25 | for &(dx, dy) in &directions { 26 | let nx = x as isize + dx; 27 | let ny = y as isize + dy; 28 | 29 | if nx >= 0 && nx < GRID_SIZE as isize && ny >= 0 && ny < GRID_SIZE as isize { 30 | let (nx, ny) = (nx as usize, ny as usize); 31 | if !visited[nx][ny] && grid[nx][ny] == '.' { 32 | let mut new_path = path.clone(); 33 | new_path.push((nx,ny)); 34 | queue.push_back((nx, ny, new_path)); 35 | visited[nx][ny] = true; 36 | } 37 | } 38 | } 39 | } 40 | (false, path_length) 41 | } 42 | 43 | pub fn solution() { 44 | let file = fs::File::open("./inputs/day18.txt").expect("Failed to open file"); 45 | let reader = io::BufReader::new(file); 46 | let mut lines_iter = reader.lines().map(Result::unwrap); 47 | let mut grid = [['.'; GRID_SIZE]; GRID_SIZE]; 48 | 49 | // Initial grid setup 50 | for line_content in lines_iter.by_ref().take(NUM_ROWS) { 51 | let (y_str, x_str) = line_content.trim().split_once(',').unwrap(); 52 | let (x, y): (usize, usize) = (x_str.parse().unwrap(), y_str.parse().unwrap()); 53 | if x < GRID_SIZE && y < GRID_SIZE { 54 | grid[x][y] = '#'; 55 | } 56 | } 57 | 58 | // Part A 59 | let (path_found, path_length) = bfs(&grid); 60 | if path_found { 61 | println!("Result A: {}", path_length); 62 | } 63 | 64 | 65 | // Part B 66 | for line_content in lines_iter { 67 | let (y_str, x_str) = line_content.trim().split_once(',').unwrap(); 68 | let (x, y): (usize, usize) = (x_str.parse().unwrap(), y_str.parse().unwrap()); 69 | 70 | if x < GRID_SIZE && y < GRID_SIZE { 71 | grid[x][y] = '#'; 72 | } 73 | 74 | let (path_found, _) = bfs(&grid); 75 | if !path_found { 76 | println!("Result B: {},{}", y, x); 77 | break; 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/day17.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use regex::Regex; 3 | 4 | pub fn solution() { 5 | let input = fs::read_to_string("./inputs/day17.txt").expect("Failed to read file"); 6 | let re = Regex::new(r"Register A:\s*(\d+)\s*Register B:\s*(\d+)\s*Register C:\s*(\d+)\s*Program:\s*([\d,]+)").unwrap(); 7 | let caps = re.captures(&input).expect("Failed to parse input"); 8 | 9 | let a_init: u64 = caps[1].parse().unwrap(); 10 | let b_init: u64 = caps[2].parse().unwrap(); 11 | let c_init: u64 = caps[3].parse().unwrap(); 12 | let programs: Vec = caps[4] 13 | .split(',') 14 | .map(|x| x.trim().parse().unwrap()) 15 | .collect(); 16 | 17 | // Part A 18 | let result_a = run_program(a_init, b_init, c_init, &programs); 19 | let result_a_joined = result_a.iter() 20 | .map(u64::to_string) 21 | .collect::>() 22 | .join(","); 23 | println!("Part A Result: {}", result_a_joined); 24 | 25 | // Part B 26 | let result_b = find_part_b_initial_a(b_init, c_init, &programs).unwrap(); 27 | println!("Part B Result: {}", result_b); 28 | } 29 | 30 | fn run_program(mut a: u64, mut b: u64, mut c: u64, programs: &[u64]) -> Vec { 31 | let mut result = Vec::new(); 32 | let mut pointer = 0; 33 | 34 | while pointer < programs.len() { 35 | let opcode = programs[pointer]; 36 | let operand = programs[pointer + 1]; 37 | let combo = get_combo(operand, a, b, c); 38 | 39 | match opcode { 40 | 0 => a /= 1 << combo, 41 | 1 => b ^= operand, 42 | 2 => b = combo % 8, 43 | 3 => if a != 0 { 44 | pointer = operand as usize; 45 | continue; 46 | }, 47 | 4 => b ^= c, 48 | 5 => result.push(combo % 8), 49 | 6 => b = a / (1 << combo), 50 | 7 => c = a / (1 << combo), 51 | _ => println!("Unknown opcode: {}", opcode), 52 | } 53 | pointer += 2; 54 | } 55 | result 56 | } 57 | 58 | fn get_combo(operand: u64, a: u64, b: u64, c: u64) -> u64 { 59 | match operand { 60 | 4 => a, 61 | 5 => b, 62 | 6 => c, 63 | _ => operand, 64 | } 65 | } 66 | 67 | 68 | fn find_part_b_initial_a(b_init: u64, c_init: u64, programs: &[u64]) -> Option { 69 | let mut candidates = vec![0]; 70 | while !candidates.is_empty() { 71 | let mut next: Vec = vec![]; 72 | for base in candidates { 73 | for i in 0..=7 { 74 | let a: u64 = 8 * base + i; 75 | let output = run_program(a, b_init, c_init, programs); 76 | if output == programs { 77 | return Some(a); 78 | } 79 | if programs.ends_with(&output) { 80 | next.push(a); 81 | } 82 | } 83 | } 84 | candidates = next; 85 | } 86 | None 87 | } -------------------------------------------------------------------------------- /src/day07.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use nom::{ 4 | bytes::complete::tag, 5 | character::complete::{self, line_ending, space1}, 6 | multi::separated_list1, 7 | sequence::separated_pair, 8 | IResult, 9 | }; 10 | 11 | pub fn solution() { 12 | let input = fs::read_to_string("./inputs/day07.txt").expect("Failed to read input file"); 13 | let data: IResult<&str, Vec<(u64, Vec)>, nom::error::Error<&str>> = separated_list1( 14 | line_ending, 15 | separated_pair( 16 | complete::u64, 17 | tag(": "), 18 | separated_list1(space1, complete::u64), 19 | ), 20 | )(input.as_str()); 21 | let (_, data) = data.unwrap(); 22 | 23 | // A. 24 | let mut result = 0; 25 | 26 | for (left, right) in &data { 27 | let len = right.len(); 28 | 29 | if len < 1 { 30 | continue; 31 | } 32 | 33 | // Test every combination of add/mul between the right side 34 | // All combinations are 2^(len - 1) 35 | // generate all possible combinations of add/mul in binary form 36 | for i in 0..(1 << (len - 1)) { 37 | let mut sum = right[0]; 38 | 39 | for j in 0..(len - 1) { 40 | // bit masking to check if the j-th bit in i is a 1 or 0 41 | // if 1, add, else multiply 42 | if i & (1 << j) != 0 { 43 | sum += right[j + 1]; 44 | } else { 45 | sum *= right[j + 1]; 46 | } 47 | } 48 | 49 | if &sum == left { 50 | result += left; 51 | break; 52 | } 53 | } 54 | } 55 | 56 | println!("Result part A: {}", result); 57 | 58 | // B. 59 | let mut result = 0; 60 | 61 | for (left, right) in &data { 62 | let len = right.len(); 63 | 64 | if len < 1 { 65 | continue; 66 | } 67 | 68 | // Test every combination of add/mul between the right side 69 | // All combinations are 2^(len - 1) 70 | // || use for concatenation and get the result of the left side 71 | // e.g 156: 15 6 72 | // 156 = 15 || 6 73 | for mut i in 0..3i64.pow((len - 1) as u32) { 74 | let mut sum = right[0]; 75 | 76 | for j in 0..(len - 1) { 77 | let op = i % 3; 78 | i /= 3; 79 | 80 | match op { 81 | 0 => sum += right[j + 1], 82 | 1 => sum *= right[j + 1], 83 | _ => { 84 | sum = format!("{}{}", sum, right[j + 1].to_string()) 85 | .parse() 86 | .unwrap() 87 | } 88 | } 89 | } 90 | 91 | if &sum == left { 92 | result += left; 93 | break; 94 | } 95 | } 96 | } 97 | 98 | println!("Result part B: {}", result); 99 | } 100 | -------------------------------------------------------------------------------- /src/day25.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | fs::File, 3 | io::{BufRead, BufReader}, 4 | }; 5 | 6 | #[derive(Debug)] 7 | struct Block { 8 | origin: String, 9 | heights: Vec, 10 | } 11 | 12 | pub fn solution() { 13 | let file = File::open("./inputs/day25.txt").expect("Could not open input file"); 14 | let reader = BufReader::new(file); 15 | let lines: Vec = reader.lines().map(|line| line.expect("Could not read line")).collect(); 16 | 17 | let blocks = parse_blocks(&lines); 18 | let processed_blocks: Vec = blocks 19 | .iter() 20 | .map(|block| { 21 | let origin = determine_block_origin(block); 22 | let heights = calculate_heights(block, &origin); 23 | Block { origin, heights } 24 | }) 25 | .collect(); 26 | 27 | let match_count = count_matches(&processed_blocks); 28 | println!("Result A: {}", match_count); 29 | } 30 | 31 | fn parse_blocks(lines: &[String]) -> Vec> { 32 | let mut blocks = vec![]; 33 | let mut current = vec![]; 34 | 35 | for line in lines { 36 | if line.trim().is_empty() { 37 | if !current.is_empty() { 38 | blocks.push(current.clone()); 39 | current.clear(); 40 | } 41 | } else { 42 | current.push(line.clone()); 43 | if current.len() == 7 { 44 | blocks.push(current.clone()); 45 | current.clear(); 46 | } 47 | } 48 | } 49 | 50 | if !current.is_empty() { 51 | blocks.push(current); 52 | } 53 | 54 | blocks 55 | } 56 | 57 | fn determine_block_origin(block: &[String]) -> String { 58 | let first_line_hashes = block[0].chars().filter(|&c| c == '#').count(); 59 | let last_line_hashes = block[6].chars().filter(|&c| c == '#').count(); 60 | 61 | if first_line_hashes > last_line_hashes { 62 | "Top".to_string() 63 | } else { 64 | "Bottom".to_string() 65 | } 66 | } 67 | 68 | fn calculate_heights(block: &[String], origin: &str) -> Vec { 69 | (0..block.iter().map(|line| line.len()).max().unwrap()) 70 | .map(|col| { 71 | let mut height = 0; 72 | let rows = if origin == "Top" { 73 | (1..7).collect::>() 74 | } else { 75 | (0..6).rev().collect::>() 76 | }; 77 | 78 | for row in rows { 79 | if block[row].chars().nth(col).unwrap_or('.') == '#' { 80 | height += 1; 81 | } else { 82 | break; 83 | } 84 | } 85 | 86 | height 87 | }) 88 | .collect() 89 | } 90 | 91 | fn count_matches(blocks: &[Block]) -> i32 { 92 | let mut match_count = 0; 93 | 94 | for (i, block_a) in blocks.iter().enumerate() { 95 | for block_b in blocks.iter().skip(i + 1) { 96 | if block_a.origin != block_b.origin 97 | && block_a.heights.iter().zip(&block_b.heights).all(|(a, b)| a + b < 6) 98 | { 99 | match_count += 1; 100 | } 101 | } 102 | } 103 | 104 | match_count 105 | } 106 | -------------------------------------------------------------------------------- /src/day23.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | collections::{HashMap, HashSet}, 3 | fs::File, 4 | io::{BufRead, BufReader}, 5 | }; 6 | 7 | use petgraph::{ 8 | graph::{Graph, NodeIndex}, 9 | Undirected, 10 | }; 11 | 12 | pub fn solution() { 13 | let file = File::open("./inputs/day23.txt").unwrap(); 14 | let reader = BufReader::new(file); 15 | 16 | let mut graph = Graph::::new_undirected(); 17 | let mut nodes: HashMap = HashMap::new(); 18 | 19 | for line_result in reader.lines() { 20 | let line = line_result.unwrap(); 21 | let parts: Vec = line.split('-').map(|s| s.to_string()).collect(); 22 | let computer1 = &parts[0]; 23 | let computer2 = &parts[1]; 24 | 25 | let node1 = *nodes 26 | .entry(computer1.to_string()) 27 | .or_insert_with(|| graph.add_node(computer1.to_string())); 28 | let node2 = *nodes 29 | .entry(computer2.to_string()) 30 | .or_insert_with(|| graph.add_node(computer2.to_string())); 31 | 32 | graph.add_edge(node1, node2, ()); 33 | } 34 | 35 | // A 36 | let mut three_node_sets: HashSet> = HashSet::new(); 37 | for u in graph.node_indices() { 38 | let neighbors: Vec<_> = graph.neighbors(u).collect(); 39 | for i in 0..neighbors.len() { 40 | for j in (i + 1)..neighbors.len() { 41 | let n1 = neighbors[i]; 42 | let n2 = neighbors[j]; 43 | 44 | if graph.contains_edge(n1, n2) { 45 | let mut tri = vec![graph[u].clone(), graph[n1].clone(), graph[n2].clone()]; 46 | tri.sort(); 47 | three_node_sets.insert(tri); 48 | } 49 | } 50 | } 51 | } 52 | 53 | let set_has_node_start_with_t = three_node_sets 54 | .iter() 55 | .filter(|triangle| triangle.iter().any(|label| label.starts_with('t'))) 56 | .count(); 57 | println!("Result A: {}", set_has_node_start_with_t); 58 | 59 | // B 60 | let mut largest_set: HashSet = HashSet::new(); 61 | for current_node in graph.node_indices() { 62 | let mut current_set = HashSet::new(); 63 | current_set.insert(current_node); 64 | let mut neighbours: Vec = graph.neighbors(current_node).collect(); 65 | 66 | while let Some(neighbour) = neighbours.pop() { 67 | let is_fully_connected = current_set 68 | .iter() 69 | .all(|¤t| graph.contains_edge(neighbour, current) || current == neighbour); 70 | 71 | if is_fully_connected { 72 | current_set.insert(neighbour); 73 | for neighbour_of_neighbour in graph.neighbors(neighbour) { 74 | if !current_set.contains(&neighbour_of_neighbour) 75 | && !neighbours.contains(&neighbour_of_neighbour) 76 | { 77 | neighbours.push(neighbour_of_neighbour); 78 | } 79 | } 80 | } 81 | } 82 | if current_set.len() > largest_set.len() { 83 | largest_set = current_set; 84 | } 85 | } 86 | 87 | let mut labels: Vec = largest_set.into_iter().map(|i| graph[i].clone()).collect(); 88 | labels.sort(); 89 | 90 | println!("Result B: {}", labels.join(",")); 91 | } 92 | -------------------------------------------------------------------------------- /src/day09.rs: -------------------------------------------------------------------------------- 1 | use itertools::Itertools; 2 | use std::fs; 3 | 4 | pub fn solution() { 5 | let input = fs::read_to_string("./inputs/day09.txt").expect("Failed to read input file"); 6 | let input = input.trim(); 7 | let mut disk = Vec::new(); 8 | 9 | let bytes = input.bytes().enumerate(); 10 | let mut bytes_rev = bytes.clone().rev(); 11 | 12 | let mut bytes_rev_i; 13 | let mut bytes_rev_i_id; 14 | let mut bytes_rev_b; 15 | let mut bytes_rev_b_remaining; 16 | 17 | (bytes_rev_i, bytes_rev_b) = bytes_rev.next().unwrap(); 18 | 19 | if bytes_rev_i % 2 == 1 { 20 | (bytes_rev_i, bytes_rev_b) = bytes_rev.next().unwrap(); 21 | } 22 | 23 | bytes_rev_i_id = bytes_rev_i / 2; 24 | bytes_rev_b_remaining = bytes_rev_b - b'0'; 25 | 26 | for (i, b) in bytes { 27 | if i >= bytes_rev_i { 28 | for _ in 0..bytes_rev_b_remaining { 29 | disk.push(bytes_rev_i_id); 30 | } 31 | break; 32 | } 33 | if i % 2 == 0 { 34 | let i_id = i / 2; 35 | for _ in 0..(b - b'0') { 36 | disk.push(i_id); 37 | } 38 | } else { 39 | for _ in 0..(b - b'0') { 40 | if bytes_rev_b_remaining == 0 { 41 | _ = bytes_rev.next().unwrap(); 42 | (bytes_rev_i, bytes_rev_b) = bytes_rev.next().unwrap(); 43 | if i >= bytes_rev_i { 44 | break; 45 | } 46 | bytes_rev_i_id = bytes_rev_i / 2; 47 | bytes_rev_b_remaining = bytes_rev_b - b'0'; 48 | } 49 | bytes_rev_b_remaining -= 1; 50 | disk.push(bytes_rev_i_id); 51 | } 52 | } 53 | } 54 | 55 | let sum: usize = disk.into_iter().enumerate().map(|(i, id)| i * id).sum(); 56 | println!("Result part A: {}", sum); 57 | 58 | // B. 59 | // (id, start, length) 60 | let mut files = Vec::new(); 61 | 62 | let _ = input.bytes().enumerate().fold(0, |mut c, (i, b)| { 63 | let length = b - b'0'; 64 | 65 | if i % 2 == 0 { 66 | files.push((i / 2, c, length)); 67 | } 68 | 69 | c += length as usize; 70 | c 71 | }); 72 | 73 | for id in (0..=files.last().unwrap().0).rev() { 74 | let file_index = files.iter().position(|file| file.0 == id).unwrap(); 75 | 76 | if let Some(new_position) = files 77 | .iter() 78 | .tuple_windows() 79 | .find_map(|(a, b)| { 80 | let a_end = a.1 + a.2 as usize; 81 | let f = &files[file_index]; 82 | 83 | if a_end > f.1 { 84 | return Some(None); 85 | } 86 | 87 | let gap = b.1 - a_end; 88 | if gap >= f.2 as usize { 89 | return Some(Some(a_end)); 90 | } 91 | 92 | None 93 | }) 94 | .flatten() 95 | { 96 | files[file_index].1 = new_position; 97 | } 98 | 99 | files.sort_by_key(|f| f.1); 100 | } 101 | 102 | let sum = files 103 | .into_iter() 104 | .map(|f| { 105 | (f.1..f.1 + f.2 as usize) 106 | .map(|idx| idx * f.0) 107 | .sum::() 108 | }) 109 | .sum::(); 110 | 111 | println!("Result part B: {}", sum); 112 | } 113 | -------------------------------------------------------------------------------- /src/day22.rs: -------------------------------------------------------------------------------- 1 | use itertools::iproduct; 2 | use rayon::prelude::*; 3 | use std::fs::File; 4 | use std::io::{BufRead, BufReader}; 5 | 6 | const MODULO: u64 = 16_777_216; 7 | 8 | fn next_secret(s: u32) -> u32 { 9 | let mut s64 = s as u64; 10 | let m1 = s64.checked_mul(64).unwrap(); 11 | s64 ^= m1; 12 | s64 %= MODULO; 13 | let m2 = s64 / 32; 14 | s64 ^= m2; 15 | s64 %= MODULO; 16 | let m3 = s64.checked_mul(2048).unwrap(); 17 | s64 ^= m3; 18 | s64 %= MODULO; 19 | s64 as u32 20 | } 21 | 22 | fn generate_2000th_secret(initial: u32) -> u32 { 23 | let mut s = initial; 24 | for _ in 0..2000 { 25 | s = next_secret(s); 26 | } 27 | s 28 | } 29 | 30 | fn generate_secret_sequence(initial: u32) -> Vec { 31 | let mut seq = Vec::with_capacity(2001); 32 | seq.push(initial); 33 | let mut current = initial; 34 | for _ in 0..2000 { 35 | current = next_secret(current); 36 | seq.push(current); 37 | } 38 | seq 39 | } 40 | 41 | fn to_prices(secrets: &[u32]) -> Vec { 42 | secrets.iter().map(|&s| (s % 10) as u8).collect() 43 | } 44 | 45 | fn to_price_changes(prices: &[u8]) -> Vec { 46 | let mut changes = Vec::with_capacity(prices.len().saturating_sub(1)); 47 | for w in prices.windows(2) { 48 | changes.push(w[1] as i8 - w[0] as i8); 49 | } 50 | changes 51 | } 52 | 53 | fn first_occurrence_bananas(changes: &[i8], prices: &[u8], pattern: &[i8]) -> u32 { 54 | if changes.len() < pattern.len() { 55 | return 0; 56 | } 57 | for i in 0..=(changes.len() - pattern.len()) { 58 | if &changes[i..i + pattern.len()] == pattern { 59 | return prices[i + pattern.len()] as u32; 60 | } 61 | } 62 | 0 63 | } 64 | 65 | pub fn solution() { 66 | // A. 67 | let file = File::open("./inputs/day22.txt").unwrap(); 68 | let reader = BufReader::new(file); 69 | let mut inputs_part1 = Vec::new(); 70 | for line in reader.lines() { 71 | let value: u32 = line.unwrap().trim().parse().unwrap(); 72 | inputs_part1.push(value); 73 | } 74 | 75 | let mut total_sum_part1 = 0u64; 76 | for &initial_secret in &inputs_part1 { 77 | let val = generate_2000th_secret(initial_secret); 78 | total_sum_part1 += val as u64; 79 | } 80 | 81 | println!("Part 1 total sum: {}", total_sum_part1); 82 | 83 | // B. 84 | let mut all_prices = Vec::new(); 85 | let mut all_changes = Vec::new(); 86 | for &initial_secret in &inputs_part1 { 87 | let secrets = generate_secret_sequence(initial_secret); 88 | let prices = to_prices(&secrets); 89 | let changes = to_price_changes(&prices); 90 | all_prices.push(prices); 91 | all_changes.push(changes); 92 | } 93 | 94 | // Brute force all possible patterns. 95 | // The pattern is a 4-tuple of i8 values. 96 | // This is a brute force solution, but it's fast enough. 97 | let best_sum = iproduct!(-9..=9, -9..=9, -9..=9, -9..=9) 98 | .par_bridge() 99 | .into_par_iter() 100 | .map(|(a, b, c, d)| { 101 | let pattern = [a, b, c, d]; 102 | all_changes 103 | .par_iter() 104 | .zip(all_prices.par_iter()) 105 | .map(|(ch, pr)| first_occurrence_bananas(ch, pr, &pattern) as u64) 106 | .sum::() 107 | }) 108 | .max() 109 | .unwrap_or(0); 110 | 111 | println!("Part 2 max bananas: {}", best_sum); 112 | } 113 | -------------------------------------------------------------------------------- /src/day04.rs: -------------------------------------------------------------------------------- 1 | use ndarray::Array2; 2 | use std::fs::File; 3 | use std::io::BufRead; 4 | 5 | pub fn solution() { 6 | let aoc_2024_a = 7 | File::open("./inputs/day04.txt").expect("Something went wrong reading the file"); 8 | let lines = std::io::BufReader::new(aoc_2024_a) 9 | .lines() 10 | .filter_map(|line| line.ok()) 11 | .map(|line| line.chars().collect()) 12 | .collect::>>(); 13 | 14 | // A. 15 | let rows = lines.len(); 16 | let cols = lines[0].len(); 17 | let data = lines.into_iter().flatten().collect::>(); 18 | let grid = Array2::from_shape_vec((rows, cols), data).unwrap(); 19 | 20 | let target = "XMAS".chars().collect::>(); 21 | let rows = grid.nrows() as i32; 22 | let cols = grid.ncols() as i32; 23 | 24 | let dxdy: [(i32, i32); 8] = [ 25 | (0, 1), 26 | (0, -1), 27 | (1, 0), 28 | (-1, 0), 29 | (1, 1), 30 | (-1, -1), 31 | (1, -1), 32 | (-1, 1), 33 | ]; 34 | 35 | let mut count = 0; 36 | for i in 0..rows { 37 | for j in 0..cols { 38 | for &(dx, dy) in &dxdy { 39 | let mut found = true; 40 | for k in 0..target.len() { 41 | let x = i + dx * k as i32; 42 | let y = j + dy * k as i32; 43 | if x < 0 44 | || y < 0 45 | || x >= rows 46 | || y >= cols 47 | || grid[[x as usize, y as usize]] != target[k] 48 | { 49 | found = false; 50 | break; 51 | } 52 | } 53 | if found { 54 | count += 1; 55 | } 56 | } 57 | } 58 | } 59 | 60 | println!("The number of XMAS is: {}", count); 61 | 62 | // B. 63 | let mas = ['M', 'A', 'S']; 64 | let sam = ['S', 'A', 'M']; 65 | let targets = [(&mas, &mas), (&mas, &sam), (&sam, &mas), (&sam, &sam)]; 66 | let mut count = 0; 67 | 68 | for i in 0..rows { 69 | for j in 0..cols { 70 | if grid[[i as usize, j as usize]] == 'A' { 71 | let diag1 = [(i - 1, j - 1), (i, j), (i + 1, j + 1)]; 72 | let diag2 = [(i - 1, j + 1), (i, j), (i + 1, j - 1)]; 73 | 74 | let in_diag1 = diag1 75 | .iter() 76 | .all(|&(x, y)| x >= 0 && y >= 0 && x < rows && y < cols); 77 | let in_diag2 = diag2 78 | .iter() 79 | .all(|&(x, y)| x >= 0 && y >= 0 && x < rows && y < cols); 80 | 81 | if in_diag1 && in_diag2 { 82 | let x_in_diag1 = diag1 83 | .iter() 84 | .map(|&(x, y)| grid[[x as usize, y as usize]]) 85 | .collect::>(); 86 | let x_in_diag2 = diag2 87 | .iter() 88 | .map(|&(x, y)| grid[[x as usize, y as usize]]) 89 | .collect::>(); 90 | 91 | for &(diag1_word, diag2_word) in &targets { 92 | if x_in_diag1 == diag1_word && x_in_diag2 == diag2_word { 93 | count += 1; 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | println!("The number of MAS is: {}", count); 102 | } 103 | -------------------------------------------------------------------------------- /src/day08.rs: -------------------------------------------------------------------------------- 1 | use ndarray::Array2; 2 | use std::collections::HashMap; 3 | use std::fs::File; 4 | use std::io::BufRead; 5 | 6 | pub fn solution() { 7 | let aoc_2024_08 = 8 | File::open("./inputs/day08.txt").expect("Something went wrong reading the file"); 9 | let lines = std::io::BufReader::new(aoc_2024_08) 10 | .lines() 11 | .filter_map(|line| line.ok()) 12 | .map(|line| line.chars().collect()) 13 | .collect::>>(); 14 | 15 | let rows = lines.len(); 16 | let cols = lines[0].len(); 17 | let data = lines.into_iter().flatten().collect::>(); 18 | 19 | let grid = Array2::from_shape_vec((rows, cols), data).unwrap(); 20 | let mut positions_by_key: HashMap> = HashMap::new(); 21 | let rows = grid.nrows() as i32; 22 | let cols = grid.ncols() as i32; 23 | 24 | let mut sum = 0; 25 | for i in 0..rows { 26 | for j in 0..cols { 27 | let key = grid[[i as usize, j as usize]]; 28 | if grid[[i as usize, j as usize]] != '.' { 29 | positions_by_key 30 | .entry(key) 31 | .and_modify(|vec| vec.push((i, j))) 32 | .or_insert_with(|| vec![(i, j)]); 33 | } 34 | } 35 | } 36 | 37 | // A. 38 | let mut grid_a = grid.clone(); 39 | for entry in &positions_by_key { 40 | let values = entry.1; 41 | 42 | for i in 0..values.len() { 43 | let first = values.get(i).unwrap(); 44 | for j in 0..values.len() { 45 | if i == j { 46 | continue; 47 | } 48 | let second = values.get(j).unwrap(); 49 | 50 | let x_diff = second.0 - first.0; 51 | let y_diff = second.1 - first.1; 52 | let new_x = second.0 + x_diff; 53 | let new_y = second.1 + y_diff; 54 | 55 | if new_x < rows && new_y < cols && new_x >= 0 && new_y >= 0 { 56 | let cell = grid_a[(new_x as usize, new_y as usize)]; 57 | if cell != '#' { 58 | sum += 1; 59 | grid_a[(new_x as usize, new_y as usize)] = '#'; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | println!("Result: {}", sum); 66 | 67 | // B 68 | let mut grid_b = grid.clone(); 69 | for entry in &positions_by_key { 70 | let values = entry.1; 71 | 72 | for i in 0..values.len() { 73 | let first = values.get(i).unwrap(); 74 | for j in 0..values.len() { 75 | if i == j { 76 | continue; 77 | } 78 | let second = values.get(j).unwrap(); 79 | 80 | let x_diff = second.0 - first.0; 81 | let y_diff = second.1 - first.1; 82 | let mut new_x = second.0 + x_diff; 83 | let mut new_y = second.1 + y_diff; 84 | 85 | while (0..rows).contains(&new_x) && (0..cols).contains(&new_y) { 86 | let cell = grid_b[(new_x as usize, new_y as usize)]; 87 | if cell != '#' { 88 | grid_b[(new_x as usize, new_y as usize)] = '#'; 89 | } 90 | new_x = new_x + x_diff; 91 | new_y = new_y + y_diff; 92 | } 93 | } 94 | } 95 | } 96 | 97 | let mut sum = 0; 98 | for i in 0..rows { 99 | for j in 0..cols { 100 | if grid_b[[i as usize, j as usize]] != '.' { 101 | sum += 1; 102 | } 103 | } 104 | } 105 | println!("Result: {}", sum) 106 | } 107 | -------------------------------------------------------------------------------- /src/day06.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::fs; 3 | 4 | pub fn solution() { 5 | let input = fs::read_to_string("./inputs/day06.txt").expect("Failed to read input file"); 6 | let mut map = input 7 | .lines() 8 | .map(|line| line.chars().collect()) 9 | .collect::>>(); 10 | 11 | // A. 12 | let mut p = (0, 0); 13 | let mut d = (0, -1); 14 | let dirs = [(0, -1), (1, 0), (0, 1), (-1, 0)]; 15 | 16 | for (y, row) in map.iter_mut().enumerate() { 17 | for (x, &cell) in row.iter().enumerate() { 18 | if cell == '^' { 19 | p = (x, y); 20 | row[x] = '.'; 21 | break; 22 | } 23 | } 24 | } 25 | 26 | let mut visited = HashSet::<(usize, usize)>::new(); 27 | visited.insert(p); 28 | 29 | loop { 30 | let (x, y) = p; 31 | let (dx, dy) = d; 32 | let next_position = ((x as isize + dx) as usize, (y as isize + dy) as usize); 33 | 34 | if next_position.1 >= map.len() || next_position.0 >= map[0].len() { 35 | break; 36 | } 37 | 38 | match map[next_position.1][next_position.0] { 39 | '#' => { 40 | d = dirs[(dirs.iter().position(|&_d| _d == d).unwrap() + 1) % dirs.len()]; 41 | } 42 | '.' => { 43 | p = next_position; 44 | visited.insert(p); 45 | } 46 | _ => { 47 | break; 48 | } 49 | } 50 | } 51 | 52 | println!("Result part A: {}", visited.len()); 53 | 54 | // B. 55 | let input = fs::read_to_string("./inputs/day06.txt").expect("Failed to read input file"); 56 | let mut map = input 57 | .lines() 58 | .map(|line| line.chars().collect()) 59 | .collect::>>(); 60 | 61 | let mut looping_positions = HashSet::<(usize, usize)>::new(); 62 | let mut p = (0, 0); 63 | let d = (0, -1); 64 | 65 | for (y, row) in map.iter_mut().enumerate() { 66 | for (x, &cell) in row.iter().enumerate() { 67 | if cell == '^' { 68 | p = (x, y); 69 | row[x] = '.'; 70 | break; 71 | } 72 | } 73 | } 74 | 75 | for y in 0..map.len() { 76 | for x in 0..map[0].len() { 77 | if map[y][x] == '.' && (x, y) != p { 78 | map[y][x] = '#'; 79 | 80 | if simulate_guard(&mut map, p, d, &dirs).is_some() { 81 | looping_positions.insert((x, y)); 82 | } 83 | 84 | map[y][x] = '.'; 85 | } 86 | } 87 | } 88 | 89 | println!("Part B Result: {}", looping_positions.len()); 90 | } 91 | 92 | fn simulate_guard( 93 | map: &Vec>, 94 | start_pos: (usize, usize), 95 | start_dir: (isize, isize), 96 | dirs: &[(isize, isize)], 97 | ) -> Option> { 98 | let mut visited = HashSet::<(usize, usize)>::new(); 99 | let mut states = HashSet::<((usize, usize), (isize, isize))>::new(); 100 | let mut p = start_pos; 101 | let mut d = start_dir; 102 | 103 | loop { 104 | let (x, y) = p; 105 | let (dx, dy) = d; 106 | let next = ((x as isize + dx) as usize, (y as isize + dy) as usize); 107 | 108 | if next.1 >= map.len() || next.0 >= map[0].len() { 109 | return None; 110 | } 111 | 112 | match map[next.1][next.0] { 113 | '#' => { 114 | d = dirs[(dirs.iter().position(|&_d| _d == d).unwrap() + 1) % dirs.len()]; 115 | } 116 | '.' => { 117 | p = next; 118 | if !states.insert((p, d)) { 119 | return Some(visited); 120 | } 121 | visited.insert(p); 122 | } 123 | _ => { 124 | return None; 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/day11.rs: -------------------------------------------------------------------------------- 1 | use ahash::AHashMap; 2 | use rayon::prelude::*; 3 | 4 | pub fn solution() { 5 | let input = std::fs::read_to_string("./inputs/day11.txt").expect("Failed to read input file"); 6 | 7 | let parse = |input: &str| { 8 | input 9 | .split_whitespace() 10 | .filter_map(|x| x.parse::().ok()) 11 | .fold(AHashMap::new(), |mut acc, x| { 12 | *acc.entry(x).or_insert(0) += 1; 13 | acc 14 | }) 15 | }; 16 | 17 | let run = |stones: &mut AHashMap, iter: &mut i32| { 18 | while *iter > 0 { 19 | let mut next_stones = AHashMap::new(); 20 | 21 | for (stone, count) in stones.iter() { 22 | if *stone == 0 { 23 | *next_stones.entry(1).or_insert(0) += count; 24 | } else if stone.to_string().len() % 2 == 0 { 25 | let stone_str = stone.to_string(); 26 | let mid = stone_str.len() / 2; 27 | let left = stone_str[..mid].parse::().unwrap(); 28 | let right = stone_str[mid..].parse::().unwrap(); 29 | *next_stones.entry(left).or_insert(0) += count; 30 | *next_stones.entry(right).or_insert(0) += count; 31 | } else { 32 | let new_stone = stone * 2024; 33 | *next_stones.entry(new_stone).or_insert(0) += count; 34 | } 35 | } 36 | 37 | *stones = next_stones; 38 | *iter -= 1; 39 | } 40 | 41 | println!("Result : {}", stones.values().sum::()); 42 | }; 43 | 44 | // A. 45 | let mut stones = parse(&input); 46 | let mut iterations = 25; 47 | run(&mut stones, &mut iterations); 48 | 49 | // B. 50 | iterations = 75; 51 | let mut stones = parse(&input); 52 | run(&mut stones, &mut iterations); 53 | } 54 | 55 | pub fn solution_par() { 56 | let input = std::fs::read_to_string("./inputs/day11.txt").expect("Failed to read input file"); 57 | let parse = |input: &str| { 58 | input 59 | .split_whitespace() 60 | .filter_map(|x| x.parse::().ok()) 61 | .fold(AHashMap::new(), |mut acc, x| { 62 | *acc.entry(x).or_insert(0) += 1; 63 | acc 64 | }) 65 | }; 66 | 67 | let run = |stones: &mut AHashMap, iter: &mut i32| { 68 | while *iter > 0 { 69 | let next_stones = stones 70 | .par_iter() 71 | .flat_map(|(&stone, &count)| { 72 | if stone == 0 { 73 | vec![(1, count)] 74 | } else if stone.to_string().len() % 2 == 0 { 75 | let stone_str = stone.to_string(); 76 | let mid = stone_str.len() / 2; 77 | let left = stone_str[..mid].parse::().unwrap(); 78 | let right = stone_str[mid..].parse::().unwrap(); 79 | vec![(left, count), (right, count)] 80 | } else { 81 | let new_stone = stone * 2024; 82 | vec![(new_stone, count)] 83 | } 84 | }) 85 | .fold(AHashMap::new, |mut acc, (stone, count)| { 86 | *acc.entry(stone).or_insert(0) += count; 87 | acc 88 | }) 89 | .reduce_with(|mut acc, map| { 90 | for (stone, count) in map { 91 | *acc.entry(stone).or_insert(0) += count; 92 | } 93 | acc 94 | }) 95 | .unwrap_or_default(); 96 | 97 | *stones = next_stones; 98 | *iter -= 1; 99 | } 100 | 101 | println!("Result: {}", stones.values().sum::()); 102 | }; 103 | 104 | // A. 105 | let mut stones = parse(&input); 106 | let mut iterations = 25; 107 | run(&mut stones, &mut iterations); 108 | 109 | // B. 110 | iterations = 75; 111 | let mut stones = parse(&input); 112 | run(&mut stones, &mut iterations); 113 | } 114 | -------------------------------------------------------------------------------- /src/day05.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use petgraph::{ 4 | graph::{DiGraph, NodeIndex}, 5 | visit::IntoNodeReferences, 6 | Direction, 7 | }; 8 | 9 | pub fn solution() { 10 | let aoc_2024_04 = 11 | fs::read_to_string("./inputs/day05.txt").expect("Something went wrong reading the file"); 12 | 13 | let mut parts = aoc_2024_04.split("\n\n"); 14 | let page_ordering_rules_text = parts.next().unwrap(); 15 | let page_ordering_rules: Vec<(i8, i8)> = page_ordering_rules_text 16 | .lines() 17 | .map(|line| { 18 | let mut numbers = line.split('|').map(|n| n.parse::().unwrap()); 19 | (numbers.next().unwrap(), numbers.next().unwrap()) 20 | }) 21 | .collect(); 22 | 23 | let pages_to_reproduce_text = parts.next().unwrap(); 24 | let pages_to_reproduce: Vec> = pages_to_reproduce_text 25 | .lines() 26 | .map(|line| line.split(',').map(|n| n.parse::().unwrap()).collect()) 27 | .collect(); 28 | 29 | // A. 30 | let sum: i32 = pages_to_reproduce 31 | .iter() 32 | .filter(|page| { 33 | page_ordering_rules.iter().all(|&(left_rule, right_rule)| { 34 | let left_index = page.iter().position(|&r| r == left_rule); 35 | let right_index = page.iter().position(|&r| r == right_rule); 36 | 37 | match (left_index, right_index) { 38 | (Some(left), Some(right)) => left <= right, 39 | _ => true, 40 | } 41 | }) 42 | }) 43 | .map(|page| *(page.get(page.len() / 2).unwrap()) as i32) 44 | .sum(); 45 | println!("Result: {}", sum); 46 | 47 | // B. 48 | let mut sum: i32 = 0; 49 | let mut failed_rows = Vec::new(); 50 | for page in &pages_to_reproduce { 51 | for rule in &page_ordering_rules { 52 | let left_index = page.iter().position(|&r| r == rule.0); 53 | let right_index = page.iter().position(|&r| r == rule.1); 54 | 55 | if left_index.is_some() && right_index.is_some() { 56 | if left_index.unwrap() > right_index.unwrap() { 57 | failed_rows.push(page); 58 | break; 59 | } 60 | } 61 | } 62 | } 63 | for failed_row in failed_rows { 64 | let mut graph = DiGraph::<&i8, ()>::new(); 65 | for number in failed_row { 66 | graph.add_node(number); 67 | } 68 | for first in failed_row { 69 | for second in failed_row { 70 | let rule = page_ordering_rules 71 | .iter() 72 | .position(|&r| r.0 == *first && r.1 == *second); 73 | if rule.is_some() { 74 | let first_node = find_node_by_value(&graph, first); 75 | let second_node = find_node_by_value(&graph, second); 76 | graph.add_edge(first_node.unwrap(), second_node.unwrap(), ()); 77 | } 78 | } 79 | } 80 | let mut no_inbound = Vec::new(); 81 | for node in graph.node_indices() { 82 | if graph 83 | .neighbors_directed(node, Direction::Incoming) 84 | .next() 85 | .is_none() 86 | { 87 | no_inbound.push(node); 88 | } 89 | } 90 | 91 | let mut nodes: Vec<(NodeIndex, usize, usize)> = graph 92 | .node_indices() 93 | .map(|node| { 94 | let incoming_count = graph 95 | .neighbors_directed(node, Direction::Incoming) 96 | .count(); 97 | let outgoing_count = graph 98 | .neighbors_directed(node, Direction::Outgoing) 99 | .count(); 100 | (node, incoming_count, outgoing_count) 101 | }) 102 | .collect(); 103 | 104 | nodes.sort_by_key(|&(_, incoming_count, outgoing_count)| (incoming_count, outgoing_count)); 105 | 106 | 107 | let middle_index = nodes.len() / 2; 108 | let middle_node = nodes[middle_index].0; 109 | let middle_value = graph[middle_node]; 110 | sum = sum + *middle_value as i32; 111 | } 112 | println!("Result: {}", sum); 113 | } 114 | 115 | fn find_node_by_value(graph: &DiGraph<&i8, ()>, value: &i8) -> Option { 116 | for (node_index, node_value) in graph.node_references() { 117 | if *node_value == value { 118 | return Some(node_index); 119 | } 120 | } 121 | None 122 | } 123 | -------------------------------------------------------------------------------- /src/day14.rs: -------------------------------------------------------------------------------- 1 | use regex::Regex; 2 | use std::array; 3 | use std::fs::File; 4 | use std::io::{BufRead, BufReader}; 5 | 6 | #[derive(Debug, Clone, Copy)] 7 | struct Robot { 8 | x: i32, 9 | y: i32, 10 | velocity_x: i32, 11 | velocity_y: i32, 12 | } 13 | 14 | fn read_input(path: &str) -> std::io::Result> { 15 | let file = File::open(path)?; 16 | let reader = BufReader::new(file); 17 | 18 | let re = Regex::new(r"^p=(-?\d+),(-?\d+)\s+v=(-?\d+),(-?\d+)$").unwrap(); 19 | 20 | let mut robots = Vec::new(); 21 | let mut lines = reader.lines().filter_map(|l| l.ok()); 22 | 23 | while let Some(line) = lines.next() { 24 | if let Some(caps) = re.captures(&line) { 25 | let p1 = caps.get(1).unwrap().as_str(); 26 | let p2 = caps.get(2).unwrap().as_str(); 27 | let v1 = caps.get(3).unwrap().as_str(); 28 | let v2 = caps.get(4).unwrap().as_str(); 29 | 30 | robots.push(Robot { 31 | x: p1.parse::().unwrap(), 32 | y: p2.parse::().unwrap(), 33 | velocity_x: v1.parse::().unwrap(), 34 | velocity_y: v2.parse::().unwrap(), 35 | }); 36 | } else { 37 | println!("No match found."); 38 | } 39 | } 40 | 41 | Ok(robots) 42 | } 43 | 44 | pub fn solution() { 45 | let robots = read_input("./inputs/day14.txt").unwrap(); 46 | 47 | const WIDE: usize = 101; 48 | const TALL: usize = 103; 49 | 50 | // A 51 | const SECONDS: i32 = 100; 52 | let middle_x = (WIDE as i32) / 2; 53 | let middle_y = (TALL as i32) / 2; 54 | let mut robots_a = robots.clone(); 55 | let mut quadrant_counts = [0; 4]; 56 | for robot in &mut robots_a { 57 | robot.x = (robot.x + SECONDS * robot.velocity_x) % (WIDE as i32); 58 | robot.y = (robot.y + SECONDS * robot.velocity_y) % (TALL as i32); 59 | 60 | if robot.x < 0 { 61 | robot.x += WIDE as i32; 62 | } 63 | if robot.y < 0 { 64 | robot.y += TALL as i32; 65 | } 66 | if robot.x != middle_x && robot.y != middle_y { 67 | if robot.x > middle_x && robot.y < middle_y { 68 | quadrant_counts[0] += 1; 69 | } else if robot.x < middle_x && robot.y < middle_y { 70 | quadrant_counts[1] += 1; 71 | } else if robot.x < middle_x && robot.y > middle_y { 72 | quadrant_counts[2] += 1; 73 | } else if robot.x > middle_x && robot.y > middle_y { 74 | quadrant_counts[3] += 1; 75 | } 76 | } 77 | 78 | } 79 | 80 | let result = quadrant_counts[0] * quadrant_counts[1] * quadrant_counts[2] * quadrant_counts[3]; 81 | println!("Result A: {}", result); 82 | 83 | // B 84 | for second in 0.. { 85 | let mut robots_b = robots.clone(); 86 | let mut tiles: [[String; WIDE]; TALL] = 87 | array::from_fn(|_| array::from_fn(|_| String::from("."))); 88 | tiles 89 | .iter_mut() 90 | .for_each(|row| row.iter_mut().for_each(|tile| *tile = String::from("."))); 91 | 92 | for robot in &mut robots_b { 93 | robot.x = (robot.x + second * robot.velocity_x) % (WIDE as i32); 94 | robot.y = (robot.y + second * robot.velocity_y) % (TALL as i32); 95 | 96 | if robot.x < 0 { 97 | robot.x += WIDE as i32; 98 | } 99 | if robot.y < 0 { 100 | robot.y += TALL as i32; 101 | } 102 | 103 | tiles[robot.y as usize][robot.x as usize] = "#".to_string(); 104 | } 105 | 106 | let mut expected_longest = 1; 107 | let mut increase_count = 0; 108 | 109 | for (_, row) in tiles.iter().enumerate() { 110 | let mut current_longest = 0; 111 | let mut count = 0; 112 | 113 | for tile in row { 114 | if tile == "#" { 115 | count += 1; 116 | if count > current_longest { 117 | current_longest = count; 118 | } 119 | } else { 120 | count = 0; 121 | } 122 | } 123 | 124 | if current_longest == expected_longest { 125 | increase_count += 1; 126 | expected_longest += 2; // should be symmetric 127 | } 128 | 129 | } 130 | if increase_count > 5 { 131 | println!("Result B: {}", second); 132 | break; 133 | } 134 | 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/day24.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{HashMap, HashSet}; 2 | use std::fs; 3 | 4 | pub fn solution() { 5 | let input = fs::read_to_string("./inputs/day24.txt").unwrap(); 6 | let lines: Vec<&str> = input 7 | .lines() 8 | .map(str::trim) 9 | .filter(|l| !l.is_empty()) 10 | .collect(); 11 | let mut init = HashMap::new(); 12 | let mut gs = Vec::new(); 13 | 14 | // A. 15 | let mut parsing_init = true; 16 | for l in &lines { 17 | if parsing_init { 18 | if let Some((w, v)) = l.split_once(':') { 19 | let v = v.trim(); 20 | if v == "0" || v == "1" { 21 | init.insert(w.trim().to_string(), v == "1"); 22 | } else { 23 | parsing_init = false; 24 | } 25 | } else { 26 | parsing_init = false; 27 | } 28 | } 29 | if !parsing_init { 30 | let parts: Vec<_> = l.split("->").collect(); 31 | if parts.len() != 2 { 32 | continue; 33 | } 34 | let s: Vec<_> = parts[0].split_whitespace().collect(); 35 | if s.len() != 3 { 36 | continue; 37 | } 38 | let g = match s[1].to_uppercase().as_str() { 39 | "AND" => 'A', 40 | "OR" => 'O', 41 | "XOR" => 'X', 42 | _ => continue, 43 | }; 44 | gs.push(( 45 | s[0].to_string(), 46 | s[2].to_string(), 47 | parts[1].trim().to_string(), 48 | g, 49 | )); 50 | } 51 | } 52 | let mut wires = HashMap::new(); 53 | for (k, &v) in &init { 54 | wires.insert(k.clone(), Some(v)); 55 | } 56 | for (a, b, o, _) in &gs { 57 | wires.entry(a.clone()).or_insert(None); 58 | wires.entry(b.clone()).or_insert(None); 59 | wires.entry(o.clone()).or_insert(None); 60 | } 61 | let mut change = true; 62 | while change { 63 | change = false; 64 | for (a, b, o, g) in &gs { 65 | if let (Some(a_val), Some(b_val)) = (wires[a], wires[b]) { 66 | let r = match g { 67 | 'A' => a_val && b_val, 68 | 'O' => a_val || b_val, 69 | 'X' => a_val ^ b_val, 70 | _ => false, 71 | }; 72 | if wires[o] != Some(r) { 73 | wires.insert(o.clone(), Some(r)); 74 | change = true; 75 | } 76 | } 77 | } 78 | } 79 | let mut zs: Vec<_> = wires.keys().filter(|x| x.starts_with('z')).collect(); 80 | zs.sort_by_key(|x| x[1..].parse::().unwrap_or(0)); 81 | let dec = zs.iter().enumerate().fold(0u64, |acc, (i, k)| { 82 | acc | ((wires[*k] == Some(true)) as u64) << i 83 | }); 84 | println!("Part A: {}", dec); 85 | 86 | // B. 87 | let connections = input.split_once("\n\n").map(|(_, c)| c).unwrap(); 88 | let parsed: Vec<(String, char, String, String)> = connections 89 | .lines() 90 | .filter_map(|line| { 91 | let tokens: Vec<_> = line.split_whitespace().collect(); 92 | if tokens.len() >= 5 && tokens[3] == "->" { 93 | let op = match tokens[1].to_uppercase().as_str() { 94 | "AND" => 'A', 95 | "OR" => 'O', 96 | "XOR" => 'X', 97 | _ => return None, 98 | }; 99 | Some(( 100 | tokens[0].to_string(), 101 | op, 102 | tokens[2].to_string(), 103 | tokens[4].to_string(), 104 | )) 105 | } else { 106 | None 107 | } 108 | }) 109 | .collect(); 110 | let connection_cache: HashSet<_> = parsed 111 | .iter() 112 | .flat_map(|(l, op, r, _)| [(l.clone(), *op), (r.clone(), *op)]) 113 | .collect(); 114 | let mut results: Vec = parsed 115 | .iter() 116 | .filter_map(|(l, op, r, ret)| match *op { 117 | 'A' if l != "x00" && r != "x00" && !connection_cache.contains(&(ret.clone(), 'O')) => { 118 | Some(ret.clone()) 119 | } 120 | 'X' if ((l.starts_with('x') || r.starts_with('x')) 121 | && l != "x00" 122 | && r != "x00" 123 | && !connection_cache.contains(&(ret.clone(), 'X'))) 124 | || (!ret.starts_with('z') && !l.starts_with('x') && !r.starts_with('x')) => 125 | { 126 | Some(ret.clone()) 127 | } 128 | 'O' if ret.starts_with('z') && ret != "z45" => Some(ret.clone()), 129 | _ => None, 130 | }) 131 | .collect(); 132 | results.sort(); 133 | println!("Part B: {}", results.join(",")); 134 | } 135 | -------------------------------------------------------------------------------- /src/day12.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::fs::File; 3 | use std::io::{self, BufRead}; 4 | 5 | use petgraph::adj::NodeIndex; 6 | use petgraph::algo; 7 | use petgraph::prelude::UnGraphMap; 8 | use petgraph::visit::IntoNodeReferences; 9 | 10 | pub fn solution() { 11 | let aoc_2024_12 = File::open("./inputs/day12.txt").expect("Failed to open file"); 12 | let grid: Vec> = io::BufReader::new(aoc_2024_12) 13 | .lines() 14 | .filter_map(|line| line.ok()) 15 | .map(|line| line.chars().collect()) 16 | .collect(); 17 | 18 | let rows = grid.len() as i32; 19 | let cols = grid[0].len() as i32; 20 | 21 | let mut visited = HashSet::new(); 22 | let directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]; 23 | 24 | let mut total_sum = 0; 25 | 26 | for r in 0..rows { 27 | for c in 0..cols { 28 | if visited.contains(&(r, c)) { 29 | continue; 30 | } 31 | 32 | let mut queue = vec![(r, c)]; 33 | visited.insert((r, c)); 34 | 35 | let mut group_size = 0; 36 | let mut perimeter = 0; 37 | 38 | while let Some((x, y)) = queue.pop() { 39 | let value = grid[x as usize][y as usize]; 40 | let mut local_perimeter = 4; 41 | group_size += 1; 42 | 43 | for &(dx, dy) in &directions { 44 | let nx = x + dx; 45 | let ny = y + dy; 46 | 47 | if nx >= 0 && nx < rows && ny >= 0 && ny < cols { 48 | if grid[nx as usize][ny as usize] == value { 49 | if visited.insert((nx, ny)) { 50 | queue.push((nx, ny)); 51 | } 52 | local_perimeter -= 1; 53 | } 54 | } 55 | } 56 | perimeter += local_perimeter; 57 | } 58 | total_sum += group_size * perimeter; 59 | } 60 | } 61 | println!("Result: {}", total_sum); 62 | 63 | // B. 64 | let mut graph = UnGraphMap::<(i32, i32), ()>::new(); 65 | 66 | for y in 0..rows { 67 | for x in 0..cols { 68 | // Add node to the graph 69 | let node = graph.add_node((x, y)); 70 | let c = grid[y as usize][x as usize]; 71 | 72 | // Add edges to the graph 73 | for &(dx, dy) in &directions { 74 | let nx = x + dx; 75 | let ny = y + dy; 76 | 77 | // Check if the node is within the grid 78 | if nx >= 0 && nx < cols && ny >= 0 && ny < rows { 79 | if grid[ny as usize][nx as usize] == c { 80 | graph.add_edge(node, (nx, ny), ()); 81 | } 82 | } 83 | } 84 | } 85 | } 86 | 87 | let graph = algo::condensation(graph.into_graph::(), false); 88 | let sum = graph.node_references().map(|(_, nodes)| { 89 | let id = grid[nodes[0].1 as usize][nodes[0].0 as usize]; 90 | let node_size = nodes.len(); 91 | let perimeter = nodes 92 | .iter() 93 | .map(|n| { 94 | let mut count = 0; 95 | 96 | for i in 0..4 { 97 | let (dx, dy) = directions[i]; 98 | let (dx1, dy1) = directions[(i + 1) % 4]; 99 | 100 | let first_neighbor_same_region = { 101 | let nx = n.0 + dx; 102 | let ny = n.1 + dy; 103 | nx >= 0 104 | && ny >= 0 105 | && (ny as usize) < grid.len() 106 | && (nx as usize) < grid[ny as usize].len() 107 | && grid[ny as usize][nx as usize] == id 108 | }; 109 | 110 | let second_neighbor_same_region = { 111 | let nx = n.0 + dx1; 112 | let ny = n.1 + dy1; 113 | nx >= 0 114 | && ny >= 0 115 | && (ny as usize) < grid.len() 116 | && (nx as usize) < grid[ny as usize].len() 117 | && grid[ny as usize][nx as usize] == id 118 | }; 119 | 120 | let diagonal_test = { 121 | let nx = n.0 + dx + dx1; 122 | let ny = n.1 + dy + dy1; 123 | nx >= 0 124 | && ny >= 0 125 | && (ny as usize) < grid.len() 126 | && (nx as usize) < grid[ny as usize].len() 127 | && grid[ny as usize][nx as usize] != id 128 | }; 129 | 130 | if first_neighbor_same_region && second_neighbor_same_region && diagonal_test { 131 | count += 1; 132 | } else if !first_neighbor_same_region && !second_neighbor_same_region { 133 | count += 1; 134 | } 135 | } 136 | 137 | count 138 | }) 139 | .sum::(); 140 | 141 | node_size * perimeter 142 | }); 143 | 144 | println!("Result: {}", sum.sum::()); 145 | } 146 | -------------------------------------------------------------------------------- /src/day16.rs: -------------------------------------------------------------------------------- 1 | use pathfinding::prelude::dijkstra_all; 2 | use std::{collections::HashMap, fs, path::Path}; 3 | 4 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] 5 | struct State { 6 | row: usize, 7 | col: usize, 8 | dir: usize, 9 | } 10 | 11 | pub fn solution() { 12 | let input = fs::read_to_string(Path::new("./inputs/day16.txt")).unwrap(); 13 | let maze = input.lines().collect::>(); 14 | let rows = maze.len(); 15 | let cols = if rows > 0 { maze[0].len() } else { 0 }; 16 | let maze_grid = maze 17 | .iter() 18 | .map(|line| line.chars().collect()) 19 | .collect::>>(); 20 | 21 | // A. 22 | let (mut start_row, mut start_col) = (0, 0); 23 | let (mut end_row, mut end_col) = (0, 0); 24 | for r in 0..rows { 25 | for c in 0..cols { 26 | match maze_grid[r][c] { 27 | 'S' => { 28 | start_row = r; 29 | start_col = c; 30 | } 31 | 'E' => { 32 | end_row = r; 33 | end_col = c; 34 | } 35 | _ => {} 36 | } 37 | } 38 | } 39 | 40 | let forward_successors = |&State { row, col, dir }: &State| -> Vec<(State, u64)> { 41 | let mut next = Vec::with_capacity(3); 42 | 43 | next.push(( 44 | State { 45 | row, 46 | col, 47 | dir: (dir + 3) % 4, 48 | }, 49 | 1000, 50 | )); 51 | 52 | next.push(( 53 | State { 54 | row, 55 | col, 56 | dir: (dir + 1) % 4, 57 | }, 58 | 1000, 59 | )); 60 | 61 | let (dr, dc) = match dir { 62 | 0 => (0, 1), 63 | 1 => (1, 0), 64 | 2 => (0, -1), 65 | 3 => (-1, 0), 66 | _ => unreachable!(), 67 | }; 68 | 69 | let nr = row as isize + dr; 70 | let nc = col as isize + dc; 71 | if nr >= 0 && nr < rows as isize && nc >= 0 && nc < cols as isize { 72 | if maze_grid[nr as usize][nc as usize] != '#' { 73 | next.push(( 74 | State { 75 | row: nr as usize, 76 | col: nc as usize, 77 | dir, 78 | }, 79 | 1, 80 | )); 81 | } 82 | } 83 | next 84 | }; 85 | 86 | let start_state = State { 87 | row: start_row, 88 | col: start_col, 89 | dir: 0, 90 | }; 91 | 92 | let dist_s_map = dijkstra_all(&start_state, forward_successors); 93 | let mut best_score = u64::MAX; 94 | 95 | for d in 0..4 { 96 | let e_state = State { 97 | row: end_row, 98 | col: end_col, 99 | dir: d, 100 | }; 101 | if let Some((_, cost)) = dist_s_map.get(&e_state) { 102 | best_score = best_score.min(*cost); 103 | } 104 | } 105 | 106 | println!("Result: {}", best_score); 107 | 108 | // B. 109 | let reverse_successors = |&State { row, col, dir }: &State| -> Vec<(State, u64)> { 110 | let mut neighbors = Vec::with_capacity(3); 111 | 112 | neighbors.push(( 113 | State { 114 | row, 115 | col, 116 | dir: (dir + 1) % 4, 117 | }, 118 | 1000, 119 | )); 120 | 121 | neighbors.push(( 122 | State { 123 | row, 124 | col, 125 | dir: (dir + 3) % 4, 126 | }, 127 | 1000, 128 | )); 129 | 130 | let (dr, dc) = match dir { 131 | 0 => (0, -1), 132 | 1 => (-1, 0), 133 | 2 => (0, 1), 134 | 3 => (1, 0), 135 | _ => unreachable!(), 136 | }; 137 | 138 | let rr = row as isize + dr; 139 | let cc = col as isize + dc; 140 | 141 | if rr >= 0 && rr < rows as isize && cc >= 0 && cc < cols as isize { 142 | if maze_grid[rr as usize][cc as usize] != '#' { 143 | neighbors.push(( 144 | State { 145 | row: rr as usize, 146 | col: cc as usize, 147 | dir, 148 | }, 149 | 1, 150 | )); 151 | } 152 | } 153 | neighbors 154 | }; 155 | 156 | let mut dist_e_map = HashMap::::new(); 157 | for d in 0..4 { 158 | let e_state = State { 159 | row: end_row, 160 | col: end_col, 161 | dir: d, 162 | }; 163 | let partial_map = dijkstra_all(&e_state, reverse_successors); 164 | 165 | for (st, (_, cost)) in partial_map { 166 | dist_e_map 167 | .entry(st) 168 | .and_modify(|existing| { 169 | if cost < existing.1 { 170 | existing.1 = cost; 171 | } 172 | }) 173 | .or_insert((e_state, cost)); 174 | } 175 | } 176 | 177 | let mut on_best_path = vec![vec![false; cols]; rows]; 178 | for (&st, &(_, cost_s)) in &dist_s_map { 179 | if let Some((_, cost_e)) = dist_e_map.get(&st) { 180 | if cost_s + cost_e == best_score { 181 | on_best_path[st.row][st.col] = true; 182 | } 183 | } 184 | } 185 | 186 | on_best_path[start_row][start_col] = true; 187 | on_best_path[end_row][end_col] = true; 188 | 189 | let count = on_best_path 190 | .iter() 191 | .flat_map(|row| row.iter()) 192 | .filter(|&&b| b) 193 | .count(); 194 | 195 | println!("Result: {}", count); 196 | } 197 | -------------------------------------------------------------------------------- /src/day20.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | collections::{HashMap, VecDeque}, 3 | fs, 4 | io::{self, BufRead}, 5 | }; 6 | 7 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] 8 | struct Pos { 9 | r: usize, 10 | c: usize, 11 | } 12 | 13 | pub fn solution() { 14 | let file = fs::File::open("./inputs/day20.txt").expect("Failed to open file"); 15 | let reader = io::BufReader::new(file); 16 | 17 | let map: Vec = reader 18 | .lines() 19 | .map(|line| line.expect("Could not parse line")) 20 | .collect(); 21 | 22 | let mut start = Pos { r: 0, c: 0 }; 23 | let mut end = Pos { r: 0, c: 0 }; 24 | let rows = map.len(); 25 | let cols = map[0].len(); 26 | 27 | for r in 0..rows { 28 | for c in 0..cols { 29 | let ch = map[r].chars().nth(c).unwrap(); 30 | if ch == 'S' { 31 | start = Pos { r, c }; 32 | } else if ch == 'E' { 33 | end = Pos { r, c }; 34 | } 35 | } 36 | } 37 | 38 | let dist_from_start = bfs_no_cheat_from(&map, start); 39 | let dist_from_end = bfs_no_cheat_from(&map, end); 40 | let dist_no_cheat = *dist_from_start.get(&end).unwrap(); 41 | 42 | let count_2 = count_cheats_saving_100( 43 | &map, 44 | &dist_from_start, 45 | &dist_from_end, 46 | dist_no_cheat, 47 | 2 48 | ); 49 | println!("Result A: {}", count_2); 50 | 51 | let count_20 = count_cheats_saving_100( 52 | &map, 53 | &dist_from_start, 54 | &dist_from_end, 55 | dist_no_cheat, 56 | 20 57 | ); 58 | println!("Result B: {}", count_20); 59 | } 60 | 61 | fn bfs_no_cheat_from(map: &[String], start: Pos) -> HashMap { 62 | let rows = map.len(); 63 | let cols = map[0].len(); 64 | 65 | let mut dist_map = HashMap::::new(); 66 | let mut visited = vec![vec![false; cols]; rows]; 67 | 68 | visited[start.r][start.c] = true; 69 | dist_map.insert(start, 0); 70 | 71 | let mut queue = VecDeque::new(); 72 | queue.push_back(start); 73 | 74 | let directions = [(1,0), (-1,0), (0,1), (0,-1)]; 75 | 76 | while let Some(cur) = queue.pop_front() { 77 | let current_dist = dist_map[&cur]; 78 | for (dr, dc) in directions { 79 | let nr = cur.r as isize + dr; 80 | let nc = cur.c as isize + dc; 81 | if nr < 0 || nc < 0 { 82 | continue; 83 | } 84 | let nr = nr as usize; 85 | let nc = nc as usize; 86 | if nr < rows && nc < cols && !visited[nr][nc] { 87 | let ch = map[nr].chars().nth(nc).unwrap(); 88 | if ch != '#' { 89 | visited[nr][nc] = true; 90 | let nxt = Pos { r: nr, c: nc }; 91 | dist_map.insert(nxt, current_dist + 1); 92 | queue.push_back(nxt); 93 | } 94 | } 95 | } 96 | } 97 | 98 | dist_map 99 | } 100 | 101 | fn count_cheats_saving_100( 102 | map: &[String], 103 | dist_s: &HashMap, 104 | dist_e: &HashMap, 105 | dist_no_cheat: usize, 106 | max_steps: usize, 107 | ) -> usize { 108 | let mut cheat_best_dist = HashMap::<(Pos, Pos), usize>::new(); 109 | 110 | let is_track = |r: usize, c: usize| { 111 | let ch = map[r].chars().nth(c).unwrap(); 112 | ch != '#' 113 | }; 114 | 115 | for (&x, &dist_sx) in dist_s.iter() { 116 | if !is_track(x.r, x.c) { 117 | continue; 118 | } 119 | 120 | let mut visited_steps = vec![vec![None; map[0].len()]; map.len()]; 121 | visited_steps[x.r][x.c] = Some(0); 122 | let mut queue = VecDeque::new(); 123 | queue.push_back(x); 124 | 125 | while let Some(cur) = queue.pop_front() { 126 | let steps_so_far = visited_steps[cur.r][cur.c].unwrap(); 127 | if steps_so_far >= max_steps { 128 | continue; 129 | } 130 | 131 | for (dr, dc) in [(1, 0), (-1, 0), (0, 1), (0, -1)] { 132 | let nr = cur.r as isize + dr; 133 | let nc = cur.c as isize + dc; 134 | if nr < 0 || nc < 0 { 135 | continue; 136 | } 137 | let nr = nr as usize; 138 | let nc = nc as usize; 139 | if nr >= map.len() || nc >= map[0].len() { 140 | continue; 141 | } 142 | // ignoring walls => always can go 143 | if visited_steps[nr][nc].is_none() { 144 | visited_steps[nr][nc] = Some(steps_so_far + 1); 145 | queue.push_back(Pos { r: nr, c: nc }); 146 | } 147 | } 148 | } 149 | 150 | // Evaluate each reachable y for 1 <= steps <= max_steps 151 | for r in 0..map.len() { 152 | for c in 0..map[0].len() { 153 | if let Some(steps) = visited_steps[r][c] { 154 | if steps >= 1 && steps <= max_steps && is_track(r, c) { 155 | let y = Pos { r, c }; 156 | if let Some(&dist_ey) = dist_e.get(&y) { 157 | let candidate_dist = dist_sx + steps + dist_ey; 158 | let entry = cheat_best_dist.entry((x, y)).or_insert(candidate_dist); 159 | if candidate_dist < *entry { 160 | *entry = candidate_dist; 161 | } 162 | } 163 | } 164 | } 165 | } 166 | } 167 | } 168 | 169 | let mut count_ge_100 = 0; 170 | for &cheat_dist in cheat_best_dist.values() { 171 | let saving = dist_no_cheat.saturating_sub(cheat_dist); 172 | if saving >= 100 { 173 | count_ge_100 += 1; 174 | } 175 | } 176 | count_ge_100 177 | } 178 | -------------------------------------------------------------------------------- /inputs/day24.txt: -------------------------------------------------------------------------------- 1 | x00: 1 2 | x01: 0 3 | x02: 1 4 | x03: 1 5 | x04: 0 6 | x05: 0 7 | x06: 1 8 | x07: 1 9 | x08: 0 10 | x09: 1 11 | x10: 1 12 | x11: 1 13 | x12: 1 14 | x13: 1 15 | x14: 1 16 | x15: 0 17 | x16: 0 18 | x17: 1 19 | x18: 0 20 | x19: 0 21 | x20: 0 22 | x21: 0 23 | x22: 0 24 | x23: 1 25 | x24: 0 26 | x25: 0 27 | x26: 1 28 | x27: 1 29 | x28: 0 30 | x29: 1 31 | x30: 1 32 | x31: 0 33 | x32: 0 34 | x33: 0 35 | x34: 0 36 | x35: 1 37 | x36: 0 38 | x37: 1 39 | x38: 1 40 | x39: 0 41 | x40: 1 42 | x41: 0 43 | x42: 1 44 | x43: 0 45 | x44: 1 46 | y00: 1 47 | y01: 0 48 | y02: 0 49 | y03: 1 50 | y04: 1 51 | y05: 0 52 | y06: 0 53 | y07: 0 54 | y08: 0 55 | y09: 0 56 | y10: 0 57 | y11: 1 58 | y12: 0 59 | y13: 0 60 | y14: 1 61 | y15: 1 62 | y16: 1 63 | y17: 0 64 | y18: 1 65 | y19: 0 66 | y20: 1 67 | y21: 0 68 | y22: 1 69 | y23: 0 70 | y24: 0 71 | y25: 0 72 | y26: 0 73 | y27: 1 74 | y28: 1 75 | y29: 0 76 | y30: 1 77 | y31: 1 78 | y32: 1 79 | y33: 1 80 | y34: 1 81 | y35: 0 82 | y36: 1 83 | y37: 1 84 | y38: 0 85 | y39: 0 86 | y40: 1 87 | y41: 1 88 | y42: 0 89 | y43: 1 90 | y44: 1 91 | 92 | y16 AND x16 -> bss 93 | wrt OR pss -> fjs 94 | qpd AND hnk -> tdb 95 | ncp AND drd -> ktn 96 | vnw AND ftq -> kgt 97 | y12 XOR x12 -> dbg 98 | y05 AND x05 -> jfq 99 | x16 XOR y16 -> grr 100 | y39 AND x39 -> tbr 101 | crp AND gkk -> qkk 102 | x02 AND y02 -> jrf 103 | x09 AND y09 -> nwn 104 | vmf AND bkp -> rjw 105 | qpd XOR hnk -> z34 106 | x06 XOR y06 -> kcc 107 | x30 AND y30 -> bgj 108 | rhk AND btv -> rmv 109 | fjs XOR bmv -> z44 110 | btv XOR rhk -> z25 111 | wgk OR ppp -> vnc 112 | kcm XOR grr -> fkb 113 | fkb AND rcc -> fbb 114 | dbd XOR shb -> z15 115 | y38 XOR x38 -> vsq 116 | sfs OR hmh -> qpd 117 | bmv AND fjs -> kwh 118 | ftq XOR vnw -> z11 119 | cjt OR svk -> kcm 120 | y33 XOR x33 -> ttn 121 | x18 XOR y18 -> dwd 122 | qpk OR btq -> nkn 123 | nnq OR pfb -> mfc 124 | crp XOR gkk -> z39 125 | x28 AND y28 -> dwg 126 | y07 XOR x07 -> ncp 127 | ssf AND hqr -> swq 128 | mfc AND hdk -> pqk 129 | y44 XOR x44 -> bmv 130 | x35 XOR y35 -> jdq 131 | y30 XOR x30 -> jnr 132 | x32 XOR y32 -> dfn 133 | ccw OR fbb -> hnq 134 | pqk OR dwg -> rsj 135 | jrk OR cpr -> kgn 136 | x01 AND y01 -> kmf 137 | kcm AND grr -> tnn 138 | y28 XOR x28 -> hdk 139 | mtb AND jdk -> fmr 140 | y29 XOR x29 -> ccs 141 | vhv OR cbh -> btv 142 | hdk XOR mfc -> z28 143 | dbg AND bcq -> wgk 144 | x11 XOR y11 -> ftq 145 | y04 XOR x04 -> mtb 146 | vnm AND mgr -> phc 147 | jfq OR tsw -> ksh 148 | gcg XOR nbm -> rrn 149 | wdv OR qph -> mcv 150 | x19 AND y19 -> pdb 151 | rqf XOR hvv -> z21 152 | y27 AND x27 -> nnq 153 | rdg OR scw -> jmt 154 | qkk OR tbr -> ggg 155 | jtm AND rqw -> tsw 156 | ccs AND rsj -> thq 157 | kgt OR qmm -> bcq 158 | kwh OR qqr -> z45 159 | twj XOR qft -> z08 160 | ttn AND jmt -> hmh 161 | y44 AND x44 -> qqr 162 | x03 XOR y03 -> mgr 163 | x40 AND y40 -> ntw 164 | jmt XOR ttn -> z33 165 | x43 XOR y43 -> dnf 166 | rmv OR smj -> hnv 167 | y17 AND x17 -> ccw 168 | y22 XOR x22 -> jck 169 | tph AND hbk -> jhd 170 | x34 AND y34 -> hrd 171 | ssf XOR hqr -> z19 172 | y37 AND x37 -> z37 173 | y04 AND x04 -> dgw 174 | qft AND twj -> qpn 175 | tnn OR bss -> z16 176 | x12 AND y12 -> ppp 177 | kmf OR cdb -> qnf 178 | vsq XOR jrg -> z38 179 | ccs XOR rsj -> z29 180 | y01 XOR x01 -> jnj 181 | mtb XOR jdk -> z04 182 | y21 AND x21 -> rqf 183 | hnq XOR dwd -> z18 184 | x19 XOR y19 -> ssf 185 | y34 XOR x34 -> hnk 186 | shp AND kcp -> pkv 187 | x08 XOR y08 -> twj 188 | fvc OR pkv -> thm 189 | x41 AND y41 -> gtv 190 | x06 AND y06 -> qmr 191 | qsj AND tjk -> z31 192 | vhj OR rrn -> jrg 193 | jrg AND vsq -> tkt 194 | y15 AND x15 -> svk 195 | prt XOR jnj -> z01 196 | shb AND dbd -> cjt 197 | hbc AND qst -> vhv 198 | x10 AND y10 -> vsm 199 | bkp XOR vmf -> z10 200 | y33 AND x33 -> sfs 201 | kgn XOR pgq -> z14 202 | y36 AND x36 -> fjn 203 | x00 XOR y00 -> z00 204 | y40 XOR x40 -> wqg 205 | vsm OR rjw -> vnw 206 | y42 XOR x42 -> kcp 207 | y29 AND x29 -> knv 208 | nbm AND gcg -> vhj 209 | y13 AND x13 -> cpr 210 | y32 AND x32 -> scw 211 | dgr AND vnc -> jrk 212 | thm XOR dnf -> z43 213 | bgj OR chb -> qsj 214 | qsj XOR tjk -> rdn 215 | thq OR knv -> rbk 216 | sqr AND njb -> smh 217 | x15 XOR y15 -> shb 218 | qfv OR qcm -> rcm 219 | x25 XOR y25 -> rhk 220 | y31 XOR x31 -> tjk 221 | rdn OR pct -> vtb 222 | sqr XOR njb -> z20 223 | fjc XOR rcm -> z27 224 | x42 AND y42 -> fvc 225 | y14 AND x14 -> qtq 226 | x36 XOR y36 -> ckw 227 | y39 XOR x39 -> gkk 228 | gtv OR jhd -> shp 229 | x38 AND y38 -> knb 230 | kgn AND pgq -> rhw 231 | sfw AND jck -> qpk 232 | pwb XOR jdq -> z35 233 | y05 XOR x05 -> rqw 234 | x23 XOR y23 -> crt 235 | x09 XOR y09 -> jtc 236 | ksh XOR kcc -> z06 237 | hnv AND mcj -> qcm 238 | y17 XOR x17 -> rcc 239 | y23 AND x23 -> nbr 240 | bqm OR qpn -> vrr 241 | fpv OR smh -> hvv 242 | swq OR pdb -> njb 243 | x13 XOR y13 -> dgr 244 | jnj AND prt -> cdb 245 | x10 XOR y10 -> vmf 246 | y37 XOR x37 -> gcg 247 | x21 XOR y21 -> nnr 248 | qst XOR hbc -> z24 249 | rcm AND fjc -> pfb 250 | y18 AND x18 -> pnv 251 | wqg AND ggg -> fvv 252 | mcj XOR hnv -> z26 253 | dwd AND hnq -> cdt 254 | wsm XOR qnf -> z02 255 | vnm XOR mgr -> z03 256 | sfw XOR jck -> z22 257 | x08 AND y08 -> bqm 258 | qmr OR fjt -> drd 259 | cdt OR pnv -> hqr 260 | ksh AND kcc -> fjt 261 | wqt OR ktn -> qft 262 | y24 AND x24 -> cbh 263 | x00 AND y00 -> prt 264 | dgr XOR vnc -> z13 265 | vrr XOR jtc -> z09 266 | fmr OR dgw -> jtm 267 | jnr AND rbk -> chb 268 | rqf AND hvv -> jsd 269 | x11 AND y11 -> qmm 270 | y31 AND x31 -> pct 271 | jrf OR shr -> vnm 272 | ckw AND mcv -> crk 273 | x43 AND y43 -> pss 274 | jnr XOR rbk -> z30 275 | x20 AND y20 -> fpv 276 | ntw OR fvv -> tph 277 | x14 XOR y14 -> pgq 278 | tph XOR hbk -> z41 279 | nbr OR spp -> qst 280 | ckw XOR mcv -> z36 281 | pps OR phc -> jdk 282 | vrr AND jtc -> hwp 283 | jdq AND pwb -> wdv 284 | y20 XOR x20 -> sqr 285 | crk OR fjn -> nbm 286 | hwp OR nwn -> bkp 287 | wsm AND qnf -> shr 288 | x26 AND y26 -> qfv 289 | y26 XOR x26 -> mcj 290 | crt XOR nkn -> z23 291 | ncp XOR drd -> z07 292 | vtb AND dfn -> rdg 293 | wqg XOR ggg -> z40 294 | x27 XOR y27 -> fjc 295 | fkb XOR rcc -> z17 296 | vtb XOR dfn -> z32 297 | rqw XOR jtm -> z05 298 | kcp XOR shp -> z42 299 | hrd OR tdb -> pwb 300 | x35 AND y35 -> qph 301 | y22 AND x22 -> btq 302 | tkt OR knb -> crp 303 | y03 AND x03 -> pps 304 | x41 XOR y41 -> hbk 305 | x25 AND y25 -> smj 306 | dnf AND thm -> wrt 307 | y02 XOR x02 -> wsm 308 | y07 AND x07 -> wqt 309 | dbg XOR bcq -> z12 310 | y24 XOR x24 -> hbc 311 | nkn AND crt -> spp 312 | qtq OR rhw -> dbd 313 | jsd OR nnr -> sfw 314 | -------------------------------------------------------------------------------- /src/day13.rs: -------------------------------------------------------------------------------- 1 | use regex::Regex; 2 | use std::fs::File; 3 | use std::io::{BufRead, BufReader}; 4 | 5 | #[derive(Debug)] 6 | struct Machine { 7 | x_a: usize, 8 | y_a: usize, 9 | x_b: usize, 10 | y_b: usize, 11 | x_prize: usize, 12 | y_prize: usize, 13 | } 14 | 15 | fn read_input(path: &str) -> std::io::Result> { 16 | let file = File::open(path)?; 17 | let reader = BufReader::new(file); 18 | 19 | let re_button_a = Regex::new(r"Button A:\s*X\+(\d+),\s*Y\+(\d+)").unwrap(); 20 | let re_button_b = Regex::new(r"Button B:\s*X\+(\d+),\s*Y\+(\d+)").unwrap(); 21 | let re_prize = Regex::new(r"Prize:\s*X=(\d+),\s*Y=(\d+)").unwrap(); 22 | 23 | let mut machines = Vec::new(); 24 | let mut lines = reader.lines().filter_map(|l| l.ok()); 25 | 26 | while let Some(line_a) = lines.next() { 27 | if line_a.trim().is_empty() { 28 | continue; 29 | } 30 | let line_b = match lines.next() { 31 | Some(line) => line, 32 | None => break, 33 | }; 34 | let line_p = match lines.next() { 35 | Some(line) => line, 36 | None => break, 37 | }; 38 | 39 | let caps_a = re_button_a.captures(&line_a).unwrap(); 40 | let caps_b = re_button_b.captures(&line_b).unwrap(); 41 | let caps_p = re_prize.captures(&line_p).unwrap(); 42 | 43 | let x_a = caps_a[1].parse::().unwrap(); 44 | let y_a = caps_a[2].parse::().unwrap(); 45 | let x_b = caps_b[1].parse::().unwrap(); 46 | let y_b = caps_b[2].parse::().unwrap(); 47 | let x_prize = caps_p[1].parse::().unwrap(); 48 | let y_prize = caps_p[2].parse::().unwrap(); 49 | 50 | machines.push(Machine { 51 | x_a, 52 | y_a, 53 | x_b, 54 | y_b, 55 | x_prize, 56 | y_prize, 57 | }); 58 | 59 | let _ = lines.next(); 60 | } 61 | 62 | Ok(machines) 63 | } 64 | 65 | pub fn solution() { 66 | let machines = read_input("./inputs/day13.txt").unwrap(); 67 | 68 | // A. 69 | // a * (XA, YA) + b * (XB, YB) = (X_prize, Y_prize) 70 | let mut total = 0; 71 | for m in &machines { 72 | let mut min_cost = None; 73 | for a in 0..=100 { 74 | for b in 0..=100 { 75 | let x = a * m.x_a + b * m.x_b; 76 | let y = a * m.y_a + b * m.y_b; 77 | if x == m.x_prize && y == m.y_prize { 78 | let cost = 3 * a + b; 79 | match min_cost { 80 | None => min_cost = Some(cost), 81 | Some(prev) if cost < prev => min_cost = Some(cost), 82 | _ => {} 83 | } 84 | } 85 | } 86 | } 87 | 88 | if let Some(c) = min_cost { 89 | total += c; 90 | } 91 | } 92 | 93 | println!("Total cost: {}", total); 94 | 95 | // B. 96 | // We add the offset (10,000,000,000,000) to each prize coordinate. 97 | // Instead of brute-forcing values of `a` and `b`, we use a direct formula approach to calculate them: 98 | // 99 | // a = (x_b * y_prize - y_b * x_prize) / (x_a * y_b - y_a * x_b) 100 | // b = (x_prize - x_a * a) / x_b 101 | // 102 | // Here: 103 | // - `x_a`, `y_a` are the x and y increments when Button A is pressed. 104 | // - `x_b`, `y_b` are the x and y increments when Button B is pressed. 105 | // - `(x_prize, y_prize)` is the target coordinate (after adding the offset in Part B). 106 | // 107 | // Let D = (x_a * y_b - y_a * x_b), which is the determinant of the 2D linear system: 108 | // a * (x_a, y_a) + b * (x_b, y_b) = (x_prize, y_prize) 109 | // 110 | // If D ≠ 0, the vectors (x_a, y_a) and (x_b, y_b) are not collinear, so the system has a unique solution in real numbers. 111 | // - We calculate `a` and `b` using the formulas above. 112 | // - Check if `a` and `b` are integers (i.e., no remainder when dividing). 113 | // - Check if `a` and `b` are both nonnegative. 114 | // - If all conditions are satisfied, the solution is valid, and the cost is `3 * a + b`. 115 | // 116 | // If D = 0, the vectors (x_a, y_a) and (x_b, y_b) are collinear. 117 | // - In this case, the system cannot determine a unique solution using the direct formula approach. 118 | // - Special handling is needed to check if the target coordinate (x_prize, y_prize) is reachable along the single direction defined by the collinear vectors. 119 | // - If reachable, we calculate the minimum cost separately (e.g., using parameterized solutions along the line). 120 | // 121 | // If the solution is invalid (e.g., non-integer `a` or `b`, or negative values), we skip the machine for Part B. 122 | // 123 | let offset = 10_000_000_000_000usize; 124 | let mut total = 0; 125 | let mut solved = 0; 126 | 127 | for m in &machines { 128 | let x_prize_b = (m.x_prize as i64) + offset as i64; 129 | let y_prize_b = (m.y_prize as i64) + offset as i64; 130 | 131 | let x_a = m.x_a as i64; 132 | let y_a = m.y_a as i64; 133 | let x_b = m.x_b as i64; 134 | let y_b = m.y_b as i64; 135 | 136 | let d = x_a * y_b - y_a * x_b; 137 | if d == 0 { 138 | // Collinear or no solution 139 | continue; 140 | } else { 141 | // Non-collinear => unique solution (if integral) 142 | let a_num = y_b * x_prize_b - x_b * y_prize_b; 143 | let denom = d; 144 | if a_num % denom != 0 { 145 | // not an integer solution 146 | continue; 147 | } 148 | 149 | let a = a_num / denom; 150 | let b_num = x_prize_b - x_a * a; 151 | if x_b == 0 { 152 | // If xb=0 but we ended up here, it's likely no solution or handled differently. 153 | continue; 154 | } 155 | 156 | if b_num % x_b != 0 { 157 | // not integer 158 | continue; 159 | } 160 | 161 | let b = b_num / x_b; 162 | 163 | // Check nonnegative and that it indeed hits the goal 164 | if a < 0 || b < 0 { 165 | continue; 166 | } 167 | 168 | let final_x = x_a * a + x_b * b; 169 | let final_y = y_a * a + y_b * b; 170 | if final_x == x_prize_b && final_y == y_prize_b { 171 | let cost = 3 * a + b; 172 | total += cost; 173 | solved += 1; 174 | } 175 | } 176 | } 177 | 178 | println!("Part B, solved {} with total cost {}", solved, total); 179 | } 180 | -------------------------------------------------------------------------------- /src/day21.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashMap, fs}; 2 | 3 | struct Solution { 4 | moves1: HashMap<(char, char), Vec>, 5 | moves2: HashMap<(char, char), Vec>, 6 | } 7 | 8 | impl Solution { 9 | fn new(keypad1: &[&str], keypad2: &[&str]) -> Self { 10 | let moves1 = Self::parse_moves(keypad1); 11 | let moves2 = Self::parse_moves(keypad2); 12 | Self { moves1, moves2 } 13 | } 14 | 15 | fn parse_moves(keypad: &[&str]) -> HashMap<(char, char), Vec> { 16 | fn get_key_pos(keypad: &[&str]) -> HashMap { 17 | let mut pos = HashMap::new(); 18 | for (r, row) in keypad.iter().enumerate() { 19 | for (c, key) in row.chars().enumerate() { 20 | pos.insert(key, (r, c)); 21 | } 22 | } 23 | pos 24 | } 25 | 26 | let pos = get_key_pos(keypad); 27 | let mut moves: HashMap<(char, char), Vec> = HashMap::new(); 28 | let mut keys: Vec = pos.keys().cloned().collect(); 29 | keys.sort(); 30 | 31 | let hash_pos = pos.get(&'#').expect("Keypad must contain '#'"); 32 | 33 | for &key1 in &keys { 34 | if key1 == '#' { 35 | continue; 36 | } 37 | for &key2 in &keys { 38 | if key2 == '#' || key1 == key2 { 39 | continue; 40 | } 41 | let p1 = pos[&key1]; 42 | let p2 = pos[&key2]; 43 | let mut sequences = Vec::new(); 44 | 45 | if p1.0 == p2.0 { 46 | let dir = if p2.1 > p1.1 { '>' } else { '<' }; 47 | let distance = (p2.1 as isize - p1.1 as isize).abs(); 48 | let move_seq = format!("{}A", dir.to_string().repeat(distance as usize)); 49 | sequences.push(move_seq); 50 | } else if p1.1 == p2.1 { 51 | let dir = if p2.0 > p1.0 { 'v' } else { '^' }; 52 | let distance = (p2.0 as isize - p1.0 as isize).abs(); 53 | let move_seq = format!("{}A", dir.to_string().repeat(distance as usize)); 54 | sequences.push(move_seq); 55 | } else { 56 | if p1.0 != hash_pos.0 || p2.1 != hash_pos.1 { 57 | let dir1 = if p2.1 > p1.1 { '>' } else { '<' }; 58 | let distance1 = (p2.1 as isize - p1.1 as isize).abs(); 59 | let dir2 = if p2.0 > p1.0 { 'v' } else { '^' }; 60 | let distance2 = (p2.0 as isize - p1.0 as isize).abs(); 61 | let move_seq = format!( 62 | "{}{}A", 63 | dir1.to_string().repeat(distance1 as usize), 64 | dir2.to_string().repeat(distance2 as usize) 65 | ); 66 | sequences.push(move_seq); 67 | } 68 | 69 | // First vertical then horizontal 70 | if p1.1 != hash_pos.1 || p2.0 != hash_pos.0 { 71 | let dir1 = if p2.0 > p1.0 { 'v' } else { '^' }; 72 | let distance1 = (p2.0 as isize - p1.0 as isize).abs(); 73 | let dir2 = if p2.1 > p1.1 { '>' } else { '<' }; 74 | let distance2 = (p2.1 as isize - p1.1 as isize).abs(); 75 | let move_seq = format!( 76 | "{}{}A", 77 | dir1.to_string().repeat(distance1 as usize), 78 | dir2.to_string().repeat(distance2 as usize) 79 | ); 80 | sequences.push(move_seq); 81 | } 82 | } 83 | 84 | if !sequences.is_empty() { 85 | moves.insert((key1, key2), sequences); 86 | } 87 | } 88 | } 89 | 90 | moves 91 | } 92 | 93 | fn build_combinations(&self, arrays: &[Vec]) -> Vec> { 94 | let mut results: Vec> = vec![Vec::new()]; 95 | for array in arrays { 96 | let mut temp = Vec::new(); 97 | for combination in &results { 98 | for item in array { 99 | let mut new_combination = combination.clone(); 100 | new_combination.push(item.clone()); 101 | temp.push(new_combination); 102 | } 103 | } 104 | results = temp; 105 | } 106 | results 107 | } 108 | 109 | fn translate( 110 | &self, 111 | code: &str, 112 | depth: usize, 113 | cache: &mut HashMap<(String, usize), usize>, 114 | ) -> usize { 115 | if let Some(&cached) = cache.get(&(code.to_string(), depth)) { 116 | return cached; 117 | } 118 | 119 | let moves = if code.chars().next().unwrap().is_numeric() { 120 | self.translate_numpad(code) 121 | } else { 122 | self.translate_keypad(code) 123 | }; 124 | 125 | let result = if depth == 0 { 126 | moves 127 | .iter() 128 | .map(|move_seq| move_seq.iter().map(|s| s.len()).sum::()) 129 | .min() 130 | .unwrap_or(0) 131 | } else { 132 | moves 133 | .iter() 134 | .map(|move_seq| { 135 | move_seq 136 | .iter() 137 | .map(|s| self.translate(s, depth - 1, cache)) 138 | .sum::() 139 | }) 140 | .min() 141 | .unwrap_or(0) 142 | }; 143 | 144 | cache.insert((code.to_string(), depth), result); 145 | result 146 | } 147 | 148 | fn translate_numpad(&self, code: &str) -> Vec> { 149 | let mut code_chars: Vec = code.chars().collect(); 150 | code_chars.insert(0, 'A'); 151 | let mut moves_list = Vec::new(); 152 | 153 | for pair in code_chars.windows(2) { 154 | if let [a, b] = pair { 155 | if let Some(moves) = self.moves1.get(&(*a, *b)) { 156 | moves_list.push(moves.clone()); 157 | } else { 158 | moves_list.push(vec!["A".to_string()]); 159 | } 160 | } 161 | } 162 | 163 | self.build_combinations(&moves_list) 164 | } 165 | 166 | fn translate_keypad(&self, code: &str) -> Vec> { 167 | let mut code_chars: Vec = code.chars().collect(); 168 | code_chars.insert(0, 'A'); 169 | let mut moves_list = Vec::new(); 170 | 171 | for pair in code_chars.windows(2) { 172 | if let [a, b] = pair { 173 | if *a != *b { 174 | if let Some(moves) = self.moves2.get(&(*a, *b)) { 175 | moves_list.push(moves.clone()); 176 | } else { 177 | // If no move exists, use a default move 178 | moves_list.push(vec!["A".to_string()]); 179 | } 180 | } else { 181 | moves_list.push(vec!["A".to_string()]); 182 | } 183 | } 184 | } 185 | 186 | self.build_combinations(&moves_list) 187 | } 188 | 189 | fn solve(&self, data: &[&str], depth: usize) -> usize { 190 | let mut complexities = 0; 191 | let mut cache = HashMap::new(); 192 | 193 | for code in data { 194 | let min_len = self.translate(code, depth, &mut cache); 195 | if let Some(num_str) = code.strip_suffix(&code.chars().last().unwrap().to_string()) { 196 | if let Ok(num) = num_str.parse::() { 197 | complexities += min_len * num; 198 | } 199 | } 200 | } 201 | 202 | complexities 203 | } 204 | } 205 | 206 | pub fn solution() { 207 | let keypad1 = ["789", "456", "123", "#0A"]; 208 | let keypad2 = ["#^A", ""]; 209 | let solution = Solution::new(&keypad1, &keypad2); 210 | let input = fs::read_to_string("./inputs/day21.txt").unwrap(); 211 | let data: Vec<&str> = input 212 | .lines() 213 | .map(str::trim) 214 | .filter(|l| !l.is_empty()) 215 | .collect(); 216 | 217 | let part1 = solution.solve(&data, 2); 218 | println!("Part 1: {}", part1); 219 | 220 | // Part 2 is insipired by: 221 | // https://github.com/nitekat1124/advent-of-code-2024/blob/main/solutions/day21.py 222 | let part2 = solution.solve(&data, 25); 223 | println!("Part 2: {}", part2); 224 | } 225 | -------------------------------------------------------------------------------- /src/day15.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | 3 | const DIRS: [(isize, isize); 4] = [(-1, 0), (1, 0), (0, -1), (0, 1)]; 4 | 5 | struct Warehouse; 6 | 7 | impl Warehouse { 8 | fn get_direction(&self, mv: char) -> Option<(isize, isize)> { 9 | match mv { 10 | '^' => Some(DIRS[0]), 11 | 'v' => Some(DIRS[1]), 12 | '<' => Some(DIRS[2]), 13 | '>' => Some(DIRS[3]), 14 | _ => None, 15 | } 16 | } 17 | 18 | fn get_robot_pos(&self, grid: &Vec>) -> Option<(usize, usize)> { 19 | for (i, row) in grid.iter().enumerate() { 20 | for (j, &cell) in row.iter().enumerate() { 21 | if cell == '@' { 22 | return Some((i, j)); 23 | } 24 | } 25 | } 26 | None 27 | } 28 | 29 | fn moving( 30 | &self, 31 | mut grid: Vec>, 32 | mut pos: (usize, usize), 33 | moves: Vec, 34 | part: usize, 35 | ) -> Vec> { 36 | for mv in moves { 37 | let (dy, dx) = match self.get_direction(mv) { 38 | Some(dir) => dir, 39 | None => { 40 | continue; 41 | } 42 | }; 43 | 44 | let ny = pos.0 as isize + dy; 45 | let nx = pos.1 as isize + dx; 46 | 47 | if ny < 0 || nx < 0 || ny >= grid.len() as isize || nx >= grid[0].len() as isize { 48 | continue; 49 | } 50 | 51 | let ny_usize = ny as usize; 52 | let nx_usize = nx as usize; 53 | 54 | match grid[ny_usize][nx_usize] { 55 | '.' => pos = (ny_usize, nx_usize), 56 | '#' => continue, 57 | _ => { 58 | let (edges, adjs) = self.get_adjs_and_edges(&grid, pos, mv, part); 59 | let mut blocked = 0; 60 | for (ey, ex) in edges { 61 | let (ey_new, ex_new) = (ey as isize + dy, ex as isize + dx); 62 | if ey_new < 0 63 | || ex_new < 0 64 | || ey_new >= grid.len() as isize 65 | || ex_new >= grid[0].len() as isize 66 | || grid[ey_new as usize][ex_new as usize] == '#' 67 | { 68 | blocked += 1; 69 | } 70 | } 71 | 72 | if blocked == 0 { 73 | grid = self.update_grid(grid, adjs, mv); 74 | pos = (ny_usize, nx_usize); 75 | } 76 | } 77 | } 78 | } 79 | grid 80 | } 81 | 82 | fn get_adjs_and_edges( 83 | &self, 84 | grid: &Vec>, 85 | pos: (usize, usize), 86 | move_dir: char, 87 | part: usize, 88 | ) -> (Vec<(usize, usize)>, HashSet<(usize, usize)>) { 89 | let (mut y, mut x) = pos; 90 | let (dy, dx) = self.get_direction(move_dir).unwrap(); 91 | let mut adjs = HashSet::new(); 92 | 93 | if part == 1 || "<>".contains(move_dir) { 94 | loop { 95 | let ny = y as isize + dy; 96 | let nx = x as isize + dx; 97 | 98 | if ny < 0 || nx < 0 || ny >= grid.len() as isize || nx >= grid[0].len() as isize { 99 | return (vec![(y, x)], adjs); 100 | } 101 | 102 | let ny_usize = ny as usize; 103 | let nx_usize = nx as usize; 104 | 105 | if grid[ny_usize][nx_usize] == '.' || grid[ny_usize][nx_usize] == '#' { 106 | return (vec![(y, x)], adjs); 107 | } 108 | 109 | y = ny_usize; 110 | x = nx_usize; 111 | adjs.insert((y, x)); 112 | } 113 | } else { 114 | let mut edges = Vec::new(); 115 | let mut queue = vec![(y, x)]; 116 | while let Some((cy, cx)) = queue.pop() { 117 | if adjs.contains(&(cy, cx)) { 118 | continue; 119 | } 120 | adjs.insert((cy, cx)); 121 | 122 | let ny = cy as isize + dy; 123 | let nx = cx as isize + dx; 124 | 125 | if ny < 0 || nx < 0 || ny >= grid.len() as isize || nx >= grid[0].len() as isize { 126 | continue; 127 | } 128 | 129 | let ny_usize = ny as usize; 130 | let nx_usize = nx as usize; 131 | 132 | match grid[ny_usize][nx_usize] { 133 | '.' | '#' => edges.push((cy, cx)), 134 | '[' => { 135 | if nx + 1 < grid[0].len() as isize { 136 | queue.push((ny_usize, nx_usize)); 137 | queue.push((ny_usize, nx_usize + 1)); 138 | } 139 | } 140 | ']' => { 141 | if nx >= 1 { 142 | queue.push((ny_usize, nx_usize)); 143 | queue.push((ny_usize, nx_usize - 1)); 144 | } 145 | } 146 | _ => (), 147 | } 148 | } 149 | (edges, adjs) 150 | } 151 | } 152 | 153 | fn update_grid( 154 | &self, 155 | mut grid: Vec>, 156 | adjs: HashSet<(usize, usize)>, 157 | move_dir: char, 158 | ) -> Vec> { 159 | let mut sorted_coords = adjs.into_iter().collect::>(); 160 | match move_dir { 161 | '^' => sorted_coords.sort_by_key(|&(y, _)| y), 162 | 'v' => sorted_coords.sort_by_key(|&(y, _)| std::cmp::Reverse(y)), 163 | '<' => sorted_coords.sort_by_key(|&(_, x)| x), 164 | '>' => sorted_coords.sort_by_key(|&(_, x)| std::cmp::Reverse(x)), 165 | _ => (), 166 | } 167 | 168 | let (dy, dx) = self.get_direction(move_dir).unwrap(); 169 | for (y, x) in sorted_coords { 170 | let ny = y as isize + dy; 171 | let nx = x as isize + dx; 172 | 173 | if ny < 0 || nx < 0 || ny >= grid.len() as isize || nx >= grid[0].len() as isize { 174 | continue; 175 | } 176 | 177 | let ny_usize = ny as usize; 178 | let nx_usize = nx as usize; 179 | 180 | grid[ny_usize][nx_usize] = grid[y][x]; 181 | grid[y][x] = '.'; 182 | } 183 | 184 | grid 185 | } 186 | 187 | fn get_coords_sum(&self, grid: &Vec>, part: usize) -> usize { 188 | let box_char = if part == 2 { '[' } else { 'O' }; 189 | grid.iter() 190 | .enumerate() 191 | .map(|(y, row)| { 192 | row.iter() 193 | .enumerate() 194 | .filter_map(|(x, &cell)| { 195 | if cell == box_char { 196 | Some(100 * y + x) 197 | } else { 198 | None 199 | } 200 | }) 201 | .sum::() 202 | }) 203 | .sum() 204 | } 205 | 206 | fn resize_grid(&self, grid: &Vec>) -> Vec> { 207 | let mappings = vec![('#', "##"), ('O', "[]"), ('.', ".."), ('@', "@.")] 208 | .into_iter() 209 | .collect::>(); 210 | 211 | grid.iter() 212 | .map(|row| { 213 | row.iter() 214 | .flat_map(|&c| mappings.get(&c).unwrap_or(&"").chars()) 215 | .collect() 216 | }) 217 | .collect() 218 | } 219 | 220 | pub fn solve(&self, data: &str, part: usize) -> usize { 221 | let parts = data.split("\n\n").collect::>(); 222 | if parts.len() != 2 { 223 | return 0; 224 | } 225 | 226 | let mut grid = parts[0].lines().map(|l| l.chars().collect()).collect(); 227 | let valid_moves = vec!['^', 'v', '<', '>']; 228 | let moves = parts[1] 229 | .chars() 230 | .filter(|c| valid_moves.contains(c)) 231 | .collect(); 232 | 233 | if part == 2 { 234 | grid = self.resize_grid(&grid); 235 | } 236 | 237 | let pos = match self.get_robot_pos(&grid) { 238 | Some(p) => p, 239 | None => return 0, 240 | }; 241 | grid[pos.0][pos.1] = '.'; 242 | 243 | let grid = self.moving(grid, pos, moves, part); 244 | self.get_coords_sum(&grid, part) 245 | } 246 | } 247 | 248 | pub fn solution() { 249 | let data = std::fs::read_to_string("inputs/day15.txt").unwrap(); 250 | 251 | let a = Warehouse.solve(&data, 1); 252 | println!("Part A: {}", a); 253 | 254 | // Part 2 is inspired by: 255 | // https://github.com/nitekat1124/advent-of-code-2024/blob/main/solutions/day15.py 256 | let b = Warehouse.solve(&data, 2); 257 | println!("Part B: {}", b); 258 | } 259 | -------------------------------------------------------------------------------- /inputs/day14.txt: -------------------------------------------------------------------------------- 1 | p=10,22 v=50,-21 2 | p=35,60 v=-8,52 3 | p=79,50 v=82,9 4 | p=52,1 v=-28,-55 5 | p=85,67 v=-51,-18 6 | p=72,34 v=82,13 7 | p=57,0 v=67,75 8 | p=7,52 v=85,67 9 | p=81,19 v=-73,-21 10 | p=46,32 v=-82,29 11 | p=68,101 v=-73,30 12 | p=23,42 v=-36,-63 13 | p=25,93 v=40,-16 14 | p=30,93 v=-76,-55 15 | p=22,58 v=72,-9 16 | p=25,84 v=18,-87 17 | p=38,80 v=39,-42 18 | p=35,71 v=-55,-53 19 | p=88,60 v=-32,-29 20 | p=86,86 v=-16,98 21 | p=30,102 v=66,35 22 | p=64,88 v=54,75 23 | p=24,4 v=18,93 24 | p=4,6 v=4,-93 25 | p=57,70 v=-7,-42 26 | p=23,38 v=-37,56 27 | p=75,84 v=-89,-21 28 | p=10,83 v=30,-33 29 | p=77,66 v=-73,-2 30 | p=4,15 v=84,2 31 | p=44,34 v=-48,31 32 | p=15,78 v=-4,50 33 | p=31,60 v=-26,-66 34 | p=62,50 v=34,-94 35 | p=98,25 v=37,49 36 | p=74,81 v=1,59 37 | p=94,81 v=-38,-60 38 | p=70,20 v=-54,-60 39 | p=89,51 v=-85,-32 40 | p=49,51 v=-48,76 41 | p=53,66 v=33,83 42 | p=61,29 v=-47,-63 43 | p=49,43 v=94,-7 44 | p=17,23 v=-49,-30 45 | p=15,55 v=24,-63 46 | p=82,3 v=-13,77 47 | p=77,44 v=54,20 48 | p=8,43 v=30,-76 49 | p=70,72 v=-34,97 50 | p=58,10 v=96,45 51 | p=67,95 v=-20,39 52 | p=92,81 v=-83,-26 53 | p=44,98 v=64,-41 54 | p=1,99 v=71,73 55 | p=81,25 v=-59,44 56 | p=16,31 v=91,-32 57 | p=48,44 v=-41,-63 58 | p=88,11 v=-72,37 59 | p=31,89 v=-77,-75 60 | p=42,41 v=-40,33 61 | p=61,41 v=-73,-16 62 | p=96,7 v=-71,-37 63 | p=16,35 v=-43,-43 64 | p=80,79 v=-59,70 65 | p=20,35 v=-70,-5 66 | p=41,47 v=-50,-70 67 | p=86,37 v=11,-72 68 | p=61,97 v=54,-73 69 | p=82,4 v=90,-3 70 | p=24,35 v=38,80 71 | p=52,93 v=-81,2 72 | p=90,37 v=90,-43 73 | p=18,28 v=31,11 74 | p=33,58 v=-2,56 75 | p=100,102 v=-32,19 76 | p=97,51 v=-45,-15 77 | p=68,17 v=76,-93 78 | p=100,13 v=83,-46 79 | p=88,8 v=-12,75 80 | p=71,14 v=-6,-30 81 | p=83,10 v=15,-37 82 | p=81,84 v=35,12 83 | p=98,90 v=-52,43 84 | p=91,60 v=65,82 85 | p=3,72 v=-24,-40 86 | p=84,49 v=-58,22 87 | p=82,75 v=-99,27 88 | p=4,73 v=46,79 89 | p=15,32 v=51,24 90 | p=6,32 v=-44,-81 91 | p=21,101 v=-36,28 92 | p=21,100 v=51,-73 93 | p=50,32 v=-92,-98 94 | p=1,58 v=-24,-2 95 | p=52,96 v=-95,-64 96 | p=83,28 v=-60,11 97 | p=85,101 v=-59,-26 98 | p=19,2 v=-31,-97 99 | p=50,32 v=-68,31 100 | p=13,66 v=43,36 101 | p=100,15 v=-30,-14 102 | p=84,78 v=-58,88 103 | p=65,50 v=-53,-21 104 | p=50,75 v=26,61 105 | p=89,60 v=-93,47 106 | p=15,39 v=38,4 107 | p=15,50 v=-90,-27 108 | p=63,66 v=29,60 109 | p=17,79 v=-50,-89 110 | p=21,39 v=-83,60 111 | p=62,35 v=6,-51 112 | p=99,44 v=9,8 113 | p=32,4 v=-43,-35 114 | p=57,2 v=-81,39 115 | p=4,7 v=-44,-10 116 | p=93,12 v=56,-19 117 | p=33,79 v=45,-24 118 | p=66,72 v=86,-41 119 | p=84,83 v=-28,39 120 | p=11,30 v=56,-88 121 | p=51,19 v=-54,-89 122 | p=0,36 v=-32,-28 123 | p=69,39 v=41,20 124 | p=75,88 v=8,79 125 | p=5,12 v=-64,93 126 | p=38,9 v=-62,91 127 | p=25,100 v=64,-15 128 | p=97,60 v=-12,-69 129 | p=57,76 v=-7,-13 130 | p=42,48 v=-69,32 131 | p=31,35 v=-81,65 132 | p=28,28 v=46,85 133 | p=77,84 v=-73,68 134 | p=57,18 v=-54,44 135 | p=48,98 v=59,17 136 | p=28,86 v=92,-17 137 | p=1,93 v=90,-53 138 | p=0,31 v=84,-32 139 | p=87,34 v=9,-65 140 | p=20,20 v=44,-25 141 | p=65,93 v=-96,-54 142 | p=45,75 v=-82,-87 143 | p=48,58 v=26,65 144 | p=87,76 v=-86,16 145 | p=31,79 v=52,34 146 | p=100,101 v=58,-36 147 | p=76,20 v=59,-76 148 | p=100,91 v=-85,-4 149 | p=14,13 v=92,-46 150 | p=72,66 v=-60,-65 151 | p=74,41 v=-60,96 152 | p=73,17 v=48,80 153 | p=48,50 v=-48,94 154 | p=76,50 v=-81,12 155 | p=51,102 v=80,1 156 | p=44,12 v=93,-86 157 | p=49,16 v=40,-43 158 | p=75,97 v=2,-24 159 | p=54,35 v=13,-34 160 | p=50,4 v=-75,75 161 | p=28,87 v=77,81 162 | p=50,38 v=13,60 163 | p=51,43 v=-27,22 164 | p=71,52 v=-13,29 165 | p=37,74 v=-29,-40 166 | p=67,82 v=-13,61 167 | p=4,21 v=-97,-50 168 | p=36,2 v=25,-66 169 | p=17,67 v=-30,-87 170 | p=90,29 v=96,15 171 | p=90,96 v=-52,39 172 | p=20,9 v=78,17 173 | p=70,74 v=-32,-93 174 | p=77,60 v=-83,51 175 | p=74,97 v=92,1 176 | p=75,82 v=28,61 177 | p=40,4 v=-58,-94 178 | p=64,26 v=6,-86 179 | p=71,14 v=-81,-93 180 | p=11,96 v=24,70 181 | p=97,26 v=97,-61 182 | p=77,53 v=-44,55 183 | p=1,93 v=83,46 184 | p=11,59 v=90,54 185 | p=3,2 v=-85,-8 186 | p=18,90 v=79,-60 187 | p=82,31 v=96,-34 188 | p=41,22 v=-9,-72 189 | p=52,17 v=86,-95 190 | p=48,39 v=-41,-63 191 | p=3,61 v=-16,-35 192 | p=6,26 v=50,42 193 | p=73,91 v=-53,99 194 | p=55,89 v=-54,-35 195 | p=24,22 v=17,-66 196 | p=80,84 v=-97,53 197 | p=20,73 v=69,-40 198 | p=26,100 v=-83,19 199 | p=68,87 v=-40,88 200 | p=80,45 v=-15,-4 201 | p=2,80 v=-98,23 202 | p=30,71 v=-62,9 203 | p=2,89 v=-50,88 204 | p=19,99 v=21,-1 205 | p=11,81 v=-3,-13 206 | p=70,59 v=-32,34 207 | p=84,68 v=89,-22 208 | p=48,35 v=-48,-79 209 | p=78,80 v=-60,34 210 | p=10,50 v=77,-31 211 | p=94,79 v=23,90 212 | p=46,47 v=-68,2 213 | p=20,52 v=30,-56 214 | p=79,36 v=2,-97 215 | p=75,21 v=-74,-22 216 | p=54,53 v=4,-75 217 | p=100,76 v=69,43 218 | p=95,33 v=-64,22 219 | p=26,61 v=38,63 220 | p=13,20 v=43,-59 221 | p=20,36 v=72,47 222 | p=78,98 v=49,-24 223 | p=83,76 v=-12,-22 224 | p=79,98 v=-73,77 225 | p=31,22 v=-96,33 226 | p=61,22 v=27,-90 227 | p=83,41 v=22,40 228 | p=98,15 v=76,-37 229 | p=23,46 v=-49,43 230 | p=2,87 v=-52,-8 231 | p=74,2 v=74,-57 232 | p=19,36 v=51,36 233 | p=30,93 v=-3,-93 234 | p=75,21 v=90,-28 235 | p=2,32 v=30,-12 236 | p=69,88 v=-40,-90 237 | p=1,77 v=-81,27 238 | p=1,70 v=-3,56 239 | p=60,70 v=3,-13 240 | p=54,14 v=67,8 241 | p=1,61 v=64,-47 242 | p=50,99 v=-40,72 243 | p=62,43 v=74,76 244 | p=63,30 v=14,98 245 | p=10,3 v=24,-46 246 | p=25,64 v=-83,-87 247 | p=8,31 v=-70,54 248 | p=17,18 v=-80,-95 249 | p=100,53 v=42,-6 250 | p=61,101 v=28,-44 251 | p=91,34 v=-6,23 252 | p=43,28 v=-31,62 253 | p=52,88 v=75,6 254 | p=45,66 v=-28,-96 255 | p=29,40 v=5,78 256 | p=21,91 v=-50,97 257 | p=72,6 v=48,35 258 | p=4,11 v=97,48 259 | p=66,89 v=-72,4 260 | p=63,70 v=-47,56 261 | p=28,75 v=10,-78 262 | p=94,47 v=-65,-27 263 | p=14,74 v=51,25 264 | p=34,65 v=5,-29 265 | p=61,65 v=-73,47 266 | p=88,17 v=-12,-28 267 | p=46,43 v=-76,40 268 | p=78,76 v=21,34 269 | p=54,32 v=-41,-7 270 | p=48,92 v=-41,-35 271 | p=89,59 v=29,9 272 | p=89,66 v=36,-58 273 | p=38,83 v=-19,16 274 | p=84,4 v=38,66 275 | p=39,101 v=88,54 276 | p=6,32 v=82,50 277 | p=30,79 v=-63,-80 278 | p=54,35 v=41,-16 279 | p=33,102 v=-49,35 280 | p=23,37 v=-91,-61 281 | p=77,30 v=-35,-69 282 | p=79,4 v=35,-57 283 | p=45,29 v=-95,-23 284 | p=49,57 v=87,71 285 | p=53,31 v=87,-7 286 | p=10,78 v=-34,35 287 | p=10,16 v=-37,26 288 | p=46,15 v=-41,-95 289 | p=2,26 v=49,-30 290 | p=15,68 v=-50,52 291 | p=69,40 v=-47,-90 292 | p=53,39 v=14,9 293 | p=23,61 v=11,83 294 | p=44,33 v=-27,-79 295 | p=81,2 v=-40,-55 296 | p=89,42 v=-72,31 297 | p=18,32 v=-39,19 298 | p=97,91 v=-76,52 299 | p=51,80 v=60,-64 300 | p=48,36 v=53,98 301 | p=86,91 v=97,1 302 | p=48,88 v=-22,-42 303 | p=100,17 v=-24,-90 304 | p=40,52 v=-36,-85 305 | p=65,52 v=-19,-25 306 | p=0,45 v=82,-84 307 | p=12,102 v=78,-73 308 | p=67,19 v=87,-43 309 | p=24,78 v=84,93 310 | p=68,52 v=-14,71 311 | p=57,10 v=-7,6 312 | p=4,10 v=87,62 313 | p=64,38 v=41,51 314 | p=23,56 v=12,-38 315 | p=53,25 v=46,-54 316 | p=16,90 v=-84,59 317 | p=23,97 v=-36,-35 318 | p=35,78 v=85,92 319 | p=53,31 v=-53,19 320 | p=61,84 v=54,41 321 | p=86,93 v=76,10 322 | p=78,80 v=-46,-24 323 | p=2,6 v=43,46 324 | p=58,82 v=20,97 325 | p=46,20 v=-75,15 326 | p=60,85 v=30,-54 327 | p=57,29 v=-7,-96 328 | p=75,98 v=62,79 329 | p=64,44 v=54,24 330 | p=42,51 v=-76,19 331 | p=37,66 v=-70,-9 332 | p=85,16 v=-58,60 333 | p=8,70 v=-57,-69 334 | p=36,55 v=-73,-96 335 | p=67,93 v=88,30 336 | p=18,48 v=54,-94 337 | p=53,14 v=20,-93 338 | p=28,37 v=24,-10 339 | p=64,10 v=-94,-94 340 | p=10,19 v=-41,-19 341 | p=6,80 v=-64,-98 342 | p=30,66 v=52,54 343 | p=35,24 v=5,-3 344 | p=14,1 v=18,-60 345 | p=54,0 v=-61,-17 346 | p=27,2 v=38,60 347 | p=49,88 v=48,-17 348 | p=63,1 v=-7,-94 349 | p=98,75 v=-78,43 350 | p=88,97 v=-25,10 351 | p=30,75 v=-68,26 352 | p=65,57 v=68,18 353 | p=19,30 v=3,49 354 | p=52,47 v=-50,94 355 | p=16,8 v=27,-52 356 | p=27,64 v=-84,-29 357 | p=85,30 v=49,31 358 | p=94,20 v=10,80 359 | p=57,84 v=-84,32 360 | p=45,93 v=-2,-46 361 | p=94,68 v=-79,83 362 | p=61,27 v=-73,2 363 | p=15,64 v=99,-4 364 | p=28,82 v=46,-51 365 | p=88,14 v=81,74 366 | p=2,90 v=67,48 367 | p=8,66 v=64,-31 368 | p=4,5 v=-97,48 369 | p=39,60 v=5,74 370 | p=62,11 v=81,-75 371 | p=82,54 v=35,-84 372 | p=89,72 v=-88,-24 373 | p=42,45 v=73,67 374 | p=77,78 v=89,90 375 | p=44,5 v=80,28 376 | p=58,28 v=-31,-31 377 | p=91,68 v=-73,-22 378 | p=68,48 v=-76,80 379 | p=22,26 v=24,6 380 | p=34,6 v=-69,-83 381 | p=64,81 v=-13,-8 382 | p=15,16 v=-16,64 383 | p=42,49 v=93,-56 384 | p=87,38 v=-59,58 385 | p=95,34 v=-92,-79 386 | p=66,101 v=7,-19 387 | p=63,38 v=82,1 388 | p=95,53 v=63,-27 389 | p=95,2 v=-65,-48 390 | p=16,73 v=-64,-78 391 | p=13,60 v=-58,27 392 | p=69,55 v=34,-11 393 | p=32,20 v=10,-71 394 | p=52,100 v=-95,-84 395 | p=50,16 v=-21,35 396 | p=42,44 v=73,85 397 | p=87,33 v=-93,74 398 | p=60,75 v=40,34 399 | p=7,1 v=27,-13 400 | p=12,63 v=29,-63 401 | p=18,56 v=-90,-18 402 | p=30,49 v=-56,-92 403 | p=49,8 v=-63,49 404 | p=80,15 v=64,-79 405 | p=36,66 v=25,-24 406 | p=76,37 v=-80,22 407 | p=76,68 v=29,-31 408 | p=90,2 v=-92,51 409 | p=14,42 v=72,49 410 | p=57,89 v=-94,-53 411 | p=48,63 v=29,-14 412 | p=80,2 v=-86,19 413 | p=62,45 v=-53,36 414 | p=40,36 v=67,67 415 | p=45,96 v=62,-66 416 | p=42,61 v=-81,18 417 | p=54,69 v=-27,-79 418 | p=72,17 v=55,-97 419 | p=92,93 v=-3,3 420 | p=11,97 v=10,59 421 | p=33,61 v=5,-65 422 | p=26,31 v=-48,34 423 | p=1,32 v=81,-18 424 | p=68,70 v=27,-54 425 | p=89,10 v=-99,-12 426 | p=32,102 v=65,-64 427 | p=52,89 v=-41,-62 428 | p=100,10 v=-11,-59 429 | p=93,63 v=83,34 430 | p=16,67 v=-23,43 431 | p=58,35 v=13,-10 432 | p=24,31 v=85,-81 433 | p=17,94 v=58,10 434 | p=40,55 v=-22,-65 435 | p=47,12 v=-10,54 436 | p=52,29 v=-68,-25 437 | p=11,83 v=-71,-80 438 | p=62,29 v=-46,-25 439 | p=73,95 v=67,47 440 | p=74,25 v=81,14 441 | p=99,45 v=11,-13 442 | p=31,13 v=76,26 443 | p=27,90 v=17,-42 444 | p=68,80 v=89,-95 445 | p=14,54 v=57,94 446 | p=97,56 v=29,-9 447 | p=65,8 v=-68,57 448 | p=86,76 v=82,83 449 | p=81,43 v=96,-54 450 | p=86,17 v=56,26 451 | p=41,92 v=-82,-10 452 | p=49,41 v=60,58 453 | p=49,72 v=93,3 454 | p=50,13 v=-7,17 455 | p=46,85 v=-5,81 456 | p=7,40 v=-51,78 457 | p=88,91 v=62,59 458 | p=97,14 v=93,86 459 | p=62,80 v=98,62 460 | p=22,50 v=51,-65 461 | p=14,34 v=77,38 462 | p=34,86 v=-54,-6 463 | p=2,86 v=-85,25 464 | p=67,28 v=-15,51 465 | p=90,87 v=19,-48 466 | p=13,25 v=45,-5 467 | p=59,62 v=13,-67 468 | p=53,40 v=13,11 469 | p=48,52 v=37,74 470 | p=82,62 v=-66,-47 471 | p=74,64 v=-25,-25 472 | p=72,28 v=-68,-37 473 | p=51,8 v=-48,73 474 | p=46,32 v=-89,75 475 | p=100,15 v=-34,58 476 | p=34,39 v=-8,71 477 | p=78,70 v=47,-22 478 | p=31,50 v=-49,2 479 | p=15,84 v=64,-98 480 | p=76,92 v=75,-6 481 | p=40,18 v=54,-96 482 | p=81,3 v=1,-96 483 | p=9,95 v=-85,-89 484 | p=64,18 v=34,87 485 | p=72,100 v=48,12 486 | p=39,77 v=40,-53 487 | p=74,11 v=95,-77 488 | p=29,20 v=72,51 489 | p=96,91 v=-19,-75 490 | p=11,68 v=51,-58 491 | p=64,9 v=67,28 492 | p=73,94 v=-46,30 493 | p=77,39 v=15,49 494 | p=100,20 v=-85,-77 495 | p=92,80 v=-5,-64 496 | p=80,11 v=-62,-41 497 | p=78,47 v=-54,74 498 | p=32,76 v=24,-12 499 | p=13,22 v=-10,-52 500 | p=30,78 v=-49,-53 501 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.8.11" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 10 | dependencies = [ 11 | "cfg-if", 12 | "getrandom", 13 | "once_cell", 14 | "version_check", 15 | "zerocopy", 16 | ] 17 | 18 | [[package]] 19 | name = "aho-corasick" 20 | version = "1.1.3" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 23 | dependencies = [ 24 | "memchr", 25 | ] 26 | 27 | [[package]] 28 | name = "aoc-2024" 29 | version = "0.1.0" 30 | dependencies = [ 31 | "ahash", 32 | "glam", 33 | "itertools", 34 | "ndarray", 35 | "nom", 36 | "nom_locate", 37 | "pathfinding", 38 | "petgraph", 39 | "rayon", 40 | "regex", 41 | ] 42 | 43 | [[package]] 44 | name = "autocfg" 45 | version = "1.4.0" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 48 | 49 | [[package]] 50 | name = "bytecount" 51 | version = "0.6.8" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" 54 | 55 | [[package]] 56 | name = "cfg-if" 57 | version = "1.0.0" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 60 | 61 | [[package]] 62 | name = "crossbeam-deque" 63 | version = "0.8.5" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 66 | dependencies = [ 67 | "crossbeam-epoch", 68 | "crossbeam-utils", 69 | ] 70 | 71 | [[package]] 72 | name = "crossbeam-epoch" 73 | version = "0.9.18" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 76 | dependencies = [ 77 | "crossbeam-utils", 78 | ] 79 | 80 | [[package]] 81 | name = "crossbeam-utils" 82 | version = "0.8.20" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 85 | 86 | [[package]] 87 | name = "deprecate-until" 88 | version = "0.1.1" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "7a3767f826efbbe5a5ae093920b58b43b01734202be697e1354914e862e8e704" 91 | dependencies = [ 92 | "proc-macro2", 93 | "quote", 94 | "semver", 95 | "syn", 96 | ] 97 | 98 | [[package]] 99 | name = "either" 100 | version = "1.13.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 103 | 104 | [[package]] 105 | name = "equivalent" 106 | version = "1.0.1" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 109 | 110 | [[package]] 111 | name = "fixedbitset" 112 | version = "0.4.2" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 115 | 116 | [[package]] 117 | name = "getrandom" 118 | version = "0.2.15" 119 | source = "registry+https://github.com/rust-lang/crates.io-index" 120 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 121 | dependencies = [ 122 | "cfg-if", 123 | "libc", 124 | "wasi", 125 | ] 126 | 127 | [[package]] 128 | name = "glam" 129 | version = "0.29.2" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" 132 | 133 | [[package]] 134 | name = "hashbrown" 135 | version = "0.15.2" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 138 | 139 | [[package]] 140 | name = "indexmap" 141 | version = "2.7.0" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 144 | dependencies = [ 145 | "equivalent", 146 | "hashbrown", 147 | ] 148 | 149 | [[package]] 150 | name = "integer-sqrt" 151 | version = "0.1.5" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" 154 | dependencies = [ 155 | "num-traits", 156 | ] 157 | 158 | [[package]] 159 | name = "itertools" 160 | version = "0.13.0" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 163 | dependencies = [ 164 | "either", 165 | ] 166 | 167 | [[package]] 168 | name = "libc" 169 | version = "0.2.168" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" 172 | 173 | [[package]] 174 | name = "matrixmultiply" 175 | version = "0.3.9" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" 178 | dependencies = [ 179 | "autocfg", 180 | "rawpointer", 181 | ] 182 | 183 | [[package]] 184 | name = "memchr" 185 | version = "2.7.4" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 188 | 189 | [[package]] 190 | name = "minimal-lexical" 191 | version = "0.2.1" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 194 | 195 | [[package]] 196 | name = "ndarray" 197 | version = "0.16.1" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841" 200 | dependencies = [ 201 | "matrixmultiply", 202 | "num-complex", 203 | "num-integer", 204 | "num-traits", 205 | "portable-atomic", 206 | "portable-atomic-util", 207 | "rawpointer", 208 | ] 209 | 210 | [[package]] 211 | name = "nom" 212 | version = "7.1.3" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 215 | dependencies = [ 216 | "memchr", 217 | "minimal-lexical", 218 | ] 219 | 220 | [[package]] 221 | name = "nom_locate" 222 | version = "4.2.0" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "1e3c83c053b0713da60c5b8de47fe8e494fe3ece5267b2f23090a07a053ba8f3" 225 | dependencies = [ 226 | "bytecount", 227 | "memchr", 228 | "nom", 229 | ] 230 | 231 | [[package]] 232 | name = "num-complex" 233 | version = "0.4.6" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 236 | dependencies = [ 237 | "num-traits", 238 | ] 239 | 240 | [[package]] 241 | name = "num-integer" 242 | version = "0.1.46" 243 | source = "registry+https://github.com/rust-lang/crates.io-index" 244 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 245 | dependencies = [ 246 | "num-traits", 247 | ] 248 | 249 | [[package]] 250 | name = "num-traits" 251 | version = "0.2.19" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 254 | dependencies = [ 255 | "autocfg", 256 | ] 257 | 258 | [[package]] 259 | name = "once_cell" 260 | version = "1.20.2" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 263 | 264 | [[package]] 265 | name = "pathfinding" 266 | version = "4.12.0" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "0699ae2f1524f028d52ff9de21e06c000118731572ef9c2da81c4b6d573f9b79" 269 | dependencies = [ 270 | "deprecate-until", 271 | "indexmap", 272 | "integer-sqrt", 273 | "num-traits", 274 | "rustc-hash", 275 | "thiserror", 276 | ] 277 | 278 | [[package]] 279 | name = "petgraph" 280 | version = "0.6.5" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" 283 | dependencies = [ 284 | "fixedbitset", 285 | "indexmap", 286 | ] 287 | 288 | [[package]] 289 | name = "portable-atomic" 290 | version = "1.10.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" 293 | 294 | [[package]] 295 | name = "portable-atomic-util" 296 | version = "0.2.4" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" 299 | dependencies = [ 300 | "portable-atomic", 301 | ] 302 | 303 | [[package]] 304 | name = "proc-macro2" 305 | version = "1.0.92" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 308 | dependencies = [ 309 | "unicode-ident", 310 | ] 311 | 312 | [[package]] 313 | name = "quote" 314 | version = "1.0.37" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 317 | dependencies = [ 318 | "proc-macro2", 319 | ] 320 | 321 | [[package]] 322 | name = "rawpointer" 323 | version = "0.2.1" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 326 | 327 | [[package]] 328 | name = "rayon" 329 | version = "1.10.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 332 | dependencies = [ 333 | "either", 334 | "rayon-core", 335 | ] 336 | 337 | [[package]] 338 | name = "rayon-core" 339 | version = "1.12.1" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 342 | dependencies = [ 343 | "crossbeam-deque", 344 | "crossbeam-utils", 345 | ] 346 | 347 | [[package]] 348 | name = "regex" 349 | version = "1.11.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 352 | dependencies = [ 353 | "aho-corasick", 354 | "memchr", 355 | "regex-automata", 356 | "regex-syntax", 357 | ] 358 | 359 | [[package]] 360 | name = "regex-automata" 361 | version = "0.4.9" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 364 | dependencies = [ 365 | "aho-corasick", 366 | "memchr", 367 | "regex-syntax", 368 | ] 369 | 370 | [[package]] 371 | name = "regex-syntax" 372 | version = "0.8.5" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 375 | 376 | [[package]] 377 | name = "rustc-hash" 378 | version = "2.1.0" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" 381 | 382 | [[package]] 383 | name = "semver" 384 | version = "1.0.24" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" 387 | 388 | [[package]] 389 | name = "syn" 390 | version = "2.0.90" 391 | source = "registry+https://github.com/rust-lang/crates.io-index" 392 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 393 | dependencies = [ 394 | "proc-macro2", 395 | "quote", 396 | "unicode-ident", 397 | ] 398 | 399 | [[package]] 400 | name = "thiserror" 401 | version = "2.0.7" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "93605438cbd668185516ab499d589afb7ee1859ea3d5fc8f6b0755e1c7443767" 404 | dependencies = [ 405 | "thiserror-impl", 406 | ] 407 | 408 | [[package]] 409 | name = "thiserror-impl" 410 | version = "2.0.7" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "e1d8749b4531af2117677a5fcd12b1348a3fe2b81e36e61ffeac5c4aa3273e36" 413 | dependencies = [ 414 | "proc-macro2", 415 | "quote", 416 | "syn", 417 | ] 418 | 419 | [[package]] 420 | name = "unicode-ident" 421 | version = "1.0.14" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 424 | 425 | [[package]] 426 | name = "version_check" 427 | version = "0.9.5" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 430 | 431 | [[package]] 432 | name = "wasi" 433 | version = "0.11.0+wasi-snapshot-preview1" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 436 | 437 | [[package]] 438 | name = "zerocopy" 439 | version = "0.7.35" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 442 | dependencies = [ 443 | "zerocopy-derive", 444 | ] 445 | 446 | [[package]] 447 | name = "zerocopy-derive" 448 | version = "0.7.35" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 451 | dependencies = [ 452 | "proc-macro2", 453 | "quote", 454 | "syn", 455 | ] 456 | -------------------------------------------------------------------------------- /inputs/day06.txt: -------------------------------------------------------------------------------- 1 | ..............................#.................................#...............#........#.#..#......#..#........#....#........... 2 | ..................##.........#..............................#...........#......................#........#......................... 3 | ...............#...............#...............................#...#..............................#.....#...............#....#..#. 4 | .........................#.........................................................#........................#..................... 5 | #...#.#.........#..#..........................#............................#.....................#................................ 6 | ......................................................#......................#..............................#..........#.........# 7 | ......................................#.#.....#....................#..................................##.......................... 8 | ...............#.....................#..........#.......................#.................#............##......................#.. 9 | .............................................................................................................#.................... 10 | .........#.#..........#....#......#.................#......................#...................................................... 11 | ..........................................................................#................................#..#......#............ 12 | .............#............#............#..................................#............#...........#......#................#...... 13 | ....................#........##....................................................#.........................................#.... 14 | ..........................................................................#.....#.............#................................#.. 15 | ...#.#.....#...........##..#.......................#.............................................................#................ 16 | ..............#.........#.........#...........................#...................................#...........#.................## 17 | ....................#.............................#.......##..#...............#.......................#...#....#..............#... 18 | ....................#..................................................................................#...........#.........#.... 19 | .......#....#.#..............................#.......................................#...........#.#.............................. 20 | .........#................................#..................#.#...........#........#..#........#...#................#............ 21 | ............................................................#......................#........#....................#.#.............. 22 | .....#......#.......#.................#.#......#..............................#..................#.................#..........#... 23 | ........................................#..........#...............##...#............................#.#.........#...#....##...... 24 | #.....#..............................................................................#............#............#.................. 25 | .................................#...........#.......................##.#..#...................................................... 26 | .....#......#........................#...................................................................#........................ 27 | ..................#.........#.............................#....#.................................................................. 28 | ...#................#......................#....#............#.....................#...#..#...................................#... 29 | .#.#...................#........................................#...#..............#.#...................#.#.................#.#.# 30 | ........#................................##.#......#.............................................................................. 31 | .......................................#..#.........................................#...........................................#. 32 | ..........#.............#..............................................#...............................#..#........#.............. 33 | ..........#................##..#..............#............................................................#...................... 34 | .............................................................................#....#...........................#................... 35 | ...#..#.....#......#...............#...........##.....#...#......#...#..........#.........#....................#....#............. 36 | ............................#............#...#..........#................................................................#........ 37 | .............#...........................................................................................#..........#........#.#.. 38 | ...................##..#............................................#.................#...#..............................#........ 39 | ...............................................#.......#.....#.........................#...................#...................... 40 | .................................................................................#.#.............................................. 41 | ...#...................#.................#......#..............................................................................#.. 42 | ....##.........................#....................................#.....#..................................#......#....##....... 43 | ......#...........................................................#......................................#.........#.............. 44 | ..........##.#.........#.........................#......#......................................................#.................. 45 | ..................................##.............#.#................#......#..................#..................................# 46 | ....#.............................................................................................#......................#....##.. 47 | .................#.....#.......................................................................................................... 48 | .............................................................................................#.............#.#.................... 49 | ........#...........................................................................#..............#...#...............#.......... 50 | .....................#...........#.............#...............#....#.....#.......................#......#........................ 51 | ........#................................................................................#.............#.........#................ 52 | .............#.................................................................#.............#...................................# 53 | .............#.................#..#.....#........#..#.................#............###.........#.................#.............#.. 54 | .....................#.........#......................................................................................#.....#..... 55 | #...#...........##...........................#......................#.........................................................#... 56 | ........................................#.................#....#..........#....#...#.................#.....##.#..#................ 57 | ...............................#..........#..................................#...............................................#.... 58 | ................##..............#...............................#.#....................#...................................#.#.... 59 | ...............................................................................................................#....#............. 60 | ......#......#.................................................................................................................... 61 | ......................#................#............#............................#........................................#....... 62 | ...............................................................#..............^..................................................# 63 | .......##..........#................................................................................................#............. 64 | ..##......#................................#.................................#......#.................#...........#.#............. 65 | #..........................................................................................#...........#......................#... 66 | .............#......#....#.............#.................................................................................#...#.... 67 | ..................#.....#.............................................................#................#.......................... 68 | .....#..............................................................................................................#..#.......... 69 | .....#........#................#....#.............#..........#...............#.....................#..........##.................. 70 | ......#...................................#...................##..................................................#..........#.... 71 | ...#..................................................................#...............#...............#........................... 72 | ..............#..........#.....................#.................................#...........................#............#...#... 73 | ......#...........................#...................#........................#...................................#......#....... 74 | .................#...........#...............................................................#.......#.......#................#... 75 | ................................#.........#..........................#......................#..#...........#.................#.... 76 | .........................#..........................#.........#.....#..................#..........#.....#......................... 77 | .............##.......#.......................................................#..............................#............#....... 78 | ..............................................#.......................#........................................................... 79 | #...............................#.................#.......................................#.......#............................... 80 | .....#......#....#........#.......................................................................................#.............#. 81 | ...#........#...................#...............................................................##...............................# 82 | ...................#................#....................#.................................#.......................#...........#.. 83 | ..................#.......#............................................................#...........#...............#.............. 84 | .............................#.#....#..............................................................#.............................. 85 | ..................#...........................#.............................#.......#.......#.#.#....#............................ 86 | .........................................................................................................#......#................. 87 | #....................................#.........................#....................#........#.................................... 88 | ..............#..........#............................................................#.........#..............................#.. 89 | ....................#.....#..............................................#.#...#......#........................#.................. 90 | .#.........................#..#.........#......................................................................................... 91 | .........................................................#..................#.............#.............................#......... 92 | .............#..........#...............#..#...................................................................................... 93 | ....................#.#.............................#.#.................................#......................................... 94 | ....................................#................................................#.....................................#...... 95 | .............##...........................................................#.#....................#................................ 96 | ....................................#.#.........................................................#...............#................. 97 | ........#..........................................................#.......................#..................................#... 98 | #..........................#.............................#....#...........................##..............#....................... 99 | ..........#...#...............................................#..#..................#...........#......#...................#...... 100 | ..............#........#..........#.................#......#...........#.........##................#..#...............#........... 101 | ..............#...............#.....................#...............#...........#.......................................#.......#. 102 | .........#..#...................................#.................#............................................................... 103 | ...............#.........#......#......#..#..#..#................#..........................#..................#.....#............ 104 | .......#.......#.........................#......#................................................................................. 105 | .#...................................................................#.................................#.........#.........#...... 106 | #............#..................#....................#...............#.........................................#.................. 107 | .....................#............................................#...#......................................................##... 108 | ...#........................................................................#......................................#.....#........ 109 | ...................................#............#.......#.#......................#...........#.........#..........#............... 110 | .....#................................#.#..#...............#..................#......#.............................#.............. 111 | .....#......................#.....................#........#................#..................................................#.. 112 | ....................#..............#..........#........................#............#.......................#........#............ 113 | .......................................#............#.......##....#..#.............................#....................#......... 114 | ..#.......#..................#....................#.#..........#........................#......#................#................. 115 | ................#.......#...............#.........#............................................................................... 116 | ..............................................#..#........#..........#...#...........................#....................###..... 117 | ...............#..........................................#.........#........#.................................................... 118 | ..#..................................................#...............#....#.......#.........................#.....#............... 119 | .........#....................................#.............#.......................#...............#..................#.......... 120 | .....................................#..........................................#..........................................#..#... 121 | .#...#............#...................................................#...................................................#....... 122 | ..#..............................#..#....#.....#...#.....#........##............#........#.##.....................#............#.. 123 | #............#.................................................#.................................................................. 124 | .......#.#....................................#.............#......#......#..................#..........#......................... 125 | ..........#......#...#...............................................................................##................#.........# 126 | ........#................................................#.....#.........#.#......................#.....#..........#.............. 127 | ..............#..........................#..#..#.............##...............#..............#.............#...........##.#....... 128 | .......................#............#................................#.........................#..........#.....................#. 129 | .#..............................................................#................#..............................................#. 130 | .....#..#........................#...............#....#......#........................................#...........#............... 131 | -------------------------------------------------------------------------------- /inputs/day09.txt: -------------------------------------------------------------------------------- 1 | 9883356733752069656661181949779760668336947879672334631498492012279248564815678743918257448799319394268097164282313431712170232427711341278448916123555398963258649192254954428653124048627490363654445098463746705264577434331872739013223257852686325396697166785638826129755245235190709399598738659344508060635161185663324868573885182433469142265019784585737647295954667470632356552310324986978582442373946683324324964975714411442032304368571210978040452375554437723241626980594046753116656563509033582217499974991050134612298676291437298830232670458958219114171954451027352367739620478811495628756386541454713737366356111396226531647796778156447213557264103125841191713843757879301825505533453412476928891777791351737361271824619255577975586534476383753744919060501896538114501577965998706141772971209530162029611212394330506366554760555985142486615059863665687038214179699497301518671235225039492252152831716676249276459715873878384073464072107130115017397861339839974612262240665898961586771878531734607833716543388957148829186678512928177033946090629333529733506188186491613897795746195676809483647332656452184268453163657020142050372765496336683247811884935692201117801592269834244542309222751840604155598822227798309394498363764883786862121857736540788261474227727573412175921075911613378269583723493564169193703048107587824874507062172662316199464348924079568980207043197747731699644026757735542726813181286644228218672046427990847221832377789165397153394375317488763889333787123219407819215168529579908731886226239268502975706487441416997356682064305998636328307113664355564840868361978472573841164836852638262380254558998276331311259321936449351314839691926943221768453235649270701181576626894059389974499339646710732716693944726670597014216317455536154850912570211723421084726837163066678451494298835856395177169799446984621942806126353719503476824664397994141971252455842399737184857680309555968583267395151918467779142081885016329640358734318651614815274714217361819541411245482744942727223724341036719762295093691593943642695981904245811763931437506664169019253386477962205615978146656122809239164153984041695920788386152526156651567161529613461075949987112434688430577931309566169938658238131388748673502393192966732727669176892230919335512042768019752490429924614995548790485236919892572581165918181889945981625991679388139740392886185070704069391458729396629064967719294157985428512749485068703151629444515826641465363794311668907458547074287419227448154297192011603664309292416178131683644752872050258037223667895571881735267731619682303693113966616892347897586716546532647515254969203958682032224086613534856095312173392176821627487358438155926690388994175855839248259592583158115924176581194228135144321212144612404814173818165971197080324010425577891463533490228555831854329959177368166973665428489143193498369966397039974022459115212827302769786335383711753289878858888347477763603116959748371911358872941047169133943230873983851190696084753533987563447044225998578548836074893487135550728570221787647980451277456271891871624638884052965468227916727087869861795555886885968159474793392795528716972474306285699940177438694265557321776690614226501349518145887036414862424271735173151666215396509958697963466163651799397415229168111121912551489570394885715344189110112361282433604124163632175357526337118452132159963182341630539680977021753880579239457089551634994026538289663528325339236328152566952086836038905324227172132834124329594591191923629950743453145992306064672222762235807963593817695660515172482489453688919570595591433751273030183683714995478755667593325936204584941326969197226471128682728999845978288190492744518431783416339478743290182163593658604157792595274347414386866048553430198923828336873693295851831465287047112486725349632081905333758331119996211127566234502295418282558161312537781738584112391614856516295872955898538881702494502275922438131954803275957973305149586967106220974672724018361192186118906128163176626674873244874518431436966840218178724296142054642332557418129132414956123214407158419679596279181341745495813039235143194037441769115217676181107224378686288044659623815988405093577141274491494270284546184583747873214053423324458846314462282862392472318084336060531738151829485076295782113040501365477364524166505660316865952326609661798143592651341054228799358817759077687559318451287829184584385093763848924720114437615427904852166522586453549189178513691669963062202377767713866084969138581221644642388399515572532717438159263432583293559754549669296578758984347086627546465729605425905342101995416573335592158918466882541643249199901697467353472250175852479938791414295165433144796691478486471251301526439296744457536479351413254751913262292810401851177040286959929252685979462173928453424181742375153072621370196987618980939081678477621248512397161496561374797886371885134691398185204413863348846133589520134176681445787399786095818933664384183427582728461416372811364896875186814192397537182244209297699374782329548370982283244568347180377438697436769588211147489572225869289915678735405977955611786722962839425875896145836157532148177590323673661595675760398879674958588684941757527660131284495090587120429395916753595621718487925288324276511897387259894614543017155269757980165877386816289598581129741553826921279815849997601295477318217671633886459583199792664652792237553557298879911191726664957522628280488559609331673161471215491261656077833025156243223613651267812936647915922771602291878249426456657170877766652440119725798137236697446243623747952092198298491293717551344060899159934356754713287233988775597913407833832821517710207972896154637773949752549652316350784061433763175887354294973443432075491063295635718679865271717197692751216898466464977727373035735337619642315897228286778046935972676291157094792637486367344697926164362672118840126234222022167810474828404259701635339838619688621165477773519813975974119050657962471951967662135826361927674365912932544210327883394764742693492498358639797913793165675220263267764515187896594166988398323144988844332310409276448397888411314185882019538359434410898991975023609032111767196983746852191727117694312525529312979422563983596667231244735696227768231823394254706367861427999915841574871739502958495024921482375264347725117418369250437463793329785224905992684494976994345413663252629190526169492437863027811827395072638493319834411679973598833926917635318230847549926486984555575936265161249083679957775878456430244885781189527810586767371570268733339614916325492498722861462145144585172083785627558451569647242372647113602570963095195526251747743377484637208429169391841791576577821548784743847045603848253573396726986010488485724511296317779148953279124572734961525144663788541031829439328485764236389524725750574924955224512159226810741863167669289751303648851248799554104765601536179821872419916433506936555193536661706634688039295915461836968769163994341118639640919795404147933484583999255262835130509610115293919094802334531636491840487441956648269753906091548766333284886769567419576499547484957039103052141481667125596671194617264176102970392179201337564770912210943015203357549427894822516880757125855017481690143193859769698923759315353860205477764052446110158873208167146159773031609545598613924922403957894319914486214276285373267931326517925796713440119530959681465422502431124787407210719016601289473011936960634435865472728412594038314377371629989325451260597040987079419244216625219042928049436462823767396545627662384468208636911356935412866488682223105098704351917686462317462737495078259533819724563196142740383870838970398824897218624563153918243444288932986299583879434777872728797391951096517361157031975220487824964765206833417591584320413070957565462750869468118068739887353356173251883879564991782334983239994675671187964648348746364977932941578098106497518274593629998739452867233724301617247747461181675033569757405914624084617431304688551663802455601699952448718537227028642394647845875030162873474155787570389232502111833053786758397197444912285715931641452866459016135571438420905596182318851743513973274885643988767539699913422282465984693031233445641547432292324497816881584881921455407546983543982744914223211481551713388590165443467143836213704116936644913234302732419476714536653492541650193538583766675980411225258388904469808333548776389373554798162057953994187749792157721191417115879418923652566924322175113370123291248866131934728030871129273756323138454526744397714477164662678170266767207738141737322444457262818889918657723047277336639311422661292245415664665679939720685089986275972755469876619265807572869691812540143116946188305772525451984316529142943847739769364089668278532341472668899964548671801677547655284524691522845863907661332425473048796291529060104646943543242644785993667484604322619926714135363664242234797818669825284349641067348834638825937976531164702993654755267026468028282322151318323383544912891799584927419399711257932820524019511648983147707319416212138761983179614075947884513751587480556343267138511220492730932194903095129997865667752025896178168778312769676973313741946364158284663676712581126191594749456696356943982985719792718120283071634894639782876384942619186629285514244646446276811559585938784996513539217080497590264040595468899471826313528045222311973659136224168474477073263710714312401516298752783723733132576294375148917549801687247725786096953910635612158423264026364767401629672977142824675884437978818877532650467813881335887184169897801949479139561121557374714268112312199674693378383123551841124152525635831483769084201285222988529225526427724820512611976717757032616330475269684298802332721518172382643261568798115759763674218539933065288769882029276526988932997439668829252573177698311294149983775050129494971332155834229542614384614363789299582468619481794753538878237078822093177480229616893650739618186560477853494015808190999386187221112835682661778530254353528145929646747070418588992874869834336747784160803639119869908434708286816737919416936766484365789961689581202667178412841418237921974335931834162381924495532571303286135047781690531425403085662520734974325720961919706653973438432277444132257635723236242481571736157614721619937912946235708370677284684287286862917742881055988327311457301546778244851128724568533537594138537178639297353880705637612885877136336013214118283975679792134536326662228548882487671665508189766433747463795533452639259465391358181697587065279138184314602959371854621675838435832258336496237617779993735667418234176146936436259168947396682999894955659055817127357567593394797375162816495112742211472421417542734461604328877268347132677528833365101399549177105986645449119996561338576983732761367813185275335861292594267441516546978885868731537195649458896524546124693268162248306493697839383363454521958915751930925213217627713472521830363388882813981333293378479633651931984595923183929922702834966844285456469445105126896854368696946254668381641788305986462240835393229783999080156430716930181457195935656397784952542830289785909252153982533332458022803474184516234763684521705622811145679082151287356723537999356814512532528949528969579149153420261525717336728254855457827980242427304257316437821868161726375297745426711048769060879245681159838438595564231082891597185147474329185291245193104954341266827012466119427710716361762496497271526730643241627790778667959896345064608438662893761130512829847121145443214639412281277646244264293479869736776852446198669374601371636554711726845892357654378590208272665129166086236636718157524337811652279283845620103951484662204444137037838593716574932031815427231056635580608546296233386598571968384441443263648547513657497758603765738354528157578318266460565644125676694848913622905317825980542226791695123783728881592098922243741934607241892380764459272741695817747362868038577165359829287047994916661958583447543716265743491084349882309696279131416771192463894871798276256038329986927658216244841243929145518992274721935892717037751987411022129998674498981942906222829795881667831050857254179929636697862155557081207248336012849368586846364246682468596584227918659329347194812776589361831491585814421023357676102175876363832595274114137536209574544825362219561319284938214024903748803539392679528466299824896550804443446613188281353444468885625310638293952010346964995524861034529197984964478376694431778475374325642770609251467057219274367932833869822783514718836563506163534338548484114576359459802354886311741960628279479841178795893845551568269399577846172279124161435489342668586349317329872674326228863962813645315423417015676112675571905611663349145153531034403010121230413525237243926568443338495356568037999870368212631424971015639252197676896218582221271633639584863883476422801093982915855989315079981481115653656515396597144516992884707788254456898021105752159350207689797625203774248828666824178049238211545072717756141020453086939596358067154454469827485749165218223445948739163333769241679325826049572488739978581560321865462558686412232868766211387579443898987472933063362273276621648570879416542180727314369154377940658965651537136769401910424984434474599717628123277330632597717052328514961280987692184774529111165996376713335716915097503778196741959743976712578096663843919527843748966263645268486572487333199866647414302517185990944275189279599476108948814844479797451994857498825139308999362277975838752373876849765353406321518493719024601398967117126675684438324214707255963551912627812726823467271440104569959638701254673847686892322659269438191292454640589915171054541779864960196872759993272999994361558930322226339250552928878051612070104913719592769739527543664363208299845051598218159315165292706331396133576692331148869665783187473163779475127711144998841473954184711296959670998035235763747529647456188252616397511064495832622610512622429821445016327820975755998693842362134465609270863033129961562396549435338586198563992216846142989932249969101535435684889022218510866318824367526572944795701266531259966291826331565950189825647174682838183774427947415560816811612050352737263973105281812389921422711087164182568670317165646714182440661055381478247181808580511746476874721445762976444141977588173328242131227147488043102351806698672280663128174352336514938599305131889693142336129066813611434424702467247362593013386559353821971589679097811575497399196911143992496274655978715883136585606930437668166225566586741178663830337748666120654313345564131888351942751929813352616568583531656460161360262287989055923449115723314312638598644347357852101229638211295235826199419529564072255776988278266041606510364484421272474269671333233171755916647444617057792777362758456493823114691019916823794563693224567965699772404738498892892557987349753045507189862756513479963084918433846043297773713552184735178444528529507922847850182748671835105892964058384824129948415690909067469252802112289940747020107042618913975694113861841296315448998338729770706075176447644672372642955963407027866531611342959968281356672696924293668235378697525664912724784027164858201094527579287624679181197234361482684077871276728788159435699350564246701177267853685421366479418977384867802955803067623018421043596741295395117381454523186422615430398196242825218139756498107776299919923990277614317514254319647176164774539059469459273156184687134886732289347259323082461959973155364576553041157952443629422394796120594888385496545177775875756325861926214291185063481294874928731422799598285482459849358195636148579116417121745476449279823242866066102823274343994631233029913997472636963847165053653696105325181531381750769133645956354365722982219734651340188174673327944331893427496810491589427270289639402646226711287010197277345173318251507755146643547630528289954530503112342780875519312760138141619322496324657264428630303552269369534148557144298743224786459285322472673681943125554985948163842575129682236661127655346054589393817658386596419268328656257467429815453879409578518592706815886573863879378611702782468230408029978028193858137498781550798897337390615839457199397428111413722777763676128364606334909374439676673672853531726417616987867187914722739850898627299196541262145670152016219190857499211168453797692977572959281597929397822962477717615984396274164939506022776754941341182160748969968767598617169581662397771428616899186915696495338679451035999757834370354924879113741549942795772923668558947377915787314396371394784574968656158657565034693327456669177542915051905575476059783220545938234511664396882360139286175046298217436760766478444144239015741869846029592198486630951993557029614379476451855626704420128482327451306211791445514343485438834838254817528567461895424434927737596953315987301041864246188076624099882225138985974070315096895247371594315518941299735368195663976255876311536117877671696713896571239689407411105863756557126785316795308321935041688243204793646782432842896615328240411178152380836310798421441414998550662721133367707695624710896079356996993398863426731931367136278855144259958374123588219098301313434052176087104260814545475984715232614135281064485520635647985723917549698547635161714156946491604895132583175915936986321747784782159327832216262363512314463047832025813650866580461426239786919410892638354986248312186078607613292361444941481225631938207179352183101491743583202525718936755176273745476514797419679385413652583789695544452574488910931419803094382972331662155934237519663035824462139056969293596223386740271396244648812626208685795151783198808765533716762215903286314824679789706966919730981389129868223264509149918326231354949775592894773060947721231771567520795093435943298935531127156036153229527893158193692547394157985344892778576396165853941433272563854629232415414558109468168580524017852887924867859193824113874799836175795642352189506093747771622286795913321781835214247039494167143024926110785963995243168120124151175117527585514788423023343548337053489558454252283119447817657214985891662945789263812772977599415677761196381630436217542659189774895473905068312810114795404115752971807892372944385039542765599320172062393919675693863178204285738196311664432131437198895895167079642438744971794673623472384321327130295244905287363349231569734748752634443433862991718624123293493795753482352958876888186729827834136910497521113229382378264724465037498817795944301971554926639884344917864352912850815182373519382370193416377770789013827445711290637077463235494549834253518858208063208837324028968650398093293415238250209584476670813270577333236447449476915841657725403640513440989848444096261146604093177865856867612867554348642727386495831786896854473143839375792289368695951677651330795881722354919165985744364645495588387635765512585336994940947050403564912573644162129261158863226697959180185853225285948933473694429341622845108910986057958186228283388596609389382957848980671524959892333379899910785149696732686117329513644252644981691769313951562037421222993327511475946320337518332434356511712259919160684168129731625519709719108515583846226357991832662963654427133359517239771987149692949560235952873845479365716649255485336458641678652557832418958364273773454558921840679291282097401461794629792769898821224694171789318371185634581664575790211914303680806346953355577035136965373530349083216614907713955965674163396666802591993767767387548959681183517692702051751690279948371546689786275717953692839630869253939643739644632081737839636392969140819870364611893354811171277341897772942685307541378978725525275544286263658370642730212142991677979888586318155787998298197290786627724729871127129226649077369522214915591915613284422234968237932718685496539140297692797728656173577027541573318631905889913920278168965292503997496138847265404592246221721197612058875021818240531368656885324733776159855470235250439667495331505251964381962790644713216414954067451724232177991311285437255575853951924022769756568557759888934784289431766810165798775124752348769764812653485034652388885945266761959047895756407468418363815018837670378564595271856184176694895293417846989544812915358344271478803880344167564821918594453538344091329 2 | -------------------------------------------------------------------------------- /inputs/day03.txt: -------------------------------------------------------------------------------- 1 | why()$mul(735,469)^?!what()don't()~~('mul(982,758)what()^-^who()mul(294,364)&#/ )&%)[~mul(285,81)what()[{where()+ mul(129,761)^]why()>$^<>who()mul(53,344)select()%mul(567,352),mul(915,20)/#(>+^how()'mul(141,658){&~!how()from()?~?who()mul(830,116)#%;mul(139,634)?,#+who()@mul(169,719)[)?'-who();mul(18,751)},when(){;/mul(691,391)mul(856,314)^mul(558,88)]('/>how()@where()(,mul(274,100)%who()#~*mul(220,748)@how(){$how()/*%$when()mul(718,754)[!when(617,291)!{(what()+*do()[;<+ /from()[mul(840,803)}?mul(429,848)?select()how()^why()],&#select()mul(519,894){ !>:^@+mul(522,225)@!^^/'[>select(118,66)>mul(847,195)when(585,749)]mul(641,667):>mul(317,349) +:/^*what()mul(352,440)select()mul(349,981))@mul(450,917)why()how()mul(471,401)?where():}select():mul(632,956))mul(727,370)!}$~*%+$don't()why()select()^]who():mul(276,773)*^^mul(757,668):}mul(232,346)%[*@$ where()mul(898,992)who()why()~+['mul(43,434),where()who()>what()mul(908,953)select();do()}!select()when()!mul(676,368)how()from(966,785)@:$+)how()mul(414,120)mul(108,395) +~{#!@select(),mul(483,964)&do()?>mul(963,893)$,,/%'mul(318,508)?,{mul(390,813)select()>(select()mul(792,357)!{where();mul(717,18)why()$#]why()$^?mul(948,239)how()&>$from()]:>?select()mul(453,180)&&]&,[how()mul(674,281);*how()mul(548,919)how()]{{who()~+where()where()&mul(962,14)/why(),%>when()mul(31,451)/)&:,>}mul(225,266)-*)where()who()]#mul(224,69)#&-+~mul(309,393)@#;%!(][select()mul(389,558)+*how()*^+when()]when()mul(995,181);(mul(5,74)&(#^from()$~&don't()}? ,($ when()mul(216,767)>()!,/how():@mul(425,905):]>>from()mul(93,831)}select()(mul(70,72)mul(137,510)[]{where()mul(477,400)&?/who()who(335,756){/mul(364,311),$select()what()mul(710,251){mul(351,763)+-}mul(517,661)mul!}?how()where()mul(948,407)-{<]*^from()who()from()mul(979,180)/,:#mul(602,496)%'what(),#}what()~how()mul(343,710))'when()from()#mul(314,877)(+,[?mul(480,685),;do()%*<^)from()what()#@what()mul(502,65)where()why()(!*where()from(){/mul(847,541)mul(116,490)]';how(612,404))when()who()&; don't()mul(446,220)(%'?;{^?mul(784,876);)]mul(959,402)%]];mul(362,432)mul(330,805)where()mul(142,473)~don't()-who()mul(965,688)when()[]):-}from()%mul(949,478)why()>~+,!&~,select()mul(633,237!-who()>where()]mul(809,464){@'/when()when()mul(720,462)&select()select() )@}'~how()mul(518,133)mul(512,118)/}what()*][++mul(56,978when(),where()&don't()who()}where()mul(329,879))&$,:when()#when()@what()mul)~who()(;mul(141,130)'?^}#+#from()'-mul(237,78)&what();];%where(614,809){:mul(391,45)mul(787,970)from()-?&~when()mul(59,790) what()where()~?what()mul(399,503)^from()where()when()mul(190,97);why()who() ,select(){mul(428,654)mul(350,302)?{mul(592,241)when()how()mul(705,191)who() !who()mul(50,6)~'from()% &]mul(902,106),select();/ why()from()>mul(800,867)select(659,586)~ )when()}~&'mul(709,298)-:'do()[who()what() mul(31,997)$%(where(309,559)%: mul(177,184)@mul(58,102) 2 | '^why()>-why()mul(489,67)who(682,115)where()how()>why()~;'^mul(179,994)who()#[+when()}mul(343,121)]^mul(622how()select()<{how()mul(315,335)-:%mul(611,869)who()when()$where()who()mul(242who()from()%&!['do()@:^-})}';*mul(266,851);^[{!&why()how()from()mul(980,269)^{where()how()/where():;+mul(971,795)#>][+^where()mul(279,554)/why()mul(736,24)mul(63,622when()who()how() -;mul(500,888) ]where()where()when();mul(255,25)<]!-,#!+how()@do()mul(670,579)?(//]from(41,426)$do()mul(427,50)/%mul(359,247)'what()~{~-?[#mul(862,40)]{from()when()mul(426,212)>who()mul(653,462)why()mul(15,779))]mul(258,38)how()**$?(}% ;mul(624,853)[;&select()where()*-)<)mul(111,225)mul(440,503)/what()###mul(840,369)who()mul(529,595)>(-/who()mul(168,832)mul(658,544)%:~~)what()why()%+]mul(358,878)who()'$+@-)*mul(30,603)&-do()mul(627?mul(834,46)+when(751,926)-mul(132,173)who()do()-%where()mul(487,54)!$what(),{mul(546,92):$where())&/mul(978,930)-/mul)#mul(693,136)!$select()mul(490,906)%!}({;where()mul(853,453)*]!<%what(85,66)+ mul(720,355)]+mul(65,942)? $mul(736,168)#who()from()< %mul(279,223),,how()select()'mul(949,79)@)-who()when()+;/why(),don't()~(@,^~mul(55,965)what()select()'where()$)?mul(615,265)mul(801,65/why())mul(55,877)[why()+>:~&%~mul(418,463)from()+'who()(how()who()when()mul(176,831)!#'mul(350,399)>'@{ '!mul(847,397):{who()'#$where() @mul(148,609))&,+,<->$@mul(475,800)who()what()do())}from()&why(821,875))mul(675when()select()), %mul(786,308)-[,/,+mul(305,3)how()what(107,974);!}+how()mul(535,976)from()[)mul(820,558):(why(){^mul(715,523);mul(288,378)'why()$why(),@mul(184,850)when()'';^where()mul(957,549)do():~{:{)select()mul(347,642)from():(mul(834,376)>mul(803,111)(,,'select()select()who()[ !mul(143,742)+:# {mul(891,385)where()}<%^>mul(995,109)'?from()$):who()mul(414,498)&/%mul(809,958),why()[!>,mul(591,908!(how()}mul(600,673)'%* *mul(48:$);(/from(371,7)(>mul(261,884)?&don't())mul(246,229) >;*'&!don't(),+mul(131,199),$don't()-(what()mul(13,595)'don't(),who()how() %mul(839,198))do()select()*from()mul(903,555)what()mul(74,674)%;@mul(190,543#)])[^*! ,>mul(428,756)/:>+%?mul(585,685)?@~/*why()){[mul(87,499)],@~!}mul(585,674) [,],]}?[:mul(511,978)!?)don't()&~*mul(735,638)select()[{from()!{>mul(897,633)select() #*mul(680,8)mul(671*how()^mul(580,632)(} how(9,101)from()where()'<&mul(936,112)select()what()how()#mul(720,608)'&^/ &when()@mul(697,116),#from(),what()!where();(:mul(833,800#mul(842,722)why()$from()[(^from()/mul(591,920)how()(don't()}mul(65,254)#why()@mul(696,883)^?what()mul(917,413)from();>{~mul(524,943)mul(465,955)how()select() &how()how()mul(528,18)how()]]do(){who();~>who()&mul(837,821) 3 | +when()mul(957,88){mul(446,234),(%[mul(225,735)mul(616,489)<[]~+@why(274,559)-why(45,518)mul(841,337)@mul(826,883)-(where()don't();@'+~/from()mul(829,811)(what()how()how()#mul(435,969)mul(743,179)from()/'[/,];mul(797,84)[from()>:~&$} mul(934,535)@?})%mul(630,155)]mul(81,271)why();@;%]who()mul(616,154)^do()^)-*;/mul(562,475)select()(select())$mul(119,594)what()?mul(103,712)why()(what()mul(358,496),why()~+select()what()~select()from()mul(316,752):+^mul(851,254)select()from(){when(216,975):*mul(776,658)from()from()?!mul(724,606)from()mul(878what()^%'why()>]mul(920,733)mul(500,262)when()why()do()]!who(333,560)]why()^ ,}mul(594,767)~':}!mul(69,623)})where()where()@-^mul(510,559)from()where()mul(990,412)%)[ how()mul(627,280)@mul(314,481)- from()how()who()}'<^*mul(515,459)$how()do()]mul(307,482)@~( $(@-%:mul(460,946)%mul(942,646) {>mul(160,832)where()when()what()~{where()&@mul(24,840)^#[mul(344,387)#how();mul(525,285)mul(221,638)-!/?#-$^don't()mul(91,395)select(43,376)what()]~mul(677,682)from()$ mul(358,545)$+%mul(697,89):how()who()^mul(599,952)?where()#mul(752,46)where()* ?},#'mul(803,569)select()+()-when()*mul(5,223)'<])#~*^[mul(360,79)<$+mul(784,713)-%when();from()why()<]mul(288,526)';^~do()[;where()}%?<^+<mul(25,575)#^;mul(169,580)when() ^where();]mul(575,888)'who() &::,mul(172,538)@when()*!mul(718,235)%+/mul(281,117)who(),don't();what()how()select(126,34);why(460,565)mul(153,278)~when()*]mul(284,592)what()#@mul(416,344)+how()from(472,343)+]+*? mul(218,315)who()#:$@{}mul(415,704)mul(367,153)*where()!'do()what()[mul(298,416)<'*$:} !mul(8,562 ~#/[{~-$what()&mul(312,424) '??mul-$ -mul(49,590)>[+{how(472,207)]^mul(482,423)&why()(#^' mul(178,565)~^&>from()!#?don't()why()who(596,596))who()from()>how():{@mul(385,718) ~?@//**mul(783,105)~why(22,278):#how()do(),from()!:mul(40,924){[when(),/*mul(694~+mul(311,607)who()[/'mul(744,908)%>: ]~,:mul(310,993)from()%:-(+where()when()[mul(455,786)from()~]?from()^where()mul(460,406)how()when(831,855)'where()>[,:mul(250,253)~:select()){#)[[[mul(825!<{from()mul(205,719))why()@?%mul(729,531):where(); $~ mul(547,617)when()/mul(791,433)from()%select()what()%how()%}}mul(616,548)?%:',when()where()who(),mul(417,691)mul(548,124)<-%mul(459,792)mul(93,742)&from()who()select()mul(38,516)why()$ ; -how();mul(682,71);*why(603,344)mul(588,565)*#:do()'from()!who()-mul(564,344)mul(58,41)mul(881,91) when();/#!/usr/bin/perl!+'mul(791,572) 4 | %mul(264,168)mul(409,229)[#what()mul(393,212)$-from()'*do()mul(274,560)-{+::&>,mul(778,511)when()[;why()'how(701,98)%}mul(630,304){%{>*why(52,488)?}[(mul(149,108&'why(222,790)[mul(8,101)}>;why())what()mul$-%^why()mul(823,831)'*+mul(2,756)>, *don't();/}~&mul(602,479)~%)from()*}-when()%^mul(849,417)$>!-+from() +mul(280,463)'select(),@how(637,7)+&?mulhow(771,951)$mul(373,910)what()when()from()-]:why()mul(835,707):<]&when(915,675)~mul(628,69)&^@&#)mul(419,539):%:mul(534,992)'mul(987,602}why() when()]mul(438,915)~}$why()@!'#>don't()^)}?-select(355,550)},,(mul(649,262)^ *[&}/%mul(867,47)mul(104,808):@why()'@'($$mul(74,805)what(597,630)}(;]>~mul(217,927)>what()mul(669,965)>from()mul(647,126)->mul(52,497) select()mul(22,612from()why()'mul(277,463)!mul(473,104)[!:;mul(655,992)how()>%(what()-mul'why()!&where(11,929)+mul(314,422)$how()what(610,732):&{~}#select()mul(517,349)why()!mul(815,441)#why(349,312)))how()['$where()[mul(593,303)]#$^;mul(901,6)<-}:,who()mul(254,964)select()@['mul(297,705) who()#^mul(794,226)when()who()who(562,667)>}[mul(265,242$'from()@}mul(724,493)mul(313,610)*->%,mul(83,839)^)%mul(149,753)&when()select()from() 'mul(3,784)select()select(715,428)mul(502,975)how()who() !when();{[mul(106,800)<;mul(513,728)select()select()}@;':from():mul(259,697}'$]&':+mul(998,295)how()@who();!mul(947,199)?/what()where()where()]mul(415,221)select(487,105)^mul(688,128)#&mul(394,445)mul(384,810) @!why()do();&!where(424,549)why()mul(934,449)%()-^from()?who()<(do()when()'what()#mul(424select(76,581):<+}from()#>+mul(616,317)#$what()@-select(425,315)mul(146,882)mul(509,291/#from()mul(152,967)why()how()mul(348,501)<[&^who()why():+mul(36/mul(856,681)!mul(46,203) 5 | mul(315,935)mul(451,658)when()when(353,392)<why()]*')mul(21,640)from()mul(755,282)>^why()from()mul(442,981)!when()^why()why()(/mul(876,31),who()/[mul(740,627)]who()/+[mul:+mul(557,285)!(&how()mul(538,865)select()what()~$from()([+when()/mul(826,278):@select(546,967)!?&select()what()mul(847,194)#{mul(468,530)*![%where()^<what()?&mul(277^ mul(780,751)^what()~!#mul(635,606)?*when(): }who()]-don't()mul(42,308)+,(how()how()$-!~mul(29,791)%)mul(248,71)#when()-)]mul(670when():from(505,247)who()>select()what()'(mul(327,578)from()from(){who()who()from()^/mulwhen(801,176)what()};}! :#-:who():/mul(466,327)#~'!),&>mul(776,335where()]why()&]?]:how()how(),do()mul(442,378)when()/^^mul(407,519)'-mul(157,451)+]from()when()when()/mul(689,597#{mul(387,624)><]&$!from()%[-don't()what()why(801,120)how():%select())(mul(847,645)where();&'}#how(698,791)!don't(){)<^mul(694,504)](/*{$who()+mul(480,559)where()#>'who()[}select()!@mul(225,926)when()?%>+mul(631,126)}#@how()mul(712,802)-select()why()~'mul(748,579)from(){%mul(649,879){:select()~&!,[ !mul(147,693)<+}mul(87,949)-{where(345,734)/ mul(351,115)>mul(52,566)&mul(427,269)}mul(901,457)when()&mul(600,957)mul(734,851)!why()/[$/how();mul(383,59)'why(802,790)(;%'from()who()mul(904how()<;select()@{,who()>[don't()why()}[&[!mul(859,668)what()^mul(483,700) 6 | ]where()>>>&^@what()mul(320,309)[#<#:]~/mul(497,511)mul(95,653)how():mul(572,330)&mul(809,308)*(&:mul(29,810)who()how():mul(915,147)when()^#mul(849,988);who()?,(/*mul(129,470)select())$select()-&/why()where():do()mul(590,753),@;'/mul(396,339)>%mul(613,991) '{,(mul(899,674))/$}from(656,762)'select()(';do()+-(@mul(502,495)]{$>@)+do()'why()select(),when()mul(454,97)')'where(326,126) select()mul(334,130who(494,552)%@*$who(979,600)mul(876,925)^&^mul(975,151))who()who()&mul(136,404);%!';#mul(450,492[}+[&[$}%//mul(487,75)%mul(870,786),when()why()+~>mul(316,132)-from()who()when()'@who()mul(169,959)~~when()]how()+from()*^mul?&why()how()mul(641,834)^:!(-#mul(197,843why()?}[-mul(479,27)#,/when()when(284,485)from()(mul{)from()+'$~from()*mul(555,485)mul(37,175what()why()who()mul(849,203)who(607,487)how()select():&&;mul(874,736)when()/from(626,997)mul(482,451))who()[};mul(186,966)select()when()*mul(918,369)~who()](%mul(452,814)/&&^-!&$<<{mul(161,632)]mul(434,106):){select()mul(137,656)why()*when()^mul(198,859):mul(589,609) @-mul(79,388)/+}~]}from()how(),do()@<#])-mul(673,936)!mul(999,158)%mul(600,817)%~!#?@<^mul(948,543)$),'mul(108,479)]&mul(359,23)~@{+when()&%^!{mul(186,477)who()from()select()*{where()how()%%/mul(714,701)select()what()why()from(138,787)from()'$ mul(589,314)&what()}]**where()don't()@'?mul(905,694)%~mul(52,222),?]mul(726,995):where()^'[/mul(948,887)how()mul(396,68)what(){;select()$[% (mul(939,722)why()from()$who() &,$]mul(917,716)how()where()']~%'mul(174,257)/how()why()@select()mul(673,441)-<)'?select()do()how():what()]{}?-mul(202,788)[mul(842,734)who(980,842)/?/{+how()select()&how(149,196)mul(533,78),@#select()don't();when()mul(595,87)[(how()-;do()@>what()mul(543,798)/&mul(118,844)who(520,900)>!mul(615,214)'-/select(){where()@do()*#{%/mul(254,489)$@*,who()^mul(209,427)<%how()'^!^{how()mul(112,898)where()-/what()% ^'mul(400,703)mul(347,239)+:who()select()'<,mul(695,520)mul(595,418)why()?!#&^,;,:mul(128,623)$:/@why()$,!$where()mul(489,451):]}mul(426,973)/)don't()-<]what()what()!how()mul(384,927)?select()~:]*])-#mul(210,978)why()-/ -------------------------------------------------------------------------------- /inputs/day04.txt: -------------------------------------------------------------------------------- 1 | MMMMASXMMMMXXMASMMXSAMMMSAMXSXMMXMXMXAMAMXSXXXMXAXAMXMMXAASAMXMSMMMSXSAMXMASAXXAMXAMXAXSXXMASXMMXMASXMAXXMASMMMMXMXSMSSSXSASASMSAMXXSMSMSSXS 2 | MAAXMXMAAAMSMSXSXSMSAXSXSXSASAXAASAMXXSMXXMASMMSMSXSAMSMSSSMSMMAAMASMMAAMAMXMASXMSAMXSMSAAMASMXSASAMAMAMXSAMAAXMASAMASAMXSASASASXMAMSAAAXAAX 3 | MSSSMMSSMMSAASAMAXAMAMSAMAMASAMSMSMSMMAAMSAMXAXAAAAXXXAAXAXXAXSSSMXSASXMSXXASXXAXXAXXMAMXXMASAXSASXSAMAMAMXSSMMSASAMXMMMMMAMAMAMMXSAMMMSMMSM 4 | XMAMAAXXMMSMSMAMAMSMMMMAMXMXMAMMASASASAMMXAAMMAMSMSMMSMXMMMMMMXAMXXSAMXAAMSMXMMMMSMMSMAMXMMMMAMMXMASXSAMXMAAAXAMMMAMMXXAAMAMAMSMSAMXSXXMASXM 5 | MMAMSXSAMAMXXXSMSMMAXSXSMASMXAMMAMAMMSASXXMMSSMXAAMXAAXMSXMAXXMASMXMAMMMMAAMAAAAXXAAMMAMSXXMMASMASMMXSXSAMXXSMSSSSMMAXSXSSMSMSAAMXSAXMAMSAMS 6 | XSXMAXSAMASXMAXAXASMMSAAMAMXSMSMSMMMAXMMMXAAAXXMMAMMSMSASAMSAXXMMMMSAMAAXSXXMMXSMMMMSMSASAMXSASXMXAMAMASXMSXMAMXAAXSSMMAAXAMXSMSMMMMSMXMAMAX 7 | MMAMMXMXSMSAMMMMMMMAAMSMMSSMXMAMXAAMXXXMAXMMXMXAXXXXAAXMXAMMMMXMXXASASMSXMMMSMMAMXSAMAMMXMAXMASMMSSMMMASASMSMAMMSMMMAAMMMSXMMXXAAAAMXAAMMXMS 8 | ASXMXXMASXMAAAAAAXXMXMMXMAAAMSAMXMMMSAMXSMMASMMSSSMSMSMXSSMSASMAMXXSAMAXMASAAASMMAMAMXMMAASAMXMMMAAAXMAMMXAASAXXAAASMMMXAMASXSSMSMSSMXASAAMA 9 | MXMXXAMXMASXMSSSSSMXAAXAMMMSMSASXAAAMSMAMMMAAMAMMAAAAAXXXAAXASAAMXAXAMAMXAMMSMMAMXSAMMMSSSMXXSXXMSSMMMSSMMSMSMSSXSMSMMMMMSAMAAXXAAXAXXAMXSSS 10 | SMASMXMXMXMSAMXAAMMSMXSAXXXMASAMMSMSAMXAMXMXXMAMMMMMSSSMMMXMXMXAXXMSMMXSMXSXMXSMMMAMXMMAMAXMAMSMXMAAXMMAMAMMXMAXXMAXXAAAASAMXMMSMXSAMMXMXMAM 11 | AASAMASXMAAXXSMXMAAMMMXAXSXMAMAMAXAXMASXSASXMSMSAAXMXMAASAASMSSSMAMAXMXXXMMXMMMAAMASMAMASMXXAMAMAXMMMMXAMAMXSMAXXMAMSSSSXSXMXSMXSAMXMMSMSMAM 12 | XSMASXMASMXMMXMASMASXSXSMSAMXSMMSMMMXMMASMSAAAAMMMMMAMSMMASMAAAAXAXMXMAMXXSAMXXSASMSAXSAXXSSMSSSMSMAAMXMMSSMMMSSXMXMXAAMAMXMXMMASMSMMASMMMAX 13 | XMAMXASXMSMAAASAAMAAMMAMMXMMAXMAAASXSAMXMAMMMMSMMXMMAMASAXXMMMMMSSMSMSAAMASMSAMXASMSXXMMSMAAAAAXAAMSMSAAXAAASAASAMXMMMMMMXAMAAMAMXXAMAMXXSAS 14 | XMAMXMSXAAMMSXMAXMMSSMXMAAASMSMMSMMAMXSXMMSSMAXAMAMSMSAXXSXXXSAMXMAAXSAMSAMXAASMXMASAMAAAXMMMXSSSXXMASMSMSSMMMSMXMAXAMXAASMSSSMSSSMMMSSMAMSM 15 | XSASXAXMSMSAXMSSMXAMAMMMMXXAASMMMAMSMAMAXXAAMASAMMMAMMASXMXMAAAMAMMMMMAXMASASMMMMMMMASXSXMXAXMMXXXAMXMAXXXAMSMMMAMSMSAMXXXAAAAAMAXASAMXMAXAM 16 | MSASMMMMMAMAXXAAAXAMAMAMASMMMMAASAMXMASAMMSSMXSMMSMMSMAMAAMMSMSMAXXMMMAMSAMXMAXAAMXMAMMMASXSMMMASMMMAMXMXXMMAAASXSMAMASMXMMMSMMMAMMMMSXXSSMS 17 | XMAMXMAAMSMSMMSSMMMSSSSMAXXMASMMSXMASXSASXAXAXMXAXASAMXSMXMAMMAXSXSASXMXAMXMASMSSMXMMMAMAMAAAXMAMSAMXMMSXASXSXMMXAMXMAMMASAMXMXMMSXAMSAMXAXA 18 | SMXMASMSSMAMXXAXAXXAAAMMMMASASMMMMSMSMMMXMMSXMMMMXMMMMMMMAMMSAMAMAAAXAMSAMXSAMAAAASMSSXMAMXSMMMXSASAXMASXMMAMSSSSMMMMXMAMXMAXMXSAMMMXMAMSAMM 19 | XAASASAMXMAMXMASXMMMSMMAMSXMASMAMAAMMAAXMAMSXXSAMASAMAMASXSAXMXMMXMXMXMAASXMASMMMMMAAAXSASXXAXASAAMXSMMSAXMSMAXMAXASMSXSAMXXMAAMASXMXSSMSMMX 20 | MSMAAMXMXSMSAMAMMMSAAXMAXMASXMMAMMMMSXMMSXXMAASAXAXAMAXXSXMASXSXMSSMMASMSMMSAMXSXMXMMMMSASMSXMMXMXMAMXASXMMMMXMSAMXAAAAXSMASXMMMMMMMXMAXSASX 21 | AAXMXMMSAMASXSASAAMSSSSSMSASASXXXAXXMSSXMXAMXMSAMSSMSSXMMAMXMAMSAAAASASXMXXSAMASAAXXXSAMXMMXMXSXMAMASMXSMMMAMAAXSMMMMMXMAMASAAMSMAAXSAMXSAMS 22 | SSSXASAAAMMMMMAMMMXMXAAXAXXMAMASXSMASAMAASXSAXMAMXAXAAASMSMMMMMMMMSMMXSAMMAXAMASAMMMMMAXMMMXAASASXSASAMXMAAAMMSMMMAXXXAXMMASMMMASMSMMAXXMAMX 23 | XAAMAMMXMMAASMSMXMXXMMSMMMSMMMMMAASMMASXMAMSMSSXMSXMXSMMAAMAASXSSMXXSASAMXSSMMASAMAAMMMMSASMSMSAMMMXSMMXSMSSSMAAASXSASASXMMSASXMSXMASAMMSSMM 24 | SMMMXSMMSXSAMXXAASASAMXAMAMXAAAMXMMXSAMXMAXXMAXMXSMMMMAXMMMSXSXAAASAMXSMMMXAMMAXAMXMXSSMXAXAAXMAMASMMASXMAXXAMSSMSXSAMSAMXXSAMMXSASAMMSMAAMM 25 | XAXXXMXAXAXMASMSMSASMXSMMSSSSSXXAXXAMASMSMSASMXSAMAAASMMMSXMAMXXMMMAMXMAMASAMXSSSMXSAMAAMSMSMMXAMSMAXAMAMAMXAMXMAXAMXMXXMMXMMMSAMAMASASMMMMM 26 | SMMXXMAXMMMSXSXAXMAMMMSAMXAAXMASMSMMSAMXAAXAMXMMASXMXSAAXSAMXMASXXSMMAMASMSXAXMAMXAMASMMMAAAASMMMASXMSSSMMSMSMAMXMXMMSMMMXXAMAMXSAMXMAXAMAXX 27 | SMASXMSXSAMXAMMMSAMXSAMAMMMMMMMAXMAMMMMMMXMXMXASMMXSMMMMXSAMXMXSXAMASASMSASMSMMXMMXXMMMXXMMMXMAMSAMMXMAMXAMXAMMXSAASAMAAASMSMASASAMAMXMSMMSA 28 | XMASAAXXSMSMXMAMAMSAMXSAMXMASAMMSSSMAAMSASMSSMXSASMSXMAXXXASXMXSMXMMSASAMAMAAASXMMMMSAMMXSAMXSAMMSMMSMAMSAMSMMSAMSMSASMMMSAAMAMXSAMSMSAXAAXM 29 | SMXSMMMXMSAMXSXMAXMASASMSMAAXAXSAMAXMMMXAMAAAXASMMAMMSMSSSXMASAXAASXMAMMMXMXMSMAAXAASAXSASAXAMAXAMXAMMAXMAMXMAMXMXXSXMXXXMMSMSSXMXMAAMASMMMM 30 | MMMMAMMAMMXSXXXSSXSAMASAAMMASMMMASMSXSAMXMMXMMAMXMAMMAAAXMASXMXMXAMAMXMASMSMMAXMMMMXMMXMASMMSXSMSMMSSSSXSMMSMSSMMSMSMMSXXMAXAMAMSMSMSMMMMAAM 31 | MAAMAASXMSAMAXMXAAMASAMMMSSXMAASXMXXAAXMXSMASAXXSSSSSMMMXMMMXMXMSSSMMXMASAAASAMMXMMMMMAMMMXAXAMAXXAMXMMASXAXSAAAXAXMAMAAMXMMSMSAMXMXXXXASMMM 32 | SSSSSXXAAMXMAMAMAMSXMAMXMAXAXMMMSMXMXMMAXAMXXAMXMAAMMXSAASAMASXAAAAMMSMAXXXMMAXSASAAASASASMXSXMAMMMSAXMAMMMMMSSMMMXSSMXXMAXAXXAMSMSMMXSXMMSS 33 | XAAAXAMXMSSSSSSSMXSMSMMAMMSSMMSMMXAMXMXXMMSSMASAMMMMXAXSASASAXMMMSMMMAMMMSMMMXMSAXMSMMASASAASMMXMXASMMMSSXSAMXXXAXAMXMAASXMMSMMXSAAAMXMAXAAA 34 | MMMMMXAMAMXAAMASMAMMAASXSAAXAMXAAXXSSSMSMXAXMAXAXMXSMSXMXSAMMXSAAAMASMXSAAXSXXXXSMXXAMMMMMMMXASMSMMSAXXMAAMXMXMAMAAXAXSXMAMXAAXAMSSSMAXSMMSS 35 | SSSMSMSSSMMMMMAMMASMMMMAMMSSMMSMMSXAASAAXMASMSSMSSMMAXXMAMAMXASMSXSXSAAMSSMMAMMAXMXMAMXAXXXMSAMAMSXSAMXMMMMSXMMSAXSMMMXAXMASMSMXXXXXMSXXAXAM 36 | AAAAAAAXMASMSMXSMMSAMSMMXAMAMAMAAXMMMMSMSSMSAXAAAXAMSMSMXSAMMMSXMXSAMMMMXMAXAXMAMASXSMSSMAAXXSMMMMMXMXAMMSAMASAMMMXASMSSMMASAXASXSAMXMASMMXS 37 | SSMMMMMXMMMAAMASXMMAMXAMSMSAMASMXSASAAMXMAAMXMMMMSSMAAMAASASXXMAAAMAMAXXXASMMSMXSAXAAAAMMSMAAXMXAMSMSMXAAMASAMAAXXSAMAAMAXXMASXMAMXMAMXSAMXA 38 | MXXXXXASMXMSMMAMAXSAMMAMMASMSMSAAXAXMSAASMMMMSXXMAMMMSMMMXAMMXSXMSSMXAXXXMXSAAMAMXSSMMMSAMXMSMXMASAAAAMMXXXMMXMMXMASMMMSAMXMAMAMXMAMXSAMAMSM 39 | MAMMSMXXAAMAMMMMMMMAMMMXSAMXMAMMMSSXAAMMXAXMASASMAMXSXMMSMMMAAMAMAMMMMMSAMAMSMSSMXAXAXXMXSXXMAASXMMSMSSMSSSMMXMXXMAAMXXMAXXMASAMASAMSMMSSMAX 40 | MASXMSSMMMAAXAAASASMMASXMASXXAXAMAMMSMSMSAMXSMAMMSMXMASAAMASMXSAMAMAAAAXAMAMAXXAMSASXMXMMMMMMSMMAAXMAMXAAAAAAASMMMASXASAXSASASASASAMMAAAAXXA 41 | SXXAAAXAAXMMSMSXSAAAMXSAMMMASASXMASXAXAXAXMXAMXXAMMAXAMMXXASXASASMSSSSSSXSXMSXSMMMAMMMAMAAAXAAAMXMMMAMMMMSMMSXXAXMAMAMMAMXAMASAMMSXMSMMSSMMA 42 | MSMMMMXSMMXMAXXMMMMXMAXAXMMXAXAASAMMMSSSMSSSXSAMXSSSSSSXSMASXXMASAAAAAMXAMXAMAMXMMAMXXAMXXSXSSSMSXMMXXXXAMXAXXMSMMMSAXMAMMXMXMAMMXMMXAMXAAAX 43 | AXXSAMAXAXSMMMSAXAAAMXSAMXXSMMXMMXMAMAAMAAAXMMAXXXAAAAAASAMXMXMASMMMMMMSAMMXMAMASMMAXMSSSXMAMXMASAASXMSSSMMSSSMXASASAMXSSMMSXSXMXAMMSSMMSSMS 44 | MAMMASAMAMXAXASMMMMMXAXMASAMXMAXXXXAMXMMMMXMMSAMXMMMMMMXMXMAMXMASXSXXSASASASMSMASAMXSXMAAAMSMMSAMMMMAAAAAAAAXAASAMASXMAXAMASXSMMSASAAXMMAMMA 45 | MAMSAMMSSMSSMASMSAMSMSMSXMAXAXMSMSSXSAXXAASAMAXSAAXXMXSXSAXAXAMASMSAMXASAMAXMAMMSAMAMXMAMXMASAMAXXXXMMMSMMMSSMMMXMMMMMXSAMXSAMAXSAMMXXAMAMXM 46 | SAMMXMXMAXAXMXMAMASAAAAAXSMSMSMAAMAASMMMXMAMSAMSMXSAMAMXSASXSXSAMMMXMMXMAMMMSMSMSMMASMMMMMSASXSXMSMMSAXAAMAXXMAMAMAAASMMAMAMAMSMMAMMAMSXSSSX 47 | MXMMMMSMMMSXMAMXSSMMSMSMAXAAAAMMSMMMMAAAMXAXMAMXMASXMASASXMAAXXAXSXSXMAMXMAAMXXAXXXXSAAMAMMMSAMAMXAASASXXMMXXMASAXMSMXAXXMMXXMAASAMMAMMAXXMX 48 | AMMSMMAAAAXXSMSAMAAMXAMXAMXMSMSXMAXMSSMSAMMXSAMXMASASASMMAMXMMMMMSAMXSASASMSXSMMMXSAMXMSAMAXMASAMMXMXXMMMMSMAMAXMMMXAXSMSMSSSMSMMMSXMXMXMASM 49 | SAAAAMSSMSSMXMAXSSMMMSMMASAAMASAXXMXAMXMMSAASASXMXSASAMXSAMAXAXAAMSMAMMSASXMASASASMMSAMXMSSSMASASXSMMASXAAAXAMSMSASMSMXAAAAASAAXAXSXSASASAMA 50 | AMSSSMAAAXXAAMXMXMASXMXMASMSMAMMMSXMASMMASMASXMMSMMAMAMXSASXSSSXXXAMXXMMXMMSMSAMMSAMMAMSAAMAMASXMXAASAMXMMSSSSXASAXAAAMXMMMXMMMSSSMASASAMXSS 51 | MXMAMMSMMMMSMXMSMSAMAMXMASXXMXMAAMAMXMAMAMXXMASAAMSASXMAXAXASXMMSSMXMASMMMMSAMXMAMMMSAMSMXSAMXMAXMSMMASMSXMAMMMMMAMSMSMXXMMMSXMAMAMXMMMXMAMA 52 | XSMXMMMAXMMASAAAAMXSXMSMASASAMSMSSMXAXXMASMSXMASMXMASMXSXMMMMAMMXAMXSASAAMAMAMAMSSMAMAMXAXSMXSXMMAAAXXMAAMMMMSSXMXMXAAMXMXAAXAMASMMMAXSXMASM 53 | SMMSAASAMXMAMMMMSMXMXAMXAMMMXAMXMAMSMSASAXAXAAMXXSMAMMAMAMASXSASMSMXMASMMSASXMAAMAMASXMMMMMAMXASMSSXMMSSMXXAAAMAXSMMSMSAASMSXXXAXMAXMMMASMSX 54 | XASMMMSMSSMMMSASAMASXMMMMSSMXSMMMAMAAAXMMSSSMMXXAMMSMMAMAXXSAMMSAMXMMMMAXSASMSXXSAMXAASXMAAAMXSMAAAXSAMMXXMMMSSMMAAXAASXMMAAASMSSSSXMASMMMSM 55 | MMMMAXMXAAXSASMSASAXXMMAMXAXXMAXSSSMSMXSXAXAMXMMAMAXMSMSMSMMAMXMAMMMAAMAMMXXAXAXXXXAXMMAMMSASXAMMMSMMAXSAMXAAXAASXMMMMMXSMMMSMAAAAAMSAMAMAMA 56 | AAAMXMMMSSMMASAXXMMSSMSASMMMMMSMAMXMAMAMMMSMMASMMMSSXAMAAAAMSXXXAMASXMXAMXAMSMSMMSMSAXSAMMXAXXXMXXXXSMMMMMSMSMMMMAMXXASAXMAXXMMMMMMMXASMMAXS 57 | SSMSAAMAMXMASMMMMAXAAASMSMXXXAAMXMMSAMXSAXMASXSAXAAMXSSMMMSSMMSMSXXMAMSMMMXMMAXAXAAAMMSAXXMMMMMMMMAMXMAAAAAMAXXAXXMXAMMASASMXMAMSXMMSMMMMMMM 58 | XAASMMMSMMXSXMXASXMMSMMMMMSMMSSXSAASASMMMSSXMASXMMXSAXMXAMXAAXSAMXSMXMAMAMMXMASXMMSMXAXXMSXSAMAAAXAAASMSMSMSASXSSMAMAXSMMAAAAXAXXMMAMXAMASAX 59 | MMMMAMAMAMMMAMXMSAAAAAAMAASAMXAAMMMMMMAAAMMXXAMAXXAMXSAASASMMAMAMASASMMSASMSMMMMMXMXSMSMMXASAXSSMSSSMSMAMAXMXSAAAAAXSAMAMXMSXSSXSAMASXMSASAS 60 | MAAMXMASAMSSXMSXSXMMSSMSMSSSSMMMMASXSSSMSSSMMMSMMMXSAMAMXAXMAMSAMAMAAAASXSXMAAMXSAMAXAAASMMMSMXAAAMAXMMAMXXSAMXMAMMMMASXMMXMAAAAMMSASAMMASAA 61 | SXSXXMXMXMAMMAMXSAMXXAXXXMMAXMASXAAXMAMAXXAMAMAAAAAMASXAMXMSAMXXSXMMMMMSMSASMMSAMASXMMMXMASAXXSMAMSXMMSMSMAMXSAXXAXXSAMXAXAMMMMMMAMMSAMMMMXM 62 | AAMMXSSSSSSXMMMXXMMMSXMSXMMSMMMAAXMMMSMXMSXMASXSMSXSMMMAAAAMMSSXXAXMAMXMASAMXAMMSAMMSAXAXXMXSAMXXXXAMXAAAMAMMMMMMSSXMASMSMXSMXSXMASASMMXMAXX 63 | MAMMAMAAAAAMSSMMXSAAXMXXASAMASXMSAMXAAMXAXASAMAXAMMXAAMASXSXAAMXSXMXXSMMXMASMMMAXASASASMSXMMMMMMASMSMAMSMSASAAAMAXMAMXMAMMMMMAMAMMMMSXSAMMSS 64 | XSAMXSMMMMXMAAAMAXMXMAMSMMAMMXAAXXMMSMSXMSXMASMMXSXSMSSMXAMXMASMMMXSAAAMASXMAAMMSMMMMXMAAASAMASAASAMAMMMASXSMSMSMSSSMXMXMAAXMAXAMXAXXXMASAAM 65 | MMXMAXXXXMAMMMMMMSMSXXAAXMXMASMMMXMAMASAMAXXXAXMXMAMSMAXMAMSXSXXAAAXMXMSASASMMSXSXSXMXMMSMSASASMSMMMAXXMAMXSAMASXAAMMMMAMXSSMMSASMMSMMSAMMSM 66 | XSAXSSMXASXSSSXSXAXAAASMXSAMMMXASXMXSMSASMMMSMAMAMAMASAMXAMXXMASMMSSSMXXAXAMAXSAMAMAMXSAMXMMMMSXXAXSMMMMMSMMAMAMMXMMXASAXSAXAAXAMXXAAAXAXMMM 67 | MMMMMAAMXMXAAAASXMMMSMMAXMAXXXMMMAXAMXSXMAAAAMASMMASAMXMSXMAMSASAAAXMASMMMSMMXMAMXMAMAMMSAMSSXMAMSMSAAXAAAAMXMXXMXAMXXMASMAMMMMSMMMSMMMSMMAS 68 | AASASMMMSMMMMMSMAXSAMAMMMXXMSMSASAMXXXMASMMSMMASAXXMXSXMAMXXXMASMMXSMMMAAAXAXXSSMMMAMXSASXSAXMXMXMAXXMSMSSSMXMMAMSMMXMASMMMMAXMAASAAASXMASAS 69 | SMSASXAXAASXXSAXXMMASXMSSSMMSAAAXSAMMMXAMXMMMMASMMSAXAMXMMSSSMMMXSSMMAXXMMXAMMMAASXSMAMMSMMMSMAMSMSMSMXAXAMXMMXSAAAMSAMXXAXSMSSSMMMMXXASAMXS 70 | XAMAMMXMXAMXMXAMMMSXMASAAAAAMXMSMMSMASXMSXAAAMXMXAMAMXSXXXAAAXSAMXAASXSSSXSASXSMMMAMMMMXXAAXAMAMMAMAAAMSMMMSMMAMSSSMXAXAMMXXAAXMXXXSAMXMAMAS 71 | MAMSMMXSMSSMSMXMAXMMSMMMSMMSMSMXASAMMSAMAAMXSSMSMSXXAXMASMMXMMAXSXMMMXXAAASAAASXSMMMAXXMMSSSSSSSMAMSMXMXASASAMXMAXXMSMMMMSAMMMSAMXAAXAAMXMXM 72 | SSMMXSAXXXAASXSXSAXMAXMAXMMAMAMXMSASASAMMXMAMAAXAMMMSSMASAMSSXMASMSSXSMMMMMMMMMAMSXSMMSAMAMMXAXXXAMAMXXSMMASAMSMSMMMMXAXMXMSXXXMAMXAMSXMASAM 73 | SAAAAMXSMMMMMAMAXMMXMSMXSAMASASMXXAMXSXMXAMMSMMMAMAAAXMAXAXAAAXAXXMSAMAAMSASXSMSMXMXMAMSMASXMSMSSSSMMXMAAMXMAMXMASAAMMSSMAMMAMXMXAXSMMXMASAS 74 | XSMMSSMMXMAMMMMSMXSAMXMMMXMASAXXSMAMAXMASMMASAMXXSSMMMMSSMMSSXMASMMMMMSMMSAXAXMASAMXMASXSMMMMMAXSXAAAXSXMMMXAMXMASMXSAAAXASAAMAMMSMMASXSXSMM 75 | MMMSAXAAAXAMAAXXAASAMMMXAMMMMMMAMXAMXSSXMAMASAMMAMAXXSXMAMAXMASAMXAAXXXMMMSMAMSASMSXMMSAMXAAAMXMMSSMMXMMSAAMSSSMAXMAMXMSAMXXSSXSAMASAMAXAMXS 76 | AAXMASMMXSMSXSXMMMXAMXAMSSSMAXMAMSXMXMMMSMMAMAMXAMXMMAMMAMSXMXAMXSXMXXXXAAXMXMMASAAMMMSMSSXSSSXSAAXASASASMSMAAAMSMMXSMSMASMMXMXMASAMMSMMSMMX 77 | MAMMXMAAXSAMAMAASXSMMMXSMAAMMMMAXSXSAAAAAAMSXSMSSMSAXMMSSSXASAMXXMAMSMMMMSMMASMMMMMSAAXAXXAMAMXMMSMXXAMAMAMXMSMMAASASMAXAXXMASXSMMMSMAMAXAXX 78 | AAXAAXMASMAMAMXMAMXAAMXSMSMMMSXMAXMASMMSMSMXAAMSAAMSMXMAMXXXMAMMMSXMAAMSMMMSAXSMXSASMSMXMMXMAMXSAXXAMSMSMSAMXAAMSSMAMMSSXMAMXSAMSMXAMASXMMMS 79 | SASMMSMSMXAMSSXMXASXXMASMXAMXSAMXSXMXXXAXMAMXMMMMMMMMSMMSXSSSSMAMAXSSSMSAAMMSMAXXMASAXMASMMSXMAMASMMMXAXMAMMMSMMXXMAMAXXMXSSXMXMAMMMSXSASMAX 80 | MXSXSAMXMSSSMMMSMMMSAMASXMASAMXMAMAMMSMSSMAMSSXSASXMAAMXSAMMAXSXMAXAAMASMMMAMMXMMMMMMASAXAXAMMAMXMASAMSMSMMSAMASMMXSMMSAMAMMMSASASAMXAMAAMXS 81 | MAMXMASXAAMXAAAAAAAXMMXSXXMXMMSMMSAMMMAAXXXMASASASAMSMSAMAMMXMMMASMMSMAMAMMASAMXAAXAMMMSMSMMXSXSXSAMASAAXAAMAXAMAXAXAASAMMXAASXMASXXXXMXMAMX 82 | MAMASMMMMMSMSMSSSMSMSAMMMXSAAMAAMSXSAMMMSAMXMXMMAMMMXAMXSSMXXAXAAMXXAMSSSMMAMXSXSMSASMAXMXAXAMAAAMASMMMMMMMXAMSSSMMSMMSAMXMMXXMSMSASXSMMXSMM 83 | SXSXSAAXMASAMMMMXAAAXMAMSASXSSMSMXXSASXSMMMSMMMMXMXAMAMMAMMMSSSMSSMSMSMAXSMXSXSAMAXXAMXMASMMMSAMXMXMASXSMXSMXSXAXXMAMASMMAASMMAAAMMMAASAAXAX 84 | AMMXMXMMMASMSMSSMSMSMMMXMAMXXAMAMXXMAMXAAAAAXAAAAMMMMAMXAXAXSXAXAXXAXAMMMXMMAAMXMAMXMASMAMAAAXMXXSASMMAAMASXSAMXMMSAXXMAXMMAASXMMMAMSMMMMSMM 85 | XASMSMXAMXSXMAAXMAAAASXMMAMSSMMAMMMMAMMSSMSSXSXSXSASAAMSXXXSMSMMMSSMSXSASAMAMXMMMXSXSXMMSSSMSSMSMXASXMXMMASXSMSAMXSXSSSSMMSSMMASMMXMXAXXAAXM 86 | MSXMAMSMSASAMMMSSMSMXMAAMMXMAMSAXAASAMAAXXMMAXAMASASXSXMSAMXMAXAMXMXMASMSAMAMAMSMMAMMSMAMXXAXMAAAMSMMMSXMASMXASXSAMXMAAAAAAAXSAMXMSAMXMMSSSX 87 | SMMSAMMAMASAMXXXMAXXXSMMMSMMSMSASMMSAXMASAXXAMAMMMAMMMAAXXMAMMMAMAMMSMXXSAMXSASASAMAAAMAMMXMMMSMMXAAAAAXAXXAMXMAMMSXMMMMMMSSMMMXSAMMSMXXXAMX 88 | AMASMMMXMXSAMXXAMSSSMSAMASAAAAXAXXXMXMXMAXMMXMAMXMAMAMMMMASXSSSSXMSAMXMXSXMASXSMSSXMSSSXSXAXAXXASXSSMSSXXAMSASMXMMAMXAMASXAMXMAAMASMAMMSMSMS 89 | MMMMAXSMXMSXMSXMXAAMASMMASMMMSMSMSMSMMMMSXXAMSSSMSSSMXAAMAMMXAAAASMMMASXMASXMASXMASMXAXMMXSSMXMAMAAAAXMMSXMAAMXAXMAXMASAXMMMAMMMSAMMAMMMAAAX 90 | XSXSMMAASMMXXMASMMSMAMXMMSXSMXAAAAXAMAAXMASMXAMAAMAAXSXMMAXAMMMMMMASMMSASASAMAMAMMMMMXMXXAMAMSMAMMMMXMAAMASMSXMSXMXSAXMXSAASASAMMXSSMSSMSMXM 91 | MXXSXMSSMAASMSAMAAAMXSAMAXAXAMSMSMSMXSXSXAMXMASMMMMMMMASMMXSAAMSMMAMAASXMAXMMMSMMMAXXMAMMMSAMASMMXXXAXMMSAMAMMAXMSAMXMAXXXMMXMAXSAXMAXAAXAMX 92 | ASMSAXMAXXMSAMXXMMMMXMASXMMMXMAAAAAXMMAXMMSSSMSAXXAXAMAMAAAMMXMAMMMSMMMMMSMAAAAAAXXMXMSAAASXSASMSSSSSSSMMMMAMMMSAMASAMSMSMSMMSSXMASMSMMMSAMX 93 | XMASAMXAMMXMMMMSSMSXMSMMAXSSSSMSMSMSASAMAXAAAASAMSSSMMSSMMMSMMSXXAMSXAXMAMMMMXMXMMSXSAMXSMMAMASAXAAAAXXXAASMSAXAMSAMMXAAAAMMAXMASAAAAAAAMAMX 94 | XMXMMXMASXMXAMXMAAXSAASMXMXXAAAAAXAMAMAMXSMSMMMAMAAAXAXAMXAAAMAXMAMSMSAMXSASXMMSAXAAMAMMMAMAMMMMMMMMMMSMSXSAMMSMMMASXSMSMXMMXSSXMMSMSMMXSMXS 95 | XXMASAXAXAMSAMXSMMMASMXXAXXMMMMMSMXMAXAMXMAMXXSMMMSMMXSASMMSSMASMSMSAXXSASMAAAASMMMXMXMASXMMMAAAAXSAXAXMMAMXSXMXAMMMAAAMAMSSMMXMAMMAMMMXAXAM 96 | MMSXMAMXSAMXAMAXXXXMXSXMMAMSXXXXXMMSMSXSAMSMXMAMXMMXSMMAMXAAXMMMAAAMSMSMAXXSMMMSXAAXXXSXSMMASMSSMSMSMMSAMXMMSAMSMSSMSMMMAMAAXSASAMXAAAMSMMXS 97 | SASAAXAXMAMXXMSSMMSXAXMASAAAMASAAXAAAAXMXMXAMXMSAXSAAAMSMMMSSSMMMMMMMXMMAMXXMASXMXSSMASMMXSASXAXMSAMXMMXMAAASAMXAAXAXAXXAMXMMSASASMSMMXAASMS 98 | MASMMXSXSSMMXXAAAAMMMSAXSAXXSASMMMSXSSMAAXMSMAMSASMAMXAXAXXXAXXAMXMMMAMAMMSASXSAXXAAXAMAMAMASMMMAMMMMXASXMMXSAMMMMSMSMMSSMXXMMAMASXMXXMSSMAS 99 | MMMMMXAAAXMASMMSMMSAMMXMMXMXMMMXMAMMMAMSMMAMMXMMXMMAMMSSMMMMMMMMASAMSASMMASAMAMMMSSMMSXXMMSASAMSSSMAMMXXAXMAMAXXAAAAAXAXAAASXMMMXMASXMXXXMAM 100 | MAAAMXMMMSAMXAXAXAMASAXSAMXXMMSSMXSAXAMASMMSMMXMMAMASXAAAAMSXSASMMAXSAXAMXSAMMMMXXAAAAASMXMASAMAAMXAXMASMMMMSAMXASMSAMXXXMMSAMXXASXMXMAMMMMS 101 | SMSSSSXSXMMXXSMAMXSXMASMSMMMSAAAAXXMSASASXAAAMXSMASMXMSSMMXSASASXSMMSMSSMASAXSAMXSMMMMSAAAMMMXMMSMSMMSAAASAMXAMXAMMMXSMSXMAXXASMXXXMAXAXMAMS 102 | AXMAXMAMXSSSMXMXMMMMMXMAAXMASMSMMMAMSXMASMSSSMASMMMMMAAMASXMAMAMAAMAXMAAMXSAMSAMXAAAAXMMAMXSASXXXAXMAMMMAMXSMAMAXMAMAAAAAMSSMMAASMASXSXMXAXX 103 | XASXSMSMAMAAAMMAAAMXMAMSMSMMXXXAXXXMMAMAMAMAAMXSAMAAMXMSAMXMMMAXSMMSMMSSMAMAMSXMXXXMXSSXSXXMAMAMMSMMMSSMMXMAMXXSSMSMAMSMXMMAMXMASMXXAAMSSSSM 104 | MXMASAMMASXMMSSSXMSMMAMMASMMMSSSMMMMSAMXXMAMXMASAMXSAMMXMASMASXMMXXAXMMMMXSSMMMMXMMSXMXAMXXMAMXMAMAMAAAXSAMXXMMMAAMXSAMXAMXAMXXXMXMMMMMXAXMA 105 | AASXMAMSMMAMXXAAMSAMMSSMAMAAAMAMAMSASASMSMSAAMASXMAXMAMAMMMXAMASXSSMMSAXXMAMXMASMMAMAMMXMAMXSAAMXSAMMSSMSASXAAASMMMAXAMSSSXXSSMMMAXAXXSMMMAS 106 | SASAMMMASMAMAMMMMSASXAAXSSSMXSASAMMASASAAAASXMASAMASXSSMXXAMSXMMAAMAAMMMMMSMMMSMSMASAMMSMASMMSASASXSXMAASAMXASXSAAMMXAMSXSAAMMMASASMSMXAAAMA 107 | MAMMMXXAXSAMXMASXMAMMSMMMXAAAXXMAMMMMAMXMXMMMMASXSMSXMAMAMSXXAMMSMMMMXSAMAAAASAAASMSXXMASASAMAXMAMXMAMMMMAMSXMASXMXSSSMSAMMSMASMSASASMSSXSMM 108 | MSMSASMMMSMMAMXXXMAMXMASXAMMMSMSXMSAMXMXSXAASMMSAAMMASAMXAMASXMAMAMXMASASXSMMMMSMMXMAMSAMMSAMMAMAMASAMXASAXSAMMMMSAMXXAMSMAAXXSAMMMASXAAMMAX 109 | XMXMASXXAXASMSXMASASXMASMXSAXAAMSASASMSAMSSMMAXMXMAMXMXSMXMAMAMXSAMXMASXMXXAMXXXXSMSAXMASAXAMXXSSSMSASMMSXMMXMXAAMMSAMXMXMSMSMSMSXMASMXSASMM 110 | XSASXXMMSMXAMXMAMSXSAMAXMAMXMMSMMXSXMAMXMAMASMMSMSXMSAMXAXMAXXMASAMXMASMSAMXMMSAXMASMMXXMASXMSMMAAXXXMAAMAAXAXSMSXXXMAMXMXMXSASASXMAMXMAXXXX 111 | MSAXXAMXMSAAAXASAMXSXMXSMMSMSMMXMXMXMMMSMASMMMAAAMAMXAXSSSSMSMMXSAMSMMSAMAMXSAMXMMMMASXMMMAMXXAMMMSSMMSASXMXMXAMAMSMSSSMAAMXMAMAMXMASMXMASMX 112 | AMXMXSMAXAMAMXXMASAXAXMAXAAXAMMAMAMAMASAMAMAAXSMSSXMSSMMAAXAAXMAMAMXAAMMMASMMXSAMXAMAMAAMASMMSSMXAAXAMXXMASAXXAMXMAAAAAASAXAMAMAMXSAMMAMAAAX 113 | SSMSAMASMMXSMSMSAAMSXSXAMXXMMXSASASASXSASMSSMXMXMAAXAMASMMMSMMMAXAMSMMSMMMXAAAMAMSASXSXMMAMAAMAXMASXSAMXMAMMSXMMSMMMMXMAXASMSMSSMMMAXMAMMMXM 114 | XXAMASMMAXMMAAAMMSMAAMMSSSXSXAXASXSXSMSAMXMXMAMAMXAMXSAMAXXXMAXSSXXAAAAAAMSMMXSAXSAMXAXAMXSMMMMXMAXMXMXAMXSAMASAMXSMMXMASMMAAMAMAXSMMSSSSSSM 115 | XMXMXMAXXMAMMMMMAAAMAMAAAXAMMMSMMMSMSAMXMMSMSASXSAMXXMAMXMXMASXAAMSSSSSSMMAMAMMMMMAMMASMSASMAMXMMAMXAMSASAMASXMASAMAMXMAXMXXMMAMSMSXAXAAXAAA 116 | SMMSMAASMMMSXSMMXASMMAMSMMSMAAAAMXSASMMASXAAMMXAMXMMMSSMMAASAXMMMMXAAAMAMSMMMSAMMSMMXAAXXAXXAMASXSXSMMAXMMSMMXSMMXXAMXMMSSXMXMXMXAMMSMMMMSMM 117 | SAAAAMMSAAASMXXASMMXXAXAMXASMSSSMAMXMASAXMXSSSSMSASAMAMAXSXSAMMSAMMMMMMMMAAAAXAMAAXXMMSSMAMSSSMSAMMAMAMXSXMMXAAMAXXSSMSAAAAXAMXMMAMAMAAMMXAX 118 | SMMSXAMSMMMSASMMSAASXXXAAXAXMAXAMMSMSMMXXSAAXXAASASMMASMMMXMXMASASXAXAAAMXSMSMSMSSSMSAAAXXMSAAAMXMAMSAMMMASXMMSMSSMMAMMMSMASASAAMAMASMMSAMXM 119 | XAAMMXMMAXAXMAAASMMMASMAMSMXASXMMAAAAXXMAMMXMMMMMAMXSXXXASXXAMAMAMMMSSSXSAMAXAAMAAMAMMXSMSSXSMMSAMMMXASXMAMXXMAMAAAXAMAXAMASASXSMAXXXAAMMSAM 120 | SMSXSAASMMSMMSMMXAXMAMAMXAMMMMAXMSSSMMSAAXSASAAXMXMASMMSMMMXXMSSXSAXXAAAMAMAMSMMMSMSMSXXAMXAXXXSASMSXMAMMAMMMMMSSSMSSSXSMMMSASAMXSMSXSMSASAS 121 | XAAAXSXMMAXAAXXMXSMMXSXMSAXAASXMMXAAAAAXXMSASAXSXMAMMXAAAASMAXAAASMMXMMMMMMXMAXXXAAAAXAMSMMAMXMSAMAAMSASXSMSAAXAAAAAXXXMXMMMMMASAMAMAAAMAXAM 122 | MMMSMMMMMAMMXMASAAASAMAMXMSSMMSMMMMMMMSSSMMMMXMSAAXXSMSMMMXAXAMMMMASMXAXASMSMMSSSMSMSMMMAXSAMMAMXMXMMMAMAAASXXMMXMMMSMMSMMXAXSAMXMAMSMMMSMAM 123 | XXAMASAMMMSMXSAMASXSASAMAMXMAMXMXMASXAXAAMXASAMMAMMMXAAXSSMSSMXAASAMAXMSXSAASAAAAXAXMASMXMSASAXAASASMMXMMMMMMSMSXMAXAAMAAMSSMMASXMXMXASAXSXM 124 | XMASXMSXAAAXXMMXMXMSAMXSASMSXMXSAMXMASMSMMSASASXSMMAMMMSAASAAMMMMMMSMSAMXMXMMMSSMMMXSMMXMXXAMXXSXMAMMASMSSMMAAAXASMXSMMSSMAMXSSMMSSXMAMXMAMX 125 | ASAMMMAMMXSXMMSAMAMMSMAMXSAMAMASAXAXAXAMXMXXMAMXAAXMMMMMXMMSSMMSAMXAAMMXSMXXXAAAAAXMSAMMSAMSMSXMXMAMMASMAMAMSSSMMMSXXAAAXMASXMAXMASXMSAMXXAS 126 | MMMXAAMMSAXAAASMXXSAMMMSMXASAMASAMSMSSSMAMSSMAMSSMMSMAAAMXMAXAASASMMSMMXMASXMMSSMMMAXASAMXXAAXMAASAMMMXMAMXMAAAASASMSMMSXXMXAMMXMASXMAAXMASA 127 | MAAMXMXAMASXMMSXSXMMSXSAMXAMMMAMAMMAAAASXSAAXAMXAAAAMSMXSAMSSMMSXMXXMAXAMAMAAMAMAASMSMMXSMSMSMMSMSASASMSXSAMXMMMMASASMAMMSSSMMMAMXXAMMMMMMXM 128 | MSSSMASAMXMAXXXAAXAASMSASMSMXMASMMMMMSMMMMXSMSSSMMXSMXAXSAMXAXAXMAXAMMSSSSSSMMASMMMAAXAAXMAMXXMMXSASASAAMSXSXSMXMMMXXMAXXXAASMSSSXSAMASMSAMX 129 | XAAAXASAMMSMMXMAMMMXSASAMAMASXMSMXXXXMASXAAXAXXAAAAXMMSMSMMSMMSSSSMSXAXXAMMAAMASAMXMSMMSXSASXSXXAMXMAMMMXSAMAXMASASXMMMSMMMMMXAXAAXAMXXAAXXM 130 | MMSMMAXAMXAAXXMAMMMMMMMMMXMAXAMMMMSAMXMSAMXMAMSSMMMSAAMASAAAAAXMAAAMMMMMSMSMMMMSAMMMXAXMASMSAMMMMMMMXMXMXMAMXMSXSAXXAAAAMMMAXMMMMMMSSSMSMSSS 131 | XAAXAMSMMSSSMMMASAAAAXAXAXMSSSMAAXAMXSXSXSXMAMMAMMMSMMSAMMSSMMXMMMMMAXXAXMSAMXASAMXAXAMXXMAMXMAAXAAMMSSMMSSMAMMMMMMSSMSXMASXSASMSAXMAXAMAAAA 132 | MSSSSMAAXAAAMASAMXXXMSMMSAMXAAXMMSMMMSAMASXSAASAMAMMMAMASAAAASXMSMXSSXMXSASMMMMSSXMASXMSSSMSASMSSSSSXMAAMAASASAXXSAAAMXAMXSMSAMASMXMMMXMMMSM 133 | MAAMMSMSMMMMMXMMSSMSAAAXMMAMMMSSXAAMASAMAMMMSXXXSASMMASXMMSSSMSAAXAMMAMAMMMSXAXMMXAAAXAAAAASXXMXAMXMASXMMXXSSSMSXMMSSMSSMAMASAMXMAMMXSXMXAAA 134 | MSXSAMXAMSASMMMMAMAAXMAMXMAMXAAMXSMMASAMXSAMMXSXSASAMXMAMAAMAAMSMMXMMAMMSMAASXXXSSSXMMMMXMMMMSMMASXSAMASXXXXXXMSMSAXXAAXMAMXSAMXXMASAMMMSSSS 135 | XXAMXXSAXSASAAAMASXMAXSMMXAMMMSSMXAMASAMXMXAAASMMAMXMASAMMXSMMMXXAXMXMSMAMSMXSXAMXAAAMAXSAMXAAAMAMAMXSXMSMMMMMMXAMMSMMMXXAXAMAMMXSXMASAXMAAX 136 | XMSMXXMMMMMMMSXSMSAXSXMASXSSSXAXXMAMXSXMXXAMMMXAMXMSSXSMXSAAAAAAMSMSAMAXXXXMAAMMMASMXXASMXMASXSMMMAMMMMMAMAAAAAMSMAAXAAXMXMSMSMSAXASASXSMMMM 137 | MMAMXMAAXAAXXXAAAXXMMAMAMXAAXMMSSMMSAMASMSMXAXMXMAMASMXMAMMXMMXMSAAXASASMMAMXMXAAXMXXMXMMASAMAAAXSAMXAASASMSSSMMXMSSSMSSXSAMAAAMASMMMXASMAMA 138 | XMAXASXMSSXSAMMMSMAAMXMAMMMMMSAAAAAMAMMXAAASMSAASXMASXMMASMSXSAMXASXXMASASAMXSSMSSMMXMSASXSAMMMMMAAMSMMSASAXMAXMAMMMMMAAASAMAMXMAMMAMMMMAAXS 139 | XSSSXXSAAAXMAMXAAXSMAASASAXAAMMSSMMSAMXMMMXMAMXXMAMASASAMXAAASXMSAMXMMXMAMASAMXXAAASAXSAMASXMXMSXMAMAAMMAMMMMAASASAAAMMSMMAMXXXXXASAMXMASMSA 140 | MAASMSAMXSXASAMSSMXMSMSASXSMSSXMAXXSMSXXSMAMXMMMAAMMSMMMAMMMMMSMMASXMASXSSSMASAXSSMMXXMMMMMXMASAXXXSSSMMMMXMMSMSASXSXSAMMSXMAXSAMXSXSAXMASXX 141 | --------------------------------------------------------------------------------