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};
|
use anyhow::{Result, bail};
|
||||||
|
|
||||||
mod parse;
|
mod parse;
|
||||||
@ -8,87 +8,17 @@ mod parse;
|
|||||||
struct Map {
|
struct Map {
|
||||||
from: String,
|
from: String,
|
||||||
to: String,
|
to: String,
|
||||||
ranges: BTreeMap<usize, usize>
|
ranges: Vec<(Range<usize>, Range<usize>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Map {
|
impl Map {
|
||||||
|
|
||||||
fn identity() -> Self {
|
fn lookup(&self, src: usize) -> usize {
|
||||||
let ranges = BTreeMap::from_iter(
|
todo!()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<()> {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -28,21 +28,13 @@ fn map<R: BufRead>(s: &mut Lines<R>) -> Option<Result<Map>> {
|
|||||||
.split_once("-to-")
|
.split_once("-to-")
|
||||||
.ok_or(anyhow!("bad map name"))?;
|
.ok_or(anyhow!("bad map name"))?;
|
||||||
|
|
||||||
let mut ranges = BTreeMap::new();
|
let mut ranges = vec![];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let line = s.next().ok_or(anyhow!("Unterminated map"))??;
|
let line = s.next().ok_or(anyhow!("Unterminated map"))??;
|
||||||
if line.is_empty() { break }
|
if line.is_empty() { break }
|
||||||
let (dst, src, len) = range(&line)?;
|
let (dst, src, len) = range(&line)?;
|
||||||
|
|
||||||
let mut collisions = ranges.range(src..src+len);
|
ranges.push((src..src+len, dst..dst+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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Map { from: from.to_owned(), to: to.to_owned(), ranges })
|
Ok(Map { from: from.to_owned(), to: to.to_owned(), ranges })
|
||||||
|
Loading…
Reference in New Issue
Block a user