day5: wip optimize
This commit is contained in:
parent
75841ecc80
commit
b478bfaf9d
|
@ -7,24 +7,22 @@ extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
||||||
|
|
||||||
fn process(data: &str) -> u64 {
|
fn process(data: &str) -> i64 {
|
||||||
let mut lines = data.split("\n\n");
|
let mut lines = data.split("\n\n");
|
||||||
|
|
||||||
let seeds: Vec<u64> = lines
|
let seeds = lines
|
||||||
.next()
|
.next()
|
||||||
.map(|x| x.split(' ').skip(1).map(|y| y.parse::<u64>().unwrap()))
|
.map(|x| x.split(' ').skip(1).map(|y| y.parse::<i64>().unwrap()))
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.collect();
|
let maps: Vec<Vec<(Range<i64>, Range<i64>)>> = lines
|
||||||
|
|
||||||
let maps: Vec<Vec<(Range<u64>, Range<u64>)>> = lines
|
|
||||||
.map(|lines| {
|
.map(|lines| {
|
||||||
lines
|
lines
|
||||||
.lines()
|
.lines()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
let y: Vec<u64> = line
|
let y: Vec<i64> = line
|
||||||
.split_ascii_whitespace()
|
.split_ascii_whitespace()
|
||||||
.map(|y| y.parse::<u64>().unwrap())
|
.map(|y| y.parse::<i64>().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
let size = y[2];
|
let size = y[2];
|
||||||
|
|
||||||
|
@ -34,7 +32,7 @@ fn process(data: &str) -> u64 {
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut answer = std::u64::MAX;
|
let mut answer = std::i64::MAX;
|
||||||
|
|
||||||
for mut src in seeds {
|
for mut src in seeds {
|
||||||
for map in maps.iter() {
|
for map in maps.iter() {
|
||||||
|
|
100
src/day5/2.rs
100
src/day5/2.rs
|
@ -1,4 +1,4 @@
|
||||||
#![feature(slice_split_once)]
|
#![feature(iter_array_chunks)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
@ -7,59 +7,111 @@ extern crate test;
|
||||||
|
|
||||||
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
const INPUTS: [&str; 2] = [include_str!("./sample.txt"), include_str!("./input.txt")];
|
||||||
|
|
||||||
fn process(data: &str) -> u64 {
|
fn process(data: &str) -> i64 {
|
||||||
let mut lines = data.split("\n\n");
|
let mut lines = data.split("\n\n");
|
||||||
|
|
||||||
let seeds: Vec<u64> = lines
|
let mut seeds: Vec<Range<i64>> = lines
|
||||||
.next()
|
.next()
|
||||||
.map(|x| {
|
.map(|x| {
|
||||||
let v: Vec<u64> = x
|
let v: Vec<i64> = x
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|y| y.parse::<u64>().unwrap())
|
.map(|y| y.parse::<i64>().unwrap())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
v.chunks(2)
|
v.chunks(2)
|
||||||
.flat_map(|x| (x[0]..x[0] + x[1]).collect::<Vec<u64>>())
|
.map(|x| (x[0]..x[0] + x[1]))
|
||||||
.collect::<Vec<u64>>()
|
.collect::<Vec<Range<i64>>>()
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let maps: Vec<Vec<(Range<u64>, Range<u64>)>> = lines
|
let maps: Vec<Vec<(Range<i64>, Range<i64>)>> = lines
|
||||||
.map(|lines| {
|
.map(|lines| {
|
||||||
lines
|
lines
|
||||||
.lines()
|
.lines()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
let y: Vec<u64> = line
|
line.split_ascii_whitespace()
|
||||||
.split_ascii_whitespace()
|
.map(|y| y.parse::<i64>().unwrap())
|
||||||
.map(|y| y.parse::<u64>().unwrap())
|
.array_chunks::<2>()
|
||||||
.collect();
|
.map(|y| {
|
||||||
let size = y[2];
|
let size = y[2];
|
||||||
|
|
||||||
(y[1]..y[1] + size, y[0]..y[0] + size)
|
(y[1]..y[1] + size, y[0]..y[0] + size)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
for map in maps {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
let mut answer = std::u64::MAX;
|
for seed in seeds.drain(..) {
|
||||||
|
// split seed based on this rangemap
|
||||||
|
let splitted = split(&map, seed);
|
||||||
|
|
||||||
for mut src in seeds {
|
out.extend(splitted);
|
||||||
for map in maps.iter() {
|
|
||||||
let dst = map
|
|
||||||
.iter()
|
|
||||||
.find(|x| x.0.contains(&src))
|
|
||||||
.map(|x| src + x.1.start - x.0.start)
|
|
||||||
.unwrap_or(src);
|
|
||||||
|
|
||||||
src = dst;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
answer = std::cmp::min(answer, src);
|
seeds.extend_from_slice(&out);
|
||||||
}
|
}
|
||||||
|
|
||||||
answer
|
seeds.into_iter().map(|x| x.start).min().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split(map: &[(Range<i64>, Range<i64>)], node: Range<i64>) -> Vec<Range<i64>> {
|
||||||
|
let mut out = vec![];
|
||||||
|
|
||||||
|
let mut stack = vec![node];
|
||||||
|
|
||||||
|
while let Some(node) = stack.pop() {
|
||||||
|
let mut found_match = false;
|
||||||
|
|
||||||
|
for (src, dst) in map.iter() {
|
||||||
|
let overlap = std::cmp::max(0, node.end.min(src.end) - node.start.max(src.start));
|
||||||
|
|
||||||
|
if overlap == 0 {
|
||||||
|
continue;
|
||||||
|
} else if node.start > src.start && node.end < src.end {
|
||||||
|
let offset = std::cmp::max(0, node.start - src.start);
|
||||||
|
let dst = dst.start + offset..dst.start + offset + overlap;
|
||||||
|
found_match = true;
|
||||||
|
out.push(dst);
|
||||||
|
} else if node.start < src.start && node.end > src.end {
|
||||||
|
let r1_non = node.start..src.start;
|
||||||
|
let r2_non = src.end..node.end;
|
||||||
|
|
||||||
|
found_match = true;
|
||||||
|
|
||||||
|
out.push(dst.clone());
|
||||||
|
stack.push(r1_non);
|
||||||
|
stack.push(r2_non);
|
||||||
|
} else {
|
||||||
|
// Partial overlap
|
||||||
|
|
||||||
|
let offset = std::cmp::max(0, node.start - src.start);
|
||||||
|
|
||||||
|
let dst_range = dst.start + offset..dst.start + offset + overlap;
|
||||||
|
|
||||||
|
found_match = true;
|
||||||
|
let new_range = if node.start < src.start {
|
||||||
|
node.start..src.start
|
||||||
|
} else {
|
||||||
|
src.end..node.end
|
||||||
|
};
|
||||||
|
|
||||||
|
stack.push(new_range);
|
||||||
|
out.push(dst_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found_match {
|
||||||
|
out.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user