Skip to content

Commit

Permalink
18(casual one) and slight utils refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
illkle committed Dec 18, 2024
1 parent 48acc36 commit 5827319
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 16 deletions.
25 changes: 25 additions & 0 deletions data/examples/18.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
5,4
4,2
4,5
3,0
2,1
6,3
2,4
1,5
0,6
3,3
2,6
5,1
1,2
5,5
2,5
6,5
1,4
0,4
6,4
1,1
6,1
1,0
0,5
1,6
2,0
4 changes: 2 additions & 2 deletions src/bin/06.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn simulate(
}

pub fn part_one(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);

let binding = map.find_char('^');
let start_pos = binding.get(0).unwrap();
Expand All @@ -105,7 +105,7 @@ pub fn part_one(input: &str) -> Option<u32> {
}

pub fn part_two(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);
let binding = map.find_char('^');
let start_pos = binding.get(0).unwrap();

Expand Down
6 changes: 3 additions & 3 deletions src/bin/08.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use advent_of_code::{CoordMap, Coords};
advent_of_code::solution!(8);

pub fn part_one(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);

let antennas: Vec<(&Coords, &char)> = map.iter().filter(|(_, v)| **v != '.').collect();

Expand Down Expand Up @@ -56,8 +56,8 @@ pub fn part_one(input: &str) -> Option<u32> {
}

