13
\$\begingroup\$

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

Task

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!
\$\endgroup\$
  • 1
    \$\begingroup\$ Can we input the grid as a two-dimensional array of ones and zeroes? \$\endgroup\$ – the default. Jan 3 at 11:37
  • \$\begingroup\$ @thedefault. no problem if you specify what 0 and 1 correspond to. \$\endgroup\$ – double-beep Jan 3 at 11:38
  • \$\begingroup\$ 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). \$\endgroup\$ – Unrelated String Jan 3 at 12:13
  • \$\begingroup\$ To be clear, should the solution work for any grid size and step size? \$\endgroup\$ – Jonah Jan 3 at 19:48

11 Answers 11

6
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ @double-beep, Thanks, but since this is code-golf ovs's 05AB1E answer should be the one you accept as it's the shortest. \$\endgroup\$ – Jonah Jan 6 at 11:02
4
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ I'd love to see an explanation to this one \$\endgroup\$ – Noone AtAll Jan 4 at 0:12
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – user Jan 4 at 13:54
  • \$\begingroup\$ @user This is clever. Thank you! \$\endgroup\$ – Michael Chatiskatzi Jan 4 at 14:27
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Where does the magic 11 come from? \$\endgroup\$ – Jonah Jan 3 at 19:41
  • \$\begingroup\$ Oh, nm. I solved it for an arbitary grid/step size. Were we allowed to assume this specific grid size? \$\endgroup\$ – Jonah Jan 3 at 19:46
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ – vrintle Jan 4 at 2:51
2
\$\begingroup\$

Haskell, 60 54 bytes

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 '.'
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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.
\$\endgroup\$
  • 1
    \$\begingroup\$ -2 bytes by reshuffling the m to remove the µs \$\endgroup\$ – caird coinheringaahing Jan 3 at 13:11
  • \$\begingroup\$ @cairdcoinheringaahing Doesn't quite work for y = 2 \$\endgroup\$ – Unrelated String Jan 4 at 0:45
  • \$\begingroup\$ huh, that's weird that it's just for \$y = 2\$ that is fails \$\endgroup\$ – caird coinheringaahing Jan 4 at 14:23
  • \$\begingroup\$ @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 \$\endgroup\$ – Unrelated String Jan 4 at 22:54
1
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ 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)? \$\endgroup\$ – Command Master Jan 3 at 11:50
  • \$\begingroup\$ @CommandMaster Well spotted - thanks! :D \$\endgroup\$ – Noodle9 Jan 3 at 11:53
  • \$\begingroup\$ If you pass g[d:] on a recursive call, you don't need y, which saves 4 bytes. \$\endgroup\$ – ovs Jan 3 at 13:04
  • \$\begingroup\$ @ovs Masterful - thanks! :D \$\endgroup\$ – Noodle9 Jan 3 at 18:32
  • \$\begingroup\$ You can save a byte by switching to an iterative solution Try it online! \$\endgroup\$ – dingledooper Jan 4 at 5:32
0
\$\begingroup\$

Charcoal, 22 21 bytes

NθNηSζIΣ⭆÷χη§⊟EηS×θ⊕ι

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:

NθNη

Input x and y.

Sζ

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

⭆÷χη

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

⊟EηS

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

§...×θ⊕ι

... and cyclically index its column.

IΣ...

Sum the number of trees.

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

NθNηSζI№E÷χη§⊟EηS×θ⊕ι#

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.

\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.