Compare commits
No commits in common. "dijkastra" and "main" have entirely different histories.
7 changed files with 5 additions and 234 deletions
46
.vscode/aoc.code-snippets
vendored
46
.vscode/aoc.code-snippets
vendored
|
@ -1,46 +0,0 @@
|
||||||
{
|
|
||||||
// Place your advent-of-code-2023 workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and
|
|
||||||
// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope
|
|
||||||
// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is
|
|
||||||
// used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
|
|
||||||
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders.
|
|
||||||
// Placeholders with the same ids are connected.
|
|
||||||
// Example:
|
|
||||||
// "Print to console": {
|
|
||||||
// "scope": "javascript,typescript",
|
|
||||||
// "prefix": "log",
|
|
||||||
// "body": [
|
|
||||||
// "console.log('$1');",
|
|
||||||
// "$2"
|
|
||||||
// ],
|
|
||||||
// "description": "Log output to console"
|
|
||||||
// }
|
|
||||||
"Day template": {
|
|
||||||
"scope": "rust",
|
|
||||||
"prefix": "day",
|
|
||||||
"body": [
|
|
||||||
"use crate::utils::Day;",
|
|
||||||
"",
|
|
||||||
"#[derive(Debug, Default)]",
|
|
||||||
"pub struct Day$1 {",
|
|
||||||
"\tpub input: String,",
|
|
||||||
"}",
|
|
||||||
"",
|
|
||||||
"impl Day for Day$1 {",
|
|
||||||
"\tfn part1(&mut self) -> String {",
|
|
||||||
"\t\t",
|
|
||||||
"\t\t",
|
|
||||||
"\t\ttodo!()",
|
|
||||||
"\t}",
|
|
||||||
"",
|
|
||||||
"\tfn part2(&mut self) -> String {",
|
|
||||||
"\t\t",
|
|
||||||
"\t\t",
|
|
||||||
"\t\ttodo!()",
|
|
||||||
"\t}",
|
|
||||||
"}"
|
|
||||||
|
|
||||||
],
|
|
||||||
"description": "Creates a template for an AOC day"
|
|
||||||
}
|
|
||||||
}
|
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -21,7 +21,6 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
name = "advent"
|
name = "advent"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array2d",
|
|
||||||
"clru",
|
"clru",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -123,12 +122,6 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "array2d"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8b39cb2c1bf5a7c0dd097aa95ab859cf87dab5a4328900f5388942dc1889f74"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
|
@ -160,12 +160,11 @@ async fn main() {
|
||||||
let deviation = (((max - min).pow(2) / 16) as f64).sqrt() as u128;
|
let deviation = (((max - min).pow(2) / 16) as f64).sqrt() as u128;
|
||||||
let range = max - min;
|
let range = max - min;
|
||||||
let median = if timings.len() % 2 == 0 {
|
let median = if timings.len() % 2 == 0 {
|
||||||
(timings[timings.len() / 2 - 1] + timings[timings.len() / 2]).as_nanos() as f64
|
(timings[timings.len()/2-1]+timings[timings.len()/2]).as_nanos() as f64 / 2.0
|
||||||
/ 2.0
|
|
||||||
} else {
|
} else {
|
||||||
timings[timings.len() / 2].as_nanos() as f64
|
timings[timings.len()/2].as_nanos() as f64
|
||||||
};
|
};
|
||||||
|
|
||||||
let (avg, avg_units) = utils::unitify(avg as f64);
|
let (avg, avg_units) = utils::unitify(avg as f64);
|
||||||
let (max, max_units) = utils::unitify(max as f64);
|
let (max, max_units) = utils::unitify(max as f64);
|
||||||
let (min, min_units) = utils::unitify(min as f64);
|
let (min, min_units) = utils::unitify(min as f64);
|
||||||
|
|
|
@ -8,4 +8,4 @@ pub fn unitify(num: f64) -> (f64, &'static str) {
|
||||||
} else {
|
} else {
|
||||||
(num, "ns")
|
(num, "ns")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -12,7 +12,6 @@ scraper = "0.18.1"
|
||||||
reqwest = "0.11.22"
|
reqwest = "0.11.22"
|
||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
clru = "0.6.1"
|
clru = "0.6.1"
|
||||||
array2d = "0.3.2"
|
|
||||||
|
|
||||||
[dependencies.getrandom]
|
[dependencies.getrandom]
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
|
|
@ -1,171 +0,0 @@
|
||||||
use crate::utils::Day;
|
|
||||||
use array2d::Array2D;
|
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct Day17 {
|
|
||||||
pub input: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug)]
|
|
||||||
pub enum Direction {
|
|
||||||
North,
|
|
||||||
East,
|
|
||||||
South,
|
|
||||||
West,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct State {
|
|
||||||
cost: usize,
|
|
||||||
row: usize,
|
|
||||||
column: usize,
|
|
||||||
tentative_distance: Option<usize>,
|
|
||||||
last_direction: Option<Direction>,
|
|
||||||
moves_in_same_direction: Option<u8>,
|
|
||||||
prev: Option<(usize, usize)>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Day17 {
|
|
||||||
pub fn calculate_node(current: &State, node: &mut State, direction: Direction) {
|
|
||||||
let new_distance = current.tentative_distance.unwrap_or_default() + node.cost;
|
|
||||||
if node.tentative_distance.is_some_and(|d| d > new_distance) || node.tentative_distance.is_none() {
|
|
||||||
node.prev = Some((current.row, current.column));
|
|
||||||
node.tentative_distance = Some(new_distance);
|
|
||||||
node.last_direction = Some(
|
|
||||||
match (node.row as isize - current.row as isize, node.column as isize - current.column as isize) {
|
|
||||||
(0, -1) => Direction::West,
|
|
||||||
(0, 1) => Direction::East,
|
|
||||||
(1, 0) => Direction::South,
|
|
||||||
(-1, 0) => Direction::North,
|
|
||||||
_ => panic!()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
node.moves_in_same_direction = Some(match current.last_direction == node.last_direction {
|
|
||||||
true => current.moves_in_same_direction.unwrap() + 1,
|
|
||||||
false => 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Day for Day17 {
|
|
||||||
fn part1(&mut self) -> String {
|
|
||||||
let columns = self.input.find('\n').unwrap();
|
|
||||||
let rows = (self.input.len() + 1) / columns - 1;
|
|
||||||
|
|
||||||
let mut parsed = Array2D::from_iter_row_major(
|
|
||||||
self.input.split('\n').enumerate().flat_map(|(i, str)| {
|
|
||||||
str.chars().enumerate().map(move |(j, b)| State {
|
|
||||||
cost: b.to_digit(10).unwrap() as usize,
|
|
||||||
column: j,
|
|
||||||
row: i,
|
|
||||||
tentative_distance: None,
|
|
||||||
moves_in_same_direction: None,
|
|
||||||
last_direction: None,
|
|
||||||
prev: None
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
rows,
|
|
||||||
columns,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut unvisited = Vec::<(usize, usize)>::from_iter(
|
|
||||||
(0..columns).flat_map(|i| (0..rows).map(move |j| (i, j))),
|
|
||||||
);
|
|
||||||
let mut current_pos = (0usize, 0usize);
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let current = parsed[current_pos].clone();
|
|
||||||
|
|
||||||
if current.last_direction != Some(Direction::South)
|
|
||||||
&& !(current.last_direction == Some(Direction::North)
|
|
||||||
&& current.moves_in_same_direction == Some(2))
|
|
||||||
&& let Some(neighbor) = parsed.get_mut(current.row.wrapping_sub(1), current.column)
|
|
||||||
{
|
|
||||||
// Going north
|
|
||||||
Self::calculate_node(¤t, neighbor, Direction::North)
|
|
||||||
}
|
|
||||||
|
|
||||||
if current.last_direction != Some(Direction::West)
|
|
||||||
&& !(current.last_direction == Some(Direction::East)
|
|
||||||
&& current.moves_in_same_direction == Some(2))
|
|
||||||
&& let Some(neighbor) = parsed.get_mut(current.row, current.column + 1)
|
|
||||||
{
|
|
||||||
// Going east
|
|
||||||
Self::calculate_node(¤t, neighbor, Direction::East)
|
|
||||||
}
|
|
||||||
|
|
||||||
if current.last_direction != Some(Direction::North)
|
|
||||||
&& !(current.last_direction == Some(Direction::South)
|
|
||||||
&& current.moves_in_same_direction == Some(2))
|
|
||||||
&& let Some(neighbor) = parsed.get_mut(current.row + 1, current.column)
|
|
||||||
{
|
|
||||||
// Going south
|
|
||||||
Self::calculate_node(¤t, neighbor, Direction::South)
|
|
||||||
}
|
|
||||||
|
|
||||||
if current.last_direction != Some(Direction::East)
|
|
||||||
&& !(current.last_direction == Some(Direction::West)
|
|
||||||
&& current.moves_in_same_direction == Some(2))
|
|
||||||
&& let Some(neighbor) = parsed.get_mut(current.row, current.column.wrapping_sub(1))
|
|
||||||
{
|
|
||||||
// Going west
|
|
||||||
Self::calculate_node(¤t, neighbor, Direction::West)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current.column, current.row) == (columns - 1, rows - 1) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
unvisited.remove(
|
|
||||||
unvisited
|
|
||||||
.iter()
|
|
||||||
.find_position(|&&coords| coords == (current.row, current.column))
|
|
||||||
.unwrap()
|
|
||||||
.0,
|
|
||||||
);
|
|
||||||
current_pos = unvisited
|
|
||||||
.iter()
|
|
||||||
.filter_map(|&coords| {
|
|
||||||
parsed[coords]
|
|
||||||
.tentative_distance
|
|
||||||
.map(|distance| (coords.0, coords.1, distance))
|
|
||||||
})
|
|
||||||
.min_by_key(|x| x.2)
|
|
||||||
.map(|(row, column, _)| (row, column))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut path = Vec::<(usize, usize)>::new();
|
|
||||||
let mut cursor = (columns - 1, rows - 1);
|
|
||||||
|
|
||||||
while let Some(prev) = parsed[cursor].prev {
|
|
||||||
path.push(prev);
|
|
||||||
cursor = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y, row_iter) in parsed.rows_iter().enumerate() {
|
|
||||||
for (x, element) in row_iter.enumerate() {
|
|
||||||
if !path.contains(&(x, y)) {
|
|
||||||
print!("{}", element.cost);
|
|
||||||
} else {
|
|
||||||
print!("{}", match element.last_direction.as_ref() {
|
|
||||||
Some(Direction::North) => "^",
|
|
||||||
Some(Direction::East) => ">",
|
|
||||||
Some(Direction::South) => "v",
|
|
||||||
Some(Direction::West) => "<",
|
|
||||||
_ => "+"
|
|
||||||
}/*, element.moves_in_same_direction.unwrap_or_default() */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
parsed[(rows - 1, columns - 1)].tentative_distance.unwrap().to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part2(&mut self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(inline_const, let_chains)]
|
#![feature(inline_const)]
|
||||||
|
|
||||||
use std::{collections::HashMap, num::NonZeroUsize};
|
use std::{collections::HashMap, num::NonZeroUsize};
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ use day13::Day13;
|
||||||
use day14::Day14;
|
use day14::Day14;
|
||||||
use day15::Day15;
|
use day15::Day15;
|
||||||
use day16::Day16;
|
use day16::Day16;
|
||||||
use day17::Day17;
|
|
||||||
use day2::Day2;
|
use day2::Day2;
|
||||||
use day3::Day3;
|
use day3::Day3;
|
||||||
use day4::Day4;
|
use day4::Day4;
|
||||||
|
@ -33,7 +32,6 @@ pub mod day13;
|
||||||
pub mod day14;
|
pub mod day14;
|
||||||
pub mod day15;
|
pub mod day15;
|
||||||
pub mod day16;
|
pub mod day16;
|
||||||
pub mod day17;
|
|
||||||
pub mod day2;
|
pub mod day2;
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
|
@ -81,7 +79,6 @@ pub fn get_day(day: u8, input: String) -> Box<dyn Day> {
|
||||||
14 => Box::new(Day14 { input }),
|
14 => Box::new(Day14 { input }),
|
||||||
15 => Box::new(Day15 { input }),
|
15 => Box::new(Day15 { input }),
|
||||||
16 => Box::new(Day16 { input }),
|
16 => Box::new(Day16 { input }),
|
||||||
17 => Box::new(Day17 { input }),
|
|
||||||
_ => panic!("Invalid day #"),
|
_ => panic!("Invalid day #"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue