diff --git a/2022/17/Cargo.lock b/2022/17/Cargo.lock new file mode 100644 index 0000000..7391327 --- /dev/null +++ b/2022/17/Cargo.lock @@ -0,0 +1,14 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "common" +version = "0.1.0" + +[[package]] +name = "day17" +version = "0.1.0" +dependencies = [ + "common", +] diff --git a/2022/17/Cargo.toml b/2022/17/Cargo.toml new file mode 100644 index 0000000..f709ded --- /dev/null +++ b/2022/17/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day17" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +common = { path = "../common" } diff --git a/2022/17/flamegraph.svg b/2022/17/flamegraph.svg new file mode 100644 index 0000000..5a23aec --- /dev/null +++ b/2022/17/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch [[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[vdso]] (7 samples, 0.10%)[unknown] (1 samples, 0.01%)day17::Game::collides (1 samples, 0.01%)[[kernel.kallsyms]] (1 samples, 0.01%)[[kernel.kallsyms]] (10 samples, 0.15%)[[kernel.kallsyms]] (10 samples, 0.15%)[[kernel.kallsyms]] (10 samples, 0.15%)[[kernel.kallsyms]] (9 samples, 0.13%)[[kernel.kallsyms]] (8 samples, 0.12%)[[kernel.kallsyms]] (8 samples, 0.12%)[[kernel.kallsyms]] (7 samples, 0.10%)[[kernel.kallsyms]] (7 samples, 0.10%)[[kernel.kallsyms]] (7 samples, 0.10%)[[kernel.kallsyms]] (7 samples, 0.10%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (5 samples, 0.07%)[[kernel.kallsyms]] (3 samples, 0.04%)__GI___libc_free (8 samples, 0.12%)_int_free (4 samples, 0.06%)tcache_put (2 samples, 0.03%)core::hash::BuildHasher::hash_one (47 samples, 0.69%)core::hash::impls::<impl core::hash::Hash for i64>::hash (20 samples, 0.29%)[libc.so.6] (1 samples, 0.01%)__GI___libc_free (2 samples, 0.03%)_int_free (2 samples, 0.03%)tcache_put (2 samples, 0.03%)__GI___libc_malloc (7 samples, 0.10%)tcache_get (4 samples, 0.06%)__memset_avx2_unaligned (1 samples, 0.01%)__rdl_alloc (2 samples, 0.03%)std::sys::unix::alloc::<impl core::alloc::global::GlobalAlloc for std::alloc::System>::alloc (1 samples, 0.01%)__rust_alloc (3 samples, 0.04%)day17::Piece::points (188 samples, 2.77%)da..hashbrown::map::HashMap<K,V,S,A>::insert (185 samples, 2.73%)ha..hashbrown::raw::RawTable<T,A>::insert (123 samples, 1.81%)h..hashbrown::raw::RawTable<T,A>::reserve_rehash (105 samples, 1.55%)core::hash::BuildHasher::hash_one (56 samples, 0.83%)core::hash::impls::<impl core::hash::Hash for i64>::hash (19 samples, 0.28%)<hashbrown::raw::RawIter<T> as core::iter::traits::iterator::Iterator>::next (2 samples, 0.03%)day17::Game::do_round (6,767 samples, 99.72%)day17::Game::do_roundday17::Game::collides (6,765 samples, 99.69%)day17::Game::collidesstd::collections::hash::set::HashSet<T,S>::is_disjoint (44 samples, 0.65%)core::hash::BuildHasher::hash_one (28 samples, 0.41%)core::hash::impls::<impl core::hash::Hash for i64>::hash (9 samples, 0.13%)<std::time::Instant as core::ops::arith::Sub>::sub (1 samples, 0.01%)std::time::Instant::duration_since (1 samples, 0.01%)std::time::Instant::checked_duration_since (1 samples, 0.01%)std::sys::unix::time::inner::Instant::checked_sub_instant (1 samples, 0.01%)std::sys::unix::time::Timespec::sub_timespec (1 samples, 0.01%)day17 (6,780 samples, 99.91%)day17_start (6,771 samples, 99.78%)_start__libc_start_main_impl (6,771 samples, 99.78%)__libc_start_main_impl__libc_start_call_main (6,771 samples, 99.78%)__libc_start_call_mainmain (6,771 samples, 99.78%)mainstd::rt::lang_start_internal (6,771 samples, 99.78%)std::rt::lang_start_internalstd::panic::catch_unwind (6,771 samples, 99.78%)std::panic::catch_unwindstd::panicking::try (6,771 samples, 99.78%)std::panicking::trystd::panicking::try::do_call (6,771 samples, 99.78%)std::panicking::try::do_callstd::rt::lang_start_internal::{{closure}} (6,771 samples, 99.78%)std::rt::lang_start_internal::{{closure}}std::panic::catch_unwind (6,771 samples, 99.78%)std::panic::catch_unwindstd::panicking::try (6,771 samples, 99.78%)std::panicking::trystd::panicking::try::do_call (6,771 samples, 99.78%)std::panicking::try::do_callcore::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once (6,771 samples, 99.78%)core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_oncestd::rt::lang_start::{{closure}} (6,771 samples, 99.78%)std::rt::lang_start::{{closure}}std::sys_common::backtrace::__rust_begin_short_backtrace (6,771 samples, 99.78%)std::sys_common::backtrace::__rust_begin_short_backtraceday17::main (6,771 samples, 99.78%)day17::mainstd::time::Instant::elapsed (3 samples, 0.04%)std::time::Instant::now (2 samples, 0.03%)std::sys::unix::time::inner::Instant::now (2 samples, 0.03%)std::sys::unix::time::inner::<impl std::sys::unix::time::Timespec>::now (2 samples, 0.03%)__GI___clock_gettime (2 samples, 0.03%)all (6,786 samples, 100%)perf-exec (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%)[[kernel.kallsyms]] (6 samples, 0.09%) \ No newline at end of file diff --git a/2022/17/input b/2022/17/input new file mode 100644 index 0000000..51f80eb --- /dev/null +++ b/2022/17/input @@ -0,0 +1 @@ +>>>><<<>><<><<><<><>>>><>><><<<<>>>><<<>><<<>><<<>>><<<>><<<<>>><<<<>>><<<>><><<<<>>>><<<<>>>><<>>><>>>><<>>><<<<>>><><<<<><>>>><>>>><>>>><><>><>>><<>>>><>>>><<<>>>><<>>><<<<>>><><<<<>>><>>><<<>>>><>><><<<>>><<<>>>><<>><<><<<>>>><><<>>><<><<<><<<><><><<<<>>>><<<<>>><<<<>><<>>><><<<<>><<<<>>><<>>>><<><>><<<<>>>><<<>>>><<<>>>><><<<>>>><<<<><<><<>>>><<><<<<>><<>>><<<><<>><><<<<>><<<><<<>><<<>><<<<><>>><<<<>>><<<>>><<<><<<>>>><<>>><<<>>>><<<>>><><<<<>><<<>>><<<>><<<><<<>><<>>>><<>><<>>>><<><<<>>><<<<>>>><<<>><<>>>><>><>><>><<<<>><><>><<<>><><>>>><<><<<<>><>>>><<<<>>><<>><<<>><<<>>><<<<><<<><<<<>>>><<<<>>>><<<><<<<>><<<>>>><>>>><<<>>>><<<<><><<<<>><>>>><<<>><><<<<><<>>><>>>><>>><<<<><<><<<><>><<<<>>><>>><>>>><<<><<<><>><<<>>>><<<<>>><<><<>>>><><>>><><<>>>><<<>>>><<<>><><<<<><<<>>><<>>><<<>><<<>><<>>>><<>>><<<><<<>><<<<><>><><<<>>>><<<<>>>><<<<>><<<<>>>><<<<>><<>>>><<<<><<>>><<>>><<<<>>><<<>>><>>><<<>>>><<<<><<>>>><<<<>>>><<<<>>>><>><<>>>><><<<>>><>>><<<>><<<<>>><>>>><<>>>><<<>>>><<<<>><<<>>>><>>>><<<<>>>><<<<>><<>>><<><>>><<<<><<<<><<><<<<>>><>>>><<<<>>><><>><<<<><<<<>><<>>>><>>><<>>><<>>>><<>><><>>>><>><<<<>>><<>>>><<<<>>><<<>>>><<<>>><<<<><<><<<>><><<<<>>><<<><<<>><<<<>>><>>><>>><<<<>>>><<<>>>><<>>><<<<>>><<<<><<<<>>>><<>><<<<>>><<<<>>>><>>>><<<<>><<<<>><<>>><><<><<><<<<>><<>>>><<>><<<>>>><>>>><>>>><<<><<<>>>><<><<>>><<<>><<<<><<<<>><<<<>><<<<>>><<>><>><<>><<<>>>><<<>><>>>><<<>>>><<>><<>>>><>><<<><<<>>>><<<><<>>><<<>>>><<><<<>>>><<<<><<<>>>><<<>>><<>><<><<>>>><<><<<>><<<<>><<>><>>>><>><<<<>>><>>>><<>><<>>><<<<>>>><<<<>><>><<<>>>><><>>><<><<<<><>><<<>>><<<>><><><<<>><<<>>>><<<<>>><>>>><<<><>><<<>><<>>><<<><<<<>><<<>>><><<>><>>><<<>>>><>>><<>><<<>>>><<<>>><><<<<>>><>>>><<<<>>><<<<>>><<<><><><<<>>><><<>>>><<<>>>><>>>><><<<>>>><<<>>>><>>><<>>>><<<>>>><<>><<<<>>><<<>>>><<<><>><<<<>>><>><<<><<<>>>><>>><>>><<>><<<>><<<<><<<>><>>><>><<<>>><<<>><<<<>>><<<><<>>><<<<>>><<<><>>>><<><<>><>>><<>><<>>><<<><<<><<<><<<>><<>>>><>>>><>><<<<>>><<<<><<<<>><>>>><<<>>>><<<>><<<>>><<<<>>><><>><<<<><<><>>>><<<>><><<><<>>>><<>><><<>><<<>><<<<>>>><><<<<>><<<><<>><><<>><>>><>>><<<<><<>><<>><<><<>>>><><<<><<<>>>><<<>>>><<><<<<><>><<<<>>><<<<>><>>>><>><>>><<<>>><<<>>><<<<>><>><<<<>>><<<>>>><>>>><<<><<<>><<>>><<>>><<>><>><<<<>>>><>>><>><<>>>><<<<>><>><<<<>>>><<>><<<<>><>>><<><<<>><<<>>><<<<>>><<><<>>>><<<>>><<<<>>><<<<>><><<>><<>><<<<>>>><<<><<>>>><<<><><>>><><<<>>><><<<<><<<<><<<>><<<>>>><>>><<<<>><<<<><<<>>><<><<<>>>><<<>>><<<<>><<<<>>><<<<><>>>><<<<>><<<><<<<>>>><>><<<<>><<<<>><<<><<<>><<<>>>><>>><<<>>><<<<>><<>>><<<>>>><>>>><<>>><<<><<>>><<<<>>>><<>>>><<<>><<<<>>>><><<<>>><<<>>>><<<>>><<<><<><<<<><><<<<>>>><<<>>>><><><<<<>><<>>>><<<<>>>><>>>><<<<>>>><><<><<>><<><<>><<<<>>><<>>><<<<>>>><<<<>>>><<<><>><<<<>>>><<<><>>>><>>><<><><><<<>>><<>>>><<>>><<>><<<<>>>><<<>>>><<>>><<><>>>><<<>><>>>><<>><>>><>>><<>><><<>>>><<>>>><>><<<<>><<<<>>>><>>>><>>>><>>><>>>><<<>><<>>>><<<>>>><><<<<><<>>><<<>>>><<>>><<><><<<<>>><<<<>>>><<<<>>><<>><<<>><<>><<<<>><<<>>>><<<>>>><<<<>>>><<>>>><<<<><<<>><<<>>><<>>>><>>>><<<<>><<<>><<>><<<>><<>>><<<<><<<<>>><<>><<<<><<<<>>>><><<<<>>><<<><>>><<>><<<<>>><<<<>>>><>><<<<>>><<<<>>>><<<>>>><>>><<><><>>><<<<>>><<<<>>><<<<>><<<<>>><<<<>>>><<<<><<<>>>><>>>><<<<>>><<<>>>><>><<<<><<>>>><>>><<<<><<<<>>>><><<<><<<>>>><<<><>>>><<<<><<<><>>>><<<>><<<>><<<><<<<>><<<<>><<><<>>>><<>>>><<<<>>><>><<<<><<<><<>>>><<<>><>>>><<<>>>><<>><>>><><<><<<>><<>><<<>><<<<><<<<>>><>><<<>><><<<<><<>>><>><<<<><<<>>>><<<><<<<><<>>>><><<<>><<>><<<><<<<>>>><<>><<>><<><<>><>><<<>><<>><<<>><>>><<<<><<<>>>><<<<>><>><<><><>>><>>>><<<<>>>><<<>>>><<<>>><<<<><<<>>>><<><<<<><<<><><<>>><<>>>><<>><<<<>>><<<>>>><<<><<<>>>><<<>>><<<>><<<>><<<<>><<<><>>>><>>>><<<<>>>><<>>><<><>><<<<>>>><<<>>>><>><>>><<><<<><<<><><<<>>><<<<><<<<>>>><<<>>>><<<<>>>><<<><<<<><<<<>><<<>>>><<>>>><>>><<>><<<<>>>><<>><>><<>><<<>><<<<>>><<<<><<<<><<>><<<>><<><<<<>><<><<<>><<<<><<<>>><<<>>><>>>><<<><<<<>><>>><<<>><<>>><<<<>><><<>>><<><<>>><<>>><<<<>><<<<>>>><<<>>>><>>>><<>>>><<<>>>><>>><<<<>><>>>><<<<>>>><>><<<>><>>><<<<><>><><<<>><><<>><<<<>>><<<<><<>>>><<>>><<<<>>>><<<<><<<<><<<>><>>>><<<>>>><<>>>><<>><><>>><<<>>><<>>>><><<<<><<>>><<>>>><<<>>><<<<>><>>><<<<>><>>><><>>><<>>><><>>>><<<>>>><<<>><<<<>>>><<<<>>>><<>><<<<><<<<>>>><<<<>>><<<>>><<<<><<<<>><<<<>>>><<<>>><<>><<><>><<>>><>>><<>>><<<<>>><<<>>>><<<><><<>><<<><<<>>><><>><<<<><<>><<<<>><<<<><<<<>><>>>><<<>>>><<<<><<<><<<<>>><<>>>><>>><<<><<>>>><>>>><>>><<<<>>>><<<>><>>><<><<<<>><<>><<>>><<<<><<>>>><<<>><<<<><<>>><>>><<>><><<<<>><<<><><<<>>>><<<>><>><<>><<<>>><<>>><<<>>>><<<>>><><<>><>>>><>>><>><<<<><><<<>>><>>>><><<<<><<<><>>><<<>><<<<>>>><<<<>>><<>><<<<>><<>><<>>><<<>>>><<>>>><<><<<>>><<<<>><<<>><<<>>><<<<>>>><><<<<>><<>><<<<>><<><<<<>>>><<>>><<<><>>>><<>>>><<>><<<><<>><<<>>>><<<><<><<<<>><<<<>>>><<<>>>><<<<>>>><<<>><><<<>>>><<<<>>><<>>><<<>><><<<<>>><>>>><<<<>>>><<<<>><<<><><<<<><<<>>>><<<<>>>><><<<>><>>>><<<<>>>><<<<><<<><<<<>>><>>>><>>>><<<<>><<>><<<>>>><<<<>>>><<<<><<<<>>>><<>>><<>>><<<>>>><<>>>><<<>>>><<>><<>>>><<<<>>>><<<<><<<><>><<>><<<<><>>>><>><<<>>>><<<><<>>>><<><><><>>>><<<<>>><<><<<>><<<<>><<<>><<<>>><<<<>>>><<<>>><<<<>><<<>>>><<<>><<<>>>><<<<>>>><<>>>><<<<>><<<>>><<>>><<<<>>>><<<<>><<<<>><<<<>>>><<<><<<>><>>><>>>><<>><>>>><<>><<<>>>><>>>><>><>>><<<<>>><<<<>>><<<<>>><<<>>>><<<>>>><<<<>>><<<>>><<>>>><>>><<>>><>><><<<>>><><<<>>><<<>><<>>><<<<>>><>>><<><<>>><<<<>>>><<>>><<<>><<>><<<>>><<<<>>>><<<>>><<<<>>><<<<>>><<<><<>>>><<<<>>><<<>>>><<>>><<>><>>>><<<>>>><<<<>>>><>>>><>>>><<><<><<<>><<<>><<><<<<>>><<<<>><>>>><<>>><<>>>><<<>><<<><<<>>>><<<>>><<<<>>><<<>>><<<<><<><<<<>><<<<><<><<<>><<<<>><><<<<>>>><<<<>><<>><<>>>><><<>><>>><<>><<<><><<>><<<<>><>><<<<>>><<><<>><>>>><>>>><<<>>><<<><<>><<><<<>>>><<<><<>>>><>>>><<<>>>><<>><<<>><>><><<<>>>><<>><<<<>><<<<>>><<<<>>>><<<<>><<<<>>><>>><>>><<><>>><<>><<<<>>>><><<<>><<<<>>>><>><<<>><<><><<><<<<>><<>>>><>>>><<>>><<>><<><><<>>><>><<<<>>><<<><<<<><><<>>>><<>>>><<<<>>><<<>>><<<>>>><<<>>><<<<>>>><<>>>><<>><>><<<>>><<<<><<<>>><<>>><<<<>><><>>>><<<>><<>>><<<><<><<<<>><<<<>>>><><<<>><<<<><<><<><<<>>>><>>><>><<<>><<<>>><><<<><<<<><>>>><><<>><<<>><<>>><<<>>>><<<<><>>>><<<>>><><<<><<<>><<>><<>><<<<><<<<>>>><><<<>>><<>><<<>>>><<>>><<<<><<<<>><<><<<>><<<<>>><<<<><<>>>><<<<>><<<>>>><><<>><>><<<><<>>>><<>>>><<<>>>><<<<>>>><<>>><><<<<>>>><<>>><><<<>><>>><<<<>>>><<<<><<<>>><<>>>><><<>><<>>><<<>>>><>><><<<<>><<<>>>><<>><<<>><<><<<<>><><<><<<>>>><<><<<<>>><<><<<>>>><>><<<>>>><<>>><><<<<>><<<<>>>><<>>>><><>>><<<><<>>>><<>>><<<>>><<<><>>>><<>><<<>><><<<>>>><>><>>><<<<>><<>>>><><<<>>>><<>>>><<<<><>>>><<<>>>><<<>><<<>>><<<<><<>>>><<<<>>><<>>><><<<<>>><>>>><<><<<>>>><<><<><<<<><<<><<>>>><>>><><<<<>>>><<<<>>>><><<<<>>><<>>>><<<<>>>><<<>>>><<>>><<<<>><<>>>><<><<><<>><<<<>>><<><<<<><>>>><<>><<>>>><<><>><<<>><<>>>><<<>>><<<<><<<<>>>><><<<<><<<><<>>><<<><<<<>>>><>>>><<<><<>><>>>><<<<><>>><<<>>><<><<<<>>>><<<<>><<<<>>>><<<<>><<<<><>><<<>>><>><<<<>>>><<<<><<<>>><<><<<<>>>><<>>>><<<<>>>><<>>>><<<<>>>><<<>>>><><>><<<>>>><<<<>>><<<<>>>><<<>>><<<<>>>><<><<>><><<>>>><>>>><<<<>>>><<>>>><>>><<<>><>>>><<<<>>><>>>><<<<>>>><<><>><<><<<<>>><<<<>><<<<>>>><>>>><<<>>><<>>>><<<<>>>><<>>><<<<><<>>>><>>><>><<<<>><<<<>>>><<<<>>><<><<>>><<><><<<>>>><<<>>><<<>><<<<><<<<>>><<>><<<<>>>><<<<>>>><<<><<<><><<>>><<<<><<<>><<<>>><<<<><><<>><<<>>>><<<<><<>>>><<<<><<>>><<>>>><<<<><>><<<<><<<<><<>>>><<><<<>><>><<<>><>>><<<>><>>>><<<>><<>>>><<><<>>><<>><>>><<<<>>><>><<<><<><><><<>>><<<><>><<>><<>><<>>><<<<>>>><<<>>><<<>>>><<<<>>><>><<>>><>>>><<<>><<<>><<<<>>><<<<><<>>>><<<<><>>>><<<<>>><<<>>>><<<>>>><<<<>><<>>>><>>><><<<<>>><<<<>><>>><<<<><<<<>>><><<<>>>><<<<>><<<>>>><<<<>>><<>><<>><<<<>><<>><<<<>><<>>>><>>>><<<<>>>><<<<>>><><>>><<>>><<<<>>>><>>>><>><<<<>>>><<><<<><<>>>><<<><<<><<>><<<<>>>><<<><<>><<<>><<>><<>>><<><<<>>><<<<>>><<<>>><>>>><<<<><<>>><>>><<<>>><>>>><<<<>>>><<<>>><<<<>><<<><<<<><<<>>><><<<<>>><<<>>>><<>>>><<>><<<>>>><<<<>>><<<><<<>><<<<>>><<<>>>><<<>>><<<>><<<>>>><<>><<<<>><<><><<>>><>>>><<<<>>>><<>>>><<<>>><<<>><<<<>>><<<<><<<<>>><<<<>>><><<>>>><<<<>>>><><<<<>><<>><<><<><<<>>><<<<><<>>>><<><<><>><<<<>>>><>><>><<>>>><<<>><<<>>>><<<>><>><<>><<<>>><<<<><<<>>><<<>>><<>>>><>><<<<>><<<>><><<<<>>>><>>>><>>>><<<>>><>>>><<<>>>><<<>>>><>><<<<>><><>>><><<>>>><<<>>>><<>>><<<>><<<<>>><<>>><>>><<<<>>>><><<<<>>><<>>><><<<>><<<<><<<><>>>><<>><<>><<><<<<><<<><<>>><<<>>>><<>><<<<>>><<<<>><><<<<>>>><<<<>>><><<<>><<>>>><>><>><<<>>>><<>><>>><<>>><<><<>>>><>>><><<>>><<>><<>>>><<<><<<<><>>><<<<>>>><<<>>><<<<><<<>>><<<<><<>><<<<><<<<>>>><>>><>><>>><>><>><><<<>>><><>>>><<<>>>><>><<>>>><<<>><<<>>><<>>>><>>>><>>><<<<>>><<>>><<<>><<<<>><<<>>>><<<>><<<<>><>>><<>>><>>><<<>>>><<>><<<<><<<><>>><><<<>>><<>><><<<>>>><>>>><<<<>>>><<<><<<><>>><<<>>>><<<<><<<<><<>>><<>><<<>><>>><<>>><<>>>><<<<><<<<>><<<>><<>>>><><<<<><<<<>>><<<>>>><<<<>><<>>>><>>>><>><<<>>><<<>><<<><<<>>>><><<<<>><<>>>><>>><<<>>>><<><<<<>><<<>>>><<<>>><<<>><<<>>><><<<<>><<<<><<<<>>>><<<>>>><>>><<><>>><<<>><>><>>><<>>>><<<>>><<>>>><>>>><<<><<<>>><<<<><<<>><<<>><<<><<>>><<<>><<<<>>><<<<>><<>><<<<>>>><<>><<<>><>>><<<<>><>>>><<<<><<<<>><>>>><<<<><<><<<><<>><><<<>>>><<<<>>><<><>>>><<>><<<<>><<<<>><<<><<>>><<>>>><<<<>>>><<><<<<>>>><<><<<><<<><<<<>>><<<>>><<<>><>><><<<<>>>><>><<>>>><<><><<>>><<<<>><<<><<<>>>><<<><<<<>><<<<>>>><<<>>><<<>>><<>>><><<<>><<<<>>><<>>><<<<>>><<>>><>>>><<<>>><<<<>>><<<>><<<<>><<<>><<><<<<>>>><<>><<<>>>><<<>>><<<<>>><<<<>>><<<<><<<<>>>><<<<>>><<><<<><<<<>>><<<<>>>><<<>>><<<<>>>><<><<><<<<>><<<<>>><>>>><>>><<>>>><>><<>>>><<<>><<<>>>><><<<>>>><>>><<<<>><><<<>>><<>>><<<<>><>><<>>>><<<<>><<>><>>><<<<>>>><<<>><>><<<<>>>><<<>><<>>><<<>><<<>><<><>>>><><<<>>><<<<>>><<<<><<<<>>><>>><<<<><<<>>><<>><<<<>>>><<<<>>><<<<><><<<<>>><<>><>>><<<>><<><<<<>>><<><<<><>><<<>><<>>><<<>><<<<><<<><<<>>>><<<<>><>><<<<>><<><<<>><<<>>>><<<<>>><>>><<>>><>>>><<<<>>><<<<>>><<>><<>>>><>><>>>><<>><<<>><<<>>>><<<<>>><<>>>><><>><><<<><<>>><<>>><<<<><>>><<<<>><<<<>>><>><<<<>><<<<>>><>>>><><<<<><>>><>>><<<>>><>>><<<<><>><<<><<<<>><<>><><<>>>><<>><<<<><>><<>>>><<>><<>>><<>>>><<<<><>>>><<<>>><<><<>><<<>>><<<<>>><<>><><<<<>>>><<<<><>>>><<<<><<<<><<<>><<<>>>><<<>>>><<<>>>><<<>><<<<>>>><<<<><<<<>>>><<>><<>><<<>><<<<>><<<>>< diff --git a/2022/17/perf.data b/2022/17/perf.data new file mode 100644 index 0000000..676adde Binary files /dev/null and b/2022/17/perf.data differ diff --git a/2022/17/src/main.rs b/2022/17/src/main.rs new file mode 100644 index 0000000..62f2601 --- /dev/null +++ b/2022/17/src/main.rs @@ -0,0 +1,387 @@ +use common::Point; + +fn main() { + let input_file = common::parse_args_input_file(&mut std::env::args()); + let contents = std::fs::read_to_string(input_file).expect("Failed to read input file"); + + let mut game = Game::new(); + let mut goal = 2022; + game.jets = JetDirection::get_jets_from_string(&contents); + loop { + game.do_round(); + + // If the 2023rd piece spawned, it's because 2022 have come to a rest + if game.stopped_rocks >= goal { + break; + } + } + println!("[PART 1] After {} rounds, {} pieces came to a rest, towering up {}", + game.rounds, game.pieces.len() - 1, game.rock_height); + + game = Game::new(); + game.jets = JetDirection::get_jets_from_string(&contents); + goal = 1_000_000_000_000; + let mut time = std::time::Instant::now(); + loop { + game.do_round(); + if time.elapsed().as_secs() > 1 { + time = std::time::Instant::now(); + println!("{} of {}", game.pieces.len(), goal); + game.print(); + break; + } + if game.stopped_rocks >= goal { + break; + } + } + println!("[PART 2] After {} rounds, {} pieces came to a rest, towering up {}", + game.rounds, game.pieces.len() - 1, game.rock_height); +} + +#[derive(Clone,Copy)] +enum JetDirection { + Left = -1, + Right = 1, +} + +impl JetDirection { + fn get_jets_from_string(contents: &String) -> std::vec::Vec { + let mut jets = std::vec::Vec::::new(); + for line in contents.lines() { + if line.eq("") { + continue; + } + for c in line.chars() { + if c.eq(&'>') { + jets.push(JetDirection::Right); + } + else if c.eq(&'<') { + jets.push(JetDirection::Left); + } + else { + unreachable!(); + } + } + break; + } + return jets; + } +} + +struct Game { + current_piece: Option, + pieces: std::vec::Vec, + jets: std::vec::Vec, + next_jet: usize, + width: u32, + next_piece: u32, + rounds: u64, + rock_height: u64, + collision_stop: usize, + stopped_rocks: u64, +} + +impl Game { + fn new() -> Game { + return Game { + current_piece: None, + pieces: std::vec::Vec::::new(), + jets: std::vec::Vec::::new(), + next_jet: 0, + width: 7, + next_piece: 0, + rounds: 0, + rock_height: 0, + collision_stop: 0, + stopped_rocks: 0, + }; + } + + fn print(&self) { + let mut max_y = 0; + let mut points = std::collections::HashSet::::new(); + for piece in self.pieces.iter() { + for p in piece.points().iter() { + max_y = std::cmp::max(max_y, p.y); + points.insert(*p); + } + } + + let mut y = max_y; + while y >= 0 { + let mut line = String::new(); + line.push('|'); + for x in 0..self.width { + if points.contains(&Point{x: x as i64, y: y}) { + line.push('#'); + } + else { + line.push('.'); + } + } + line.push('|'); + println!("{}", line); + y -= 1; + } + println!("+-------+"); + } + + fn collides(&self, piece: &Piece, offset: Point) -> bool { + let mut collides = false; + let mut hypothetical_piece = piece.clone(); + hypothetical_piece.position.y += offset.y; + hypothetical_piece.position.x += offset.x; + let points = hypothetical_piece.points(); + let mut all_points = std::collections::HashSet::::new(); + + // Start with the the more recent indices, since they might be nearer. + if self.pieces.len() < 2 { + // If we're the only piece, or there are no pieces we can leave. + return false; + } + + let mut index = self.pieces.len() - 1; + while index > 0 { + let piece = &self.pieces[index]; + if piece.falling { + index -= 1; + continue; + } + if piece.position.y + PieceType::height(&piece.t) as i64 >= hypothetical_piece.position.y { + if !piece.points().is_disjoint(&points) { + // println!("[Round {}] Current piece will collide with piece at index {}", + // self.rounds, index); + collides = true; + break; + } + } + index -= 1; + } + return collides; + } + + fn do_round(&mut self) { + if self.current_piece.is_none() { + // Create a new piece + self.current_piece = Some(self.pieces.len()); + let mut piece = Piece::new(PieceType::from(self.next_piece).unwrap()); + self.next_piece = (self.next_piece + 1) % PieceType::count(); + + // Determine where it's origin should be. + // Since we're using a bottom left origin, the point is easy to set. + piece.position.x = 2; + // Since we're tracking the rock height for the part 1 score, we can + // re-use that. Otherwise we would have to iterate over the pieces + // at rest and get the highest y coordinate + the piece height + 3 + piece.position.y = self.rock_height as i64 + 3; + // println!("[Round {}] Spawned new piece of type {:?} at {:?}", + // self.rounds, piece.t, piece.position); + self.pieces.push(piece); + + // self.print(); + // println!("^ Spawned on round {} ^", self.rounds); + } + let current_piece_index = self.current_piece.unwrap(); + let mut current_piece = self.pieces[current_piece_index].clone(); + + // In each round, the piece is blown to the left or right based on the + // the next jet. Then, it falls one spot if possible. + let jet_offset = self.jets[self.next_jet] as i64; + self.next_jet = (self.next_jet+1) % self.jets.len(); + + let mut blown = true; + if current_piece.position.x + jet_offset < 0 { + blown = false; + } + if current_piece.position.x + jet_offset + PieceType::width(¤t_piece.t) as i64 > self.width as i64 { + blown = false; + } + // There may be collision between pieces in the blow step. + blown = blown && !self.collides(¤t_piece, Point {x: jet_offset, y: 0}); + if blown { + current_piece.position.x += jet_offset; + // println!("[Round {}] Piece blown {} from {:?} to {:?}", + // self.rounds, jet_offset, self.pieces[current_piece_index].position, + // current_piece.position); + self.pieces[current_piece_index].position = current_piece.position; + } + + // Check if falling would collide with anything. + let mut fall = true; + if current_piece.position.y - 1 < 0 { + fall = false; + } + // Find pieces that are vertically near the current piece, and check collisions + // between the current piece down one square and those pieces. However, we don't + // want to do the check if we've already stopped falling. + fall = fall && !self.collides(¤t_piece, Point {x: 0, y: -1}); + + if fall { + current_piece.position.y -= 1; + // println!("[Round {}] Piece fell from {:?} to {:?}", + // self.rounds, self.pieces[current_piece_index].position, + // current_piece.position); + self.pieces[current_piece_index].position = current_piece.position; + } + else { + // Coming to a rest. + self.pieces[current_piece_index].falling = false; + // println!("[Round {}] Piece came to a rest", self.rounds); + // Update max height + self.rock_height = std::cmp::max( + self.rock_height, + (current_piece.position.y as u64) + (PieceType::height(¤t_piece.t) as u64) + ); + self.stopped_rocks += 1; + self.current_piece = None; + + // When a piece comes to rest, we check the nearby pieces to see if a line is formed, + // keeping track of the oldest piece nearby. If a line is formed, nothing can fall below. + // let mut max_y = 0; + // let mut points = std::collections::HashMap::::new(); + // for (index, piece) in self.pieces.iter().enumerate() { + // for p in piece.points().iter() { + // max_y = std::cmp::max(max_y, p.y); + // points.insert(*p, index); + // } + // } + + // let mut lowest_piece_index = usize::MAX; + // let mut blocked = 0; + // let mut all_blocked = 0; + // for x in 0..self.width { + // all_blocked |= 1 << x; + // } + // let y = max_y; + // while y >= 0 { + // for x in 0..self.width { + // if (blocked >> x) & 1 == 1 { + // continue; + // } + // let point = Point{x: x as i64, y: y as i64}; + // if points.contains_key(&point) { + // lowest_piece_index = std::cmp::min(lowest_piece_index, *points.get(&point).unwrap()); + // blocked |= 1 << x; + // } + // } + // if blocked == all_blocked { + // self.collision_stop = std::cmp::max(lowest_piece_index, self.collision_stop); + // } + // y -= 1; + // } + } + self.rounds += 1; + } + +} + +#[derive(Clone,Copy,Debug)] +enum PieceType { + HorizontalLine = 0, + Plus = 1, + Ell = 2, + VerticalLine = 3, + Square = 4, +} + +impl PieceType { + fn from(v: u32) -> Option { + let t = match v { + 0 => { Some(PieceType::HorizontalLine) }, + 1 => { Some(PieceType::Plus) }, + 2 => { Some(PieceType::Ell) }, + 3 => { Some(PieceType::VerticalLine) }, + 4 => { Some(PieceType::Square) }, + _ => { None }, + }; + return t; + } + + fn count() -> u32 { + return 5; + } + + fn width(&self) -> u32 { + return match self { + PieceType::HorizontalLine => { 4 }, + PieceType::Plus => { 3 }, + PieceType::Ell => { 3 }, + PieceType::VerticalLine => { 1 }, + PieceType::Square => { 2 }, + }; + } + + fn height(&self) -> u32 { + return match self { + PieceType::HorizontalLine => { 1 }, + PieceType::Plus => { 3 }, + PieceType::Ell => { 3 }, + PieceType::VerticalLine => { 4 }, + PieceType::Square => { 2 }, + }; + } +} + +#[derive(Clone)] +struct Piece { + // Bottom left of the piece + position: Point, + falling: bool, + t: PieceType, +} + +impl Piece { + fn new(t: PieceType) -> Piece { + return Piece { + position: Point { x: 0, y: i64::MAX }, + falling: true, + t: t, + }; + } + + fn points(&self) -> std::collections::HashSet { + let mut p = std::collections::HashSet::::new(); + match self.t { + PieceType::HorizontalLine => { + for x in 0..PieceType::width(&self.t) { + p.insert(Point { x: self.position.x + x as i64, y: self.position.y }); + } + }, + PieceType::VerticalLine => { + for y in 0..PieceType::height(&self.t) { + p.insert(Point { x: self.position.x, y: self.position.y + y as i64}); + } + }, + PieceType::Square => { + for x in 0..PieceType::width(&self.t) { + for y in 0..PieceType::height(&self.t) { + p.insert(Point { x: self.position.x + x as i64, y: self.position.y + y as i64 }); + } + } + }, + PieceType::Ell => { + for x in 0..PieceType::width(&self.t) { + p.insert(Point { x: self.position.x + x as i64, y: self.position.y as i64 }); + } + for y in 0..PieceType::height(&self.t) { + let x = PieceType::width(&self.t) as i64 - 1; + p.insert(Point { x: self.position.x + x, y: self.position.y + y as i64}); + } + }, + PieceType::Plus => { + let max_x = PieceType::width(&self.t); + let max_y = PieceType::height(&self.t); + for x in 0..max_x { + for y in 0..max_y { + if (x == 0 && y == 0) || (x == 0 && y == max_y - 1) || + (x == max_x - 1 && y == 0) || (x == max_x -1 && y == max_y -1) { + continue; + } + p.insert(Point{ x: self.position.x + x as i64, y: self.position.y + y as i64}); + } + } + }, + } + return p; + } +} diff --git a/2022/17/test_input b/2022/17/test_input new file mode 100644 index 0000000..97a1aa1 --- /dev/null +++ b/2022/17/test_input @@ -0,0 +1 @@ +>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>> diff --git a/2022/common/src/lib.rs b/2022/common/src/lib.rs index 56eac39..d2abebe 100644 --- a/2022/common/src/lib.rs +++ b/2022/common/src/lib.rs @@ -19,12 +19,12 @@ pub fn parse_args_input_file(args: &mut std::env::Args) -> String { #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct Point { - pub x: i32, - pub y: i32, + pub x: i64, + pub y: i64, } impl Point { - pub fn displacement(direction: char, magnitude: i32) -> Point { + pub fn displacement(direction: char, magnitude: i64) -> Point { let delta = match direction { 'U' => Point { x: 0, y: magnitude }, 'D' => Point { x: 0, y: -magnitude}, @@ -84,13 +84,13 @@ impl Point { pub fn unit(&mut self) { let larger = std::cmp::max(self.x.abs(), self.y.abs()) as f32; assert!(larger != 0.0); - self.x = (self.x.abs() as f32 / larger).ceil() as i32; - self.y = (self.y.abs() as f32 / larger).ceil() as i32; + self.x = (self.x.abs() as f32 / larger).ceil() as i64; + self.y = (self.y.abs() as f32 / larger).ceil() as i64; } - pub fn manhattan_distance(&self, other: &Point) -> u32 { - let x = (self.x - other.x).abs() as u32; - let y = (self.y - other.y).abs() as u32; + pub fn manhattan_distance(&self, other: &Point) -> u64 { + let x = (self.x - other.x).abs() as u64; + let y = (self.y - other.y).abs() as u64; return x + y; } } @@ -113,8 +113,8 @@ mod tests { let h = Point { x: 0, y: 0 }; - for x in -1..2 as i32 { - for y in -1..2 as i32 { + for x in -1..2 as i64 { + for y in -1..2 as i64 { let p = Point { x: x, y: y }; println!("{},{}", x, y); assert_eq!(p.towards(&h), no_movement);