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>, next: Query>>, ) { 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>>, ) { if let Some((min_entity, _)) = line_nums.iter().min_by_key(|(_, line)| line.0) { commands.remove_one::(min_entity); commands.insert_one(min_entity, Done); } else { println!("All numbers cleared"); } } fn find_contiguous_range( mut exit_events: ResMut>, line_nums: Query<(&LineNum, &Num)>, invalid: Query>, ) { 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 = 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); } }