Pause to go touch grass
This commit is contained in:
parent
99b0fd06be
commit
397a95f2dc
156
2023/rust/src/day5.rs
Normal file
156
2023/rust/src/day5.rs
Normal file
|
@ -0,0 +1,156 @@
|
|||
mod prelude;
|
||||
use std::collections::HashMap;
|
||||
extern crate nom;
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::{tag, take_while},
|
||||
character::complete::{line_ending, newline, space1},
|
||||
combinator::{map_res, value},
|
||||
multi::separated_list0,
|
||||
sequence::tuple,
|
||||
IResult,
|
||||
};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
fn main() {
|
||||
Day5::show(day_input(5), day_input(5))
|
||||
}
|
||||
|
||||
#[derive(Hash, Debug, PartialEq, Eq, Clone)]
|
||||
enum Layer {
|
||||
Seed,
|
||||
Soil,
|
||||
Fertilizer,
|
||||
Water,
|
||||
Light,
|
||||
Temperature,
|
||||
Humidity,
|
||||
Location,
|
||||
}
|
||||
|
||||
#[derive(Hash, Eq, Debug, PartialEq, Clone)]
|
||||
struct LayerDir {
|
||||
from: Layer,
|
||||
to: Layer,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Mapping {
|
||||
from_start: usize,
|
||||
to_start: usize,
|
||||
length: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Almanac {
|
||||
seeds: Vec<usize>,
|
||||
mappings: HashMap<LayerDir, Vec<Mapping>>,
|
||||
}
|
||||
|
||||
fn layer(input: &str) -> IResult<&str, Layer> {
|
||||
alt((
|
||||
value(Layer::Seed, tag("seed")),
|
||||
value(Layer::Soil, tag("soil")),
|
||||
value(Layer::Fertilizer, tag("fertilizer")),
|
||||
value(Layer::Water, tag("water")),
|
||||
value(Layer::Light, tag("light")),
|
||||
value(Layer::Temperature, tag("temperature")),
|
||||
value(Layer::Humidity, tag("humidity")),
|
||||
value(Layer::Location, tag("location")),
|
||||
))(input)
|
||||
}
|
||||
|
||||
fn int(input: &str) -> IResult<&str, usize> {
|
||||
map_res(take_while(char::is_numeric), str::parse)(input)
|
||||
}
|
||||
|
||||
fn mapping(input: &str) -> IResult<&str, Mapping> {
|
||||
println!("mapping input: {input:?}");
|
||||
let (input, nums) = separated_list0(space1, int)(input)?;
|
||||
println!("nums: {nums:?}");
|
||||
Ok((
|
||||
input,
|
||||
Mapping {
|
||||
from_start: nums[0],
|
||||
to_start: nums[1],
|
||||
length: nums[2],
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn mapping_entry(input: &str) -> IResult<&str, (LayerDir, Vec<Mapping>)> {
|
||||
// TODO: this is probably confusing my parser since the newline separator would need to lookahead?
|
||||
let (input, (from, _, to, _)) = tuple((layer, tag("-to-"), layer, tag(" map:\n")))(input)?;
|
||||
// take while here
|
||||
let (input, mappings) = separated_list0(newline, mapping)(input)?;
|
||||
Ok((input, (LayerDir { from, to }, mappings)))
|
||||
}
|
||||
|
||||
fn almanac(input: &str) -> IResult<&str, Almanac> {
|
||||
let (input, seeds) = separated_list0(space1, int)(tag("seeds: ")(input)?.0)?;
|
||||
let (input, mapping_tuples) =
|
||||
separated_list0(tuple((line_ending, line_ending)), mapping_entry)(tag("\n\n")(input)?.0)?;
|
||||
let mappings: HashMap<LayerDir, Vec<Mapping>> = mapping_tuples.into_iter().collect();
|
||||
Ok((input, Almanac { seeds, mappings }))
|
||||
}
|
||||
|
||||
struct Day5 {}
|
||||
impl AoCSolution for Day5 {
|
||||
type Input = String;
|
||||
type Solution = usize;
|
||||
|
||||
fn part1(input: Self::Input) -> Self::Solution {
|
||||
let almanac = almanac(&input);
|
||||
println!("{almanac:?}");
|
||||
0
|
||||
}
|
||||
|
||||
fn part2(input: Self::Input) -> Self::Solution {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let 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"#;
|
||||
assert_eq!(Day5::part1(input.into()), 35);
|
||||
assert_eq!(Day5::part2(input.into()), 0);
|
||||
}
|
||||
}
|
32
2023/rust/src/template.rs
Normal file
32
2023/rust/src/template.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
mod prelude;
|
||||
use crate::prelude::*;
|
||||
|
||||
fn main() {
|
||||
Day5::show(day_input(5), day_input(5))
|
||||
}
|
||||
|
||||
struct Day5 {}
|
||||
impl AoCSolution for Day5 {
|
||||
type Input = String;
|
||||
type Solution = usize;
|
||||
|
||||
fn part1(input: Self::Input) -> Self::Solution {
|
||||
0
|
||||
}
|
||||
|
||||
fn part2(input: Self::Input) -> Self::Solution {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let input = r#""#;
|
||||
assert_eq!(Day2::part1(input.into()), 1);
|
||||
assert_eq!(Day2::part2(input.into()), 0);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue