You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Advent_of_Code/day_5/src/main.rs

148 lines
3.6 KiB
Rust

2 years ago
use std::{io::prelude::*, fs::File, path::Path, io, collections::HashMap };
#[derive(Clone, Debug)]
struct SubMap
{
destination_start: i32,
source_start: i32,
length: i32,
map: HashMap<i32, i32>
}
impl SubMap
{
fn new() -> SubMap
{
SubMap { destination_start: 0, source_start: 0, length: 0, map: HashMap::new() }
}
fn map_values(&mut self)
{
for i in 0..self.length
{
self.map.insert(self.source_start + i, self.destination_start + i);
}
}
}
#[derive(Clone, Debug)]
struct Map
{
name: String,
sub_maps: Vec<SubMap>,
}
impl Map
{
fn new(name: &str) -> Map
{
Map { name: name.to_string(), sub_maps: Vec::new() }
}
fn map_input(&self, input: i32) -> i32
{
for sub_map in &self.sub_maps
{
if sub_map.map.contains_key(&input)
{
return sub_map.map[&input];
}
}
return input;
}
}
2 years ago
fn main()
{
let input = load_data("data/test_input");
let (seeds, maps) = parse_input(&input);
println!("SEEDS: {:#?}, MAPS: {:#?}", seeds, maps);
}
fn parse_input(input: &str) -> (Vec<i32>, HashMap<String, Map>) // String is the map name
{
let mut seeds: Vec<i32> = Vec::new();
let mut maps: HashMap<String, Map> = HashMap::new();
let mut current_map = "";
for (idx, line) in input.to_ascii_lowercase().split("\n").into_iter().enumerate()
{
// stupid windows dumb line ending non-sense
if line.starts_with("\r")
{
continue;
}
// SEEDS
if line.contains("seeds:")
{
for val in line.trim_start_matches("seeds:").trim().split(" ")
{
let num = val.parse::<i32>().expect(&format!("Failed to parse seed value: {}", val));
seeds.push(num);
}
continue;
}
// NEW MAP
if line.contains("map:")
{
let name = line.trim_end_matches("map:");
current_map = name.clone();
let map = Map::new(&current_map);
maps.insert(current_map.to_string(), map.clone());
continue;
}
// NEW SUB MAP
let mut sub_map = SubMap::new();
let vals: Vec<&str> = line.trim().split(" ").collect();
if vals.len() < 3
{
println!("========INVALID SUBMAP FOR {}: {:#?}========", current_map, vals);
continue;
}
sub_map.destination_start = vals[0].parse::<i32>().expect(&format!("Failed to parse dest value: {}", vals[0]));
sub_map.source_start = vals[1].parse::<i32>().expect(&format!("Failed to parse source value: {}", vals[1]));
sub_map.length = vals[2].parse::<i32>().expect(&format!("Failed to parse length value: {}", vals[2]));
sub_map.map_values();
if let Some(map) = maps.get_mut(current_map)
{
map.sub_maps.push(sub_map.clone());
}
else
{
println!("========CURRENT MAP NOT FOUND IN MAP: {}========", current_map);
}
}
2 years ago
(seeds, maps)
2 years ago
}
fn load_data(file_name: &str) -> String
{
let mut file = match File::open(Path::new(file_name))
{
Ok(file) => file,
Err(why) => panic!("Could not open file {}: {}", Path::new(file_name).display(), why),
};
let mut s = String::new();
let file_contents = match file.read_to_string(&mut s)
{
Err(why) => panic!("couldn't read {}: {}", Path::new(file_name).display(), why),
Ok(_) => s,
};
return file_contents;
}