# Program my microwave oven

I'm very lazy so I try to always program my microwave with the fewest possible button presses. My microwave has the following buttons:

• A "minute plus" button which may only be pressed first and implies "start". It may be pressed multiple times for multiple minutes, but it will not add a minute to a manually entered time. Output `+`
• A set of 0-9 buttons. Time entry is MMSS (i.e. "130" means 1 minute 30 seconds). Seconds may range from 0..99. So "130" and "90" are equivalent entries. Obviously each minute is 60 seconds even if the seconds part of the entry exceeds 59. Output `0`..`9`
• A "start" button which must be pressed to start the microwave if the time is entered manually. Output `S`

My food packages specify time in MM:SS and so the program must accept that input.

### Examples

• 1:00 is `+` (remember "minute plus" implies start)
• 1:01 is `61S` (seconds can exceed 59, but "minute plus" does not work in conjunction with digits -- I think this is a design flaw in my microwave)
• 9:00 is `900S` (shorter than `+++++++++`)
-
will the answers be verified with your dinner? – ardnew Oct 24 '12 at 0:52
also which takes precedence: `400S` or `++++` ? – ardnew Oct 24 '12 at 1:54
@ardnew: I guess tiebreak should be minimum finger movement, thus `++++` wins. :) – Ben Jackson Oct 24 '12 at 2:03
finger movement? so is `888S` shorter than `928S`, but `900S` shorter than `860S` ? i'm gonna need precise geometry of your buttons and each of their positions. – ardnew Oct 24 '12 at 2:10
If I had to microwave my "Pedant's Meal for One" for 1:59, I would press ++ (wait for 1:59) and then press "cancel" one second before the end. Three button presses, assuming you have a "cancel" button and consider standing staring at the timer to be a cheap process. Maybe you could consider this option for subsequent meals! (Or for a subsequent challenge) – Johno Oct 26 '12 at 9:36

## APL

APL has a bad reputation that it's unreadable, which is totally not the case if it's not golfed.

The rules:

• Whole minutes <= 4 get +, ++, +++, and ++++
• 960-999 is preferred above 1000-1039. 9960-9999 is preferred above 10000-10039, etc.
• If the time can be rewritten such that the seconds are 66, 77, 88, or 99 then this is done. (This never gives a worse solution and usually gives a better one, i.e. 888 instead of 928.)
```∇ Microwave;time;secs;mins;fmt;⎕ML

⎕ML←3

⎕←'Enter the time (m+:ss)'
time←⍞
mins secs←⍎¨(time≠':')⊂time

⍝ 'minute plus' can only be used on whole minutes ≤ 4
:If (secs=0)∧(mins≤4)
⎕←mins⍴'+'
:Return
:EndIf
⍝ If possible, save a keypress by using seconds > 60
⍝ if mins is a power of ten
:If (mins>0)
:If ((⌈10⍟mins)=(⌊10⍟mins))∧(secs<40)
⎕←('BI2'⎕FMT mins-1),(⎕FMT secs+60),'S'
:Return
:EndIf
:EndIf
⍝ For the 'finger movement' requirement we want as many
⍝ of the keypresses as possible to be of the same key.
⍝ So 888S i.p.v. 928S.
:If secs∊66 77 88 99-60
⎕←('BI2'⎕FMT mins-1),(⎕FMT secs+60),'S'
:Return
:EndIf
⍝ Otherwise, just output mmssS, there was no better alternative.
:If mins>0
⍝ output seconds with leading zero
⎕←('BI2'⎕FMT mins),('G⊂99⊃'⎕FMT secs),'S'
:Else
⍝ only output seconds, not with leading zero
⎕←('BI2'⎕FMT secs),'S'
:EndIf
∇
```
-
I didn't specify a winning criteria, so I will retroactively choose the one that teaches me the most about APL. – Ben Jackson May 20 '14 at 21:45

## JavaScript

``````var x = /(\d+):(\d\d)/.exec('<time here>');
x[1] === '0' ? +x[2] + 'S' :
x[1] < 4 && x[2] === '00' ? (
x[1] === '1' ? '+' :
x[1] === '2' ? '++' : '+++') :
x[2] < 40 ?
(x[1] - 1 ? x[1] - 1 : '') + '' + (6 + +x[2][0]) + x[2][1] + 'S' :
x[1] + x[2] + 'S'
``````
-

