2020 AoC Day 3 – Toboggan Trajectory

This is a solution to Advent of Code 2020 day 3, written in Raku and Python.

https://adventofcode.com/2020/day/3

Part 1

Starting at the top-left corner of your map and following a slope of right 3 and down 1, how many trees would you encounter?

Raku

This solution uses modulo arithmetic to map unlimited width onto the input width. The row and column increments are hard-coded, not really anticipating what might come next.

The answer is a sum of the mapped # trees.

  my @lines = '3-input.txt'.IO.lines;
  my $rows = +@lines;
  my $cols = +@lines[0].comb;

  my @grid[$rows;$cols] = @lines.map(*.comb);

  say [+] (1..^$rows).map(
      -> $row {
          my $column = ($row * 3) % $cols;
          @grid[$row; $column] eq '#';
      })
242

Python

This is a fairly direct translation of the Raku solution into Python.

lines = open('3-input.txt', 'r').read().splitlines()
rows = len(lines)
cols = len(lines[0])

hits = map(lambda r: 1 if lines[r][(r * 3) % cols] == '#' else 0, range(1, rows))
print(sum(hits))
242

Part 2

Determine the number of trees you would encounter if, for each of the following slopes, you start at the top-left corner and traverse the map all the way to the bottom:

Right 1, down 1. Right 3, down 1. (This is the slope you already checked.) Right 5, down 1. Right 7, down 1. Right 1, down 2.

What do you get if you multiply together the number of trees encountered on each of the listed slopes?

Raku

A slightly weird evolution of part one, passing a sequence into the trees sub.

  my @lines = '3-input.txt'.IO.lines;
  my $rows = +@lines;
  my $cols = +@lines[0].comb;

  my @grid[$rows;$cols] = @lines.map(*.comb);

  sub trees(@rows, $col-inc) {
      [+] @rows.map(
          -> $row {
              my $column = ($row * $col-inc) % $cols;
              @grid[$row; $column] eq '#';
          })
  }

  say 'Part 1';
  say trees(1..^$rows, 3);

  say 'Part 2';
  my @totals =
  trees(1..^$rows, 1),
  trees(1..^$rows, 3),
  trees(1..^$rows, 5),
  trees(1..^$rows, 7),
  trees((2,4,6...^$rows), 0.5);
  say "[*] { @totals } = { [*] @totals }";
Part 1
242
Part 2
[*] 82 242 71 67 24 = 2265549792

Python

Python solution written in a more iterative style.

  from math import prod

  lines = open('3-input.txt', 'r').read().splitlines()
  rows = len(lines)
  cols = len(lines[0])

  def trees(rowinc, colinc):
      row, col = rowinc, colinc
      hits = 0
      while row < rows:
          if lines[row][col % cols] == '#':
              hits += 1
          row, col = row + rowinc, col + colinc
      return hits

  totals = trees(1, 1), trees(1, 3), trees(1, 5), trees(1, 7), trees(2, 1);

  print('Part 2')
  print(prod(totals))
Part 2
2265549792
raku