Refactor for stage 2

This commit is contained in:
Maxime Augier 2023-12-07 12:04:01 +01:00
parent 27a3ce98bc
commit 18ee41a59a
2 changed files with 7 additions and 85 deletions

View File

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, io::stdin, ops::Mul};
use std::{collections::BTreeMap, io::stdin, ops::{Mul, Range}};
use anyhow::{Result, bail};
mod parse;
@ -8,87 +8,17 @@ mod parse;
struct Map {
from: String,
to: String,
ranges: BTreeMap<usize, usize>
ranges: Vec<(Range<usize>, Range<usize>)>,
}
impl Map {
fn identity() -> Self {
let ranges = BTreeMap::from_iter(
Some((0,0)).into_iter()
);
Map {
from: "-".to_owned(),
to: "seed".to_owned(),
ranges,
}
}
fn follow(&self, src: usize) -> usize {
self.ranges
.range(..src+1)
.last().map(|(s,d)| src-s+d)
.unwrap_or(src)
fn lookup(&self, src: usize) -> usize {
todo!()
}
}
impl Mul<&Map> for &Map {
type Output = Option<Map>;
fn mul(self, rhs: &Map) -> Self::Output {
let mut cur = self.ranges.iter();
let mut next = self.ranges.keys();
next.next();
let mut result = BTreeMap::new();
while let Some((&base, &tgt)) = cur.next() {
let len = next.next().map(|n| n - base);
let tgt_range = match len {
Some(len) => rhs.ranges.range(tgt..tgt+len),
None => rhs.ranges.range(tgt..)
};
for (&rbase, &rtgt) in tgt_range {
}
}
Some(Map { ranges: result, from: self.from.to_owned(), to: rhs.to.to_owned() })
}
}
fn main() -> Result<()> {
let stdin = stdin().lock();
let (seeds, maps) = parse::input(stdin)?;
println!("{maps:?}");
let mut step = "seed";
for map in &maps {
if &map.from != step {
bail!("incorrect map order, got {map:?}, expected {step}");
}
step = &map.to;
}
let mut best = None;
for &seed in &seeds {
let mut x = seed;
for map in &maps {
x = map.follow(x);
}
if best.map(|old| old > x).unwrap_or(true) {
best = Some(x)
}
}
println!("Best: {best:?}");
Ok(())
}

View File

@ -28,21 +28,13 @@ fn map<R: BufRead>(s: &mut Lines<R>) -> Option<Result<Map>> {
.split_once("-to-")
.ok_or(anyhow!("bad map name"))?;
let mut ranges = BTreeMap::new();
let mut ranges = vec![];
loop {
let line = s.next().ok_or(anyhow!("Unterminated map"))??;
if line.is_empty() { break }
let (dst, src, len) = range(&line)?;
let mut collisions = ranges.range(src..src+len);
if let Some(old) = collisions.next() {
if old.0 != old.1 || collisions.next().is_some() {
Err(anyhow!("range collision {src}-{len} vs {old:?}"))?;
}
}
ranges.insert(src, dst);
ranges.entry(src+len).or_insert(src+len);
ranges.push((src..src+len, dst..dst+len));
}
Ok(Map { from: from.to_owned(), to: to.to_owned(), ranges })