# Toasty, Burnt, Brûlée!

It turns out that my toaster is a tad broken. It lost WiFi (You know, it's one of those newfangled smart toasters), and its been going bonkers! Since it no longer works, I've been having to hack into my breakfast's source code and run Plate.bread.toastAs(3); every morning. Will you help?

My toaster takes one input: the amount of time you want to toast your bread. This is written as min:sec, such as 5:45 or 0:40 (Up to 59:59). It then returns a specific value for different levels of toastiness:

0:00-0:30 = Bread
1:01-2:00 = Toasty
2:01-3:30 = Burnt
3:31 and up = Brûlée (or Brulee)


But here's the catch: my toaster has a broken keyboard! Your code can't contain any semicolons or...colons. This might be harder than the toaster repairman said it would be...

Here are some test cases, so you can...test your cases?

0:00 = Bread
5:50 = Brulee or Brûlée
2:00 = Toasty
ChicknMcNuggets = Anything
-1:00 = Anything
0:60 = Anything
1 = Anything
60:00 = Anything
1:00:00 = Anything

• Is the time at most 59:59? – xnor Nov 3 at 2:47
• Shouldn't it be 3:31 and up: Brulee? – Mego Nov 3 at 4:17
• Where are all the golfing languages where colons wouldn't be used anyway? – Jo King Nov 3 at 6:13
• I have't realized until now why there aren't any Python submissions... – Redwolf Programs Nov 3 at 13:43
• Can we take in input with a leading zero so that all inputs are 5 characters long? – Quintec Nov 3 at 16:58

# Python 2, 124 118 116

t=eval(input().replace("\x3A","."))


Try it online!

-6 with thanks to @tsh and also thanks for tho TIO test cases.

-2 with a couple of cool tips from @BlackOwlKai

Throws a ValueError for invalid inputs that cannot be converted to a float. For numbers less than 0 it returns "Bread" because it is still bread. Guess if we are really strict on ensuring that the input is a valid time it could be done but for me the interesting bit was how to avoid the : in Python.

• 118 bytes – tsh Nov 3 at 16:03
• @tsh Thanks for the neat trick and thanks also for the TIO tests. – ElPedro Nov 3 at 16:48
• -1 byte by replacing float by eval – Black Owl Kai Nov 3 at 18:11
• Thanks @BlackOwlKai. Hadn't seen that. Will update tomorrow with appropriate credits ☺ – ElPedro Nov 3 at 22:01
• -1 byte because chr(58) can be shortened to "\x3A" – Black Owl Kai Nov 3 at 22:11

# JavaScript (SpiderMonkey), 100 bytes

a=>'Bread,Warm Bread,Toasty,Burnt,Brulee'.split,[((t=a.replace(/\D/,'.'))>3.3)+(t>2)+(t>1)+(t>.3)]


Try it online!

# JavaScript (Node.js), 91 bytes

a=>[,b='Bread','Warm '+b,o='Toasty',o,u='Burnt',u,u][new Date([70,a])/-~18e5+1|0]||'Brulee'


Try it online!

• The second solution is invalid since it contains a : in the source code. – kamoroso94 Nov 3 at 18:00
• @kamoroso94 rolled back. – tsh Nov 3 at 18:35

# T-SQL, 409379328 318 bytes

DECLARE @i varchar(9)DECLARE @a time='0'+CHAR(58)+@i DECLARE @ int=DATEPART(N,@a),@s int=DATEPART(S,@a)SELECT CASE WHEN @<1AND @s<31THEN'Bread'WHEN @<1OR @=1AND @s=0THEN'Warm Bread'WHEN @<2OR @=2AND @s=0THEN'Toasty'WHEN @<3OR @<4AND @s<31THEN'Burnt'ELSE'Brulee'END WHERE LEN(RIGHT(@i,LEN(@i)-CHARINDEX(CHAR(58),@i)))=2


-30 bytes: removed AS keywords, combined DECLARE statements (thanks to BradC)
-51 bytes: changed declarations/where clause to take advantage of SQL's datetime functionality
-10 bytes: changed MINUTE to N and SECOND to S (thanks to BradC)

Did you know that SQL can't natively split strings in any decent capacity? Don't let STRING_SPLIT fool you; it doesn't work for this. Or at least, I'm not smart enough to figure it out.

Different from BradC's table-based T-SQL solution.

Ungolfed:

-- Input variable
DECLARE @i varchar(9)

-- Time declarations (passes in as form "00:mm:ss")
-- CHAR(58) maps to ':'
DECLARE @a time = '0' + CHAR(58) + @i

-- Integer declarations
DECLARE @ int = DATEPART(N, @a),    -- minutes
@s int = DATEPART(S, @a)    -- seconds

SELECT CASE
WHEN @ < 1 AND @x < 31              -- 0:00 - 0:30
WHEN @ < 1 OR @ = 1 AND @x = 0      -- 0:31 - 1:00
WHEN @ < 2 OR @ = 2 AND @x = 0      -- 1:01 - 2:00
THEN 'Toasty'
WHEN @ < 3 OR @ < 4 AND @x < 31     -- 2:01 - 3:30
THEN 'Burnt'
ELSE 'Brulee'                       -- 3:31 - 59:59
END

-- Setting input as a time means that you only have to check if the seconds input is two characters, all other checks accounted for
WHERE LEN(RIGHT(@i, LEN(@i) - CHARINDEX(CHAR(58), @i))) = 2

• You could do something like SELECT value FROM STRING_SPLIT(@i,CHAR(58)), although I'm wondering if a TRY_CAST(@i AS TIME) might cut some corners. – BradC Nov 8 at 22:48
• Interesting language for golfing! – Redwolf Programs Nov 9 at 2:17
• @BradC I tried doing STRING_SPLIT like that, but it doesn't exactly work as you'd think - it actually returns both values from each side simultaneously, and you can't do any checks on the data (at least that I could figure out). As for using TRY_CAST, it looks like it would require having "00:" appended to the front. I might be able to work further with that. – Meerkat Nov 9 at 14:15
• Yeah, STRING_SPLIT returns them as separate rows. Even without changing those parts, you can still save a ton of bytes by keeping only your very first DECLARE and changing the rest to commas. Also drop AS and just do DECLARE @i varchar(99),@a varchar(9)=... – BradC Nov 9 at 14:31
• Yeah, good call. Since @a and @b both require @i though, I have to declare that separately. Can still save quite a few bytes there though. – Meerkat Nov 9 at 14:35

# T-SQL, 143 155 bytes

SELECT TOP 1b FROM i,
WHERE a>DATEDIFF(s,0,'0'+CHAR(58)+v)ORDER BY a


Line breaks are for readability only. Different method than Meerkat's variable-based SQL solution.

Input is taken via pre-existing table i with varchar field v, per our IO standards. That input table is cross-joined to an in-memory table t with our cutoff values (in seconds) and the desired labels.

The magic happens in the WHERE clause: DATEDIFF calculates the difference in seconds between midnight and our input (with an extra 0: attached to the front), then returns the lowest matching label (via the TOP 1 and ORDER BY).

Invalid inputs either return an unpredictable value or throw an error:
Conversion failed when converting date and/or time from character string.

The question was a little vague, but if needed I can avoid these errors (and return nothing) by adding a LIKE pattern to the WHERE clause, bringing the total bytes to 238 211:

SELECT TOP 1b FROM i,
WHERE a>DATEDIFF(s,0,'0'+CHAR(58)+v)
AND RIGHT('0'+v,5)LIKE'[0-5][0-9]'+CHAR(58)+'[0-5][0-9]'
ORDER BY a


EDIT: My original shorter submission was failing for inputs over 24:00, since I was treating it as hh:mm. Had to add the '0'+CHAR(58)+ prefix, which added 12 bytes.

EDIT 2: Shaved 27 bytes from the LIKE in my alternate version

# Javascript(ES6+), 180 bytes

Node.js(180 bytes)

let f=(s,i=s.split("\u{3a}"),j=i[0]*60+1*i[1],k="Bread",l=assert(new RegExp("^(.|[0-5].)\u{3a}[0-5].$").test(s)))=>eval("(j<31)?k\u{3a}(j<61)?'Warm '+k\u{3a}(j<121)?'Toasty'\u{3a}(j<211)?'Burnt'\u{3a}'Brulee'")  Browser(188 bytes): let f=(s,i=s.split("\u{3a}"),j=i[0]*60+1*i[1],k="Bread",l=console.assert(new RegExp("^(.|[0-5].)\u{3a}[0-5].$").test(s)))=>eval("(j<31)?k\u{3a}(j<61)?'Warm '+k\u{3a}(j<121)?'Toasty'\u{3a}(j<211)?'Burnt'\u{3a}'Brulee'")


Gotta use those unicode escape sequences :-) just a big chain of ternary operators, with variables defined by default parameters. Also a one-liner, so no semicolon-hungry js

