diff options
author | Justin Wernick <justin@worthe-it.co.za> | 2020-12-09 15:49:37 +0200 |
---|---|---|
committer | Justin Wernick <justin@worthe-it.co.za> | 2020-12-09 15:49:37 +0200 |
commit | 6efb8d0afb70e3fbd06dca5ec4e2bd8283b617a0 (patch) | |
tree | ae4431254679c28bb827e56782b19701f0811b42 /src | |
parent | 60f0fce822527372135ead5ca2a4843ee9b8d31c (diff) |
Day 9
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/day_9.rs | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/bin/day_9.rs b/src/bin/day_9.rs new file mode 100644 index 0000000..b5a02e6 --- /dev/null +++ b/src/bin/day_9.rs @@ -0,0 +1,120 @@ +use bevy::{app::AppExit, prelude::*}; +use std::fs::File; +use std::io::{BufRead, BufReader}; + +fn main() { + App::build() + .add_resource(WindowDescriptor { + title: "Advent of Code".to_string(), + width: 1920, + height: 1080, + ..Default::default() + }) + .add_resource(ClearColor(Color::rgb(0., 0., 0.))) + .add_startup_system(setup_camera.system()) + .add_startup_system(read_input_file.system()) + .add_stage("add") + .add_system_to_stage("add", check_next_num.system()) + .add_stage("remove") + .add_system_to_stage("remove", remove_oldest_line.system()) + .add_stage("find_range") + .add_system_to_stage("find_range", find_contiguous_range.system()) + .add_plugins(DefaultPlugins) + .run(); +} + +fn setup_camera(mut commands: Commands) { + commands.spawn(Camera2dComponents::default()); +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +struct LineNum(usize); +#[derive(Clone)] +struct Num(i64); +struct Active; +struct Invalid; +struct Done; + +fn read_input_file(mut commands: Commands) { + let f = File::open("./inputs/day_9.txt").unwrap(); + + for (line_num, line) in BufReader::new(f).lines().enumerate() { + let line = line.unwrap(); + let line = line.trim(); + let num = line.parse().unwrap(); + commands.spawn((LineNum(line_num), Num(num))); + if line_num < 25 { + commands.with(Active); + } + } +} + +fn check_next_num( + mut commands: Commands, + active: Query<With<Active, &Num>>, + next: Query<Without<Done, Without<Active, (Entity, &LineNum, &Num)>>>, +) { + if let Some((min_entity, line, num)) = next.iter().min_by_key(|(_, line, _)| line.0) { + let mut is_sum = false; + for active_1 in active.iter() { + for active_2 in active.iter() { + is_sum = is_sum || (num.0 == active_1.0 + active_2.0) + } + } + commands.insert_one(min_entity, Active); + + if !is_sum { + commands.insert_one(min_entity, Invalid); + println!( + "{} on line {} was not a sum of the previous lot!", + num.0, line.0 + ); + } + } +} + +fn remove_oldest_line( + mut commands: Commands, + line_nums: Query<Without<Done, With<Active, (Entity, &LineNum)>>>, +) { + if let Some((min_entity, _)) = line_nums.iter().min_by_key(|(_, line)| line.0) { + commands.remove_one::<Active>(min_entity); + commands.insert_one(min_entity, Done); + } else { + println!("All numbers cleared"); + } +} + +fn find_contiguous_range( + mut exit_events: ResMut<Events<AppExit>>, + line_nums: Query<(&LineNum, &Num)>, + invalid: Query<With<Invalid, &Num>>, +) { + for invalid in invalid.iter() { + let mut nums: Vec<(LineNum, Num)> = line_nums + .iter() + .map(|(line, num)| (line.clone(), num.clone())) + .collect(); + + nums.sort_by_key(|(line, _num)| line.clone()); + let nums: Vec<i64> = nums.into_iter().map(|(_line, num)| num.0).collect(); + + for min in 0..nums.len() { + for max in min + 2..nums.len() + 1 { + let sum: i64 = nums[min..max].iter().sum(); + if sum == invalid.0 { + let min_in_range = nums[min..max].iter().min().unwrap(); + let max_in_range = nums[min..max].iter().max().unwrap(); + println!( + "Range found! {} + {} = {}", + min_in_range, + max_in_range, + min_in_range + max_in_range + ); + } + } + } + + exit_events.send(AppExit); + } +} |