2023-advent-of-code/src/05part2.rs

163 lines
5.4 KiB
Rust

use std::fs;
fn main() {
let file_path = "input/05input.txt";
let contents = fs::read_to_string(file_path).expect("should read file");
let mut lines = contents.lines();
let seeds_str = lines.next().unwrap().strip_prefix("seeds: ").unwrap();
let mut seeds: Vec<i128> = seeds_str.split(" ").map(|x| {x.parse::<i128>().ok().unwrap()}).collect();
let mut soil = Vec::new();
lines.next();
lines.next();
seeds = sort_by_pair(seeds);
loop {
let line = lines.next().unwrap();
if line == "" {
soil.append(&mut seeds);
break;
}
process_line(line, &mut seeds, &mut soil);
}
soil = sort_by_pair(soil);
let mut fertilizer = Vec::new();
lines.next();
loop {
let line = lines.next().unwrap();
if line == "" {
fertilizer.append(&mut soil);
break;
}
process_line(line, &mut soil, &mut fertilizer);
}
fertilizer = sort_by_pair(fertilizer);
let mut water = Vec::new();
lines.next();
loop {
let line = lines.next().unwrap();
if line == "" {
water.append(&mut fertilizer);
break;
}
process_line(line, &mut fertilizer, &mut water);
}
water = sort_by_pair(water);
let mut light = Vec::new();
lines.next();
loop {
let line = lines.next().unwrap();
if line == "" {
light.append(&mut water);
break;
}
process_line(line, &mut water, &mut light);
}
light = sort_by_pair(light);
let mut temperature = Vec::new();
lines.next();
loop {
let line = lines.next().unwrap();
if line == "" {
temperature.append(&mut light);
break;
}
process_line(line, &mut light, &mut temperature);
}
temperature = sort_by_pair(temperature);
let mut humidity = Vec::new();
lines.next();
loop {
let line = lines.next().unwrap();
if line == "" {
humidity.append(&mut temperature);
break;
}
process_line(line, &mut temperature, &mut humidity);
}
humidity = sort_by_pair(humidity);
let mut location = Vec::new();
lines.next();
loop {
match lines.next() {
Some(line) => {
process_line(line, &mut humidity, &mut location);
},
None => {
location.append(&mut humidity);
break;
}
}
}
location = sort_by_pair(location);
println!("{:?}", location.first().unwrap());
}
fn range_from_line(line: &str) -> (i128, i128, i128) {
let mut nums = line.split_whitespace();
let dest = nums.next().unwrap().parse::<i128>().ok().unwrap();
let source = nums.next().unwrap().parse::<i128>().ok().unwrap();
let count = nums.next().unwrap().parse::<i128>().ok().unwrap();
return (source, dest, count);
}
fn process_line(line: &str, input_vec: &mut Vec<i128>, out_vec: &mut Vec<i128>) {
let values = range_from_line(line);
let input_clone = input_vec.clone();
let mut index = 0;
for n in 0..input_clone.len()/2 {
if input_clone[n*2] < values.0 + values.2 && input_clone[n*2] >= values.0 {
out_vec.push(input_clone[n*2] - values.0 + values.1);
if input_clone[n*2+1] <= values.2 - (input_clone[n*2] - values.0) {
out_vec.push(input_clone[n*2+1]);
input_vec.remove(index);
input_vec.remove(index);
} else {
out_vec.push(values.2 - 1);
input_vec.push(values.0 + values.2);
input_vec.push(input_clone[n*2+1] - values.2 + 1);
input_vec.remove(index);
input_vec.remove(index);
}
} else if input_clone[n*2] < values.0 && input_clone[n*2] + input_clone[n*2+1] >= values.0 {
out_vec.push(values.1);
if input_clone[n*2] + input_clone[n*2+1] > values.0 + values.2 {
out_vec.push(values.2 - 1);
input_vec.push(input_clone[n*2]);
input_vec.push(values.0 - input_clone[n*2]);
input_vec.push(values.0 + values.2);
input_vec.push(input_clone[n*2] + input_clone[n*2+1] - values.0 - values.2);
input_vec.remove(index);
input_vec.remove(index);
} else {
out_vec.push(input_clone[n*2] - values.0 + input_clone[n*2+1] - 1);
input_vec.push(input_clone[n*2]);
input_vec.push(values.0 - input_clone[n*2]);
input_vec.remove(index);
input_vec.remove(index);
}
} else if input_clone[n*2] + input_clone[n*2+1] < values.0 {
index += 2;
} else {
break;
}
}
}
fn sort_by_pair(input_vec: Vec<i128>) -> Vec<i128> {
let mut sort_vec = Vec::new();
let mut out_vec = Vec::new();
for i in 0..input_vec.len()/2 {
if input_vec[i*2+1] == 0 {
continue;
}
let insert_index: usize;
match sort_vec.binary_search(&input_vec[i*2]) {
Ok(val) => insert_index = val,
Err(val) => insert_index = val,
}
sort_vec.insert(insert_index, input_vec[i*2]);
out_vec.insert(insert_index * 2, input_vec[i*2]);
out_vec.insert(insert_index*2+1, input_vec[i*2+1]);
}
return out_vec;
}