32
\$\begingroup\$

Deadfish is a joke "programming language" with four commands. Because the Esolang page is a bit contradictory and the interpreters on that page don't all work exactly the same, you should implement the following variation:


Specification

  1. There is an accumulator which is at least 16 bits in size, more is allowed but less is not. Negative numbers do not need to be supported. The accumulator is 0 when the program starts.
  2. There are the following two sets of four commands, and your program must support both at the same time.
      Standard Deadfish    │   XKCD Variant   │    Meaning
      ─────────────────────┼──────────────────┼────────────────────────────────────
            i              │        x         │    Increment accumulator
            d              │        d         │    Decrement accumulator
            s              │        k         │    Square ( acc = acc * acc )
            o              │        c         │    Output accumulator, as a number
    
  3. If, after executing a command, the accumulator is either -1 or 256, the accumulator must be reset to zero. Note that this is not normal wrap-around. If, say, the accumulator is 20, and the s command is run, the accumulator should be 400 afterward. Similarly, if the accumulator is 257 and the d command is run, the accumulator should become 0.
  4. Any input that isn't one of these commands should be ignored.

Test programs

  • xiskso should output 0
  • xiskisc should output 289

I/O

Your program should display a prompt: >>. The prompt must be at the beginning of a new line. It should then read a line of user input, and run the given commands left-to-right. When outputing numbers, the numbers must be separated. I.e., 12 34 is OK, 12,34 is OK,

12
34 

is OK, but 1234 is not.

Your program should keep doing this in a loop, at least until EOF is reached.

Example session:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
\$\endgroup\$
7
  • \$\begingroup\$ Because of the prompting for input, I can't use GolfScript :-( \$\endgroup\$
    – ProgramFOX
    Commented Dec 22, 2013 at 10:04
  • \$\begingroup\$ @ProgramFOX: You can use ruby input right? \$\endgroup\$
    – marinus
    Commented Dec 23, 2013 at 6:02
  • \$\begingroup\$ According to the GolfScript tutorial, you can't prompt for input in GolfScript, all input comes from STDIN. \$\endgroup\$
    – ProgramFOX
    Commented Dec 23, 2013 at 8:22
  • \$\begingroup\$ @ProgramFOX: I would have thought something like #{STDIN.gets} would work but indeed it doesn't. \$\endgroup\$
    – marinus
    Commented Dec 23, 2013 at 8:33
  • \$\begingroup\$ Are we allowed to take input with uppercase letters instead? \$\endgroup\$
    – lirtosiast
    Commented Jul 4, 2015 at 20:06

36 Answers 36

1
2
0
\$\begingroup\$

C#, 311 bytes

using System;class p{static void Main(){int a=0;int s(int b)=>b==-1||b==256?0:b;while(true){Console.Write(">>");var c=Console.ReadLine();for(int i=0;i<c.Length;i++){switch(c[i]){case'i':case'x':a=s(a+1);break;case'd':a=s(a-1);break;case's':case'k':a=s(a*a);break;case'o':case'c':Console.WriteLine(a);break;}}}}}

would be 283 byte if usings and class declaration etc could be ommitted by just providing a function definition

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

05AB1E, 50 bytes

0[„>>,I"idsoxdkc"©Ãε®skн}"><n="sè"Džz1(‚såi0}"ý.V 

Try it online!

Explanation:

The basic idea is to translate it into 05AB1E code and eval it.

0[„>>,I"idsoxdkc"©Ãε®skн}"><n="sè"Džz1(‚såi0}"ý.V
0                                                    Set the accumulator to 0.
 [                                                   Do this forever.
  „>>,                                               Print ">>"
      I                                              Read input
       "idsoxdkc" Ã                                  Keep only "idsoxdkc" characters.
                 ©                                   Also put "idsoxdkc" in the register.
                   ε    }                            For each character in the filtered input:
                    ®skн                             Find it's index in "idsoxdkc"
                         "><n="sè                    Index into "><n="
                                 "Džz1(‚såi }"ý      After each command, check if accumulator = -1 or 256
                                           0         If it does, change it to 0
                                               .V    Evaluate as 05AB1E code.
\$\endgroup\$
0
\$\begingroup\$

Tidy, 136 bytes

