-
-
Save anonymous/6428866 to your computer and use it in GitHub Desktop.
Commented version of code golf entry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
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) | |
L←(⍴S)-⊃⌽s | |
⍝ Set the direction | |
⍵∊G←'><^v':d∘←D[G⍳⍵;] | |
⍝ Turn around | |
⍵∊G←'\/':d∘←⌽d×1-2×G⍳⍵ | |
⍝ Bounce off | |
⍵∊G←'|_#':d×←⊃(1 ¯1)(¯1 1)(¯1 ¯1)[G⍳⍵] | |
⍝ Random direction | |
⍵∊'x':d∘←D[?4;] | |
⍝ 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 | |
⍵∊G←⎕D,'abcdef':S,←G⍳⍵ | |
⍝ 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 | |
⍵∊'l':S,←L | |
⍝ Add new stack (add marker at current position - popped value) | |
⍵∊'[':s,←1-⍨L-R 1 | |
⍝ Remove stack (delete last marker) | |
⍵∊']':s↓⍨←¯1 | |
⍝ 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 | |
⍵∊'i':i↓⍨←1⊣S,←⊃{i∘←10,⍨U⍞}⍣(⊃~×⍴i)⍨i | |
⍝ 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 ) | |
⍵∊';':S∘←0 | |
⍝ If the marker list is empty, the last stack is gone, so empty S and put the 0 marker back | |
s≡⍬:s∘←,0⊣S∘←⍬ | |
}U p⌷M | |
→end | |
⍝ Process a string | |
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 | |
end: | |
{}W ⍬ ⍝ Increment the current position | |
⍝ If S is not the scalar 0, do another step. | |
→step/⍨S≢0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment