| Bytes | Lang | Time | Link |
|---|---|---|---|
| 118 | Desmos | 230816T175403Z | fwoosh |
| 165 | Ruby | 230731T135355Z | grizzthe |
| 104 | Perl 5 | 230804T161644Z | Toto |
| 129 | Swift | 230720T005304Z | Bbrk24 |
| 189 | Rust | 230719T074145Z | mousetai |
| 116 | Java 8 | 230720T083542Z | Kevin Cr |
| 019 | x86 assembly Linux | 230722T030447Z | Saladin |
| 082 | Python | 230719T071912Z | SuperSto |
| 032 | 05AB1E | 230721T075853Z | Kevin Cr |
| 233 | Racket | 230719T133702Z | Ed The & |
| 061 | C clang | 230719T165522Z | c-- |
| nan | Vyxal | 230719T062046Z | lyxαl |
| 116 | Excel ms365 | 230719T101249Z | JvdV |
| 043 | Charcoal | 230719T102424Z | Neil |
| 067 | JavaScript ES6 | 230719T090032Z | Arnauld |
Desmos, 118 bytes
Expects an array in variable A and a number in variable n (explained later).
Code in ticker
\left\{0<v<120:k->k+1\right\},f(\left\{v=60:-1,v=62,v=94:-n,v=118:n,v=0:d\right\})
Everything else
i=1
d=0
k=0
v=A[i]
f(x)=d->x,i->i+x
Input, explained
Desmos neither supports characters nor multidimensional arrays, so input is instead recieved as a 1D array A containing the rows of the matrix, along with an integer n containing the length of a row. For example, the test case
[['>', 0, 0, 'v','<'],
[ 0, '>','x','<', 0 ]]
Turns into
n=5
A=[62,0,0,118,60,0,62,120,60,0]
To speed things up you can use this conversion tool to automagically convert the input format for you.
After you enter your input into the program (see the "testcases" folder), reset the variables (run the action at the bottom of the page), and then start the ticker to run the program.
Once the program finishes, the result should be stored in k.
Program code, explained
Program code:
i=1 pointer to current position
d=0 direction of travel
k=0 number of arrows
v=A[i] shorthand for current value under the pointer
f(x)=d->x,i->i+x change the direction and also increment the pointer in that direction
Ticker code (prettified for readability):
{0<v<120:k->k+1},f({v=60:-1,v=62,v=94:-n,v=118:n,v=0:d})
{0<v<120:k->k+1}, increment k if this is an arrow
f({ }) change the direction to...
v=60:-1, ...left if '<'
v=62, ...right if '>'
v=94:-n, ...up if '^'
v=118:n, ...down if `v`
v=0:d ...no change if 0
As a result of the fact that i points to a 1D array, the row number of i can be changed by adding/subtracting n, which is why the direction changes to ±n for '^' and 'v'.
Ruby - 165 characters
No deviations from the rules. Uses 0 as the no-op. You can test the code here.
s,i,j,x,y=0,0,0,0,0
loop do
c = p[i][j]
break if c=='x'
if c!=0
if c=='v'||c=='^'
y=0
x=c=='v'?1:-1
elsif c=='>'||c=='<'
x=0
y=c=='>'?1:-1
end
s+=1
end
i+=x
j+=y
end
The readable version:
par_5 = [
['v',0,'>','v',0,0,0],
[0,0,0,'>','v',0,0],
['>',0,'^',0,'v',0,0],
['>',0,0,0,'x','<','<'],
[0,0,0,0,0,0,'^']
]
strokes = 0
i = 0
j = 0
i_inc = 0
j_inc = 0
loop do
shot = par_5[i][j]
if shot == 'x'
break
end
unless shot == 0
if shot == 'v' || shot == '^'
j_inc = 0
i_inc = shot == 'v' ? 1 : -1
elsif shot == '>' || shot == '<'
i_inc = 0
j_inc = shot == '>' ? 1 : -1
end
strokes += 1
end
i += i_inc
j += j_inc
end
puts "You had #{strokes} shots!"
Output:
You had 8 shots!
Perl 5, 104 bytes
while(($_=$p[$i][$j])ne"x"){$i+=$b=/v/?1:/\^/?-1:/0/?$b:0;$j+=$d=/>/?1:/</?-1:/0/?$d:0;$t++if$_}print$t
@p = (
['v',0,'>','v',0,0,0],
[0,0,0,'>','v',0,0],
['>',0,'^',0,'v',0,0],
['>',0,0,0,'x','<','<'],
[0,0,0,0,0,0,'^']
);
#@p=(['>',0,0,'v','<'],[0,'>','x','<',0]);
while(($_=$p[$i][$j])ne"x"){
$i+=$b=/v/?1:/\^/?-1:/0/?$b:0;
$j+=$d=/>;/?1:/<;/?-1:/0/?$d:0;
$t++if$_
}
print$t
Swift, 166 157 135 129 bytes
{var x=0,y=0,u=0,v=0,s=0
while 0<1{let i=$0[y][x]
if i>119{return s}
if i>0{(u,v)=i>63 ?(0,i>95 ?1:-1):(i-61,0)
s+=1}
x+=u
y+=v}}
Inspired by @mousetail's Rust answer. Takes a 2D array of ASCII values.
Try it on SwiftFiddle!
Explanation:
{ (arr: [[Int]]) -> Int in
// Create some working variables.
var x = 0
var y = 0
var dx = 0
var dy = 0
var strokes = 0
// Swift has no dedicated 'loop' keyword
while true {
let currentValue = arr[y][x]
// Swift uses switch/case rather than match, so these ifs are shorter
if currentValue > 119 {
// It must be 120, 'x'
return strokes
}
if currentValue > 0 {
(dx, dy) = currentValue > 63
? // It may be 'v' or '^'
// 'v' = 118, '^' = 94
(dx: 0, dy: currentValue > 95 ? 1 : -1)
: // It may be '<' or '>'
(dx: currentValue - 61, dy: 0)
strokes += 1
}
y += dy
x += dx
}
}
It might be possible to further optimize those ifs.
Original answer:
{a in var c=(0,0),d=(0,0,0)
var i:Int{a[c.0][c.1]}
while 0<1{if i>119{return d.2}
if i>0{if i>63{d.1=0
d.0=i>95 ?1:-1}else{d.0=0
d.1=i-61}
d.2+=1}
c.0+=d.0
c.1+=d.1}}
- -9 by using a constant inside the loop rather than a computed local outside it
- -22 by using several variables rather than tuples
- -6 by combining the assignments to
uandvinto a single statement
Rust, 189 bytes
|a|{let(mut c,mut d)=((0,0),(0,0,0));loop{d=match a[c.0 as usize][c.1 as usize]{60=>(0,-1,d.2+1),62=>(0,1,d.2+1),94=>(-1,0,d.2+1),118=>(1,0,d.2+1),120=>break d.2,_=>d};c=(c.0+d.0,c.1+d.1)}}
Hate needing to do explicit type conversions from signed to unsigned.
Takes input as ASCII character codes.
Rust, 147 143 bytes
|a,b|{let(mut c,mut d)=(0,(0,0));loop{d=match a[c as usize]%9{6=>(-1,d.1+1),8=>(1,d.1+1),4=>(-b,d.1+1),1=>(b,d.1+1),3=>break d.1,_=>d};c+=d.0}}
Same as above but takes input as a flattened array and length
Java 8, 129 119 118 117 116 bytes
m->{int c=0,p=0,l=m[0].length,d=0,t=0;for(;t<120;p+=d>99?l:d>93?-l:d/62*2-1)d=(t=m[p/l][p%l])>0?t+0*c--:d;return~c;}
-1 byte thanks to @ceilingcat.
Uses ␀-bytes ('\0') instead of 0 for the no-ops.
Input as a character-matrix.
Explanation:
m->{ // Method with char-matrix parameter and integer return-type
int c=0, // Arrow-counter, starting at 0
p=0, // Position, starting at {0,0}
l=m[0].length, // Width of the input-matrix
d=0, // Direction, starting initialized at anything
// (since the cell at {0,0} is guaranteed to contain an arrow)
t=0; // Current character, starting at 0
for(;t<120 // Loop until the current character is 'x':
; // After every iteration:
p+= // Update the position by increasing by:
d>99? // If the direction is 'v':
l // Increase by the matrix-width: {x,y}→{x,y+1}
:d>93? // Else-if the direction is '^':
-l // Decrease by the matrix-width: {x,y}→{x,y-1}
: // Else (the direction is '>' or '<'):
d/62*2-1) // If the direction is '>': increase by 1: {x,y}→{x+1,y}
// If the direction is '<': decrease by 1: {x,y}→{x-1,y}
d=(t=m[p/l][p%l]) // Set `t` to the value of the current position
>0? // If `t` is an arrow (or 'x'):
t // Update the direction to this `t`
+0*c-- // And decrease the arrow-counter by 1
: // Else:
d; // Keep the direction the same
return~c;} // After the loop, return -c-1 as result,
// where the -1 is to subtract 'x', since it isn't an arrow
x86 assembly (Linux), 19 bytes
This solution is a bit cheeky on the input. It expects a pointer to a M×N 2d array with the following symbols:
0->0x->-128<->-1>->1^->-Mv->M
Which is, of course, the offset in bytes to the next element in the pointed-to direction, allowing us to just add the values. As the dimensions of the golf field is encoded into the field itself, we cannot have fields with rows larger than 127 bytes.
If the row length is a limitation, just design the field to use all the columns you'd like. Who wants a square golf course anyway?
; int golf(char *ptr) __attribute__((fastcall));
00000000 <golf>:
0: 83 c8 ff or $0xffffffff,%eax ; int result = -1
; do {
00000003 <loop>:
3: 80 39 00 cmpb $0x0,(%ecx) ; if (*ptr) {
6: 74 04 je c <skip>
8: 0f be 11 movsbl (%ecx),%edx ; int step = *ptr;
b: 40 inc %eax ; result++;
; }
0000000c <skip>:
c: 01 d1 add %edx,%ecx ; ptr += step;
e: 83 fa 80 cmp $0xffffff80,%edx ; } while (step != -128)
11: 75 f0 jne 3 <loop>
13: c3 ret ; return result;
I can save an additional byte by making the input an array of ints rather than chars, but (to me) that violates the rule that:
[The input array] contains only either characters or the integer 0.
I admit the distinction may be pointless when dealing with assembly.
Python, 82 bytes
-12 bytes thanks to Jonathan Allan
f=lambda g,w,a=0,x=0:(n:=g[x])<119and(n>0)+f(g,w,a:=[a,n%3+n//14%3*w+~w][n>0],x+a)
Takes input as a flattened list of codepoints, plus the width of a row.
05AB1E, 37 32 bytes
Ç[¬нZ<#©Āi¼®U}©À®€Á®Á®€À)X11%è}¾
Uses 0 like in the challenge description.
Try it online or verify all test cases.
Explanation:
Since 05AB1E lacks a multidimensional index builtins, I instead rotate the entire matrix, so the cell at coordinate {0,0} will always contain the current value.
Ç # Convert all characters in the (implicit) input-matrix to codepoint
# integers (0s remain 0s)
[ # Start an infinite loop:
¬ # Push the first row (without popping the matrix)
н # Pop this list and push its first value
Z # Push its maximum digit (without popping the value)
< # Decrease it by 1
# # Pop this maxDigit-1, and if it's 1: stop the infinite loop
# (which is only the case for 'x'=120)
© # Store the current value in variable `®` (without popping the value)
Āi } # Pop the value, and if it's NOT 0:
¼ # Increase counter `¾` by 1 (starts initially at 0)
®U # And store `®` in variable `X`
© # Store the current matrix in variable `®` now (without popping the matrix)
À # Rotate its rows once towards the left
® # Push the matrix `®` again
€Á # Rotate the values in each of its rows once towards the right
®Á # Similar, but rotate its rows once towards the right
®€À # Similar, but rotate the values in each of its rows once towards the left
) # Wrap all four rotated matrix into a list
X # Push the current direction codepoint-integer `X`
11% # Modulo-11
è # (0-based) modular index it into the list of four matrices
}¾ # After the infinite loop: push counter `¾`
# (which is output implicitly as result)
Ç+Z<is[-1,8,5,7,5,1]for[0,"^",">","v","<","x"]respectively (only1is truthy in 05AB1E);Ç+11%4%(the4%is implicit due to modular indexing) is[2,3,0,1]for["^",">","v","<"]respectively.
Racket, 233 bytes
(display(let P([L(read)][x 0][y 0][X 0][Y 0][H 0][a add1])(match(list-ref(list-ref L y)x)['x H]['>(P L(a x)y 1 0(a H)a)]['<(P L(- x 1)y -1 0(a H)a)]['^(P L x(- y 1)0 -1(a H)a)]['v(P L x(a y)0 1(a H)a)][_(P L(+ x X)(+ y Y)X Y H a)])))
Input is a two-dimensional list of symbols:
((> > 0 0 0 v)
(v < 0 ^ < 0)
(0 ^ 0 0 > V)
(> 0 v 0 x <)
(0 0 > 0 ^ 0))
(That is, you don't need to use double quotes. Racket lists use parentheses () instead of brackets [] and don't use commas ,.)
Output is displayed on STDOUT. If the ball hits the edges, the program crashes with an index too large error.
Changelog
- Removed
#!racket(-9bytes). Thanks a lot @SuperStormer!
Explanation
Our program consists of a recursive function. At the initial run, we receive inputs and configure the initial variables. Note that for the golfed version I added an extra variable a that is shorthand for add1. It isn't necessary for the explanation.
(let program ([lst (read)] [x 0] [y 0] [dx 0] [dy 0] [hits 0])
...)
lstis the input list.xandyare the indices at which the ball is currently at.dxanddyare the directions that the ball is traveling to.- Used when a
0or any unrecognizable symbol is seen.
- Used when a
hitsare the number of hits/strokes that have occurred.
We then use Racket's match statement to determine the action we must do. The first argument of the match statement is the symbol we are matching to. To get the current symbol we can think of the two-dimensional list as a table of rows and columns. Each row is selected with the y variable and inside of the row are columns which are selected with the x variable.
(let program ([lst (read)] [x 0] [y 0] [dx 0] [dy 0] [hits 0])
(match (list-ref (list-ref lst y) x)
...))
In the body of the match statement, we have our cases. The cases are in the for of [if-match? do-this]. If the symbol is an x, we return the number of hits. If it is an arrow, we rerun the program with modified arguments. If is anything else (_ in the statement), we rerun the program, but we set x and y according to dx and dy respectively.
(let program ([lst (read)] [x 0] [y 0] [dx 0] [dy 0] [hits 0])
(match (list-ref (list-ref lst y) x)
['x hits]
['> (program lst (add1 x) y 1 0 (add1 hits))]
['< (program lst (- x 1) y -1 0 (add1 hits))]
['^ (program lst x (- y 1) 0 -1 (add1 hits))]
['v (program lst x (add1 y) 0 1 (add1 hits))]
[_ (program lst (+ x dx) (+ y dy) dx dy hits)]))
To display the results, we surround the let statement with a display statement.
(display
(let program (...)
...))
Conclusion
This was a fun code golf to solve! I learnt something new in the process (the match statement) and got a new view on how to see two-dimensional lists (rows and columns).
Hope you all have an amazing week further!
C (clang), 61 bytes
Expects an array containing 0, '>', '<', '^', 'v', or 'x'
d;f(*a,m){d=*a?:d;return'x'-d?!!*a+f(a+d%3+d/14%3*m+~m,m):0;}
Explanation
a tracks our current position, m is the side length of the array, and d is the direction we're going (which changes anytime a != 0). In each call to f() we update the value of a going one step in the direction of d.
Commented
d; // int d;
f(*a,m){ // function f() takes a pointer to int (a) and an int (m)
d=*a?:d; // if *a != 0 then d = *a
return //
'x'-d? // if d != 'x':
!!*a+ // add one if we're changing direction (*a != 0)
f(...) // to the result of calling f() recursively
: // else
0;} // we're at the end (return 0)
Vyxal, 225 bitsv1, 28.125 bytes
00"£{?¥ṘÞi:\x≠|¨^÷N":∑¬ß_:&+}!‹
Less of a mess than before. Takes 0s as "0"
Explained
00"£{?¥ṘÞi:\x≠|¨^÷N":∑¬ß_:&+}_!
00"£ # Put the list [0, 0] into the register. The register will act as the current character pointer
{ | # While:
¥ṘÞi # Indexing the register
? # Into the input
:\x≠ # Does not give "x" (leaving an extra copy of the retrieved character)
| # Do:
¨^ # Convert the retrieved character to the offsets that character represents. E.g. > maps to [1, 0] as it indicates incrementing the x coordinate.
# Characters not in "^<>v" are mapped to [0,0]
÷N" # Due to a goofy logic bug, ^ and v have their y-offset inverted, so un-invert it
:∑¬ # Check whether the sum of the offsets is not 0 (i.e. that the character is indeed a direction arrow)
ß_ # If it isn't a direction arrow, ignore the direction of the character. Otherwise, leave the offsets on the stack
:&+ # Add whatever offset is on the top of the stack (either a new arrow or the previous direction) to the register. This leaves a copy on the stack.
# This act of leaving the copy on the stack is how the number of arrows is determined. Every time an arrow is encountered, it's direction is pushed permanently to the stack.
_! # Remove the last item (which will be "x" due to the nature of the while loop stopping with an extra copy) and then push the length of the stack.
💎
Created with the help of Luminespire.
Excel (ms365), 119, 116 bytes
-3 Bytes thanks to @JosWooley
Formula in I1:
=Z(A1,A1,0)
Explaination:
Z() refers to a custom function:
=LAMBDA(i,s,c,LET(y,IF(i=0,s,i),IF(i="x",c,Z(OFFSET(i,SWITCH(y,"^",-1,"v",1,),SWITCH(y,"<",-1,">",1,)),y,c+(i>0)))))
This is a recursive LAMBDA() with 3 parameters:
- The starting cell as 'i';
- The starting direction as 's';
- The starting count as 'c', being zero at the 1st iteration.
If the current cell ('i') equals 'x' the recursion stops and the function will output the current value of 'c'.
If the current cell <> 'x' this means we need to call Z() and use the new cell as 'i' which is acquired via OFFSET() using the current direction. The 's' will always be equal to the 'y' parameter found while we need to add one to our counter 'c'.
Charcoal, 43 bytes
WS⊞υιP⪫υ¶≔⁰θW⌕x <v>^KK«F‹¹ι«≔⊗ιφ≦⊕θ»M✳φ»⎚Iθ
Try it online! Link is to verbose version of code. Takes input as a list of newline-terminated strings of spaces, arrows and an x. Explanation:
WS⊞υιP⪫υ¶
Copy the input to the canvas without moving the cursor.
≔⁰θ
Start with 0 strokes.
W⌕x <v>^KK«
Repeat until the ball goes in the hole.
F‹¹ι«
If the current character is an arrow, then...
≔⊗ιφ
... change the current direction, and...
≦⊕θ
... increment the number of strokes.
»M✳φ
Move the cursor in the current direction.
»⎚Iθ
Output the final count.
JavaScript (ES6), 67 bytes
Expects a matrix filled with 0 for no-op and the ASCII codes of the other characters.
f=(m,x=y=0)=>(q=m[y][x])-120&&(q?c=q:0)/c+f(m,x+c%3-1,y+=~-c%5%3-1)
JavaScript (ES6), 62 bytes
Using the custom mapping of <^>vx0 to [-1,0,1,2,3,4].
f=(m,x=y=0)=>(q=m[y][x])-3&&(q<3&&(c=q,1))+f(m,x+c%2,y+=~-c%2)

