This commit is contained in:
Tyler Beckman 2023-12-04 23:17:46 -07:00
parent f23334c962
commit 7bbd5ff22c
Signed by: Ty
GPG key ID: 2813440C772555A4
3 changed files with 255 additions and 9 deletions

View file

@ -6,7 +6,7 @@ use crate::utils::Day;
pub struct Day4 { pub struct Day4 {
pub input: String, pub input: String,
pub acc: usize, pub acc: usize,
pub cards: HashMap::<usize /* Card # */, Vec<usize> /* (won card indexes) */> pub cards: HashMap<usize /* Card # */, Vec<usize> /* (won card indexes) */>,
} }
impl Day4 { impl Day4 {
@ -37,7 +37,10 @@ impl Day for Day4 {
} }
if winning_numbers.len() != 0 { if winning_numbers.len() != 0 {
sum += winning_numbers.iter().skip(1).fold(1usize, |acc, _| acc * 2); sum += winning_numbers
.iter()
.skip(1)
.fold(1usize, |acc, _| acc * 2);
} }
} }
@ -57,7 +60,14 @@ impl Day for Day4 {
} }
} }
self.cards.insert(i + 1, winning_numbers.into_iter().enumerate().map(|(j, _)| (i + 1) + (j + 1)).collect()); self.cards.insert(
i + 1,
winning_numbers
.into_iter()
.enumerate()
.map(|(j, _)| (i + 1) + (j + 1))
.collect(),
);
} }
self.recurse(&self.cards.keys().map(|e| *e).collect::<Vec<_>>()); self.recurse(&self.cards.keys().map(|e| *e).collect::<Vec<_>>());

233
src/day5/mod.rs Normal file
View file

