Jake Fenton 1 рік тому
батько
коміт
6b9177cce8
2 змінених файлів з 127 додано та 0 видалено
  1. 122 0
      src/bin/08.rs
  2. 5 0
      src/examples/08.txt

+ 122 - 0
src/bin/08.rs

@@ -0,0 +1,122 @@
+fn or_bitrow(first: &Vec<bool>, second: &Vec<bool>) -> Vec<bool> {
+    first.iter().zip(second.iter().rev()).map(|(l, r)| *l || *r).collect()
+}
+
+fn look_down_treeline(line: &Vec<u32>) -> Vec<bool> {
+    let (ltr_viz, _ltr_biggest) = line.iter().skip(1).fold((vec![true], line[0]), |mut acc, el| if *el > acc.1 { acc.0.push(true); (acc.0, *el)} else {acc.0.push(false); (acc.0, acc.1)});
+    // right to left
+    let (rtl_viz, _rtl_biggest) = line.iter().rev().skip(1).fold((vec![true], *(line.last().unwrap())), |mut acc, el| if *el > acc.1 { acc.0.push(true); (acc.0, *el)} else {acc.0.push(false); (acc.0, acc.1)});
+
+    let thing = or_bitrow(&ltr_viz, &rtl_viz);
+    thing
+}
+
+pub fn part_one(input: &str) -> Option<u32> {
+    let trees: Vec<Vec<u32>> = 
+    input.lines()
+        .map(|line| line.chars()
+            .map(|c| c.to_digit(10).unwrap()).collect()
+        ).collect();
+
+    let mut bitfield: Vec<Vec<bool>> = (0..trees.len()).map(|_| (0..trees[0].len()).map(|_| false).collect()).collect();
+
+    for (row_idx, row) in (&trees).iter().enumerate() {
+        let mut rowtreeline = or_bitrow(&bitfield[row_idx], &look_down_treeline(row));
+        // dunno why the rows are reversed, but they are
+        rowtreeline.reverse();
+        bitfield[row_idx] = rowtreeline;
+        
+    }
+
+    for col in 0..trees[0].len() {
+        let column: Vec<u32> = trees.iter().map(|row| *(row.get(col).unwrap())).collect();
+        let seen_trees = look_down_treeline(&column);
+
+        for row_idx in 0..trees.len() {
+            bitfield[row_idx][col] |= seen_trees[row_idx];
+        }
+    }
+
+    let visible = bitfield.iter().fold(0, |acc, row| acc + row.iter().fold(0, |acc, tree| if *tree { acc + 1} else { acc}));
+    Some(visible)
+}
+
+fn look_down_single_row<'a, I>(trees: I, height: u32) -> u32 where I: Iterator<Item=&'a u32> {
+    let mut seen = 0;
+    for tree in trees {
+        seen += 1;
+        if *tree >= height {
+            break;
+        }
+    }
+
+    seen
+}
+
+pub fn get_scenic_score_for_tree(row: usize, col: usize, trees: &Vec<Vec<u32>>) -> u32 {
+    let our_tree = trees[row][col];
+    let mut our_score = 1;
+    let rowlen = trees[0].len();
+
+    if col < rowlen - 1 {
+        let right = &trees[row][col+1..rowlen];
+        our_score *= look_down_single_row(right.iter(), our_tree);
+    } else { return 0 }
+    if 0 < col { 
+        let left = &trees[row][0..col];
+        our_score *= look_down_single_row(left.iter().rev(), our_tree);
+    } else { return 0}
+    if row > 0 {
+        let up: Vec<u32> = (0..row).map(|idx| trees[idx][col]).collect();
+        our_score *= look_down_single_row(up.iter().rev(), our_tree);
+    } else { return 0}
+    if row < trees.len() - 1 {
+        let down: Vec<u32> = (row+1..rowlen).map(|idx| trees[idx][col]).collect();
+        our_score *= look_down_single_row(down.iter(), our_tree);
+    } else { return 0}
+    our_score
+}
+
+pub fn part_two(input: &str) -> Option<u32> {
+    let trees: Vec<Vec<u32>> = 
+    input.lines()
+        .map(|line| line.chars()
+            .map(|c| c.to_digit(10).unwrap()).collect()
+        ).collect();
+
+
+    let mut best: u32 = 0;
+
+    for row_idx in 0..trees.len() {
+        for col_idx in 0..trees[0].len() {
+            let this_tree = get_scenic_score_for_tree(row_idx, col_idx, &trees);
+            if this_tree > best {
+                best = this_tree;
+            }
+        }
+    }
+    Some(best)
+}
+
+fn main() {
+    let input = &advent_of_code::read_file("inputs", 8);
+    advent_of_code::solve!(1, part_one, input);
+    advent_of_code::solve!(2, part_two, input);
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_part_one() {
+        let input = advent_of_code::read_file("examples", 8);
+        assert_eq!(part_one(&input), Some(21));
+    }
+
+    #[test]
+    fn test_part_two() {
+        let input = advent_of_code::read_file("examples", 8);
+        assert_eq!(part_two(&input), Some(8));
+    }
+}

+ 5 - 0
src/examples/08.txt

@@ -0,0 +1,5 @@
+30373
+25512
+65332
+33549
+35390