mirror of
https://github.com/OMGeeky/advent-of-code-2023.git
synced 2026-02-23 15:38:26 +01:00
day 05 part 1
This commit is contained in:
205
src/day05.rs
Normal file
205
src/day05.rs
Normal file
@@ -0,0 +1,205 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::*;
|
||||
|
||||
pub struct Day05;
|
||||
impl Day for Day05 {
|
||||
const DAY_NUM: u8 = 05;
|
||||
type Input = String;
|
||||
type Output = usize;
|
||||
|
||||
fn get_test_data() -> Self::Input {
|
||||
"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()
|
||||
}
|
||||
|
||||
fn get_test_result() -> Self::Output {
|
||||
35
|
||||
}
|
||||
|
||||
fn run(data: Self::Input) -> Self::Output {
|
||||
let mut data = data.lines().map(|x| x.trim());
|
||||
let target_seeds = data.next().unwrap();
|
||||
println!("targets: {}", target_seeds);
|
||||
let mut dict = HashMap::new();
|
||||
|
||||
for (is_map, lines) in &data
|
||||
// .inspect(|x| println!("{}", x))
|
||||
.group_by(|x| x.len() > 0)
|
||||
{
|
||||
if !is_map {
|
||||
continue;
|
||||
}
|
||||
let lines = lines.collect::<Vec<_>>();
|
||||
dbg!(&lines);
|
||||
let map = Map::from_vec(lines);
|
||||
dbg!(&map);
|
||||
dict.insert(map.from, map);
|
||||
}
|
||||
let result = target_seeds
|
||||
.trim()
|
||||
.strip_prefix("seeds: ")
|
||||
.unwrap()
|
||||
.split(' ')
|
||||
.map(|seed_pos| {
|
||||
let seed_pos = seed_pos.parse().unwrap();
|
||||
let target = map_seed_to_position(seed_pos, &dict);
|
||||
dbg!(target);
|
||||
target
|
||||
})
|
||||
.min()
|
||||
.unwrap();
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
fn map_seed_to_position(var_name: usize, dict: &HashMap<Kind, Map>) -> usize {
|
||||
let mut kind = Kind::Seed;
|
||||
let mut source = var_name;
|
||||
while kind != Kind::Location {
|
||||
let map = dict.get(&kind).unwrap();
|
||||
println!("Mapping {:?} to {:?}", kind, map.to);
|
||||
kind = map.to;
|
||||
let get_mapped = map.get_mapped(source);
|
||||
println!("Mapping {:?} to {:?}", source, get_mapped);
|
||||
source = get_mapped;
|
||||
}
|
||||
println!("destination: {source}");
|
||||
source
|
||||
}
|
||||
|
||||
use data::*;
|
||||
use itertools::Itertools;
|
||||
mod data {
|
||||
use super::*;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Map {
|
||||
pub from: Kind,
|
||||
pub to: Kind,
|
||||
ranges: Vec<Range>,
|
||||
}
|
||||
|
||||
impl Map {
|
||||
pub fn from_vec(value: Vec<&str>) -> Self {
|
||||
value.join("\n").into()
|
||||
}
|
||||
pub fn get_mapped(&self, source: usize) -> usize {
|
||||
for range in &self.ranges {
|
||||
if let Some(target) = range.get_mapped(source) {
|
||||
return target;
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
}
|
||||
impl<T> From<T> for Map
|
||||
where
|
||||
T: AsRef<str>,
|
||||
{
|
||||
fn from(value: T) -> Self {
|
||||
let value = value.as_ref();
|
||||
let mut values = value.trim().lines();
|
||||
let mut map_name = values
|
||||
.next()
|
||||
.unwrap()
|
||||
.strip_suffix(" map:")
|
||||
.unwrap()
|
||||
.split("-to-");
|
||||
let from = map_name.next().unwrap().into();
|
||||
let to = map_name.next().unwrap().into();
|
||||
let ranges = values.map(|x| x.into()).collect();
|
||||
Self { from, to, ranges }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Kind {
|
||||
Seed,
|
||||
Soil,
|
||||
Fertilizer,
|
||||
Water,
|
||||
Light,
|
||||
Temperature,
|
||||
Humidity,
|
||||
Location,
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> From<T> for Kind {
|
||||
fn from(value: T) -> Self {
|
||||
match value.as_ref() {
|
||||
"soil" => Kind::Soil,
|
||||
"fertilizer" => Kind::Fertilizer,
|
||||
"humidity" => Kind::Humidity,
|
||||
"light" => Kind::Light,
|
||||
"location" => Kind::Location,
|
||||
"seed" => Kind::Seed,
|
||||
"temperature" => Kind::Temperature,
|
||||
"water" => Kind::Water,
|
||||
other => panic!("got an invalid kind to parse: {other}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Range {
|
||||
destination_start: usize,
|
||||
source_start: usize,
|
||||
length: usize,
|
||||
}
|
||||
impl Range {
|
||||
fn get_mapped(&self, source: usize) -> Option<usize> {
|
||||
if source >= self.source_start && source < self.source_start + self.length {
|
||||
Some(self.destination_start + source - self.source_start)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: AsRef<str>> From<T> for Range {
|
||||
fn from(value: T) -> Self {
|
||||
let value = value.as_ref();
|
||||
let mut values = value.trim().split(' ');
|
||||
let destination_start = values.next().unwrap().parse().unwrap();
|
||||
let source_start = values.next().unwrap().parse().unwrap();
|
||||
let length = values.next().unwrap().parse().unwrap();
|
||||
Self {
|
||||
destination_start,
|
||||
source_start,
|
||||
length,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ mod day03;
|
||||
pub use day03::*;
|
||||
mod day04;
|
||||
pub use day04::*;
|
||||
mod day05;
|
||||
pub use day05::*;
|
||||
|
||||
pub mod utils {
|
||||
#[macro_export]
|
||||
|
||||
@@ -4,7 +4,8 @@ fn main() {
|
||||
// Day01::run_all();
|
||||
// Day02::run_all();
|
||||
// Day03::run_all();
|
||||
Day04::run_all();
|
||||
// Day04::run_all();
|
||||
Day05::part1();
|
||||
|
||||
// utils::run!(01);
|
||||
// utils::run!(02);
|
||||
|
||||
Reference in New Issue
Block a user