• I used a regex to enforce the 59:59 & no negatives rule :-) – Michael Nov 3 at 4:14
• OH WAIT I forgot i added : – Michael Nov 3 at 4:15
• actually done :-) – Michael Nov 3 at 4:21
• You don't need a regex to enforce the 59:59 and no negatives...they can result in anything, be it an error, nothing, or Brulee. – Redwolf Programs Nov 3 at 13:40

# Perl 6, 86 79 67 bytes

-4 bytes thanks to nwellnhof! -12 bytes by porting tsh's solution

{<<Bread'Warm Bread'Toasty Burnt Brulee>>[sum S/\D/./X>.3,1,2,3.3]}


Try it online!

# C (gcc), 130 bytes

f(a){if(*strchr(a,58)=48,a=atoi(a),a=(int*[]){"Bread","Warm Bread","Toasty","Burnt","Brulee"}[(a>30)+(a>1e3)+(a>2e3)+(a>3030)]){}}


Try it online!

# Snap! 4.2, 257 251 bytes

Minified the text version some more.

I haven't found any answers in Snap!, a visual programming language similar to Scratch, so I'll use scratchblocks2 syntax, pretending that Snap! exclusive blocks are valid in scratchblocks2.

Try it online! (click the button with the two arrows to see the code)

when gf clicked
set [t v]to(((item(1 v)of(l))*(60))+(item(2 v)of(l
if<(t)<[31
else
if<(t)<[61
else
if<(t)<[121
say[Toasty
else
if<(t)<[211
say[Burnt
else
say[Brulee


# R, 127 122 bytes

function(t)cut((x=eval(parse(t=t)))[1]*60+tail(x,1),30*c(0:2,4,7,Inf),c("Bread","Warm Bread","Toasty","Burnt","Brulee"),T)


Try it online!

Returns a factor with the appropriate level.

-5 bytes thanks to JayCe.

• Would this work? tio.run/… – JayCe Nov 8 at 22:56
• @JayCe IDK, the input is "any acceptable format" but then everything takes the string...I'll ask in the comments. – Giuseppe Nov 8 at 23:06
• @JayCe I'm not sure what you mean. As far as I can see, it takes the time as an input to a function which is an acceptable input IMO – Redwolf Programs Nov 9 at 2:20
• And you can also do 30*c(0,1,2,4,7,Inf) – JayCe Nov 9 at 3:59
• @RedwolfPrograms the input isn't a time, it's an array, : is the sequence operator. – Giuseppe Nov 9 at 15:58

<?=[Bread,"Warm Bread",$t=Toasty,$t,$u=Burnt,$u,$u,Brulee][min(7,2*$argn+substr($argn,-2)/30)]?>  requires PHP 5.5 or later. Run as pipe with -nF or try it online. # Retina 0.8.2, 97 bytes .+(..)$*1#$1$*
+1#
#60$* #1{211,} Brulee #1{121,} Burnt #1{61,} Toasty #1{31,} Warm # #1* Bread  Try it online! Link includes test cases. Explantion: .+(..)$*1#$1$*


Convert the minutes and seconds to unary.

+1#
#60$*  Multiply the minutes by 60 and add to the seconds. #1{211,} Brulee #1{121,} Burnt #1{61,} Toasty  Decode the seconds into the toastiness. #1{31,} Warm #  Decode Warm Bread by noting that # (for 0:00) decodes to Bread. #1* Bread  If we don't have a toastiness yet then the bread is still cold. # Javascript, 115 101 bytes -6 from tsh d=>[b="Bread","Warm "+b,a="Toasty",a,c="Burnt",c,c][~~(parseInt(d)*1.999+d.slice(-2)/30.1)]||"Brulee"  ## JavaScript (ES6), 171 bytes (x,y=Math.ceil(x.split(/\D/).reduce((a,b)=>(+a)*60+(+b))/30))=>["Bread","Bread","Warm Bread","Toasty","Toasty","Burnt","Burnt","Burnt","Brulee","Brulee","Brulee"][y>8?8:y]  Run some test cases with this Stack Snippet: var f=(x,y=Math.ceil(x.split(/\D/).reduce((a,b)=>(+a)*60+(+b))/30))=>["Bread","Bread","Warm Bread","Toasty","Toasty","Burnt","Burnt","Burnt","Brulee","Brulee","Brulee"][y>8?8:y] var result = document.getElementById("result"); ["0:00", "0:30", "0:31", "1:00", "1:01", "2:00", "2:01", "2:30", "2:31", "3:00", "3:01", "3:30", "3:31", "4:00", "4:01", "4:30", "4:31", "5:00", "6:00"].forEach(x => result.innerHTML += ${x}: \${f(x)}\n);
<pre id="result"></pre>

• @JoKing Whoops, I missed a few possibilities while trying to save bytes. Working on a fix. – Mego Nov 4 at 5:26

# Japt, 54 bytes

[BÎ%W‡m BÎ%To†tyB¨›BrÔ‡]g[30L200,330]è<Ur58d


Try it online!

Explanation:

[BÎ%...BrÔ‡]                        Possible outputs as compressed strings
g                       Get the one at the index given by...
è          The number of items...
[30L200,330]           From the list [30,100,200,330]...
<Ur58d    Which are less than the input without ":"