Code for the Advent of Code event
aoc
advent-of-code
1#!/usr/bin/env ruby
2# frozen_string_literal: true
3
4GRID = ARGF.readlines.map { |l| l.scan(/\d/).map(&:to_i) }
5TRANSPOSED = GRID.transpose
6
7WIDTH = GRID[0].size
8HEIGHT = GRID.size
9
10def score(x, y)
11 val = GRID[y][x]
12 left = GRID[y][..x - 1]
13 right = GRID[y][x + 1..]
14 up = TRANSPOSED[x][..y - 1]
15 down = TRANSPOSED[x][y + 1..]
16 dirs = [left, right, up, down]
17
18 is_edge = x == 0 || y == 0 || x >= WIDTH - 1 || y >= HEIGHT - 1
19 is_visible = is_edge || dirs.any? { |d| d.all? { _1 < val } }
20
21 if is_edge
22 score = 0
23 else
24 left_index = left.reverse.find_index { _1 >= val }
25 left_count = left_index.nil? ? x : left_index + 1
26 right_index = right.find_index { _1 >= val }
27 right_count = right_index.nil? ? right.size : right_index + 1
28 up_index = up.reverse.find_index { _1 >= val }
29 up_count = up_index.nil? ? y : up_index + 1
30 down_index = down.find_index { _1 >= val }
31 down_count = down_index.nil? ? down.size : down_index + 1
32 score = left_count * right_count * up_count * down_count
33 end
34
35 [is_visible ? 1 : 0, score]
36end
37
38result = (0..HEIGHT - 1).reduce([0, 0]) do |a, y|
39 inter = (0..WIDTH - 1).reduce([0, 0]) do |i, x|
40 s = score(x, y)
41 [i[0] + s[0], [s[1], i[1]].max]
42 end
43
44 [a[0] + inter[0], [inter[1], a[1]].max]
45end
46
47puts result[0]
48puts result[1]