diff options
-rw-r--r-- | 2022/nim/day08/src/main.nim | 66 | ||||
-rw-r--r-- | 2022/rust/day08/Cargo.lock | 16 | ||||
-rw-r--r-- | 2022/rust/day08/Cargo.toml | 9 | ||||
-rw-r--r-- | 2022/rust/day08/src/main.rs | 96 |
4 files changed, 187 insertions, 0 deletions
diff --git a/2022/nim/day08/src/main.nim b/2022/nim/day08/src/main.nim new file mode 100644 index 0000000..c588dd0 --- /dev/null +++ b/2022/nim/day08/src/main.nim @@ -0,0 +1,66 @@ +# Day 8: Treetop Tree House +import std/[os, strutils, sugar] + +let input = paramStr(1).readFile().strip().split("\n") + +type Tree = object + height: int + visible: bool + scenic: int + +var forest = collect: + for line in input: + collect: + for c in line: + Tree(height: parseInt($c), visible: false, scenic: 1) + +var sum = 0 +var max = 0 + +template gaze(s: seq[seq[Tree]], a, b: iterable[int], min: int): int = + var result = 0 + block loop: + for k in a: + for l in b: + inc result + if s[k][l].height >= min: + break loop + result + +for i in 0 ..< forest.len: + var min = (-1, -1, -1, -1) + for j in 0 ..< forest.len: + let k = forest[0].len - 1 - j + + if forest[i][j].height > min[0]: + min[0] = forest[i][j].height + if not forest[i][j].visible: inc sum + forest[i][j].visible = true + + if forest[i][k].height > min[1]: + min[1] = forest[i][k].height + if not forest[i][k].visible: inc sum + forest[i][k].visible = true + + if forest[j][i].height > min[2]: + min[2] = forest[j][i].height + if not forest[j][i].visible: inc sum + forest[j][i].visible = true + + if forest[k][i].height > min[3]: + min[3] = forest[k][i].height + if not forest[k][i].visible: inc sum + forest[k][i].visible = true + + let min = forest[i][j].height + + forest[i][j].scenic *= forest.gaze(countdown(i-1, 0), j..j, min) + forest[i][j].scenic *= forest.gaze(i..i, countdown(j-1, 0), min) + forest[i][j].scenic *= forest.gaze(i+1 ..< forest.len, j..j, min) + forest[i][j].scenic *= forest.gaze(i..i, j+1 ..< forest.len, min) + + if forest[i][j].scenic > max: + max = forest[i][j].scenic + +echo sum +echo max diff --git a/2022/rust/day08/Cargo.lock b/2022/rust/day08/Cargo.lock new file mode 100644 index 0000000..66a960e --- /dev/null +++ b/2022/rust/day08/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day08" +version = "0.1.0" +dependencies = [ + "take-until", +] + +[[package]] +name = "take-until" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4e17d8598067a8c134af59cd33c1c263470e089924a11ab61cf61690919fe3b" diff --git a/2022/rust/day08/Cargo.toml b/2022/rust/day08/Cargo.toml new file mode 100644 index 0000000..d2e406b --- /dev/null +++ b/2022/rust/day08/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "day08" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +take-until = "0.1.0" diff --git a/2022/rust/day08/src/main.rs b/2022/rust/day08/src/main.rs new file mode 100644 index 0000000..4c53e14 --- /dev/null +++ b/2022/rust/day08/src/main.rs @@ -0,0 +1,96 @@ +use std::env; +use std::fs; + +#[derive(Debug)] +struct Tree { + height: i32, + visible: bool, + scenic: i32 +} + +#[allow(unused_parens)] +fn main() { + let args = env::args().nth(1).expect("missing input"); + let input = fs::read_to_string(args).unwrap(); + let mut forest: Vec<Vec<Tree>> = input.trim().split("\n") + .map(|x| x.chars() + .map(|x| Tree { + height: x.to_digit(10).unwrap() as i32, + visible: false, + scenic: 1 + }).collect()).collect(); + + let mut sum = 0; + let mut max = 0; + let len = forest.len(); + + // not thrilled with this code. + for i in 0 .. forest.len() { + let mut min = (-1, -1, -1, -1); + for j in 0 .. forest.len() { + let k = forest[0].len() - 1 - j; + + if forest[i][j].height > min.0 { + min.0 = forest[i][j].height; + if !forest[i][j].visible { + sum += 1; + } + forest[i][j].visible = true; + } + if forest[i][k].height > min.1 { + min.1 = forest[i][k].height; + if !forest[i][k].visible { + sum += 1; + } + forest[i][k].visible = true; + } + if forest[j][i].height > min.2 { + min.2 = forest[j][i].height; + if !forest[j][i].visible { + sum += 1; + } + forest[j][i].visible = true; + } + if forest[k][i].height > min.3 { + min.3 = forest[k][i].height; + if !forest[k][i].visible { + sum += 1; + } + forest[k][i].visible = true; + } + + let min = forest[i][j].height; + forest[i][j].scenic *= gaze(&forest, (i..=i), (j+1..len), min); + forest[i][j].scenic *= gaze(&forest, (i+1..len), (j..=j), min); + forest[i][j].scenic *= gaze(&forest, (i..=i), (0..j).rev(), min); + forest[i][j].scenic *= gaze(&forest, (0..i).rev(), (j..=j), min); + + if forest[i][j].scenic > max { + max = forest[i][j].scenic; + } + + } + } + println!("{}", sum); + println!("{}", max); +} + +// bluh why are range and rangeinclusive separate types +// bluhhh why are types not directly generic-able +// bluhhhhhh https://kaylynn.gay/blog/post/rust_ranges_and_suffering + +// all things considered i'm happy with this function +// considering how many Interesting behaviors of rust i ran into on the way +fn gaze(forest: &Vec<Vec<Tree>>, x: impl Iterator<Item=usize>, + y: impl Iterator<Item=usize> + Clone, min: i32) -> i32 { + let mut count = 0; + for i in x { + for j in y.clone() { + count += 1; + if forest[i][j].height >= min { + return count; + } + } + } + return count; +} |