# Program my microwave oven [closed]

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? Commented Oct 24, 2012 at 0:52
• also which takes precedence: 400S or ++++ ? Commented Oct 24, 2012 at 1:54
• @ardnew: I guess tiebreak should be minimum finger movement, thus ++++ wins. :) Commented Oct 24, 2012 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. Commented Oct 24, 2012 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) Commented Oct 26, 2012 at 9:36

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


## 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. Commented May 20, 2014 at 21:45
• @BenJackson Challenges require an objective winning criterion. See the description of the [code-challenge] tag you used. Commented Jan 12, 2017 at 17:04

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