pub fn part_two(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let mut vizmap = CoordMap::new(input);
let map = CoordMap::new_from_map(input);
let mut vizmap = CoordMap::new_from_map(input);

let antennas: Vec<(&Coords, &char)> = map.iter().filter(|(_, v)| **v != '.').collect();

Expand Down
4 changes: 2 additions & 2 deletions src/bin/10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn is_next_number(a: &char, b: &char) -> bool {
}

pub fn part_one(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);

let count: usize = map
.find_char('0')
Expand Down Expand Up @@ -60,7 +60,7 @@ struct PathBuilder {
}

pub fn part_two(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);

let count: usize = map
.find_char('0')
Expand Down
4 changes: 2 additions & 2 deletions src/bin/12.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn find_zones(map: &CoordMap) -> Vec<Zone> {
}

pub fn part_one(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);
let zones = find_zones(&map);

let mut acc: u32 = 0;
Expand Down Expand Up @@ -188,7 +188,7 @@ fn sort_borders_into_sides(
}

pub fn part_two(input: &str) -> Option<u32> {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);
let zones = find_zones(&map);

let mut acc: u32 = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/bin/14.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub fn part_two(input: &str) -> Option<u32> {
let percent_symm = x_symm_coeff as f64 / (robots.len() as f64);

if percent_symm > 0.2 {
let mut map = CoordMap::new("");
let mut map = CoordMap::new_from_map("");

for r in moved {
map.set(&Coords { x: r.x, y: r.y }, 'R');
Expand Down
4 changes: 2 additions & 2 deletions src/bin/15.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ enum Move {
fn create_map(input: &str) -> (CoordMap, Vec<Move>) {
let spl: Vec<&str> = input.split("\n\n").collect();

let map = CoordMap::new(&spl[0]);
let map = CoordMap::new_from_map(&spl[0]);

(
map,
Expand Down Expand Up @@ -200,7 +200,7 @@ pub fn part_two(input: &str) -> Option<u32> {

let (mut map, commands) = create_map(&inp);

map.viz(&'.');
map.viz('.');

for mv in commands {
let cloned_map = map.clone();
Expand Down
2 changes: 1 addition & 1 deletion src/bin/16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct Position {
}

fn solver(input: &str, store_visited: bool) -> (u32, Vec<Position>) {
let map = CoordMap::new(input);
let map = CoordMap::new_from_map(input);

let start = map.find_char('S');

Expand Down
91 changes: 91 additions & 0 deletions src/bin/18.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
use advent_of_code::{extract_numbers, CoordMap, Coords};

advent_of_code::solution!(18);

pub fn part_one(input: &str) -> Option<u32> {
//let (max, b) = (6, 12);
let (max, b) = (70, 1024);

let mut map = CoordMap::new_max(max, max);
for (i, line) in input.lines().enumerate() {
if i >= b {
break;
}
let c = extract_numbers(line);

map.set(
&Coords {
x: c[0] as i32,
y: c[1] as i32,
},
'#',
);
}

map.shortest_steps(&Coords { x: 0, y: 0 }, &Coords { x: max, y: max }, |c| {
c == None
})
}

pub fn part_two(input: &str) -> Option<String> {
//let (max, _) = (6, 12);
let (max, _) = (70, 1024);

let lines: Vec<&str> = input.lines().collect();
let ll = lines.len();

let mut range = (0, ll);

while range.1 - range.0 > 1 {
let mid = (range.1 - range.0) / 2;

let mut map = CoordMap::new_max(max, max);
for (i, line) in input.lines().enumerate() {
if i >= range.0 + mid {
break;
}
let c = extract_numbers(line);

map.set(
&Coords {
x: c[0] as i32,
y: c[1] as i32,
},
'#',
);
}

map.viz('.');

let v = map.shortest_steps(&Coords { x: 0, y: 0 }, &Coords { x: max, y: max }, |c| {
c == None
});

if v.is_none() {
range = (range.0, mid + range.0);
} else {
range = (mid + range.0, range.1);
}
}

let a = lines[range.0];

Some(a.to_string())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(22));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some("6,1".to_owned()));
}
}
93 changes: 90 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ pub mod template;

// Use this file to add helper functions and additional modules.

fn divide_range(start: i64, end: i64, n: i64) -> Vec<(i64, i64)> {
if n <= 0 {
return vec![];
}

let range_size = (end - start) as f64;
let chunk_size = (range_size / n as f64).ceil() as i64;

(0..n)
.map(|i| {
let chunk_start = start + (i * chunk_size);
let chunk_end = (start + ((i + 1) * chunk_size)).min(end);
(chunk_start, chunk_end)
})
.collect()
}

pub fn extract_numbers(text: &str) -> Vec<f64> {
let re = Regex::new(r"-?\d+(?:\.\d+)?").unwrap();

Expand Down Expand Up @@ -108,7 +125,23 @@ pub struct CoordMap {
}

impl CoordMap {
pub fn new(input: &str) -> CoordMap {
pub fn new_max(x_max: i32, y_max: i32) -> CoordMap {
return CoordMap {
map: HashMap::new(),
y_len: y_max + 1,
x_len: x_max + 1,
};
}

pub fn new_len(x_len: i32, y_len: i32) -> CoordMap {
return CoordMap {
map: HashMap::new(),
y_len: y_len,
x_len: x_len,
};
}

pub fn new_from_map(input: &str) -> CoordMap {
let lines: Vec<&str> = input.lines().collect();
let mut c = CoordMap {
map: HashMap::new(),
Expand All @@ -131,6 +164,7 @@ impl CoordMap {
}
return c;
}

pub fn set(&mut self, k: &Coords, v: char) {
self.map.insert(k.clone(), v);
}
Expand Down Expand Up @@ -181,8 +215,8 @@ impl CoordMap {
);
}

pub fn viz(&self, empty: &char) {
print!("{}", self.viz_to_string(empty));
pub fn viz(&self, empty: char) {
print!("{}", self.viz_to_string(&empty));
}

pub fn viz_to_string(&self, empty: &char) -> String {
Expand Down Expand Up @@ -222,4 +256,57 @@ impl CoordMap {
pub fn coord_exists(&self, c: &Coords) -> bool {
self.get(c).is_some()
}

pub fn shortest_steps(
&self,
from: &Coords,
to: &Coords,
can_step_on: fn(Option<&char>) -> bool,
) -> Option<u32> {
let mut best_steps_to_pos: HashMap<Coords, u32> = HashMap::new();

let mut q = vec![(from.clone(), 0)];

let mut min_to_end = 100000000;

while q.len() > 0 {
let (position, steps) = q.pop().unwrap();

let best = best_steps_to_pos.get(&position);

if best.is_some() && steps >= *best.unwrap() {
continue;
} else {
best_steps_to_pos.insert(position.clone(), steps);
}

if position == *to {
continue;
}

let adj = self.get_adjacent_xy(&position);
let possible: Vec<&Coords> = adj
.iter()
.filter(|c| {
if c.x < 0 || c.y < 0 || c.x >= self.x_len || c.y >= self.y_len {
return false;
}

let best = best_steps_to_pos.get(c);

if best.is_some() && steps + 1 >= *best.unwrap() {
return false;
}
let letter = self.get(c);
return can_step_on(letter);
})
.collect();

for item in possible {
q.push((item.clone(), steps + 1));
}
}

best_steps_to_pos.get(to).copied()
}
}

0 comments on commit 5827319

Please sign in to comment.