Compare commits
4 Commits
0e5d98d1bc
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 85de6b1539 | |||
| 944faf2159 | |||
| d25a45cb52 | |||
| 2d34e77b13 |
61
src/day18.rs
61
src/day18.rs
@@ -1,10 +1,9 @@
|
|||||||
use std::{
|
use std::{collections::VecDeque, fs::read_to_string};
|
||||||
collections::{HashMap, HashSet, VecDeque},
|
|
||||||
fs::read_to_string,
|
|
||||||
};
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use crate::utils::grid::Grid;
|
||||||
|
|
||||||
pub fn day_main() {
|
pub fn day_main() {
|
||||||
let input = read_to_string("input/day18.txt").unwrap();
|
let input = read_to_string("input/day18.txt").unwrap();
|
||||||
let input = input.trim();
|
let input = input.trim();
|
||||||
@@ -18,30 +17,33 @@ fn part1(input: &str) -> RiddleResult {
|
|||||||
solve1(input, 1024, 70)
|
solve1(input, 1024, 70)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve1(input: &str, n: usize, coord_max: i32) -> usize {
|
fn solve1(input: &str, n: usize, coord_max: i64) -> usize {
|
||||||
let points = parse(input);
|
let points = parse(input);
|
||||||
sp(&points[..n], coord_max).unwrap()
|
sp(&points[..n], coord_max).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sp(points: &[(i32, i32)], coord_max: i32) -> Option<usize> {
|
fn sp(points: &[(i64, i64)], coord_max: i64) -> Option<usize> {
|
||||||
let pointss: HashSet<&(i32, i32)> = HashSet::from_iter(points);
|
let mut pcheck = Grid::from_default(coord_max + 1, coord_max + 1);
|
||||||
let mut visited = HashMap::new();
|
for p in points {
|
||||||
|
pcheck.set(*p, true);
|
||||||
|
}
|
||||||
|
let mut visited = Grid::from_default(coord_max + 1, coord_max + 1);
|
||||||
let mut queue = VecDeque::from_iter([(0, 0, 0)]);
|
let mut queue = VecDeque::from_iter([(0, 0, 0)]);
|
||||||
while let Some((x, y, c)) = queue.pop_front() {
|
while let Some((x, y, c)) = queue.pop_front() {
|
||||||
if x == coord_max && y == coord_max {
|
if x == coord_max && y == coord_max {
|
||||||
return Some(c);
|
return Some(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if visited.contains_key(&(x, y)) {
|
if visited.get((x, y)) == Some(&true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
visited.insert((x, y), c);
|
visited.set((x, y), true);
|
||||||
|
|
||||||
for (dx, dy) in [(0, 1), (1, 0), (0, -1), (-1, 0)] {
|
for (dx, dy) in [(0, 1), (1, 0), (0, -1), (-1, 0)] {
|
||||||
let (a, b) = (x + dx, y + dy);
|
let (a, b) = (x + dx, y + dy);
|
||||||
if (0..=coord_max).contains(&a)
|
if (0..=coord_max).contains(&a)
|
||||||
&& (0..=coord_max).contains(&b)
|
&& (0..=coord_max).contains(&b)
|
||||||
&& !pointss.contains(&(a, b))
|
&& pcheck.get((a, b)) == Some(&false)
|
||||||
{
|
{
|
||||||
queue.push_back((a, b, c + 1));
|
queue.push_back((a, b, c + 1));
|
||||||
}
|
}
|
||||||
@@ -50,7 +52,7 @@ fn sp(points: &[(i32, i32)], coord_max: i32) -> Option<usize> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(input: &str) -> Vec<(i32, i32)> {
|
fn parse(input: &str) -> Vec<(i64, i64)> {
|
||||||
input
|
input
|
||||||
.trim()
|
.trim()
|
||||||
.lines()
|
.lines()
|
||||||
@@ -67,14 +69,39 @@ fn part2(input: &str) -> String {
|
|||||||
solve2(input, 1024, 70)
|
solve2(input, 1024, 70)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve2(input: &str, fixed: usize, max_coord: i32) -> String {
|
fn solve2(input: &str, fixed: usize, max_coord: i64) -> String {
|
||||||
let points = parse(input);
|
let points = parse(input);
|
||||||
for i in fixed..points.len() {
|
|
||||||
if let None = sp(&points[..=i], max_coord) {
|
// we want the first point with which there is no shortest path
|
||||||
return format!("{},{}", points[i].0, points[i].1);
|
let mut i = fixed;
|
||||||
|
let mut jump = (points.len() - fixed) / 2;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let mut loops = 0;
|
||||||
|
loop {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
loops += 1;
|
||||||
|
}
|
||||||
|
let l = sp(&points[..i - 1], max_coord);
|
||||||
|
let r = sp(&points[..i], max_coord);
|
||||||
|
if l.is_some() && r.is_none() {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
let iters_needed = i - fixed;
|
||||||
|
dbg!(loops, iters_needed);
|
||||||
|
}
|
||||||
|
return format!("{},{}", points[i - 1].0, points[i - 1].1);
|
||||||
|
}
|
||||||
|
if l.is_some() {
|
||||||
|
i += jump;
|
||||||
|
} else {
|
||||||
|
i -= jump;
|
||||||
|
}
|
||||||
|
jump /= 2;
|
||||||
|
if jump == 0 {
|
||||||
|
jump += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ fn part1(input: &str) -> RiddleResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let sets = sets.iter().unique().collect_vec();
|
let sets = sets.iter().unique().collect_vec();
|
||||||
dbg!(sets.len());
|
|
||||||
sets.iter()
|
sets.iter()
|
||||||
.filter(|set| set.iter().any(|t| t.starts_with("t")))
|
.filter(|set| set.iter().any(|t| t.starts_with("t")))
|
||||||
.count()
|
.count()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ fn main() {
|
|||||||
(15, day15::day_main),
|
(15, day15::day_main),
|
||||||
(16, day16::day_main),
|
(16, day16::day_main),
|
||||||
(17, day17::day_main),
|
(17, day17::day_main),
|
||||||
|
(18, day18::day_main),
|
||||||
(19, day19::day_main),
|
(19, day19::day_main),
|
||||||
(21, day21::day_main),
|
(21, day21::day_main),
|
||||||
(22, day22::day_main),
|
(22, day22::day_main),
|
||||||
@@ -29,17 +30,20 @@ fn main() {
|
|||||||
(23, day23::day_main),
|
(23, day23::day_main),
|
||||||
(24, day24::day_main),
|
(24, day24::day_main),
|
||||||
(25, day25::day_main),
|
(25, day25::day_main),
|
||||||
(18, day18::day_main),
|
|
||||||
// PLACEHOLDER
|
// PLACEHOLDER
|
||||||
]);
|
]);
|
||||||
let day: Option<u8> = args().nth(1).and_then(|a| a.parse().ok());
|
let day: Option<u8> = args().nth(1).and_then(|a| a.parse().ok());
|
||||||
let Some(day) = day else {
|
let Some(day) = day else {
|
||||||
|
let start = Instant::now();
|
||||||
mains
|
mains
|
||||||
.iter()
|
.iter()
|
||||||
.sorted_by_key(|entry| entry.0)
|
.sorted_by_key(|entry| entry.0)
|
||||||
.for_each(|(d, f)| {
|
.for_each(|(d, f)| {
|
||||||
run(*d, f);
|
run(*d, f);
|
||||||
});
|
});
|
||||||
|
let duration = start.elapsed();
|
||||||
|
println!();
|
||||||
|
println!("{COLOR}{ITALIC}All tasks took {duration:?}{RESET_FORMATTING}");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user