1
0

Compare commits

..

2 Commits

Author SHA1 Message Date
345b29278f extended the grid with parsing from string and added position iterator 2024-12-06 16:09:20 +01:00
2d3443907d made coordinate public 2024-12-06 15:36:07 +01:00
3 changed files with 64 additions and 25 deletions

View File

@@ -108,8 +108,8 @@ mod test {
#[test] #[test]
fn test1() { fn test1() {
assert!(valid_book(&vec![97, 5, 13], &HashSet::from([(97, 13)]))); assert!(valid_book(&[97, 5, 13], &HashSet::from([(97, 13)])));
assert!(!valid_book(&vec![13, 5, 97], &HashSet::from([(97, 13)]))); assert!(!valid_book(&[13, 5, 97], &HashSet::from([(97, 13)])));
assert_eq!(part1(TEST_INPUT), 143); assert_eq!(part1(TEST_INPUT), 143);
} }

View File

@@ -1,9 +1,9 @@
use std::{ use std::{
collections::{HashMap, HashSet}, collections::HashSet,
fs::read_to_string, fs::read_to_string,
}; };
use crate::utils::grid::Grid; use crate::utils::grid::{Coord, Grid};
pub fn day_main() { pub fn day_main() {
let input = read_to_string("input/day06.txt").unwrap(); let input = read_to_string("input/day06.txt").unwrap();
@@ -13,7 +13,6 @@ pub fn day_main() {
} }
type RiddleResult = usize; type RiddleResult = usize;
type Point = (i64, i64);
fn part1(input: &str) -> RiddleResult { fn part1(input: &str) -> RiddleResult {
let (m, pos) = parse(input); let (m, pos) = parse(input);
@@ -23,7 +22,7 @@ fn part1(input: &str) -> RiddleResult {
visited.len() visited.len()
} }
fn get_visited(m: &Grid<char>, mut pos: Point, mut dir: char) -> HashSet<Point> { fn get_visited(m: &Grid<char>, mut pos: Coord, mut dir: char) -> HashSet<Coord> {
let mut visited = HashSet::new(); let mut visited = HashSet::new();
while m.contains_key(pos) { while m.contains_key(pos) {
let (x, y) = pos; let (x, y) = pos;
@@ -60,25 +59,14 @@ fn part2(input: &str) -> RiddleResult {
.count() .count()
} }
fn parse(input: &str) -> (Grid<char>, Point) { fn parse(input: &str) -> (Grid<char>, Coord) {
let mut m = HashMap::new(); let mut m = Grid::parse(input);
let mut pos = None; let start = m.entries().find(|(_, c)| **c == '^').unwrap().0;
input.lines().enumerate().for_each(|(y, line)| { m[start] = '.';
line.char_indices().for_each(|(x, c)| { (m, start)
let x = x as i64;
let y = y as i64;
if c == '^' {
pos = Some((x, y));
m.insert((x, y), '.');
} else {
m.insert((x, y), c);
}
});
});
(Grid::from(m), pos.unwrap())
} }
fn is_loop(m: &Grid<char>, block: Point, mut pos: Point, mut dir: char) -> bool { fn is_loop(m: &Grid<char>, block: Coord, mut pos: Coord, mut dir: char) -> bool {
let mut visited = HashSet::new(); let mut visited = HashSet::new();
loop { loop {
let (x, y) = pos; let (x, y) = pos;

View File

@@ -4,13 +4,14 @@ use std::{
}; };
/// A grid structure, indexed by (x, y) tuples. The top-left coordinate is (0, 0). /// A grid structure, indexed by (x, y) tuples. The top-left coordinate is (0, 0).
#[derive(Eq, PartialEq, Debug)]
pub struct Grid<T> { pub struct Grid<T> {
content_width: i64, content_width: i64,
content_height: i64, content_height: i64,
content: Vec<T>, content: Vec<T>,
} }
type Coord = (i64, i64); pub type Coord = (i64, i64);
impl<T> Grid<T> { impl<T> Grid<T> {
pub fn from(mut source: HashMap<Coord, T>) -> Grid<T> { pub fn from(mut source: HashMap<Coord, T>) -> Grid<T> {
@@ -54,6 +55,34 @@ impl<T> Grid<T> {
pub fn contains_key(&self, c: Coord) -> bool { pub fn contains_key(&self, c: Coord) -> bool {
0 <= c.0 && c.0 < self.content_width && 0 <= c.1 && c.1 < self.content_height 0 <= c.0 && c.0 < self.content_width && 0 <= c.1 && c.1 < self.content_height
} }
pub fn entries(&self) -> impl Iterator<Item = (Coord, &T)> {
self.content.iter().enumerate().map(|(i, val)| {
(
(i as i64 % self.content_width, i as i64 / self.content_width),
val,
)
})
// .collect_vec()
}
}
impl Grid<char> {
pub fn parse(input: &str) -> Grid<char> {
let content_width = input.lines().next().unwrap().len();
let mut content_height = 0;
let mut content = vec![];
for line in input.lines() {
content_height += 1;
content.reserve(content_width);
line.chars().for_each(|v| content.push(v));
}
Grid {
content_width: content_width as i64,
content_height,
content,
}
}
} }
impl<T> Index<Coord> for Grid<T> { impl<T> Index<Coord> for Grid<T> {
@@ -73,9 +102,10 @@ impl<T> IndexMut<Coord> for Grid<T> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::collections::HashMap; use itertools::Itertools;
use super::Grid; use super::Grid;
use std::collections::HashMap;
#[test] #[test]
fn init_and_read() { fn init_and_read() {
@@ -90,6 +120,7 @@ mod test {
assert_eq!(&'.', grid.get((1, 0))); assert_eq!(&'.', grid.get((1, 0)));
assert_eq!(&'#', grid.get((1, 1))); assert_eq!(&'#', grid.get((1, 1)));
} }
#[test] #[test]
fn mutate_by_index() { fn mutate_by_index() {
let mut grid = generate(); let mut grid = generate();
@@ -106,4 +137,24 @@ mod test {
])); ]));
grid grid
} }
#[test]
fn from_str() {
let s = "..\n.x";
let m_str = Grid::parse(s);
let mut m_gen = generate();
m_gen[(1, 1)] = 'x';
assert_eq!(m_gen, m_str);
}
#[test]
fn entries() {
let v = vec![
((0, 0), &'.'),
((1, 0), &'.'),
((0, 1), &'.'),
((1, 1), &'.'),
];
assert_eq!(v, generate().entries().collect_vec());
}
} }