# What temperature is my stove?

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

• May a string list of input be newline separated? – Dom Hastings Feb 1 at 9:56
• (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)? – user202729 Feb 1 at 10:26
• @user202729 No. – Wheat Wizard Feb 1 at 10:35
• @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. – Wheat Wizard Feb 1 at 11:13
• @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. – Wheat Wizard Feb 1 at 16:25

# 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


# 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.

# 05AB1E, 161514 12 bytes

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

ÎvD_Ƶ≠yè*yOθ


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.

# Retina 0.8.2, 33 bytes

^
0
{T+09d_9d^.\+
T-d_4d^.-


Try it online! Link includes test suite. Explanation:

^
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 (T9dd 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.

# C (gcc), 58 57 bytes

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


Try it online!

Inputs a string of minuses and pluses bell-characters (ASCII 7) and returns the stovetop temperature.

• You could save one character by using a one-digit encoded character instead of '+', but it's just one byte. Upvoted. – Sheik Yerbouti Feb 1 at 12:40
• @Davide I just did that 2 minutes ago! T_T But my comment was backwards - fixed! :) – Noodle9 Feb 1 at 12:41
• 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. – Sheik Yerbouti Feb 1 at 12:44

# 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. # PHP, 10390 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. • -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) – Kaddath Feb 1 at 11:08

# 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!

## 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


# 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!

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.)

# 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)
+                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


# 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!

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
• 35 – Wheat Wizard Feb 1 at 16:26
• And if you want to keep the same input format 39. – Wheat Wizard Feb 1 at 16:29

# Perl 5-pF, 36 bytes

$\+=$\?1-2*/-/:9-5*/-/,$\%=10for@F}{  Try it online! • 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! – Dom Hastings Feb 8 at 12:52

# Brain-Flak, 132 bytes

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


Try it online!

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

# 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

## 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
STORE   TMP
* CHECK ZERO DOWN TO 4
JINEG   ZTF
* CHECK 9 UP TO 0
SUBTRACT        10
JIZERO  NTZ
* CHECK 0 UP TO 9
JINEG   DEC
SUBTRACT        1
JIZERO  ZTN
STORE   HEAT

PRINT   "HEAT IS "
OUT
LINE
JUMP    LOOP

STORE   HEAT
JUMP    SHOW

END     HALT

* 0 GOES DOWN TO 4
STORE   HEAT
JUMP    SHOW

* 9 GOES UP TO 0
STORE   HEAT
JUMP    SHOW

* ZERO GOES UP TO 9
STORE   HEAT
JUMP    SHOW

%
-1
-1
-1
1
0

• 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. – Arnauld Feb 4 at 23:32

## 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!

• 55 bytes by using "if" instead of ifelse... – Dominic van Essen Feb 6 at 15:47

# 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
µ      :
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.

• -1 byte: R} -> < – xigoi Feb 1 at 12:09

# Julia, 47 bytes

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


Try it online!

# ><>, 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


# 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,
If not,
-                subtract
1                        1,

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



# 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


# 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!

• 54 bytes? :) – Zaelin Goodman Feb 3 at 14:51
• awesome! thanks! ٩(^‿^)۶ – mazzy Feb 3 at 16:21

# 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


# 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


# 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


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:

# Stax, 23 bytes

╙ù╞{)#Xk↕¬;÷<fh/IKô[[zô


Run and debug it

Input as a list of 1s and 0s. Will be further optimized soon.

# Charcoal, 23 bytes

≔⁰θＦＳ≔⎇⁼ι+﹪⊕∨θ⁸χ⊖∨θ⁵θＩθ


Try it online! Link is to verbose version of code. Explanation:

≔⁰θ


ＦＳ


Loop through the input string.

≔⎇⁼ι+﹪⊕∨θ⁸χ⊖∨θ⁵θ


If the next character is a plus, then take the heat setting, or 8 if it was zero, and increment it modulo 10, otherwise take the heat setting, or 5 if it was zero, and decrement it.

Ｉθ


Output the final heat setting.

# Japt, 21 bytes

Port of @Arnauld's Answer to Japt.

Expects input to be a binary array where 0 represents increment and 1 represents decrement

£T=T°?X?T-2:T%A:9ÁXÃT


Try it

## Explanation

£              // Map input with func (X) {
T=            //   update T:
T°?         //     if T is not 0 (increment T afterwards)
X?       //       if X is 1 ('-' case)
T-2    //          subtract 2
:        //       else      ('+' case)
T%A    //          modulo 10
:           //     else
9ÁX       //       yield 4 if X is 1 ('-' case), or 9 if X is 0 ('+' case)
ÃT             // End map; implicit output T