## Perl

meets the requirements, but it isn't how I would enter the buttons (e.g. "860S" vs "900S") handles exactly 60 seconds as a special case

``````use strict;
use warnings;

sub cook
{
my (\$mins, \$secs) = @_;

my \$plus = \$secs =~ /00/ ? \$mins : undef;

my \$secs_total = \$mins * 60 + \$secs;
my \$mins_total = 0;

while (\$secs_total > 99)
{
++\$mins_total;
\$secs_total -= 60;
}

\$plus = "+" x \$plus if defined \$plus;

my \$nums = "";
my \$even = (\$mins_total > 0 and \$secs_total == 60);

\$secs_total *= not \$even;
\$mins_total += \$even;

if (\$mins_total > 0)
{
\$nums = sprintf "%s%02dS", \$mins_total, \$secs_total;
}
else
{
\$nums = sprintf "%2dS", \$secs_total;
}

return (\$nums, \$plus)
[defined \$plus and length \$plus < length \$nums];
}

die "usage:\$/\tperl \$0 <MINUTES>:<SECONDS>\$/"
unless @ARGV > 0 and shift =~ /([0-9]{1,2}):([0-9]{1,2})/;

print cook(\$1, \$2), \$/;
``````

## Output

``````andrew@gidget:~\$ perl mic.pl 9:00
900S
andrew@gidget:~\$ perl mic.pl 1:00
+
andrew@gidget:~\$ perl mic.pl 1:01
61S
andrew@gidget:~\$ perl mic.pl 1:30
90S
andrew@gidget:~\$ perl mic.pl 0:07
7S
andrew@gidget:~\$ perl mic.pl 4:00
400S
``````
-

## ruby

``````#Build a string for the microwave
def build_result(minutes, seconds)
duration = minutes * 60 + seconds
if duration < 99
result = "%iS" % [ duration]    #shortcut '90S' instead '130S'
else
result = "%i%02iS" % [ minutes, seconds]
end
result
end

#Call microwave optimizer
def microwave( input )
minutes  = input.split(/:/).first.to_i
seconds = input.split(/:/).last.to_i

#build result
result = build_result(minutes, seconds)
#try a shorter result, make 999S out of '10:39':
if seconds < 40 and minutes > 0
result2 = build_result(minutes - 1, seconds + 60)   #try a
result = ( result.size <= result2.size ? result : result2 )
end

#Check if a version with only '+' is shorter
if seconds == 0 and minutes <= result.size
result = '+' * minutes
end
result
end

#Test if called with an argument
if ARGV.empty?
require 'test/unit'   #Exceute a test
class MicrowaveTest < Test::Unit::TestCase
def test_007
assert_equal('7S', microwave('0:07'))
end
def test_100
assert_equal('+', microwave('1:00'))
end
def test_101
assert_equal('61S', microwave('1:01'))
end
def test_130
assert_equal('90S', microwave('1:30'))
end
def test_400
#~ assert_equal('400S', microwave('4:00'))
assert_equal('++++', microwave('4:00'))
end
def test_500
assert_equal('500S', microwave('5:00'))
end
def test_900
assert_equal('900S', microwave('9:00'))
end
def test_1000
#~ assert_equal('1000S', microwave('10:00'))
assert_equal('960S', microwave('10:00'))
end
def test_1015
#~ assert_equal('1015S', microwave('10:15'))
assert_equal('975S', microwave('10:15'))
end
def test_1039
#~ assert_equal('1039S', microwave('10:39'))
assert_equal('999S', microwave('10:39'))
end
end
else  #started via shell, evaluate input
puts microwave(ARGV.first)
end
``````

Remarks:

• Start it with `ruby program-my-microwave-oven.rb` and a unit test is evaluated.
• Start it with `ruby program-my-microwave-oven.rb 10:00` and it writes `960S`

Some remarks on the rules (and my interpretation):

• The shortest for `10:00` is `960S` (9 minutes and 60 seconds -> 10 minutes).
• The shortest for `10:39` is `999S` (9 minutes and 99 seconds -> 10 minutes and 39 seconds).
• for `4:00` it prefers `++++` (less finger movements)
-