a:=0{h:a:=a+1 if h='i∨h='xa:=a-1 if h='da:=a*a if h='s∨h='kout(a)if h='o∨h='ca:=0 if a=-1∨a=256}→stoa(h)while h:=prompt(">> ")

Try it online! prompt is interactive, so it looks a bit weird online. See the "Example run" section below.

Ungolfed and commented

? initialize the accumulator
acc := 0

map(

    ? map this function...
    { char :
        acc := acc + 1      if char = 'i  or  char = 'x
        acc := acc - 1      if char = 'd
        acc := acc * acc    if char = 's  or  char = 'k
        out(acc)            if char = 'o  or  char = 'c
        acc := 0            if acc  = -1  or  acc  = 256
    },

    ? over each character...
    stoa(line)

? over each line
) while line := prompt(">> ")

Example run

C:\Users\conorpc\Programming\Tidy (master -> origin)
λ tidy test.tidy
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
\$\endgroup\$
0
\$\begingroup\$

Emojicode, 308 bytes

🏁🍇0➡️🖍🆕a🔁👍🍇😀🔤>>🔤❗️🔂c🆕🔡👂🏼❗️🍇↪️🔍🔤dxdiksco🔤c❗️➡️i🍇↪️i◀4🍇a⬅️➕i🚮2✖2➖1🍉🙅↪️i◀6🍇a⬅️✖️a🍉🙅🍇😀🔡a 10❗️❗️🍉↪️a🙌-1👐a🙌256🍇0➡️🖍a🍉🍉🍉🍉🍉

Try it online here.

Ungolfed:

🏁 🍇  💭 Main code block
    0 ➡️ 🖍 🆕 a  💭 Accumulator, initialised to 0
    🔁 👍 🍇  💭 Repeat forever:
        😀 🔤>>🔤 ❗️  💭 Output prompt
        🔂 c 🆕 🔡 👂🏼 ❗️ 🍇  💭 For each character c in the next line of input:
            ↪️ 🔍 🔤dxdiksco🔤 c ❗️ ➡️ i 🍇  💭 If the character is a valid command, get its index i in the string "dxdiksco"
                ↪️ i ◀ 4 🍇  💭 If that index is less than 4, it is either the increment or the decrement command ...
                    a ⬅️ ➕ i 🚮 2 ✖ 2 ➖ 1  💭 ... adjust accumulator accordingly
                🍉
                🙅 ↪️ i ◀ 6 🍇  💭 Else, if it is smaller than 6, it is the square command ...
                    a ⬅️ ✖️ a  💭 ... multiply the accumulator by itself
                🍉 🙅 🍇  💭 Else, it must be the print command ...
                    😀 🔡 a 10 ❗️❗️  💭 .. output the accumulator in base 10, followed by a line feed
                🍉
                ↪️ a 🙌 - 1 👐 a 🙌 256 🍇  💭 If the accumulator is now either -1 or 256 ...
                    0 ➡️ 🖍 a  💭 ... reset it to 0
                🍉
            🍉
        🍉
    🍉
🍉
\$\endgroup\$
0
\$\begingroup\$

Pip, 70 bytes

W(O">> ")&#YqR'i'xFcy@`[xkcdso]`;V("U SQ:  P i&D SQ:"^sAc)."i*:i!=256"

(-1 byte if no space is needed after the >>, which is what the accepted answer does but is contrary to the example given in the question. +1 byte if an empty line isn't an acceptable way of marking end-of-input.)

Try it here!

Explanation

The core of the interpreter is based on my answer to the other Deadfish question, with some reshuffling to accommodate the xkcd input, so I won't repeat that part of the explanation. The interaction loop is as follows:

W                                 While...
  O">> "                           Output the prompt with no newline
 (      )&                         Logical AND that (nonempty string, truthy) with...
            q                      Read a line of input
             R'i'x                 Replace all i's with x's
           Y                       Store it in y
          #                        Take the length
                                  So, loop while (prompt and read input) is nonempty:
                                    [translate and eval all valid commands in y]
\$\endgroup\$
0
\$\begingroup\$

AWK, [133] 122 bytes

gsub(z,FS){for(a=0;b=$++a;c==-1||c==256?c=0:0)if(b~"o"||b~"c")print c;else b~"i"||b~"x"?c++:b~"d"?c--:b~"s"||b~"k"?c*=c:0}

Try it online!

Thanks to user41805 for hints that dropped 11(!) chars

This is pretty straight forward in the end. I think the only reason it's somewhat short is that AWK is essentially a state machine, which fits the problem pretty well.

gsub(z,FS)

Splits the input line such that each letter is one positional field.

{for(a=0;b=$++a; ... ) ... }

Loops through all the positional variables (one letter for each one).

c==-1||c==256?c=0:0

The end of loop statement just handles the wrap around code, resetting the accumulator c when it hits -1 or 256.

if(b~"o"||b~"c")print c;else ...

The print command can't be handled by the nested ternary that deals with all the other commands, since in AWK print doesn't return a value. So that's pulled out into an if/then/else statement.

b~"i"||b~"x"?c++:b~"d"?c--:b~"s"||b~"k"?c*=c:0

Handles all the other commands, adjusting the accumlator c as necessary.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ $0 is implicit in gsub and can be removed. " " can be replaced with FS. Also the b=="..."'s can be replaced with b~"...". \$\endgroup\$
    – user41805
    Commented Sep 11, 2021 at 11:43
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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