diff --git a/day8.chpl b/day8.chpl new file mode 100644 index 0000000..fd2069f --- /dev/null +++ b/day8.chpl @@ -0,0 +1,61 @@ +use IO; + +// It's easiest to just yield all numbers as a list, then reshape that list +// into a square given `rowSize` information. +iter allNumbers(ref rowSize: int) { + for line in stdin.lines() { + const trimmedLine = line.strip(); + rowSize = trimmedLine.size; + + for num in trimmedLine { + yield num : int; + } + } +} + +// Time to do that reshaping! +var rowSize = 0; +var allNums = allNumbers(rowSize); +var shapedNums = reshape(allNums, { 1..allNums.size / rowSize, 1..rowSize }); + +// In this problem, we're considering the view from each direction at each +// tree. Define a helper iterator to return an array slice representing trees +// in that direction, as well as the "by" step indicating which direction +// the path should be walked in. +iter eachDirection((x,y)) { + yield (shapedNums[..= this then break; + } + return count; +} + +// Finally, we iterate (in parallel) over each tree, and tally up if it's +// visible, as well as compute and note its score. +var visible = 0; +var bestScore = 0; +forall coord in shapedNums.domain with (+ reduce visible, max reduce bestScore) { + const tree = shapedNums[coord]; + visible += || reduce tree.visibleAlong(eachDirection(coord)); + bestScore reduce= * reduce tree.scoreAlong(eachDirection(coord)); +} +writeln(visible); +writeln(bestScore); diff --git a/day8.cr b/day8.cr new file mode 100644 index 0000000..ee4d6f5 --- /dev/null +++ b/day8.cr @@ -0,0 +1,58 @@ +require "advent" +INPUT = input(2022, 8).lines.map(&.chars.map(&.to_i32)) + +def visible_in_row(arr, idx) + (arr[..idx-1].max < arr[idx]) || (arr[idx+1..].max < arr[idx]) +end + +def score(arr, x, y, dx, dy) + tree = arr[x][y] + x += dx + y += dy + count = 0 + while x >= 0 && x < arr.size && y >= 0 && y < arr[x].size && arr[x][y] < tree + count += 1 + x += dx + y += dy + end + count += 1 if (x >= 0 && x < arr.size && y >= 0 && y < arr[x].size) + puts ({dx, dy, count}).to_s + count +end + +def part1(input) + input_t = input.transpose + count = 0 + count += input.size * 2 + count += (input[0].size - 2) * 2 + (input.size - 2).times do |x| + x += 1 + (input[x].size - 2).times do |y| + y += 1 + tree = input[x][y] + if visible_in_row(input[x], y) || visible_in_row(input_t[y], x) + puts ({x, y, tree}).to_s + count += 1 + end + end + end + count +end + +def part2(input) + best = 0 + (input.size - 0).times do |x| + (input[x].size - 0).times do |y| + tree_score = score(input, x, y, 1, 0) * score(input, x, y, -1, 0) * score(input, x, y, 0, 1) * score(input, x, y, 0, -1) + puts ({x, y, input[x][y], tree_score}).to_s + if tree_score > best + best = tree_score + end + puts "--" + end + end + best +end + +puts part1(INPUT.clone) +puts part2(INPUT.clone)