first commit
This commit is contained in:
		
						commit
						33b031c8da
					
				
							
								
								
									
										14
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| **/*.input | ||||
| 
 | ||||
| # Generated by Cargo | ||||
| # will have compiled files and executables | ||||
| */debug/ | ||||
| */target/ | ||||
| 
 | ||||
| # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||||
| # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||||
| */Cargo.lock | ||||
| 
 | ||||
| # These are backup files generated by rustfmt | ||||
| **/*.rs.bk | ||||
| 
 | ||||
							
								
								
									
										6
									
								
								day01/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								day01/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| [package] | ||||
| name = "day01" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
							
								
								
									
										54
									
								
								day01/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								day01/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| use std::collections::HashMap; | ||||
| use std::fs; | ||||
| use std::env; | ||||
| use std::iter; | ||||
| 
 | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 01!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
| 
 | ||||
|     let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); | ||||
|     let mut first: Vec<i32> = Vec::new(); | ||||
|     let mut second: Vec<i32> = Vec::new(); | ||||
| 
 | ||||
|     let mut counts: HashMap<i32, i32> = HashMap::new(); | ||||
| 
 | ||||
|     for line in contents.lines() { | ||||
|         let numbers: Vec<_> = line.split_whitespace().collect(); | ||||
|         let (first_str, second_str) = (numbers[0], numbers[1]); | ||||
|         let (first_num, second_num) = (first_str.parse().unwrap(), second_str.parse().unwrap()); | ||||
|         
 | ||||
|         first.push(first_num); | ||||
|         second.push(second_num); | ||||
| 
 | ||||
|         let count = counts.entry(second_num).or_insert(0); | ||||
|         *count = *count + 1; | ||||
|     } | ||||
| 
 | ||||
|     first.sort(); | ||||
|     second.sort(); | ||||
| 
 | ||||
|     let mut sum:i32 = 0; | ||||
|     for (first_num, second_num) in iter::zip(first.iter(), second.iter()) { | ||||
|         let difference = (first_num - second_num).abs(); | ||||
| 
 | ||||
|         sum = sum + difference; | ||||
|     } | ||||
| 
 | ||||
|     println!("the sum of the differences is {sum}"); | ||||
| 
 | ||||
|     let mut similarity: i32 = 0; | ||||
|     for num in first { | ||||
|         similarity += num * counts.get(&num).unwrap_or(&0); | ||||
|     } | ||||
| 
 | ||||
|     println!("similarity score is {similarity}"); | ||||
| } | ||||
							
								
								
									
										6
									
								
								day02/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								day02/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| [package] | ||||
| name = "day02" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
							
								
								
									
										71
									
								
								day02/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								day02/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| use std::fs; | ||||
| use std::env; | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 02!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
|     let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); | ||||
| 
 | ||||
|     let mut safe_reports: i32 = 0; | ||||
|     let mut safe_reports_with_dampener: i32 = 0; | ||||
| 
 | ||||
|     for line in contents.lines() { | ||||
|         let report: Vec<i32> = line.split_whitespace().map(|s| s.parse().unwrap()).collect(); | ||||
| 
 | ||||
|         let safe = is_safe(&report); | ||||
| 
 | ||||
|         if safe { | ||||
|             safe_reports += 1; | ||||
|         } | ||||
| 
 | ||||
|         for i in 0..report.len() { | ||||
|             let skipped = [ &report[..i], &report[(i+1)..] ].concat(); | ||||
|             
 | ||||
|             if is_safe(&skipped) || safe { | ||||
|                 safe_reports_with_dampener += 1; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     println!("there were {safe_reports} safe reports"); | ||||
|     println!("there were {safe_reports_with_dampener} safe reports with the dampener turned on"); | ||||
| } | ||||
| 
 | ||||
| fn is_safe(report: &[i32]) -> bool { | ||||
|     let mut increasing = false; | ||||
|     let mut last_value = 0; | ||||
| 
 | ||||
|     for (i, &value) in report.iter().enumerate() { | ||||
|         if i == 0 { | ||||
|             last_value = value; | ||||
|             continue; | ||||
|         } | ||||
|         if i == 1 { | ||||
|             increasing = value > last_value; | ||||
|         } else { | ||||
|             if increasing && (value < last_value) { | ||||
|                 return false; | ||||
|             } | ||||
|             if !increasing && (value > last_value) { | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let difference = (value - last_value).abs(); | ||||
|         if difference < 1 || difference > 3 { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         last_value = value; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
							
								
								
									
										7
									
								
								day03/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								day03/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| [package] | ||||
| name = "day03" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
| regex = "1.11.1" | ||||
							
								
								
									
										70
									
								
								day03/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								day03/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| use std::fs; | ||||
| use std::env; | ||||
| use regex::Regex; | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 03!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
|     let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); | ||||
| 
 | ||||
|     let mul_instructions = Regex::new(r"mul\(([0-9]{1,3}),([0-9]{1,3})\)").unwrap(); | ||||
|     let mut sum = 0; | ||||
|     for (_, [a, b]) in mul_instructions.captures_iter(&contents).map(|n| n.extract()) { | ||||
|         let (first, second): (i32, i32) = (a.parse().unwrap(), b.parse().unwrap()); | ||||
|         sum = sum + first*second; | ||||
|     } | ||||
| 
 | ||||
|     println!("the sum is {sum}"); | ||||
| 
 | ||||
|     let initial_dont = Regex::new(r"^don't()").unwrap(); | ||||
| 
 | ||||
|     let donts = contents.match_indices("don't()"); | ||||
|     let dos = contents.match_indices("do()"); | ||||
| 
 | ||||
|     let donts_indices = donts.map(|(i, _sep)| i); | ||||
|     let dos_indices = dos.map(|(i, _sep)| i); | ||||
|     let mut dos_and_donts_indices: Vec<usize> = 
 | ||||
|         donts_indices | ||||
|         .chain(dos_indices) | ||||
|         .chain([contents.len()]) // just to make sure the last segment gets caught!
 | ||||
|         .collect(); | ||||
| 
 | ||||
|     dos_and_donts_indices.sort(); | ||||
| 
 | ||||
|     let mut sum = 0; | ||||
|     let mut last_index = 0; | ||||
|     for current_index in dos_and_donts_indices { | ||||
|         let current_slice = &contents[last_index..current_index]; | ||||
|         last_index = current_index; | ||||
| 
 | ||||
|         if initial_dont.is_match(current_slice) { | ||||
|             continue; | ||||
|         } | ||||
|         
 | ||||
|         for (_, [a, b]) in mul_instructions.captures_iter(current_slice).map(|n| n.extract()) { | ||||
|             let (first, second): (i32, i32) = (a.parse().unwrap(), b.parse().unwrap()); | ||||
|             sum = sum + first * second; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     println!("the sum for part b is {sum}"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										6
									
								
								day04/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								day04/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| [package] | ||||
| name = "day04" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
							
								
								
									
										82
									
								
								day04/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								day04/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| use std::collections::HashMap; | ||||
| use std::fs; | ||||
| use std::env; | ||||
| use crate::Dir::{North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest}; | ||||
| 
 | ||||
| // nodes are (coord, direction) pairs.
 | ||||
| // neighbors are step1+turnleft, step2+turnleft, step3+turnleft, step1+turnright, etc
 | ||||
| #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||||
| enum Dir { North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest } | ||||
| 
 | ||||
| fn step(start: &Coord, d: Dir, steps: i32) -> Coord { | ||||
|     match d { | ||||
|         North => (start.0, start.1 - steps), | ||||
|         South => (start.0, start.1 + steps), | ||||
|         East => (start.0 + steps, start.1), | ||||
|         West => (start.0 - steps, start.1), | ||||
|         NorthEast => (start.0 + steps, start.1 - steps), | ||||
|         NorthWest => (start.0 - steps, start.1 - steps), | ||||
|         SouthEast => (start.0 + steps, start.1 + steps), | ||||
|         SouthWest => (start.0 - steps, start.1 + steps) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| type Coord = (i32, i32); | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 04!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
| 
 | ||||
|     let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); | ||||
|     let mut grid: HashMap<Coord, char> = HashMap::new(); | ||||
| 
 | ||||
|     let mut x; | ||||
|     // build our grid!
 | ||||
|     let mut y = 0; | ||||
|     for line in contents.lines() { | ||||
|         x = 0; | ||||
|         for c in line.chars() { | ||||
|             grid.insert((x,y), c); | ||||
|             x += 1; | ||||
|         } | ||||
|         y += 1; | ||||
|     } | ||||
| 
 | ||||
|     let mut sum = 0; | ||||
|     let mut xsum = 0; | ||||
| 
 | ||||
|     let directions = vec![North, South, East, West, NorthEast, NorthWest, SouthEast, SouthWest]; | ||||
|     for (position, _letter) in &grid { | ||||
|         for dir in &directions { | ||||
|             if check(position, &grid, *dir) { sum += 1 } | ||||
|         } | ||||
|         if xcheck(position, &grid) { xsum += 1 } | ||||
|     } | ||||
| 
 | ||||
|     println!("there are {sum} xmases"); | ||||
|     println!("there are {xsum} x-mases"); | ||||
| } | ||||
| 
 | ||||
| fn check(position: &Coord, grid: &HashMap<Coord, char>, direction: Dir) -> bool { | ||||
|     if grid.get(&step(position, direction, 0)) != Some(&'X') { return false; } | ||||
|     if grid.get(&step(position, direction, 1)) != Some(&'M') { return false; } | ||||
|     if grid.get(&step(position, direction, 2)) != Some(&'A') { return false; } | ||||
|     if grid.get(&step(position, direction, 3)) != Some(&'S') { return false; } | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| fn xcheck(position: &Coord, grid: &HashMap<Coord, char>) -> bool { | ||||
|     if grid.get(position) != Some(&'A') { return false; } | ||||
|     let a = (grid.get(&step(position, NorthEast, 1)), grid.get(&step(position, SouthWest, 1))); | ||||
|     let b = (grid.get(&step(position, SouthEast, 1)), grid.get(&step(position, NorthWest, 1))); | ||||
|     if a != (Some(&'M'), Some(&'S')) && a != (Some(&'S'), Some(&'M')) { return false; } | ||||
|     if b != (Some(&'M'), Some(&'S')) && b != (Some(&'S'), Some(&'M')) { return false; } | ||||
|     return true; | ||||
| } | ||||
							
								
								
									
										8
									
								
								day05/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								day05/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| [package] | ||||
| name = "day05" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
| regex = "1.11.1" | ||||
| topological-sort = "0.2.2" | ||||
							
								
								
									
										70
									
								
								day05/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								day05/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| use std::iter; | ||||
| use std::fs; | ||||
| use std::env; | ||||
| use topological_sort::TopologicalSort; | ||||
| 
 | ||||
| #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] | ||||
| struct Rule ( i32, i32 ); | ||||
| 
 | ||||
| fn main() { | ||||
|     println!("Hello, AoC day 05!"); | ||||
| 
 | ||||
|     let args: Vec<String> = env::args().collect(); | ||||
|     if args.len() != 2 { | ||||
|         println!("wrong number of arguments!"); | ||||
|         std::process::exit(1); | ||||
|     } | ||||
| 
 | ||||
|     let file_path = &args[1]; | ||||
| 
 | ||||
|     let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); | ||||
|     let (first, second) = contents.split_once("\n\n").unwrap(); | ||||
| 
 | ||||
|     let rules: Vec<Rule> = first | ||||
|         .lines() | ||||
|         .map(|line| { | ||||
|             let (before, after) = line.split_once("|").unwrap(); | ||||
|             Rule(before.parse().unwrap(), after.parse().unwrap()) | ||||
|         }) | ||||
|         .collect(); | ||||
|     let updates = second.lines(); | ||||
| 
 | ||||
|     let mut good_sum: i32 = 0; | ||||
|     let mut bad_sum: i32 = 0; | ||||
|     for update in updates { | ||||
|         let pages: Vec<i32> = update | ||||
|             .split(",") | ||||
|             .map(|page| page.parse::<i32>().unwrap()) | ||||
|             .collect(); | ||||
| 
 | ||||
|         let mut my_sort: TopologicalSort::<i32> = TopologicalSort::new(); | ||||
| 
 | ||||
|         rules | ||||
|             .iter() | ||||
|             .filter(|&Rule(a, b)| pages.contains(a) && pages.contains(b)) | ||||
|             .for_each(|&Rule(a, b)| my_sort.add_dependency(a, b)); | ||||
| 
 | ||||
|         let true_pages: Vec<i32> = iter::from_fn(|| my_sort.pop()) | ||||
|             .filter(|p| pages.contains(p)) | ||||
|             .collect(); | ||||
| 
 | ||||
|         let middle: i32 = *halfway(&true_pages).expect("error finding the halfway point"); | ||||
| 
 | ||||
|         if iter::zip(pages.iter(), true_pages.iter()).all(|(a, b)| a==b) { | ||||
|             // it's good!
 | ||||
|             good_sum += middle; | ||||
|         } else { | ||||
|             // it's bad!
 | ||||
|             bad_sum += middle; | ||||
|         } | ||||
|        
 | ||||
|     } | ||||
| 
 | ||||
|     println!("the sum of middle pages of good updates is {good_sum}"); | ||||
|     println!("and the bad updates is {bad_sum}"); | ||||
| } | ||||
| 
 | ||||
| fn halfway<T>(v: &[T]) -> Option<&T> { | ||||
|     if v.len() == 0 { return None; } | ||||
|     return v.get((v.len() - 1) / 2) | ||||
| } | ||||
							
								
								
									
										6
									
								
								day06/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								day06/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| [package] | ||||
| name = "day06" | ||||
| version = "0.1.0" | ||||
| edition = "2021" | ||||
| 
 | ||||
| [dependencies] | ||||
							
								
								
									
										3
									
								
								day06/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								day06/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| fn main() { | ||||
|     println!("Hello, world!"); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user