Skip to content

Instantly share code, notes, and snippets.


Created September 3, 2013 20:06
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Commented version of code golf entry
Fish f
⍝ Variables
⎕IO←0 ⍝ Arrays start with 0
S←⍬ ⍝ This will hold the stack(s)
i←'' ⍝ This is an input buffer
s←,0 ⍝ This will hold the markers for [ and ], the first stack is at pos 0.
D←4 2⍴D,⌽D←0 1 0 ¯1 ⍝ Directions
p←0 0 ⍝ Position (start at 0,0)
v←0 ⍝ This is set to 1 when reading a string
r←⍬ ⍝ This is the register (starts out empty)
d←0 1 ⍝ Direction (start at 0,1 (y,x))
⍝ Read the program from the file. If in Windows format, strip the '\r's.
M←d↓↑M⊂⍨10=M←13~⍨10,83 ¯1 ⎕MAP f
⍝ Advance the position given the direction
W←{p+←d ⋄ p|⍨←⍴M ⋄ p}
⍝ Pop N numbers from the stack
R←{⌽{v←⊃⌽S ⋄ S↓⍨←¯1 ⋄ v}¨⍳⍵}
U←⎕UCS ⍝ Shorten the unicode conversion function (it's used a lot)
⍝ Do a step
→v/string ⍝ If v is true, jump to 'string'
⍝ Handle the current command
⍝ L is the length of the current stack (length of all stacks minus position of last marker)
⍝ Set the direction
⍝ Turn around
⍝ Bounce off
⍵∊G←'|_#':d×←⊃(1 ¯1)(¯1 1)(¯1 ¯1)[G⍳⍵]
⍝ Random direction
⍝ If the command is '!', or if the command is '?' and the stack is zero or empty, skip one.
(((~×⊃⌽S)∨L≤0)∧⍵∊'?')∨⍵∊'!':{}W ⍬
⍝ Jump (position is the topmost two stack values)
⍵∊'.':p∘←R 2
⍝ Number
⍝ Math translates to APL commands directly...
⍵∊G←'+-=*,)(':S,←⊃(⍎'+-=×,><'[G⍳⍵])/R 2
⍝ ...but the modulo command needs its arguments reversed.
⍵∊'%':S,←⊃|⍨/R 2
⍝ Start reading a string (v←1, V←delimiter)
⍵∊'"''':v V∘←1,U ⍵
⍝ Duplicate (pop one, push it twice)
⍵∊':':S,←2/R 1
⍝ Pop (pop one and eat it)
⍵∊'~':{}R 1
⍝ Rotate two or three values
⍵∊'$@':S,←¯1⌽R 2+⍵='@'
⍝ Rotate entire current stack
⍵∊G←'{}':S,←(1-2×G⍳⍵)⌽R L
⍝ Reverse entire current stack
⍵∊'r':S,←⌽R L
⍝ Length
⍝ Add new stack (add marker at current position - popped value)
⍵∊'[':s,←1-⍨L-R 1
⍝ Remove stack (delete last marker)
⍝ Ouput: pop one, run the unicode function over it by the position of the command in
⍝ 'no' (i.e. not for 'n' and once for 'o'), and output the result
⍵∊G←'no':⍞←(U⍣(G⍳⍵))R 1
⍝ Register: if there is anything in it, push and empty, otherwise, pop and store
⍵∊'&':{⍴r:r∘←⍬⊣S,←r ⋄ r,←R 1}⍬
⍝ Input: if the buffer is empty, read a line; push first character in buffer
⍝ Get (push M[y;x])
⍵∊'g':S,←M⌷⍨⌽R 2
⍝ Store (M[y;x]←pop)
⍵∊'p':((⌽1↓G)⌷M)∘←⊃G←R 3
⍝ Signal stop: replace the entire stack (a vector) by 0 (a scalar, so this won't happen
⍝ without )
⍝ If the marker list is empty, the last stack is gone, so empty S and put the 0 marker back
}U p⌷M
⍝ Process a string
⍝ Push current value and increment position until current value is the delimiter (V)
{}{+S,←p⌷M}⍣{V=M⌷⍨W ⍬}⍬
v←0 ⍝ Having read the string, we are no longer reading a string so set v back to 0
{}W ⍬ ⍝ Increment the current position
⍝ If S is not the scalar 0, do another step.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment