porting over AOC from previous years to a monorepo.
This commit is contained in:
commit
84c4cf9991
194 changed files with 30104 additions and 0 deletions
11
2023/days/01/Cargo.toml
Normal file
11
2023/days/01/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day01"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
regex.workspace = true
|
||||
once_cell.workspace = true
|
||||
1000
2023/days/01/src/input.txt
Normal file
1000
2023/days/01/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
15
2023/days/01/src/main.rs
Normal file
15
2023/days/01/src/main.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
let structured_input = parse::parse_english(input);
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
77
2023/days/01/src/parse.rs
Normal file
77
2023/days/01/src/parse.rs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
static REPLACEMENT_STRINGS: [(&str, &str); 10] = [
|
||||
("zero", "zero0zero"),
|
||||
("one", "one1one"),
|
||||
("two", "two2two"),
|
||||
("three", "three3three"),
|
||||
("four", "four4four"),
|
||||
("five", "five5five"),
|
||||
("six", "six6six"),
|
||||
("seven", "seven7seven"),
|
||||
("eight", "eight8eight"),
|
||||
("nine", "nine9nine"),
|
||||
];
|
||||
|
||||
pub fn parse_english(input: &str) -> Vec<Vec<char>> {
|
||||
input
|
||||
.to_string()
|
||||
.lines()
|
||||
.map(|l| {
|
||||
let mut ret = l.to_string();
|
||||
for (string, replacement) in REPLACEMENT_STRINGS.iter() {
|
||||
ret = ret.replace(string, replacement)
|
||||
}
|
||||
ret
|
||||
})
|
||||
.map(|l| l.chars().filter(|c| c.is_ascii_digit()).collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Vec<char>> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| l.chars().filter(|c| c.is_ascii_digit()).collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!("1abc2\n", "pqr3stu8vwx\n", "a1b2c3d4e5f\n", "treb7uchet\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
vec!['1', '2',],
|
||||
vec!['3', '8',],
|
||||
vec!['1', '2', '3', '4', '5'],
|
||||
vec!['7']
|
||||
]
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_english() {
|
||||
let input = concat!(
|
||||
"two1nine\n",
|
||||
"eightwothree\n",
|
||||
"abcone2threexyz\n",
|
||||
"xtwone3four\n",
|
||||
"4nineeightseven2\n",
|
||||
"zoneight234\n",
|
||||
"7pqrstsixteen\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse_english(input),
|
||||
vec![
|
||||
vec!['2', '1', '9',],
|
||||
vec!['8', '2', '3',],
|
||||
vec!['1', '2', '3',],
|
||||
vec!['2', '1', '3', '4'],
|
||||
vec!['4', '9', '8', '7', '2'],
|
||||
vec!['1', '8', '2', '3', '4'],
|
||||
vec!['7', '6'],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
27
2023/days/01/src/part1.rs
Normal file
27
2023/days/01/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
pub fn part1(input: &[Vec<char>]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let mut string = String::new();
|
||||
string.push_str(&s.first().unwrap().to_string());
|
||||
string.push_str(&s.last().unwrap().to_string());
|
||||
string.parse::<usize>().unwrap()
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
vec!['1', '2'],
|
||||
vec!['3', '8'],
|
||||
vec!['1', '2', '3', '4', '5'],
|
||||
vec!['7'],
|
||||
];
|
||||
assert_eq!(part1(&input), 142);
|
||||
}
|
||||
}
|
||||
30
2023/days/01/src/part2.rs
Normal file
30
2023/days/01/src/part2.rs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
pub fn part2(input: &[Vec<char>]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let mut string = String::new();
|
||||
string.push_str(&s.first().unwrap().to_string());
|
||||
string.push_str(&s.last().unwrap().to_string());
|
||||
string.parse::<usize>().unwrap()
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
vec!['2', '1', '9'],
|
||||
vec!['8', '2', '3'],
|
||||
vec!['1', '2', '3'],
|
||||
vec!['2', '1', '3', '4'],
|
||||
vec!['4', '9', '8', '7', '2'],
|
||||
vec!['1', '8', '2', '3', '4'],
|
||||
vec!['7', '6'],
|
||||
];
|
||||
assert_eq!(part2(&input), 281);
|
||||
}
|
||||
}
|
||||
10
2023/days/02/Cargo.toml
Normal file
10
2023/days/02/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day02"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace = true
|
||||
100
2023/days/02/src/input.txt
Normal file
100
2023/days/02/src/input.txt
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
Game 1: 3 blue, 7 green, 10 red; 4 green, 4 red; 1 green, 7 blue, 5 red; 8 blue, 10 red; 7 blue, 19 red, 1 green
|
||||
Game 2: 6 red, 10 green; 11 green, 4 red; 16 green, 2 blue; 7 green, 5 blue, 4 red; 17 green, 1 red, 1 blue
|
||||
Game 3: 5 red, 9 blue, 1 green; 5 red; 11 red, 2 green, 8 blue; 2 green, 6 blue
|
||||
Game 4: 2 red, 5 green; 2 blue, 3 red, 3 green; 3 red, 2 blue; 8 green, 2 red
|
||||
Game 5: 12 red, 13 blue; 13 blue, 2 green, 9 red; 9 blue, 1 red; 2 green, 12 blue; 1 green, 1 red, 11 blue
|
||||
Game 6: 4 blue, 11 red; 4 red; 1 green, 7 red; 1 green, 1 blue; 8 blue, 10 red; 1 green, 2 blue, 8 red
|
||||
Game 7: 7 blue, 15 red, 1 green; 5 green, 17 red, 7 blue; 5 blue, 1 green; 11 blue, 2 green, 17 red; 14 green, 9 red, 2 blue; 6 blue, 19 red
|
||||
Game 8: 13 green; 5 green; 3 blue, 9 green, 1 red; 4 red, 11 green, 4 blue
|
||||
Game 9: 4 green, 1 red, 1 blue; 4 green, 7 blue, 7 red; 9 blue, 4 red; 2 blue, 8 red, 5 green; 6 blue, 2 green; 5 red, 5 green, 10 blue
|
||||
Game 10: 1 green, 5 blue, 3 red; 4 green, 9 red, 3 blue; 11 red, 2 green, 5 blue; 3 green, 1 blue, 2 red; 6 red, 2 blue
|
||||
Game 11: 2 red, 6 green, 12 blue; 2 red, 9 blue, 1 green; 12 green, 3 blue
|
||||
Game 12: 1 red, 1 blue, 12 green; 6 green, 2 red, 1 blue; 6 red, 6 green, 1 blue; 3 green, 6 red
|
||||
Game 13: 5 red, 19 green, 3 blue; 6 red, 7 blue, 11 green; 8 blue, 6 red; 3 blue, 4 green, 4 red; 8 red, 15 green, 5 blue; 5 blue, 2 red, 10 green
|
||||
Game 14: 5 blue, 9 green; 4 green, 6 blue; 14 green, 1 red, 4 blue; 3 blue, 3 green; 2 green; 5 blue, 7 green, 1 red
|
||||
Game 15: 5 red, 8 blue; 9 blue, 3 red; 5 red, 1 green, 16 blue; 1 blue, 3 red, 2 green; 5 red, 2 green, 10 blue
|
||||
Game 16: 6 blue, 9 green, 10 red; 8 blue, 9 red, 14 green; 7 green, 1 blue, 1 red; 8 red, 5 green, 8 blue; 10 red, 5 blue, 14 green; 7 blue, 11 red, 3 green
|
||||
Game 17: 12 blue, 12 red, 6 green; 14 green, 17 blue, 4 red; 11 blue, 1 red, 13 green
|
||||
Game 18: 7 blue, 2 green, 4 red; 1 blue, 2 green, 4 red; 2 red, 17 blue
|
||||
Game 19: 3 red, 9 green; 8 red, 2 blue, 2 green; 3 blue, 15 green, 11 red; 18 green, 3 red, 1 blue
|
||||
Game 20: 5 green, 5 red, 16 blue; 8 blue, 6 green, 4 red; 10 red, 11 blue; 5 red, 5 blue, 5 green
|
||||
Game 21: 1 red, 3 blue, 14 green; 6 red, 6 blue, 17 green; 12 green, 17 blue, 3 red; 15 green, 1 red, 19 blue; 3 red, 18 blue, 4 green
|
||||
Game 22: 15 blue; 11 blue, 2 red, 1 green; 1 green, 7 red; 1 red, 18 blue, 1 green; 16 blue; 3 red, 6 blue
|
||||
Game 23: 11 blue, 6 green, 4 red; 9 green, 11 red, 8 blue; 5 green, 5 red, 2 blue; 11 green, 4 blue, 11 red; 3 green, 9 blue, 2 red
|
||||
Game 24: 7 green, 2 red; 8 red, 1 blue, 15 green; 3 red, 6 green, 6 blue
|
||||
Game 25: 9 blue, 9 green; 3 green, 7 blue, 1 red; 6 green, 1 red, 1 blue; 6 green, 1 red, 1 blue
|
||||
Game 26: 1 green, 15 blue, 1 red; 1 red, 12 blue, 1 green; 16 blue; 5 red, 11 green, 14 blue; 6 green, 4 red, 14 blue
|
||||
Game 27: 14 red, 9 green; 11 red, 5 green, 6 blue; 1 red, 6 blue, 9 green
|
||||
Game 28: 6 green, 1 blue, 9 red; 1 green, 9 red; 7 red; 11 red, 1 blue, 2 green; 8 red, 10 green; 6 green, 1 blue, 5 red
|
||||
Game 29: 1 red, 19 blue, 3 green; 9 blue, 1 red; 8 green, 17 blue; 11 blue, 4 green
|
||||
Game 30: 7 blue; 5 blue, 1 red, 1 green; 3 blue, 1 red
|
||||
Game 31: 9 red, 2 green, 1 blue; 5 red, 1 green, 3 blue; 2 green, 7 red; 2 green, 12 red
|
||||
Game 32: 1 red, 1 blue, 17 green; 14 blue, 10 green, 6 red; 12 green, 11 blue, 3 red
|
||||
Game 33: 2 red, 1 green, 3 blue; 7 blue, 4 green; 1 red, 3 green, 5 blue
|
||||
Game 34: 9 blue, 1 green, 9 red; 12 blue, 2 green, 12 red; 3 blue, 12 red; 2 green, 14 blue, 11 red; 10 red, 12 blue
|
||||
Game 35: 6 blue, 2 red; 5 blue; 6 green, 9 blue, 3 red; 3 green, 1 red, 2 blue
|
||||
Game 36: 9 blue, 4 green, 6 red; 2 red, 4 green; 7 red, 3 green; 6 green, 2 blue; 3 red, 4 blue, 3 green; 3 green, 4 red, 16 blue
|
||||
Game 37: 2 green, 8 red, 4 blue; 3 red, 4 blue, 2 green; 5 blue, 3 green; 9 blue, 15 green; 5 red, 11 green, 7 blue
|
||||
Game 38: 12 red, 1 blue; 10 red, 3 green, 2 blue; 7 blue, 3 green, 8 red; 14 red, 2 green
|
||||
Game 39: 16 green, 2 red, 17 blue; 6 red, 4 green, 13 blue; 7 blue, 1 green, 4 red; 2 green, 3 blue; 12 green, 6 red, 17 blue; 5 red, 2 blue, 6 green
|
||||
Game 40: 3 green, 4 blue, 2 red; 2 green, 3 red; 6 blue, 2 red, 6 green; 5 green; 3 blue, 1 red, 5 green
|
||||
Game 41: 13 green, 11 red; 3 green, 2 red, 1 blue; 1 blue, 3 green, 9 red; 12 red, 11 green; 9 red, 1 green; 9 green, 4 red
|
||||
Game 42: 4 green, 2 blue; 6 blue, 10 green; 13 blue, 3 red, 6 green; 11 blue, 17 green; 8 blue, 5 red
|
||||
Game 43: 10 green, 2 blue, 10 red; 3 red, 3 blue, 5 green; 10 green, 11 red, 4 blue; 5 green; 7 green, 13 red, 2 blue
|
||||
Game 44: 4 red, 1 blue, 5 green; 1 blue, 8 red, 3 green; 11 red, 1 green, 1 blue; 2 green, 12 red, 1 blue; 1 blue, 12 red; 14 red, 3 green
|
||||
Game 45: 4 green, 5 red, 7 blue; 10 red, 8 green, 3 blue; 12 blue, 1 green, 13 red; 1 red, 3 blue, 7 green
|
||||
Game 46: 5 blue, 13 red; 15 red, 3 green, 17 blue; 8 red, 2 green, 1 blue; 1 green, 7 red, 16 blue; 4 blue, 10 red
|
||||
Game 47: 2 red, 3 green; 2 blue, 9 red, 15 green; 7 green, 4 red; 3 blue, 13 red, 9 green
|
||||
Game 48: 11 green, 4 red, 9 blue; 1 blue, 7 green; 4 blue, 4 red; 4 red, 4 blue, 2 green; 9 green, 2 blue, 2 red
|
||||
Game 49: 10 green, 6 blue; 2 blue, 5 green, 1 red; 5 green, 4 blue; 11 green, 3 red, 3 blue
|
||||
Game 50: 2 red, 15 green, 1 blue; 8 green, 7 blue; 4 blue, 8 green; 7 blue, 17 green; 5 blue, 6 green, 2 red; 16 green, 2 red, 1 blue
|
||||
Game 51: 3 green, 5 blue, 1 red; 11 red, 9 blue, 8 green; 3 red, 8 green, 7 blue; 1 red, 9 blue, 6 green; 4 green, 1 red, 3 blue; 8 green, 7 red
|
||||
Game 52: 1 green, 2 blue, 10 red; 8 green, 1 blue, 2 red; 7 red, 8 green
|
||||
Game 53: 2 red, 6 green; 1 green, 4 blue; 12 green, 19 blue; 11 blue, 1 green; 4 green, 20 blue; 7 blue, 9 green, 1 red
|
||||
Game 54: 2 blue, 2 green, 2 red; 13 red, 1 green, 6 blue; 9 blue, 1 green, 18 red; 11 red, 16 blue; 15 red, 3 green, 13 blue
|
||||
Game 55: 5 green, 5 blue, 9 red; 8 red, 11 blue, 7 green; 6 green, 2 red, 10 blue; 6 red, 6 blue, 9 green; 11 green, 14 blue, 4 red
|
||||
Game 56: 8 blue, 14 green; 3 red, 8 green, 3 blue; 14 green, 1 red, 13 blue; 8 green, 3 red; 8 blue, 11 green, 1 red; 8 blue, 10 green, 2 red
|
||||
Game 57: 7 blue, 7 red; 11 green, 5 blue, 2 red; 14 green, 8 blue; 5 blue, 2 red, 17 green; 12 green, 3 red; 7 red, 7 blue, 9 green
|
||||
Game 58: 3 blue, 4 red, 1 green; 2 green, 3 red; 1 red, 2 green, 4 blue; 4 green, 4 red, 2 blue
|
||||
Game 59: 6 red, 4 blue, 5 green; 6 blue, 6 red; 1 red; 8 blue, 1 red
|
||||
Game 60: 4 blue, 9 green, 11 red; 12 green, 3 red, 9 blue; 7 green, 1 blue; 14 green, 11 blue, 11 red
|
||||
Game 61: 12 green; 9 green, 9 red; 12 red, 18 blue, 8 green; 16 red, 10 blue, 3 green; 6 green, 15 red, 3 blue; 13 green
|
||||
Game 62: 2 green, 3 red, 12 blue; 12 blue, 12 green, 12 red; 1 red, 12 blue, 5 green; 7 red, 9 blue, 13 green; 1 blue, 3 red, 10 green; 2 blue, 8 red, 17 green
|
||||
Game 63: 10 green, 7 blue, 4 red; 3 blue, 6 green, 2 red; 4 green, 10 red, 6 blue; 16 blue, 5 red, 4 green
|
||||
Game 64: 11 red, 1 green, 6 blue; 12 red, 3 green; 6 green, 5 blue, 2 red; 4 green, 9 blue, 11 red; 5 blue, 8 green, 8 red; 9 green, 11 blue
|
||||
Game 65: 4 blue, 12 red; 1 green, 3 blue, 12 red; 1 green, 3 blue, 13 red; 2 red; 12 red
|
||||
Game 66: 4 red, 3 green, 3 blue; 2 blue, 4 red; 10 red, 6 blue, 3 green
|
||||
Game 67: 7 red, 2 blue, 5 green; 3 green, 5 red, 18 blue; 16 red, 5 green, 13 blue; 16 red, 5 blue, 2 green
|
||||
Game 68: 11 blue, 2 red; 1 green, 3 blue, 8 red; 16 red, 1 green, 17 blue; 4 red, 1 green, 11 blue; 3 red
|
||||
Game 69: 1 green, 9 red, 12 blue; 12 red; 11 blue; 1 green
|
||||
Game 70: 1 green, 18 blue, 16 red; 3 green, 15 red, 7 blue; 3 blue, 3 green, 10 red; 1 blue, 3 green, 10 red
|
||||
Game 71: 3 red, 12 blue, 8 green; 18 green, 12 blue, 5 red; 2 blue, 7 red; 11 blue, 9 green; 5 blue, 7 red, 19 green; 2 red, 1 blue, 13 green
|
||||
Game 72: 8 red, 6 blue, 3 green; 2 green, 13 blue, 15 red; 5 green, 8 blue, 2 red; 5 red, 12 blue, 3 green
|
||||
Game 73: 3 blue, 13 green; 7 red, 3 green; 10 red, 2 blue, 1 green
|
||||
Game 74: 3 red; 2 red, 1 blue, 7 green; 10 green, 3 blue, 1 red; 6 green, 1 blue; 11 green, 4 blue
|
||||
Game 75: 8 blue, 2 green, 4 red; 19 blue, 2 green; 1 red, 18 blue, 3 green; 3 red, 5 green, 18 blue
|
||||
Game 76: 3 green, 2 red, 2 blue; 3 blue, 6 green, 1 red; 1 green, 3 blue; 1 blue, 1 green
|
||||
Game 77: 4 green, 7 red, 13 blue; 18 blue; 4 blue, 9 red, 1 green; 2 green, 16 blue, 9 red
|
||||
Game 78: 2 green, 5 blue, 11 red; 2 blue, 3 red, 1 green; 4 green, 6 blue, 6 red
|
||||
Game 79: 9 blue, 1 green, 3 red; 1 green, 2 red, 4 blue; 5 red, 4 green, 10 blue; 1 red, 9 blue, 4 green
|
||||
Game 80: 8 red, 5 green, 7 blue; 15 red, 6 blue, 8 green; 8 blue, 14 red, 7 green; 3 blue, 2 green, 20 red; 10 red, 8 blue, 1 green; 7 green, 11 red, 9 blue
|
||||
Game 81: 7 red, 1 blue, 5 green; 5 green, 10 blue, 9 red; 8 blue, 2 green, 7 red
|
||||
Game 82: 1 green, 6 blue, 14 red; 7 blue, 2 green; 7 blue, 17 red, 3 green
|
||||
Game 83: 2 red, 19 blue, 2 green; 5 red, 5 blue, 2 green; 2 red, 4 blue, 1 green
|
||||
Game 84: 1 blue, 1 red, 12 green; 11 blue, 6 red, 13 green; 10 red, 8 blue, 8 green; 14 blue, 15 red; 19 blue, 10 green, 17 red; 11 red, 7 green
|
||||
Game 85: 16 blue, 12 red, 8 green; 13 red, 3 green; 1 red, 16 blue, 10 green
|
||||
Game 86: 5 green, 8 blue, 3 red; 8 green, 9 red, 13 blue; 4 green, 1 red, 12 blue; 13 red, 15 blue, 5 green
|
||||
Game 87: 1 green, 16 red; 10 red, 2 green, 2 blue; 16 red, 5 blue; 1 blue, 2 green
|
||||
Game 88: 3 blue, 1 green; 1 red, 2 green, 13 blue; 5 blue, 2 green, 1 red
|
||||
Game 89: 9 blue, 2 red, 1 green; 10 blue; 5 blue, 1 green
|
||||
Game 90: 8 red, 2 blue, 5 green; 2 red, 2 green, 2 blue; 1 blue, 8 green, 10 red; 11 green, 1 blue; 10 green, 4 red, 3 blue
|
||||
Game 91: 14 blue, 9 red; 5 green, 5 red, 11 blue; 7 green, 4 blue, 12 red; 8 red, 6 green, 10 blue
|
||||
Game 92: 2 green, 2 blue, 12 red; 2 green, 1 blue, 14 red; 14 red, 2 blue, 6 green; 11 red, 6 green, 2 blue; 11 green, 12 red, 2 blue
|
||||
Game 93: 4 green, 7 blue, 3 red; 1 green, 12 blue, 1 red; 8 blue, 7 green, 2 red; 3 red, 9 blue, 2 green
|
||||
Game 94: 13 green, 9 blue; 9 blue, 1 red, 8 green; 12 green, 1 red, 8 blue; 1 red, 9 green; 1 red, 5 blue, 14 green
|
||||
Game 95: 7 blue, 14 red; 9 blue, 17 red; 2 blue, 1 green, 4 red
|
||||
Game 96: 11 blue, 2 green, 3 red; 3 blue, 12 red, 3 green; 4 green, 11 red, 1 blue
|
||||
Game 97: 9 red, 5 green, 2 blue; 12 red, 1 blue, 11 green; 7 green, 4 red, 2 blue; 1 blue, 6 red, 10 green
|
||||
Game 98: 5 green, 5 red, 11 blue; 1 red, 10 blue, 7 green; 8 red, 1 blue, 7 green; 8 green, 11 red, 2 blue; 4 red, 5 blue, 2 green; 10 green, 5 red, 9 blue
|
||||
Game 99: 3 green, 7 red, 4 blue; 9 red, 13 blue, 2 green; 3 red, 2 green, 11 blue; 5 red, 6 blue, 3 green; 8 blue, 5 green, 6 red; 6 green, 13 red, 1 blue
|
||||
Game 100: 9 green, 7 blue; 1 green, 3 red, 4 blue; 15 red, 9 green; 3 blue, 6 red, 13 green; 2 red, 11 blue, 12 green
|
||||
14
2023/days/02/src/main.rs
Normal file
14
2023/days/02/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
294
2023/days/02/src/parse.rs
Normal file
294
2023/days/02/src/parse.rs
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::tag,
|
||||
character::{self},
|
||||
combinator::map,
|
||||
multi::separated_list1,
|
||||
sequence::{preceded, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Handful {
|
||||
pub red: u8,
|
||||
pub green: u8,
|
||||
pub blue: u8,
|
||||
}
|
||||
|
||||
impl Handful {
|
||||
pub fn is_possible_given_contents(&self, contents: &Handful) -> bool {
|
||||
contents.red >= self.red && contents.green >= self.green && contents.blue >= self.blue
|
||||
}
|
||||
|
||||
pub fn power(&self) -> usize {
|
||||
self.red as usize * self.green as usize * self.blue as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Game {
|
||||
pub id: u8,
|
||||
pub handfuls: Vec<Handful>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn parse(input: &str) -> IResult<&str, Self> {
|
||||
let (input, id) = Self::parse_game_id(input)?;
|
||||
let (input, handfuls) = separated_list1(tag("; "), Self::parse_handful)(input)?;
|
||||
Ok((input, Game { id, handfuls }))
|
||||
}
|
||||
|
||||
fn parse_game_id(input: &str) -> IResult<&str, u8> {
|
||||
terminated(
|
||||
preceded(tag("Game "), nom::character::complete::u8),
|
||||
tag(": "),
|
||||
)(input)
|
||||
}
|
||||
|
||||
fn parse_colour_set(input: &str) -> IResult<&str, Colour> {
|
||||
let red = terminated(character::complete::u8, tag(" red"));
|
||||
let green = terminated(character::complete::u8, tag(" green"));
|
||||
let blue = terminated(character::complete::u8, tag(" blue"));
|
||||
alt((
|
||||
map(red, Colour::Red),
|
||||
map(green, Colour::Green),
|
||||
map(blue, Colour::Blue),
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn parse_handful(input: &str) -> IResult<&str, Handful> {
|
||||
let (input, colours) = separated_list1(tag(", "), Self::parse_colour_set)(input)?;
|
||||
let mut red = 0;
|
||||
let mut green = 0;
|
||||
let mut blue = 0;
|
||||
for colour in colours {
|
||||
match colour {
|
||||
Colour::Red(n) => red = n,
|
||||
Colour::Green(n) => green = n,
|
||||
Colour::Blue(n) => blue = n,
|
||||
}
|
||||
}
|
||||
Ok((input, Handful { red, green, blue }))
|
||||
}
|
||||
|
||||
pub fn is_possible_given_contents(&self, contents: &Handful) -> bool {
|
||||
self.handfuls
|
||||
.iter()
|
||||
.all(|h| h.is_possible_given_contents(contents))
|
||||
}
|
||||
|
||||
pub fn min_contents(&self) -> Handful {
|
||||
Handful {
|
||||
red: self.handfuls.iter().map(|g| g.red).max().unwrap_or(0),
|
||||
green: self.handfuls.iter().map(|g| g.green).max().unwrap_or(0),
|
||||
blue: self.handfuls.iter().map(|g| g.blue).max().unwrap_or(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
enum Colour {
|
||||
Red(u8),
|
||||
Green(u8),
|
||||
Blue(u8),
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Game> {
|
||||
input.lines().map(|l| Game::parse(l).unwrap().1).collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green\n",
|
||||
"Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue\n",
|
||||
"Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red\n",
|
||||
"Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red\n",
|
||||
"Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Game {
|
||||
id: 1,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 0,
|
||||
blue: 3
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 6
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
Game {
|
||||
id: 2,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 1
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 3,
|
||||
blue: 4
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
Game {
|
||||
id: 3,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 20,
|
||||
green: 8,
|
||||
blue: 6
|
||||
},
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 13,
|
||||
blue: 5
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 5,
|
||||
blue: 0
|
||||
}
|
||||
]
|
||||
},
|
||||
Game {
|
||||
id: 4,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 3,
|
||||
green: 1,
|
||||
blue: 6
|
||||
},
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 0
|
||||
},
|
||||
Handful {
|
||||
red: 14,
|
||||
green: 3,
|
||||
blue: 15
|
||||
}
|
||||
]
|
||||
},
|
||||
Game {
|
||||
id: 5,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 1
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_game_parsing() {
|
||||
let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green";
|
||||
assert_eq!(
|
||||
Game::parse(input).unwrap(),
|
||||
(
|
||||
"",
|
||||
Game {
|
||||
id: 1,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
blue: 3,
|
||||
red: 4,
|
||||
green: 0
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 6
|
||||
},
|
||||
Handful {
|
||||
green: 2,
|
||||
blue: 0,
|
||||
red: 0
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_handful() {
|
||||
assert_eq!(
|
||||
Game::parse_handful("10 blue, 53 red, 3 green").unwrap(),
|
||||
(
|
||||
"",
|
||||
Handful {
|
||||
red: 53,
|
||||
green: 3,
|
||||
blue: 10
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
Game::parse_handful("15 green, 53 red").unwrap(),
|
||||
(
|
||||
"",
|
||||
Handful {
|
||||
red: 53,
|
||||
green: 15,
|
||||
blue: 0
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_colour_set() {
|
||||
assert_eq!(
|
||||
Game::parse_colour_set("5 red").unwrap(),
|
||||
("", Colour::Red(5))
|
||||
);
|
||||
assert_eq!(
|
||||
Game::parse_colour_set("10 blue").unwrap(),
|
||||
("", Colour::Blue(10))
|
||||
);
|
||||
assert_eq!(
|
||||
Game::parse_colour_set("123 green").unwrap(),
|
||||
("", Colour::Green(123))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_game_id() {
|
||||
assert_eq!(Game::parse_game_id("Game 2: ").unwrap(), ("", 2));
|
||||
assert_eq!(Game::parse_game_id("Game 100: ").unwrap(), ("", 100));
|
||||
assert_eq!(Game::parse_game_id("Game 15: ").unwrap(), ("", 15));
|
||||
}
|
||||
}
|
||||
121
2023/days/02/src/part1.rs
Normal file
121
2023/days/02/src/part1.rs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &[Game]) -> usize {
|
||||
let contents = Handful {
|
||||
red: 12,
|
||||
green: 13,
|
||||
blue: 14,
|
||||
};
|
||||
input
|
||||
.iter()
|
||||
.filter(|g| g.is_possible_given_contents(&contents))
|
||||
.map(|g| g.id as usize)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Game {
|
||||
id: 1,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 0,
|
||||
blue: 3,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 2,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 1,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 3,
|
||||
blue: 4,
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 3,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 20,
|
||||
green: 8,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 13,
|
||||
blue: 5,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 5,
|
||||
blue: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 4,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 3,
|
||||
green: 1,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 0,
|
||||
},
|
||||
Handful {
|
||||
red: 14,
|
||||
green: 3,
|
||||
blue: 15,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 5,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 1,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
assert_eq!(part1(&input), 8);
|
||||
}
|
||||
}
|
||||
112
2023/days/02/src/part2.rs
Normal file
112
2023/days/02/src/part2.rs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &[Game]) -> usize {
|
||||
input.iter().map(|g| g.min_contents().power()).sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
Game {
|
||||
id: 1,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 0,
|
||||
blue: 3,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 2,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 2,
|
||||
blue: 1,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 3,
|
||||
blue: 4,
|
||||
},
|
||||
Handful {
|
||||
red: 0,
|
||||
green: 1,
|
||||
blue: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 3,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 20,
|
||||
green: 8,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 4,
|
||||
green: 13,
|
||||
blue: 5,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 5,
|
||||
blue: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 4,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 3,
|
||||
green: 1,
|
||||
blue: 6,
|
||||
},
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 0,
|
||||
},
|
||||
Handful {
|
||||
red: 14,
|
||||
green: 3,
|
||||
blue: 15,
|
||||
},
|
||||
],
|
||||
},
|
||||
Game {
|
||||
id: 5,
|
||||
handfuls: vec![
|
||||
Handful {
|
||||
red: 6,
|
||||
green: 3,
|
||||
blue: 1,
|
||||
},
|
||||
Handful {
|
||||
red: 1,
|
||||
green: 2,
|
||||
blue: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
assert_eq!(part2(&input), 2286);
|
||||
}
|
||||
}
|
||||
9
2023/days/03/Cargo.toml
Normal file
9
2023/days/03/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day03"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
140
2023/days/03/src/input.txt
Normal file
140
2023/days/03/src/input.txt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
....................................18..........889.270.....748.280...997.................617..............622........763............476....
|
||||
...529......434.....191..489...717...@.....................&....................939*7.....*....................606............760....*......
|
||||
....*...473....*221................$........182......812........493.84....793..........794.......589..407..41...*.....................68....
|
||||
..380.................553..559..105.....749.............*..........*.........*.............-968....@.....*..*....908..603...................
|
||||
.........................................#...600.........441..#833...490....366.........................225..488........&...456.........224.
|
||||
........288=......896*469..........831..........*....................*..............#...@.146.......*.............790#......%...194....@....
|
||||
..730.........................250+......./......359....=.462..............138...#.49..713.-........342...604*676.........=.....*.........418
|
||||
....*....907.......526................274...........346.....*.876..........-..725.............376......................541...600.....366*...
|
||||
.....747...*..........*......56$...10........422........-.86.....*.......................728./............*.................................
|
||||
.........486.........349............*..........=......696....$.............850&......906*......831.....539.195.........202..................
|
||||
..............592.............................................592....+.847.......676......365..=......................*........469.%........
|
||||
.542............*...............385....60.................329......657..@......=..*....&...........355.........=....52.........*....352.....
|
||||
.............994......937...................45.....48........*..............835...791..654....................75.............523............
|
||||
...................&..............269.486.....+...*......&....954.........#........................246&...&..............203......693.......
|
||||
.....262..........920...248.454......*...........289...822.........530...569..............................256.......929....*......*.........
|
||||
........%............../.........................................../..............+..57.@............616=...........*...462...198.757.......
|
||||
...............65........=.........764*.....$581.727........62.......4.....796..280......444.807...............174@.20................512...
|
||||
.........877....*...687..187.522.......853..........*321.....*........*345...........513.....=.......849..........................@....*....
|
||||
.........*...635......*........=..............................380...........77...44*..*................#......*......484.....65.886.........
|
||||
.....153.........@.&.....320........96..619....510......221.............139..*........957..977......20.....232.20......&.....*..............
|
||||
......*...397*.610..479...*....=....%.....*.......*.............839.......*................*............*.................144........#554...
|
||||
..510...................927.....384........714...286....................799.....733.........832......815.187.....*....470...................
|
||||
........892..................................................645.427.............%......562...................133.442....*906...............
|
||||
.........=..........803............577.......%.....447..185.........*957.637*97..............132...............................83.258@..$...
|
||||
...........=55......+....+...435.......930...143.............475................./..............#......................=..675...%......709..
|
||||
777....................841..*...........*......................*........*.........859...../...............640%..955..903.*..................
|
||||
..............639/...........803.829.....877........#.........716....873....387.........857..837.................*.......390................
|
||||
.................................*...............994......................%....*.............&.......749.........718.174.....138..697...463.
|
||||
.....................697...873#.435......*141...........914*656....@......414..981.....541.......%....*...+.#.........*......&....+.........
|
||||
.....................*................544.......524.............446.......................+.397..486....603.463......497....................
|
||||
.........161........412....273..218..............*..80............................708.......=....................899........+......-........
|
||||
............*..435*.........-..$.........666..401.....*897.214..472..499............*...955......................@...867....607.491..43@....
|
||||
666%.851..653......44...............152....................*....@.....*..........294.....*...313...237....580...............................
|
||||
............................989....*.....954.....69.....488../.......90.495*..........697....*.......*.....*..686.......=.......594*981.....
|
||||
.....104..#...................=.....773...$../.....*396.....959.............272...........433........889.821.....*759.469...................
|
||||
.......*..865.318.@812........................267...............969.............................758........................913........646...
|
||||
......132......*.........*699......+...............+.......126......468.....651............424........270.765.....53...965.*...19...........
|
||||
..............725.....449.......337..187........862.............553*........*....=282.28....*........*....*........*.....%.779..&....218*...
|
||||
.....744...36.....203.......452.......%..846........&......................................811..501..342...891.....776...................395
|
||||
.................$.....567&...@..689.......%.......619..392.........847#..#.....236*833............*.........................408............
|
||||
............./.....732............*........................*..............568................375..561..-270..111....=..565..................
|
||||
...........801............221....336...493....263..81*.....981...........................449*....................809......*239...........686
|
||||
...................+.........*87......*..........#....510...........20*684.../..387.....................................*...........132.....
|
||||
.......674......&..364...........734.141.854*290...........................572.*......878...929.141.#.......526...919.646..*..........*.....
|
||||
..............980...............*...............................500...229......876....*..............220.....*.....*........809......522....
|
||||
394....374......................194......660.....172..............&.....*...........774...................367......452..952.................
|
||||
.......*...................918/............*.....*.......220........776.542..............843..857....560....................................
|
||||
........728.......@951.668.........651......589.857.........../.....*.........354....509.......@........*.................+.....151.........
|
||||
......-......262.........#.....*95...................878./...563.642.............#.......................586........638..933....=...........
|
||||
504.454.......*............540..........524..........*...531...........942...................632@.830.........302..-................%.......
|
||||
.........498..357..........*....&..........%.......340.........925.......*....623.707.479............*36....%........+.....659*149.401.117..
|
||||
34..................608.....156.747...602@...............................748..*....*..$............*.........565.....93................*....
|
||||
........426.................................60.938...........................615.328.....818....143.118..................*.@...........916..
|
||||
...............547..............25*32.......*..*.......64..-813..........405.........802...*............188............246.236..............
|
||||
652................*426...................74.....822...*.................*...533....*....764..............*....................%............
|
||||
....920.64......437......598....738..#..............+..44...625...*....879......*..879.......668.#.......509...385..123....677..553.62......
|
||||
....*....+.783..........*..........*.552...534...............*.....312........=.........@...-....819............#..-..........*.............
|
||||
....779.......&....21..582......264.........*.............564...............561........811...........................943....68..$...........
|
||||
.....................&.....................915.472*918.................848.......943.........803....................*..........386..........
|
||||
...........................62........668..........................*801.*.........*...............878.......212....613.......................
|
||||
.......208.......302..313*...*........*...........&.717........237.....11.........551.569.................*...............717...............
|
||||
...742*......886*.........15.402....806...84...527.....*....=................650......*.....56.....401...276......964......-.....@..........
|
||||
..........................................*.........411...277.722.337.........*.....915.252*........*................+..........356....553..
|
||||
.......*...2.........406...............922.....=605............*............403......................316..........84.......%..........=.....
|
||||
.......385.+....%893........200............150...........420.548.......+111...........70............................*675.895................
|
||||
...........................+.......198-...@.........532...........23..........349#....*......#...............................920.........844
|
||||
.....#.....387/.............................31..638..*....580.....#...........................397..720..........161...+.......*..628....*...
|
||||
......816..............669....36..#393..848..........884.+...........&676.....876*341...565%.......*..........*....#...914...356..-..210....
|
||||
...............646........&..$.........*...................542....................................370......686.567..........................
|
||||
............../....94................414......18.............................861....*.....878..........24@.............875=.693*320..864.989
|
||||
...................*.........665..............*...595..........201......738..+...784..187....*237..../..............................*.......
|
||||
......236-.......126.....641*..../............486.*.....638.............................*.%.......242....*153....+.........63.837.723.41....
|
||||
...........35....................114...............661....-....534.........626*......796..28..........579......367..78.929...*..............
|
||||
......108.........271*144.........................................*............5.....................................*.*.......669.533..704.
|
||||
.........*635................#..@947.......290.....544.............707...................465..632.....771...181........471.380*......*......
|
||||
.....114..........89$.....699...........=....*........=.....416...........................&.....$......$..........365...............131.....
|
||||
.......-.............................410....64......*.........*.........&....684.....15.....317...340*..............*.......................
|
||||
.........26.609........152........................94.498.....26......671.......*.221*..........*......718...824.....56...........915........
|
||||
..218..............707*.......786.....839................790.....192.........181......836....287..............%.......................-.....
|
||||
......937.722...............%.........*...378$...........*.........@.449..............%............226...........&...........428.......341..
|
||||
.795....*...&..185..405.....60.121....159.......275...996............*....981.....710........363...%...528....-.888....*641...*....880......
|
||||
...-..806.......*.....*......................@.....#......545..467...289..*.........*....681..........*.....86......326.......664.&.........
|
||||
.............221.....142...860+....933..653..291......52&../..*............300.%...811...*..................................................
|
||||
......................................-....*.....861.........149...............673......762........./284..588..................%.....316....
|
||||
..373......290..............................665.....*................&.............&552.....51.............=.......105.......162.......*....
|
||||
...-........*.....388........%...772....................=...57....163..932..41...............*...693.116*......#.....*..............434.....
|
||||
......*489...248..*........395...=.....................676..#..........*...................835...........570.199..678.......................
|
||||
780...............713................952...479...379..................83.554.........919.......486..980...............984.$468.....720......
|
||||
..........66..-.....................*.......*....*...........................380%.....$.........*..........899*..118..............*.........
|
||||
............*..694........382....793.........668.92.....747.......49.....&..........#.....284...462....303........*....518......50.....798..
|
||||
...*146..642.......@880...*............79=.............*.....93....&...885...785..780.......*..........=...-.....663..................*.....
|
||||
533...........996.........352..................619%...200......+......................142....408....=....634............379*491.588@..183...
|
||||
........$127........970...............902..........................943.649............$..........909.........619............................
|
||||
................-..*....640............*.......-459..#.....446......&.....*.934.....#....313............/....*........509...473..901....132.
|
||||
..........*..415..805..*.....786.....12...............863...*...........674....$...296.....&...474......281...326.......&....*......$.......
|
||||
........909...........136.......@.........645................961................................/...250...............$................*554.
|
||||
...*.........589....................253..../...166.....&429.........96......568*684.%186...............*958........678..............466.....
|
||||
.759............*96..........658.......*......*...............105...-....................428.............................=...73.............
|
||||
......54*...................+......168.592..536.=................*8...671........753+.......*.................74........564....*............
|
||||
.304.....728..764................=...*...........804.575....266........*.....................94......27.316....=.-644.*.......209...485.....
|
||||
.....997.......*.........#....792...855.................#......*169...496./615........683.......225.*..................474............$.395.
|
||||
............573....206.477...................*158..........702....................298../......*...=..100....................714.........*...
|
||||
448...............*..................769...27........691..$.......178....675......*........980.28...............*727...%.....@...201.545....
|
||||
............223...561..........261.....*.............*................+...........610.250....................496......408..........*........
|
||||
....@775.....*............&.....@....195..........303..+.............141..865..............629..+....659...................855*....958......
|
||||
...........407........92...22................493......605..................@..........477...*....160...................743.....163..........
|
||||
......................../......*......602@......=..+.......*....668$..245................*...731..........69.....213.....*........./....%...
|
||||
................213*........903.75..........64......945...221.........+.......740........739..........393*...301*......562...../...53...4...
|
||||
...164&.....145.....580.......................*................425........900......828*............................*........536.............
|
||||
...............*.....................91....185..................../....................85.................414...890.204.....................
|
||||
....772............422..*.351...218..................584................263...849...............*...639*.....*..............................
|
||||
.......*307...897...*..28.*........*.*49.......300....=../72...........%......*.....544......974..@.....214...55.......347.............914..
|
||||
901............*..67......840...343.........................................447....*...............400...................*..................
|
||||
.......684..498.........*......................544...347..+........493.............612..........59.........741..........593.........416*....
|
||||
..........*........369.577........690...770....*......*..983.*160....#.................623*248.#......437..*........258.................275.
|
||||
....+...603....+...*............./......*...913....609.................823........................62.%....83...........&....................
|
||||
....538.....356..=..117......-.........556................................*..............920.......*...............746......................
|
||||
................483.......197...................&....................231...210......92....*.....982..&......199....$........848.$.....$.....
|
||||
...370..413.........$.............*............556........325...902@....$..........@...182..........933................*.....&...829.402....
|
||||
......*..%...........524.131..134..163.....185...............*...............................756........282&.774......822...................
|
||||
....340....373...*...............*...........*....649.20....289....799..549.939.....120..........61............*..345.......778...550.267...
|
||||
............&...699......&319..170...492....61.....*.......................*.....+.................*.........345.....@........*...+.........
|
||||
534.............................................144..849.......174......*........219.....$......140...476..................970..............
|
||||
.../....681............444.....819$...................*..=305../.....413.95...............589.................229...235................644..
|
||||
...........-.....28.......*403................&....548.............&...........17..........................33..........+........962.........
|
||||
373..........500....%429.....................291........*....881.296.....163*....*..............796...585....&.............802..*.......138.
|
||||
................*..................983&................809.....*.............417.999....$.......*...............633.........*...322....*....
|
||||
......907..$921.............665...........731...............903.........................638..662..............-..........495.........130.9..
|
||||
.........*......168............&..353.....-..........639.........#...........349......................660....914...570......................
|
||||
...%......695..*....679...........=..........$...958.+.....494..369..........*...........................*44........*.........964......548..
|
||||
...826.........268..*.....675..............136....-...................650.964....728.823.403..................842.983..........*......*.....
|
||||
...................328................................519.....210.......................*....143.....*46....../.................241..55.....
|
||||
.......855$...199.......526.....849...764*294..........#.....*.....280..........261.885.........#.434...................610.................
|
||||
...............=...............+...................498.......936......*..831.......*.......&...........462.939+..439.......*845.....443.....
|
||||
.....@360.842......986%.902-.....21.307....234*......*...324.......505....*.............315..............*.............................*....
|
||||
..........*....................*.*....*..............42..*................474...../919................50.674..713................./..27.....
|
||||
........249....291...........448.622..228.......308.........189...............629........-...................*............594..127......782.
|
||||
..................*173..817.....................*.......91.....*..#................*649...492...400.........17...878.....*..........950.....
|
||||
...32.674......-........%.....402/...........610..%.....*.....549..853...........96.................=.............*....779.......@..........
|
||||
.............885.................................600.456...........................................679.............16.........392.....841...
|
||||
14
2023/days/03/src/main.rs
Normal file
14
2023/days/03/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
560
2023/days/03/src/parse.rs
Normal file
560
2023/days/03/src/parse.rs
Normal file
|
|
@ -0,0 +1,560 @@
|
|||
use std::{iter, ops::Range};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct PartNumber {
|
||||
pub number: usize,
|
||||
pub x: Range<usize>,
|
||||
pub y: usize,
|
||||
}
|
||||
|
||||
impl PartNumber {
|
||||
fn is_adjacent_to_symbol(&self, symbol: &Symbol) -> bool {
|
||||
(self.x.start.saturating_sub(1)..=self.x.end).contains(&symbol.x)
|
||||
&& (self.y.saturating_sub(1)..=self.y + 1).contains(&symbol.y)
|
||||
}
|
||||
|
||||
pub fn is_ajacent_to_any_symbol(&self, symbols: &[Symbol]) -> bool {
|
||||
symbols
|
||||
.iter()
|
||||
.any(|symbol| self.is_adjacent_to_symbol(symbol))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Symbol {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
pub char: char,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
fn ajacent_part_numbers(&self, part_numbers: &[PartNumber]) -> Vec<usize> {
|
||||
part_numbers
|
||||
.iter()
|
||||
.filter(|pn| pn.is_adjacent_to_symbol(self))
|
||||
.map(|pn| pn.number)
|
||||
.collect()
|
||||
}
|
||||
pub fn gear_ratio(&self, part_numbers: &[PartNumber]) -> Option<usize> {
|
||||
if self.char != '*' {
|
||||
return None;
|
||||
}
|
||||
let ajacent_parts = self.ajacent_part_numbers(part_numbers);
|
||||
if ajacent_parts.len() != 2{
|
||||
return None;
|
||||
}
|
||||
Some(ajacent_parts.iter().product())
|
||||
}
|
||||
}
|
||||
|
||||
pub type StructuredInput = (Vec<PartNumber>, Vec<Symbol>);
|
||||
|
||||
pub fn parse(input: &str) -> StructuredInput {
|
||||
let mut part_numbers = vec![];
|
||||
let mut symbols = vec![];
|
||||
for (y, line) in input.lines().enumerate() {
|
||||
let mut length: usize = 0;
|
||||
let mut number: Option<usize> = None;
|
||||
for (x, char) in line.chars().chain(iter::once('.')).enumerate() {
|
||||
if let Some(digit) = char.to_digit(10) {
|
||||
length += 1;
|
||||
// this essentially 'shifts' the number left if it already exists.
|
||||
number = number.map_or(Some(digit as usize), |n| Some(n * 10 + digit as usize))
|
||||
} else {
|
||||
if char != '.' {
|
||||
symbols.push(Symbol { x, y, char })
|
||||
}
|
||||
// if number is not none, we must have just 'left' a number.
|
||||
if let Some(number) = number {
|
||||
part_numbers.push(PartNumber {
|
||||
number,
|
||||
x: (x - length)..x,
|
||||
y,
|
||||
})
|
||||
}
|
||||
number = None;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
(part_numbers, symbols)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_gear_ratio() {
|
||||
let partnums = vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
];
|
||||
let symbols = vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
];
|
||||
assert_eq!(symbols[0].gear_ratio(&partnums), Some(467*35));
|
||||
assert_eq!(symbols[1].gear_ratio(&partnums), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num_ajacent_parts() {
|
||||
let partnums = vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
];
|
||||
let symbols = vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
];
|
||||
assert_eq!(symbols[0].ajacent_part_numbers(&partnums), [467, 35]);
|
||||
assert_eq!(symbols[1].ajacent_part_numbers(&partnums), [633]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_ajacent_to_symbol() {
|
||||
let partnums = vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
];
|
||||
let symbols = vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
];
|
||||
assert!(partnums[0].is_adjacent_to_symbol(&symbols[0]));
|
||||
assert!(!partnums[0].is_adjacent_to_symbol(&symbols[1]));
|
||||
assert!(partnums[3].is_adjacent_to_symbol(&symbols[1]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_ajacent_to_any_symbol() {
|
||||
let partnums = vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
];
|
||||
let symbols = vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
];
|
||||
assert!(partnums[0].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(!partnums[1].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[2].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[3].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[4].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(!partnums[5].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[6].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[7].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[8].is_ajacent_to_any_symbol(&symbols));
|
||||
assert!(partnums[9].is_ajacent_to_any_symbol(&symbols));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"467..114..\n",
|
||||
"...*......\n",
|
||||
"..35..633.\n",
|
||||
"......#...\n",
|
||||
"617*......\n",
|
||||
".....+.58.\n",
|
||||
"..592.....\n",
|
||||
"......755.\n",
|
||||
"...$.*....\n",
|
||||
".664.598..\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
(
|
||||
vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9
|
||||
}
|
||||
],
|
||||
vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*'
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#'
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*'
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+'
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$'
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*'
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
106
2023/days/03/src/part1.rs
Normal file
106
2023/days/03/src/part1.rs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &StructuredInput) -> usize {
|
||||
input
|
||||
.0
|
||||
.iter()
|
||||
.filter(|pn| pn.is_ajacent_to_any_symbol(&input.1))
|
||||
.map(|pn| pn.number)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = (
|
||||
vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
],
|
||||
vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part1(&input), 4361);
|
||||
}
|
||||
}
|
||||
105
2023/days/03/src/part2.rs
Normal file
105
2023/days/03/src/part2.rs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &StructuredInput) -> usize {
|
||||
input
|
||||
.1
|
||||
.iter()
|
||||
.filter_map(|symbol| symbol.gear_ratio(&input.0))
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = (
|
||||
vec![
|
||||
PartNumber {
|
||||
number: 467,
|
||||
x: 0..3,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 114,
|
||||
x: 5..8,
|
||||
y: 0,
|
||||
},
|
||||
PartNumber {
|
||||
number: 35,
|
||||
x: 2..4,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 633,
|
||||
x: 6..9,
|
||||
y: 2,
|
||||
},
|
||||
PartNumber {
|
||||
number: 617,
|
||||
x: 0..3,
|
||||
y: 4,
|
||||
},
|
||||
PartNumber {
|
||||
number: 58,
|
||||
x: 7..9,
|
||||
y: 5,
|
||||
},
|
||||
PartNumber {
|
||||
number: 592,
|
||||
x: 2..5,
|
||||
y: 6,
|
||||
},
|
||||
PartNumber {
|
||||
number: 755,
|
||||
x: 6..9,
|
||||
y: 7,
|
||||
},
|
||||
PartNumber {
|
||||
number: 664,
|
||||
x: 1..4,
|
||||
y: 9,
|
||||
},
|
||||
PartNumber {
|
||||
number: 598,
|
||||
x: 5..8,
|
||||
y: 9,
|
||||
},
|
||||
],
|
||||
vec![
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 1,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 6,
|
||||
y: 3,
|
||||
char: '#',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 4,
|
||||
char: '*',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 5,
|
||||
char: '+',
|
||||
},
|
||||
Symbol {
|
||||
x: 3,
|
||||
y: 8,
|
||||
char: '$',
|
||||
},
|
||||
Symbol {
|
||||
x: 5,
|
||||
y: 8,
|
||||
char: '*',
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part2(&input), 467835);
|
||||
}
|
||||
}
|
||||
11
2023/days/04/Cargo.toml
Normal file
11
2023/days/04/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day04"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace = true
|
||||
collection_literals.workspace = true
|
||||
193
2023/days/04/src/input.txt
Normal file
193
2023/days/04/src/input.txt
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
Card 1: 17 15 5 75 36 13 16 66 92 39 | 13 92 16 5 87 78 15 94 21 48 30 62 70 41 3 39 22 17 77 58 75 52 83 34 24
|
||||
Card 2: 72 64 18 5 58 94 25 59 75 51 | 34 17 48 75 25 8 2 94 64 29 33 92 73 12 51 38 27 4 1 60 31 85 59 18 5
|
||||
Card 3: 71 16 97 6 68 38 82 93 33 24 | 31 75 7 99 10 70 79 61 5 80 1 33 58 30 22 48 73 72 50 16 56 4 98 43 3
|
||||
Card 4: 68 80 44 96 43 20 11 18 85 48 | 96 99 38 29 36 28 77 68 47 70 98 80 63 65 11 12 43 3 54 92 18 90 58 16 51
|
||||
Card 5: 27 61 28 60 50 59 43 96 85 9 | 3 45 14 55 39 6 93 82 96 31 70 22 8 98 88 46 72 9 79 28 23 81 87 15 30
|
||||
Card 6: 32 69 24 83 40 39 19 42 17 11 | 68 26 28 71 22 50 64 20 53 82 7 36 58 78 73 51 6 48 97 30 99 61 84 34 5
|
||||
Card 7: 99 14 25 95 31 62 1 65 59 30 | 8 9 58 73 6 2 44 11 43 4 34 70 78 90 16 24 23 39 30 69 74 59 91 84 42
|
||||
Card 8: 88 48 85 67 73 33 96 57 47 86 | 35 17 85 97 46 50 77 23 4 31 76 34 12 59 14 42 72 64 44 96 90 65 73 69 88
|
||||
Card 9: 99 17 38 77 73 71 59 86 11 97 | 60 14 19 4 6 78 51 48 87 36 88 66 30 13 94 45 97 69 62 40 47 32 7 77 57
|
||||
Card 10: 82 35 83 64 60 84 67 62 24 77 | 93 32 7 12 84 24 94 43 65 44 17 45 38 62 80 95 77 26 73 28 91 57 60 55 4
|
||||
Card 11: 9 95 29 15 88 33 58 49 83 45 | 31 38 55 62 86 60 21 97 74 53 94 19 40 50 77 26 63 43 3 52 85 8 73 35 42
|
||||
Card 12: 54 33 34 57 29 64 40 30 3 11 | 78 86 92 70 91 93 32 79 12 13 97 63 28 66 77 85 51 36 35 3 4 23 30 11 42
|
||||
Card 13: 16 49 93 29 96 23 64 57 3 42 | 56 11 53 20 72 67 26 5 4 63 8 70 97 52 6 81 62 80 12 98 33 35 77 84 58
|
||||
Card 14: 20 32 49 55 63 74 33 51 66 40 | 43 29 70 48 61 13 96 73 67 27 15 6 46 56 45 30 97 76 1 77 12 26 39 78 42
|
||||
Card 15: 65 67 7 43 83 36 24 46 16 29 | 76 12 69 27 26 71 84 11 22 86 33 63 50 49 14 40 6 4 47 34 90 21 19 74 97
|
||||
Card 16: 78 43 11 21 53 35 86 85 27 68 | 98 43 53 66 52 62 21 91 81 69 93 76 73 86 17 31 27 40 85 12 68 83 65 36 71
|
||||
Card 17: 52 55 3 69 20 96 57 67 10 38 | 91 16 3 30 52 34 78 71 55 36 48 89 79 20 37 69 67 57 18 68 46 10 25 38 96
|
||||
Card 18: 23 46 90 44 85 19 49 30 8 43 | 72 34 75 48 74 33 88 41 78 65 98 60 3 19 26 63 69 83 89 21 66 5 37 53 58
|
||||
Card 19: 69 24 83 60 59 45 51 74 93 34 | 45 83 1 8 28 60 27 38 81 36 69 24 73 90 88 59 93 16 98 34 74 48 10 61 51
|
||||
Card 20: 41 83 4 44 28 90 16 69 86 88 | 7 41 28 4 5 73 97 30 70 88 69 2 38 55 86 60 14 83 16 90 15 49 78 44 27
|
||||
Card 21: 41 61 99 59 48 8 26 92 19 85 | 35 17 49 14 94 6 29 43 55 88 63 26 13 53 66 67 8 32 18 24 7 70 86 96 38
|
||||
Card 22: 57 29 37 75 42 88 68 67 92 18 | 8 6 54 77 75 18 68 26 67 87 92 31 72 29 37 21 42 17 88 93 84 57 9 63 66
|
||||
Card 23: 70 3 75 17 64 68 53 45 23 10 | 27 7 59 68 97 72 64 30 61 29 86 45 63 53 17 3 44 87 23 75 70 10 15 4 43
|
||||
Card 24: 89 81 36 9 73 27 31 8 77 11 | 14 71 9 87 47 39 26 29 24 74 42 58 17 51 19 68 32 46 52 78 64 12 35 45 72
|
||||
Card 25: 82 3 92 95 29 14 52 41 15 98 | 21 17 51 55 77 34 72 59 78 30 5 58 92 4 85 15 91 75 26 53 25 94 7 90 22
|
||||
Card 26: 51 55 33 59 66 42 43 92 85 96 | 2 66 92 24 50 33 63 96 54 51 13 1 42 98 73 88 57 84 94 7 93 78 59 43 55
|
||||
Card 27: 19 80 30 31 15 4 65 13 66 29 | 93 75 36 26 5 14 21 49 97 43 96 54 45 57 25 55 71 95 1 27 60 61 9 59 34
|
||||
Card 28: 57 79 99 54 72 18 33 34 87 1 | 56 99 55 17 87 80 72 79 88 31 38 63 42 33 10 23 76 4 67 21 98 68 93 57 65
|
||||
Card 29: 85 26 24 34 21 35 49 92 89 73 | 70 39 73 44 67 50 43 63 4 82 14 64 22 25 2 41 8 36 89 10 54 79 87 40 6
|
||||
Card 30: 21 33 62 4 57 9 50 49 95 13 | 12 84 86 49 26 42 20 37 30 57 44 96 62 6 4 65 15 59 60 73 19 28 89 39 55
|
||||
Card 31: 7 61 76 92 70 15 45 71 98 20 | 4 33 26 63 73 52 7 3 62 60 89 28 86 55 45 90 41 83 74 31 48 27 11 65 72
|
||||
Card 32: 9 35 67 79 85 46 14 42 84 45 | 63 51 64 5 81 70 36 47 33 30 54 83 85 34 35 32 1 79 7 96 82 28 3 89 91
|
||||
Card 33: 76 48 44 64 41 62 4 25 11 8 | 15 22 10 80 59 82 89 81 2 57 31 25 50 34 53 39 86 19 47 95 23 30 88 91 51
|
||||
Card 34: 17 12 86 82 70 16 19 11 42 57 | 78 49 72 18 25 35 58 81 26 6 84 87 67 60 61 13 53 56 4 14 90 11 29 34 33
|
||||
Card 35: 16 65 64 28 25 50 73 95 20 10 | 6 4 12 77 41 98 2 74 29 15 52 91 83 49 14 40 69 88 82 22 21 89 9 70 90
|
||||
Card 36: 68 38 59 63 30 32 14 97 77 17 | 6 23 49 75 12 76 58 22 74 29 24 48 56 54 41 26 69 90 70 93 66 42 78 33 60
|
||||
Card 37: 49 37 88 55 20 95 11 86 53 18 | 53 95 18 80 25 2 88 17 11 20 22 63 45 70 55 37 86 81 28 61 47 74 49 79 48
|
||||
Card 38: 82 38 13 70 48 52 91 6 46 47 | 6 91 78 43 16 48 61 29 80 92 82 13 44 90 9 87 40 54 52 46 58 38 70 65 47
|
||||
Card 39: 82 50 67 89 49 18 24 93 98 76 | 95 61 1 91 52 86 89 53 38 98 44 67 50 49 33 66 21 18 93 82 60 76 40 24 19
|
||||
Card 40: 15 34 17 87 51 5 98 26 71 99 | 15 40 70 98 96 1 45 14 94 28 39 87 56 51 89 17 77 64 26 5 99 71 83 27 34
|
||||
Card 41: 1 98 55 28 10 14 57 62 88 96 | 96 52 8 34 88 41 73 23 16 43 98 45 55 97 1 14 28 10 62 81 33 57 32 53 99
|
||||
Card 42: 98 75 42 34 59 41 11 69 45 44 | 28 98 54 65 41 51 16 49 45 60 44 69 82 37 67 46 34 71 78 61 50 43 38 90 85
|
||||
Card 43: 42 98 96 75 68 2 23 36 37 40 | 93 59 36 33 16 68 24 42 13 75 53 2 6 86 1 98 23 70 89 5 37 40 96 84 39
|
||||
Card 44: 44 31 83 28 66 80 84 17 73 65 | 39 73 95 33 74 66 31 28 17 2 65 12 84 91 83 15 22 44 53 90 29 56 80 57 69
|
||||
Card 45: 13 90 67 40 48 54 52 53 64 9 | 17 57 67 65 45 30 95 96 3 18 52 90 7 98 21 73 8 92 59 75 5 13 6 76 64
|
||||
Card 46: 95 21 68 93 77 40 47 48 20 31 | 74 90 43 4 41 40 24 72 2 56 88 44 38 45 15 29 79 46 17 39 75 42 69 92 49
|
||||
Card 47: 25 87 64 94 99 47 29 34 89 23 | 29 25 99 58 94 7 33 6 34 36 76 5 39 64 56 87 17 52 47 50 89 16 91 23 69
|
||||
Card 48: 37 75 82 29 91 2 85 23 76 80 | 23 33 80 85 89 46 94 15 2 43 51 62 91 79 37 76 29 56 40 26 9 63 75 82 31
|
||||
Card 49: 99 80 21 7 14 27 24 13 76 70 | 36 32 16 28 30 37 73 59 42 47 40 29 19 84 18 23 79 44 93 45 87 62 60 69 65
|
||||
Card 50: 89 87 92 61 59 58 90 24 70 22 | 3 81 53 61 55 82 52 85 66 44 74 98 6 56 33 13 63 25 65 67 47 26 35 27 64
|
||||
Card 51: 65 15 62 72 92 57 1 87 55 86 | 1 47 49 98 93 38 53 68 96 59 11 4 52 84 86 94 51 13 95 29 65 16 91 45 54
|
||||
Card 52: 3 72 69 39 77 36 55 13 56 95 | 35 61 77 36 40 65 64 13 58 27 55 12 94 66 42 37 5 78 62 84 56 39 69 95 48
|
||||
Card 53: 78 57 27 16 17 55 59 56 73 40 | 65 31 20 18 64 89 44 52 92 11 62 76 13 48 72 79 94 8 82 77 5 74 30 46 98
|
||||
Card 54: 22 17 28 78 59 87 52 47 41 2 | 74 94 38 25 58 89 20 99 71 14 86 95 10 63 18 35 24 67 85 80 7 50 6 33 72
|
||||
Card 55: 78 83 54 87 55 68 77 38 34 48 | 87 23 51 75 83 86 43 93 18 34 53 56 76 72 29 27 45 85 89 36 65 84 19 88 39
|
||||
Card 56: 50 89 10 79 86 37 27 16 56 54 | 2 59 91 50 8 39 90 46 37 36 27 15 10 9 85 92 83 35 45 74 19 61 63 17 96
|
||||
Card 57: 50 39 84 22 17 73 57 77 80 85 | 8 57 15 74 38 83 32 67 99 28 63 16 30 49 75 26 55 48 47 91 33 14 62 21 20
|
||||
Card 58: 63 26 97 45 9 24 65 66 59 14 | 42 81 39 62 45 46 23 49 98 34 72 64 17 11 96 15 6 88 78 93 20 33 66 95 37
|
||||
Card 59: 46 91 3 4 70 21 2 13 19 10 | 95 56 84 16 66 7 91 11 69 89 87 29 60 47 37 40 15 55 38 80 20 81 23 64 18
|
||||
Card 60: 32 65 89 23 54 36 49 18 26 78 | 16 11 14 20 76 33 72 45 94 87 85 2 74 99 3 67 57 37 75 96 82 95 73 77 52
|
||||
Card 61: 41 42 4 27 89 64 80 28 35 92 | 97 50 88 13 19 45 49 42 85 36 4 92 29 80 77 47 91 27 46 89 68 16 35 11 28
|
||||
Card 62: 30 27 17 63 59 11 78 74 75 57 | 88 57 5 61 1 56 24 99 10 39 48 15 89 82 95 9 45 71 54 83 3 28 27 98 91
|
||||
Card 63: 86 91 21 10 84 47 83 62 90 35 | 11 16 90 10 31 84 36 74 89 5 35 47 21 40 62 63 77 67 65 83 91 86 70 85 44
|
||||
Card 64: 39 55 92 80 17 2 66 97 33 70 | 92 22 85 6 88 4 46 57 71 40 89 15 49 48 66 11 93 28 37 5 30 23 27 98 43
|
||||
Card 65: 62 94 36 40 23 61 34 46 47 63 | 6 44 23 74 97 96 62 94 61 46 93 34 47 31 87 54 26 67 56 40 27 81 63 99 36
|
||||
Card 66: 64 45 78 34 32 29 62 84 90 28 | 42 6 80 66 10 13 41 55 50 40 72 90 25 24 93 98 46 73 52 14 61 86 49 89 71
|
||||
Card 67: 9 89 2 82 42 8 78 90 59 7 | 69 55 58 2 95 78 43 26 11 75 50 22 44 4 9 59 82 68 19 32 63 49 35 42 45
|
||||
Card 68: 72 9 87 26 17 43 58 8 45 74 | 8 85 9 7 73 21 92 74 28 5 33 25 50 60 26 1 65 78 24 69 87 19 46 58 67
|
||||
Card 69: 51 69 81 71 32 59 85 29 39 5 | 68 16 31 47 29 86 50 62 98 14 22 80 56 91 35 49 51 21 36 67 52 6 15 48 58
|
||||
Card 70: 67 1 31 29 16 71 69 54 15 11 | 91 49 76 87 14 13 58 23 19 20 82 48 98 79 66 35 38 22 67 96 43 55 52 92 12
|
||||
Card 71: 73 20 52 53 61 17 87 78 82 37 | 28 21 95 74 77 58 25 84 68 75 47 49 9 18 65 51 63 12 56 50 98 23 57 69 90
|
||||
Card 72: 39 66 35 93 62 28 9 13 56 30 | 29 1 39 54 10 33 40 99 91 65 16 28 37 23 77 43 61 64 11 55 69 85 63 47 78
|
||||
Card 73: 9 10 84 56 6 14 54 36 94 61 | 89 33 88 23 87 46 47 31 55 29 69 90 11 65 19 84 35 2 32 95 80 12 3 7 50
|
||||
Card 74: 59 27 84 1 11 63 39 57 62 65 | 41 75 83 51 13 91 93 79 66 23 70 86 16 52 26 50 72 5 48 80 74 47 38 97 8
|
||||
Card 75: 38 65 93 30 12 64 31 10 37 81 | 8 76 72 3 52 89 32 60 73 40 85 55 49 43 45 42 83 58 61 47 86 67 82 94 50
|
||||
Card 76: 26 83 4 70 88 7 50 34 36 76 | 64 49 4 77 83 39 34 50 79 24 22 6 70 85 7 75 80 26 38 36 68 63 29 17 88
|
||||
Card 77: 31 97 45 39 24 5 87 26 75 15 | 38 36 10 57 39 8 45 74 24 94 31 17 25 27 92 75 60 87 12 26 69 15 70 63 7
|
||||
Card 78: 44 21 15 91 62 67 47 24 95 90 | 26 1 62 42 71 43 91 95 59 37 16 3 56 14 21 15 17 87 86 51 39 19 46 36 4
|
||||
Card 79: 67 84 14 87 21 22 91 17 88 72 | 92 82 94 31 85 54 55 93 46 35 77 67 74 96 36 50 68 19 3 40 15 69 72 6 49
|
||||
Card 80: 11 36 90 64 51 31 83 30 18 69 | 36 86 90 43 8 3 65 49 31 78 30 18 79 52 51 88 80 63 24 77 16 1 13 83 55
|
||||
Card 81: 47 2 72 59 87 30 58 68 63 61 | 55 49 42 39 99 94 50 72 90 54 29 37 21 41 48 8 82 7 63 30 62 70 87 26 14
|
||||
Card 82: 22 17 64 40 89 67 83 71 43 50 | 89 12 52 32 42 78 38 3 51 26 2 67 96 81 77 13 48 7 73 28 62 1 82 22 24
|
||||
Card 83: 53 4 35 89 23 36 8 92 32 49 | 35 52 92 73 23 64 80 32 53 4 65 20 42 31 8 39 89 95 62 44 45 77 36 68 49
|
||||
Card 84: 86 48 90 55 79 57 31 40 3 74 | 85 67 62 4 33 23 60 43 19 14 32 34 6 56 59 9 87 47 54 26 88 66 65 41 11
|
||||
Card 85: 82 66 31 3 87 19 89 57 59 8 | 15 8 31 58 53 22 89 59 63 96 40 85 3 82 35 33 49 30 75 87 66 64 83 57 19
|
||||
Card 86: 22 4 55 97 13 54 65 51 86 9 | 11 73 5 63 36 23 27 13 15 75 22 85 38 99 54 44 32 41 12 47 82 51 8 77 17
|
||||
Card 87: 27 91 1 77 75 8 76 99 88 85 | 55 46 50 2 4 27 54 10 89 3 14 91 22 75 13 77 8 6 76 69 44 19 88 1 99
|
||||
Card 88: 54 96 19 2 73 48 50 82 18 23 | 95 12 16 73 35 48 60 31 50 98 19 17 32 47 2 55 44 93 11 41 23 82 74 9 51
|
||||
Card 89: 91 89 35 65 33 19 94 76 77 45 | 99 32 96 64 31 44 45 80 71 51 83 97 21 5 20 35 40 93 39 54 29 56 23 70 66
|
||||
Card 90: 31 87 35 2 89 24 59 13 4 15 | 18 87 65 59 71 31 98 26 68 96 3 13 80 36 25 47 2 4 7 37 92 83 73 23 58
|
||||
Card 91: 28 85 49 44 87 17 56 74 25 53 | 96 23 18 27 17 72 84 29 32 85 91 86 62 94 55 49 37 56 28 59 78 88 25 1 30
|
||||
Card 92: 1 94 54 67 51 21 79 6 93 5 | 9 51 13 91 68 59 19 41 76 20 57 55 54 72 48 21 83 95 44 56 71 80 28 85 25
|
||||
Card 93: 53 86 2 60 56 18 21 22 63 59 | 79 86 73 9 32 80 7 76 26 63 48 17 90 36 91 31 69 50 49 87 37 43 92 10 55
|
||||
Card 94: 91 59 76 78 48 56 7 51 52 97 | 36 15 31 62 65 64 34 79 92 53 29 60 9 3 75 26 14 46 59 35 85 52 2 77 67
|
||||
Card 95: 59 49 67 43 82 13 19 7 58 69 | 5 65 21 86 4 3 64 72 51 94 73 88 78 98 28 85 29 96 36 1 97 37 89 62 58
|
||||
Card 96: 95 88 64 65 12 15 3 50 44 79 | 53 72 74 60 22 7 75 19 10 3 49 23 33 29 57 31 82 84 16 37 32 21 77 28 47
|
||||
Card 97: 3 85 7 2 51 27 67 32 46 9 | 60 45 11 49 13 62 76 56 63 1 37 96 20 55 24 89 31 50 19 10 6 72 30 38 54
|
||||
Card 98: 25 92 5 7 90 2 84 79 34 65 | 30 20 86 33 63 84 65 92 38 5 43 12 2 73 98 81 82 94 51 25 88 75 54 22 15
|
||||
Card 99: 59 57 36 90 26 81 15 78 49 2 | 81 26 91 47 77 46 65 59 90 57 72 99 2 98 15 5 78 36 49 63 45 9 16 92 64
|
||||
Card 100: 18 9 41 19 57 82 73 48 62 2 | 41 42 3 82 73 83 91 48 94 96 20 9 19 90 45 54 13 67 62 44 37 51 18 2 57
|
||||
Card 101: 56 35 62 52 89 60 19 71 15 50 | 60 21 39 71 45 64 73 25 80 54 50 13 6 20 1 51 42 93 92 87 96 61 16 77 40
|
||||
Card 102: 40 33 78 80 79 47 57 3 17 64 | 85 17 94 78 20 47 58 3 37 40 68 75 81 79 21 64 97 70 80 33 8 57 95 35 4
|
||||
Card 103: 99 22 60 2 93 8 46 50 90 79 | 46 2 67 62 30 93 50 99 79 8 33 34 81 98 90 78 60 92 42 80 28 89 22 16 74
|
||||
Card 104: 93 3 98 99 1 90 20 70 67 91 | 98 85 78 51 26 71 10 92 90 35 94 66 21 1 70 18 13 93 8 91 5 4 50 33 15
|
||||
Card 105: 63 86 21 98 76 18 35 7 23 41 | 88 86 53 89 31 67 55 82 3 35 18 32 76 42 23 98 7 27 79 41 14 71 83 6 93
|
||||
Card 106: 71 48 3 34 73 72 85 76 69 66 | 66 7 22 76 65 25 46 69 96 34 3 35 14 45 21 23 36 5 17 60 98 71 33 93 59
|
||||
Card 107: 49 42 7 79 31 18 97 45 6 36 | 6 43 18 51 1 39 36 76 92 88 59 26 45 5 73 7 97 55 44 21 31 49 82 42 79
|
||||
Card 108: 48 16 51 41 23 59 65 80 89 26 | 1 75 35 5 80 2 51 23 45 16 30 44 26 89 64 65 91 11 59 48 69 21 77 93 41
|
||||
Card 109: 70 63 17 48 93 67 59 22 16 89 | 28 48 22 16 79 56 21 19 89 62 67 4 17 64 49 63 59 93 60 70 1 7 43 94 81
|
||||
Card 110: 89 87 31 97 33 7 66 96 24 37 | 5 8 53 71 99 96 88 74 39 20 62 67 11 64 70 47 37 95 77 86 27 61 97 89 60
|
||||
Card 111: 27 48 31 61 39 80 81 36 87 12 | 80 43 5 12 84 67 70 91 8 39 10 48 61 27 86 16 54 22 40 90 9 36 87 44 81
|
||||
Card 112: 20 22 17 89 26 55 43 49 75 30 | 51 58 71 28 29 15 26 8 99 48 61 4 54 75 13 46 78 68 86 22 56 20 33 69 65
|
||||
Card 113: 18 40 34 27 32 15 65 19 60 87 | 32 34 60 90 24 92 51 2 91 35 27 14 15 93 88 75 48 58 65 97 87 63 94 55 56
|
||||
Card 114: 46 19 51 7 25 85 30 73 31 27 | 40 25 90 58 2 12 59 68 8 9 88 21 63 46 37 51 52 75 84 89 93 3 20 87 80
|
||||
Card 115: 70 81 83 98 66 69 72 44 1 45 | 30 40 13 80 55 77 7 85 97 18 78 53 59 31 9 45 6 21 16 63 65 27 33 49 90
|
||||
Card 116: 89 46 58 68 38 59 13 85 28 92 | 59 81 23 86 18 6 73 78 11 74 48 40 13 97 27 52 38 9 16 47 26 29 54 60 14
|
||||
Card 117: 43 38 54 63 44 95 4 64 25 57 | 43 44 94 58 54 51 56 21 6 89 30 31 8 11 46 53 5 79 16 72 90 76 67 49 34
|
||||
Card 118: 47 72 23 74 29 37 45 69 89 40 | 27 79 36 40 10 87 92 41 22 1 90 21 57 28 38 53 82 32 43 70 19 96 97 4 47
|
||||
Card 119: 11 81 28 95 53 51 90 33 8 68 | 88 74 49 27 58 57 97 4 34 2 18 22 29 99 66 28 55 7 94 41 24 60 5 14 1
|
||||
Card 120: 9 67 89 55 59 96 15 90 37 54 | 70 98 77 71 6 95 34 60 48 18 69 72 36 35 22 27 76 83 30 99 80 63 12 47 82
|
||||
Card 121: 63 50 70 62 14 22 97 65 5 53 | 24 99 55 58 47 87 77 37 5 19 83 33 42 40 45 54 46 62 28 81 95 85 23 57 49
|
||||
Card 122: 40 80 69 62 14 73 47 87 91 37 | 16 47 37 93 40 91 34 17 36 98 69 60 15 49 90 92 80 87 14 62 82 4 25 56 73
|
||||
Card 123: 51 36 72 40 53 99 69 8 96 24 | 93 74 54 8 52 59 3 57 69 85 31 72 44 89 23 9 2 27 71 48 35 17 19 96 28
|
||||
Card 124: 14 75 17 70 48 82 93 39 99 98 | 66 55 6 33 34 32 25 65 20 86 90 87 93 46 42 89 24 43 23 30 64 94 62 61 5
|
||||
Card 125: 36 96 78 58 75 87 25 28 76 52 | 7 47 46 13 3 90 35 18 53 60 30 78 74 77 33 58 22 57 80 63 92 87 76 93 70
|
||||
Card 126: 75 30 35 7 63 65 13 42 78 26 | 30 71 35 26 6 42 90 63 12 36 75 9 7 96 67 93 18 2 25 77 94 47 99 62 60
|
||||
Card 127: 7 40 79 33 52 3 21 1 71 5 | 44 14 19 29 56 25 34 41 64 12 93 70 66 94 54 97 58 59 18 27 77 17 15 38 88
|
||||
Card 128: 99 87 2 95 67 33 73 52 22 23 | 65 91 97 11 34 36 56 38 79 52 82 22 26 83 12 1 95 9 23 99 81 42 92 27 86
|
||||
Card 129: 98 68 59 25 58 27 20 23 38 46 | 97 91 59 41 70 18 36 38 46 42 58 48 53 60 81 75 83 23 15 86 89 68 69 39 88
|
||||
Card 130: 85 72 65 71 14 25 22 53 12 28 | 67 9 27 94 96 30 86 83 4 59 91 79 7 60 31 39 36 77 23 38 40 51 84 16 57
|
||||
Card 131: 6 77 45 51 48 46 21 52 84 62 | 70 74 83 39 26 27 86 96 56 33 79 18 76 34 22 32 68 59 35 66 38 71 3 20 88
|
||||
Card 132: 66 80 84 9 59 23 64 44 71 36 | 63 49 73 62 68 48 80 32 99 29 24 61 40 35 20 1 57 58 15 92 87 18 47 71 67
|
||||
Card 133: 19 94 9 45 91 35 36 60 34 26 | 72 47 82 86 88 69 6 17 7 8 21 78 90 9 12 24 85 28 15 31 98 76 35 10 39
|
||||
Card 134: 8 79 4 31 6 88 7 57 40 23 | 66 74 93 26 98 54 87 82 48 63 19 11 68 3 85 88 80 25 15 64 99 77 47 71 43
|
||||
Card 135: 86 31 63 82 83 78 19 55 20 73 | 36 98 68 52 99 8 39 60 70 80 64 41 92 91 62 85 27 32 9 97 22 46 34 23 81
|
||||
Card 136: 57 94 7 14 49 18 80 67 85 25 | 59 28 82 38 40 5 64 69 41 70 23 91 56 32 6 71 12 75 22 98 11 16 79 37 54
|
||||
Card 137: 60 88 68 93 6 98 16 17 7 62 | 59 78 54 41 98 1 66 13 71 68 45 60 70 19 96 93 77 99 95 42 55 21 30 86 7
|
||||
Card 138: 17 93 77 84 65 31 60 7 45 76 | 7 45 60 42 9 25 65 77 16 70 93 34 37 12 76 17 84 40 49 74 96 88 31 54 79
|
||||
Card 139: 15 68 80 74 33 50 57 93 78 16 | 95 96 50 71 16 99 17 58 83 72 4 80 98 11 41 63 73 62 33 37 26 70 24 29 93
|
||||
Card 140: 74 32 6 69 33 13 85 82 80 87 | 62 66 98 20 67 77 86 31 2 9 18 39 92 28 59 45 4 87 84 46 6 99 80 85 27
|
||||
Card 141: 42 52 60 31 22 99 49 61 43 72 | 55 61 81 65 97 31 60 23 6 70 62 80 58 72 56 43 98 96 87 42 53 63 52 99 45
|
||||
Card 142: 5 72 15 50 65 28 87 94 96 37 | 62 38 37 23 65 80 67 96 50 72 8 60 46 28 33 94 13 52 15 1 32 78 14 43 5
|
||||
Card 143: 57 65 29 27 41 55 94 56 73 49 | 55 84 57 56 27 72 93 41 33 28 88 75 94 51 76 98 26 32 49 36 7 44 63 20 97
|
||||
Card 144: 31 20 97 50 17 67 80 91 78 95 | 76 16 26 38 48 90 32 93 5 68 56 78 25 87 85 40 97 12 21 96 47 10 49 75 36
|
||||
Card 145: 36 58 11 92 51 32 76 39 80 62 | 6 62 37 83 40 94 81 36 2 69 45 91 8 95 78 55 27 70 22 73 53 13 67 64 63
|
||||
Card 146: 25 28 30 81 1 51 49 59 10 48 | 20 9 66 36 50 65 78 27 87 88 7 94 63 97 39 14 67 71 76 11 60 93 13 15 61
|
||||
Card 147: 18 21 81 36 33 19 99 88 24 78 | 16 19 5 40 55 12 90 44 67 20 59 71 51 32 93 2 15 22 54 87 26 92 89 49 96
|
||||
Card 148: 84 78 26 66 35 31 10 3 32 57 | 73 30 6 27 43 76 58 63 29 19 92 41 93 70 46 16 38 53 11 77 68 21 18 33 12
|
||||
Card 149: 3 20 48 92 4 37 68 54 61 42 | 64 24 23 97 65 73 1 39 14 99 51 36 2 46 30 87 79 19 49 38 52 53 40 90 88
|
||||
Card 150: 64 45 47 50 19 69 39 48 56 3 | 93 70 65 37 58 32 57 5 35 10 72 18 51 36 44 31 46 34 11 1 97 8 92 86 23
|
||||
Card 151: 29 55 30 72 6 78 56 70 36 10 | 49 28 64 13 1 24 51 5 62 17 43 48 91 38 89 59 18 54 44 86 79 46 9 53 58
|
||||
Card 152: 40 68 80 77 81 50 79 13 67 1 | 79 43 60 15 86 49 67 85 66 13 40 12 48 6 82 14 37 1 80 23 65 72 96 73 84
|
||||
Card 153: 67 29 26 94 28 52 35 69 8 81 | 35 98 78 94 11 95 87 37 42 93 82 58 4 43 47 1 19 54 3 64 7 22 27 36 74
|
||||
Card 154: 4 45 27 92 75 31 93 54 16 83 | 45 81 67 92 1 61 93 59 37 20 54 55 63 6 44 29 33 27 70 31 24 51 58 75 19
|
||||
Card 155: 17 75 37 60 72 96 40 95 3 10 | 51 58 60 40 24 2 84 37 72 41 45 78 6 28 74 64 3 75 97 89 10 96 95 83 17
|
||||
Card 156: 78 54 82 93 16 77 50 46 69 29 | 89 21 6 82 38 80 44 40 76 74 18 90 83 59 42 33 57 53 1 73 94 20 35 37 63
|
||||
Card 157: 51 24 57 3 87 90 35 27 77 34 | 12 11 7 2 84 75 6 40 23 86 91 4 32 78 83 76 48 80 8 53 98 16 38 97 79
|
||||
Card 158: 86 29 64 32 66 61 20 75 8 27 | 5 61 4 8 66 99 20 32 25 96 64 45 51 19 75 29 6 13 27 91 2 86 55 33 12
|
||||
Card 159: 59 64 39 53 10 74 35 89 84 15 | 25 1 39 49 23 90 84 61 91 30 35 76 68 24 64 6 83 15 40 54 87 98 10 52 2
|
||||
Card 160: 7 86 13 48 73 70 47 91 39 93 | 47 56 65 41 30 93 87 73 27 91 18 86 62 63 50 32 48 77 16 7 54 22 49 43 34
|
||||
Card 161: 71 95 97 94 34 37 50 98 60 28 | 78 64 99 45 40 93 31 28 24 17 56 49 18 3 25 34 59 82 97 91 68 85 75 1 96
|
||||
Card 162: 20 76 42 79 77 19 6 90 69 48 | 23 17 20 92 4 72 66 52 69 2 97 75 57 78 95 94 88 61 1 80 59 10 91 84 11
|
||||
Card 163: 63 61 5 81 67 8 30 33 2 51 | 50 53 35 67 61 84 37 97 79 49 39 34 45 17 76 41 86 81 42 14 30 38 18 8 13
|
||||
Card 164: 95 85 44 84 60 64 24 57 48 65 | 34 33 8 16 99 5 19 30 55 21 81 98 67 88 36 90 35 4 28 43 61 62 52 13 70
|
||||
Card 165: 88 31 3 71 61 37 35 51 38 76 | 42 19 63 31 40 11 56 1 27 97 22 74 79 6 4 49 35 37 45 32 93 46 52 34 24
|
||||
Card 166: 93 29 1 76 94 87 10 25 68 81 | 8 80 58 62 66 93 39 75 77 30 29 63 31 19 92 18 34 67 33 35 97 44 89 40 71
|
||||
Card 167: 48 3 58 31 26 47 66 51 35 5 | 84 33 45 90 83 9 51 68 49 29 18 50 86 25 6 34 93 82 39 24 98 23 96 89 69
|
||||
Card 168: 36 95 30 50 22 29 25 64 35 5 | 79 56 54 1 70 12 7 42 76 99 90 15 61 55 23 81 93 60 49 26 88 40 89 58 2
|
||||
Card 169: 65 35 39 95 71 16 1 6 7 34 | 59 57 27 48 97 17 87 30 75 41 19 55 99 93 54 98 86 2 81 31 4 25 69 22 39
|
||||
Card 170: 84 78 94 24 11 40 60 50 33 91 | 11 78 24 55 46 67 65 52 66 69 14 91 33 1 23 60 45 40 50 34 84 16 94 70 62
|
||||
Card 171: 38 48 45 3 11 28 43 58 4 74 | 41 21 96 58 94 97 45 95 91 28 3 43 69 70 4 99 25 48 64 38 74 86 98 11 7
|
||||
Card 172: 73 29 25 36 78 93 21 76 55 32 | 34 42 55 64 29 35 13 77 76 94 75 32 89 38 33 25 73 21 20 36 52 92 30 41 17
|
||||
Card 173: 81 61 78 38 98 2 82 51 13 21 | 82 17 51 73 8 35 77 36 68 38 26 76 2 88 53 98 9 86 97 18 95 13 21 31 45
|
||||
Card 174: 26 71 44 62 58 34 94 6 63 56 | 94 30 35 65 93 49 21 31 33 36 58 34 76 62 16 44 63 26 71 64 56 90 9 6 43
|
||||
Card 175: 48 28 15 21 81 27 25 12 36 32 | 75 61 62 92 54 24 7 23 45 89 96 67 46 57 5 47 14 30 4 90 52 72 63 76 98
|
||||
Card 176: 72 22 84 56 28 15 44 62 55 12 | 30 11 24 62 52 56 84 73 38 55 22 31 36 15 72 12 28 88 51 91 44 60 26 95 89
|
||||
Card 177: 53 85 34 5 38 82 93 51 30 28 | 80 5 28 53 70 31 63 85 89 44 7 51 33 43 93 30 34 46 49 82 26 24 69 38 54
|
||||
Card 178: 65 14 66 63 85 86 89 30 84 32 | 92 24 76 86 38 56 82 84 66 89 42 32 63 43 14 65 79 99 70 85 80 6 97 83 61
|
||||
Card 179: 85 59 18 22 15 29 2 55 16 10 | 91 48 16 15 74 75 44 77 62 58 22 88 40 34 54 55 30 2 29 18 45 51 76 79 10
|
||||
Card 180: 45 13 56 71 79 75 86 16 95 32 | 30 91 39 85 79 35 5 12 4 90 53 95 47 1 75 15 9 3 50 45 10 32 22 24 13
|
||||
Card 181: 47 13 85 45 98 21 78 68 80 27 | 64 46 42 85 82 60 8 47 69 91 15 33 52 7 95 34 86 53 40 49 27 76 63 26 78
|
||||
Card 182: 78 84 43 31 86 90 13 83 7 29 | 51 64 67 82 39 87 49 93 69 12 29 36 47 84 18 96 77 10 91 92 60 16 53 81 88
|
||||
Card 183: 28 78 55 47 42 63 49 25 76 33 | 35 15 41 37 49 50 69 70 87 88 73 77 30 6 97 61 7 38 98 1 32 48 99 47 16
|
||||
Card 184: 96 39 9 10 41 91 42 89 8 55 | 94 53 33 12 81 88 42 87 39 1 92 10 98 26 48 29 72 54 96 91 47 13 78 83 68
|
||||
Card 185: 62 93 55 27 14 24 52 1 9 48 | 58 62 35 88 45 46 24 82 12 27 77 25 10 81 6 60 71 41 52 37 50 48 28 80 75
|
||||
Card 186: 90 95 45 20 89 88 34 55 25 2 | 89 31 34 8 86 5 91 90 25 84 45 81 24 65 60 64 19 94 49 55 75 20 47 44 61
|
||||
Card 187: 43 2 16 46 75 68 71 15 45 9 | 30 7 14 37 44 48 65 62 99 89 87 75 10 69 56 78 25 76 59 1 39 23 79 70 68
|
||||
Card 188: 67 81 88 51 13 5 61 45 27 10 | 35 39 80 10 30 27 38 3 36 22 52 7 40 49 45 79 9 63 42 13 96 31 23 78 98
|
||||
Card 189: 9 6 93 60 97 95 81 94 15 35 | 95 28 17 2 52 47 5 3 86 57 59 81 21 23 41 80 34 51 53 70 68 62 83 74 22
|
||||
Card 190: 65 67 94 63 74 34 48 36 27 20 | 1 91 37 3 49 16 18 7 31 53 25 96 68 88 90 95 27 6 19 58 66 45 73 26 32
|
||||
Card 191: 33 50 17 66 25 78 56 26 93 58 | 24 27 1 28 84 63 8 54 12 39 10 17 65 51 68 37 43 85 42 38 7 96 92 2 71
|
||||
Card 192: 4 6 53 67 24 7 31 98 51 64 | 23 89 13 77 22 40 20 88 21 44 49 41 93 64 15 56 50 62 57 80 3 82 70 48 18
|
||||
Card 193: 77 56 76 24 35 51 22 43 31 34 | 86 38 36 63 58 91 87 73 66 67 61 95 28 16 42 39 41 9 83 37 59 97 92 5 6
|
||||
14
2023/days/04/src/main.rs
Normal file
14
2023/days/04/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
128
2023/days/04/src/parse.rs
Normal file
128
2023/days/04/src/parse.rs
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
use std::collections::BTreeSet;
|
||||
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
multi::{many1, separated_list1},
|
||||
sequence::{preceded, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Card {
|
||||
pub id: usize,
|
||||
pub winning_numbers: BTreeSet<u8>,
|
||||
pub numbers: BTreeSet<u8>,
|
||||
pub multiplier: usize,
|
||||
}
|
||||
|
||||
impl Card {
|
||||
pub fn parse(input: &str) -> IResult<&str, Card> {
|
||||
let mut game_id = terminated(
|
||||
preceded(
|
||||
preceded(tag("Card"), many1(tag(" "))),
|
||||
nom::character::complete::u8,
|
||||
),
|
||||
preceded(tag(":"), many1(tag(" "))),
|
||||
);
|
||||
let mut number_list = separated_list1(many1(tag(" ")), nom::character::complete::u8);
|
||||
let seperator = preceded(tag(" |"), many1(tag(" ")));
|
||||
let (input, id) = game_id(input)?;
|
||||
let (input, winning_numbers) = number_list(input)?;
|
||||
let (input, numbers) = preceded(seperator, number_list)(input)?;
|
||||
let winning_numbers: BTreeSet<u8> = winning_numbers.into_iter().collect();
|
||||
let numbers: BTreeSet<u8> = numbers.into_iter().collect();
|
||||
Ok((
|
||||
input,
|
||||
Card {
|
||||
id: id as usize,
|
||||
winning_numbers,
|
||||
numbers,
|
||||
multiplier: 1,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn num_matches(&self) -> usize {
|
||||
self.numbers.intersection(&self.winning_numbers).count()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Card> {
|
||||
input.lines().map(|l| Card::parse(l).unwrap().1).collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use collection_literals::collection;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53\n",
|
||||
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19\n",
|
||||
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1\n",
|
||||
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83\n",
|
||||
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36\n",
|
||||
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Card {
|
||||
id: 1,
|
||||
winning_numbers: collection! {17, 41, 48, 83, 86},
|
||||
numbers: collection! {6, 9, 17, 31, 48, 53, 83, 86},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 2,
|
||||
winning_numbers: collection! {13, 16, 20, 32, 61},
|
||||
numbers: collection! {17, 19, 24, 30, 32, 61, 68, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 3,
|
||||
winning_numbers: collection! {1, 21, 44, 53, 59},
|
||||
numbers: collection! {1, 14, 16, 21, 63, 69, 72, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 4,
|
||||
winning_numbers: collection! {41, 69, 73, 84, 92},
|
||||
numbers: collection! {5, 51, 54, 58, 59, 76, 83, 84},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 5,
|
||||
winning_numbers: collection! {26, 28, 32, 83, 87},
|
||||
numbers: collection! {12, 22, 30, 36, 70, 82, 88, 93},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 6,
|
||||
winning_numbers: collection! {13 , 18, 31, 56, 72},
|
||||
numbers: collection! {10, 11, 23, 35, 36, 67, 74, 77},
|
||||
multiplier: 1,
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_card_parse() {
|
||||
let input = "Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53";
|
||||
assert_eq!(
|
||||
Card::parse(input).unwrap(),
|
||||
(
|
||||
"",
|
||||
Card {
|
||||
id: 1,
|
||||
winning_numbers: collection! {41, 48, 83, 86, 17},
|
||||
numbers: collection! {83, 86, 6, 31, 17, 9, 48, 53},
|
||||
multiplier: 1,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
65
2023/days/04/src/part1.rs
Normal file
65
2023/days/04/src/part1.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &[Card]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|c| {
|
||||
let len = c.num_matches();
|
||||
if len >= 1 {
|
||||
2_usize.pow((len - 1).try_into().unwrap())
|
||||
} else {
|
||||
0
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collection_literals::collection;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Card {
|
||||
id: 1,
|
||||
winning_numbers: collection! {17, 41, 48, 83, 86},
|
||||
numbers: collection! {6, 9, 17, 31, 48, 53, 83, 86},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 2,
|
||||
winning_numbers: collection! {13, 16, 20, 32, 61},
|
||||
numbers: collection! {17, 19, 24, 30, 32, 61, 68, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 3,
|
||||
winning_numbers: collection! {1, 21, 44, 53, 59},
|
||||
numbers: collection! {1, 14, 16, 21, 63, 69, 72, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 4,
|
||||
winning_numbers: collection! {41, 69, 73, 84, 92},
|
||||
numbers: collection! {5, 51, 54, 58, 59, 76, 83, 84},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 5,
|
||||
winning_numbers: collection! {26, 28, 32, 83, 87},
|
||||
numbers: collection! {12, 22, 30, 36, 70, 82, 88, 93},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 6,
|
||||
winning_numbers: collection! {13 , 18, 31, 56, 72},
|
||||
numbers: collection! {10, 11, 23, 35, 36, 67, 74, 77},
|
||||
multiplier: 1,
|
||||
},
|
||||
];
|
||||
assert_eq!(part1(&input), 13);
|
||||
}
|
||||
}
|
||||
65
2023/days/04/src/part2.rs
Normal file
65
2023/days/04/src/part2.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &[Card]) -> usize {
|
||||
let mut stack: Vec<Card> = input.to_vec();
|
||||
for i in 0..stack.len() {
|
||||
let matches = stack[i].num_matches();
|
||||
if matches >= 1 {
|
||||
//+1 because we want 3 matches to give the num 1,2,3
|
||||
for advance in 1..(matches+1){
|
||||
stack[i+advance].multiplier+=stack[i].multiplier
|
||||
}
|
||||
}
|
||||
}
|
||||
stack.iter().map(|c| c.multiplier).sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collection_literals::collection;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
Card {
|
||||
id: 1,
|
||||
winning_numbers: collection! {17, 41, 48, 83, 86},
|
||||
numbers: collection! {6, 9, 17, 31, 48, 53, 83, 86},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 2,
|
||||
winning_numbers: collection! {13, 16, 20, 32, 61},
|
||||
numbers: collection! {17, 19, 24, 30, 32, 61, 68, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 3,
|
||||
winning_numbers: collection! {1, 21, 44, 53, 59},
|
||||
numbers: collection! {1, 14, 16, 21, 63, 69, 72, 82},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 4,
|
||||
winning_numbers: collection! {41, 69, 73, 84, 92},
|
||||
numbers: collection! {5, 51, 54, 58, 59, 76, 83, 84},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 5,
|
||||
winning_numbers: collection! {26, 28, 32, 83, 87},
|
||||
numbers: collection! {12, 22, 30, 36, 70, 82, 88, 93},
|
||||
multiplier: 1,
|
||||
},
|
||||
Card {
|
||||
id: 6,
|
||||
winning_numbers: collection! {13 , 18, 31, 56, 72},
|
||||
numbers: collection! {10, 11, 23, 35, 36, 67, 74, 77},
|
||||
multiplier: 1,
|
||||
},
|
||||
];
|
||||
assert_eq!(part2(&input), 30);
|
||||
}
|
||||
}
|
||||
10
2023/days/05/Cargo.toml
Normal file
10
2023/days/05/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day05"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace = true
|
||||
252
2023/days/05/src/input.txt
Normal file
252
2023/days/05/src/input.txt
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
seeds: 432986705 28073546 1364097901 88338513 2733524843 234912494 3151642679 224376393 485709676 344068331 1560394266 911616092 3819746175 87998136 892394515 435690182 4218056486 23868437 848725444 8940450
|
||||
|
||||
seed-to-soil map:
|
||||
748585809 2125564114 88980459
|
||||
1317392128 775565564 217595062
|
||||
1218610825 676784261 98781303
|
||||
954230685 2235762425 141777617
|
||||
2920242079 4081180892 51765553
|
||||
2972007632 3159586797 16102841
|
||||
0 2377540042 17565155
|
||||
2834452876 3712797875 58062179
|
||||
2892515055 2917079842 6424918
|
||||
3327351062 3175689638 162608005
|
||||
673338549 647264576 29519685
|
||||
1197392973 2214544573 21217852
|
||||
738232750 116664417 10353059
|
||||
2988110473 2429807442 71556277
|
||||
17565155 334379348 277510712
|
||||
1700771639 228674051 105705297
|
||||
3059666750 4132946445 162020851
|
||||
1806476936 993160626 588628261
|
||||
1096008302 127289380 101384671
|
||||
622123656 1908836676 50942989
|
||||
3221687601 3338297643 28028532
|
||||
2408505336 3770860054 310320838
|
||||
4175210607 3039830108 119756689
|
||||
3326652416 3039131462 698646
|
||||
2898939973 2408505336 21302106
|
||||
673066645 127017476 271904
|
||||
3489959067 3382623558 330174317
|
||||
702858234 611890060 35374516
|
||||
4086270124 2562002619 88940483
|
||||
837566268 0 116664417
|
||||
1534987190 1959779665 165784449
|
||||
2718826174 2923504760 115626702
|
||||
3249716133 3366326175 16297383
|
||||
3820133384 2650943102 266136740
|
||||
3266013516 2501363719 60638900
|
||||
295075867 1581788887 327047789
|
||||
|
||||
soil-to-fertilizer map:
|
||||
2018515973 2192795257 82329405
|
||||
3722326327 3015971185 249665840
|
||||
3046459770 3689390318 25519185
|
||||
3971992167 3265637025 40217941
|
||||
3071978955 3453653215 203407731
|
||||
0 443504340 17965088
|
||||
584437096 1722124969 470670288
|
||||
1055107384 744431503 164966659
|
||||
1489299099 461469428 282962075
|
||||
2321848831 2380372526 153650776
|
||||
2100845378 269225056 174279284
|
||||
3487660258 2648616968 234666069
|
||||
3275386686 3305854966 147798249
|
||||
1772261174 1172578553 246254799
|
||||
4012210108 2883283037 132688148
|
||||
3423184935 4138946628 64475323
|
||||
4144898256 2321848831 58523695
|
||||
538253726 1418833352 46183370
|
||||
1220074043 0 269225056
|
||||
17965088 909398162 263180391
|
||||
2590093273 3657060946 32329372
|
||||
281145479 1465016722 257108247
|
||||
2622422645 3714909503 424037125
|
||||
2475499607 2534023302 114593666
|
||||
|
||||
fertilizer-to-water map:
|
||||
3731805434 353192162 37567806
|
||||
926873139 889685769 255250442
|
||||
3170336676 695153543 194532226
|
||||
679924479 451681440 193671776
|
||||
3009343704 3081959489 160992972
|
||||
1242360754 3579359343 278026518
|
||||
1861131448 2500688596 20068354
|
||||
4028837903 4006213119 266129393
|
||||
1182123581 3242952461 60237173
|
||||
3877550443 645353216 49800327
|
||||
2223776164 1371077033 341527178
|
||||
3364868902 2566566565 36440100
|
||||
1773121333 0 76664401
|
||||
264823995 2444756861 55931735
|
||||
3929841219 3857385861 27802851
|
||||
2166799431 1712604211 56976733
|
||||
873596255 1769580944 53276884
|
||||
645696746 3047731756 34227733
|
||||
3927350770 3955153621 2490449
|
||||
3769373240 177937131 108177203
|
||||
0 3314535348 264823995
|
||||
1942121274 3885188712 69964909
|
||||
1881199802 390759968 60921472
|
||||
1849785734 3303189634 11345714
|
||||
3401309002 2855740726 104355610
|
||||
2079164011 2960096336 87635420
|
||||
544424016 76664401 101272730
|
||||
2565303342 2520756950 45809615
|
||||
1520387272 2603006665 252734061
|
||||
2012086183 286114334 67077828
|
||||
2611112957 1822857828 398230747
|
||||
320755730 2221088575 223668286
|
||||
3505664612 1144936211 226140822
|
||||
4006213119 4272342512 22624784
|
||||
|
||||
water-to-light map:
|
||||
62780592 544346201 30115959
|
||||
2740764032 1352944740 34082945
|
||||
377487729 807592920 35446631
|
||||
1316419610 1454554942 34907962
|
||||
986581913 756881718 50711202
|
||||
4167758628 3240047125 127208668
|
||||
818809239 1222506283 58684750
|
||||
3649838514 2036598113 6212644
|
||||
127663629 0 10715051
|
||||
3023280854 1435387310 19167632
|
||||
663070842 10715051 124076893
|
||||
2774846977 2422700597 37614763
|
||||
1812617371 2460315360 5121443
|
||||
1640337506 1864318248 172279865
|
||||
2986755724 1316419610 36525130
|
||||
2023334670 2467203928 540327060
|
||||
1159184084 248462172 14557802
|
||||
1037293115 152894449 95567723
|
||||
0 134791944 18102505
|
||||
18102505 712203631 44678087
|
||||
465375803 972369801 197695039
|
||||
2576394916 3007530988 65274194
|
||||
92896551 1281191033 34767078
|
||||
3656051158 4289142647 5824649
|
||||
412934360 1170064840 52441443
|
||||
3417303830 3873138614 84580361
|
||||
787147735 263019974 31661504
|
||||
1817738814 2042810757 205595856
|
||||
1285160111 843039551 30798000
|
||||
2563661730 3123136764 12733186
|
||||
138378680 305237152 239109049
|
||||
3648071389 2465436803 1767125
|
||||
1132860838 574462160 26323246
|
||||
888049663 873837551 98532250
|
||||
3626039273 3072805182 22032116
|
||||
3530183657 4193287031 95855616
|
||||
1404769450 3957718975 235568056
|
||||
3042448486 1489462904 374855344
|
||||
2641669110 1387027685 48359625
|
||||
877493989 294681478 10555674
|
||||
3501884191 3094837298 28299466
|
||||
1351327572 3186605247 53441878
|
||||
2690028735 3135869950 50735297
|
||||
2812461740 2248406613 174293984
|
||||
3661875807 3367255793 505882821
|
||||
1173741886 600785406 111418225
|
||||
|
||||
light-to-temperature map:
|
||||
964570004 989608620 226759942
|
||||
2204148775 2545437438 20646474
|
||||
233260112 338444213 39032265
|
||||
958191857 332066066 6378147
|
||||
2318799855 914518254 75090366
|
||||
4247140372 3146297568 47826924
|
||||
2224795249 1216368562 94004606
|
||||
2871022952 1310373168 80313918
|
||||
1400254919 233260112 98805954
|
||||
445493256 487550555 149554087
|
||||
2576473348 3962746668 294549604
|
||||
3535295748 2775008885 371288683
|
||||
1499060873 377476478 110074077
|
||||
272292377 2215619580 173200879
|
||||
3347481948 1867953550 157067409
|
||||
4161267146 3794452372 85873226
|
||||
3504549357 2184873189 30746391
|
||||
1759636962 1780717197 87236353
|
||||
2951336870 2388820459 6114967
|
||||
1191329946 2566083912 208924973
|
||||
1884544339 3880325598 82421070
|
||||
595047343 3431307858 363144514
|
||||
2393890221 731935127 182583127
|
||||
4001414916 2025020959 159852230
|
||||
2957451837 1390687086 390030111
|
||||
1846873315 4257296272 37671024
|
||||
1966965409 3194124492 237183366
|
||||
1609134950 2394935426 150502012
|
||||
3906584431 637104642 94830485
|
||||
|
||||
temperature-to-humidity map:
|
||||
1406768592 2335526312 13344484
|
||||
666958498 1862550129 472976183
|
||||
558853371 843618476 74696086
|
||||
1168798622 129171378 168640618
|
||||
1713291209 297811996 183431863
|
||||
1993628008 635748116 152317885
|
||||
2560263686 2849350774 11516524
|
||||
32266442 1212766321 287276323
|
||||
2571780210 3319898101 11192927
|
||||
375095240 995599149 183758131
|
||||
2661986290 2353962919 50829838
|
||||
3252020768 4280298713 14668583
|
||||
1337439240 1793220777 69329352
|
||||
3419718116 3502299739 574454544
|
||||
2353962919 2650392505 198958269
|
||||
633549457 1179357280 33409041
|
||||
2582973137 4076754283 50515665
|
||||
319542765 788066001 55552475
|
||||
1896723072 32266442 96904936
|
||||
1420113076 1500042644 293178133
|
||||
3006421020 2404792757 245599748
|
||||
2842554807 3331091028 163866213
|
||||
2633488802 2990605977 28497488
|
||||
2300450150 947178503 48420646
|
||||
3266689351 4127269948 153028765
|
||||
2145945893 481243859 154504257
|
||||
3994172660 3019103465 300794636
|
||||
1139934681 918314562 28863941
|
||||
2712816128 2860867298 129738679
|
||||
2552921188 3494957241 7342498
|
||||
|
||||
humidity-to-location map:
|
||||
897459980 3171885613 268595078
|
||||
506368722 1864971513 13322696
|
||||
1166055058 2803961444 53745388
|
||||
2572095034 667166679 114420176
|
||||
687118932 1725187165 139784348
|
||||
2478398695 0 14138781
|
||||
3427672233 370325921 251085897
|
||||
3888215738 3612891343 82449665
|
||||
1674720770 1530101168 79955344
|
||||
3970665403 925512154 2812137
|
||||
519691418 2452425610 167427514
|
||||
3884704963 3168374838 3510775
|
||||
826903280 2381868910 70556700
|
||||
2399774019 349568762 20757159
|
||||
2972099388 3465151802 147739541
|
||||
1754676114 131614075 217954687
|
||||
2865104023 3440480691 24671111
|
||||
2206760431 932309368 77882935
|
||||
2284643366 1610056512 115130653
|
||||
2492537476 14138781 35151040
|
||||
2527688516 3695341008 44406518
|
||||
3119838929 781586855 143925299
|
||||
2732270071 2857706832 132833952
|
||||
1599442846 2728683520 75277924
|
||||
3263764228 3995626854 27783181
|
||||
0 2990540784 177834054
|
||||
2686515210 621411818 45754861
|
||||
2420531178 2670816003 57867517
|
||||
1219800446 1010192303 191374197
|
||||
3678758130 3789680021 205946833
|
||||
3973477540 3739747526 49932495
|
||||
1972630801 2014419033 234129630
|
||||
3291547409 1878294209 136124824
|
||||
2889775134 49289821 82324254
|
||||
1411174643 2619853124 50962879
|
||||
1466122599 2248548663 133320247
|
||||
177834054 1201566500 328534668
|
||||
1462137522 928324291 3985077
|
||||
14
2023/days/05/src/main.rs
Normal file
14
2023/days/05/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
543
2023/days/05/src/parse.rs
Normal file
543
2023/days/05/src/parse.rs
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::{alpha1, multispace0},
|
||||
multi::{count, many1, separated_list1},
|
||||
sequence::{delimited, preceded, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
pub type SeedRange = Range<u64>;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Map {
|
||||
pub from: String,
|
||||
pub to: String,
|
||||
pub ranges: Vec<MapRange>,
|
||||
}
|
||||
|
||||
impl Map {
|
||||
pub fn map_ranges(&self, seeds: SeedRange) -> Vec<SeedRange> {
|
||||
let mut unprocessed_seeds = vec![seeds];
|
||||
let mut processed_seeds = Vec::new();
|
||||
//using this instead of a for loop so that we can continue to push new stuff onto the
|
||||
//unprocessed queue
|
||||
while let Some(seed) = unprocessed_seeds.pop() {
|
||||
//find map with intersection with seed
|
||||
let map_to_apply = self
|
||||
.ranges
|
||||
.iter()
|
||||
.find(|&map_range| !map_range.intersection_with_seed(&seed).is_empty());
|
||||
|
||||
let Some(map_to_apply) = map_to_apply else {
|
||||
//if no mapping to do, consider seed processed
|
||||
processed_seeds.push(seed);
|
||||
continue;
|
||||
};
|
||||
|
||||
let map_end = map_to_apply.src_start + map_to_apply.len;
|
||||
let offset = map_to_apply.dest_start as i64 - map_to_apply.src_start as i64;
|
||||
let intersection = map_to_apply.intersection_with_seed(&seed);
|
||||
|
||||
processed_seeds.push(Range {
|
||||
start: (intersection.start as i64 + offset) as u64,
|
||||
end: (intersection.end as i64 + offset) as u64,
|
||||
});
|
||||
|
||||
//add the part before the map range back to the queue
|
||||
if seed.start < map_to_apply.src_start {
|
||||
unprocessed_seeds.push(Range {
|
||||
start: seed.start,
|
||||
end: intersection.start,
|
||||
})
|
||||
};
|
||||
|
||||
//add the part after the map range back to the queue
|
||||
if seed.end > map_end {
|
||||
unprocessed_seeds.push(Range {
|
||||
start: intersection.end,
|
||||
end: seed.end,
|
||||
})
|
||||
};
|
||||
}
|
||||
processed_seeds
|
||||
}
|
||||
|
||||
pub fn map(&self, src: u64) -> u64 {
|
||||
for range in &self.ranges {
|
||||
if range.is_applicable(&src) {
|
||||
return range.map(src);
|
||||
}
|
||||
}
|
||||
src
|
||||
}
|
||||
fn parse(input: &str) -> IResult<&str, Self> {
|
||||
let (input, (from, to)) = delimited(multispace0, Self::parse_to_from, multispace0)(input)?;
|
||||
let (input, ranges) = many1(MapRange::parse)(input)?;
|
||||
Ok((input, Map { from, to, ranges }))
|
||||
}
|
||||
fn parse_to_from(input: &str) -> IResult<&str, (String, String)> {
|
||||
let (input, from) = alpha1(input)?;
|
||||
let (input, to) = terminated(preceded(tag("-to-"), alpha1), tag(" map:\n"))(input)?;
|
||||
Ok((input, (from.to_string(), to.to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct MapRange {
|
||||
pub dest_start: u64,
|
||||
pub src_start: u64,
|
||||
pub len: u64,
|
||||
}
|
||||
|
||||
impl MapRange {
|
||||
fn intersection_with_seed(&self, seed: &SeedRange) -> SeedRange {
|
||||
seed.start.max(self.src_start)..seed.end.min(self.src_start + self.len)
|
||||
}
|
||||
|
||||
fn is_applicable(&self, src: &u64) -> bool {
|
||||
self.src_start <= *src && *src < (self.src_start + self.len)
|
||||
}
|
||||
|
||||
fn map(&self, src: u64) -> u64 {
|
||||
if self.is_applicable(&src) {
|
||||
let offset = src - self.src_start;
|
||||
self.dest_start + offset
|
||||
} else {
|
||||
src
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(input: &str) -> IResult<&str, Self> {
|
||||
let number = delimited(multispace0, nom::character::complete::u64, multispace0);
|
||||
let (input, numbers) = count(number, 3)(input)?;
|
||||
Ok((
|
||||
input,
|
||||
MapRange {
|
||||
dest_start: numbers[0],
|
||||
src_start: numbers[1],
|
||||
len: numbers[2],
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> IResult<&str, (Vec<u64>, Vec<Map>)> {
|
||||
let (input, seeds) = preceded(
|
||||
tag("seeds: "),
|
||||
separated_list1(tag(" "), nom::character::complete::u64),
|
||||
)(input)?;
|
||||
let (input, maps) = many1(Map::parse)(input)?;
|
||||
Ok((input, (seeds, maps)))
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> (Vec<u64>, Vec<Map>) {
|
||||
parse_input(input).unwrap().1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_map_range() {
|
||||
let tested = Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
},
|
||||
],
|
||||
};
|
||||
let input: SeedRange = 40..120;
|
||||
assert_eq!(
|
||||
tested.map_ranges(input),
|
||||
vec![
|
||||
50..52,
|
||||
100..120,
|
||||
52..100,
|
||||
40..50
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_intersection_with_seed() {
|
||||
let tested = MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
};
|
||||
let input: SeedRange = 80..120;
|
||||
assert_eq!(tested.intersection_with_seed(&input), 80..98);
|
||||
let input: SeedRange = 40..60;
|
||||
assert_eq!(tested.intersection_with_seed(&input), 50..60);
|
||||
let input: SeedRange = 55..79;
|
||||
assert_eq!(tested.intersection_with_seed(&input), 55..79);
|
||||
let input: SeedRange = 40..120;
|
||||
assert_eq!(tested.intersection_with_seed(&input), 50..98);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map() {
|
||||
let tested = Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
},
|
||||
],
|
||||
};
|
||||
let input = [79, 14, 55, 13];
|
||||
let output = input.map(|i| tested.map(i));
|
||||
assert_eq!(output, [81, 14, 57, 13])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_appliccable() {
|
||||
let tested = MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
};
|
||||
assert!(tested.is_applicable(&99));
|
||||
assert!(!tested.is_applicable(&100));
|
||||
assert!(!tested.is_applicable(&97));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_map() {
|
||||
let tested = MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
};
|
||||
assert_eq!(tested.map(79), 81);
|
||||
assert_eq!(tested.map(100), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_map_parse() {
|
||||
let input = concat!("seed-to-soil map:\n", "50 98 2\n", "52 50 48\n", "\n",);
|
||||
assert_eq!(
|
||||
Map::parse(input).unwrap(),
|
||||
(
|
||||
"",
|
||||
Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_parse() {
|
||||
assert_eq!(
|
||||
MapRange::parse("50 98 2\n").unwrap(),
|
||||
(
|
||||
"",
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
MapRange::parse("0 15 37\n").unwrap(),
|
||||
(
|
||||
"",
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 15,
|
||||
len: 37,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_to_from() {
|
||||
assert_eq!(
|
||||
Map::parse_to_from("seed-to-soil map:\n").unwrap(),
|
||||
("", ("seed".to_string(), "soil".to_string()))
|
||||
);
|
||||
assert_eq!(
|
||||
Map::parse_to_from("hello-to-world map:\n").unwrap(),
|
||||
("", ("hello".to_string(), "world".to_string()))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_input() {
|
||||
let input = concat!(
|
||||
"seeds: 79 14 55 13\n",
|
||||
"\n",
|
||||
"seed-to-soil map:\n",
|
||||
"50 98 2\n",
|
||||
"52 50 48\n",
|
||||
"\n",
|
||||
"soil-to-fertilizer map:\n",
|
||||
"0 15 37\n",
|
||||
"37 52 2\n",
|
||||
"39 0 15\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse_input(input).unwrap(),
|
||||
(
|
||||
"",
|
||||
(
|
||||
vec![79, 14, 55, 13],
|
||||
vec![
|
||||
Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48
|
||||
},
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "soil".to_string(),
|
||||
to: "fertilizer".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 15,
|
||||
len: 37
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 37,
|
||||
src_start: 52,
|
||||
len: 2
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 39,
|
||||
src_start: 0,
|
||||
len: 15
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"seeds: 79 14 55 13\n",
|
||||
"\n",
|
||||
"seed-to-soil map:\n",
|
||||
"50 98 2\n",
|
||||
"52 50 48\n",
|
||||
"\n",
|
||||
"soil-to-fertilizer map:\n",
|
||||
"0 15 37\n",
|
||||
"37 52 2\n",
|
||||
"39 0 15\n",
|
||||
"\n",
|
||||
"fertilizer-to-water map:\n",
|
||||
"49 53 8\n",
|
||||
"0 11 42\n",
|
||||
"42 0 7\n",
|
||||
"57 7 4\n",
|
||||
"\n",
|
||||
"water-to-light map:\n",
|
||||
"88 18 7\n",
|
||||
"18 25 70\n",
|
||||
"\n",
|
||||
"light-to-temperature map:\n",
|
||||
"45 77 23\n",
|
||||
"81 45 19\n",
|
||||
"68 64 13\n",
|
||||
"\n",
|
||||
"temperature-to-humidity map:\n",
|
||||
"0 69 1\n",
|
||||
"1 0 69\n",
|
||||
"\n",
|
||||
"humidity-to-location map:\n",
|
||||
"60 56 37\n",
|
||||
"56 93 4\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
(
|
||||
vec![79, 14, 55, 13],
|
||||
vec![
|
||||
Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "soil".to_string(),
|
||||
to: "fertilizer".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 15,
|
||||
len: 37
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 37,
|
||||
src_start: 52,
|
||||
len: 2
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 39,
|
||||
src_start: 0,
|
||||
len: 15
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "fertilizer".to_string(),
|
||||
to: "water".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 49,
|
||||
src_start: 53,
|
||||
len: 8
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 11,
|
||||
len: 42
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 42,
|
||||
src_start: 0,
|
||||
len: 7
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 57,
|
||||
src_start: 7,
|
||||
len: 4
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "water".to_string(),
|
||||
to: "light".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 88,
|
||||
src_start: 18,
|
||||
len: 7
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 18,
|
||||
src_start: 25,
|
||||
len: 70
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "light".to_string(),
|
||||
to: "temperature".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 45,
|
||||
src_start: 77,
|
||||
len: 23
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 81,
|
||||
src_start: 45,
|
||||
len: 19
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 68,
|
||||
src_start: 64,
|
||||
len: 13
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "temperature".to_string(),
|
||||
to: "humidity".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 69,
|
||||
len: 1
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 1,
|
||||
src_start: 0,
|
||||
len: 69
|
||||
}
|
||||
]
|
||||
},
|
||||
Map {
|
||||
from: "humidity".to_string(),
|
||||
to: "location".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 60,
|
||||
src_start: 56,
|
||||
len: 37
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 56,
|
||||
src_start: 93,
|
||||
len: 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
156
2023/days/05/src/part1.rs
Normal file
156
2023/days/05/src/part1.rs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &(Vec<u64>, Vec<Map>)) -> usize {
|
||||
let mut seeds = input.0.clone();
|
||||
for map in &input.1 {
|
||||
seeds = seeds.into_iter().map(|s| map.map(s)).collect()
|
||||
}
|
||||
*seeds.iter().min().unwrap() as usize
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = (
|
||||
vec![79, 14, 55, 13],
|
||||
vec![
|
||||
Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "soil".to_string(),
|
||||
to: "fertilizer".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 15,
|
||||
len: 37,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 37,
|
||||
src_start: 52,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 39,
|
||||
src_start: 0,
|
||||
len: 15,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "fertilizer".to_string(),
|
||||
to: "water".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 49,
|
||||
src_start: 53,
|
||||
len: 8,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 11,
|
||||
len: 42,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 42,
|
||||
src_start: 0,
|
||||
len: 7,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 57,
|
||||
src_start: 7,
|
||||
len: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "water".to_string(),
|
||||
to: "light".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 88,
|
||||
src_start: 18,
|
||||
len: 7,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 18,
|
||||
src_start: 25,
|
||||
len: 70,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "light".to_string(),
|
||||
to: "temperature".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 45,
|
||||
src_start: 77,
|
||||
len: 23,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 81,
|
||||
src_start: 45,
|
||||
len: 19,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 68,
|
||||
src_start: 64,
|
||||
len: 13,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "temperature".to_string(),
|
||||
to: "humidity".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 69,
|
||||
len: 1,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 1,
|
||||
src_start: 0,
|
||||
len: 69,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "humidity".to_string(),
|
||||
to: "location".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 60,
|
||||
src_start: 56,
|
||||
len: 37,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 56,
|
||||
src_start: 93,
|
||||
len: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part1(&input), 35);
|
||||
}
|
||||
}
|
||||
168
2023/days/05/src/part2.rs
Normal file
168
2023/days/05/src/part2.rs
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &(Vec<u64>, Vec<Map>)) -> usize {
|
||||
let mut seeds = convert_seeds_to_ranges(&input.0);
|
||||
for map in &input.1{
|
||||
seeds = seeds.into_iter().flat_map(|s|{
|
||||
map.map_ranges(s)
|
||||
}).collect();
|
||||
};
|
||||
seeds.iter().map(|s| s.start).min().unwrap() as usize
|
||||
}
|
||||
|
||||
fn convert_seeds_to_ranges(seeds: &[u64]) -> Vec<SeedRange> {
|
||||
seeds.chunks(2).map(|c| c[0]..(c[0] + c[1])).collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_convert_seeds_to_ranges() {
|
||||
let input = [79, 14, 55, 13];
|
||||
assert_eq!(convert_seeds_to_ranges(&input), vec![79..93, 55..68])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = (
|
||||
vec![79, 14, 55, 13],
|
||||
vec![
|
||||
Map {
|
||||
from: "seed".to_string(),
|
||||
to: "soil".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 50,
|
||||
src_start: 98,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 52,
|
||||
src_start: 50,
|
||||
len: 48,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "soil".to_string(),
|
||||
to: "fertilizer".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 15,
|
||||
len: 37,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 37,
|
||||
src_start: 52,
|
||||
len: 2,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 39,
|
||||
src_start: 0,
|
||||
len: 15,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "fertilizer".to_string(),
|
||||
to: "water".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 49,
|
||||
src_start: 53,
|
||||
len: 8,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 11,
|
||||
len: 42,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 42,
|
||||
src_start: 0,
|
||||
len: 7,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 57,
|
||||
src_start: 7,
|
||||
len: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "water".to_string(),
|
||||
to: "light".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 88,
|
||||
src_start: 18,
|
||||
len: 7,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 18,
|
||||
src_start: 25,
|
||||
len: 70,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "light".to_string(),
|
||||
to: "temperature".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 45,
|
||||
src_start: 77,
|
||||
len: 23,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 81,
|
||||
src_start: 45,
|
||||
len: 19,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 68,
|
||||
src_start: 64,
|
||||
len: 13,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "temperature".to_string(),
|
||||
to: "humidity".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 0,
|
||||
src_start: 69,
|
||||
len: 1,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 1,
|
||||
src_start: 0,
|
||||
len: 69,
|
||||
},
|
||||
],
|
||||
},
|
||||
Map {
|
||||
from: "humidity".to_string(),
|
||||
to: "location".to_string(),
|
||||
ranges: vec![
|
||||
MapRange {
|
||||
dest_start: 60,
|
||||
src_start: 56,
|
||||
len: 37,
|
||||
},
|
||||
MapRange {
|
||||
dest_start: 56,
|
||||
src_start: 93,
|
||||
len: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part2(&input), 46);
|
||||
}
|
||||
}
|
||||
10
2023/days/06/Cargo.toml
Normal file
10
2023/days/06/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day06"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace=true
|
||||
2
2023/days/06/src/input.txt
Normal file
2
2023/days/06/src/input.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Time: 40 81 77 72
|
||||
Distance: 219 1012 1365 1089
|
||||
15
2023/days/06/src/main.rs
Normal file
15
2023/days/06/src/main.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
let structured_input = parse::part2_parse(input);
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(structured_input));
|
||||
}
|
||||
148
2023/days/06/src/parse.rs
Normal file
148
2023/days/06/src/parse.rs
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::multispace0,
|
||||
multi::separated_list1,
|
||||
sequence::{preceded, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Race {
|
||||
pub time: u64,
|
||||
pub record: u64,
|
||||
}
|
||||
|
||||
impl Race {
|
||||
// pub fn distance_given_charge_time(&self, charge_time: u64) -> u64 {
|
||||
// if charge_time <= self.time {
|
||||
// charge_time * (self.time - charge_time)
|
||||
// } else {
|
||||
// 0
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn num_ways_to_win(&self) -> u64 {
|
||||
// since distance = charge(time-charge),
|
||||
// we can rearrange into charge^2-(time)charge + distance = 0.
|
||||
// if we set distance to record+1 (the min distance needed to win), we can use the quadratic formula, where
|
||||
// a=1
|
||||
// also notice that the upper and lower bound of charge times always sums up to
|
||||
// the total time, so we can compute the lower bound from the upper bound.
|
||||
// (too lazy to prove this...)
|
||||
let b = -(self.time as f64);
|
||||
let c = (self.record + 1) as f64;
|
||||
let upper_bound = ((-b + (b.powi(2) - 4.0 * c).sqrt()) / 2.0).floor() as u64;
|
||||
let lower_bound = self.time - upper_bound;
|
||||
println!(
|
||||
"upper bound is {}, lower bound is {}",
|
||||
upper_bound, lower_bound
|
||||
);
|
||||
// off by one because if your upper and lower bounds are the same, there is 1 way to win.
|
||||
upper_bound - lower_bound + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Race> {
|
||||
let times: IResult<&str, Vec<u64>> = terminated(
|
||||
preceded(
|
||||
preceded(tag("Time:"), multispace0),
|
||||
separated_list1(multispace0, nom::character::complete::u64),
|
||||
),
|
||||
multispace0,
|
||||
)(input);
|
||||
let (input, times) = times.unwrap();
|
||||
let distances: IResult<&str, Vec<u64>> = terminated(
|
||||
preceded(
|
||||
preceded(tag("Distance:"), multispace0),
|
||||
separated_list1(multispace0, nom::character::complete::u64),
|
||||
),
|
||||
multispace0,
|
||||
)(input);
|
||||
let (input, distances) = distances.unwrap();
|
||||
assert_eq!(input, "");
|
||||
times
|
||||
.into_iter()
|
||||
.zip(distances)
|
||||
.map(|r| Race {
|
||||
time: r.0,
|
||||
record: r.1,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn part2_parse(input: &str) -> Race {
|
||||
let mut string = input.to_string();
|
||||
string.retain(|c| c != ' ');
|
||||
let time: IResult<&str, u64> = terminated(
|
||||
preceded(tag("Time:"), nom::character::complete::u64),
|
||||
multispace0,
|
||||
)(&string);
|
||||
let (input, time) = time.unwrap();
|
||||
let distance: IResult<&str, u64> = terminated(
|
||||
preceded(tag("Distance:"), nom::character::complete::u64),
|
||||
multispace0,
|
||||
)(input);
|
||||
let (input, distance) = distance.unwrap();
|
||||
assert_eq!(input, "");
|
||||
Race {
|
||||
time,
|
||||
record: distance,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_num_ways_to_win() {
|
||||
let input = Race { time: 7, record: 9 };
|
||||
assert_eq!(input.num_ways_to_win(), 4);
|
||||
let input = Race {
|
||||
time: 15,
|
||||
record: 40,
|
||||
};
|
||||
assert_eq!(input.num_ways_to_win(), 8);
|
||||
let input = Race {
|
||||
time: 30,
|
||||
record: 200,
|
||||
};
|
||||
assert_eq!(input.num_ways_to_win(), 9);
|
||||
let input = Race {
|
||||
time: 71530,
|
||||
record: 940200,
|
||||
};
|
||||
assert_eq!(input.num_ways_to_win(), 71503);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_part2() {
|
||||
let input = concat!("Time: 7 15 30\n", "Distance: 9 40 200\n",);
|
||||
assert_eq!(
|
||||
part2_parse(input),
|
||||
Race {
|
||||
time: 71530,
|
||||
record: 940200
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!("Time: 7 15 30\n", "Distance: 9 40 200\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Race { time: 7, record: 9 },
|
||||
Race {
|
||||
time: 15,
|
||||
record: 40
|
||||
},
|
||||
Race {
|
||||
time: 30,
|
||||
record: 200
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
26
2023/days/06/src/part1.rs
Normal file
26
2023/days/06/src/part1.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &[Race]) -> u64 {
|
||||
input.iter().map(|r| r.num_ways_to_win()).product()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Race { time: 7, record: 9 },
|
||||
Race {
|
||||
time: 15,
|
||||
record: 40,
|
||||
},
|
||||
Race {
|
||||
time: 30,
|
||||
record: 200,
|
||||
},
|
||||
];
|
||||
assert_eq!(part1(&input), 288);
|
||||
}
|
||||
}
|
||||
16
2023/days/06/src/part2.rs
Normal file
16
2023/days/06/src/part2.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: Race) -> u64 {
|
||||
input.num_ways_to_win()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = Race{ time: 71530, record: 940200 };
|
||||
assert_eq!(part2(input), 71503);
|
||||
}
|
||||
}
|
||||
10
2023/days/07/Cargo.toml
Normal file
10
2023/days/07/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day07"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
itertools.workspace = true
|
||||
1000
2023/days/07/src/input.txt
Normal file
1000
2023/days/07/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
14
2023/days/07/src/main.rs
Normal file
14
2023/days/07/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let mut structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&mut structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&mut structured_input));
|
||||
}
|
||||
648
2023/days/07/src/parse.rs
Normal file
648
2023/days/07/src/parse.rs
Normal file
|
|
@ -0,0 +1,648 @@
|
|||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash)]
|
||||
pub enum Card {
|
||||
Ace = 14,
|
||||
King = 13,
|
||||
Queen = 12,
|
||||
Jack = 11,
|
||||
Tim = 10,
|
||||
Nine = 9,
|
||||
Eight = 8,
|
||||
Seven = 7,
|
||||
Six = 6,
|
||||
Five = 5,
|
||||
Four = 4,
|
||||
Three = 3,
|
||||
Two = 2,
|
||||
Joker = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
pub enum Formation {
|
||||
FiveOfKind = 7,
|
||||
FourOfKind = 6,
|
||||
FullHouse = 5,
|
||||
ThreeOfKind = 4,
|
||||
TwoPair = 3,
|
||||
OnePair = 2,
|
||||
HighCard = 1,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct Hand {
|
||||
formation: Formation,
|
||||
cards: [Card; 5],
|
||||
}
|
||||
|
||||
impl Hand {
|
||||
pub fn new(cards: [Card; 5]) -> Hand {
|
||||
Hand {
|
||||
formation: Self::determine_formation(&cards),
|
||||
cards,
|
||||
}
|
||||
}
|
||||
fn determine_formation(cards: &[Card; 5]) -> Formation {
|
||||
let mut counts = cards.iter().counts();
|
||||
let jokers = counts.remove(&Card::Joker).unwrap_or(0);
|
||||
let types = counts.len();
|
||||
let max_of_type = counts.into_values().max().unwrap_or(0) + jokers;
|
||||
match types {
|
||||
// if 0 types, they are all joker.
|
||||
0 => Formation::FiveOfKind,
|
||||
1 => Formation::FiveOfKind,
|
||||
2 => {
|
||||
// if there are 4 of 1 kind, doesnt matter what the other card is. If there are
|
||||
// three of a kind but only 2 card types, the other 2 must be a pair.
|
||||
match max_of_type {
|
||||
4 => Formation::FourOfKind,
|
||||
3 => Formation::FullHouse,
|
||||
_ => panic!("idk what type of hand this is: {:?}", cards),
|
||||
}
|
||||
}
|
||||
3 => {
|
||||
// if there are 3 types, it could either be three of a kind, or two pair.
|
||||
match max_of_type {
|
||||
3 => Formation::ThreeOfKind,
|
||||
2 => Formation::TwoPair,
|
||||
_ => panic!("idk what type of hand this is: {:?}", cards),
|
||||
}
|
||||
}
|
||||
4 => Formation::OnePair,
|
||||
5 => Formation::HighCard,
|
||||
_ => panic!("how are there more than 5 types!"),
|
||||
}
|
||||
}
|
||||
pub fn turn_jacks_to_jokers(&mut self) {
|
||||
self.cards = self
|
||||
.cards
|
||||
.map(|c| if c == Card::Jack { Card::Joker } else { c });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<(Hand, u32)> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let mut splits = line.split(' ');
|
||||
let hand = splits.next().unwrap();
|
||||
let bid: u32 = splits.next().unwrap().parse().unwrap();
|
||||
let hand: Vec<Card> = hand
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'A' => Card::Ace,
|
||||
'K' => Card::King,
|
||||
'Q' => Card::Queen,
|
||||
'J' => Card::Jack,
|
||||
'T' => Card::Tim,
|
||||
'9' => Card::Nine,
|
||||
'8' => Card::Eight,
|
||||
'7' => Card::Seven,
|
||||
'6' => Card::Six,
|
||||
'5' => Card::Five,
|
||||
'4' => Card::Four,
|
||||
'3' => Card::Three,
|
||||
'2' => Card::Two,
|
||||
e => panic!("invalid card {}", e),
|
||||
})
|
||||
.collect();
|
||||
(Hand::new(hand.try_into().unwrap()), bid)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_ord_with_joker_conversion() {
|
||||
let mut input = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
1,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Joker, Card::Joker]),
|
||||
13,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
19,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Joker]),
|
||||
17,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
11,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Joker]),
|
||||
3,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
2,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
5,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Joker, Card::Five]),
|
||||
29,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
7,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Joker, Card::Joker, Card::Tim]),
|
||||
34,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Joker,
|
||||
Card::Ace,
|
||||
]),
|
||||
31,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
37,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
43,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Joker]),
|
||||
59,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
61,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
23,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Two,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
53,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Two,
|
||||
]),
|
||||
41,
|
||||
),
|
||||
];
|
||||
input.iter_mut().for_each(|i| i.0.turn_jacks_to_jokers());
|
||||
input.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
println!("{:#?}", input);
|
||||
//check that the bids are sorted (the input is curated to ensure that the bids are sorted
|
||||
//when the hands are sorted.)
|
||||
assert!(input.windows(2).all(|w| w[0].1 <= w[1].1))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_determine_formation_after_joker_conversion() {
|
||||
let mut tests = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
Formation::HighCard,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Joker, Card::Joker]),
|
||||
Formation::ThreeOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
Formation::FullHouse,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Joker]),
|
||||
Formation::FullHouse,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
Formation::ThreeOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Joker]),
|
||||
Formation::OnePair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
Formation::OnePair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
Formation::OnePair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Joker, Card::Five]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
Formation::TwoPair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Joker, Card::Joker, Card::Tim]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Joker,
|
||||
Card::Ace,
|
||||
]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Joker]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Two,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Two,
|
||||
]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
];
|
||||
tests.iter_mut().for_each(|i| i.0.turn_jacks_to_jokers());
|
||||
for test in tests {
|
||||
assert_eq!(test.0.formation, test.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ord() {
|
||||
let mut input = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
1,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Jack, Card::Jack]),
|
||||
13,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
19,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Jack]),
|
||||
17,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
11,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Jack]),
|
||||
3,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
2,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
5,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Jack, Card::Five]),
|
||||
29,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
7,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Jack, Card::Jack, Card::Tim]),
|
||||
34,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Queen, Card::Queen, Card::Jack, Card::Ace]),
|
||||
31,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
37,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
43,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Jack]),
|
||||
59,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
61,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
23,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
53,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Two]),
|
||||
41,
|
||||
),
|
||||
];
|
||||
input.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
println!("{:#?}", input);
|
||||
assert_eq!(
|
||||
input.iter().map(|h| h.1).collect::<Vec<i32>>(),
|
||||
vec![3, 1, 2, 5, 13, 17, 34, 7, 11, 29, 31, 19, 53, 23, 41, 43, 59, 37, 61]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_determine_formation() {
|
||||
let tests = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
Formation::HighCard,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Jack, Card::Jack]),
|
||||
Formation::OnePair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
Formation::FullHouse,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Jack]),
|
||||
Formation::TwoPair,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
Formation::ThreeOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Jack]),
|
||||
Formation::HighCard,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
Formation::HighCard,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
Formation::OnePair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Jack, Card::Five]),
|
||||
Formation::ThreeOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
Formation::TwoPair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Jack, Card::Jack, Card::Tim]),
|
||||
Formation::TwoPair,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Queen, Card::Queen, Card::Jack, Card::Ace]),
|
||||
Formation::ThreeOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Jack]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FiveOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Two]),
|
||||
Formation::FourOfKind,
|
||||
),
|
||||
];
|
||||
for test in tests {
|
||||
assert_eq!(test.0.formation, test.1)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"2345A 1\n",
|
||||
"Q2KJJ 13\n",
|
||||
"Q2Q2Q 19\n",
|
||||
"T3T3J 17\n",
|
||||
"T3Q33 11\n",
|
||||
"2345J 3\n",
|
||||
"J345A 2\n",
|
||||
"32T3K 5\n",
|
||||
"T55J5 29\n",
|
||||
"KK677 7\n",
|
||||
"KTJJT 34\n",
|
||||
"QQQJA 31\n",
|
||||
"JJJJJ 37\n",
|
||||
"JAAAA 43\n",
|
||||
"AAAAJ 59\n",
|
||||
"AAAAA 61\n",
|
||||
"2AAAA 23\n",
|
||||
"2JJJJ 53\n",
|
||||
"JJJJ2 41\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
1
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Jack, Card::Jack]),
|
||||
13
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
19
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Jack]),
|
||||
17
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three
|
||||
]),
|
||||
11
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Jack]),
|
||||
3
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
2
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
5
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Jack, Card::Five]),
|
||||
29
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
7
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Jack, Card::Jack, Card::Tim]),
|
||||
34
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Queen, Card::Queen, Card::Jack, Card::Ace]),
|
||||
31
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
37
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
43
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Jack]),
|
||||
59
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
61
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
23
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
53
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Two]),
|
||||
41
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
104
2023/days/07/src/part1.rs
Normal file
104
2023/days/07/src/part1.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &mut [(Hand, u32)]) -> usize {
|
||||
input.sort_by(|a, b| a.0.cmp(&b.0) );
|
||||
input
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|i| (i.0 + 1) * i.1 .1 as usize)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let mut input = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
1,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Jack, Card::Jack]),
|
||||
13,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
19,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Jack]),
|
||||
17,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
11,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Jack]),
|
||||
3,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
2,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
5,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Jack, Card::Five]),
|
||||
29,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
7,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Jack, Card::Jack, Card::Tim]),
|
||||
34,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Queen, Card::Queen, Card::Jack, Card::Ace]),
|
||||
31,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
37,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
43,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Jack]),
|
||||
59,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
61,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
23,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Jack, Card::Jack, Card::Jack, Card::Jack]),
|
||||
53,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Jack, Card::Jack, Card::Jack, Card::Jack, Card::Two]),
|
||||
41,
|
||||
),
|
||||
];
|
||||
assert_eq!(part1(&mut input), 6592);
|
||||
}
|
||||
}
|
||||
129
2023/days/07/src/part2.rs
Normal file
129
2023/days/07/src/part2.rs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &mut [(Hand, u32)]) -> usize {
|
||||
input.iter_mut().for_each(|i| i.0.turn_jacks_to_jokers());
|
||||
input.sort_by(|a, b| a.0.cmp(&b.0) );
|
||||
input
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|i| (i.0 + 1) * i.1 .1 as usize)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let mut input = vec![
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
1,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::King, Card::Joker, Card::Joker]),
|
||||
13,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Queen, Card::Two, Card::Queen, Card::Two, Card::Queen]),
|
||||
19,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Three, Card::Tim, Card::Three, Card::Joker]),
|
||||
17,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Tim,
|
||||
Card::Three,
|
||||
Card::Queen,
|
||||
Card::Three,
|
||||
Card::Three,
|
||||
]),
|
||||
11,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Three, Card::Four, Card::Five, Card::Joker]),
|
||||
3,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Three, Card::Four, Card::Five, Card::Ace]),
|
||||
2,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Three, Card::Two, Card::Tim, Card::Three, Card::King]),
|
||||
5,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Tim, Card::Five, Card::Five, Card::Joker, Card::Five]),
|
||||
29,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::King, Card::Six, Card::Seven, Card::Seven]),
|
||||
7,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::King, Card::Tim, Card::Joker, Card::Joker, Card::Tim]),
|
||||
34,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Queen,
|
||||
Card::Joker,
|
||||
Card::Ace,
|
||||
]),
|
||||
31,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
37,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Joker, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
43,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Joker]),
|
||||
59,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Ace, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
61,
|
||||
),
|
||||
(
|
||||
Hand::new([Card::Two, Card::Ace, Card::Ace, Card::Ace, Card::Ace]),
|
||||
23,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Two,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
]),
|
||||
53,
|
||||
),
|
||||
(
|
||||
Hand::new([
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Joker,
|
||||
Card::Two,
|
||||
]),
|
||||
41,
|
||||
),
|
||||
];
|
||||
assert_eq!(part2(&mut input), 6839);
|
||||
}
|
||||
}
|
||||
12
2023/days/08/Cargo.toml
Normal file
12
2023/days/08/Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "day08"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
regex.workspace = true
|
||||
once_cell.workspace = true
|
||||
collection_literals.workspace = true
|
||||
752
2023/days/08/src/input.txt
Normal file
752
2023/days/08/src/input.txt
Normal file
|
|
@ -0,0 +1,752 @@
|
|||
LLRRLRRRLLRLRRLLLLRLRRLRRRLRLRRRLLRRLRRRLLRRLRRLRRLLRRRLRRLRRLRRRLRRLRLRLRRLRRLRRRLLRRLLLRRLRRRLRRRLRRRLRRLRRRLRLLRLRRRLRLRRLLRLRRRLRRRLRLRRRLRRRLRLRLRRLRRLRLRRLLRRRLRRRLRRRLLRRRLRLRLRLRLLRRRLRRRLRRLRRRLLRLRRLRRLRRRLRRRLRRLRLRLRRRLRRLRRLRRRLLRRLRLRLRRRLRLRLRRLRRLLRRLRRRLLRLLRLRLRRRR
|
||||
|
||||
FGF = (HTC, DTX)
|
||||
PTP = (MCL, BDN)
|
||||
LHL = (LJF, BDX)
|
||||
XMM = (KCX, JHL)
|
||||
GLD = (RNN, MXG)
|
||||
HSR = (JPX, CXF)
|
||||
CRF = (BMJ, FHT)
|
||||
QSS = (KPH, FVD)
|
||||
RHV = (LRD, XDS)
|
||||
KTT = (XPS, VCX)
|
||||
LQK = (TLF, VJX)
|
||||
MMK = (VJV, HQV)
|
||||
RKX = (RKG, XJB)
|
||||
HDM = (NFK, JNB)
|
||||
PFJ = (QDJ, NDH)
|
||||
JKB = (MDK, MRJ)
|
||||
BSP = (QBQ, JPM)
|
||||
FQH = (HJD, VHF)
|
||||
QQL = (VDB, KGM)
|
||||
TRB = (KTC, RGN)
|
||||
VXC = (NDK, MVK)
|
||||
BCS = (PSX, PLK)
|
||||
FHK = (MLK, RDP)
|
||||
TVB = (JXV, SSR)
|
||||
GXD = (KSF, BRK)
|
||||
MNJ = (MHG, CRF)
|
||||
RLC = (TGD, CHV)
|
||||
LBQ = (NQK, MHP)
|
||||
JLH = (FGB, KNM)
|
||||
PCN = (CQF, NDF)
|
||||
FVP = (NKS, RCB)
|
||||
GHL = (TTB, KLQ)
|
||||
MTB = (VDM, FKT)
|
||||
LLB = (VXL, TRT)
|
||||
RSS = (GDP, TKD)
|
||||
SFH = (FCM, GKF)
|
||||
KSF = (VQB, JXJ)
|
||||
LJH = (PNS, DGC)
|
||||
TJC = (KQM, BVL)
|
||||
PRL = (TCG, GCQ)
|
||||
NBG = (GNR, SRM)
|
||||
CST = (FXL, BDF)
|
||||
XXH = (KVH, KSM)
|
||||
FJP = (PKX, DSF)
|
||||
DTS = (FFF, DQM)
|
||||
CMG = (VBJ, DBF)
|
||||
NHD = (TCJ, DHF)
|
||||
KKF = (RVP, FVR)
|
||||
LDS = (VPJ, MPN)
|
||||
GHC = (DBK, SCS)
|
||||
KVK = (NFV, MXJ)
|
||||
NTN = (TDC, VNC)
|
||||
FCR = (DCR, FQH)
|
||||
PLK = (GHT, PBT)
|
||||
VJF = (VJN, PVB)
|
||||
TKR = (GHS, TTP)
|
||||
PQJ = (VGB, SGP)
|
||||
TGM = (JQM, PPK)
|
||||
LFQ = (QGB, QXB)
|
||||
RDP = (HSF, MQV)
|
||||
SGP = (HVK, XMV)
|
||||
FTB = (RFV, MLT)
|
||||
LCX = (RSB, RSB)
|
||||
VGD = (XJB, RKG)
|
||||
PFD = (RGK, JGB)
|
||||
DBK = (RMP, RSH)
|
||||
TTC = (NDH, QDJ)
|
||||
PVF = (QRG, QCV)
|
||||
BGV = (TDS, DRK)
|
||||
VHF = (XTB, TGM)
|
||||
DBF = (GGT, BRQ)
|
||||
TFG = (SVV, FCV)
|
||||
MDK = (THF, PLQ)
|
||||
NDF = (BSP, STC)
|
||||
SMZ = (KHB, TST)
|
||||
SLC = (BKM, BCS)
|
||||
NSV = (VVM, VQG)
|
||||
GCA = (XQT, RCD)
|
||||
FVD = (NXJ, MBJ)
|
||||
HCH = (MRF, RQJ)
|
||||
PLN = (BNK, CLF)
|
||||
TTP = (BCP, SLC)
|
||||
BRF = (SHR, CTK)
|
||||
KCX = (PDR, HHQ)
|
||||
GMG = (NFV, MXJ)
|
||||
SNN = (XDS, LRD)
|
||||
SBB = (JXL, BFK)
|
||||
NCV = (KVH, KSM)
|
||||
DQQ = (FFF, DQM)
|
||||
THT = (MFP, VSD)
|
||||
GVH = (KHF, TKB)
|
||||
HPC = (MKX, SVS)
|
||||
KSS = (QQQ, HSR)
|
||||
NCP = (FCV, SVV)
|
||||
FGB = (LGN, LKJ)
|
||||
TST = (DFV, GND)
|
||||
PJR = (VMQ, HPB)
|
||||
BHB = (VMQ, HPB)
|
||||
LMG = (SHS, XJC)
|
||||
GGT = (TQQ, XQK)
|
||||
PKR = (QQR, JGG)
|
||||
FLR = (LJP, VQT)
|
||||
NFK = (HKG, BPJ)
|
||||
MGG = (SST, MCT)
|
||||
BVD = (SNV, TTH)
|
||||
GHX = (GMK, JXG)
|
||||
PDR = (HCD, HNG)
|
||||
XJN = (NHR, CBN)
|
||||
XRG = (LBQ, MTV)
|
||||
VFM = (MMS, VXT)
|
||||
PPP = (LHR, HJH)
|
||||
FJG = (NLS, CCF)
|
||||
NDK = (RHD, BVD)
|
||||
VSB = (LKB, CCX)
|
||||
NJG = (PTK, MCD)
|
||||
MLS = (XCQ, FCR)
|
||||
QSM = (CBJ, GRG)
|
||||
PTC = (NJG, FLT)
|
||||
MRJ = (PLQ, THF)
|
||||
HJD = (XTB, TGM)
|
||||
XCQ = (DCR, FQH)
|
||||
HPN = (CQD, CTP)
|
||||
BDJ = (JND, JRB)
|
||||
PXL = (VXT, MMS)
|
||||
NFV = (SFX, BDQ)
|
||||
SNQ = (PQJ, TNG)
|
||||
LSL = (KFN, JFL)
|
||||
SMK = (FQS, FJJ)
|
||||
QDV = (BDX, LJF)
|
||||
GMK = (TSJ, SVF)
|
||||
GDP = (MML, MML)
|
||||
GRG = (PVF, CKG)
|
||||
CXF = (MNJ, TBZ)
|
||||
LKM = (HJH, LHR)
|
||||
GHS = (BCP, SLC)
|
||||
XBH = (BDS, NDQ)
|
||||
NLL = (NJT, QCJ)
|
||||
MXJ = (BDQ, SFX)
|
||||
FCF = (QQQ, QQQ)
|
||||
SXG = (LFQ, TTZ)
|
||||
PLP = (MJL, FPL)
|
||||
FSV = (SBB, JFC)
|
||||
NLH = (TDS, DRK)
|
||||
QDM = (GHX, GGM)
|
||||
JJB = (MSQ, MMK)
|
||||
TRS = (BXN, RLM)
|
||||
DMP = (RTP, CHG)
|
||||
XGG = (PCC, XKH)
|
||||
MCT = (NLK, DTM)
|
||||
DLC = (JTQ, BLF)
|
||||
VBJ = (GGT, BRQ)
|
||||
XQD = (NTN, XRC)
|
||||
FKM = (QKK, JBQ)
|
||||
PNN = (RGN, KTC)
|
||||
LCM = (DTG, GHC)
|
||||
LKJ = (LFV, RNG)
|
||||
HRR = (JND, JRB)
|
||||
BDN = (SNQ, NVC)
|
||||
RSH = (PJS, LHG)
|
||||
CTP = (DJM, NHF)
|
||||
XMV = (CFJ, MDV)
|
||||
HXM = (PTP, XVQ)
|
||||
CKG = (QCV, QRG)
|
||||
GKK = (CRG, MPJ)
|
||||
LNS = (VSB, GNQ)
|
||||
RVP = (JJB, LCN)
|
||||
DVH = (QLD, QGV)
|
||||
CPH = (PMN, QSC)
|
||||
BXQ = (CPH, DSQ)
|
||||
SDM = (DSB, CNV)
|
||||
RNN = (SHM, LSL)
|
||||
VQC = (GKH, DMP)
|
||||
KXV = (GKN, PTC)
|
||||
TNK = (NMK, PKR)
|
||||
TSL = (MTV, LBQ)
|
||||
VSD = (LGH, HNM)
|
||||
QRQ = (QXH, GRQ)
|
||||
NKS = (NSL, HPN)
|
||||
TQC = (JQK, TXF)
|
||||
THF = (TVM, KKF)
|
||||
VSL = (PLN, GDS)
|
||||
SSN = (FTB, NXF)
|
||||
NHF = (BFG, XTZ)
|
||||
HSP = (QRQ, DFC)
|
||||
JQM = (BNP, PMD)
|
||||
GDV = (RVK, MQF)
|
||||
MTK = (TGD, CHV)
|
||||
FFX = (DSN, XXJ)
|
||||
HKG = (THT, KNJ)
|
||||
RCN = (DCB, XFN)
|
||||
HCD = (TDF, BQM)
|
||||
TKJ = (JPV, GRR)
|
||||
RVK = (HXX, PRL)
|
||||
HDN = (TRT, VXL)
|
||||
KHQ = (DQQ, DTS)
|
||||
MPJ = (PLP, KBG)
|
||||
SFX = (KTT, NTG)
|
||||
NMJ = (BGV, NLH)
|
||||
LXK = (CRB, GXD)
|
||||
KBG = (FPL, MJL)
|
||||
GNQ = (LKB, CCX)
|
||||
MRV = (RVK, MQF)
|
||||
PKH = (NPN, MHQ)
|
||||
NLK = (LTJ, RXP)
|
||||
LBH = (VTP, SGG)
|
||||
NTG = (VCX, XPS)
|
||||
CCD = (GVF, SSJ)
|
||||
BBB = (SSR, JXV)
|
||||
NSL = (CQD, CQD)
|
||||
BNK = (SGS, JQD)
|
||||
TTB = (KVK, GMG)
|
||||
FDR = (RBS, TXD)
|
||||
PJG = (RTV, JQS)
|
||||
LGV = (LSB, NPF)
|
||||
XVQ = (MCL, BDN)
|
||||
BMJ = (KRT, XXN)
|
||||
XCM = (LXK, VKJ)
|
||||
CCF = (SDR, PTQ)
|
||||
GSS = (PJR, BHB)
|
||||
CJL = (QKK, JBQ)
|
||||
FBT = (VJF, SGL)
|
||||
DSB = (QKQ, RBK)
|
||||
SGS = (MLQ, PXT)
|
||||
PKX = (KPF, CNQ)
|
||||
JND = (SDG, SND)
|
||||
DJM = (BFG, BFG)
|
||||
LHK = (SBB, JFC)
|
||||
QLD = (SGX, KDP)
|
||||
NPF = (VDC, KHQ)
|
||||
BRQ = (XQK, TQQ)
|
||||
NGQ = (JNB, NFK)
|
||||
NFH = (MPN, VPJ)
|
||||
KHF = (LKG, GLD)
|
||||
XKC = (XTX, XTX)
|
||||
DJG = (XGL, BTF)
|
||||
LGN = (RNG, LFV)
|
||||
HQV = (CJL, FKM)
|
||||
JPV = (SVD, XJN)
|
||||
TSJ = (NMD, MGG)
|
||||
QRG = (HBD, CST)
|
||||
FXL = (PFX, HVV)
|
||||
TNG = (VGB, SGP)
|
||||
HXX = (GCQ, TCG)
|
||||
RTP = (CDD, QJR)
|
||||
RXN = (LFQ, LFQ)
|
||||
MVK = (BVD, RHD)
|
||||
PLR = (FVP, DHP)
|
||||
GRR = (XJN, SVD)
|
||||
DHJ = (VRN, DTR)
|
||||
HSF = (TSS, JSQ)
|
||||
TXN = (FGF, NMV)
|
||||
CBJ = (CKG, PVF)
|
||||
GHT = (RCN, NTR)
|
||||
SMH = (FJG, LQD)
|
||||
CVN = (PLR, DDF)
|
||||
SJK = (TTF, SLQ)
|
||||
LMN = (XHT, CFF)
|
||||
KLQ = (GMG, KVK)
|
||||
KXC = (CHP, NLL)
|
||||
KNM = (LKJ, LGN)
|
||||
QHK = (LNV, GKK)
|
||||
BTH = (KVR, FNQ)
|
||||
QFV = (PRK, LTV)
|
||||
DBH = (HND, HFC)
|
||||
CRG = (KBG, PLP)
|
||||
TCG = (DVF, BXQ)
|
||||
SJQ = (KPR, QKP)
|
||||
JMJ = (TTB, KLQ)
|
||||
RFV = (XBH, CGX)
|
||||
AAA = (QDM, GMV)
|
||||
JTQ = (HRR, BDJ)
|
||||
MHQ = (HPQ, KXC)
|
||||
SDG = (HGR, RJN)
|
||||
PNS = (FMC, JKB)
|
||||
KHB = (DFV, GND)
|
||||
NXJ = (MLS, HLT)
|
||||
HND = (LVF, BBJ)
|
||||
FCZ = (RCD, XQT)
|
||||
NFP = (FVD, KPH)
|
||||
NTH = (FVH, DJG)
|
||||
GMV = (GHX, GGM)
|
||||
FKT = (CLC, BTH)
|
||||
LTV = (BKP, HVT)
|
||||
VLF = (DLX, FMB)
|
||||
NNP = (NFH, LDS)
|
||||
GQV = (RTR, NMJ)
|
||||
MCD = (PFK, HPC)
|
||||
XML = (RNR, GJF)
|
||||
TXD = (LGT, QSM)
|
||||
DKG = (RTV, JQS)
|
||||
MQF = (PRL, HXX)
|
||||
XJB = (HKV, FLR)
|
||||
SHS = (VVH, CHN)
|
||||
PMD = (NSV, BMQ)
|
||||
TLJ = (DMP, GKH)
|
||||
CMA = (TST, KHB)
|
||||
CRB = (KSF, BRK)
|
||||
XQT = (TXN, LNN)
|
||||
QHF = (XKH, PCC)
|
||||
FQM = (PKR, NMK)
|
||||
DHP = (NKS, RCB)
|
||||
KSM = (DKP, SDM)
|
||||
LKB = (RQV, BRF)
|
||||
BVL = (TRB, PNN)
|
||||
GJF = (NTH, JRX)
|
||||
HTC = (HRL, HXM)
|
||||
JGB = (QVX, GMR)
|
||||
VJV = (CJL, FKM)
|
||||
RGK = (QVX, GMR)
|
||||
KPF = (JCK, XDV)
|
||||
LNV = (CRG, MPJ)
|
||||
QNP = (LXK, VKJ)
|
||||
MFT = (NJK, VVL)
|
||||
PBT = (RCN, NTR)
|
||||
CKV = (XHT, CFF)
|
||||
RCD = (TXN, LNN)
|
||||
MBJ = (HLT, MLS)
|
||||
QDC = (NMJ, RTR)
|
||||
SVV = (FJC, MJR)
|
||||
STN = (LQC, HFR)
|
||||
QXB = (RPJ, MHL)
|
||||
VJN = (TVB, BBB)
|
||||
GKH = (RTP, CHG)
|
||||
XGL = (PMX, FFX)
|
||||
KNH = (FGB, KNM)
|
||||
TVN = (QKP, KPR)
|
||||
JFC = (BFK, JXL)
|
||||
LHG = (TFG, NCP)
|
||||
HFT = (HND, HFC)
|
||||
DKP = (DSB, CNV)
|
||||
LGH = (DCG, QPN)
|
||||
LGC = (VVL, NJK)
|
||||
HSC = (NTJ, QQL)
|
||||
CFF = (JMJ, GHL)
|
||||
PFH = (SGL, VJF)
|
||||
LGT = (GRG, CBJ)
|
||||
JSQ = (SFH, RVQ)
|
||||
VDM = (CLC, BTH)
|
||||
NTR = (DCB, XFN)
|
||||
KVH = (DKP, SDM)
|
||||
BVQ = (LSH, SDX)
|
||||
NRC = (QCH, TRS)
|
||||
DCB = (KBT, TSR)
|
||||
DGC = (FMC, JKB)
|
||||
VMQ = (LJR, LJR)
|
||||
MXG = (LSL, SHM)
|
||||
CPM = (TRS, QCH)
|
||||
DLX = (LQN, TJC)
|
||||
GDS = (BNK, CLF)
|
||||
JRK = (PGJ, NHD)
|
||||
JXV = (DRH, CVN)
|
||||
SVD = (CBN, NHR)
|
||||
LCN = (MSQ, MMK)
|
||||
MJL = (RQL, RGF)
|
||||
JLT = (QRQ, DFC)
|
||||
BGP = (DPV, VXC)
|
||||
PSQ = (PJR, BHB)
|
||||
NTJ = (KGM, VDB)
|
||||
SGX = (VFM, PXL)
|
||||
QBQ = (MCM, VNV)
|
||||
CHV = (QJN, CMG)
|
||||
DRK = (BKT, LBH)
|
||||
SVS = (NPV, HCH)
|
||||
BCP = (BKM, BCS)
|
||||
BXN = (PSQ, GSS)
|
||||
GQJ = (SMH, XHX)
|
||||
NPV = (RQJ, MRF)
|
||||
NMV = (HTC, DTX)
|
||||
LKR = (SPG, SJK)
|
||||
HLT = (XCQ, FCR)
|
||||
SKX = (HSC, CFR)
|
||||
SDR = (BLQ, FKV)
|
||||
FCN = (FKT, VDM)
|
||||
VPB = (CJR, FHK)
|
||||
MHL = (PFJ, TTC)
|
||||
XQK = (BBK, PBQ)
|
||||
MDV = (SCJ, BKF)
|
||||
VDC = (DQQ, DTS)
|
||||
RTV = (LDP, PCN)
|
||||
GRQ = (FDR, DHG)
|
||||
NDH = (JGX, SSN)
|
||||
NCG = (GNR, SRM)
|
||||
LQN = (BVL, KQM)
|
||||
NHR = (FQM, TNK)
|
||||
LJR = (GDP, GDP)
|
||||
JXL = (VKV, MJQ)
|
||||
QCH = (BXN, RLM)
|
||||
QGB = (MHL, RPJ)
|
||||
DDN = (GLT, DHJ)
|
||||
SHR = (BGP, FCX)
|
||||
DPV = (MVK, NDK)
|
||||
XHT = (GHL, JMJ)
|
||||
QKK = (LCX, LCX)
|
||||
TRT = (QFV, NHT)
|
||||
PBQ = (DPX, LNS)
|
||||
JHL = (HHQ, PDR)
|
||||
DCG = (JLX, VSL)
|
||||
SST = (NLK, DTM)
|
||||
QPN = (JLX, VSL)
|
||||
GXS = (FJP, DCM)
|
||||
VJX = (DKB, FCZ)
|
||||
XXJ = (HDN, LLB)
|
||||
JPM = (VNV, MCM)
|
||||
QGV = (SGX, KDP)
|
||||
QNA = (QGB, QXB)
|
||||
CQD = (DJM, DJM)
|
||||
TTF = (TVN, SJQ)
|
||||
CHP = (QCJ, NJT)
|
||||
BBJ = (LVT, TKJ)
|
||||
VKJ = (CRB, GXD)
|
||||
LJF = (FFL, KXV)
|
||||
TKD = (MML, ZZZ)
|
||||
QKP = (CKV, LMN)
|
||||
CQF = (STC, BSP)
|
||||
PHM = (FHK, CJR)
|
||||
BTF = (PMX, FFX)
|
||||
JRX = (FVH, DJG)
|
||||
PMN = (NBG, NCG)
|
||||
LKG = (RNN, MXG)
|
||||
NXB = (JLH, KNH)
|
||||
MLQ = (FBT, PFH)
|
||||
JML = (XKC, GLX)
|
||||
NHT = (PRK, LTV)
|
||||
BLQ = (SKX, HGL)
|
||||
BDX = (FFL, KXV)
|
||||
DVN = (SCR, JML)
|
||||
FPL = (RQL, RGF)
|
||||
MMS = (SVR, KSV)
|
||||
FLT = (PTK, MCD)
|
||||
PTQ = (BLQ, FKV)
|
||||
DHG = (RBS, TXD)
|
||||
QSC = (NCG, NBG)
|
||||
LFV = (NXP, GMF)
|
||||
XDS = (KQP, STN)
|
||||
PVB = (BBB, TVB)
|
||||
JGX = (NXF, FTB)
|
||||
CNB = (PRR, JRK)
|
||||
TQQ = (PBQ, BBK)
|
||||
GMF = (MKH, CRH)
|
||||
SDP = (KCQ, PKV)
|
||||
MHP = (HMR, LCM)
|
||||
RRS = (QGV, QLD)
|
||||
PKV = (XKG, HTH)
|
||||
JLX = (GDS, PLN)
|
||||
RJN = (VGD, RKX)
|
||||
NMK = (QQR, JGG)
|
||||
PFK = (SVS, MKX)
|
||||
NXF = (MLT, RFV)
|
||||
VVM = (HDM, NGQ)
|
||||
VSJ = (QDG, VKM)
|
||||
RBS = (QSM, LGT)
|
||||
KFN = (RRS, DVH)
|
||||
XXN = (XMM, SKM)
|
||||
TXF = (LKM, PPP)
|
||||
DFV = (VLF, GPC)
|
||||
RMP = (PJS, LHG)
|
||||
LVP = (QDG, VKM)
|
||||
DFC = (QXH, GRQ)
|
||||
GPC = (DLX, FMB)
|
||||
LJP = (CCD, FSM)
|
||||
MPN = (PFD, RSN)
|
||||
SGG = (RHV, SNN)
|
||||
BDF = (HVV, PFX)
|
||||
QQR = (GVH, QSB)
|
||||
RPJ = (TTC, PFJ)
|
||||
NDQ = (NXV, XQD)
|
||||
RGF = (BVQ, GMB)
|
||||
TXM = (DCM, FJP)
|
||||
VRN = (XFV, MFG)
|
||||
FCX = (VXC, DPV)
|
||||
RQJ = (HFT, DBH)
|
||||
MLT = (CGX, XBH)
|
||||
TSR = (QSS, NFP)
|
||||
BCD = (VQC, TLJ)
|
||||
JQK = (PPP, LKM)
|
||||
DSF = (CNQ, KPF)
|
||||
CVS = (LDS, NFH)
|
||||
VTP = (SNN, RHV)
|
||||
FTA = (MHG, CRF)
|
||||
RNR = (NTH, JRX)
|
||||
DRH = (PLR, DDF)
|
||||
KSV = (SMK, NHC)
|
||||
VKM = (HFV, LMG)
|
||||
DTR = (XFV, MFG)
|
||||
MML = (QDM, GMV)
|
||||
HPQ = (CHP, NLL)
|
||||
GKF = (QHK, TDM)
|
||||
TDF = (DHX, LPT)
|
||||
PXT = (FBT, PFH)
|
||||
BRK = (VQB, JXJ)
|
||||
VXT = (KSV, SVR)
|
||||
HNM = (QPN, DCG)
|
||||
HHQ = (HNG, HCD)
|
||||
MPG = (JJS, SMZ)
|
||||
CGS = (QDC, GQV)
|
||||
GMR = (GQJ, RMH)
|
||||
BKF = (CNB, NKP)
|
||||
VDB = (VPB, PHM)
|
||||
DSQ = (PMN, QSC)
|
||||
DTX = (HRL, HXM)
|
||||
QXH = (FDR, DHG)
|
||||
LPT = (QDV, LHL)
|
||||
DKB = (XQT, RCD)
|
||||
QJN = (VBJ, DBF)
|
||||
FVR = (JJB, LCN)
|
||||
MFG = (CPM, NRC)
|
||||
FMC = (MDK, MRJ)
|
||||
JLL = (RXN, SXG)
|
||||
NQK = (LCM, HMR)
|
||||
KBT = (QSS, NFP)
|
||||
DHX = (QDV, LHL)
|
||||
SKM = (JHL, KCX)
|
||||
FSM = (SSJ, GVF)
|
||||
NVC = (TNG, PQJ)
|
||||
SRM = (HSP, JLT)
|
||||
FCM = (TDM, QHK)
|
||||
NPN = (HPQ, KXC)
|
||||
JGG = (QSB, GVH)
|
||||
DCM = (DSF, PKX)
|
||||
BLF = (BDJ, HRR)
|
||||
JXJ = (JCC, LGV)
|
||||
PSX = (PBT, GHT)
|
||||
CRH = (NXX, BCD)
|
||||
SCS = (RSH, RMP)
|
||||
LTJ = (FSV, LHK)
|
||||
PSV = (PKV, KCQ)
|
||||
TVM = (FVR, RVP)
|
||||
LSH = (DDN, HNX)
|
||||
XTX = (RXN, RXN)
|
||||
RKG = (FLR, HKV)
|
||||
JNB = (BPJ, HKG)
|
||||
GKN = (NJG, FLT)
|
||||
RLM = (PSQ, GSS)
|
||||
CNQ = (XDV, JCK)
|
||||
HFR = (TQC, KLB)
|
||||
RQV = (SHR, CTK)
|
||||
DSN = (HDN, LLB)
|
||||
FFF = (KSR, KSR)
|
||||
FJJ = (FCF, KSS)
|
||||
KPH = (NXJ, MBJ)
|
||||
KCQ = (XKG, HTH)
|
||||
PPK = (BNP, PMD)
|
||||
TKB = (LKG, GLD)
|
||||
JQD = (MLQ, PXT)
|
||||
BPJ = (THT, KNJ)
|
||||
RBK = (FCN, MTB)
|
||||
PDK = (GHS, TTP)
|
||||
SDX = (DDN, HNX)
|
||||
BQM = (DHX, LPT)
|
||||
KNJ = (MFP, VSD)
|
||||
CLC = (FNQ, KVR)
|
||||
XPS = (NXB, SXK)
|
||||
CLF = (JQD, SGS)
|
||||
DQM = (KSR, LQK)
|
||||
XKG = (MRV, GDV)
|
||||
RHD = (TTH, SNV)
|
||||
RTR = (BGV, NLH)
|
||||
QSB = (TKB, KHF)
|
||||
BKP = (PJG, DKG)
|
||||
RMH = (XHX, SMH)
|
||||
PGR = (PNS, DGC)
|
||||
GND = (VLF, GPC)
|
||||
PCC = (QNP, XCM)
|
||||
KDP = (PXL, VFM)
|
||||
SPG = (TTF, SLQ)
|
||||
SXK = (KNH, JLH)
|
||||
PFX = (MFT, LGC)
|
||||
BKM = (PLK, PSX)
|
||||
TGD = (CMG, QJN)
|
||||
NXV = (NTN, XRC)
|
||||
MFP = (HNM, LGH)
|
||||
MQQ = (RSB, MPG)
|
||||
TBZ = (CRF, MHG)
|
||||
XDV = (TKR, PDK)
|
||||
DVF = (CPH, DSQ)
|
||||
SNV = (GXS, TXM)
|
||||
DCR = (HJD, VHF)
|
||||
QDG = (LMG, HFV)
|
||||
MHG = (FHT, BMJ)
|
||||
NKP = (PRR, JRK)
|
||||
XRC = (VNC, TDC)
|
||||
JFL = (RRS, DVH)
|
||||
KRT = (SKM, XMM)
|
||||
CDD = (DVN, PDM)
|
||||
NXP = (MKH, CRH)
|
||||
LVT = (GRR, JPV)
|
||||
NJT = (RLC, MTK)
|
||||
HVV = (MFT, LGC)
|
||||
RNG = (GMF, NXP)
|
||||
SVR = (SMK, NHC)
|
||||
QDJ = (SSN, JGX)
|
||||
RQL = (BVQ, GMB)
|
||||
HMR = (GHC, DTG)
|
||||
CGX = (BDS, NDQ)
|
||||
MJQ = (LVP, VSJ)
|
||||
XJC = (CHN, VVH)
|
||||
FFL = (GKN, PTC)
|
||||
XJS = (SJK, SPG)
|
||||
JQS = (PCN, LDP)
|
||||
SHM = (JFL, KFN)
|
||||
HPB = (LJR, RSS)
|
||||
JXG = (SVF, TSJ)
|
||||
STC = (QBQ, JPM)
|
||||
FHT = (XXN, KRT)
|
||||
LRD = (KQP, STN)
|
||||
VCX = (SXK, NXB)
|
||||
KSR = (TLF, TLF)
|
||||
KQM = (PNN, TRB)
|
||||
KTC = (TSL, XRG)
|
||||
VKV = (VSJ, LVP)
|
||||
XTB = (PPK, JQM)
|
||||
BFK = (MJQ, VKV)
|
||||
GLT = (VRN, DTR)
|
||||
VPJ = (PFD, RSN)
|
||||
BKT = (SGG, VTP)
|
||||
BMQ = (VVM, VQG)
|
||||
KVR = (QHF, XGG)
|
||||
LNH = (QDC, GQV)
|
||||
SLQ = (SJQ, TVN)
|
||||
CJR = (RDP, MLK)
|
||||
JCK = (TKR, PDK)
|
||||
GVF = (XXH, NCV)
|
||||
LQC = (TQC, KLB)
|
||||
TSS = (SFH, RVQ)
|
||||
HRL = (XVQ, PTP)
|
||||
TDM = (GKK, LNV)
|
||||
BNP = (BMQ, NSV)
|
||||
BFG = (RNQ, PKH)
|
||||
CFJ = (BKF, SCJ)
|
||||
QQQ = (JPX, JPX)
|
||||
MQV = (JSQ, TSS)
|
||||
XHX = (LQD, FJG)
|
||||
PMX = (XXJ, DSN)
|
||||
KGM = (VPB, PHM)
|
||||
GNR = (JLT, HSP)
|
||||
NLS = (PTQ, SDR)
|
||||
MSQ = (VJV, HQV)
|
||||
FMB = (TJC, LQN)
|
||||
XFV = (NRC, CPM)
|
||||
RSN = (JGB, RGK)
|
||||
PRK = (HVT, BKP)
|
||||
HFV = (XJC, SHS)
|
||||
SVF = (NMD, MGG)
|
||||
QVX = (GQJ, RMH)
|
||||
TCF = (BLF, JTQ)
|
||||
MLK = (HSF, MQV)
|
||||
RVQ = (FCM, GKF)
|
||||
GLX = (XTX, JLL)
|
||||
PDM = (SCR, JML)
|
||||
HGR = (RKX, VGD)
|
||||
JRB = (SND, SDG)
|
||||
FKV = (SKX, HGL)
|
||||
TDC = (LNH, CGS)
|
||||
FVH = (XGL, BTF)
|
||||
NHC = (FQS, FJJ)
|
||||
BBK = (LNS, DPX)
|
||||
VVH = (NNP, CVS)
|
||||
NJK = (DLC, TCF)
|
||||
SGL = (VJN, PVB)
|
||||
MTV = (NQK, MHP)
|
||||
PJS = (TFG, NCP)
|
||||
DTG = (SCS, DBK)
|
||||
TCJ = (SDP, PSV)
|
||||
VGB = (HVK, XMV)
|
||||
MCL = (SNQ, NVC)
|
||||
NXX = (TLJ, VQC)
|
||||
HVK = (MDV, CFJ)
|
||||
NMD = (MCT, SST)
|
||||
TTZ = (QXB, QGB)
|
||||
VNC = (LNH, CGS)
|
||||
GMB = (LSH, SDX)
|
||||
CHN = (NNP, CVS)
|
||||
FCV = (MJR, FJC)
|
||||
HNG = (TDF, BQM)
|
||||
SCR = (XKC, GLX)
|
||||
DDF = (DHP, FVP)
|
||||
CTK = (BGP, FCX)
|
||||
CHG = (QJR, CDD)
|
||||
VXL = (QFV, NHT)
|
||||
SSJ = (XXH, NCV)
|
||||
RNQ = (NPN, MHQ)
|
||||
FJC = (XJF, XML)
|
||||
XTZ = (PKH, RNQ)
|
||||
CBN = (TNK, FQM)
|
||||
RSB = (JJS, JJS)
|
||||
TTH = (GXS, TXM)
|
||||
HJH = (LKR, XJS)
|
||||
VQB = (JCC, LGV)
|
||||
HKV = (LJP, VQT)
|
||||
RGN = (XRG, TSL)
|
||||
MKX = (NPV, HCH)
|
||||
JJS = (TST, KHB)
|
||||
JPX = (MNJ, MNJ)
|
||||
HTH = (MRV, GDV)
|
||||
VQT = (CCD, FSM)
|
||||
PGJ = (DHF, TCJ)
|
||||
DHF = (SDP, PSV)
|
||||
XJF = (GJF, RNR)
|
||||
LQD = (CCF, NLS)
|
||||
MRF = (DBH, HFT)
|
||||
FNQ = (XGG, QHF)
|
||||
GGM = (JXG, GMK)
|
||||
BDS = (NXV, XQD)
|
||||
MCM = (PGR, LJH)
|
||||
LDP = (NDF, CQF)
|
||||
QCJ = (RLC, MTK)
|
||||
CCX = (RQV, BRF)
|
||||
HBD = (BDF, FXL)
|
||||
CBA = (RNQ, PKH)
|
||||
MJR = (XJF, XML)
|
||||
JCC = (LSB, NPF)
|
||||
VQG = (NGQ, HDM)
|
||||
RCB = (NSL, HPN)
|
||||
QCV = (HBD, CST)
|
||||
TDS = (LBH, BKT)
|
||||
CNV = (QKQ, RBK)
|
||||
KLB = (JQK, TXF)
|
||||
XKH = (QNP, XCM)
|
||||
SCJ = (CNB, NKP)
|
||||
HGL = (CFR, HSC)
|
||||
BDQ = (NTG, KTT)
|
||||
PRR = (PGJ, NHD)
|
||||
KPR = (CKV, LMN)
|
||||
HFC = (LVF, BBJ)
|
||||
TLF = (DKB, DKB)
|
||||
SND = (HGR, RJN)
|
||||
VNV = (PGR, LJH)
|
||||
PLQ = (KKF, TVM)
|
||||
LVF = (LVT, TKJ)
|
||||
QJR = (PDM, DVN)
|
||||
HVT = (DKG, PJG)
|
||||
CFR = (QQL, NTJ)
|
||||
DTM = (LTJ, RXP)
|
||||
HNX = (GLT, DHJ)
|
||||
QKQ = (FCN, MTB)
|
||||
PTK = (HPC, PFK)
|
||||
FQS = (FCF, KSS)
|
||||
JBQ = (LCX, MQQ)
|
||||
RXP = (LHK, FSV)
|
||||
SSR = (DRH, CVN)
|
||||
LSB = (VDC, KHQ)
|
||||
DPX = (GNQ, VSB)
|
||||
ZZZ = (GMV, QDM)
|
||||
XFN = (TSR, KBT)
|
||||
LNN = (NMV, FGF)
|
||||
KQP = (LQC, HFR)
|
||||
LHR = (XJS, LKR)
|
||||
GCQ = (DVF, BXQ)
|
||||
VVL = (TCF, DLC)
|
||||
MKH = (NXX, BCD)
|
||||
14
2023/days/08/src/main.rs
Normal file
14
2023/days/08/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
79
2023/days/08/src/parse.rs
Normal file
79
2023/days/08/src/parse.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Direction {
|
||||
Left,
|
||||
Right,
|
||||
}
|
||||
|
||||
#[derive(Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Node {
|
||||
pub left: String,
|
||||
pub right: String,
|
||||
}
|
||||
|
||||
static NODE_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new(r"^([[:alnum:]]{3}) = \(([[:alnum:]]{3}), ([[:alnum:]]{3})\)$").unwrap()
|
||||
});
|
||||
|
||||
pub fn parse(input: &str) -> (Vec<Direction>, HashMap<String, Node>) {
|
||||
let mut lines = input.lines();
|
||||
let mut directions = Vec::new();
|
||||
//parse the directions
|
||||
let dirline = lines.next().unwrap();
|
||||
for char in dirline.chars() {
|
||||
directions.push(match char {
|
||||
'L' => Direction::Left,
|
||||
'R' => Direction::Right,
|
||||
e => panic!("unexpected direction {}", e),
|
||||
})
|
||||
}
|
||||
//skip a blank line
|
||||
lines.next();
|
||||
|
||||
// process the rest of the lines
|
||||
let mut graph = HashMap::new();
|
||||
for line in lines {
|
||||
let captures = NODE_REGEX.captures(line).unwrap();
|
||||
graph.insert(
|
||||
captures[1].to_string(),
|
||||
Node {
|
||||
left: captures[2].to_string(),
|
||||
right: captures[3].to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
(directions, graph)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use collection_literals::collection;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"LLR\n",
|
||||
"\n",
|
||||
"AAA = (BBB, BBB)\n",
|
||||
"BBB = (AAA, ZZZ)\n",
|
||||
"ZZZ = (ZZZ, ZZZ)\n",
|
||||
);
|
||||
println!("{:#?}", parse(input));
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
(
|
||||
vec![Direction::Left, Direction::Left, Direction::Right],
|
||||
collection! {
|
||||
"AAA".to_string() => Node{ left: "BBB".to_string(), right: "BBB".to_string() },
|
||||
"BBB".to_string() => Node{ left: "AAA".to_string(), right: "ZZZ".to_string() },
|
||||
"ZZZ".to_string() => Node{ left: "ZZZ".to_string(), right: "ZZZ".to_string() },
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
37
2023/days/08/src/part1.rs
Normal file
37
2023/days/08/src/part1.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &(Vec<Direction>, HashMap<String, Node>)) -> usize {
|
||||
let mut nodes_visited: usize = 0;
|
||||
let mut current_node: String = "AAA".to_string();
|
||||
while current_node != *"ZZZ" {
|
||||
let direction = input.0[nodes_visited % input.0.len()];
|
||||
match direction {
|
||||
Direction::Left => current_node = input.1.get(¤t_node).unwrap().left.clone(),
|
||||
Direction::Right => current_node = input.1.get(¤t_node).unwrap().right.clone(),
|
||||
};
|
||||
nodes_visited += 1;
|
||||
}
|
||||
nodes_visited
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collection_literals::collection;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input: (Vec<Direction>, HashMap<String, Node>) = (
|
||||
vec![Direction::Left, Direction::Left, Direction::Right],
|
||||
collection! {
|
||||
"AAA".to_string() => Node{ left: "BBB".to_string(), right: "BBB".to_string() },
|
||||
"BBB".to_string() => Node{ left: "AAA".to_string(), right: "ZZZ".to_string() },
|
||||
"ZZZ".to_string() => Node{ left: "ZZZ".to_string(), right: "ZZZ".to_string() },
|
||||
},
|
||||
);
|
||||
assert_eq!(part1(&input), 6);
|
||||
}
|
||||
}
|
||||
113
2023/days/08/src/part2.rs
Normal file
113
2023/days/08/src/part2.rs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
use aoc_libs::misc::arr_lcm;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::parse::*;
|
||||
|
||||
// note about inputs: each "ends with A" node is the starting point,
|
||||
// and is not returned to part of the loop.
|
||||
// eatch 'Z' node is at the 'end' of the loop,
|
||||
// so the time when you first hit z is equal to your cycle time.
|
||||
|
||||
pub fn part2(input: &(Vec<Direction>, HashMap<String, Node>)) -> usize {
|
||||
let (directions, graph) = input;
|
||||
let starting_points = find_starting_points(graph);
|
||||
println!("{:?}", starting_points);
|
||||
let cycle_lengths: Vec<_> = starting_points
|
||||
.iter()
|
||||
.inspect(|p| print!("starting point {}: ", p))
|
||||
.map(|p| cycle_len_and_offset(p, directions, graph))
|
||||
.inspect(|c| println!("cycles: {}", c))
|
||||
.collect();
|
||||
arr_lcm(&cycle_lengths)
|
||||
}
|
||||
|
||||
//returns the length of the loop
|
||||
fn cycle_len_and_offset(
|
||||
start: &str,
|
||||
directions: &[Direction],
|
||||
graph: &HashMap<String, Node>,
|
||||
) -> usize {
|
||||
let mut current_node: String = start.to_string();
|
||||
let mut dir_index: usize = 0;
|
||||
let mut cycles: usize = 0;
|
||||
while !current_node.ends_with('Z') {
|
||||
match directions[dir_index % directions.len()] {
|
||||
Direction::Left => current_node = graph.get(¤t_node).unwrap().left.clone(),
|
||||
Direction::Right => current_node = graph.get(¤t_node).unwrap().right.clone(),
|
||||
};
|
||||
cycles += 1;
|
||||
dir_index += 1;
|
||||
// println!("finding index: {}", current_node);
|
||||
}
|
||||
cycles
|
||||
}
|
||||
|
||||
fn find_starting_points(input: &HashMap<String, Node>) -> Vec<String> {
|
||||
let mut ret = Vec::new();
|
||||
for point in input.keys() {
|
||||
if point.ends_with('A') {
|
||||
ret.push(point.to_string())
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_find_len_of_cycle() {
|
||||
let input = parse(concat!(
|
||||
"LR\n",
|
||||
"\n",
|
||||
"11A = (11B, XXX)\n",
|
||||
"11B = (XXX, 11Z)\n",
|
||||
"11Z = (11B, XXX)\n",
|
||||
"22A = (22B, XXX)\n",
|
||||
"22B = (22C, 22C)\n",
|
||||
"22C = (22Z, 22Z)\n",
|
||||
"22Z = (22B, 22B)\n",
|
||||
"XXX = (XXX, XXX)\n",
|
||||
));
|
||||
assert_eq!(cycle_len_and_offset("11A", &input.0, &input.1), 2);
|
||||
assert_eq!(cycle_len_and_offset("22A", &input.0, &input.1), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_starting_points() {
|
||||
let input = parse(concat!(
|
||||
"LR\n",
|
||||
"\n",
|
||||
"11A = (11B, XXX)\n",
|
||||
"11B = (XXX, 11Z)\n",
|
||||
"11Z = (11B, XXX)\n",
|
||||
"22A = (22B, XXX)\n",
|
||||
"22B = (22C, 22C)\n",
|
||||
"22C = (22Z, 22Z)\n",
|
||||
"22Z = (22B, 22B)\n",
|
||||
"XXX = (XXX, XXX)\n",
|
||||
));
|
||||
let starting_points = find_starting_points(&input.1);
|
||||
assert_eq!(starting_points.len(), 2);
|
||||
assert!(starting_points.contains(&"11A".to_string()));
|
||||
assert!(starting_points.contains(&"22A".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = parse(concat!(
|
||||
"LR\n",
|
||||
"\n",
|
||||
"11A = (11B, XXX)\n",
|
||||
"11B = (XXX, 11Z)\n",
|
||||
"11Z = (11B, XXX)\n",
|
||||
"22A = (22B, XXX)\n",
|
||||
"22B = (22C, 22C)\n",
|
||||
"22C = (22Z, 22Z)\n",
|
||||
"22Z = (22B, 22B)\n",
|
||||
"XXX = (XXX, XXX)\n",
|
||||
));
|
||||
assert_eq!(part2(&input), 6);
|
||||
}
|
||||
}
|
||||
9
2023/days/09/Cargo.toml
Normal file
9
2023/days/09/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "day09"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
200
2023/days/09/src/input.txt
Normal file
200
2023/days/09/src/input.txt
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
13 14 13 10 5 -2 -11 -22 -35 -50 -67 -86 -107 -130 -155 -182 -211 -242 -275 -310 -347
|
||||
9 19 37 66 111 177 266 388 625 1318 3490 9701 25720 63813 149272 333318 718069 1503353 3071375 6134368 11983281
|
||||
17 46 98 176 281 429 679 1172 2193 4286 8484 16784 33150 65659 131075 264391 538087 1099560 2241224 4527470 9018149
|
||||
7 8 7 15 65 227 628 1477 3095 5950 10697 18223 29697 46625 70910 104917 151543 214292 297355 405695 545137
|
||||
16 20 32 75 200 503 1144 2368 4528 8110 13760 22313 34824 52601 77240 110662 155152 213400 288544 384215 504584
|
||||
12 19 22 16 -5 -46 -106 -162 -130 213 1366 4324 10909 24244 49406 94298 170784 296135 494838 800824 1260175
|
||||
2 6 26 72 158 308 570 1038 1882 3389 6024 10529 18090 30617 51200 84825 139458 227632 368702 591966 940886
|
||||
22 46 83 136 215 355 655 1362 3045 6934 15547 33816 71102 144866 287545 559746 1075870 2053792 3909961 7437838 14134735
|
||||
11 28 56 110 211 392 719 1340 2589 5207 10809 22836 48395 101619 209484 421412 824479 1566646 2891150 5186042 9053851
|
||||
18 41 80 155 308 608 1164 2162 3949 7210 13337 25194 48675 95789 190569 380005 753596 1477199 2849870 5396645 10016062
|
||||
27 45 78 149 302 624 1293 2676 5512 11226 22431 43686 82589 151295 268560 462423 773649 1260067 2001948 3108579 4726200
|
||||
-4 -8 -13 0 71 277 765 1806 3871 7731 14593 26319 45879 78460 134275 235391 431268 831772 1672945 3440668 7091533
|
||||
3 16 32 55 106 241 575 1307 2748 5384 10073 18593 34941 68045 136906 279649 568545 1133784 2199646 4137747 7543244
|
||||
12 37 77 132 202 287 387 502 632 777 937 1112 1302 1507 1727 1962 2212 2477 2757 3052 3362
|
||||
21 25 24 23 40 123 392 1125 2909 6873 15012 30615 58861 107802 190292 328053 560129 959637 1665192 2936927 5251986
|
||||
-3 4 31 85 169 285 443 684 1131 2086 4193 8687 17747 34967 65953 119046 206161 343720 553643 864345 1311669
|
||||
12 39 94 190 340 557 854 1244 1740 2355 3102 3994 5044 6265 7670 9272 11084 13119 15390 17910 20692
|
||||
8 3 6 32 108 279 614 1212 2208 3779 6150 9600 14468 21159 30150 41996 57336 76899 101510 132096 169692
|
||||
19 34 45 58 97 211 481 1027 2015 3664 6253 10128 15709 23497 34081 48145 66475 89966 119629 156598 202137
|
||||
19 32 43 45 36 32 85 301 856 2020 4216 8156 15115 27474 49920 92445 178177 363369 786019 1778286 4114938
|
||||
21 23 28 49 115 297 747 1743 3732 7381 13707 24503 43577 79880 154567 315616 666091 1415815 2971538 6088153 12113739
|
||||
12 25 38 55 85 142 245 418 690 1095 1672 2465 3523 4900 6655 8852 11560 14853 18810 23515 29057
|
||||
2 1 -3 -10 -20 -33 -49 -68 -90 -115 -143 -174 -208 -245 -285 -328 -374 -423 -475 -530 -588
|
||||
15 31 53 83 130 228 479 1144 2816 6725 15248 32734 66829 130665 246726 454311 825117 1497239 2749951 5165469 9968628
|
||||
13 22 41 94 227 530 1182 2527 5189 10234 19387 35312 61963 105014 172376 274809 426637 646574 958669 1393378 1988771
|
||||
10 27 61 128 265 541 1078 2086 3929 7275 13453 25271 48812 97287 199231 415823 876990 1854968 3909809 8167901 16837713
|
||||
20 41 69 115 210 426 919 2014 4376 9357 19685 40775 83102 166290 325847 623822 1165084 2121433 3766357 6523955 11036362
|
||||
20 41 79 145 260 469 859 1576 2833 4898 8048 12472 18103 24356 29746 31357 24130 -65 -53611 -154621 -328754
|
||||
12 15 14 14 20 31 44 93 361 1429 4792 13917 36403 88335 202900 447124 953909 1982790 4034693 8068571 15910501
|
||||
7 1 -10 -26 -47 -73 -104 -140 -181 -227 -278 -334 -395 -461 -532 -608 -689 -775 -866 -962 -1063
|
||||
8 17 28 41 56 73 92 113 136 161 188 217 248 281 316 353 392 433 476 521 568
|
||||
-7 -7 -3 20 91 253 563 1092 1925 3161 4913 7308 10487 14605 19831 26348 34353 44057 55685 69476 85683
|
||||
19 41 75 131 239 467 955 1978 4070 8281 16709 33558 67130 133373 261887 505645 956125 1766081 3182815 5595557 9601425
|
||||
19 38 76 145 252 412 679 1198 2286 4562 9162 18098 34869 65554 120910 220664 402655 742670 1397682 2699767 5358228
|
||||
-8 -12 -16 -20 -24 -28 -32 -36 -40 -44 -48 -52 -56 -60 -64 -68 -72 -76 -80 -84 -88
|
||||
14 19 25 47 123 330 805 1770 3568 6733 12138 21281 36762 62959 106853 179040 295716 485185 810417 1439321 2840823
|
||||
-5 -10 -5 27 113 307 712 1508 3008 5813 11227 22245 45678 96398 205401 434621 903560 1836489 3645526 7077172 13474410
|
||||
6 12 37 100 225 454 877 1695 3352 6804 14053 29199 60520 124585 254292 514213 1028998 2034192 3964089 7598714 14302319
|
||||
9 -1 -3 16 71 191 448 1014 2276 5083 11286 24888 54380 117243 248195 513614 1035739 2031815 3875387 7189552 12985245
|
||||
13 9 3 11 67 227 573 1217 2305 4021 6591 10287 15431 22399 31625 43605 58901 78145 102043 131379 167019
|
||||
3 13 41 93 185 367 766 1656 3563 7413 14731 27899 50481 87623 146536 237070 372387 569741 851373 1245529 1787609
|
||||
26 35 37 26 -2 -45 -94 -139 -186 -289 -601 -1448 -3430 -7553 -15396 -29317 -52702 -90261 -148375 -235498 -362618
|
||||
24 35 46 57 68 79 90 101 112 123 134 145 156 167 178 189 200 211 222 233 244
|
||||
-1 -3 7 45 137 336 752 1595 3231 6251 11553 20437 34713 56822 89970 138275 206927 302361 432443 606669 836377
|
||||
5 14 43 100 196 351 596 980 1613 2813 5492 12035 28135 66420 153386 342383 737601 1537808 3114941 6152870 11887554
|
||||
-4 6 31 79 177 390 850 1806 3720 7456 14647 28396 54601 104440 198986 377657 713404 1339426 2495079 4602917 8394985
|
||||
8 14 26 47 83 143 236 375 620 1224 2998 8105 21675 54992 131693 299673 653536 1375886 2810998 5591955 10852643
|
||||
-6 -6 -6 -13 -32 -48 15 366 1463 4197 10185 22236 45083 86509 159036 282393 487032 819020 1346700 2169585 3430026
|
||||
16 35 67 113 174 251 345 457 588 739 911 1105 1322 1563 1829 2121 2440 2787 3163 3569 4006
|
||||
18 25 35 61 126 269 567 1182 2449 5043 10322 21086 43303 89970 189428 402531 856796 1812337 3786333 7783995 15721100
|
||||
1 0 -3 -8 -15 -24 -35 -48 -63 -80 -99 -120 -143 -168 -195 -224 -255 -288 -323 -360 -399
|
||||
22 29 36 43 50 57 64 71 78 85 92 99 106 113 120 127 134 141 148 155 162
|
||||
12 25 47 93 190 380 730 1359 2492 4551 8293 15005 26766 46786 79832 132751 215100 339893 524475 791533 1170254
|
||||
3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63
|
||||
8 22 44 75 116 168 232 309 400 506 628 767 924 1100 1296 1513 1752 2014 2300 2611 2948
|
||||
7 18 45 93 171 292 473 735 1103 1606 2277 3153 4275 5688 7441 9587 12183 15290 18973 23301 28347
|
||||
16 25 41 71 122 201 315 471 676 937 1261 1655 2126 2681 3327 4071 4920 5881 6961 8167 9506
|
||||
11 8 7 14 34 73 153 358 946 2603 6990 17860 43245 99637 219904 468209 967955 1953669 3866490 7528970 14465012
|
||||
5 7 7 9 24 70 172 362 679 1169 1885 2887 4242 6024 8314 11200 14777 19147 24419 30709 38140
|
||||
20 41 88 184 360 655 1116 1798 2764 4085 5840 8116 11008 14619 19060 24450 30916 38593 47624 58160 70360
|
||||
5 1 -3 -7 -11 -15 -19 -23 -27 -31 -35 -39 -43 -47 -51 -55 -59 -63 -67 -71 -75
|
||||
14 28 49 84 144 244 403 644 994 1484 2149 3028 4164 5604 7399 9604 12278 15484 19289 23764 28984
|
||||
22 39 76 159 327 632 1139 1926 3084 4717 6942 9889 13701 18534 24557 31952 40914 51651 64384 79347 96787
|
||||
-2 2 14 48 128 302 671 1448 3080 6489 13516 27685 55442 108067 204505 375415 668794 1157596 1949834 3201726 5134524
|
||||
8 26 74 174 355 653 1111 1779 2714 3980 5648 7796 10509 13879 18005 22993 28956 36014 44294 53930 65063
|
||||
23 33 50 91 180 356 702 1409 2889 5944 11981 23232 42888 74981 123741 192008 278083 370147 437052 413881 180172
|
||||
3 21 50 101 197 368 646 1058 1610 2250 2793 2786 1286 -3481 -14617 -37247 -79459 -153541 -277572 -477429 -789277
|
||||
11 24 52 113 232 438 776 1348 2397 4448 8520 16423 31154 57406 102204 175682 292015 470520 736940 1124925 1677724
|
||||
-10 -6 14 71 204 480 1012 2001 3833 7274 13814 26222 49416 91898 168406 305363 552580 1008090 1868702 3527701 6753848
|
||||
20 34 64 128 254 493 939 1767 3313 6233 11791 22339 42065 78098 142072 252264 436434 735508 1208258 1937146 3035512
|
||||
2 10 22 45 90 169 301 550 1131 2634 6438 15432 35251 76403 157947 313829 603648 1130570 2070406 3717599 6556112
|
||||
3 14 47 113 223 383 590 829 1076 1332 1752 2991 6966 18339 47197 113725 256297 545618 1109757 2178733 4163617
|
||||
9 24 49 94 186 381 792 1643 3363 6738 13143 24880 45652 81207 140190 235245 384413 612876 955101 1457442 2181262
|
||||
14 23 35 58 105 197 366 658 1136 1883 3005 4634 6931 10089 14336 19938 27202 36479 48167 62714 80621
|
||||
27 44 59 64 57 56 117 356 975 2292 4775 9080 16093 26976 43217 66684 99683 145020 206067 286832 392033
|
||||
17 25 33 41 49 57 65 73 81 89 97 105 113 121 129 137 145 153 161 169 177
|
||||
17 32 70 139 249 433 788 1552 3245 6924 14644 30289 61045 119922 229851 429893 783891 1391526 2401936 4033413 6616003
|
||||
16 27 55 113 230 463 916 1774 3367 6293 11651 21464 39397 71870 129603 229529 397057 669452 1104102 1803952 2993211
|
||||
11 34 80 162 301 533 917 1545 2563 4231 7097 12477 23695 49066 108610 248366 569762 1288551 2852013 6171819 13087348
|
||||
19 26 30 31 29 24 16 5 -9 -26 -46 -69 -95 -124 -156 -191 -229 -270 -314 -361 -411
|
||||
1 20 64 146 293 561 1063 2033 3966 7896 15901 31956 63292 122461 230354 420471 744799 1281716 2146406 3504342 5588471
|
||||
-4 0 10 41 129 333 731 1413 2475 4021 6200 9375 14701 25775 52754 121612 293282 700634 1615986 3568633 7541309
|
||||
14 29 57 101 164 254 391 628 1118 2290 5238 12478 29293 65976 141417 288696 563690 1058247 1920315 3384655 5819558
|
||||
12 22 42 72 112 162 222 292 372 462 562 672 792 922 1062 1212 1372 1542 1722 1912 2112
|
||||
18 38 82 159 280 460 722 1114 1749 2874 4983 9051 17156 34208 72464 162434 377514 886708 2062686 4695469 10402310
|
||||
3 5 19 57 145 338 735 1494 2847 5115 8723 14215 22269 33712 49535 70908 99195 135969 183027 242405 316393
|
||||
20 29 38 60 132 334 816 1836 3813 7404 13640 24238 42403 74835 136386 260038 516810 1053119 2157346 4373288 8686278
|
||||
16 42 90 173 313 554 995 1863 3648 7320 14640 28559 53665 96580 166117 272869 427704 638366 903014 1199049 1464961
|
||||
15 24 33 42 51 60 69 78 87 96 105 114 123 132 141 150 159 168 177 186 195
|
||||
8 31 73 153 298 550 988 1770 3200 5825 10567 18895 33042 56272 93202 150184 235752 361139 540869 793429 1142026
|
||||
9 30 70 140 259 471 876 1691 3385 6979 14670 31027 65128 134201 269698 527469 1005174 1872859 3427543 6190589 11077866
|
||||
-6 0 11 33 89 233 568 1274 2661 5271 10062 18716 34122 61094 107393 185131 312644 516930 836757 1326555 2061215
|
||||
6 22 41 56 57 40 22 53 226 709 1860 4547 10912 26080 61944 145656 338842 780748 1782863 4029602 8988143
|
||||
-9 -10 -4 15 67 204 545 1347 3146 7020 15048 31086 62104 120613 229283 429883 800389 1486794 2760144 5114905 9431989
|
||||
7 26 59 115 203 330 507 765 1178 1885 3098 5078 8056 12071 16692 20586 20889 12332 -13931 -71851 -182431
|
||||
25 50 84 133 218 381 694 1277 2328 4164 7285 12537 21617 38505 73019 148687 318659 695614 1504754 3173253 6475212
|
||||
4 0 -13 -29 -17 103 501 1516 3817 8718 18751 38637 76837 147924 276125 500603 883477 1522303 2569754 4264250 6975394
|
||||
27 47 81 153 311 639 1273 2437 4536 8382 15705 30247 60020 121869 250601 517175 1064855 2180784 4436721 8962954 17974199
|
||||
14 13 9 18 75 240 621 1432 3106 6494 13211 26249 51075 97579 183443 339777 620222 1115163 1973237 3432972 5868163
|
||||
23 50 93 161 277 492 914 1774 3579 7453 15857 34031 72745 153319 316418 636898 1248031 2379836 4418061 7992677 14107645
|
||||
11 10 21 56 127 246 425 676 1011 1442 1981 2640 3431 4366 5457 6716 8155 9786 11621 13672 15951
|
||||
26 45 69 98 132 171 215 264 318 377 441 510 584 663 747 836 930 1029 1133 1242 1356
|
||||
15 41 78 131 225 419 830 1676 3361 6664 13177 26300 53407 110349 230417 481486 997646 2035714 4073411 7975968 15273628
|
||||
-8 -8 -6 -4 2 30 119 334 774 1597 3082 5745 10513 18946 33506 57948 98120 163906 273862 465454 815928
|
||||
8 17 26 35 44 53 62 71 80 89 98 107 116 125 134 143 152 161 170 179 188
|
||||
-1 5 16 35 77 177 397 823 1538 2555 3704 4510 4223 2477 1816 15090 84677 329015 1049600 2966735 7719325
|
||||
4 15 32 59 108 199 360 627 1044 1663 2544 3755 5372 7479 10168 13539 17700 22767 28864 36123 44684
|
||||
-5 0 16 60 178 464 1087 2343 4767 9362 18027 34292 64492 119530 217386 386519 670275 1132348 1863234 2987460 4671150
|
||||
8 13 29 70 160 330 615 1051 1672 2507 3577 4892 6448 8224 10179 12249 14344 16345 18101 19426 20096
|
||||
2 7 12 14 26 92 302 807 1834 3701 6832 11772 19202 29954 45026 65597 93042 128947 175124 233626 306762
|
||||
13 22 55 135 310 683 1460 3025 6057 11710 21883 39613 69630 119119 198740 323963 516781 807870 1239271 1867675 2768398
|
||||
-9 -4 16 59 142 297 585 1133 2218 4431 8962 18062 35782 69203 130622 241651 441077 799858 1449144 2631225 4789554
|
||||
17 30 53 86 129 182 245 318 401 494 597 710 833 966 1109 1262 1425 1598 1781 1974 2177
|
||||
16 31 57 92 134 181 231 282 332 379 421 456 482 497 499 486 456 407 337 244 126
|
||||
15 23 45 95 192 361 640 1097 1863 3193 5577 9934 17943 32647 59747 110768 211035 418963 869777 1868209 4073414
|
||||
15 41 89 166 277 425 611 834 1091 1377 1685 2006 2329 2641 2927 3170 3351 3449 3441 3302 3005
|
||||
13 21 40 89 207 459 933 1736 3024 5143 9015 16975 34352 72189 151614 310506 613247 1164513 2128234 3753045 6405757
|
||||
16 23 38 68 130 264 551 1136 2256 4273 7712 13304 22034 35194 54441 81860 120032 172107 241882 333884 453458
|
||||
12 18 24 22 14 35 199 777 2326 5912 13508 28700 57900 112345 211255 386631 690296 1203918 2052904 3425218 5596354
|
||||
-8 -13 -18 -23 -28 -33 -38 -43 -48 -53 -58 -63 -68 -73 -78 -83 -88 -93 -98 -103 -108
|
||||
5 2 -3 -1 29 127 377 956 2206 4728 9528 18351 34588 65629 128400 261301 548362 1166341 2475406 5194738 10747314
|
||||
-9 -17 -13 18 105 315 784 1765 3731 7612 15304 30678 61474 122778 243443 478215 931187 1801827 3475476 6699809 12924125
|
||||
16 30 44 58 72 86 100 114 128 142 156 170 184 198 212 226 240 254 268 282 296
|
||||
-4 8 33 73 136 237 395 634 1019 1796 3769 9158 23371 58431 139277 314867 677022 1391344 2746409 5229879 9643306
|
||||
11 19 22 16 -7 -59 -159 -336 -612 -921 -880 748 7202 26037 73573 183088 419305 903051 1851778 3644040 6919135
|
||||
3 7 23 51 87 122 139 108 -21 -327 -929 -1999 -3777 -6588 -10861 -17150 -26157 -38757 -56025 -79265 -110041
|
||||
26 47 76 110 141 168 237 537 1594 4619 12080 28582 62153 126048 241197 439437 767682 1293199 2110172 3347750 5179789
|
||||
1 -3 5 43 135 311 607 1065 1733 2665 3921 5567 7675 10323 13595 17581 22377 28085 34813 42675 51791
|
||||
26 36 51 78 121 181 256 341 428 506 561 576 531 403 166 -209 -754 -1504 -2497 -3774 -5379
|
||||
24 49 83 120 161 228 376 695 1305 2378 4283 8064 16660 37614 88602 208180 476214 1052579 2250883 4679724 9513235
|
||||
6 11 34 83 159 267 436 749 1395 2780 5782 12315 26488 56816 120170 248451 499348 973001 1836946 3362379 5975549
|
||||
7 1 0 21 91 242 504 899 1439 2131 2992 4077 5523 7612 10856 16107 24695 38597 60640 94741 146187
|
||||
15 28 45 60 63 40 -27 -160 -385 -732 -1235 -1932 -2865 -4080 -5627 -7560 -9937 -12820 -16275 -20372 -25185
|
||||
12 19 30 45 64 87 114 145 180 219 262 309 360 415 474 537 604 675 750 829 912
|
||||
13 37 73 123 189 273 377 503 653 829 1033 1267 1533 1833 2169 2543 2957 3413 3913 4459 5053
|
||||
8 24 59 123 226 378 589 869 1228 1676 2223 2879 3654 4558 5601 6793 8144 9664 11363 13251 15338
|
||||
6 0 1 22 90 259 623 1329 2590 4698 8037 13096 20482 30933 45331 64715 90294 123460 165801 219114 285418
|
||||
1 0 4 15 33 59 104 204 441 970 2052 4093 7689 13677 23192 37730 59217 90084 133348 192699 272593
|
||||
18 22 33 57 109 231 522 1202 2761 6298 14256 31955 70704 153980 329421 691523 1423433 2871746 5676622 10992031 20849292
|
||||
21 23 32 62 131 275 575 1194 2432 4832 9409 18127 34816 66802 127618 241273 448679 816973 1452622 2519364 4262217
|
||||
3 10 22 41 68 108 186 383 907 2220 5248 11707 24584 48818 92232 166773 290123 487750 795474 1262629 1955908
|
||||
17 29 59 129 284 597 1180 2217 4044 7313 13292 24371 44865 82229 148827 264427 459627 780453 1294409 2098301 3328202
|
||||
-4 -7 -4 11 44 101 188 311 476 689 956 1283 1676 2141 2684 3311 4028 4841 5756 6779 7916
|
||||
13 31 65 132 273 571 1184 2408 4801 9423 18284 35154 66995 126451 236111 435682 793821 1427231 2530787 4423992 7621045
|
||||
-2 -5 -7 -5 16 92 291 737 1664 3518 7130 14019 27008 51653 99674 196927 400914 837061 1769967 3736899 7787848
|
||||
-7 -8 9 65 194 460 988 2015 3970 7595 14122 25524 44861 76745 127951 208204 331175 515722 787415 1180387 1739556
|
||||
21 44 94 181 311 498 791 1326 2429 4835 10159 21876 47279 101271 213575 442351 900001 1802661 3566842 7001844 13698911
|
||||
9 17 23 27 29 29 27 23 17 9 -1 -13 -27 -43 -61 -81 -103 -127 -153 -181 -211
|
||||
9 15 15 4 -11 3 122 493 1382 3245 6810 13147 23740 40756 68207 115815 209575 416951 901321 2031090 4585703
|
||||
15 26 51 114 247 502 981 1886 3601 6851 13046 25016 48484 94825 185957 362689 698703 1323992 2464873 4514282 8158873
|
||||
28 48 72 93 98 67 -31 -251 -694 -1518 -2883 -4725 -6176 -4292 8596 50348 160256 421832 1007774 2265645 4875030
|
||||
10 31 77 158 281 450 664 923 1271 1929 3607 8160 19938 48615 115226 265034 594392 1305015 2809553 5929150 12249559
|
||||
11 31 66 133 257 470 820 1399 2399 4205 7534 13629 24517 43340 74768 125503 204883 325595 504506 763621 1131177
|
||||
14 19 31 62 120 212 356 616 1182 2519 5613 12362 26228 53462 105720 206075 402990 801955 1634195 3399266 7148256
|
||||
5 -3 -6 14 89 276 686 1539 3264 6689 13407 26460 51554 99104 187509 348173 632919 1124589 1951784 3308874 5482599
|
||||
-4 3 34 112 283 625 1266 2420 4446 7930 13784 23349 38481 61590 95592 143723 209152 294317 399894 523294 656567
|
||||
-4 5 33 88 192 399 815 1624 3145 5985 11417 22210 44287 89811 182627 367450 724810 1394557 2611681 4759268 8444498
|
||||
15 30 58 110 197 330 520 778 1115 1542 2070 2710 3473 4370 5412 6610 7975 9518 11250 13182 15325
|
||||
14 11 2 -2 32 169 513 1214 2486 4655 8264 14270 24376 41549 70783 120174 202382 336563 550862 885566 1397024
|
||||
18 43 79 125 182 263 410 716 1359 2669 5267 10352 20327 40295 81829 172433 378440 857986 1978345 4565832 10419624
|
||||
4 10 17 26 42 88 231 636 1675 4136 9608 21163 44514 89909 175172 330649 607626 1093546 1940883 3423120 6042846
|
||||
3 22 53 98 162 263 459 900 1927 4263 9384 20245 42704 88286 179422 359061 707675 1372260 2614095 4884884 8944614
|
||||
4 15 38 73 120 179 250 333 428 535 654 785 928 1083 1250 1429 1620 1823 2038 2265 2504
|
||||
23 42 81 152 262 406 554 631 489 -130 -1641 -4674 -10144 -19334 -33992 -56443 -89717 -137694 -205267 -298524 -424950
|
||||
12 19 49 116 230 404 678 1165 2136 4196 8684 18602 40728 90256 200608 443427 967876 2075253 4356031 8933736 17886258
|
||||
-2 -8 -16 -16 7 73 207 438 805 1393 2443 4607 9452 20356 43984 92583 187392 363526 676762 1212730 2099093
|
||||
15 20 22 21 17 10 0 -13 -29 -48 -70 -95 -123 -154 -188 -225 -265 -308 -354 -403 -455
|
||||
2 5 14 30 53 82 115 149 180 203 212 200 159 80 -47 -233 -490 -831 -1270 -1822 -2503
|
||||
8 15 38 93 209 435 852 1596 2894 5121 8921 15540 27768 52407 106190 228941 511121 1148880 2550469 5537596 11722540
|
||||
-7 4 30 71 127 198 284 385 501 632 778 939 1115 1306 1512 1733 1969 2220 2486 2767 3063
|
||||
4 21 54 101 157 212 245 214 42 -401 -1320 -3021 -5941 -10682 -18049 -29092 -45152 -67911 -99446 -142287 -199479
|
||||
24 44 72 121 229 467 952 1889 3693 7283 14711 30431 63812 134129 280578 582555 1200874 2461318 5022490 10208249 20654203
|
||||
16 44 87 158 277 466 759 1245 2165 4087 8186 16659 33308 64327 119332 212676 365094 605726 974569 1525412 2329311
|
||||
23 51 104 192 325 513 766 1094 1507 2015 2628 3356 4209 5197 6330 7618 9071 10699 12512 14520 16733
|
||||
10 25 51 92 164 314 665 1513 3530 8178 18521 40743 86848 179241 358175 693406 1301834 2373431 4208375 7269030 12251244
|
||||
12 27 60 111 175 257 398 722 1523 3415 7570 16073 32432 62295 114440 202106 344702 569835 915392 1431035 2177845
|
||||
26 49 81 132 228 419 803 1580 3151 6278 12322 23577 43719 78390 135938 228335 372296 590623 913799 1381858 2046558
|
||||
13 13 25 74 204 497 1103 2287 4510 8579 15939 29260 53625 98891 184223 346449 654819 1236049 2315277 4280846 7783762
|
||||
10 31 75 145 249 406 653 1054 1721 2875 4998 9151 17554 34538 67982 131336 246300 446175 779821 1316045 2148095
|
||||
13 15 17 16 19 55 189 554 1427 3390 7660 16783 36127 77064 163516 344803 719657 1479081 2979707 5864762 11257059
|
||||
9 21 37 66 129 268 555 1100 2060 3670 6359 11077 20036 38154 75584 151800 301771 584784 1096751 1988587 3500239
|
||||
9 23 37 51 65 79 93 107 121 135 149 163 177 191 205 219 233 247 261 275 289
|
||||
3 6 27 74 157 302 581 1180 2541 5628 12381 26436 54203 106408 200219 362090 631471 1065546 1745175 2782230 4328529
|
||||
3 21 49 96 195 422 916 1896 3668 6604 11047 17037 23644 27511 19924 -18697 -128591 -387257 -936475 -2024770 -4072135
|
||||
2 19 49 85 125 186 324 662 1428 3005 5995 11299 20215 34556 56790 90204 139094 208983 306869 441505 623713
|
||||
3 -2 -12 -31 -56 -63 9 271 889 2076 4066 7065 11174 16279 21903 27015 29791 27322 15264 -12575 -64716
|
||||
-7 -12 -9 28 138 383 875 1840 3763 7691 15813 32487 65944 130968 252929 473633 859549 1513078 2587643 4307502 6993318
|
||||
2 1 -3 -13 -27 -17 104 527 1604 3917 8359 16227 29327 50091 81706 128255 194870 287897 415073 585715 810921
|
||||
-3 -1 2 6 11 17 24 32 41 51 62 74 87 101 116 132 149 167 186 206 227
|
||||
13 26 44 64 92 165 385 976 2383 5443 11681 23833 46794 89362 167440 309821 568385 1035568 1873426 3360638 5966520
|
||||
14 43 88 154 261 457 833 1552 2918 5524 10539 20244 39039 75362 145344 279640 535806 1019929 1923066 3580526 6565265
|
||||
9 6 5 6 9 14 21 30 41 54 69 86 105 126 149 174 201 230 261 294 329
|
||||
-3 12 39 84 173 364 759 1516 2861 5100 8631 13956 21693 32588 47527 67548 93853 127820 171015 225204 292365
|
||||
12 20 52 124 251 454 780 1348 2447 4728 9552 19581 39730 78636 150846 279981 503198 877348 1487316 2457130 3964541
|
||||
10 4 -3 -11 -20 -30 -41 -53 -66 -80 -95 -111 -128 -146 -165 -185 -206 -228 -251 -275 -300
|
||||
23 45 69 102 160 276 530 1122 2528 5807 13164 28920 61095 123874 241299 452612 819765 1437713 2448215 4057986 6562170
|
||||
22 47 91 160 273 481 903 1800 3731 7881 16734 35407 74202 153333 311438 620531 1211684 2318227 4346981 7993474 14424847
|
||||
3 18 59 136 255 417 617 843 1075 1284 1431 1466 1327 939 213 -955 -2685 -5114 -8397 -12708 -18241
|
||||
23 49 87 137 199 273 359 457 567 689 823 969 1127 1297 1479 1673 1879 2097 2327 2569 2823
|
||||
24 35 47 71 128 250 480 878 1551 2737 4986 9495 18669 36996 72341 137782 254130 453295 782681 1310815 2134438
|
||||
14
2023/days/09/src/main.rs
Normal file
14
2023/days/09/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let mut structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&mut structured_input));
|
||||
}
|
||||
48
2023/days/09/src/parse.rs
Normal file
48
2023/days/09/src/parse.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
pub fn parse(input: &str) -> Vec<Vec<i32>> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| l.split(' ').map(|n| n.parse().unwrap()).collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_differences(input: &[i32]) -> Vec<i32> {
|
||||
input.windows(2).map(|p| p[1] - p[0]).collect()
|
||||
}
|
||||
|
||||
pub fn extrapolate_sequence(input: &[i32]) -> i32 {
|
||||
if input.iter().all(|i| *i == 0) {
|
||||
return 0;
|
||||
};
|
||||
let diffs = get_differences(input);
|
||||
input.last().unwrap() + extrapolate_sequence(&diffs)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_differences() {
|
||||
assert_eq!(get_differences(&[0, 3, 6, 9, 12, 15]), vec![3, 3, 3, 3, 3]);
|
||||
assert_eq!(get_differences(&[1, 3, 6, 10, 15, 21]), vec![2, 3, 4, 5, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extrapolate_sequence() {
|
||||
assert_eq!(extrapolate_sequence(&[0, 3, 6, 9, 12, 15]), 18);
|
||||
assert_eq!(extrapolate_sequence(&[1, 3, 6, 10, 15, 21]), 28);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!("0 3 6 9 12 15\n", "1 3 6 10 15 21\n", "10 13 16 21 30 45\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
vec![0, 3, 6, 9, 12, 15],
|
||||
vec![1, 3, 6, 10, 15, 21],
|
||||
vec![10, 13, 16, 21, 30, 45],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
20
2023/days/09/src/part1.rs
Normal file
20
2023/days/09/src/part1.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &[Vec<i32>]) -> i32 {
|
||||
input.iter().map(|l| extrapolate_sequence(l)).sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
vec![0, 3, 6, 9, 12, 15],
|
||||
vec![1, 3, 6, 10, 15, 21],
|
||||
vec![10, 13, 16, 21, 30, 45],
|
||||
];
|
||||
assert_eq!(part1(&input), 114);
|
||||
}
|
||||
}
|
||||
26
2023/days/09/src/part2.rs
Normal file
26
2023/days/09/src/part2.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &mut [Vec<i32>]) -> i32 {
|
||||
input
|
||||
.iter_mut()
|
||||
.map(|l| {
|
||||
l.reverse();
|
||||
extrapolate_sequence(l)
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let mut input = vec![
|
||||
vec![0, 3, 6, 9, 12, 15],
|
||||
vec![1, 3, 6, 10, 15, 21],
|
||||
vec![10, 13, 16, 21, 30, 45],
|
||||
];
|
||||
assert_eq!(part2(&mut input), 2);
|
||||
}
|
||||
}
|
||||
11
2023/days/11/Cargo.toml
Normal file
11
2023/days/11/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day11"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
collection_literals.workspace = true
|
||||
itertools.workspace = true
|
||||
140
2023/days/11/src/input.txt
Normal file
140
2023/days/11/src/input.txt
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
.#..........#.....................#........................................................#....................................#...........
|
||||
...................#........................................#......................#........................................................
|
||||
...........................................#......#..................#...................................................#..................
|
||||
....#......................#...............................................#.........................#.....#......#................#........
|
||||
.................................................................#.......................#..................................................
|
||||
..............................................................................................................................#.............
|
||||
.......#........#.............#...................................................#...................................#.....................
|
||||
.........................#...................................#............................................................................#.
|
||||
....................#.............#.........#..........................................#...............#....................................
|
||||
.....................................................#...............#.............................................................#........
|
||||
...........................................................................................................................#................
|
||||
..........................................................#.........................................#...............#.......................
|
||||
..............................................................................................#.............................................
|
||||
.#........#........................#......#..............................................#..............................#...............#...
|
||||
...............#......#...............................#.......#.........#......#.............................#.................#............
|
||||
...............................#..............#.............................................................................................
|
||||
............................................................................................................................................
|
||||
.........................#.......................................#..........................................................................
|
||||
..................#........................#......................................#........................................#................
|
||||
..................................................#.......#..............................................#........................#.......#.
|
||||
...#........#........................#....................................#...............#.................................................
|
||||
............................................................................................................................................
|
||||
.......#........................#....................................................................................#......................
|
||||
...............#...........#........................................................................#.......................................
|
||||
.............................................#................#.........#.............................................................#.....
|
||||
...........#...........................#................#...........................#.......................................................
|
||||
..................................................#.......................................#.............#...................................
|
||||
.....#..................#..........#..............................#.............................#........................................#..
|
||||
..............................#...............................................................................................#.............
|
||||
...................................................................................................................#........................
|
||||
..............#..........................................#.............#...........................#..............................#.........
|
||||
...#...................................#.........................................#..........................................................
|
||||
..................#...................................................................#................................................#....
|
||||
..........................#...................................#.........................................#...................................
|
||||
............................................................................................................................................
|
||||
.........#...........#..........#..........................................#....................#..............#........#.....#...........#.
|
||||
....................................................#.......................................................................................
|
||||
.............................................#..............................................................................................
|
||||
......................................#..................#..............................#...........#.......#...............................
|
||||
............................#..................................#..............#.............................................................
|
||||
...............#............................................................................................................................
|
||||
...........................................#............................#.......................#...........................................
|
||||
.....#..............#.................................................................................#...........................#.........
|
||||
............................................................................................................................................
|
||||
........................................#..........#.................#..........................................#...........................
|
||||
.............................................#.................................#...........#................................................
|
||||
...............................#.......................#...........................................#.......#....................#...........
|
||||
#........#.............#...............................................................................................#...................#
|
||||
.....................................#........................#..........#.........#........................................................
|
||||
.................#............................................................................#.............................................
|
||||
..........................#.......................................#.................................................#.......................
|
||||
.....................................................#...................................#....................................#.............
|
||||
..#.........................................................................................................................................
|
||||
.............#.....#.......................#.............#....................................................#........................#....
|
||||
......#........................................................................................#............................................
|
||||
.................................#.................................#........................................................................
|
||||
.................................................................................#.......................#................................#.
|
||||
#.....................................................#...................................................................#.....#...........
|
||||
.........#..................................................#......................................#........................................
|
||||
..............................#.............#.................................................................#.......#.....................
|
||||
........................#............................................................#......#................................#..............
|
||||
.............#..............................................................................................................................
|
||||
.....#........................................................#............#..........................#...........................#.........
|
||||
...........................#......#.................................................................................#...................#...
|
||||
.........#.....................................#...............................#............................................................
|
||||
..................#.......................................#.......#................................#........................................
|
||||
...............................#.....................#...................................#................................#.................
|
||||
..............#..........................#.............................#............#.....................#.....................#.........#.
|
||||
.................................................................................................................#..........................
|
||||
......#.....................................................................................................................................
|
||||
...........#.............#.........#........................................................................................................
|
||||
...................................................................#..............#..................#......................................
|
||||
..................#...........................................................................................#.............................
|
||||
........#.................................#..............#.................................................................#..........#.....
|
||||
...#.....................................................................#..............#.......#...........................................
|
||||
............................................................................................................................................
|
||||
............................................................................................................................................
|
||||
.................................#................#..........................................................#...............#.............#
|
||||
..............#............................................................#................................................................
|
||||
......#.....................#..........................#........#.....#............#..............#.........................................
|
||||
....................#..................................................................................#..................#.................
|
||||
....................................#.........#........................................................................................#....
|
||||
..........................................................#..............#..................................................................
|
||||
................#...............................................................................................#.............#.............
|
||||
............................................................................................................................................
|
||||
............................#...................#......#.............#..............................................#.......................
|
||||
.............#...................................................................................#........................................#.
|
||||
......................#..........................................................#.......#..................................................
|
||||
#...........................................................#...............................................................................
|
||||
.........#.........................#.................#....................................................#.................#...............
|
||||
............................................................................................................................................
|
||||
...................#.............................................#.....#....................................................................
|
||||
........................#.........................#.....................................................................................#...
|
||||
.....#........................................................................................................................#.............
|
||||
.......................................#...............................................................#.........#..........................
|
||||
............................#...........................#...........#......................#..............................#.......#.........
|
||||
..#................................#...........#............................................................................................
|
||||
.................#..................................#...................#...................................................................
|
||||
..........#.................................................#................................................#..............................
|
||||
.....................#...............................................................................#......................................
|
||||
..............#..................#..............................#.............#....................................#.........#........#.....
|
||||
...#.............................................................................................#..........................................
|
||||
............................................#..........................................#....................................................
|
||||
.........#...............................................#..............................................................#...................
|
||||
................#.........#.................................................................................................................
|
||||
.....#..................................#............................#..............................#........#..................#..........#
|
||||
...............................#............................................................................................................
|
||||
....................................................#........#..............................................................................
|
||||
........#..........................#.........#...............................................................................#..............
|
||||
....................................................................................................................#.......................
|
||||
....................#........#......................................#.........#.....#.....#.................................................
|
||||
................................................................................................................................#.....#.....
|
||||
...............#..........................................#...............#...............................#.................................
|
||||
...#..............................#.........................................................................................................
|
||||
........................................................................................#............#....................................#.
|
||||
............................................................................................................................#...............
|
||||
...................................................................................#............................#...........................
|
||||
#........#........#........#..........#.........#...........................................................................................
|
||||
.............................................................#..............................#............................#..................
|
||||
................................#.......................#...................................................................................
|
||||
.......................#................................................#...............#.........#..................#................#.....
|
||||
............#..................................................................#........................#...................................
|
||||
............................................................................................................................................
|
||||
......#.....................#.......#......#..............#......#..........................................................................
|
||||
.....................#......................................................................................................................
|
||||
................................#................................................#.............#...........................#.............#..
|
||||
..............................................................................................................#.............................
|
||||
............#............#..........................................................................#.............................#.........
|
||||
.....#...........#.....................#.............................#.....#........................................#.......................
|
||||
................................................#...........#..........................#....................................................
|
||||
............................................................................................................................................
|
||||
#..........................#.....#................................................................#......................................#..
|
||||
..........................................#.................................................................#.............#.................
|
||||
................#.........................................................#.................................................................
|
||||
.......#..............................#..............................................#..........................................#...........
|
||||
........................#...................................#...............................................................................
|
||||
............................................................................................................................#...............
|
||||
..............................#.....................#.............................#...........#.................#...........................
|
||||
...............................................#................#.....#................................................#....................
|
||||
...................#...................#.................#.................#.........................#......................................
|
||||
14
2023/days/11/src/main.rs
Normal file
14
2023/days/11/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
388
2023/days/11/src/parse.rs
Normal file
388
2023/days/11/src/parse.rs
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use aoc_libs::distances::Distances;
|
||||
use aoc_libs::points::UPoint;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Space {
|
||||
Galaxy,
|
||||
Space,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct SparseSpace {
|
||||
galaxies: HashSet<UPoint>,
|
||||
empty_rows: HashSet<usize>,
|
||||
empty_columns: HashSet<usize>,
|
||||
}
|
||||
|
||||
impl SparseSpace {
|
||||
pub fn get_distance_between_galaxies(
|
||||
&self,
|
||||
galaxy1: &UPoint,
|
||||
galaxy2: &UPoint,
|
||||
expantion: &usize,
|
||||
) -> usize {
|
||||
// println!("distance between {:?} and {:?}", galaxy1, galaxy2);
|
||||
|
||||
//get unexpanded distance.
|
||||
let mut distance = galaxy1.taxicab_distance(galaxy2);
|
||||
// println!("unexpanded distance is {}", distance);
|
||||
|
||||
//expand rows
|
||||
for y in galaxy1.y.min(galaxy2.y)+1..galaxy1.y.max(galaxy2.y) {
|
||||
if self.empty_rows.contains(&y) {
|
||||
// println!("expanding row {}", y);
|
||||
distance += expantion
|
||||
}
|
||||
}
|
||||
|
||||
//expand columns.
|
||||
for x in galaxy1.x.min(galaxy2.x)+1..galaxy1.x.max(galaxy2.x) {
|
||||
if self.empty_columns.contains(&x) {
|
||||
// println!("expanding col {}", x);
|
||||
distance += expantion
|
||||
}
|
||||
}
|
||||
distance
|
||||
}
|
||||
|
||||
pub fn get_sum_of_distances(&self, expantion: usize) -> usize {
|
||||
self.galaxies
|
||||
.iter()
|
||||
.combinations(2)
|
||||
// .inspect(|pair| println!("{:?}", pair))
|
||||
.map(|pair| self.get_distance_between_galaxies(pair[0], pair[1], &expantion))
|
||||
// .inspect(|distance| println!("{:?}", distance))
|
||||
.sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Vec<Space>>> for SparseSpace {
|
||||
fn from(value: Vec<Vec<Space>>) -> Self {
|
||||
let mut galaxies: HashSet<UPoint> = HashSet::new();
|
||||
let mut empty_rows: HashSet<usize> = HashSet::new();
|
||||
let mut empty_columns: HashSet<usize> = HashSet::new();
|
||||
//find all galaxies and empty rows.
|
||||
for (y, row) in value.iter().enumerate() {
|
||||
let mut has_galaxy = false;
|
||||
for (x, space) in row.iter().enumerate() {
|
||||
if *space == Space::Galaxy {
|
||||
has_galaxy = true;
|
||||
galaxies.insert(UPoint { x, y });
|
||||
};
|
||||
}
|
||||
if !has_galaxy {
|
||||
empty_rows.insert(y);
|
||||
};
|
||||
}
|
||||
|
||||
//find all empty columns
|
||||
for x in 0..value[0].len() {
|
||||
let mut has_galaxy = false;
|
||||
for y in 0..value.len() {
|
||||
if value[y][x] == Space::Galaxy {
|
||||
has_galaxy = true;
|
||||
}
|
||||
}
|
||||
if !has_galaxy {
|
||||
empty_columns.insert(x);
|
||||
};
|
||||
}
|
||||
|
||||
SparseSpace {
|
||||
galaxies,
|
||||
empty_rows,
|
||||
empty_columns,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> SparseSpace {
|
||||
parse_to_space(input).into()
|
||||
}
|
||||
|
||||
pub fn parse_to_space(input: &str) -> Vec<Vec<Space>> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
l.chars()
|
||||
.map(|c| match c {
|
||||
'#' => Space::Galaxy,
|
||||
'.' => Space::Space,
|
||||
_ => panic!("unexpected char {}", c),
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use collection_literals::collection;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_sum_of_distances() {
|
||||
let tested = SparseSpace {
|
||||
galaxies: collection! {
|
||||
UPoint { x: 0, y: 2 },
|
||||
UPoint { x: 0, y: 9 },
|
||||
UPoint { x: 1, y: 5 },
|
||||
UPoint { x: 3, y: 0 },
|
||||
UPoint { x: 4, y: 9 },
|
||||
UPoint { x: 6, y: 4 },
|
||||
UPoint { x: 7, y: 1 },
|
||||
UPoint { x: 7, y: 8 },
|
||||
UPoint { x: 9, y: 6 }
|
||||
},
|
||||
empty_rows: collection! {3, 7},
|
||||
empty_columns: collection! {2, 5, 8},
|
||||
};
|
||||
assert_eq!(tested.get_sum_of_distances(1), 374)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_distance_between_galaxies() {
|
||||
let tested = SparseSpace {
|
||||
galaxies: collection! {
|
||||
UPoint { x: 0, y: 2 },
|
||||
UPoint { x: 0, y: 9 },
|
||||
UPoint { x: 1, y: 5 },
|
||||
UPoint { x: 3, y: 0 },
|
||||
UPoint { x: 4, y: 9 },
|
||||
UPoint { x: 6, y: 4 },
|
||||
UPoint { x: 7, y: 1 },
|
||||
UPoint { x: 7, y: 8 },
|
||||
UPoint { x: 9, y: 6 }
|
||||
},
|
||||
empty_rows: collection! {3, 7},
|
||||
empty_columns: collection! {2, 5, 8},
|
||||
};
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 4, y: 9 },
|
||||
&UPoint { x: 1, y: 5 },
|
||||
&1
|
||||
),
|
||||
9
|
||||
);
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 7, y: 8 },
|
||||
&UPoint { x: 0, y: 3 },
|
||||
&1
|
||||
),
|
||||
15
|
||||
);
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 0, y: 2 },
|
||||
&UPoint { x: 9, y: 6 },
|
||||
&1
|
||||
),
|
||||
17
|
||||
);
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 0, y: 9 },
|
||||
&UPoint { x: 4, y: 9 },
|
||||
&1
|
||||
),
|
||||
5
|
||||
);
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 3, y: 0 },
|
||||
&UPoint { x: 6, y: 4 },
|
||||
&1
|
||||
),
|
||||
9
|
||||
);
|
||||
assert_eq!(
|
||||
tested.get_distance_between_galaxies(
|
||||
&UPoint { x: 7, y: 8 },
|
||||
&UPoint { x: 7, y: 8 },
|
||||
&1
|
||||
),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"...#......\n",
|
||||
".......#..\n",
|
||||
"#.........\n",
|
||||
"..........\n",
|
||||
"......#...\n",
|
||||
".#........\n",
|
||||
".........#\n",
|
||||
"..........\n",
|
||||
".......#..\n",
|
||||
"#...#.....\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
SparseSpace {
|
||||
galaxies: collection! {
|
||||
UPoint { x: 0, y: 2 },
|
||||
UPoint { x: 0, y: 9 },
|
||||
UPoint { x: 1, y: 5 },
|
||||
UPoint { x: 3, y: 0 },
|
||||
UPoint { x: 4, y: 9 },
|
||||
UPoint { x: 6, y: 4 },
|
||||
UPoint { x: 7, y: 1 },
|
||||
UPoint { x: 7, y: 8 },
|
||||
UPoint { x: 9, y: 6 }
|
||||
},
|
||||
empty_rows: collection! {3, 7},
|
||||
empty_columns: collection! {2, 5, 8}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_to_space() {
|
||||
let input = concat!(
|
||||
"...#......\n",
|
||||
".......#..\n",
|
||||
"#.........\n",
|
||||
"..........\n",
|
||||
"......#...\n",
|
||||
".#........\n",
|
||||
".........#\n",
|
||||
"..........\n",
|
||||
".......#..\n",
|
||||
"#...#.....\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse_to_space(input),
|
||||
vec![
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
],
|
||||
vec![
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Galaxy,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space,
|
||||
Space::Space
|
||||
]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
27
2023/days/11/src/part1.rs
Normal file
27
2023/days/11/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part1(input: &SparseSpace) -> usize {
|
||||
input.get_sum_of_distances(1)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = concat!(
|
||||
"...#......\n",
|
||||
".......#..\n",
|
||||
"#.........\n",
|
||||
"..........\n",
|
||||
"......#...\n",
|
||||
".#........\n",
|
||||
".........#\n",
|
||||
"..........\n",
|
||||
".......#..\n",
|
||||
"#...#.....\n",
|
||||
);
|
||||
assert_eq!(part1(&parse(input)), 374)
|
||||
}
|
||||
}
|
||||
28
2023/days/11/src/part2.rs
Normal file
28
2023/days/11/src/part2.rs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use crate::parse::*;
|
||||
|
||||
pub fn part2(input: &SparseSpace) -> usize {
|
||||
input.get_sum_of_distances(999_999)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = concat!(
|
||||
"...#......\n",
|
||||
".......#..\n",
|
||||
"#.........\n",
|
||||
"..........\n",
|
||||
"......#...\n",
|
||||
".#........\n",
|
||||
".........#\n",
|
||||
"..........\n",
|
||||
".......#..\n",
|
||||
"#...#.....\n",
|
||||
);
|
||||
assert_eq!(parse(input).get_sum_of_distances(9), 1030);
|
||||
assert_eq!(parse(input).get_sum_of_distances(99), 8410);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue