32
\$\begingroup\$

My stovetop has 10 (0 through 9) different settings of heat and a very odd way of cycling through them.

  • It always starts at 0

  • When I hit plus it increments the number, unless the number is 9 in which case it becomes 0, or the number is 0 in which case it becomes 9.

  • When I hit minus it decrements the number, unless the number is zero in which case it becomes 4.

There are no other temperature control buttons.

In this challenge you will take as input a string of commands and output which setting my stovetop ends up on after running that sequence.

Answers will be scored in bytes with fewer bytes being better.

Input

You may take input in any of the following formats:

  • A list/array/vector/stream of booleans/1s or 0s/1s or -1s
  • A string (or list/array/vector/stream) of two different characters (which should be consistent for your program)

And you may output

  • An integer on the range 0-9.

  • A character on the range '0'-'9'.

  • A string of size 1 consisting of the above.

Testcases

Input as a string - for decrement and + for increment.

 : 0
- : 4
+ : 9
-- : 3
-+ : 5
+- : 8
++ : 0
--- : 2
--+ : 4
-+- : 4
-++ : 6
+-- : 7
+-+ : 9
++- : 4
+++ : 9
---- : 1
---+ : 3
\$\endgroup\$
11
  • 1
    \$\begingroup\$ (I see that this is a relatively weird input format) Can I take input like this f(f(f(0,M),M),P)? (for the string MMP) What about (M)(M)(P)? \$\endgroup\$
    – DELETE_ME
    Feb 1 at 10:26
  • 1
    \$\begingroup\$ @user202729 No. \$\endgroup\$
    – Wheat Witch
    Feb 1 at 10:35
  • 1
    \$\begingroup\$ @user202729 If it is a standard way of taking input you don't need to ask. If it is not then either it should be, in which case you should bring that up in the relevant place on meta, or it shouldn't be in which case I don't intend to permit it. \$\endgroup\$
    – Wheat Witch
    Feb 1 at 11:13
  • 2
    \$\begingroup\$ @Jonah Under the equivalence by temperature (+ = +++ because they both give 9), they certainly don't form a group. Something like 5+9 is not well defined (9 can be represented by any odd number of +s so 5+9 could be 6, 8 or 0). Under the equivalence of the sequences themselves, they also don't form a group. They are isomorphic binary strings under concatenation and thus don't have an inverse. You can relax the latter into a category, and try some other stuff but nothing really interesting come out of it. I don't think this corresponds to any mathematical structure of any note. \$\endgroup\$
    – Wheat Witch
    Feb 1 at 16:25
  • 1
    \$\begingroup\$ A related question could be "Take as input the initial temperature and the final temperature and output the necessary increment/decrement sequence." \$\endgroup\$
    – LorenDB
    May 22 at 13:36

40 Answers 40

10
\$\begingroup\$

JavaScript (ES6),  38 37  36 bytes

Expects an array of Boolean values, with false for + and true for -. Returns an integer.

a=>a.map(c=>a=a++?c?a-2:a%10:9>>c)|a

Try it online!

Commented

It's important to note that a++ with a = [ true ] is evaluated to NaN because it's first coerced to the string "true" and then to a number. That's why we can safely re-use the array a[] to store the temperature even when we get the singleton [ true ] as input.

a =>             // a[] = input array, re-used to store the temperature
  a.map(c =>     // for each command c in a[]:
    a =          //   update the temperature:
      a++ ?      //     if a is numeric and not equal to 0
                 //     (increment it afterwards):
        c ?      //       if this is a '-':
          a - 2  //         subtract 2
        :        //       else:
          a % 10 //         apply a modulo 10
      :          //     else:
        9 >> c   //       yield 4 if this is a '-', or 9 if this is a '+'
  ) | a          // end of map(); return the final result
\$\endgroup\$
7
\$\begingroup\$

PHP, 103 90 86 bytes

foreach(str_split($argv[1])as$k){$k?($p?($p>8?$p=0:$p++):$p=9):($p?$p--:$p=4);}echo$p;

Example explained

//note: p is setting var
foreach(str_split($argv[1])as$k){ // go through input
$k?    // if 1 (+) then...
  ($p?   // if p isnt 0 then...
    ($p>8? // if p is 9 then...
     $p=0:  // set p to 0
     $p++)  // else increment p
    :$p=9)  //else (if p is 0) set p to 9
:($p? // else, if 0 (-)
$p--: //decrement p
$p=4); //or if p is 0, set 
}echo$p; // print setting

Try it online! - Add string as argument - 0 for -, 1 for +. Example: for ---+, 0001.

Thanks to @Kaddath for -13 bytes (see comment). -4 by changing input format to 0/1.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ -13 bytes with some further golf: no need to init $p, used $k<'-' instead of $k=='+' (compared by ascii order), replaced $p==0 by $p with ternary alternatives the other way round, and replaced $p==9 by $p>8. Also you don't need the curly braces for the foreach (only one instruction) \$\endgroup\$
    – Kaddath
    Feb 1 at 11:08
6
\$\begingroup\$

Rust, 46 bytes

|x|x.fold(0,|u,v|if u>0{u-v*2+1}else{9>>v}%10)

Try it online!

Takes an Iterator of zeros (for +) and ones (for -), and returns the resulting stove temperature. Taking -1s and 1s doesn't seem to help, because (-1,1) -> (4,9) isn't trivial to represent in integer arithmetic.

Uses Arnauld's input method and bit-shift trick for the zero case. Also, Rust's if-else expression can be a part of larger expression, so %10 is factored out to avoid the parentheses in (u-v*2+1)%10.

\$\endgroup\$
6
\$\begingroup\$

convey, 41 bytes

Takes in a list of 0 for + and 1 for -.

  }{
0>?@`"+1
^ 1-0=v
`15|8*v
|<<,<+<
^10

Try it online!

stove

a loops around and based on the input } goes @ down towards -1 and mod 15 |15 (to set -1 to 14), or goes to +1 and + ((a=0) * 8) – thus gets set to 9 if n was 0. We join both paths , and with mod 10 |10 we get 14 -> 4, 10 -> 0. If the input is empty, a goes on ? to the side path to the output }.

(The ^ next to the 10 shouldn't be necessary, but I haven't fixed the bug yet.)

\$\endgroup\$
6
\$\begingroup\$

C (clang), 58 \$\cdots\$ 56 54 bytes

t;f(*s){for(t=0;*s;)t=*s++-7?t?t-1:4:t?-~t%10:9;*s=t;}

Try it online!

Saved a 3 bytes thanks to Johan du Toit!!!

Inputs a string of minuses and pluses bell-characters (ASCII 7) and returns the stovetop temperature in the input string (right at the end where the '\0' terminator would have been).

\$\endgroup\$
15
  • \$\begingroup\$ You could save one character by using a one-digit encoded character instead of '+', but it's just one byte. Upvoted. \$\endgroup\$ Feb 1 at 12:40
  • 1
    \$\begingroup\$ @Davide I just did that 2 minutes ago! T_T But my comment was backwards - fixed! :) \$\endgroup\$
    – Noodle9
    Feb 1 at 12:41
  • \$\begingroup\$ Ahaha I swear that I didn't see it! I was busy modifying the TIO to see if you could use an array of int instead. \$\endgroup\$ Feb 1 at 12:44
  • \$\begingroup\$ -1 byte \$\endgroup\$
    – upkajdt
    Sep 8 at 18:13
  • \$\begingroup\$ @JohanduToit Nice one - thanks! :D \$\endgroup\$
    – Noodle9
    Sep 8 at 19:45
5
\$\begingroup\$

05AB1E, 16 15 14 12 bytes

Input as a list of -1/1 for -/+ respectively.

ÎvD_Ƶ≠yè*yOθ

Try it online or verify all test cases.

Explanation:

Î             # Push 0 and the input-list
 v            # Loop `y` over the input-list:
  D           #  Duplicate the current value
   _          #  Pop the copy, and check that it's 0 (1 if 0; 0 otherwise)
    Ƶ≠        #  Push compressed integer 185
      yè      #  Index `y` into it (0-based modulair, so the leading 1 is ignored, while
              #  1→8 and -1→5)
        *     #  Multiply it to the ==0 boolean
         y    #  Push `y`
          O   #  Take the sum of the three values on the stack
           θ  #  And only leave the last digit (for 10→0)
              # (after the loop, the value is output implicitly as result)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ƶ≠ is 185.

\$\endgroup\$
4
\$\begingroup\$

Retina 0.8.2, 33 bytes

^
0
{T`+09d`_9d`^.\+
T`-d`_4d`^.-

Try it online! Link includes test suite. Explanation:

^
0

Start with heat setting 0.

{

Process all of the control buttons.

T`+09d`_9d`^.\+

If the control button is a plus, then delete it (by transliterating to _) and cyclically increment the digit (T`9d`d is the standard way to cyclically increment digits) but change 0 to 9 instead by listing it as an exception before the expansion of d to 0123456789.

T`-d`_4d`^.-

If the control button is a minus, then delete it and decrement the digit, but use 4 instead of the usual 9 for cyclic decrement.

\$\endgroup\$
4
\$\begingroup\$

Coconut, 39 bytes

Takes input as a list of 1/-1

reduce$((p,k)->[k%7-2,p+k][p>0]%10,?,0)

Try it online!

This uses ((-1)%7-2)%10 = (6-2)%10 = 4 and (1%7-2)%10 = (-1)%10 = 9, which works because in Python the result of the modulo operation has the same sign as the divisor.
-k%-7 would work instead of k%7-2 and is one byte shorter if we swap -1 and 1 in the input, but that feels like abusing the input format.

\$\endgroup\$
4
\$\begingroup\$

Python 2, 50 bytes

n=0
for b in input():n=[b%7-2,n+b][n>0]%10
print n

Try it online!

Takes input as ±1's. Pretty explicitly fixes the n=0 case to have b=-1 give 4 and b=1 give 9. There's probably a better way.

50 bytes

n=0
for b in input():n=((n or 9-b%5)+b)%10
print n

Try it online!

\$\endgroup\$
3
\$\begingroup\$

AWK, 47 43 bytes

Expects each operation on a separate line with + for increment and - for decrement

/-/{a?a--:a=4}/+/{a=a?++a%10:9}END{print+a}

Try it online!

\$\endgroup\$
3
\$\begingroup\$

x86-16 machine code, 40 bytes

Port of @Arnauld's answer. Be sure to upvote him! (Example run is unneccecary since it's just a port.)

0BAC:0100  31 DB E3 23 AC 84 DB 74-14 84 C0 75 04 FE CB EB   1..#...t...u....
0BAC:0110  14 FE C3 89 D8 B7 0A F6-F7 88 C3 EB 08 B3 09 86   ................
0BAC:0120  C8 D2 EB 86 C8 E2 DD C3                           ........

Callable function.

Expects [SI] = index of list (0x00 for -, 0x01 for +), CX = length of list.

Needs a spare AX.

Function output is to BL (accumulator value).

Disassembled:

0BAC:0100 31DB          XOR     BX,BX
0BAC:0102 E323          JCXZ    0127
0BAC:0104 AC            LODSB
0BAC:0105 84DB          TEST    BL,BL
0BAC:0107 7414          JZ      011D
0BAC:0109 84C0          TEST    AL,AL
0BAC:010B 7504          JNZ     0111
0BAC:010D FECB          DEC     BL
0BAC:010F EB14          JMP     0125
0BAC:0111 FEC3          INC     BL
0BAC:0113 89D8          MOV     AX,BX
0BAC:0115 B70A          MOV     BH,0A
0BAC:0117 F6F7          DIV     BH
0BAC:0119 88C3          MOV     BL,AL
0BAC:011B EB08          JMP     0125
0BAC:011D B309          MOV     BL,09
0BAC:011F 86C8          XCHG    CL,AL
0BAC:0121 D2EB          SHR     BL,CL
0BAC:0123 86C8          XCHG    CL,AL
0BAC:0125 E2DD          LOOP    0104
0BAC:0127 C3            RET
\$\endgroup\$
3
\$\begingroup\$

J, 24 bytes

Takes -1 for - and 1 for +.

0(10|15|++8*0=<.)/@|.@,]

Try it online!

0(10|15|++8*0=<.)/@|.@,]
0                    @,] prepend a 0 and …
                  @|.    rotate and …
 (              )/       fold from the left:
            0=<.         if the minimum of the step and the accumulator is 0
                           (can only happen if they are 1/0)
         +8*             add 8 to …
        +                the sum of the step and the accumulator
     15|                 mod 15 to get -1 -> 14
  10|                    mod 10 to get 10 -> 0, and 14 -> 4
\$\endgroup\$
3
\$\begingroup\$

Haskell, 45 37 bytes

0#1=9
0#a=4
9#1=0
x#a=x+a
f=foldl(#)0

Try it online!

  • Saved 8 thanks to @Wheat Wizard
\$\endgroup\$
2
  • \$\begingroup\$ 35 \$\endgroup\$
    – Wheat Witch
    Feb 1 at 16:26
  • \$\begingroup\$ And if you want to keep the same input format 39. \$\endgroup\$
    – Wheat Witch
    Feb 1 at 16:29
3
\$\begingroup\$

Perl 5 -pF, 36 bytes

$\+=$\?1-2*/-/:9-5*/-/,$\%=10for@F}{

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Nice solution! As the input format can be newline separated, you could save 5 bytes just omitting the for@F part (Try it online!), also with a bit of fudge in the -F you can save another two, replacing 5*/-/ with $#F: Try it online! \$\endgroup\$ Feb 8 at 12:52
2
\$\begingroup\$

Brain-Flak, 132 bytes

([](<()>)){({}[()]<((){[()](<(({}({})[()]{})[(()()()()()){}])((){[()](<{}>)}{}){((<{}{}>))}{}>)}{}){(<{}(((({})()){}){}{})>)}{}>)}{}

Try it online!

This loses a lot of bytes to simple equality checks (equals 0 and equals 10).

\$\endgroup\$
2
\$\begingroup\$

Python 3, 151 117 bytes

p=0
for k in input():
  if k=='+':
    if p==0:p=9
    elif p==9:p=0
    else:p+=1
  if p==0:p=4
  else:p-=1
print(p)

Try it online!

@pxeger So Nice thank you -35 bytes

\$\endgroup\$
8
2
\$\begingroup\$

CESIL , 850 bytes (including data section)

CESIL was taught in UK schools until the mid-1980s (I may have been in one of the last years that had it as an introduction before moving on to the powerhouse of BASIC).

This has been run through a parser I wrote in Python as a little exercise, each column is tab separated.

Everything has to be moved in and out of the accumulator for any function to be performed on that.

There was no real input, as it was designed for punched cards, so data has to be in a separate section at the end (I use -1 and 1 to indicate both temperature controls, and zero to terminate). It gave the correct results from the samples, but did mean I had to update the data section each time, save it, and run it again.

        LOAD    0
        STORE   HEAT
LOOP    IN
        JIZERO  END
        STORE   BUTTON
        ADD     HEAT
        STORE   TMP
* CHECK ZERO DOWN TO 4
        JINEG   ZTF
* CHECK 9 UP TO 0
        LOAD    TMP
        SUBTRACT        10
        JIZERO  NTZ
* CHECK 0 UP TO 9
        LOAD    BUTTON
        JINEG   DEC
        LOAD    TMP
        SUBTRACT        1
        JIZERO  ZTN
        LOAD    TMP
        STORE   HEAT

SHOW    LOAD    HEAT
        PRINT   "HEAT IS "
        OUT
        LINE
        JUMP    LOOP

DEC     LOAD    TMP
        STORE   HEAT
        JUMP    SHOW

END     HALT

* 0 GOES DOWN TO 4
ZTF     LOAD    4
        STORE   HEAT
        JUMP    SHOW

* 9 GOES UP TO 0
NTZ     LOAD    0
        STORE   HEAT
        JUMP    SHOW

* ZERO GOES UP TO 9
ZTN     LOAD    9
        STORE   HEAT
        JUMP    SHOW

        %
        -1
        -1
        -1
        1
        0
\$\endgroup\$
1
  • \$\begingroup\$ Never heard about CESIL before. I love the idea of teaching a low-level language to pupils. In France, my generation went through the "Plan Informatique pour Tous" which was primarily focused on Logo (aka Turtle). Better than nothing, I guess. \$\endgroup\$
    – Arnauld
    Feb 4 at 23:32
2
\$\begingroup\$

R, 57 55 bytes

f=function(x){for(i in x)F=(F+i)%%10+"if"(i>0,8,-5)*!F;F}

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ 55 bytes by using "if" instead of ifelse... \$\endgroup\$ Feb 6 at 15:47
  • \$\begingroup\$ Yes, I read about this trick only yesterday and should revisit my solutions accordingly! \$\endgroup\$
    – Xi'an
    Feb 6 at 16:17
2
\$\begingroup\$

Python 3, 92 bytes

f=lambda x,t=0:f(x[1:],{"+":{9:0,0:9},"-":{0:4}}[x[0]].get(t,t+eval(f"{x[0]}1")))if x else t

Try it online!

Expects input as a string of "-" and "+" as in the test cases.
Recursively looks up the few exceptions or defaults to adding and subtracting one based on the first character of the given string.

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! Make sure to check out our tips for golfing in Python to see if there's any way you can shorten your answer. \$\endgroup\$ Sep 9 at 15:48
2
\$\begingroup\$

TI-Basic, 52 47 bytes

Prompt A
For(I,1,dim(ʟA
If ʟA(I:Then
Ans+1+8not(Ans
Ans(Ans≤9
Else
Ans-1+5not(Ans
End
End

-5 bytes thanks to MarcMush.

Takes input as a list of 0s and 1s. Output is stored in Ans as an integer. Note that there can not be empty lists in TI-Basic, so the first test case throws an error. The below version has 8 bytes more but outputs 0 for the first test case.


60 55 bytes

Prompt Str1
For(I,1,length(Str1
If expr(sub(Str1,I,1:Then
Ans+1+8not(Ans
Ans(Ans≤9
Else
Ans-1+5not(Ans
End
End

Takes input as a string of "0"s and "1"s. Output is stored in Ans as an integer.

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

Jelly, 14 13 bytes

¹o8 5<?+%⁵µƒ0

Try it online!

-1 thanks to xigoi: -1 is always smaller than the accumulator, and the right argument to o doesn't matter if it's nonzero anyways

Takes input as 1/-1.

           ƒ     Reduce from
            0    zero
          µ      :
¹                (break the leading triple dyad pattern.)
 o               Logical OR the left argument with
  8              eight
     <?          if it is less than the right argument,
    5            else five.
       +         Add the right argument to the result,
        %⁵       mod 10.
\$\endgroup\$
1
  • 1
    \$\begingroup\$ -1 byte: R} -> < \$\endgroup\$
    – xigoi
    Feb 1 at 12:09
1
\$\begingroup\$

Julia, 47 bytes

l->(n=0;[n=n>0 ? (n+2i-1)%10 : 4+5i for i=l];n)

Try it online!

\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 111 bytes

	X =0
N	I =INPUT	:F(O)S($I)
A	X =REMDR(X + 1,10)
	X =EQ(X,1) 9	:(N)
S	X =X - 1
	X =4	LT(X)	:(N)
O	OUTPUT =X
END

Try it online!

Uses A for + and S for -, separated by newlines.

	X =0				;* Set X
N	I =INPUT	:F(O)S($I)	;* read input. If empty, goto O, else goto label identified by I
A	X =REMDR(X + 1,10)		;* Incremenet X, mod 10
	X =EQ(X,1) 9	:(N)		;* if X = 1, set it to 9. Goto N
S	X =X - 1			;* decrement X.
	X =4	LT(X)	:(N)		;* If X is less than 0, set X to 4. Goto N.
O	OUTPUT =X			;* Output X and exit.
END

SNOBOL won't reassign values on a FAILURE, so X =EQ(X,1) 9 is a no-op if X isn't equal to 1.

\$\endgroup\$
1
\$\begingroup\$

><>, 30 bytes

0l1=?n:?v~49{?$~!
+1-a%00.>{2*

Try it online! (or fishlanguage.com, as this input format is a bit tricky)

Takes an array of 0s(decrement) and 1s(increment)

---row 1---
0               !    Initialisation
 l1=?n:              Termination
       ?             Branching to special case 0
         ~49{?$~       0 branch, discard 4 or 9 depending on button
---row 2---
+1-a%   >{2*           other branch, conditional increment/decrement mod 10
     00.               loop
\$\endgroup\$
1
\$\begingroup\$

Befunge-98, 21 bytes

:&|@>#.
-1_4^
+1_9^%a

Try it online!

Input as a list of 0s and 1s (or any other format with some character after the last number).

Explanation

:&|@>#.
:        Create a copy of the temperature counter (which starts at 0).
 &       Get the next input number.
  |      Is it 0 (minus) or 1 (plus)?
         If the input is 0, move down to the second line.
         If the input is nonzero, move up (and wrap around) to the third line.

    >    Once the program has returned to the first line:
     #   Skip the next instruction.
      .  (skipped)
         Repeat.

On EOF:
:        Duplicate the final temperature.
      .  Print it.
     #   Skip the next instruction.
    >    (skipped)
   @     End the program.
    
  
Second line (minus):
-1_4^
  _      Is the copy of the current temperature zero?
         If so, 
   4            replace it with 4, 
    ^                              and return to the first line.
         If not, 
-                subtract 
 1                        1, 
    ^                        and return to the first line.


Third line (plus):
+1_9^%a
  _      Is the copy of the current temperature zero?
         If so, 
   9            replace it with 9, 
    ^                              and return to the first line.
         Otherwise, 
+                   add 
 1                      1, 
     %   take the result modulo 
      a                         10, 
    ^                               and return to the first line. 

\$\endgroup\$
1
\$\begingroup\$

PowerShell 7, 50 44 bytes

$args|%{$x=$_ ?$x ?++$x%10:9:$x ?$x-1:4};+$x

TIO still runs on PS 6, which this solution is incompatible with, so no Try It Online link, for now.

Explanation

$args|%{                            #For each number in the argument list (0 or 1)
    $x=                             #Assign to x
        $_                            #Ternary on the number
            ?                           #Number is non-zero, + button was pressed
                $x                        #Ternary on x
                    ? ++$x%10               #x is non-zero, set x to its increment mod 10
                    : 9                     #x is 0, set x to 9
            :                           #Number is zero, - button was pressed
                $x                        #Ternary on x
                    ? $x-1                  #x is non-zero, decrement
                    : 4                     #x is zero, set x to 4
}                                   #End for each loop
+$x                                 #Output x, coercing it to 0 if null
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 58 54 bytes

-4 bytes thanks @Zaelin Goodman

$args-ge0|%{$x=(($x-1),4,(($x+1)%10),9)[2*$_+!$x]}
+$x

Try it online!

Any version of PowerShell. See also the solution for PS7+

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 54 bytes? :) \$\endgroup\$ Feb 3 at 14:51
  • 1
    \$\begingroup\$ awesome! thanks! ٩(^‿^)۶ \$\endgroup\$
    – mazzy
    Feb 3 at 16:21
1
\$\begingroup\$

naz, 152 bytes

2x0v2x3v1a2x1v1a2x2v7a2x4v1x0f3v1o0x1x1f3v3x0v2e1s2x3v6f0x1x2f4a2x3v6f0x1x3f3v3x0v4e3x4v5e1a2x3v6f0x1x4f9a2x3v6f0x1x5f9s2x3v6f0x1x6f1r3x0v0e3x1v1e3f0x6f

Expects a null-terminated string of SOH and STX characters (U+0001 and U+0002), representing the minus and plus buttons respectively. Variable 3 stores the temperature.

Explanation (with 0x instructions removed)

2x0v2x3v                   # Set both variables 0 and 3 equal to 0
1a2x1v                     # Set variable 1 equal to 1
1a2x2v                     # Set variable 2 equal to 2
7a2x4v                     # Set variable 4 equal to 9
1x0f                       # Function 0
    3v1o                   # Output variable 3
1x1f                       # Function 1
    3v                     # Move variable 3 into the register
      3x0v2e               # Goto function 2 if it equals variable 0
            1s2x3v6f       # Otherwise, subtract 1, write to variable 3, & call function 6
1x2f                       # Function 2
    4a2x3v6f               # Add 4, write to variable 3, and call function 6
1x3f                       # Function 3
    3v                     # Move variable 3 into the register
      3x0v4e               # Goto function 4 if it equals variable 0
            3x4v5e         # Goto function 5 if it equals variable 4
                  1a2x3v6f # Otherwise, add 1, write to variable 3, and call function 6
1x4f                       # Function 4
    9a2x3v6f               # Add 9, write to variable 3, and call function 6
1x5f                       # Function 5
    9s2x3v6f               # Subtract 9, write to variable 3, and call function 6
1x6f                       # Function 6
    1r                     # Read a byte of input
      3x0v0e               # Goto function 0 if it equals variable 0 (NUL)
            3x1v1e         # Goto function 1 if it equals variable 1 (SOH)
                  3f       # Otherwise, call function 3
6f                         # Call function 6
\$\endgroup\$
1
\$\begingroup\$

Pyth, 23 bytes

 m?Z=Z%?dhZtZT=Z?d9 4QZ

Try it online!

 m?Z=Z%?dhZtZT=Z?d9 4QZ   Q auto-initialized to input; Z auto-initialized to zero
 m                   Q    Map through input, using 'd' as current element
  ?Z                      If Z is not 0:   
    =Z%?dhZtZT                          Z++ or Z--, Then modulo by 10
                          Else:
              =Z?d9 4          Z = 9 if + or 4 if -
                     Z    Print Z   
\$\endgroup\$
1
\$\begingroup\$

x86-16 machine code, 27 26 bytes

00000000: 33c0 803c 2d74 0a84 c075 02b0 0840 37eb  3..<-t...u...@7.
00000010: 0548 3f14 003f 46e2 e9c3                 .H?..?F...

Listing:

33 C0           XOR  AX, AX             ; clear accumulator 
            SLOOP: 
80 3C 2D        CMP  BYTE PTR[SI], '-'  ; is a "-"? 
74 0A           JZ   MINUS              ; is a minus operation 
84 C0           TEST AL, AL             ; is plus op and 0? 
75 02           JNZ  PLUS               ; if not, continue as plus op 
B0 08           MOV  AL, 8              ; otherwise add 8 
            PLUS:
40              INC  AX                 ; increment 
37              AAA                     ; if al > 9 { al = 0, cf = 1 } 
EB 06           JMP  DONE               ; done 
            MINUS: 
48              DEC  AX                 ; decrement 
3F              AAS                     ; if al < 0 { al = 9, cf = 1 } 
14 00           ADC  AL, 0              ; if cf { al = 10 }
3F              AAS                     ; if al == 10 { al = 4 } 
            DONE:
46              INC  SI                 ; next input instruction 
E2 E8           LOOP SLOOP
C3              RET                     ; return to caller

Callable function, input as string in [SI], length in CX. Output to AL.

This is the first time I can ever think of where AAA and AAS were actually useful in a challenge! These instructions, intended for BCD math, are able to be abused a little to do a bit of the dirty work here.

Tests:

enter image description here

enter image description here

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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