Commits vergleichen

...

3 Commits

Autor SHA1 Nachricht Datum
b683e45aff reformatted some code 2024-12-16 21:37:17 +01:00
dbc7c9e7ef formatted some code 2024-12-16 20:42:16 +01:00
4f10c7fb5e solved day 16 part 1 2024-12-16 20:40:41 +01:00
18 geänderte Dateien mit 281 neuen und 99 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1 @@
16c.txt

15
examples/2024/16a.txt Normale Datei
Datei anzeigen

@ -0,0 +1,15 @@
###############
#.......#....E#
#.#.###.#.###.#
#.....#.#...#.#
#.###.#####.#.#
#.#.#.......#.#
#.#.#####.###.#
#...........#.#
###.#.#####.#.#
#...#.....#.#.#
#.#.#.###.#.#.#
#.....#...#.#.#
#.###.#.#.#.#.#
#S..#.....#...#
###############

17
examples/2024/16b.txt Normale Datei
Datei anzeigen

@ -0,0 +1,17 @@
#################
#...#...#...#..E#
#.#.#.#.#.#.#.#.#
#.#.#.#...#...#.#
#.#.#.#.###.#.#.#
#...#.#.#.....#.#
#.#.#.#.#.#####.#
#.#...#.#.#.....#
#.#.#####.#.###.#
#.#.#.......#...#
#.#.###.#####.###
#.#.#...#.....#.#
#.#.#.#####.###.#
#.#.#.........#.#
#.#.#.#########.#
#S#.............#
#################

27
examples/2024/16c.txt Normale Datei
Datei anzeigen

@ -0,0 +1,27 @@
###########################
#######################..E#
######################..#.#
#####################..##.#
####################..###.#
###################..##...#
##################..###.###
#################..####...#
################..#######.#
###############..##.......#
##############..###.#######
#############..####.......#
############..###########.#
###########..##...........#
##########..###.###########
#########..####...........#
########..###############.#
#######..##...............#
######..###.###############
#####..####...............#
####..###################.#
###..##...................#
##..###.###################
#..####...................#
#.#######################.#
#S........................#
###########################

4
examples/2024/README:md Normale Datei
Datei anzeigen

@ -0,0 +1,4 @@
# Examples
# 16c
Thanks to Thanks to https://www.reddit.com/r/adventofcode/comments/1hfhgl1/2024_day_16_part_1_alternate_test_case/

Datei anzeigen

@ -1,11 +1,13 @@
#binop_separator= "Back"
#brace_style="SameLineWhere"
#force_multiline_blocks = true
#imports_layout = "Vertical"
array_width = 0 array_width = 0
binop_separator= "Back" attr_fn_like_width = 80
brace_style="SameLineWhere" chain_width = 144
chain_width = 240
fn_params_layout = "Tall" fn_params_layout = "Tall"
force_explicit_abi = true force_explicit_abi = true
hard_tabs = false hard_tabs = false
imports_layout = "Vertical"
match_block_trailing_comma = true match_block_trailing_comma = true
max_width = 240 max_width = 240
merge_derives = true merge_derives = true
@ -14,4 +16,8 @@ remove_nested_parens = true
reorder_imports = true reorder_imports = true
reorder_modules = true reorder_modules = true
single_line_if_else_max_width = 0 single_line_if_else_max_width = 0
single_line_let_else_max_width = 0
tab_spaces = 4 tab_spaces = 4
use_field_init_shorthand = true
use_small_heuristics = "Off"
use_try_shorthand = true

Datei anzeigen

