# Simulate My Stupid Old Alarm Clock

I have a stupid old alarm clock with two buttons: hour and minute. The hour button increments the hour of a set alarm, and minute increments the minute time of a set alarm. However, some smart designers realized that pressing both buttons at the same time should have a meaning, and decided that pressing hour and minute simultaneously would cause the alarm to be set to 12:00 am/0:00. Your task is to simulate this behavior.

# Task

Given a start time and a sequence of button states, figure out the end time.

Starting from the start time, increment the hour for each occurrence of (1,0), increment the minute for each occurrence of (0,1), and set the time to 0:00 for each occurrence of (1,1). The states (0,0) should be ignored because they correspond to neither button being pressed.

When adding to minutes and hours, if the minute/hour goes above the maximum, set it to 0, i.e. incrementing a minute value of 59 should set the minute value to 0 and incrementing an hour value of 23 should set the hour value to 0. Incrementing minute/hour values above their limits do not affect the other value, for example incrementing the minute of 10:59 yields 10:00, not 11:00.

# Example

Given the input time 13:58 and steps [(0,1),(0,1),(0,1),(0,0),(1,1),(1,0)],

1. (0,1). This corresponds to minute being pressed. The time is now 13:59.
2. (0,1). This corresponds to minute being pressed. The time is now 13:00.
3. (0,1). This corresponds to minute being pressed. The time is now 13:01.
4. (0,0). This corresponds to neither button being pressed. The time,unaffected, is now 13:01
5. (1,1). This corresponds to both buttons being pressed. The time is now 0:00.
6. (1,0) This corresponds to hour being pressed. The time is now 1:00.

Since we end with 1:00, it is the output.

# I/O

The input will consist of a time and a sequence of button states. The output is a single time.

The input time and output time may be

• a 2-tuple of (hour, minute) or (minute, hour) in 24-hour time such as (13, 30) (hour ranges from 0 to 23 and minute ranges from 0 to 59)
• same as the previous but in 12-hour time and a Boolean am/pm switch (hour ranges from 0 to 11 or 12 and 1 to 11 with minute from 0 to 59).
• a number of minutes since 0:00 such as 810 (from 0 to 1439, inclusive)
• any other format which encodes the same information

The sequence of button states is a representation of a list of Boolean 2-tuples, for example:

• a list of tuples: [(0,1),(1,0),(0,0),(1,1)]
• a space-delimited string: "01 10 00 11"
• a string: "01100011"
• in Quaternary: [1,2,0,3]
• converted to an integer: 99
• any other format which encodes the same information

# Test Cases

