day_5_part_2_broken
Joey Pollack 2 years ago
parent abd869ff05
commit e64f83c681

@ -1,5 +1,5 @@
use std::{io::prelude::*, fs::File, path::Path, collections::HashMap };
use std::{io::prelude::*, fs::File, path::Path, collections::HashMap, thread::current };
/////////////////////////////////////////////////////////////////////
@ -46,6 +46,18 @@ impl SubMap
return self.destination_start + distance;
}
fn map_reverse(&self, val: i64) -> i64
{
if val >= self.destination_start && val <= self.destination_start + self.length
{
let distance = val - self.destination_start;
return self.source_start + distance;
}
return -1;
}
}
#[derive(Clone, Debug)]
@ -53,13 +65,14 @@ struct Map
{
name: String,
sub_maps: Vec<SubMap>,
lowest_dest_value: i64,
}
impl Map
{
fn new(name: &str) -> Map
{
Map { name: name.to_string(), sub_maps: Vec::new() }
Map { name: name.to_string(), sub_maps: Vec::new(), lowest_dest_value: i64::MAX }
}
fn map_input(&self, input: i64) -> i64
@ -74,6 +87,35 @@ impl Map
return input;
}
fn map_reverse(&self, input: i64) -> i64
{
for sub_map in &self.sub_maps
{
let source = sub_map.map_reverse(input);
if source > -1
{
return source;
}
}
return input;
}
}
struct SeedRange
{
start: i64,
length: i64,
}
impl SeedRange
{
fn new(start: i64, length: i64) -> SeedRange
{
SeedRange { start, length }
}
}
/////////////////////////////////////////////////////////////////////
@ -81,8 +123,8 @@ impl Map
/////////////////////////////////////////////////////////////////////
fn main()
{
let input = load_data("data/input");
let (seeds, maps) = parse_input(&input);
let input = load_data("data/test_input");
let (seeds, maps, seed_ranges) = parse_input(&input);
// TEST STUFF
// println!("SEEDS: {:#?}, MAPS: {:#?}", seeds, maps);
@ -93,10 +135,116 @@ fn main()
// println!("=========TESTS:\n\tseed-to-soil {} maps to {}\n\n\tseed-to-soil {} maps to {}\n\n\tseed-to-soil {} maps to {}\n",
// 99, test_1, 53, test_2, 47, test_3);
//
// let location_map_idx = maps.len() -1;
// for (idx, sub_map) in maps[location_map_idx].sub_maps.iter().enumerate()
// {
// println!("map index: {} -- Location dest_start: {}", idx, sub_map.destination_start);
// }
let location = find_closest_location(&seeds, &maps);
println!("Closest location: {}", location);
println!("================= Closest location: {} =================", location);
let l2 = find_closest_location_from_ranges(&seed_ranges, &maps);
println!("================= Closest location from ranges: {} =================", l2);
}
fn find_closest_location_from_ranges(seed_ranges: &Vec<SeedRange>, maps: &Vec<Map>) -> i64
{
// let mut closest_location = i64::MAX;
// for seed_range in seed_ranges
// {
// println!("Checking next seed range (start {}, {} length)...", seed_range.start, seed_range.length);
// for seed in seed_range.start..seed_range.start + seed_range.length + 1
// {
// let location = find_seed_location(seed, maps);
// if location < closest_location
// {
// closest_location = location;
// // best_seed = *seed;
// // let idx = maps.len() - 1;
// // if maps[idx].lowest_dest_value == closest_location
// // {
// // return closest_location;
// // }
// }
// }
// }
// closest_location
for location in 0..52510811
{
// println!("Current Location: {}", location);
if location >= 52510810
{
println!("FAILED: location value greater than known max!");
return -1;
}
// if location == 46
// {
// println!("LOCATOIN 46!");
// }
let seed = get_seed_from_location(location, maps, seed_ranges);
if seed > -1
{
return location;
}
}
return -1;
}
fn get_seed_from_location(location: i64, maps: &Vec<Map>, seed_ranges: &Vec<SeedRange>) -> i64
{
// let mut skip_first = true;
let mut current_type_value = location;
for map in maps.iter().rev()
{
// Don't actually want to skip because we need to map
// the location dest to it's source
// if skip_first
// {
// skip_first = false;
// continue;
// }
current_type_value = map.map_reverse(current_type_value);
if current_type_value < 0
{
return -1;
}
}
if is_valid_seed(current_type_value, seed_ranges)
{
return current_type_value;
}
return -1;
}
fn is_valid_seed(value: i64, seed_ranges: &Vec<SeedRange>) -> bool
{
for range in seed_ranges
{
if value >= range.start && value <= range.start + range.length
{
return true;
}
}
false
}
fn find_closest_location(seeds: &Vec<i64>, maps: &Vec<Map>) -> i64
@ -104,9 +252,9 @@ fn find_closest_location(seeds: &Vec<i64>, maps: &Vec<Map>) -> i64
// let mut best_seed = 0;
let mut closest_location = i64::MAX;
for seed in seeds
for (idx, seed) in seeds.iter().enumerate()
{
println!("Checking seed: {}", seed);
println!("Checking seed: {} ({} of {})", seed, idx + 1, seeds.len());
let location = find_seed_location(*seed, maps);
if location < closest_location
@ -125,7 +273,7 @@ fn find_seed_location(seed: i64, maps: &Vec<Map>) -> i64
let mut current_value = seed;
for map in maps
{
println!("Mapping {}...", map.name);
// println!("Mapping {}...", map.name);
current_value = map.map_input(current_value);
}
@ -135,9 +283,10 @@ fn find_seed_location(seed: i64, maps: &Vec<Map>) -> i64
/////////////////////////////////////////////////////////////////////
// INPUT PARSING
/////////////////////////////////////////////////////////////////////
fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>, Vec<SeedRange>) // String is the map name
{
let mut seeds: Vec<i64> = Vec::new();
let mut seed_ranges: Vec<SeedRange> = Vec::new();
let mut maps: Vec<Map> = Vec::new();
let mut current_map = "";
@ -154,10 +303,20 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
if line.contains("seeds:")
{
println!("Parseing seed input...");
let mut start_seed: i64 = -1;
for val in line.trim_start_matches("seeds:").trim().split(" ")
{
let num = val.parse::<i64>().expect(&format!("Failed to parse seed value: {}", val));
seeds.push(num);
if start_seed == -1
{
start_seed = num;
continue;
}
seed_ranges.push(SeedRange::new(start_seed, num));
start_seed = -1;
}
continue;
@ -167,6 +326,12 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
// NEW MAP
if line.contains("map:")
{
if maps.len() > 0
{
let idx = maps.len() - 1;
maps[idx].sub_maps.sort_by(|a, b| a.destination_start.partial_cmp(&b.destination_start).unwrap());
}
sub_map_idx = 0;
current_map = line.trim().trim_end_matches("map:").trim();
println!("Parsing map: {}", current_map);
@ -179,7 +344,7 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
// NEW SUB MAP
let mut sub_map = SubMap::new();
let vals: Vec<&str> = line.trim().split(" ").collect();
println!("Parsing sub map: {}", sub_map_idx);
// println!("Parsing sub map: {}", sub_map_idx);
if vals.len() < 3
{
@ -190,8 +355,15 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
sub_map.destination_start = vals[0].parse::<i64>().expect(&format!("Failed to parse dest value: {}", vals[0]));
sub_map.source_start = vals[1].parse::<i64>().expect(&format!("Failed to parse source value: {}", vals[1]));
sub_map.length = vals[2].parse::<i64>().expect(&format!("Failed to parse length value: {}", vals[2]));
//sub_map.map_values();
let idx = maps.len() - 1;
if sub_map.destination_start < maps[idx].lowest_dest_value
{
maps[idx].lowest_dest_value = sub_map.destination_start;
}
maps[idx].sub_maps.push(sub_map.clone());
sub_map_idx += 1;
// if let Some(map) = maps.get_mut(current_map)
@ -204,7 +376,10 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>) // String is the map name
// }
}
(seeds, maps)
let idx = maps.len() - 1;
maps[idx].sub_maps.sort_by(|a, b| a.destination_start.partial_cmp(&b.destination_start).unwrap());
(seeds, maps, seed_ranges)
}

Loading…
Cancel
Save