| Bytes | Lang | Time | Link |
|---|---|---|---|
| 109 | Swift 6 | 240401T123632Z | macOSist |
| 039 | Uiua 0.10.0 | 240331T112316Z | RomanPro |
| 167 | Easyfuck | 240330T222645Z | Quadrupl |
| 049 | ><> Fish | 230503T150836Z | mousetai |
| 144 | Scala | 230422T044059Z | 138 Aspe |
| 055 | minigolf | 230422T023955Z | user1176 |
| 121 | *><> | 220805T181109Z | Bee H. |
| 057 | Knight | 220802T021121Z | 97.100.9 |
| 113 | Kotlin | 220719T020342Z | Eric Xue |
| 019 | Vyxal O | 220717T223403Z | naffetS |
| 269 | Desmos /w ticker | 220406T191253Z | Not A Ch |
| 140 | Piet with asciipiet encoding | 220404T140952Z | Tim Pede |
| 104 | PHP 7 | 220330T093227Z | user1117 |
| 117 | Python 3.8 prerelease | 220329T235249Z | Larry Ba |
| 160 | Batch | 211026T110102Z | T3RR0R |
| 083 | TIBasic | 211025T214733Z | Youserna |
| 074 | Perl 5 F E | 210830T125331Z | plentyof |
| 6458 | J | 210206T061225Z | Jonah |
| 120 | Swift | 210828T231823Z | Bbrk24 |
| 039 | Pip | 210828T205324Z | DLosc |
| 025 | Vyxal DO | 210826T225259Z | emanresu |
| 070 | Julia | 210301T155102Z | MarcMush |
| 115 | Yabasic | 210301T093828Z | Caleb Fu |
| 028 | Vyxal | 210301T034628Z | lyxal |
| 030 | Ohm v2 | 210210T164021Z | Cinaski |
| 043 | x8616 machine code | 210130T204645Z | EasyasPi |
| 151 | Lua LuaJIT | 210208T032837Z | LuaNoob |
| 091 | C gcc | 210204T075405Z | ErikF |
| 098 | Java JDK | 210206T192127Z | Olivier |
| 119 | Rust | 210206T171017Z | Technoha |
| 047 | APL Dyalog Classic | 210206T130317Z | rak1507 |
| 081 | AWK | 210131T003707Z | cnamejj |
| 021 | 05AB1E | 210131T141537Z | ovs |
| 074 | PowerShell 7 | 210202T183813Z | Zaelin G |
| 091 | R | 210201T090141Z | pajonk |
| 035 | Stax | 210201T165754Z | Joshua |
| 081 | ><> | 210201T212156Z | SE - sto |
| 104 | Nim | 210130T222757Z | xigoi |
| 178 | Racket | 210201T095046Z | Galen Iv |
| 074 | Python 2 | 210130T234213Z | ovs |
| 059 | Pyth | 210201T085922Z | Ian H. |
| 023 | MathGolf | 210201T083315Z | Kevin Cr |
| 025 | Husk | 210201T003226Z | Leo |
| 157 | Batch | 210131T203316Z | Neil |
| 080 | Arturo | 210131T184522Z | xigoi |
| 068 | PowerShell | 210131T160606Z | mazzy |
| 082 | flex | 210130T173133Z | Noodle9 |
| 118 | PowerShell | 210131T153618Z | wasif |
| 051 | AWK | 210131T031917Z | Mukundan |
| 024 | Jelly | 210130T221408Z | xigoi |
| 106 | Red | 210131T102508Z | Galen Iv |
| 136 | PHP | 210131T100806Z | emanresu |
| 095 | Python 3 | 210130T223631Z | Gotoro |
| 106 | Icon | 210131T094212Z | Galen Iv |
| 058 | Ruby | 210130T204815Z | Dingus |
| 060 | Wolfram Language Mathematica | 210131T051855Z | att |
| 066 | JavaScript ES10 | 210130T153022Z | Arnauld |
| 037 | Charcoal | 210130T213215Z | Neil |
| 061 | Retina | 210130T212155Z | Neil |
| 076 | convey | 210130T160024Z | xash |
Swift 6, 119 109 bytes
var a=0,f={(a=0,""+$0).1.reduce([]){"o"==$1 ?$0+[a]:(a="r"<$1 ?a*a:"d"<$1 ?a+1:a-1,a=a<0||a==256 ?0:a,$0).2}}
Easyfuck, 167 bytes
Ì¡n␅␏␖SHYÀ¡kæ␋^)VSHYòMWo␒>|NELâGÉAPCE³ù忸␔>VñM×É␖àPñâ¥2PU2>|§:NELwAPC^RPU1ãåPLD¯[¼ùbë×ZÙ]nSŸ␝«¶òëêl%!}yn␅␏APC>|ù^␅␏␕¾SSGCIâSTëp(|ùóå¸␔<ZùNe9ÖàPùòGÏDCS¼I5óä/␒>SCIPU1ãÇSS3_f|§:Ü␊␟>APCMPU2êyAPC>R®õØ␃täç¼␀␀␀␀
due to lack of unicode representations for c1 control characters, they have been replaced by their superscripted abbreviations
Decompressed:
f(-`(<--`(->0-<)++>)+<$>>!<$>&>EY~<[}`(>+<)]>$-`(<<*)J$>>)g(+^>^)$<>,.^[^>,.^]5Y.[J<-`;+[<]>S0J!>^-`(>>>>>+`(<+>)f<)g-`(>>>>-`(<->)f)g-`(>>$>>!<$M>>!<$>M$<<<=>f>)g-`(>>OS2.Sf>>)+^]@␍idso␀␀␀␀
><> (Fish), 49 bytes
05i8%.
1+v
:*v
1-v
:nv
0.\:01-=}:"Ā"={+0$?$~0
Beats the existing answer by about 30 bytes. Branchless -1 and 256 checking logic copied from this excellent answer
Scala, 144 bytes
Modified from @Gotoro's answer.
Golfed version. Attempt it online!
var n=0;for(x<-readLine()){if(n== -1||n==256)n=0;if(x=='o')println(n)else n=((x.toInt%4)^1)match{case 0=>n+1;case 1=>n-1;case 2=>n*n;case _=>n}}
Ungolfed version. Attempt it online!
import scala.io.StdIn.readLine
object Main {
def main(args: Array[String]): Unit = {
var n = 0
for (x <- readLine()) {
if (n == -1 || n == 256) n = 0
if (x == 'o') println(n)
else n = ((x.toInt % 4)^1) match {
case 0 => n + 1
case 1 => n - 1
case 2 => n * n
case _ => n
}
}
}
}
minigolf, 55 bytes
Had to do this because it's ridiculously easy to do in minigolf.
0i,nWT*+1,;,nB=,:_n0=,T+_n5=,1+_nF=,:*__::V=sT=+,0*__,_
(For the iiii case, though, it produces an index out of bounds error to STDERR, but nothing is outputted to STDOUT.)
Explanation
0 Push 0 as initial accumulator
i, For each item in the (inputted) command sequence:
n Push current command
WT*+ Subtract by 100
(since we have constants 0 thru 17
as convenient 1-byte builtins)
1,; Wrap it into a singleton list
(because we want to re-use it several times)
, Fry sequence:
nB=, If current result is 11 (aka. `o`)
: Duplicate the current accumulator value.
(which effectively outputs the accumulator as it's not changed later)
_ End if
n0=, If curr = 0 (aka. `d`):
T+ Add acc by -1
_ End if
n5=, If curr = 5 (aka. `i`)
1+ Add acc by 1
_ End if
nF=, If curr = 15 (aka. `s`)
:* Square the acc
_ End if
_ End fry sequence
:: Triplicate the acc
V= Is it equal to 256?
sT= Swap, is it equal to -1?
+ Add them together
, Repeat n times:
(we definitely only have one condition satisfied, so the value of + must be either 0 or 1)
0* Multiply acc by 0 (i.e. set it to 0)
_ End repeat
_ End foreach loop
,_ Drop the last acc value (so that it's not outputted to STDOUT)
Implicit output stack
*><>, 121 bytes
I didn't check before writing this, and now see that I was already long ago beat by ><> but oh well. I'm not going to not post this after all that effort.
r01[D63.
>:884**= ?!\~0v
^v0~u!?=-10:<u <
^> OD~l0=?!\;
^+1I/!?="i":/
^ \:"d"=?!\I1-
^*:I/!?="s":/
^ \:"o"=?!;I:aon
Explanation
The program works through 3 main sections, and one initialization section. It uses two stacks: one input stack, and one accumulator stack.
Breakdown
; Initialize
r01[D63.
; Bounds Check
>:884**= ?!\~0v
^v0~u!?=-10:<u <
; End of input check
^> OD~l0=?!\;
; Main look
^+1I/!?="i":/
^ \:"d"=?!\I1-
^*:I/!?="s":/
^ \:"o"=?!;I:aon
Initialization
r Reverse the input
0 Push the accumulator onto the stack
1[ Move the accumulator to a new stack
D Return to the input stack
63. Move to [3,6] in the code block (pushing the length of the stack onto the stack in the input check)
Bounds check
> Set the IP direction rightward
: Duplicate the accumulator
884** Push 256 onto the stack
= Is the accumulator 256
?!\ If not, mirror the IP downward
Else
~ Remove the accumulator from the stack
0 Push 0 onto the stack
v Change IP direction downward
< Change IP direction leftward
u Dive, and ignore any non-movement instructions until we rise
< Change IP direction leftward
: Duplicate the accumulator
-10 Push -1 onto the stack
= Is the accumulator -1
u!? If not, dive
Else
~ Remove the accumulator from the stack
0 Push 0 onto the stack
v Change IP direction downward
^ Change IP direction upward (Used when returning to the top of the bounds check)
End of Input check
^ Change IP direction upward (Used when returning to the top of the bounds check)
> Set the IP direction rightward
O Rise from any potential dive we may have done (ignored if there was none)
D Change to the input stack
~ Remove the an instruction from the top of the stack
l Push the length of the stack onto the stack
0 Push 0 onto the stack
= Is the length of the stack 0
?!\ If not, mirror the IP downward
; Else, halt execution
Main block
I've condensed the main block's explanation for the sake of brevity.
/ Mirror IP to the left
="i": Is our current instruction i
/!? If not, mirror IP downward
Else
^+1I Switch to accumulator stack, add 1, and set IP direction upward (returning to bounds check)
\ Mirror IP to the right
:"d"= Is our current instruction d
?!\ If not, mirror IP downward
Else
^ I1- Switch to accumulator stack, subtract 1, and set IP direction upward
/ Mirror IP to the left
="s": Is our current instruction s
/!? If not, mirror IP downward
Else
^*:I Switch to accumulator stack, duplicate the accumulator and multiply it against itself, set IP direction upward
\ Mirror IP to the right
:"o"= Is our current instruction o
?!; If not, halt execution
Else
I:a Switch to accumulator stack, duplicate the accumulator, push 10 onto the stack
^ on Print the 10 (newline) and our accumulator value, and set IP direction upward
Knight, 57 bytes
;=a 0W=cP I?c"o"Oa=a*=a I?c"d"-a 1I?c"i"+1a^a 2!|?256a>0a
Takes in each character on a separate input line.
Explanation
Here's the code with generous whitespace and comments added:
;=a 0 #set a to 0
W=cP # while the next input character `c` is not null:
I?c"o" # if c is "o":
Oa # output a
=a # else...
*=a # set a to the following:
I?c"d" # (if a is "d":
-a 1 # a-1
I?c"i" # else if a is "i":
+1a # a+1
^a 2 # else a^2)
!|?256a>0a # multiply a by (not (a is 256) or (0>a)), which is 1 when a is within bounds and 0 otherwise
An earlier version where I tried to use some more clever tricks which ended up being longer (66 bytes):
;=a 0W =cP I?c"o"Oa=a*=aE S G"^2-1+1"/%Ac 23 3 2 1 0"a "!|?256a>0a
Kotlin, 113 bytes
{var o=listOf<Int>();var a=0;for(s in it){when(s){'i'->a++;'d'->a--;'s'->a*=a;'o'->o+=a};if(a==-1||a==256)a=0};o}
Type signature: String -> List<Int>
Vyxal O, 19 bytes
0?(n`ḟ``ġ`ĿĖ:₈u"c[0
This is really cheating, but whatever. Short dictionary abuse ftw
Vyxal OD, 20 bytes
0?(n½`›²‹…`iĖ:₈u"c[0
Input as list of codepoints, no cheating.
Desmos /w ticker, 269 bytes
Code in ticker:
\left\{I[n]=4:T,\ I[n]=3:v->\left\{v^2=256:-1,v^2\right\},I[n]=2:v->\left\{v-1=-1:0,v-1=256:0,v-1\right\},I[n]=1:v->\left\{v+1=-1:0,\ v+1=256:0,\ v+1\right\}\right\},\ n-> n+1
Code in list:
I=[]
O=[]
i=1
d=2
s=3
o=4
n=0
v=0
T=O->\operatorname{join}(O,\left\{v=-1:0,v=256:0,v\right\})
Piet with ascii-piet encoding, 140 bytes
Outputs numbers with a space as a separator. Goes into an infinite loop once it runs out of input. (If using npiet, the -q flag will suppress the "?" prompts, and -e will set a number of execution steps to kill the program after. 1300 steps is enough to run the longest test case.)
Piet code (codel size 4):
ascii-piet version (with line breaks added):
vnmdeusausejbsvcldvufktdtqeC
eeeee jjllllltln tdt A
e dde jjrjc????? dda K
e dmn????c mmiii m N
e ??narvfctisjicemmnaai??ctD
Explanation
After initialising the accumulator with 0, a character is read from standard input. Its value is then decremented by 100 (for "d"), by another 5 ("i"), and by another 6 ("o"), branching once it hits zero. If it still hasn't hit zero, it's assumed to be "s".
(Actually, I messed up and put the "s" code on the branch and the "o" code on the straight path, which runs all the way around the outside. This was convenient, since output takes more code than squaring, so I left it that way and just negated the relevant check.)
Coming back across the bottom, after some codel-chooser twiddling, the new accumulator value is compared to 256 and then (if that didn't branch) to -1. If either one compares equal, it branches again into code that resets the accumulator to 0.
And then it repeats from the character read.
PHP 7 (104 chars)
Given argv[1] as a command line argument :
for($r=0,$s=$argv[1];@$a=$s[$i++];$r*=$r-256&&~$r)@($a>i?$a>o?$r*=$r:print$s[$i]?"$r,":$r:$r+=$a>d?:-1);
Python 3.8 (pre-release), 117 bytes
def f(x,o=0):
for c in x:
if o>256or o<0:o=0
if(v:=ord(c)&6)<1:o+=1
if v<3:o**=2
if v<5:o-=1
else:print(o)
Batch 160 bytes
@Set v=0&@Set i=v+=1&@Set d=v-=1&@Set s=v*=v&2>nul (@For %%i in (%*)Do @Set/A"-1/(v+1)"||Set v=0&Set/A"256/(v-256)"||Set v=0&Call Set/A%%%%i%%||Call Echo(%%v%%)
How? :
&= concatenate commands@Set v=0= Zero accumulator valueSet i=v+=1;Set d=v-=1;Set s=v*=v= Defines operation to perform when command parameters parsedFor %%i in (%*)Do= Iterate over command parameters@Set/A"-1/(v+1)"||Set v=0= Conditional assesment of accumalator ifvalue EQU -1 (Set /A opeations fails due to divide by zero error)Set/A"256/(v-256)"||Set v=0= Conditional assesment of accumalator ifvalue EQU 256 (Set /A opeations fails due to divide by zero error)Call Set/A%%%%i%%||= expands to the defined command arg operation or FAILS for the undefinedocommand (Missing operator), triggering||execution ofCall Echo(%%v%%Calltriggers additional parsing steps for the subsequent command, allowing a variable named with %%I's value to be expanded, without having to resort to using delayed expansion.
2>nul (For ...)redirection used to suppress STDERR resulting from operations with missing operators or that divide by zero
TI-Basic, 83 bytes
Input Str1
For(I,1,length(Str1
inString("ids",sub(Str1,I,1→J
If Ans:Then
{A+1,A-1,A²
Ans(J
max(0,Ans)(Ans≠256→A
Else
Disp A
End
End
Input is taken as a string and outputs are printed and separated with newlines.
Perl 5 -F -E, 96 91 90 79 74 bytes
(+4 bytes for switches included)
Saved 5 bytes by using a built-in variable that defaults to 0 ($- / $FORMAT_LINES_LEFT) instead of $a
Saved 1 byte by using print and $/ instead of CORE::say
Saved 11 bytes by using -F and -E switches
Saved 4 bytes by (ab)using regex match return value coercion. Saved 0 bytes but improved readability by changing $- to $% ($FORMAT_PAGE_NUMBER)
for(@F){$%+=/i/;$%-=/d/;$%*=$%if/s/;say$%if/o/;$%=0if$%=~/^(-1|256)$/}
More-readable version:
for (@F) {
$% += /i/;
$% -= /d/;
$% *= $% if /s/;
say($%) if /o/;
$% = 0 if $% =~ /^(-1|256)$/;
}
J, 64 58 bytes
g=:]e.&256 _1|]
i=:g>:
d=:g<:
s=:g*:
o=:1!:2&2
f=:'0'".@|.@,]
-6 thanks to FrownyFrog!
Note: -3 off TIO count for f=:
This stores each Deadfish command in a variable of the same name, followed by the -1/256 check. Then we just prepend 0, reverse, and eval.
Takes input with spaces between the letters.
Swift, 120 bytes
{(s:String)in var i=0
s.forEach{switch $0{case"i":i+=1 case"d":i-=1 case"s":i*=i default:print(i)}
if i==256||i<0{i=0}}}
Returns a closure that takes the input as an argument. If the input contains o multiple times, the numbers are separated by newlines.
Try it online (full program that uses hardcoded input)
Ungolfed:
{ (str: String) in
var i = 0
str.forEach { (char: Character) in
switch char {
case "i":
i += 1
case "d":
i -= 1
case "s":
i *= i
default: // "o"
print(i)
}
if i == 256 || i < 0 {
i = 0
}
}
}
Pip, 39 bytes
Fca;V("U i&D SQ: P"^sAc)."i*:i!=256"
Takes the Deadfish program as a command-line argument. Try it here! Or, here's a 42-byte version in Pip Classic: Try it online!
Explanation
The variable i is preset to 0, so we'll use it for the accumulator.
Fca;V("U i&D SQ: P"^sAc)."i*:i!=256"
Fca; For each c in command-line argument a:
"U i&D SQ: P" Take this string
^s Split on spaces into a list of 7 strings
( ) Index (0-based, modular) into that list using
Ac the ASCII code of c
. Concatenate
"i*:i!=256" this string
V Eval as Pip code
The code snippets for each command are:
i -> index 0 -> Ui*:i!=256
d -> index 2 -> i&Di*:i!=256
s -> index 3 -> SQ:i*:i!=256
o -> index 6 -> Pi*:i!=256
The first three expressions change the value of i and then multiply it by 0 if the new value equals 256:
Ui Increment i
i&Di If i is not 0, decrement i
SQ:i Square i in place
The fourth expression parses a little differently: since P is lower precedence than assignment, it works out to "multiply i by 0 if it equals 256, and then print." Fortunately, since printing doesn't change the value of i, the order doesn't matter.
Vyxal DO, 25 bytes
0Ȯ(n«ƛ√J«`›‹²…`ĿĖ:₈u"=a[0
Saved a byte thanks to Aaron Miller.
0 # Push 0
Ȯ(n # Iterating over the input
«ƛ√J«`›‹²…`Ŀ # Transliterate into appropriate Vyxal instruction
Ė # Evaluate
:₈u"=a[ # If 256 or negative
0 # Push 0
Julia, 70 bytes
s->(a=0;!c=a=[a*=a⊻256>0,a-1,a*a,a+1,c%5>0&&print(a,-)][c÷2%6];.!s)
Based on ovs's answer
Yabasic, 119 115 bytes
a=0
for j=1 to len(i$)
c=instr("isdo",mid$(i$,j,1))
if c<4 a=a+2-c
if c=2 a=a*a
if c=4 ?a;
if a<0 or a=256 a=0
next
The actual input is done via reading DATA statements for each Deadfish program. For an interactive version I'd just replace that with an INPUT i$ statement, and calling RUN at the end should re-run the program, initializing variables to 0 and removing the need for the a=0 statement.
I feel this could be more compact, but everything else I try actually makes it bigger. The only really "golf-y" thing is the line:
if c<4 a=a+2-c
which for command 2=square has no effect, avoiding the need for one IF evaluation and saving 11 bytes vs the more straightforward implementation.
Even the XOR 256 trick works out identical in length to the more straightforward version above so I stuck with the simpler code.
edit - I did save 4 bytes because the BASIC interpreter I'm using puts a space as a seperator between numbers automatically, so no need to add it.
Vyxal, 28 bytes
❝,(\&`\⨥\⨪\²\₴`ni+ₑuγd‿¥c[0£
Takes a list of numbers, where 0 represents i, 1 represents d, 2 represents s and 3 represents o
x86-16 machine code, 45 43 bytes
Source-compatible with x86 and x86_64.
Fails one test due to integer overflow, but instructions are given to switch it to 64-bit arithmetic in the demo.
00000000: 31 d2 ac 3c 64 72 23 74 0d 3c 69 74 0c 3c 6f 92 1..<dr#t.<it.<o.
00000010: 74 0a f7 e0 eb 07 4a eb 05 42 eb 02 ab 92 85 d2 t.....J..B......
00000020: 78 de 81 fa 00 01 74 d8 eb d8 c3 x.....t....
// "//" comments are solely for syntax highlighting
// sed -i -e 's#//#;#g' deadfish.asm
// nasm compatible
[bits 16]
[cpu 8086]
global deadfish
// Input:
// si: input, null terminated string
// di: output, uint16_t array
// Output:
//
// di: points past the last value in the array
deadfish:
.Lzero:
// Set accumulator to 0
xor dx, dx
.Lloop:
// Load byte
lodsb
// Check for null terminator and for 'd'
cmp al, 'd'
// Below means null terminator, return
jb .Lret
// equal means 'd'
je .Lop_d
// check for 'i'
cmp al, 'i'
je .Lop_i
// check for 'o'
cmp al, 'o'
// Since O and S both need AX instead of DX, xchg here.
xchg dx, ax
je .Lop_o
// assume 's'
.Lop_s:
// Square
mul ax
// Jump to the end of the o code to swap AX to DX.
jmp .Lnext_xchg
.Lop_d:
// Decrement
dec dx
jmp .Lnext
.Lop_i:
// Increment
inc dx
jmp .Lnext
.Lop_o:
// Output
// *di++ = ax
stosw
// Swap dx and ax again for o and s
.Lnext_xchg:
xchg dx, ax
.Lnext:
// Check for -1 (less than zero) and 256
// If equal, jump to the xor dx, dx conveniently placed before the loop
test dx, dx
js .Lzero
// Literally the only reason I am using 16-bit is this instruction :P
cmp dx, 256
je .Lzero
// Otherwise, jump to the top of the loop
jmp .Lloop
.Lret:
// Return
ret
The input is a null terminated string in si, and the output is stored to the uint16_t array in di.
di will point to the end of the array to indicate the length (C++ <algorithm> style)
Try it online! Uses GAS Intel syntax because I want to use libc with it, and uses macros for registers to make it possible to switch to 64-bit arithmetic.
Lua (LuaJIT), 153 151 bytes
t={}v=0;loadstring(s:gsub('.',{d='v=v-1;',i='v=v+1;',s='v=v*v;',o='t[#t+1]=v;'}):gsub(';',';v=(v==256 or v<0)and 0 or v;'))()print(table.concat(t,','))
C (gcc), 92 91 bytes
Thanks to ceilingcat for the -1.
Converts each operation into the range [0,3] to simplify the decoding process.
a,b;f(char*s){for(a=0;b=*s++/2;a*=a-256&&~a)(b&=3)?--b?--b?printf("%i ",a):a--:(a*=a):a++;}
Java (JDK), 98 bytes
s->{int a=0;for(var c:s){if((c%=7)>5)System.out.println(a);a=c%5<3?1-c%5+a:a*a;a=a<0|a==256?0:a;}}
Rust, 119 bytes
Closure with a single parameter of type Iterator<Item = u8> with ASCII bytes
|s|{let mut a=0;for c in s{a=match c{105=>a+1,100=>a-1,115=>a*a,111=>{println!("{}",a);a},_=>a};if a==-1||a==256{a=0}}}
Try it online! (with caller function)
Ungolfed version
|s|{
let mut a = 0;
for c in s {
a = match c {
105 => a + 1,
100 => a - 1,
115 => a * a,
111 => { println!("{}", a); a },
_ => a
};
if a == -1 || a == 256 { a = 0 }
}
}
AWK, 83 81 bytes
Thanks to Dominic van Essen for shaving off 2 bytes...
{for(;c=$++b%9;)printf c-3?(d=(x=c-6?c-1?d*d:--d:++d)<1?0:x==256?0:x)?f:f:+d"\n"}
This is pretty brute force, but it's ugly enough that I wanted to submit it. :) It's mostly abusing ternaries to save characters.
The input is code points separated by spaces as commandline arguments. The code converts them to modulo-9 to shorten the comparisons to the specific command values.
There's a minor trick on the printf line that might be worth highlighting.
printf c-3?..not-a-print-command..:d"\n"
prints the accumulator value when a o command is found.
The logic in the "truthy" part updates the accumulator, but always returns a value of f. Since that's a uninitialized variables, AWK picks a value based on the content where it's used. In this context it turns into a null string, so printf doesn't produce any output for non-o commands.
The code to update the accumulator is bundled into the print statement, so it's only called for a, d, i, and s commands. As result it doesn't have to check for o.
05AB1E, 23 22 21 bytes
-1 -2 bytes thanks to Command Master!
Takes input as a list of codepoints.
õ?Îv">n<="y;è.VD₁^0›*
Commented:
õ? # print the empty string without a trailing newline
# this is necessary to disable implicit output if no 'o' is in the code
Î # push 0 and the input
v # iterate over the instructions y in the input:
">n<=" # push string literal ">n<="
# These are the instructions in 05AB1E equivalent to "isdo"
y # push the current instruction
; # halve the instruction
è # modular index into the instruction string
.V # execute the instruction
D # duplicate the current value
₁^ # XOR with 256
0› # is this larger than 0?
* # multiply the result with the current value
# x*(x^256>0) maps negative numbers and 256 to 0
PowerShell 7, 74 bytes
$args|%{switch($_){i{$x++}d{$x--}s{$x*=$x}o{+$x}}$x=1+$x-and$x-256?$x :0}
Link is to a slightly longer PS 6 solution, as TIO does not yet have PS 7. Try it online!
R, 111 91 bytes
-20 bytes thanks to CriminallyVulgar
C=scan(,'');n=0;for(x in C){if(n%in%c(-1,256))n=0;n=switch(x,i=n+1,d=n-1,s=n^2,o=print(n))}
Stax, 37 35 bytes
ï☺C£q▒▒v¡ñ|≥íHQ3╤Ä╫Q,§╪c(>∙α._A↓ö≈/
I only need one more byte to not blow up on a trailing newline in the input
saved two bytes thanks to Razetime
><>, 81 bytes
Not the dead one :)
0v~$?$0+{="Ā":}=-10<
l<n:oav?="i"{v?="d"}:{v?="s"}:{;?=1
{~:*1-> 2+0}>{~1-:v >
Branching is the kryptonite of ><> terseness, so the golfiness here was creating a branchless -1 and 256 check ~$?$0+{="Ā":}=-10 backwards on the first line to get rid of whitespace. The s, i and d commands also feed into each other to make the layout manageable.
Nim, 104 bytes
var r=0
for c in stdin.readAll:
r=[r*r,r,r+1,r-1][28-c.ord div 4];r*=int (r xor 256)>0;if c=='o':echo r
Based on @ovs's amazing Python answer.
Nim, 120 114 109 bytes
var r=0
for c in stdin.readAll:
case c
of'i':r+=1
of'd':r-=1
of's':r*=r
else:r.echo
if r in[-1,256]:r=0
This is embarassingly readable.
-5 bytes by taking inspiration from @Gotoro's Python answer
Racket, 178 bytes
(define(f s[a 0])(unless(null? s)(let([x(car s)][y(cdr s)][b(match a[-1 0][256 0][_ a])])(match x[105(f y(+ b 1))][100(f y(- b 1))][115(f y(* b b))][_(and(writeln b)(f y b))]))))
More readable:
(define (f s [a 0])
(unless (empty? s)
(let ([x (first s)]
[y (rest s)]
[b (match a
[-1 0]
[256 0]
[_ a])])
(match x
[105 (f y (+ b 1))]
[100 (f y (- b 1))]
[115 (f y (* b b))]
[_ (and (writeln b)
(f y b))]))))
Python 2, 83 82 76 74 bytes
Thanks to dingledooper for spotting a bug and -6 bytes!
-2 bytes thanks to Mukundan!
Takes input as a list of codepoints.
a=0
for x in input():
a=[a-1,a+1,a,a*a][x/6%4];a*=a^256>0
if x%5:print a
MathGolf, 23 bytes
0ÿ)²(o▒ê½§"_♠bαm¡╓*"u~╘
Input as a list of codepoint integers.
Explanation:
0 # Start with 0
ÿ)²(o # Push 4-char string ")²(o"
▒ # Convert it to a list of characters: [")","²","(","o"]
ê # Push the input-list of codepoint integers
½ # Integer-divide each by 2
§ # Index (modulair 0-based) them into the list of characters
"_♠bαm¡╓*"u # Join these characters with "_♠bαm¡╓*" delimiter
~ # Execute the entire string as MathGolf code
╘ # Discard everything left on the stack (which otherwise would be
# output implicitly)
) # Increase by 1
² # Square
( # Decrease by 1
o # Print without popping
_ # Duplicate the top of the stack
♠bα # Push 256, push -1, wrap them in a list: [256,-1]
m # Map over both of them:
¡ # And check that they're NOT equal to the value we've duplicated
# (0 if the duplicated value is -1 or 256; 1 otherwise)
╓ # Pop and get the minimum of this list
* # Multiply it to the value
Husk, 26 25 bytes
tGF₅0hx'o
S&≠256!ë→a□?←0c
Explanation
The first line is the main program, the second line an helper function that computes the output of a Deadfish command that could be 'i', 'd' or 's'.
Let's start from the first line:
tGF₅0hx'o
x'o Split the string on each 'o'
h and discard the last part
(we don't care what happens after the last 'o')
G 0 Scan this list of strings using 0 as initial value
F₅ computing the result of each Deadfish subprogram
t Discard the first value (0)
What we are doing here is splitting the Deadfish code into the subprograms preceding each output 'o', and then computing the result of each subprogram.
The result of a subprogram is computed by folding the helper function over the commands: the fold will start with the value of the accumulator coming from the previous subprogram (initially 0), and will apply the helper function to the next command and the accumulator to generate the new value for the accumulator.
Lines in a Husk program are zero-indexed and modular: referring to line ₅ here is effectively the same as referring to line ₁, but the number of times we "loop around" back to the first line determines how the called function should be modified (in order argdup,flip,map,zip,hook); in this case we loop around 2 times, so we flip the helper function, passing the command ('i','d',or 's') first, and the accumulator second.
We chain together the interpretations of the subprograms by scanning over the list of subprograms. A scan G is the same thing as a fold F, except it returns all partial results instead of only the final one. We explicitly set 0 as the initial value, but then the result of each subprogram will be passed as the accumulator to the next subprogram. The initial value is always part of the output for a scan, so we have to discard it at the end (t).
So, how does the helper function compute the result of a Deadfish command?
S&≠256!ë→a□?←0c Takes a character (one of "ids") and an accumulator,
returns the new value for the accumulator
c Convert the character to its codepoint value
!ë and use it to index into this list of four functions:
→ Increment
a Absolute value (dummy)
□ Square
?←0 If nonzero then decrement else return 0
S&≠256 Return the result if ≠256, else 0
The trick here is that ord(c)%4 will return a different value for each c in "ids" (respectively 1,0,3). List indexing in Husk is modular so by indexing with this value into the list of functions we will get the function we need. a is there only to pad the list to 4 elements (because otherwise 's' and 'd' would have the same value modulo 3).
We check for -1 by only decreasing the accumulator if its value is not 0, and we check for 256 explicitly after any command.
Batch, 157 bytes
@set a=0
@for %%c in (%*) do @call:%%c
:s
@set/aa=a*a-1
:i
@set/aa+=2
:d
@set/aa-=1
@if %a%==-1 set a=0
@if %a%==256 set a=0
@exit/b
:o
@echo %a%
Takes each Deadfish command as a separate command-line argument. Explanation:
@set a=0
Initialise the accumulator.
@for %%c in (%*) do @call:%%c
Loop through all of the commands, executing each in turn, then fall through into performing an additional s command, whose effect is non-observable.
:s
@set/aa=a*a-1
For the s command, square the accumulator and decrement it, then fall through to the i command, which increments it again.
:i
@set/aa+=2
For the i command, add 2 to the accumulator, then fall through to the d command, which decrements it.
:d
@set/aa-=1
For the d command, decrement the accumulator.
@if %a%==-1 set a=0
@if %a%==256 set a=0
@exit/b
Adjust the accumulator if necessary, then return for the next command.
:o
@echo %a%
For the o command, output the accumulator, then implicitly return for the next command.
204 bytes taking input as a single string (probably actually not the best approach; the call-and-fall through approach above could probably save 10 bytes):
@set/ps=
@set a=0
:l
@if "%s%"=="" exit/b
@for %%a in (1+1.i 1-1.d a.s)do @if %%~xa==.%s:~,1% set/aa=a*%%~na
@if %s:~,1%==o echo %a%
@set s=%s:~1%
@if %a%==-1 set a=0
@if %a%==256 set a=0
@goto l
Takes input on STDIN. Explanation:
@set/ps=
@set a=0
Read the commands and clear the accumulator.
:l
@if "%s%"=="" exit/b
Loop until there are no commands left.
@for %%a in (1+1.i 1-1.d a.s)do @if %%~xa==.%s:~,1% set/aa=a*%%~na
If the command is an arithmetic operation then perform the calculation: a=a*1+1 for i, a=a*1-1 for d and a=a*a for s; it's not possible to use * in a for loop because it's always a wildcard and cannot be quoted (unlike =, which can be quoted).
@if %s:~,1%==o echo %a%
If the command is an o then output the accumulator.
@set s=%s:~1%
Remove the command from the input.
@if %a%==-1 set a=0
@if %a%==256 set a=0
@goto l
Adjust the accumulator if necessary and loop.
Arturo, 80 bytes
$[p][r:0loop p'c[do[[r:r*r][print r][r:r+1][r:r-1]]\28-c/4if or? r<0r=256[r:0]]]
A function that takes an array of codepoints and prints numbers separated by newlines.
PowerShell, 68 bytes
switch -r($args){i{$a++}d{$a--}s{$a*=$a}o{+$a}.{$a*=$a-notin-1,256}}
flex, 86 \$\cdots\$ 83 82 bytes
Saved 2 bytes and got moved into TIO thanks to Mukundan314!!!
%{
a;m(){a*=a!=256;}
%}
%%
i m(++a);
d m(a&&--a);
s m(a*=a);
o printf("%d ",a);
%%
flex stands for fast lexical analyser generator. It takes input as above and generates a lexer in C.
The input comprises of a C declaration section:
%{
a;m(){a*=a!=256;}
%}
where here we simply declare the accumulator a (implicitly as an int) and a function to set the accumulator to \$0\$ if it's \$256\$ after a computation.
This is followed by the rules section comprised of all the regexes that need to be parsed along with their actions (in C):
%%
i m(++a);
d m(a&&--a);
s m(a*=a);
o printf("%d ",a);
%%
here we have our 4 characters along with the code to run when each is encountered. Decrement will only happen if the accumulator is non-zero.
There's a program section that follows this but it will simply default to a main that runs the parser if left out (as in this case).
You can generate the C-source code lexer from the above (in file deadfish.l) and compile it with the following:
flex deadfish.l
gcc lex.yy.c -o deadfish -lfl
After compiling, running the following:
echo iissso | ./deadfish
echo diissisdo | ./deadfish
echo iissisdddddddddddddddddddddddddddddddddo | ./deadfish
echo isssoisoisoisoiso | ./deadfish
echo ooooosioiiisooo | ./deadfish
echo iiiiiiiissdiiiiiiiiiiiiiiiiio | ./deadfish
outputs:
0
288
0
1 4 25 676 458329
0 0 0 0 0 1 16 16 16
4112
You can also just run it as ./deadfish and have an interactive deadfish environment to play with to your heart's content!
PowerShell, 118 bytes
$args[0]|% t*y|%{if($a-in@(-1,256)){$a=0}if($_-eq'i'){$a+=1}elseif($_-eq'd'){$a-=1}elseif($_-eq's'){$a=$a*$a}else{$a}}
AWK, 55 53 52 51 bytes
Thanks to user41805 for removing awk flags
Expects each operation to be on a separate line
{a*=a!=256}/i/{a++}/d/{a&&a--}/s/{a*=a}/o/{print+a}
Explanation
{a*=a!=256} # Before each operation multiply a by 0 if it equals 256
/i/{a++} # If line contains 'i' increase a by 1
/d/{a&&a--} # If line contains 'd' and a is non-zero decrement a by 1
/s/{a*=a} # If line contains 's' square a
/o/{print+a} # If line contains 'o' output a
Jelly, 25 24 bytes
:4ị⁾’‘;⁾Ṅ²¤j“-,⁹¤i¬×Ʋ”VZ
Interprets a Deadfish program given as a list of codepoints in a command-line argument, printing newlines between the numbers, then crashes with a TypeError.
Without the last two characters, it's a Deadfish to Jelly transpiler.
Explanation
:4ị⁾’‘;⁾Ṅ²¤j“-,⁹¤i¬×Ʋ”VZ Main monadic link
:4 Integer divide by 4
ị Index into
⁾’‘;⁾Ṅ²¤ "’‘Ṅ²"
’ Decrement
‘ Increment
Ṅ Print with newline
² Square
j Join with separator
“-,⁹¤i¬×Ʋ” "-,⁹¤i¬×Ʋ"
-,⁹¤ [-1, 256]
i Find 1-based index
¬ Negate
× Multiply by the number
Ʋ Group this into one instruction
V Evaluate (implicitly starting with 0)
Z Zip — a number can't be zipped,
so this crashes the program in order to
suppress the implicit output
Red, 106 bytes
func[s][a: 0 parse s[any[(if a xor 256 < 1[a: 0])"i"(a: a + 1)|"d"(a: a - 1)|"s"(a: a * a)|"o"(print a)]]]
Pretty simple solution :
f: func[s][
a: 0
parse s[
any[
(if a xor 256 < 1[a: 0])
"i"(a: a + 1)
|"d"(a: a - 1)
|"s"(a: a * a)
|"o"(print a)
]
]
]
PHP, 136 bytes
<?php $w=0;foreach(str_split($argv[1])as$v){if($v=='o'){echo$w.' ';}else{$w=$v=='s'?$w**2:($v=='i'?++$w:--$w);}if($w==256||$w<0){$w=0;}}
Example explained:
$w=0; #declare w var, is accumulator
foreach(str_split($argv[1])as$v){ # for each char of first CLI argument
if($v=='o'){ #if output
echo$w.' '; #output w
}else{ #otherwise
$w= #set w to
$v=='s'? #if input is s
$w**2 #squared
:($v=='i'? #otherwise if incremented
++$w: #add one
--$w);} #otherwise subtract one
if($w==256||$w<0){$w=0;}} #if -1 or 256 set 0
PHP is annoying for this.
Is run php deadfish.php <program>
Note: run on CLI so no online example.
Python 3, 120 95 bytes
n=0
for x in input():
if n in(-1,256):n=0
if"o"==x:print(n)
else:n=[n+1,n-1,n*n][ord(x)%4^1]
Brought it down by 25 bytes thanks to Danis suggestion!
Using bit manipulation ^ we choose from the list of possible operations.
Original suggestion used ord(x)%4^2 which yielded 0,1,2,3 for indexes and required the use of an additional 0 in the list at the index 0;
using ^1 instead yields 0,1,2, which allows to save 2 bytes in comparison.
Maybe it is possible to account for that additional 0 and use it as a condition to print o instead.(?)
Icon, 106 bytes
procedure f(s);a:=0
c:=!s&(if a:=[a+1,a-1,a*a][find(c,"ids")]then 1>ixor(a,256)&a:=0 else write(a))&\z
end
Ruby, 60 58 bytes
Saved 2 bytes thanks to @Sisyphus
a=0;$<.bytes{|b|a=0if(a=eval'~-~p a*'[b%20/3,2]+?a)^256<1}
Try it online or verify all test cases.
Full program that reads a string from STDIN and outputs to STDOUT, one number per line.
Each operation on the accumulator a is carried out by evaling a 3-byte string. The third byte is always a. The first two bytes are extracted from the string ~-~p a* starting at index b%20/3:
| Op | \$b\$ | \$\left\lfloor\frac{b\bmod20}{3}\right\rfloor\$ | eval |
|---|---|---|---|
d |
\$100\$ | \$0\$ | ~-a |
i |
\$105\$ | \$1\$ | -~a |
o |
\$111\$ | \$3\$ | p a |
s |
\$115\$ | \$5\$ | a*a |
The reset conditions on the accumulator, which might be written a==-1||a==256 in ungolfed form, are replaced by the single condition a^256<1 (^ is bitwise XOR) because negative accumulator values other than \$-1\$ are not possible.
Wolfram Language (Mathematica), 60 bytes
Fold[<|i->#+1,d->#-1,s->#^2,o:>Echo@#|>@#2/.-1|256->0&,0,#]&
Input a list of symbols.
JavaScript (ES10), 66 bytes
Expects a list of codepoints.
a=>a.flatMap(n=>n%5?p:(p=(p=[p-!!p,p+1,,p*p][n&3])-256&&p,[]),p=0)
How?
o is the only command whose codepoint (\$111\$) modulo \$5\$ is not equal to \$0\$. This is also the only command that requires a special operation that doesn't update the accumulator. That's why we first test that.
If the first modulo is \$0\$, we apply a modulo \$4\$ to distinguish between the other commands and update the accumulator accordingly.
char. | code | mod 5 | mod 4
-------+------+-------+-------
'd' | 100 | 0 | 0
'i' | 105 | 0 | 1
'o' | 111 | 1 | (3)
's' | 115 | 0 | 3
Charcoal, 37 bytes
≔⁰θFS«F№⟦²⁵⁶±¹⟧θ≔⁰θ≡ιi≦⊕θd≦⊖θs≧X²θ⟦Iθ
Try it online! Link is to verbose version of code. Explanation:
≔⁰θ
Initialise the accumulator to 0.
FS«
Loop over the commands.
F№⟦²⁵⁶±¹⟧θ
If the list (256, -1) includes the accumulator...
≔⁰θ
... then set the accumulator to 0. (This is done before the operation because it's golfier, and doesn't change the result, since it still always happens between two operations, and whether it happens after the last operation isn't observable.)
≡ι
Switch on the current operation: ...
i≦⊕θ
... i means increment the accumulator; ...
d≦⊖θ
... d means decrement the accumulator; ...
s≧X²θ
... s means square the accumulator; ...
⟦Iθ
... otherwise print the accumulator on its own line.
Retina, 61 bytes
\bi()|#?\bd|^(#*)s
$#1*#$.2*$2
^#{256}\b
m}`^(#*)o
$.1¶$1
#
Try it online! Link includes test cases, although they can be a bit slow (I think #?\bd is the slow case, but I'm not sure). Explanation:
\bi()|#?\bd|^(#*)s
$#1*#$.2*$2
Handle the i, d and s cases by inserting a # (for the i case), deleting an optional # (for the d case, also handling a d of 0) or squaring the number of #s (for the s case).
^#{256}\b
But if the value is exactly 256, then set it back to 0 (assuming that there's another operation, otherwise the remaining #s are ignored anyway).
^(#*)o
$.1¶$1
Handle the o case by prepending a decimal copy of the current number of #s on a previous line.
m}`
Evaluate the above stages until there are no more letters to process; also turn on multiline matching for all of the stages.
#
Delete any remaining accumulated unary value.
convey, 90 76 bytes
{"='i'
0+#<
^v"='d'
^-#<
^v"='s'
^*#+1
^.=<'o'
^>@`
^}",
*<<"=256
.="*.
0-1
On the top right side, the input gets compared with idso. The result (0 or 1) then gets combined with the accumulator: a += c == 'i', a -= c == 'd', a = pow(a, (c == 's') + 1) (pow = *.), and o pushes a copy into the output @"}. At the bottom are the checks for -1/256, by calculating a *= a != 256 and a *= a != -1. Then the accumulator loops back to start the next round.
One iteration of the accumulator loop:

