# Golfing Advent of Code 2020, Day 3

I thought it'd be interesting to turn AoC day 3 puzzle into a Golfing Challenge, so here it is.

Find the number of # you'd encounter in an 11x11 grid (consisting of # and .) that repeats itself (to the right side), starting at the top left corner, which is always a .. You will need to check the position that is $$\x\$$ right, $$\y\$$ down, then the position that is $$\x\$$ right, $$\y\$$ down from there and so on until you reach one of the bottom # or ..

### Input

Two arguments:

• 3,1

• ..##.......
#...#...#..
.#....#..#.
..#.#...#.#
.#...##..#.
..#.##.....
.#.#.#....#
.#........#
#.##...#...
#...##....#
.#..#...#.#


means that you should traverse the grid going 3 right and 1 down. The output should be 7 (see the example in the AoC link above).

Without changing the grid but only the positions, here are some example inputs and outputs:

• $$\x=1, y=1 \to 2\$$.
• $$\x=5, y=1 \to 3\$$.
• $$\x=7, y=1 \to 4\$$.
• $$\x=1, y=2 \to 2\$$.

• 1,1

• .........##
.#.#.......
#.......#..
.........#.
.....#.....
...##...#..
#.#..#....#
........##.
......#....
...####...#
.........#.


means traversing the grid going 1 right, 1 down each time. You'd encounter only 1 # in this example, so the output should be 1.

### Rules

• $$\x\$$ (right) and $$\y\$$ (down) will be positive integers, where $$\y < 3\$$ (no limits for $$\x\$$).
• The grid can be repeated unlimited times.
• You can replace . and # with whatever you like in the grid (e.g. 0/1). Just mention which corresponds to which.
• You can receive input through any of the standard IO methods.
• This is , so shortest code in bytes wins!
• Can we input the grid as a two-dimensional array of ones and zeroes? Commented Jan 3, 2021 at 11:37
• @thedefault. no problem if you specify what 0 and 1 correspond to. Commented Jan 3, 2021 at 11:38
• A test case with y=2 could be good for the sake of self-containedness, especially seeing as the only example of y=2 on AoC requires logging in (since it's in part 2). Commented Jan 3, 2021 at 12:13
• To be clear, should the solution work for any grid size and step size? Commented Jan 3, 2021 at 19:48

# J, 30 26 23 22 bytes

0{0{[:+/|.^:(<@%&{.~$)  Try it online! Note: This solution works for any grid J supports multi-dimensional rotation, which reduces the problem almost to a single summation. To clarify what's happening, assume the board looks like this:  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39  Now we rotate the columns left and the rows up |. by 1 3, iteratively, 3 times: ┌──────────────┬──────────────┬──────────────┐ │ 0 1 2 3 4│ 8 9 5 6 7│11 12 13 14 10│ │ 5 6 7 8 9│13 14 10 11 12│16 17 18 19 15│ │10 11 12 13 14│18 19 15 16 17│21 22 23 24 20│ │15 16 17 18 19│23 24 20 21 22│26 27 28 29 25│ │20 21 22 23 24│28 29 25 26 27│31 32 33 34 30│ │25 26 27 28 29│33 34 30 31 32│36 37 38 39 35│ │30 31 32 33 34│38 39 35 36 37│ 1 2 3 4 0│ │35 36 37 38 39│ 3 4 0 1 2│ 6 7 8 9 5│ └──────────────┴──────────────┴──────────────┘  We are bringing the sled's "new position" to the top-left corner every time, rather than moving a pointer within a fixed grid and adjusting indexes with modular arithmetic. Once we have every iteration like this, we need only "sum the planes" element-wise [:+/, and then our answer will the number in the top left corner of the resulting matrix 0{0{. The only piece left is to determine how many times we need to iterate. This amounts to dividing the first element of our "step" vector (the down part) into the height of the input matrix: %&{.~$.

## old approach, 26 bytes

1#.]{~[:;/$@]|"1#\@]*($~#)


Try it online!

# 05AB1E, 9 bytes

Takes y, grid and x as seperate inputs where grid is a 2d-list of 0/1.

ιнε³N*è}O


Try it online! Convert a grid into the required format with this Retina script.

ι          # un-interleave the grid with step y
н         # take the first element grid[0::y]
ε    }   # map over each row
³N*     #   multiply x with 0-based iteration index N
è    #   index into row (modular)
O  # sum the values


# Scala, 47 44 bytes

-3 bytes thanks to user!

When replacing the ./# grid with a 0/1 one:

(x,y,z)=>1 to 10/y map(i=>z(i*y)(i*x%11))sum


Try it online!

## 77..62 60 bytes

using a ./# grid:

(x,y,z)=>1 to 10/y map(i=>if(z(i*y)(i*x%11)==35)1 else 0)sum


Try it online!

Explanation:

(x, y, z) =>                  // x: steps to the right, y: steps to the bottoms, z: grid as a String sequence
(1 to 10 / y)               // range r := [1;10/y]
.map (                    // override every entry in r
i => if (               // every entry i in r if
z(i * y)(i * x % 11)  // the character from the grid that is at the position (i * y, i * x),
// because i * x can get bigger than the number of columns modulo (%) it by 11
// so the correct position is: (i * y, i * x % 11)
== 35               // is equal to 35 (ASCII numeric value for '#')
) 1 else 0              // with 1 else 0
) sum                     // sum over all entries


Example: (5, 3, grid):

  val grid = Seq(
"..##.......",
"#...#...#..",
".#....#..#.",
"..#.#...#.#",
".#...##..#.",
"..#.##.....",
".#.#.#....#",
".#........#",
"#.##...#...",
"#...##....#",
".#..#...#.#"
)

   Steps                   | Sequence
------------------------|---------
init                    | [1, 2, 3]
i = 1; z(3)(5)  == '.'  | [0, 2, 3]
i = 2; z(6)(10) == '#'  | [0, 1, 3]
i = 3; z(9)(4)  == '#'  | [0, 1, 1]
sum == 2

• I'd love to see an explanation to this one Commented Jan 4, 2021 at 0:12
• Great answer! I think you can move the 0/1 version to the top since it's valid. Also, %2 is a byte shorter than -48, but you can probably use the integers themselves.
– user
Commented Jan 4, 2021 at 13:54
• @user This is clever. Thank you! Commented Jan 4, 2021 at 14:27

# Ruby, 50 bytes

->x,y,m,r=c=t=0{t+=m[r][(c+=x)%11]while m[r+=y];t}


Try it online!

Expects a matrix of $$\0\$$s and $$\1\$$s. It is given that m[0][0] is never a tree, so I always skip it.

• Where does the magic 11 come from? Commented Jan 3, 2021 at 19:41
• Oh, nm. I solved it for an arbitary grid/step size. Were we allowed to assume this specific grid size? Commented Jan 3, 2021 at 19:46
• @Jonah - Acc to OP, we are allowed. And, at first I'd also posted for arbitrary size, but it was longer than the Python, which I wasn't able to believe xD, there I got this assumption. Commented Jan 4, 2021 at 2:51

# Wolfram Language (Mathematica), 39 bytes

#[[i+1,Mod[i#2,11]+1]]~Sum~{i,0,10/#3}&


Try it online!

Input f[grid, x, y], where #s are 1 and .s are 0.

f x y g=sum[cycle(g!!b)!!a|(a,b)<-zip[0,x..][0,y..10]]


Try it online!

• saved 6 using 1 and 0 as '#' and '.'

# APL+WIN, 40 bytes

Prompts for y, x and the rows of the grid as a nested vector 1=# and 0=.:

+/(∊n⍴¨⎕)[((n←⌈/n)×y×m)+n←1+⎕×m←⍳10÷y←⎕]


Try it online! Thanks to Dyalog Classic

# Jelly, 11 10 bytes

mLḶ×⁵‘ị"mS


Try it online!

-1 byte mostly thanks to caird coinheringaahing

Takes a grid of 1 for # and 0 for . as the first argument, y as the second argument, and x as the third argument.

m             Take every yth row of the grid (starting from the first).
LḶ           For the range from 0 to its length minus 1,
×⁵         multiply each of those numbers by x,
‘ị       and 0-index into
"      corresponding items from
m     every yth row of the grid.
S    Sum the retrieved items.

• -2 bytes by reshuffling the m to remove the µs Commented Jan 3, 2021 at 13:11
• @cairdcoinheringaahing Doesn't quite work for y = 2 Commented Jan 4, 2021 at 0:45
• huh, that's weird that it's just for $y = 2$ that is fails Commented Jan 4, 2021 at 14:23
• @cairdcoinheringaahing I was about to say "it looks like " handles length mismatches differently than implicit zipwith-vectorization", but then I realized that implicit zipwith-vectorization also passes one argument through unchanged once there aren't any elements left of the other. Not sure where I got the idea from that it fills with zeroes Commented Jan 4, 2021 at 22:54

# Python 3, 71 $$\\cdots\$$ 54 53 bytes

Saved 11 bytes thanks to Command Master!!!
Saved 4 bytes thanks to ovs!!!
Saved a byte thanks to dingledooper!!!!

lambda g,r,d:sum(g[i*d][i*r%11]for i in range(11//d))


Try it online!

Inputs the grid as a list of lists of $$\1\$$s and $$\0\$$s (representing the number of trees at each place) along with the right and down moves and returns the number of trees hit.

• Isn't it it gives that the length of the grid is 11 (which allow you to remove the len and replace both of them with a constant 11)? Commented Jan 3, 2021 at 11:50
• @CommandMaster Well spotted - thanks! :D Commented Jan 3, 2021 at 11:53
• If you pass g[d:] on a recursive call, you don't need y, which saves 4 bytes.
– ovs
Commented Jan 3, 2021 at 13:04
• @ovs Masterful - thanks! :D Commented Jan 3, 2021 at 18:32
• You can save a byte by switching to an iterative solution Try it online! Commented Jan 4, 2021 at 5:32

# Charcoal, 22 21 bytes

ＮθＮηＳζＩΣ⭆÷χη§⊟ＥηＳ×θ⊕ι


Try it online! Link is to verbose version of code. Edit: Saved 1 byte by using @Razetime's suggestion of taking input in an alternate format. Input is as a list of [x, y, ...rows] where each row is either a numeric or character array or string of digits representing the number of trees in each cell. In the case where each row is a string, the input does not need to be JSON encoded. Explanation:

ＮθＮη


Input x and y.

Ｓζ


Ignore the first line of the grid as we know it always begins with a ..

⭆÷χη


Repeat 10/y times (joining the results together)...

⊟ＥηＳ


... input y lines of the grid but keeping only the last...

§...×θ⊕ι


... and cyclically index its column.

ＩΣ...


Sum the number of trees.

Previous 22-byte version used the original # and non-# characters:

ＮθＮηＳζＩ№Ｅ÷χη§⊟ＥηＳ×θ⊕ι#


Try it online! Link is to verbose version of code. There are two differences, the first is that this version works just as will with a regular Map instead of a StringMap, and the second is that it counts #s instead of summing trees.

# Ruby 2.7, 42 bytes

->r,y,m{((0..10)%y).count{m[_1][_1*r%11]}}


Try it online!

Expect inputs as $$\r = \frac xy\$$, $$\y\$$ and a matrix of true and false values indicating the presence of a tree at that place. This solution uses a different approach from my previous one. TIO uses an older version of Ruby, whereas in Ruby 2.7, we've numbered parameters and Enumerable#% method, which saves five bytes.