@ -0,0 +1,233 @@
use std::collections::HashMap;
use crate::utils::Day;
#[derive(Debug)]
pub struct Day5 {
pub input: String,
}
impl Day for Day5 {
fn part1(&mut self) -> String {
let groups = self.input.split("\n\n").skip(1).map(|g| {
let mut lines = g.lines();
(lines.next().unwrap(), lines.collect::<Vec<_>>())
});
let seeds = self
.input
.lines()
.next()
.unwrap()
.split_once(": ")
.unwrap()
.1
.split_whitespace()
.map(|s| s.parse::<usize>().unwrap());
let groups = groups
.map(|(name, list)| {
(
name.split_once(' ').unwrap().0.split_once("-to-").unwrap(),
list.into_iter().map(|line| {
let nums = line.split_whitespace()
.map(|n| n.parse::<usize>().unwrap())
.collect::<Vec<_>>();
(nums[0], nums[1], nums[2])
}).collect::<Vec<_>>(),
)
})
.map(|((from, to), mappings)| (
from,
(
to,
mappings
)
))
.collect::<HashMap<&str, (&str, Vec<(usize, usize, usize)>)>>();
let mut locations = Vec::<usize>::new();
for seed in seeds {
let (mut category, mut value) = ("seed", seed);
while category != "location" {
let (new_category, mappings) = groups.get(category).unwrap();
category = new_category;
for (destination_start, source_start, length) in mappings {
if (source_start..&(source_start + length)).contains(&&value) {
let delta = *source_start as isize - *destination_start as isize;
value = (value as isize - delta) as usize;
break;
}
}
}
locations.push(value)
}
locations.into_iter().min().unwrap().to_string()
}
/// Yes my solution was to brute force it
/// Yes it worked
/// Yes it only took 13m and 31s to solve
/// No I will not elaborate on why I felt the need to do it this way
/// Yes I should probably solve it correctly at some point
fn part2(&mut self) -> String {
let groups = self.input.split("\n\n").skip(1).map(|g| {
let mut lines = g.lines();
(lines.next().unwrap(), lines.collect::<Vec<_>>())
});
let seeds = self
.input
.lines()
.next()
.unwrap()
.split_once(": ")
.unwrap()
.1
.split_whitespace()
.map(|s| s.parse::<usize>().unwrap())
.collect::<Vec<usize>>();
let seeds = seeds
.as_slice()
.chunks(2);
let groups = groups
.map(|(name, list)| {
(
name.split_once(' ').unwrap().0.split_once("-to-").unwrap(),
list.into_iter().map(|line| {
let nums = line.split_whitespace()
.map(|n| n.parse::<usize>().unwrap())
.collect::<Vec<_>>();
(nums[0], nums[1], nums[2])
}).collect::<Vec<_>>(),
)
})
.map(|((from, to), mappings)| (
from,
(
to,
mappings
)
))
.collect::<HashMap<&str, (&str, Vec<(usize, usize, usize)>)>>();
let mut location = 100000000usize;
let seedslen = seeds.len();
for (i, chunk) in seeds.enumerate() {
let (initial, range) = (chunk[0], chunk[1]);
for (j, seed) in (initial..(initial + range)).enumerate() {
if j % 1000 == 0 {
println!("Chunk {}/{}, Seed {}/{} ({:.2}%)", i, seedslen, j, range, j as f64 / range as f64 * 100.0);
}
let (mut category, mut value) = ("seed", seed);
while category != "location" {
let (new_category, mappings) = groups.get(category).unwrap();
category = new_category;
for (destination_start, source_start, length) in mappings {
if (source_start..&(source_start + length)).contains(&&value) {
let delta = *source_start as isize - *destination_start as isize;
value = (value as isize - delta) as usize;
break;
}
}
}
if location > value { location = value }
}
}
location.to_string()
}
}
#[cfg(test)]
mod tests {
use crate::{day5::Day5, utils::Day};
#[test]
fn passes_example_1() {
dbg!(Day5 {
input: r#"seeds: 79 14 55 13
seed-to-soil map:
50 98 2
52 50 48
soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15
fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4
water-to-light map:
88 18 7
18 25 70
light-to-temperature map:
45 77 23
81 45 19
68 64 13
temperature-to-humidity map:
0 69 1
1 0 69
humidity-to-location map:
60 56 37
56 93 4"#.to_string(),
}
.solve(1));
}
#[test]
fn passes_example_2() {
dbg!(Day5 {
input: r#"seeds: 79 14 55 13
seed-to-soil map:
50 98 2
52 50 48
soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15
fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4
water-to-light map:
88 18 7
18 25 70
light-to-temperature map:
45 77 23
81 45 19
68 64 13
temperature-to-humidity map:
0 69 1
1 0 69
humidity-to-location map:
60 56 37
56 93 4"#.to_string(),
}
.solve(2));
}
}

View file

@ -6,12 +6,13 @@ use std::{
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use crate::{day1::Day1, day2::Day2, day3::Day3, day4::Day4, utils::Day}; use crate::{day1::Day1, day2::Day2, day3::Day3, day4::Day4, day5::Day5, utils::Day};
pub mod day1; pub mod day1;
pub mod day2; pub mod day2;
pub mod day3; pub mod day3;
pub mod day4; pub mod day4;
pub mod day5;
pub mod fetcher; pub mod fetcher;
pub mod utils; pub mod utils;
@ -91,6 +92,7 @@ async fn main() {
acc: 0usize, acc: 0usize,
cards: HashMap::new(), cards: HashMap::new(),
}), }),
5 => Box::new(Day5 { input: response }),
_ => panic!("Invalid day #"), _ => panic!("Invalid day #"),
}; };
let start = std::time::Instant::now(); let start = std::time::Instant::now();
@ -140,6 +142,7 @@ async fn main() {
acc: 0usize, acc: 0usize,
cards: HashMap::new(), cards: HashMap::new(),
}), }),
5 => Box::new(Day5 { input: response }),
_ => panic!("Invalid day #"), _ => panic!("Invalid day #"),
}; };
let mut timings = Vec::<Duration>::new(); let mut timings = Vec::<Duration>::new();