Compare commits

..

1 Commits

Author SHA1 Message Date
Joey Pollack e64f83c681 Borked 2 years ago

@ -1,25 +0,0 @@
1972667147 405592018
1450194064 27782252
348350443 61862174
3911195009 181169206
626861593 138786487
2886966111 275299008
825403564 478003391
514585599 6102091
2526020300 15491453
3211013652 546191739
TO LOW:
6335758
New lowest location: 852082781 - from seed: 348350443 (VALID)
New lowest location: 624704155 - from seed: 368099087 (VALID)
New lowest location: 462405710 - from seed: 421798005 (INVALID!)
New lowest location: 123535056 - from seed: 1211303880 (VALID) -- INCORRECT
New lowest location: 122300259 - from seed: 1537339145 (INVALID!)
New lowest location: 102613526 - from seed: 2301593560 (VALID) -- ????
New lowest location: 44948412 - from seed: 2488220507 (INVALID!)
New lowest location: 6335758 - from seed: 2837209310 (INVALID!) -- INCORRECT

@ -1,26 +1,11 @@
use std::{io::prelude::*, fs::File, path::Path, collections::HashMap };
use std::{io::prelude::*, fs::File, path::Path, collections::HashMap, thread::current };
/////////////////////////////////////////////////////////////////////
// DATA STRUCTS
/////////////////////////////////////////////////////////////////////
#[derive(Clone, Debug)]
struct SeedRange
{
start: i64,
length: i64,
}
impl SeedRange
{
fn new(start: i64, length: i64) -> SeedRange
{
SeedRange { start, length }
}
}
#[derive(Clone, Debug)]
struct SubMap
{
@ -61,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)]
@ -68,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
@ -89,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 }
}
}
/////////////////////////////////////////////////////////////////////
@ -96,7 +123,7 @@ impl Map
/////////////////////////////////////////////////////////////////////
fn main()
{
let input = load_data("data/input");
let input = load_data("data/test_input");
let (seeds, maps, seed_ranges) = parse_input(&input);
// TEST STUFF
@ -108,68 +135,106 @@ 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 second_loc = find_closest_from_range(&seed_ranges, &maps);
println!("Closest location from range: {}", second_loc);
let l2 = find_closest_location_from_ranges(&seed_ranges, &maps);
println!("================= Closest location from ranges: {} =================", l2);
}
fn find_closest_from_range(seed_ranges: &Vec<SeedRange>, maps: &Vec<Map>) -> i64
fn find_closest_location_from_ranges(seed_ranges: &Vec<SeedRange>, maps: &Vec<Map>) -> i64
{
let mut closest_location = i64::MAX;
// let mut closest_location = i64::MAX;
// for seed_range in seed_ranges
// {
// println!("Checking seed range: start: {}, length: {}", seed_range.start, seed_range.length);
// let start = seed_range.start;
// let end = seed_range.start + seed_range.length + 1;
// for seed in start..end
// 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;
// println!("New lowest location: {}", closest_location);
// // best_seed = *seed;
// // let idx = maps.len() - 1;
// // if maps[idx].lowest_dest_value == closest_location
// // {
// // return closest_location;
// // }
// }
// }
// }
// OTHER THINGS TO TRY:
// Super brute force but reject any seeds that are not valid (using the is_seed_valid function).
// Maybe this will include some seeds that were left out before by mistake?
//
//
// closest_location
// SUPER BRUTE FORCE ALL SEED VALUES BETWEEN SMALLEST SEED AND LARGEST SEED (INCLUDES INVALID SEEDS!)
let smallest_seed: i64 = 348350443;
let largest_seed: i64 = 4092364215 + 1;
for seed in smallest_seed..largest_seed
for location in 0..52510811
{
let location = find_seed_location(seed, maps);
// println!("Current Location: {}", location);
if location >= 52510810
{
println!("FAILED: location value greater than known max!");
return -1;
}
if location < closest_location
// if location == 46
// {
// println!("LOCATOIN 46!");
// }
let seed = get_seed_from_location(location, maps, seed_ranges);
if seed > -1
{
closest_location = location;
let valid = match is_seed_valid(seed, seed_ranges)
{
true => "VALID",
false => "INVALID!"
};
println!("New lowest location: {} - from seed: {} ({})", closest_location, seed, valid);
return location;
}
}
closest_location
return -1;
}
fn is_seed_valid(value: i64, seed_ranges: &Vec<SeedRange>) -> bool
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
{
@ -187,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
@ -237,22 +302,21 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>, Vec<SeedRange>) // String is
// SEEDS
if line.contains("seeds:")
{
println!("Parsing seed input...");
let mut start_value: i64 = -1;
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_value == -1
if start_seed == -1
{
start_value = num;
}
else
{
seed_ranges.push(SeedRange::new(start_value, num));
start_value = -1;
start_seed = num;
continue;
}
seed_ranges.push(SeedRange::new(start_seed, num));
start_seed = -1;
}
continue;
@ -262,6 +326,12 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>, Vec<SeedRange>) // String is
// 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);
@ -285,8 +355,15 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>, Vec<SeedRange>) // String is
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)
@ -299,6 +376,9 @@ fn parse_input(input: &str) -> (Vec<i64>, Vec<Map>, Vec<SeedRange>) // String is
// }
}
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)
}

