Refactor for stage 2
This commit is contained in:
parent
27a3ce98bc
commit
18ee41a59a
@ -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(())
|
||||
}
|
||||
|
@ -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 })
|
||||
|
Loading…
Reference in New Issue
Block a user