time,steps -> output
06:49,[(0, 1)] -> 06:50
12:23,[(1, 0)] -> 13:23
02:23,[(0, 1), (1, 0)] -> 03:24
21:40,[(0, 1), (0, 1), (0, 1), (0, 1)] -> 21:44
13:10,[(0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (1, 1), (0, 1), (0, 1)] -> 00:02
21:33,[(1, 0), (0, 1), (1, 0), (0, 1)] -> 23:35
14:21,[(0, 1), (0, 1), (0, 1)] -> 14:24
02:39,[(0, 0), (0, 1)] -> 02:40
16:07,[(0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1)] -> 19:16
17:55,[(0, 1), (1, 0), (0, 1)] -> 18:57
15:55,[(1, 0), (1, 0), (1, 0), (0, 1), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (1, 0), (1, 0), (0, 1), (1, 0)] -> 23:00
22:11,[(0, 1), (1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1)] -> 00:19
03:58,[(1, 0), (0, 0), (0, 0), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (0, 1), (1, 0), (0, 1)] -> 07:03
13:02,[(0, 1), (1, 0), (0, 1), (1, 0), (0, 1), (0, 1), (1, 0)] -> 16:06
04:37,[(1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (1, 0), (0, 1), (1, 0)] -> 08:47
00:01,[(0, 1), (1, 0), (1, 0), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1)] -> 03:08
02:58,[(1, 0), (1, 0), (0, 1)] -> 04:59
01:43,[(0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (1, 0), (0, 1)] -> 04:52
07:54,[(1, 0), (0, 1), (1, 0), (1, 0), (1, 1)] -> 00:00
09:33,[(0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1)] -> 10:38
09:01,[(0, 1), (0, 1)] -> 09:03
19:04,[(0, 1), (1, 0), (0, 1), (1, 0)] -> 21:06
11:17,[(0, 1), (1, 0), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (1, 1), (0, 1), (0, 1)] -> 00:02
19:32,[(0, 1), (1, 0), (0, 1), (1, 0), (1, 0), (1, 0)] -> 23:34
17:31,[(0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (1, 0), (0, 1), (0, 0), (1, 1), (0, 1)] -> 00:01
06:46,[(0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (0, 1), (0, 1), (1, 0), (0, 1), (1, 0), (0, 1), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1), (1, 0), (1, 0), (0, 1), (1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)] -> 18:16

• Heavily related – Stephen Sep 15 '17 at 23:16
• – Justin Mariner Sep 15 '17 at 23:39
• Is an input format of the two sets of data as one list acceptable? For example [[initialHour, initialMinute], [hourPressed1, minuitePressed1], [hourPressed2, minuitePressed2], ...]? – Jonathan Allan Sep 16 '17 at 17:04
• @JonathanAllan Yes. – fireflame241 Sep 16 '17 at 17:07
• What does 1200am mean in normal digital time? – Ferrybig Sep 18 '17 at 6:41

# Jelly, 13 bytes

_+Ạ}?/%24,60


Try it online!

• Note, I'm not sure we can just go ahead and use that input format (so I asked) since the OP states "The sequence of button states is a representation of a list". – Jonathan Allan Sep 16 '17 at 17:15
• @JonathanAllan if so then OP will comment on my answer but I'm using the exact format you used in your comment...it's sometimes that OP is lazy or forgot to update the challenge – Erik the Outgolfer Sep 16 '17 at 17:16

# Python 2, 84 75 bytes

lambda c,a:reduce(lambda(h,m),(d,e):(d&e)and(0,0)or((h+d)%24,(m+e)%60),a,c)


Try it online!

Function that takes time as a tuple (hour,minute); outputs same way.

• -3 bytes by using all(b) instead of b[0]&b[1]: lambda c,a:reduce(lambda t,b:all(b)and((t[0]+b[0])%24,(t[1]+b[1])%60)or(0,0),a,c) – Erik the Outgolfer Sep 16 '17 at 12:36
• 73 bytes – Halvard Hummel Sep 17 '17 at 11:45
• lambda(h,m),(d,e): is this pattern matching in Python!? – Quelklef Sep 18 '17 at 14:38

# C, 89 87 bytes

Thanks to @Jonathan Frech for saving two bytes!

f(h,m,s)char*s;{for(;*s;++s)*s++&1?*s&1?h=m=0:++h:*s&1&&++m;printf("%d %d",h%24,m%60);}


Try it online!

# Jelly,  21  (17?) 19 bytes

17 bytes? -- If the input format: [[initHour, initMinute], [a1, b1], [a2, b2], ...] is acceptable we'd have a monadic link and may remove W; from the beginning of the second line.

Note: This is now converging towards Erik the Outgolfers Jelly answer, so I wont bother golfing more (I had not seen it)...

N⁹⁹Ạ¤?+⁸
W;ç/%24,60


A dyadic link taking a list of the initial time as integers [hour, minute] (24-hour) on the left and a list of button states [[hourPressed, minPressed], ...] on the right
which returns a list of the end result time as integers, again [hour, minute] (24-hour).

Try it online! or see the test-suite

### How?

N⁹⁹Ạ¤?+⁸ - Link 1, nextState: list, currentState [cH, cM]; list, presses [pH, pM]
?   - if:
¤    - ...condition: nilad followed by link(s) as a nilad:
⁹      -   chain's right argument, presses
Ạ     -   all truthy? (1 for [1,1] 0 otherwise)
N        - ...then: negate (the left argument, currentState, i.e. [-cH, -cM])
⁹       - ...else: chain's right argument, presses
⁸ - chain's left argument, currentState
+  - add
i.e.: if presses was [1,1] then [cH+-cH,cM+-cM]=[0,0]
otherwise [cH+pH,cM+cM]

W;ç/%24,60
24,60 - literal list of integers [24,60]
%      - modulo by (vectorises)

• -1 byte by replacing ⁹Ạ¤ with Ạ}. Another -2 for using an allowed format. Finally, another -1 because the chain before the µ here is called as a dyad.. – Erik the Outgolfer Sep 16 '17 at 17:07

# Retina, 75 bytes

.*,1:1
:
\d+
$* O\D1* , 1>: +1{24}:|:1{60} : (?<=^|:)1*$.&
\b\d\b
0$&  Try it online! Link includes test cases. Explanation: .*,1:1 :  Delete everything up to and including the last double button press, replacing it with an empty time (in case that's the last button press). \d+$*


Convert to unary.

O\D1*


Sort the minutes to the end.

,


Add the hours together.

1>:


Add the minutes together, but keeping the hours separate.

+1{24}:|:1{60}
:


Reduce the hours and minute modulo 24 or 60 as appropriate.

(?<=^|:)1*
$.&  Convert to decimal. \b\d\b 0$&


Format to two digits.

# Python 3, 135117 115 bytes

-20 bytes thanks to Jonathan Frech

def a(m,f):
for b,c in f:
if b&c:m=[0,0]
elif b:m[0]=-~m[0]*(m[0]<23)
elif c:m[1]=-~m[1]*(m[1]<59)
return m


Try it online!

Takes the time as a list in the form [hour, minute].

• You may be able to replace (m[0]+1) with -~m[0] and if m[0]<23 else 0 with *(m[0]<23). – Jonathan Frech Sep 16 '17 at 5:08
• Also, as b and c are always boolean values, you can replace b+c>1 with b&c. – Jonathan Frech Sep 16 '17 at 5:33
• 76 bytes (Shortened link, due to TIO being to large for comment box) – Halvard Hummel Sep 16 '17 at 11:17

# Haskell, 58 bytes

foldl(#)
_#(1,1)=(0,0)
(h,m)#(x,y)=(mod(h+x)24,mod(m+y)60)


Try it online! Example usage: foldl(#) (23,58) [(0,1),(1,0),(0,0),(0,1),(0,1)].

# JavaScript (ES6), 55 bytes

t=>a=>a.map(x=>x>2?t=[0,0]:t[x-1]++)&&[t[0]%60,t[1]%24]


Takes input in currying syntax, with the starting time in the array form [min, hour] and the steps as a Quaternary array. Output time is in the same format as the input time.

## Test Cases

let f=
t=>a=>a.map(x=>x>2?t=[0,0]:t[x-1]++)&&[t[0]%60,t[1]%24]

;[[[49, 06], [1]], [[23, 12], [2]], [[23, 02], [2, 1]], [[40, 21], [1, 1, 1, 1]], [[10, 13], [1, 1, 1, 1, 2, 3, 1, 1]], [[33, 21], [2, 1, 2, 1]], [[21, 14], [1, 1, 1]], [[39, 02], [1, 0]], [[07, 16], [1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1]], [[55, 17], [1, 2, 1]], [[55, 15], [2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 1, 2]], [[11, 22], [1, 2, 1, 1, 1, 1, 1, 2, 1, 1]], [[58, 03], [2, 0, 0, 1, 1, 2, 2, 1, 1, 2, 1]], [[02, 13], [1, 2, 1, 2, 1, 1, 2]], [[37, 04], [2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2]], [[01, 00], [1, 2, 2, 1, 1, 1, 2, 1, 1, 1]], [[58, 02], [2, 2, 1]], [[43, 01], [1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, 1]], [[54, 07], [2, 1, 2, 2, 3]], [[33, 09], [1, 1, 1, 2, 1, 1]], [[01, 09], [1, 1]], [[04, 19], [1, 2, 1, 2]], [[17, 11], [1, 2, 1, 1, 2, 1, 1, 3, 1, 1]], [[32, 19], [1, 2, 1, 2, 2, 2]], [[31, 17], [1, 1, 1, 2, 1, 2, 1, 0, 3, 1]], [[46, 06], [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1]]]
.forEach(([time,steps])=>{
let res = f([...time])(steps)
console.log(JSON.stringify(time)+" -> "+JSON.stringify(res))
})
.as-console-wrapper{max-height:100%!important}

# Perl 6, 40 bytes

{.reduce({(@^a Z+@^b)X*!@b.min})Z%24,60}


Try it online!

Takes a list containing the start time followed by the button presses. Returns the end time. Times and buttons are (hour, minute) pairs. 24-hour time.

# Perl 5, 70 bytes

69 bytes of code + 1 for -n flag

s/.*d/0:0/;/(.*):(\d+)/;printf"%02d:%02d",($1+y/c//)%24,($2+y/b//)%60


Try it online!

Input Format

hh:mm,abcdabcdabcdaddccbbaa

where:

hh=start hour
mm=start minute
a = (0, 0) = no buttons pressed
b = (0, 1) = minute button pressed
c = (1, 0) = hour button pressed
d = (1, 1) = both buttons pressed


Spaces or other separators between the presses are insignificant.

Explanation

s/.*d/0:0/;    # If both buttons were ever pressed, previous presses
# don't matter.  Get rid of them and set start time to midnight.
/(.*):(\d+)/;  # Extract start hour and minute
printf"%02d:%02d",            # Output numbers with leading 0
($1+y/c//)%24, # Take starting hour, add number of presses, remainder 24 ($2+y/b//)%60                 # Take starting minute, add number of presses, remainder 24


# Swift, 106 96 bytes

-10, thanks to Xcoder

func x(m:(Int,Int),n:[(Int,Int)]){let i=n.reduce(m){($0.0+$1.0,$0.1+$1.1)};print(i.0%24,i.1%60)}


Try it on ideone!

function will take initial value and array of tuples and returns final time.

• 96 bytes, by printing to STDOUT instead: func x(m:(Int,Int),n:[(Int,Int)]){let i=n.reduce(m){($0.0+$1.0,$0.1+$1.1)};print(i.0%24,i.1%60)}. This also gets rid of typealias. – Mr. Xcoder Sep 16 '17 at 9:46
• By the way, welcome to PPCG! Amazing first answer. – Mr. Xcoder Sep 16 '17 at 9:53
• thank you so much, actually I used print() first... but I forgot after switching between different implementations. Thanks again for your help. – Naresh Sep 16 '17 at 9:57

# Terrapin Logo, 304 bytes

Not optimized; lots of spaces.

MAKE "M :B MAKE "H :A LABEL "L IF EMPTY? :I OP LIST :H :M MAKE "C FIRST :I IF AND ((ITEM 2 :C)=1) ((ITEM 1 :C) = 0) MAKE "M :M+1 IF :M=60 MAKE "M 0 IF AND ((ITEM 1 :C) = 1) ((ITEM 2 :C)=1 MAKE "M 0 MAKE "H 0 IF AND ((ITEM 1 :C)-1) ((ITEM 2 :C) = 0) MAKE "H :H + 1 IF :H = 23 MAKE "H 0 MAKE "I BF :I GO "L


Takes a list as its first input and the starting hour+minute (seperate inputs) as second and third, respectively.

I can't copy+paste from Terrapin Logo as it's a trial version so that's that :(

# Mathematica, 54 bytes

Switch[#2,a={0,0},#,a+1,a,_,Mod[+##,{24,60}]]&~Fold~#&


Anonymous function. Takes a list of 2-tuples as input and returns a 2-tuple as output.

# R, 61 bytes

function(I,B){for(b in B)I=I+"if"(sum(b)>1,-I,b)
I%%c(24,60)}


Takes I as a length-2 vector c(H,M) and B as a list of length-2 vectors for the buttons, c(H,M). Iterates through B, setting I to c(0,0) if the sum is 2. Then it mods down at the end. There's also a function in the header to translate the button presses into the right R format if you'd like to test them all; it takes the array [(H,M),...] as a string.

Try it online!

# C# (.NET Core), 93 bytes

(n,l)=>{for(int i=0,x;i<n.Length;){x=n[i++];if(x>1)l[0]=l[1]=0;else{l[x]=++l[x]%(24+36*x);}}}


Try it online!

Takes input as in trinary, with 0==(1,0),1==(0,1),2==(1,1), and the time in an array with index 0 being hours and 1 being minutes. Modifies the time array in place.

# Pyth, 22 bytes

%Vu?.AH,00+VGHEQ,24 60


Try it here.

# Scala, 116 bytes

So I just take the start time as two first parameters of my func (h and m), and I take the input sequence as an Array[Tuple2].

var x=h
var y=m
for(u<-a)u match{case (0,1)=>y=(y+1)%60
case (1,0)=>x=(x+1)%24
case (1,1)=>{x=0;y=0}
case _=>}
(x,y)


I wonder ... should I count the func declaration (def time(h:Int,m:Int,a:Array[Tuple2[Int,Int]]):Tuple2[Int,Int]={ plus the ending }`) in byte count?

Try it online!