1
day_6/.gitignore vendored

@ -1 +0,0 @@
/target

@ -1,45 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'day_1'",
"cargo": {
"args": [
"build",
"--bin=day_1",
"--package=day_1"
],
"filter": {
"name": "day_1",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
},
{
"type": "lldb",
"request": "launch",
"name": "Debug unit tests in executable 'day_1'",
"cargo": {
"args": [
"test",
"--no-run",
"--bin=day_1",
"--package=day_1"
],
"filter": {
"name": "day_1",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

7
day_6/Cargo.lock generated

@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day_6"
version = "0.1.0"

@ -1,8 +0,0 @@
[package]
name = "day_6"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

@ -1,31 +0,0 @@
use std::{env, fs, path::Path};
fn main()
{
// let out_dir = env::var("OUT_DIR").unwrap();
// let cwd = env::var("CARGO_MANIFEST_DIR").unwrap();
// println!("CWD: {}\n", cwd);
// let data_dir = cwd + "\\data";
// let data_path = Path::new(&data_dir);
// println!("Data path: {}", data_path.to_string_lossy());
// let data_path = Path::new("data/test_input");
let out_path = format!("target/{}", &env::var("PROFILE").unwrap());
let out_path = Path::new(&out_path);
//let out_path = Path::new(&out_dir).join(&env::var("PROFILE").unwrap());
let out_path_data = out_path.join(Path::new("data"));
if !out_path_data.exists()
{
fs::create_dir(&out_path_data).expect(&format!("Could not create data directory at: {}", out_path_data.to_string_lossy()));
}
for file in fs::read_dir("data").unwrap()
{
let file = file.unwrap();
let dest = out_path.join(file.path());
fs::copy(file.path(), &dest).expect(&format!("Could not copy file {} to {}", file.path().to_string_lossy(), dest.to_string_lossy()));
}
}

@ -1,2 +0,0 @@
Time: 47 84 74 67
Distance: 207 1394 1209 1014

@ -1,2 +0,0 @@
Time: 7 15 30
Distance: 9 40 200

@ -1,68 +0,0 @@
use std::{io::prelude::*, fs::File, path::Path, io };
#[derive(Clone, Debug)]
struct Race
{
time: i32,
record_dist: i32,
}
fn main()
{
let input = load_data("data/test_input");
let races = parse_input(&input);
}
/////////////////////////////////////////////////////////////////////
// LOAD AND PARSE INPUT
/////////////////////////////////////////////////////////////////////
fn parse_input(input: &str) -> Vec<Race>
{
let mut times: Vec<i32> = Vec::new();
let mut record_dists: Vec<i32> = Vec::new();
Vec::new()
}
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 normalize_line_endings(&file_contents);
}
fn normalize_line_endings(data: &str) -> String
{
let mut data: Vec<u8> = data.as_bytes().into();
let mut idx = 0;
while idx < data.len()
{
if data[idx as usize] == b'\r'
{
data.remove(idx as usize);
idx -= 1;
}
idx += 1;
}
String::from_utf8(data).expect("normalize_line_endings - FAILED: string was not valid utf_8")
}
Loading…
Cancel
Save