aboutsummaryrefslogtreecommitdiff
path: root/2022
diff options
context:
space:
mode:
Diffstat (limited to '2022')
-rw-r--r--2022/nim/day08/src/main.nim66
-rw-r--r--2022/rust/day08/Cargo.lock16
-rw-r--r--2022/rust/day08/Cargo.toml9
-rw-r--r--2022/rust/day08/src/main.rs96
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;
+}