day 2 and revised day 1 with advantage of DoubleEndedIterator
This commit is contained in:
parent
b2f78d33e7
commit
69b53f37a6
11 changed files with 2392 additions and 28 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -69,6 +69,7 @@ dependencies = [
|
|||
"async-recursion",
|
||||
"expanduser",
|
||||
"futures",
|
||||
"itertools",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
|
@ -357,6 +358,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.33"
|
||||
|
@ -752,6 +759,15 @@ version = "2.9.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
|
|
|
@ -24,3 +24,4 @@ serde = { version = "1", features = ["derive"] }
|
|||
serde_json = "1"
|
||||
tiktoken-rs = "0.5"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
itertools = "0.12"
|
||||
|
|
100
aoc_puzzle_cache/day_2
Normal file
100
aoc_puzzle_cache/day_2
Normal file
|
@ -0,0 +1,100 @@
|
|||
Game 1: 7 green, 4 blue, 3 red; 4 blue, 10 red, 1 green; 1 blue, 9 red
|
||||
Game 2: 2 red, 4 blue, 3 green; 5 green, 3 red, 1 blue; 3 green, 5 blue, 3 red
|
||||
Game 3: 12 red, 1 blue; 6 red, 2 green, 3 blue; 2 blue, 5 red, 3 green
|
||||
Game 4: 3 green, 1 red, 3 blue; 1 red; 2 green, 1 red, 1 blue; 3 green, 1 blue; 2 blue; 2 green, 4 blue
|
||||
Game 5: 3 blue, 3 red, 8 green; 5 blue, 1 red; 1 green, 19 blue, 3 red; 1 red, 5 green, 3 blue; 4 green, 20 blue, 4 red; 20 blue, 4 green
|
||||
Game 6: 7 green, 6 blue, 1 red; 3 blue, 5 green, 3 red; 9 blue, 3 red, 6 green; 8 blue, 11 green, 3 red; 2 blue, 1 red; 7 green, 4 blue, 1 red
|
||||
Game 7: 5 green, 1 blue; 2 green, 2 blue; 1 blue, 1 red; 5 blue, 2 green; 3 green
|
||||
Game 8: 5 blue, 5 red, 10 green; 6 green, 1 blue, 1 red; 5 red, 2 blue, 16 green; 2 blue, 14 green, 9 red; 9 red, 3 green, 7 blue; 8 red, 4 blue, 10 green
|
||||
Game 9: 1 red, 1 blue, 7 green; 4 red, 6 green, 2 blue; 6 green, 14 blue, 3 red
|
||||
Game 10: 1 red, 16 green, 3 blue; 1 red, 3 blue; 6 green; 4 green, 2 blue, 1 red
|
||||
Game 11: 5 red, 2 blue; 14 blue, 8 red, 10 green; 8 green, 1 red, 15 blue; 2 green, 5 red, 11 blue; 8 red, 11 blue, 4 green
|
||||
Game 12: 5 green, 8 blue, 4 red; 15 green, 8 blue, 8 red; 13 red, 1 blue; 6 blue, 7 green, 14 red; 9 red
|
||||
Game 13: 7 blue, 5 red; 3 green, 10 blue; 5 blue, 2 green, 5 red; 3 blue, 1 green, 5 red; 6 blue, 4 red, 6 green; 5 red, 2 green, 6 blue
|
||||
Game 14: 5 red, 1 blue, 5 green; 6 blue, 13 green, 4 red; 7 blue, 4 red, 1 green; 6 blue, 5 red; 2 red, 7 blue, 2 green
|
||||
Game 15: 8 red, 16 green; 10 green, 1 blue; 16 green, 7 blue, 3 red; 13 red, 7 blue, 8 green; 4 red, 2 green, 8 blue
|
||||
Game 16: 1 red, 1 blue, 5 green; 5 green, 2 red; 2 green, 1 red; 3 red, 4 green
|
||||
Game 17: 3 green, 7 blue, 5 red; 2 red, 1 blue; 8 blue, 1 red
|
||||
Game 18: 9 green, 6 blue, 3 red; 3 red, 15 green, 5 blue; 7 green, 3 red, 3 blue
|
||||
Game 19: 4 green, 3 red, 7 blue; 4 blue, 6 red, 4 green; 6 red, 5 green, 1 blue; 6 blue, 4 green, 3 red; 5 green, 5 red, 2 blue
|
||||
Game 20: 3 green, 5 blue, 1 red; 1 red, 1 blue; 1 red, 6 blue; 1 green, 4 blue
|
||||
Game 21: 2 green, 1 blue, 3 red; 16 green, 1 blue, 4 red; 11 green, 2 red, 1 blue; 6 green, 1 blue; 10 green, 1 red, 1 blue
|
||||
Game 22: 1 blue, 2 green, 4 red; 3 red, 4 green; 1 blue, 3 red, 10 green; 7 green, 1 blue
|
||||
Game 23: 2 red, 14 blue; 2 red, 14 blue; 1 red, 14 blue, 1 green; 1 red, 6 blue; 13 blue, 1 green
|
||||
Game 24: 3 green, 7 blue, 3 red; 4 green, 2 blue; 12 blue, 8 red, 4 green; 10 blue, 9 red, 1 green; 13 blue, 4 red; 12 blue, 9 red, 2 green
|
||||
Game 25: 9 green, 11 red; 14 green, 3 red, 1 blue; 8 red, 7 green; 10 red, 8 green, 1 blue; 6 red, 11 green, 1 blue
|
||||
Game 26: 10 blue, 6 red, 11 green; 9 red, 2 green, 10 blue; 5 red; 9 red, 8 blue, 7 green; 13 green, 10 red, 1 blue
|
||||
Game 27: 3 blue, 1 green; 10 green, 1 blue; 8 red, 6 green, 6 blue
|
||||
Game 28: 10 blue, 2 red, 13 green; 2 blue, 2 red, 6 green; 10 blue; 4 red, 4 blue, 11 green; 3 green, 2 red, 6 blue; 14 green, 2 red, 2 blue
|
||||
Game 29: 8 blue, 5 red, 6 green; 1 green, 4 blue, 15 red; 8 blue, 14 red, 3 green; 9 blue, 4 red, 5 green; 3 red, 3 green, 4 blue
|
||||
Game 30: 19 green, 14 blue, 2 red; 2 red, 8 green, 7 blue; 4 blue, 1 red, 13 green; 10 blue, 3 green; 8 blue, 2 red
|
||||
Game 31: 12 green, 5 blue, 3 red; 15 blue, 11 green, 6 red; 6 green, 6 red; 4 green, 6 blue, 10 red
|
||||
Game 32: 7 red, 2 green, 3 blue; 9 red, 1 green; 2 green, 5 red, 1 blue; 12 red; 14 red, 4 blue
|
||||
Game 33: 9 red, 4 green, 6 blue; 4 red, 10 green; 16 red, 4 green, 4 blue; 15 blue, 12 red
|
||||
Game 34: 5 green, 1 blue; 18 red, 1 green, 1 blue; 1 blue, 9 green, 3 red; 6 green, 11 red
|
||||
Game 35: 2 blue, 19 green, 6 red; 16 green, 1 red, 1 blue; 1 green, 2 blue, 5 red; 8 green, 3 blue, 13 red; 11 red, 10 green, 4 blue
|
||||
Game 36: 17 green, 6 blue; 10 blue, 2 red, 8 green; 16 green, 4 blue, 1 red
|
||||
Game 37: 9 green, 7 red, 8 blue; 1 blue, 10 red; 10 red, 4 blue, 11 green; 8 green, 11 red, 5 blue
|
||||
Game 38: 8 green, 11 blue; 13 green, 2 blue; 7 blue, 2 red, 8 green
|
||||
Game 39: 14 red, 2 green; 2 red, 3 green, 1 blue; 4 red, 5 green, 4 blue; 2 blue, 3 red, 1 green; 17 red, 2 blue; 5 green, 3 red
|
||||
Game 40: 10 blue; 2 red, 9 blue; 5 red, 1 green, 2 blue; 8 blue, 2 red; 6 blue, 2 red; 4 red, 2 blue, 1 green
|
||||
Game 41: 2 blue, 3 red, 2 green; 4 green, 2 red, 11 blue; 11 blue, 3 red, 1 green; 1 red, 6 green, 1 blue; 5 red, 7 green
|
||||
Game 42: 1 blue, 14 green, 1 red; 2 blue, 2 green; 5 green, 2 blue, 8 red
|
||||
Game 43: 15 red, 5 blue, 5 green; 15 green, 15 red, 1 blue; 4 blue, 13 green, 13 red; 3 red, 16 green; 2 red, 3 green, 2 blue
|
||||
Game 44: 8 green, 8 blue; 9 blue, 9 green; 9 green, 3 blue; 8 green, 3 blue; 8 blue, 2 green; 9 blue, 1 red, 8 green
|
||||
Game 45: 4 red, 4 blue, 4 green; 5 red, 2 green, 9 blue; 8 blue, 5 red, 3 green; 4 red, 3 blue; 5 red, 5 green, 1 blue
|
||||
Game 46: 1 blue, 9 green, 2 red; 2 blue, 9 green, 1 red; 8 green, 3 red
|
||||
Game 47: 2 green, 4 blue, 10 red; 4 green, 5 blue, 1 red; 10 green, 13 red, 6 blue; 4 green, 4 blue, 12 red; 15 red, 1 blue, 4 green
|
||||
Game 48: 1 red, 7 green; 2 blue, 4 green, 5 red; 5 red, 3 green, 1 blue; 8 green
|
||||
Game 49: 3 blue, 4 green, 3 red; 6 red, 5 green, 5 blue; 1 blue, 4 green, 3 red; 6 red, 1 blue, 5 green; 4 red, 3 green, 5 blue; 2 green, 3 blue, 1 red
|
||||
Game 50: 1 green, 5 red, 6 blue; 3 red, 2 green; 1 red, 1 green, 6 blue; 1 green, 7 red, 3 blue
|
||||
Game 51: 7 green, 8 blue; 6 blue, 6 red, 4 green; 6 green, 1 blue; 8 blue, 5 red, 4 green
|
||||
Game 52: 7 red, 3 blue, 6 green; 7 green, 5 red, 4 blue; 6 red, 4 blue
|
||||
Game 53: 12 blue, 1 red, 5 green; 4 green, 2 blue, 5 red; 5 red, 4 green; 1 green, 3 blue, 5 red; 5 blue, 2 red, 5 green
|
||||
Game 54: 15 green, 12 red; 11 red, 3 green, 2 blue; 3 blue, 6 green; 3 red, 1 blue, 5 green; 17 red, 7 green
|
||||
Game 55: 7 green, 10 red, 7 blue; 8 red, 4 blue, 11 green; 9 green, 11 red
|
||||
Game 56: 7 green, 3 blue, 5 red; 6 green, 1 red, 4 blue; 4 green, 2 red; 5 blue, 6 red, 8 green
|
||||
Game 57: 1 green, 3 red, 3 blue; 5 blue, 2 red, 2 green; 1 green, 5 blue
|
||||
Game 58: 4 red, 2 green; 13 green, 4 red, 1 blue; 12 green, 4 blue
|
||||
Game 59: 4 red, 4 green; 5 blue, 1 green, 20 red; 11 red, 3 green, 15 blue; 5 blue, 7 red, 3 green; 18 blue, 4 green, 19 red
|
||||
Game 60: 5 blue, 8 red, 4 green; 4 blue, 12 green, 19 red; 3 blue, 1 green, 17 red; 1 green, 3 blue; 2 green, 6 blue, 3 red
|
||||
Game 61: 3 red, 7 blue, 12 green; 7 red, 1 green, 6 blue; 6 red, 2 green, 18 blue; 14 blue, 5 red, 1 green
|
||||
Game 62: 1 red, 2 blue; 1 green, 3 red; 1 green, 9 blue, 4 red
|
||||
Game 63: 6 green, 4 blue, 17 red; 2 green, 2 blue, 12 red; 10 green, 9 blue, 13 red; 15 red, 8 green, 5 blue
|
||||
Game 64: 4 green, 7 blue, 10 red; 3 green, 4 blue, 12 red; 6 green, 6 red, 8 blue; 4 green, 9 red, 1 blue; 2 blue, 15 red, 15 green
|
||||
Game 65: 5 green, 4 blue, 7 red; 6 green, 7 blue, 8 red; 1 green, 7 red; 1 blue, 10 red, 8 green
|
||||
Game 66: 5 green, 5 blue, 2 red; 3 red; 1 red, 1 blue, 16 green; 2 blue, 1 green; 8 green, 1 blue, 3 red; 14 green, 4 red
|
||||
Game 67: 12 blue, 7 green; 7 blue, 7 green, 1 red; 12 blue, 1 green, 6 red
|
||||
Game 68: 2 blue, 8 red, 1 green; 9 blue, 3 green, 12 red; 14 blue, 15 red, 6 green
|
||||
Game 69: 7 red, 1 blue; 11 green, 2 blue, 13 red; 3 blue, 13 green, 3 red; 1 blue, 10 red, 8 green; 15 red, 2 blue, 19 green
|
||||
Game 70: 10 green, 10 red, 12 blue; 7 red, 15 blue, 2 green; 8 blue, 9 green
|
||||
Game 71: 1 blue, 2 green, 13 red; 7 red; 1 green, 5 red
|
||||
Game 72: 2 red, 1 blue, 11 green; 1 red, 2 blue, 18 green; 5 red, 3 blue, 3 green
|
||||
Game 73: 13 red, 3 blue, 4 green; 3 green, 17 red, 1 blue; 6 blue, 4 green, 4 red; 13 red, 7 blue
|
||||
Game 74: 1 blue, 3 red; 13 blue, 5 red, 2 green; 1 red, 8 green, 11 blue; 4 blue, 1 green, 5 red; 11 blue, 8 red, 6 green; 8 red, 3 green, 4 blue
|
||||
Game 75: 7 blue, 4 green, 1 red; 3 green, 4 blue; 5 green, 2 red, 3 blue; 6 blue, 3 red, 5 green
|
||||
Game 76: 9 green, 1 blue, 4 red; 6 red, 9 green, 3 blue; 2 red, 6 green, 2 blue; 5 green; 6 green, 2 red, 3 blue; 6 blue, 5 red, 5 green
|
||||
Game 77: 2 green, 2 red; 1 blue, 6 red, 2 green; 4 green, 3 red, 2 blue; 2 blue, 1 green, 1 red
|
||||
Game 78: 2 green, 10 red, 2 blue; 6 green, 2 red, 2 blue; 2 blue, 9 red, 6 green; 11 red, 6 green; 3 red, 8 green; 1 blue, 6 green, 1 red
|
||||
Game 79: 3 blue, 8 green, 13 red; 3 blue, 2 red, 3 green; 10 red, 6 green, 4 blue; 11 red, 1 blue, 3 green
|
||||
Game 80: 3 green, 5 red, 9 blue; 3 red, 5 blue, 2 green; 5 green, 6 red, 2 blue
|
||||
Game 81: 2 green, 7 blue, 3 red; 9 blue, 3 red; 1 green, 17 blue, 2 red
|
||||
Game 82: 4 green, 8 blue, 7 red; 10 blue, 1 green, 10 red; 7 blue, 4 green, 5 red
|
||||
Game 83: 7 green, 4 blue, 3 red; 15 blue, 3 red, 14 green; 9 blue, 4 red, 7 green
|
||||
Game 84: 5 red, 5 green; 16 blue, 1 red, 7 green; 17 blue, 11 red
|
||||
Game 85: 7 red, 1 green, 11 blue; 13 blue, 5 green, 6 red; 11 blue, 2 green, 8 red; 5 blue, 17 red, 4 green; 12 blue, 2 green, 8 red
|
||||
Game 86: 3 red, 8 blue, 2 green; 15 green, 15 blue, 2 red; 18 blue, 2 red, 11 green
|
||||
Game 87: 1 blue; 6 red, 6 green; 1 blue, 9 red, 3 green
|
||||
Game 88: 10 green, 2 blue, 1 red; 7 blue, 1 green, 1 red; 9 green, 4 blue; 8 green, 1 red, 7 blue
|
||||
Game 89: 6 green, 2 red, 2 blue; 5 red, 3 blue, 3 green; 3 blue, 4 red, 1 green; 5 red, 4 green, 5 blue; 4 blue, 6 green, 3 red; 3 red, 1 green
|
||||
Game 90: 1 green, 6 blue; 1 blue, 1 red; 2 blue, 3 green; 7 green, 6 blue; 1 red, 7 green, 6 blue
|
||||
Game 91: 8 blue, 14 green, 5 red; 8 red, 6 green; 4 red, 7 blue, 14 green; 4 blue, 7 green; 9 blue, 7 red; 14 green, 7 blue, 4 red
|
||||
Game 92: 11 blue, 8 green, 6 red; 11 blue, 1 red, 11 green; 10 blue, 19 green, 5 red
|
||||
Game 93: 5 green, 1 red, 7 blue; 8 green, 14 blue, 2 red; 5 red, 14 blue, 7 green
|
||||
Game 94: 2 blue, 6 red, 3 green; 4 red, 2 green, 2 blue; 4 red, 1 blue, 1 green
|
||||
Game 95: 9 red, 15 green, 1 blue; 2 blue, 10 red, 18 green; 3 red, 10 green; 10 red, 17 green, 2 blue; 3 blue, 13 green, 1 red; 2 red, 2 blue, 6 green
|
||||
Game 96: 8 green, 1 blue; 1 blue, 1 red, 11 green; 2 green, 15 blue; 1 red, 2 green, 1 blue
|
||||
Game 97: 3 green, 3 blue; 5 green, 3 blue, 1 red; 5 green, 1 red, 3 blue; 1 green, 1 red, 2 blue; 2 green, 2 blue, 3 red
|
||||
Game 98: 6 red, 6 green, 5 blue; 19 red, 7 green; 6 green, 8 blue, 4 red; 10 green, 4 red
|
||||
Game 99: 9 red, 8 blue, 10 green; 3 blue, 7 green, 8 red; 6 red, 12 blue; 8 blue, 8 green, 2 red; 16 green, 14 blue, 5 red
|
||||
Game 100: 8 red, 13 green; 5 red, 4 green; 7 blue, 3 red, 8 green; 13 blue, 6 green; 1 blue, 8 green, 7 red; 2 red, 1 green, 16 blue
|
|
@ -1,14 +1,24 @@
|
|||
use aoc23::prelude::*;
|
||||
|
||||
fn d1_0(input: String) -> Result<usize> {
|
||||
fn part1(input: String) -> Result<usize> {
|
||||
let mut sum = 0;
|
||||
for line in input.lines().into_iter() {
|
||||
let chars = line.chars();
|
||||
let first_num: usize = chars.clone().into_iter().skip_while(|c| !c.is_digit(10)).take(1)
|
||||
let first_num: usize = chars
|
||||
.clone()
|
||||
.into_iter()
|
||||
.skip_while(|c| !c.is_digit(10))
|
||||
.take(1)
|
||||
// This would get continuous digits: .take_while(|c| c.is_digit(10))
|
||||
.collect::<String>().parse()?;
|
||||
let last_num: usize =
|
||||
chars.into_iter().rev().skip_while(|c| !c.is_digit(10)).take(1).collect::<String>().parse()?;
|
||||
.collect::<String>()
|
||||
.parse()?;
|
||||
let last_num: usize = chars
|
||||
.into_iter()
|
||||
.rev()
|
||||
.skip_while(|c| !c.is_digit(10))
|
||||
.take(1)
|
||||
.collect::<String>()
|
||||
.parse()?;
|
||||
let value = first_num * 10 + last_num;
|
||||
sum += value;
|
||||
}
|
||||
|
@ -36,10 +46,11 @@ fn first_occurrence(str: &str, reversed: bool) -> Option<u32> {
|
|||
if reversed {
|
||||
for (i, char) in str.chars().rev().enumerate() {
|
||||
let digit = char.to_digit(10).or_else(|| {
|
||||
for num in 1 ..= 9 {
|
||||
for num in 1..=9 {
|
||||
if let Some(num_word) = num_to_word(num) {
|
||||
if i + 1 >= num_word.len() &&
|
||||
&str[str.len() - i - 1 .. str.len()][..num_word.len()] == num_word {
|
||||
if i + 1 >= num_word.len()
|
||||
&& &str[str.len() - i - 1..str.len()][..num_word.len()] == num_word
|
||||
{
|
||||
return Some(num);
|
||||
}
|
||||
}
|
||||
|
@ -53,9 +64,9 @@ fn first_occurrence(str: &str, reversed: bool) -> Option<u32> {
|
|||
} else {
|
||||
for (i, char) in str.chars().enumerate() {
|
||||
let digit = char.to_digit(10).or_else(|| {
|
||||
for num in 1 ..= 9 {
|
||||
for num in 1..=9 {
|
||||
if let Some(num_word) = num_to_word(num) {
|
||||
if i + 1 >= num_word.len() && &str[i + 1 - num_word.len() ..= i] == num_word {
|
||||
if i + 1 >= num_word.len() && &str[i + 1 - num_word.len()..=i] == num_word {
|
||||
return Some(num);
|
||||
}
|
||||
}
|
||||
|
@ -70,15 +81,15 @@ fn first_occurrence(str: &str, reversed: bool) -> Option<u32> {
|
|||
None
|
||||
}
|
||||
|
||||
fn d1_1(input: String) -> Result<u32> {
|
||||
fn part_2(input: String) -> Result<u32> {
|
||||
let mut sum = 0;
|
||||
for line in input.lines().into_iter() {
|
||||
let first_num = first_occurrence(line, false).ok_or("No number found in line")?;
|
||||
let last_num = first_occurrence(line, true).ok_or("No number found in line reversed")?;
|
||||
let value = first_num * 10 + last_num;
|
||||
sum += value;
|
||||
println!("Line {line}: a:{first_num}|b:{last_num} = {value} ++ {sum}");
|
||||
}
|
||||
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
|
@ -87,8 +98,7 @@ async fn main() -> Result<()> {
|
|||
println!("Day 1");
|
||||
println!("=====");
|
||||
let input = utils::aoc::get_puzzle_input(1).await?;
|
||||
|
||||
println!("Day 1, 0: {}", d1_0(input.clone())?);
|
||||
println!("Day 1, 1: {}", d1_1(input.clone())?);
|
||||
println!("part 1: {}", part1(input.clone())?);
|
||||
println!("part 2: {}", part_2(input.clone())?);
|
||||
Ok(())
|
||||
}
|
||||
|
|
91
src/bin/day1_revised.rs
Normal file
91
src/bin/day1_revised.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
use aoc23::prelude::*;
|
||||
|
||||
fn part1(input: String) -> Result<usize> {
|
||||
let mut sum = 0;
|
||||
for line in input.lines().into_iter() {
|
||||
let chars = line.chars();
|
||||
let first_num: usize = chars
|
||||
.clone()
|
||||
.into_iter()
|
||||
.skip_while(|c| !c.is_digit(10))
|
||||
.take(1)
|
||||
// This would get continuous digits: .take_while(|c| c.is_digit(10))
|
||||
.collect::<String>()
|
||||
.parse()?;
|
||||
let last_num: usize = chars
|
||||
.into_iter()
|
||||
.rev()
|
||||
.skip_while(|c| !c.is_digit(10))
|
||||
.take(1)
|
||||
.collect::<String>()
|
||||
.parse()?;
|
||||
let value = first_num * 10 + last_num;
|
||||
sum += value;
|
||||
}
|
||||
|
||||
// println!("Answer: {}", sum);
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
fn part_2(input: String) -> Result<u32> {
|
||||
let numbers: [(&'static str, u32); 9] = [
|
||||
("one", 1),
|
||||
("two", 2),
|
||||
("three", 3),
|
||||
("four", 4),
|
||||
("five", 5),
|
||||
("six", 6),
|
||||
("seven", 7),
|
||||
("eight", 8),
|
||||
("nine", 9),
|
||||
];
|
||||
let mut sum = 0;
|
||||
for line in input.lines().into_iter() {
|
||||
let mut chars = line.chars();
|
||||
let mut peek_index = 0;
|
||||
let first_num = loop {
|
||||
// I wanted this to work but peek advances the iterator anyways despite saying it
|
||||
// doesn't. I don't understand
|
||||
//
|
||||
// ```
|
||||
// if let Some(Some(peek_digit)) = chars.by_ref().peekable().peek().map(|c| c.to_digit(10))
|
||||
// ```
|
||||
if let Some(Some(peek_digit)) = line.chars().nth(peek_index).map(|c| c.to_digit(10)) {
|
||||
break peek_digit;
|
||||
}
|
||||
if let Some((_, digit)) = numbers.iter().find(|num| chars.as_str().starts_with(num.0)) {
|
||||
break *digit;
|
||||
}
|
||||
if chars.next().is_none() {
|
||||
break 0;
|
||||
}
|
||||
peek_index += 1;
|
||||
};
|
||||
let last_num = loop {
|
||||
if let Some((_, digit)) = numbers.iter().find(|num| chars.as_str().ends_with(num.0)) {
|
||||
break *digit;
|
||||
}
|
||||
if let Some(last_char) = chars.next_back() {
|
||||
if let Some(digit) = last_char.to_digit(10) {
|
||||
break digit;
|
||||
}
|
||||
} else {
|
||||
break first_num;
|
||||
}
|
||||
};
|
||||
let value = first_num * 10 + last_num;
|
||||
sum += value;
|
||||
println!("Line {line}: a:{first_num}|b:{last_num} = {value} ++ {sum}");
|
||||
}
|
||||
Ok(sum)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
println!("Day 1");
|
||||
println!("=====");
|
||||
let input = utils::aoc::get_puzzle_input(1).await?;
|
||||
println!("part 1: {}", part1(input.clone())?);
|
||||
println!("part 2: {}", part_2(input.clone())?);
|
||||
Ok(())
|
||||
}
|
144
src/bin/day2.rs
Normal file
144
src/bin/day2.rs
Normal file
|
@ -0,0 +1,144 @@
|
|||
use aoc23::prelude::*;
|
||||
use std::{collections::HashMap, error::Error, fmt::Display, str::FromStr, string::ParseError};
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||
enum Cube {
|
||||
Blue,
|
||||
Red,
|
||||
Green,
|
||||
}
|
||||
|
||||
impl FromStr for Cube {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
match s {
|
||||
"blue" => Ok(Cube::Blue),
|
||||
"red" => Ok(Cube::Red),
|
||||
"green" => Ok(Cube::Green),
|
||||
_ => Err("asd".into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cube {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Cube::Blue => "blue",
|
||||
Cube::Red => "red",
|
||||
Cube::Green => "green",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
struct Game {
|
||||
id: u32,
|
||||
sets: Vec<HashMap<Cube, u32>>,
|
||||
}
|
||||
|
||||
impl FromStr for Game {
|
||||
type Err = String;
|
||||
|
||||
// Game 1: 7 green, 4 blue, 3 red; 4 blue, 10 red, 1 green; 1 blue, 9 red Game 2:
|
||||
// 2 red, 4 blue, 3 green; 5 green, 3 red, 1 blue; 3 green, 5 blue, 3 red Game 3:
|
||||
// 12 red, 1 blue; 6 red, 2 green, 3 blue; 2 blue, 5 red, 3 green
|
||||
fn from_str(line: &str) -> std::result::Result<Self, Self::Err> {
|
||||
let parts: Vec<&str> = line.split(':').collect();
|
||||
let id = parts[0]
|
||||
.trim()
|
||||
.split_whitespace()
|
||||
.last()
|
||||
.ok_or("no id")?
|
||||
.parse::<u32>()
|
||||
.ok()
|
||||
.ok_or("not a number")?;
|
||||
let sets = parts[1]
|
||||
.split(';')
|
||||
.map(|set| {
|
||||
set.split(',')
|
||||
.filter_map(|part| {
|
||||
let mut iter = part.trim().split_whitespace();
|
||||
let count = iter.next().unwrap().parse::<u32>().unwrap();
|
||||
let color = iter.next().unwrap().parse::<Cube>().ok()?;
|
||||
Some((color, count))
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
Ok(Game { id, sets })
|
||||
}
|
||||
}
|
||||
|
||||
fn part1(input: String) -> Result<impl Display> {
|
||||
let games: Vec<Game> = input
|
||||
.lines()
|
||||
.into_iter()
|
||||
.map(|l| l.parse().expect("failed to parse line"))
|
||||
.collect();
|
||||
let mut possible_game_id_sum = 0;
|
||||
let limit_red = 12;
|
||||
let limit_green = 13;
|
||||
let limit_blue = 14;
|
||||
for game in games {
|
||||
let out_of_bounds = game.sets.iter().any(|set| match set.get(&Cube::Red) {
|
||||
Some(red) => red > &limit_red,
|
||||
None => false,
|
||||
} || match set.get(&Cube::Green) {
|
||||
Some(green) => green > &limit_green,
|
||||
None => false,
|
||||
} || match set.get(&Cube::Blue) {
|
||||
Some(blue) => blue > &limit_blue,
|
||||
None => false,
|
||||
});
|
||||
if !out_of_bounds {
|
||||
// println!("Valid game id, {:?}", game);
|
||||
possible_game_id_sum += game.id;
|
||||
} else {
|
||||
// println!("INVALID game {:?}", game);
|
||||
}
|
||||
}
|
||||
Ok(possible_game_id_sum)
|
||||
}
|
||||
|
||||
fn part2(input: String) -> Result<impl Display> {
|
||||
let games: Vec<Game> = input
|
||||
.lines()
|
||||
.into_iter()
|
||||
.map(|l| l.parse().expect("failed to parse line"))
|
||||
.collect();
|
||||
let mut power_sum = 0;
|
||||
for game in games {
|
||||
let mut maxes: HashMap<Cube, u32> = [(Cube::Red, 1), (Cube::Green, 1), (Cube::Blue, 1)]
|
||||
.into_iter()
|
||||
.collect();
|
||||
for set in game.sets.iter() {
|
||||
for (cube, &count) in set {
|
||||
let max_count = maxes.get_mut(cube).ok_or("default missing")?;
|
||||
*max_count = u32::max(*max_count, count);
|
||||
}
|
||||
}
|
||||
let power = maxes.values().into_iter().fold(1u32, |acc, v| acc * v);
|
||||
power_sum += power;
|
||||
}
|
||||
Ok(power_sum)
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
println!("Day 1");
|
||||
println!("=====");
|
||||
let input = utils::aoc::get_puzzle_input(2).await?;
|
||||
|
||||
// ```
|
||||
// let input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
|
||||
// Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
|
||||
// Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
|
||||
// Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
|
||||
// Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"
|
||||
// .to_owned();
|
||||
// ```
|
||||
println!("part 1: {}", part1(input.clone())?);
|
||||
println!("part 2: {}", part2(input.clone())?);
|
||||
Ok(())
|
||||
}
|
|
@ -3,12 +3,7 @@ pub mod utils;
|
|||
pub mod prelude {
|
||||
pub use super::utils::{
|
||||
self,
|
||||
common::{
|
||||
BoxE,
|
||||
Result,
|
||||
SError,
|
||||
SResult,
|
||||
},
|
||||
common::{BoxE, Result, SError, SResult},
|
||||
config::get_config,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use std::{
|
||||
env::var,
|
||||
sync::OnceLock,
|
||||
};
|
||||
use std::{env::var, sync::OnceLock};
|
||||
|
||||
static CONFIG: OnceLock<Config> = OnceLock::new();
|
||||
|
||||
|
@ -9,13 +6,15 @@ pub struct Config {
|
|||
pub aoc_session: String,
|
||||
}
|
||||
|
||||
impl Config { }
|
||||
impl Config {}
|
||||
|
||||
fn get_var(var_name: &str) -> String {
|
||||
var(var_name).unwrap_or("".to_owned())
|
||||
}
|
||||
|
||||
pub fn get_config() -> &'static Config {
|
||||
let config = CONFIG.get_or_init(|| Config { aoc_session: get_var("AOC_SESSION") });
|
||||
let config = CONFIG.get_or_init(|| Config {
|
||||
aoc_session: get_var("AOC_SESSION"),
|
||||
});
|
||||
config
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pub mod aoc;
|
||||
pub mod common;
|
||||
pub mod config;
|
||||
pub mod aoc;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue