You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.2 KiB

const INPUT: &str = include_str!("../../data/day3");
struct Forest {
pub rows: usize,
stride: usize,
trees: Vec<bool>,
}
impl Forest {
fn parse(text: &str) -> Self {
let first_line = text.lines().next().unwrap();
let stride = first_line.len();
let mut trees = Vec::new();
let mut rows = 0;
for line in text.lines() {
assert_eq!(line.len(), stride);
trees.extend(line.as_bytes().iter().map(|&c| c == b'#'));
rows += 1;
}
Self {
rows,
stride,
trees,
}
}
fn is_tree(&self, row: usize, column: u64) -> bool {
assert!(row < self.rows);
let column = (column % self.stride as u64) as usize;
self.trees[column + row * self.stride]
}
fn hit_trees(&self, slope_y: usize, slope_x: u64) -> u64 {
let mut row = slope_y;
let mut col = slope_x;
let mut hits = 0;
while row < self.rows {
if self.is_tree(row, col) {
hits += 1;
}
row += slope_y;
col += slope_x;
}
hits
}
}
const TEST_SLOPES: &[(usize, u64)] = &[
(1, 1),
(1, 3),
(1, 5),
(1, 7),
(2, 1),
];
fn main() {
let forest = Forest::parse(INPUT);
println!("Hit trees: {}", forest.hit_trees(1, 3));
println!(
"Hit product: {}",
TEST_SLOPES.iter().map(|(slope_y, slope_x)| {
forest.hit_trees(*slope_y, *slope_x)
}).product::<u64>(),
);
}