@ -1,6 +1,9 @@
use advent_of_code::{strings::{convert_to_array, parsenumber}, KD};
#[allow(unused_imports)] #[allow(unused_imports)]
use advent_of_code::{include_data, include_example}; use advent_of_code::{include_data, include_example};
use advent_of_code::{
strings::{convert_to_array, parsenumber},
KD,
};
include_data!(DATA 2024 02); include_data!(DATA 2024 02);
@ -73,7 +76,7 @@ fn safe(record: Vec<u32>) -> bool {
match (direction, last > level) { match (direction, last > level) {
(KD::Top, false) | (KD::Bottom, true) => last = level, (KD::Top, false) | (KD::Bottom, true) => last = level,
(KD::Top, true) | (KD::Bottom, false) => errors += 1, (KD::Top, true) | (KD::Bottom, false) => errors += 1,
_=>unreachable!() _ => unreachable!(),
} }
} }
if errors > 0 { if errors > 0 {

Datei anzeigen

@ -1,4 +1,5 @@
use advent_of_code::{ use advent_of_code::{
find_character,
strings::{convert_to_array, line_to_char}, strings::{convert_to_array, line_to_char},
Kartesian, KartesianDirection, Map, Kartesian, KartesianDirection, Map,
}; };
@ -30,21 +31,6 @@ fn instructions_to_dir(instructions: &str) -> Vec<KartesianDirection> {
dirs dirs
} }
fn get_position(map: &Map<char>) -> Kartesian<usize> {
let maximum = map.size();
let mut coord = Kartesian::new(0, 0);
for x in 1..maximum.x - 1 {
for y in 1..maximum.y - 1 {
coord.x = x;
coord.y = y;
if map.get(coord) == Some(ROBOT) {
return coord;
}
}
}
unreachable!()
}
fn calc_sum(map: &Map<char>) -> usize { fn calc_sum(map: &Map<char>) -> usize {
let maximum = map.size(); let maximum = map.size();
let mut sum = 0; let mut sum = 0;
@ -63,7 +49,7 @@ fn main() {
let (maze, instructions): (&str, &str) = DATA.split_once("\n\n").unwrap(); let (maze, instructions): (&str, &str) = DATA.split_once("\n\n").unwrap();
let mut map = Map::from(convert_to_array::<_, _, '\n'>(maze, line_to_char)); let mut map = Map::from(convert_to_array::<_, _, '\n'>(maze, line_to_char));
let directions = instructions_to_dir(instructions); let directions = instructions_to_dir(instructions);
let mut position = get_position(&map); let mut position = find_character(&map, ROBOT);
let mut new; let mut new;
for direction in directions { for direction in directions {
new = position.move_dir(direction.vector(), direction).unwrap(); new = position.move_dir(direction.vector(), direction).unwrap();

100
src/bin/2024/16.rs Normale Datei
Datei anzeigen

@ -0,0 +1,100 @@
use std::{cmp::Ordering, collections::HashMap, u32};
use advent_of_code::{
find_character,
strings::{convert_to_array, line_to_char},
Kartesian, KartesianDirection, Map, KD,
};
#[allow(unused_imports)]
use advent_of_code_macros::{include_data, include_example};
include_data!(DATA 2024 16);
const START: Option<char> = Some('S');
const WALL: Option<char> = Some('#');
const END: Option<char> = Some('E');
const SPACE: Option<char> = Some('.');
fn new_score(old_score: u32, old: KD, new: KD) -> u32 {
old_score
+ if new == old {
1
} else if old == new.neg() {
2001
} else {
1001
}
}
fn sorter(a: &(Kartesian<usize>, KartesianDirection, u32, Kartesian<usize>), b: &(Kartesian<usize>, KartesianDirection, u32, Kartesian<usize>)) -> Ordering {
a.2.cmp(&b.2).reverse()
}
fn search_end(map: &Map<char>, startpos: Kartesian<usize>, last_dir: KartesianDirection) -> u32 {
let mut posmap: HashMap<Kartesian<usize>, u32> = HashMap::new();
let mut branches = Vec::with_capacity(200);
branches.push((startpos, last_dir, 0, startpos));
let mut vmap = map.clone();
let mut best = u32::MAX;
loop {
let (newpos, old_dir, score, oldpos) = match branches.pop() {
Some(b) => b,
None => break,
};
if !posmap.contains_key(&newpos) {
posmap.insert(newpos, score);
} else {
if score > *posmap.get(&newpos).unwrap() {
continue;
}
posmap.insert(newpos, score);
}
println!("moved {} with increased score {}", old_dir, score);
vmap.set(
newpos,
match old_dir {
KartesianDirection::Left => '←',
KartesianDirection::Top => '↑',
KartesianDirection::Right => '→',
KartesianDirection::Bottom => '↓',
_ => unreachable!(),
},
);
for dir in KD::iter(false, false, true) {
let after_move = newpos.move_dir(dir.vector(), dir).unwrap();
match map.get(after_move) {
WALL => {},
END => {
if best > new_score(score, old_dir, dir) {
best = new_score(score, old_dir, dir);
}
break;
},
SPACE | START => {
let added = new_score(score, old_dir, dir);
branches.push((after_move, dir, added, newpos));
},
_ => unreachable!(),
}
}
branches.sort_by(sorter);
}
print!("{}", vmap);
best
}
fn main() {
let map = Map::from(convert_to_array::<_, _, '\n'>(DATA, line_to_char));
//println!("Startmap: \n{}", map);
let deer = find_character(&map, 'S');
let best = search_end(&map, deer, KartesianDirection::Right);
println!(
"Best Score is: {}",
best
)
}
#[cfg(test)]
mod test {
use super::*;
}

Datei anzeigen

@ -1,5 +1,7 @@
use std::fmt::Display; use std::fmt::Display;
use crate::enum_alias;
use super::{Kartesian, KartesianIterator}; use super::{Kartesian, KartesianIterator};
use num::*; use num::*;
@ -17,6 +19,20 @@ pub enum KartesianDirection {
BottomRight, BottomRight,
} }
impl KartesianDirection {
enum_alias!(KartesianDirection, NorthWest, TopLeft);
enum_alias!(KartesianDirection, North, Top);
enum_alias!(KartesianDirection, Up, Top);
enum_alias!(KartesianDirection, NorthEast, TopRight);
enum_alias!(KartesianDirection, West, Left);
enum_alias!(KartesianDirection, Center, None);
enum_alias!(KartesianDirection, East, Right);
enum_alias!(KartesianDirection, SouthWest, BottomLeft);
enum_alias!(KartesianDirection, South, Bottom);
enum_alias!(KartesianDirection, Down, Bottom);
enum_alias!(KartesianDirection, SouthEast, BottomLeft);
}
impl KartesianDirection { impl KartesianDirection {
pub fn vector<T: Integer>(self) -> Kartesian<T> { pub fn vector<T: Integer>(self) -> Kartesian<T> {
Kartesian { Kartesian {

Datei anzeigen

@ -108,12 +108,12 @@ impl<T: Display + Copy + Default> Display for Map<T> {
for v in row.iter() { for v in row.iter() {
v.fmt(f)? v.fmt(f)?
} }
for _ in row.len()..=self.maximum.y { for _ in row.len()..self.maximum.y {
T::default().fmt(f)? T::default().fmt(f)?
} }
println!() println!()
} }
for _ in self.data.len()..=self.maximum.x { for _ in self.data.len()..self.maximum.x {
for _ in 0..self.maximum.y { for _ in 0..self.maximum.y {
T::default().fmt(f)? T::default().fmt(f)?
} }

Datei anzeigen

@ -135,3 +135,18 @@ impl<T: Clone + Copy> From<Vec<Vec<T>>> for Map<T> {
} }
} }
} }
pub fn find_character<T: Clone + Copy + Default + PartialEq>(map: &Map<T>, character: T) -> Kartesian<usize> {
let maximum = map.size();
let mut coord = Kartesian::new(0, 0);
for x in 1..maximum.x - 1 {
for y in 1..maximum.y - 1 {
coord.x = x;
coord.y = y;
if map.get(coord) == Some(character) {
return coord;
}
}
}
unreachable!("This function does not expect an non-existing character");
}

Datei anzeigen

@ -5,32 +5,23 @@ pub trait MaximumFromMap<T: Integer> {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<T>; fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<T>;
} }
impl MaximumFromMap<u32> for Kartesian<u32> { macro_rules! impl_maximum {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<u32> { ($type:ident) => {
impl MaximumFromMap<$type> for Kartesian<$type> {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<$type> {
Kartesian { Kartesian {
x: map.len().to_u32().unwrap(), x: map.len() as $type,
y: map[0].len().to_u32().unwrap(), y: map[0].len() as $type,
} }
} }
} }
};
impl MaximumFromMap<u64> for Kartesian<u64> {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<u64> {
Kartesian {
x: map.len().to_u64().unwrap(),
y: map[0].len().to_u64().unwrap(),
}
}
}
impl MaximumFromMap<u128> for Kartesian<u128> {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<u128> {
Kartesian {
x: map.len().to_u128().unwrap(),
y: map[0].len().to_u128().unwrap(),
}
}
} }
impl_maximum!(u8);
impl_maximum!(u16);
impl_maximum!(u32);
impl_maximum!(u64);
impl_maximum!(u128);
impl MaximumFromMap<usize> for Kartesian<usize> { impl MaximumFromMap<usize> for Kartesian<usize> {
fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<usize> { fn maximum<U>(map: &Vec<Vec<U>>) -> Kartesian<usize> {

Datei anzeigen

@ -18,10 +18,6 @@ pub use traits::*;
pub type KD = KartesianDirection; pub type KD = KartesianDirection;
pub trait ToCoords: Copy {
fn to_coords(self) -> Kartesian<usize>;
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Kartesian<T> pub struct Kartesian<T>
where where
@ -37,42 +33,6 @@ impl<T: Integer> Kartesian<T> {
} }
} }
impl ToCoords for Kartesian<u8> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
}
impl ToCoords for Kartesian<u16> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
}
impl ToCoords for Kartesian<u32> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
}
impl ToCoords for Kartesian<u64> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
}
impl ToCoords for Kartesian<u128> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
}
impl ToCoords for Kartesian<usize> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x, y: self.y }
}
}
fn wrap<T: Integer + Rem + MaximumValue + From<u32> + Copy + MaximumValue + Display, const FACTOR: u32>(v: T, max: T) -> T { fn wrap<T: Integer + Rem + MaximumValue + From<u32> + Copy + MaximumValue + Display, const FACTOR: u32>(v: T, max: T) -> T {
if v < max { if v < max {
v v

Datei anzeigen

@ -88,7 +88,6 @@ fn diff_dir() {
#[test] #[test]
fn moving_wrapping() { fn moving_wrapping() {
/*
let max: Kartesian<u32> = Kartesian::new(10, 10); let max: Kartesian<u32> = Kartesian::new(10, 10);
let mut pos = Kartesian::new(0, 0); let mut pos = Kartesian::new(0, 0);
let velocity = Velocity::new(1, 1, KartesianDirection::BottomRight); let velocity = Velocity::new(1, 1, KartesianDirection::BottomRight);
@ -98,7 +97,6 @@ fn moving_wrapping() {
pos = pos.wrapping_move_velocity(velocity, max); pos = pos.wrapping_move_velocity(velocity, max);
} }
assert_eq!(pos, Kartesian::new(0, 0)); assert_eq!(pos, Kartesian::new(0, 0));
*/
let max = Kartesian::<u32>::new(7, 11); let max = Kartesian::<u32>::new(7, 11);
assert_eq!(Kartesian::new(2, 0).wrapping_move_velocity(Velocity::new(1, 3, KartesianDirection::TopLeft), max), Kartesian::new(1, 9)); assert_eq!(Kartesian::new(2, 0).wrapping_move_velocity(Velocity::new(1, 3, KartesianDirection::TopLeft), max), Kartesian::new(1, 9));
assert_eq!(Kartesian::new(4, 2).wrapping_move_velocity(Velocity::new(3, 2, KartesianDirection::TopRight), max), Kartesian::new(1, 4)) assert_eq!(Kartesian::new(4, 2).wrapping_move_velocity(Velocity::new(3, 2, KartesianDirection::TopRight), max), Kartesian::new(1, 4))

Datei anzeigen

@ -1,9 +1,15 @@
use num::*; use num::*;
macro_rules! predefined_const { use crate::predefined_const;
($trait_name:ident, $const:ident, $t:ty) => {
impl $trait_name for $t { use super::Kartesian;
const $const: $t = <$t>::$const;
macro_rules! to_coords_impl {
($subtype:ident) => {
impl ToCoords for Kartesian<$subtype> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x as usize, y: self.y as usize }
}
} }
}; };
} }
@ -41,3 +47,19 @@ predefined_const!(MinimumValue, MIN, i32);
predefined_const!(MinimumValue, MIN, i64); predefined_const!(MinimumValue, MIN, i64);
predefined_const!(MinimumValue, MIN, i128); predefined_const!(MinimumValue, MIN, i128);
predefined_const!(MinimumValue, MIN, isize); predefined_const!(MinimumValue, MIN, isize);
pub trait ToCoords: Copy {
fn to_coords(self) -> Kartesian<usize>;
}
to_coords_impl!(u8);
to_coords_impl!(u16);
to_coords_impl!(u32);
to_coords_impl!(u64);
to_coords_impl!(u128);
impl ToCoords for Kartesian<usize> {
fn to_coords(self) -> Kartesian<usize> {
Kartesian { x: self.x, y: self.y }
}
}

Datei anzeigen

@ -65,3 +65,24 @@ pub enum ExtendedOption<T> {
Some(T), Some(T),
None, None,
} }
#[macro_export]
macro_rules! enum_alias {
($enum:ident, $alias:ident, $target:ident) => {
#[allow(non_upper_case_globals)]
pub const $alias: $enum = <$enum>::$target;
};
($visibility:vis $enum:ident, $alias:ident, $target:ident) => {
#[allow(non_upper_case_globals)]
$visibility const $alias: $enum = <$enum>::$target;
};
}
#[macro_export]
macro_rules! predefined_const {
($trait_name:ident, $const:ident, $t:ty) => {
impl $trait_name for $t {
const $const: $t = <$t>::$const;
}
};
}