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)],
(0,1). This corresponds to minute being pressed. The time is now13:59.(0,1). This corresponds to minute being pressed. The time is now13:00.(0,1). This corresponds to minute being pressed. The time is now13:01.(0,0). This corresponds to neither button being pressed. The time,unaffected, is now13:01(1,1). This corresponds to both buttons being pressed. The time is now0:00.(1,0)This corresponds to hour being pressed. The time is now1: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)in24-hour time such as(13, 30)(hourranges from0to23andminuteranges from0to59) - same as the previous but in
12-hour time and a Booleanam/pmswitch (hourranges from0to11or12and1to11withminutefrom0to59). - a number of minutes since
0:00such 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
17 Answers 17
-
\$\begingroup\$ 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". \$\endgroup\$Jonathan Allan– Jonathan Allan2017年09月16日 17:15:36 +00:00Commented Sep 16, 2017 at 17:15
-
\$\begingroup\$ @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 \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年09月16日 17:16:17 +00:00Commented Sep 16, 2017 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)
Function that takes time as a tuple (hour,minute); outputs same way.
-
1\$\begingroup\$ -3 bytes by using
all(b)instead ofb[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)\$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年09月16日 12:36:41 +00:00Commented Sep 16, 2017 at 12:36 -
1\$\begingroup\$ 73 bytes \$\endgroup\$anon– anon2017年09月17日 11:45:26 +00:00Commented Sep 17, 2017 at 11:45
-
\$\begingroup\$
lambda(h,m),(d,e):is this pattern matching in Python!? \$\endgroup\$Quelklef– Quelklef2017年09月18日 14:38:00 +00:00Commented Sep 18, 2017 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);}
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)...
N99Ạ¤?+8
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?
N99Ạ¤?+8 - Link 1, nextState: list, currentState [cH, cM]; list, presses [pH, pM]
? - if:
¤ - ...condition: nilad followed by link(s) as a nilad:
9 - chain's right argument, presses
Ạ - all truthy? (1 for [1,1] 0 otherwise)
N - ...then: negate (the left argument, currentState, i.e. [-cH, -cM])
9 - ...else: chain's right argument, presses
8 - 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)
-
\$\begingroup\$ -1 byte by replacing
9Ạ¤withẠ}. Another -2 for using an allowed format. Finally, another -1 because the chain before theµhere is called as a dyad.. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2017年09月16日 17:07:46 +00:00Commented Sep 16, 2017 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, (削除) 135 (削除ここまで) (削除) 117 (削除ここまで) 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
Takes the time as a list in the form [hour, minute].
-
\$\begingroup\$ You may be able to replace
(m[0]+1)with-~m[0]andif m[0]<23 else 0with*(m[0]<23). \$\endgroup\$Jonathan Frech– Jonathan Frech2017年09月16日 05:08:02 +00:00Commented Sep 16, 2017 at 5:08 -
\$\begingroup\$ Also, as
bandcare always boolean values, you can replaceb+c>1withb&c. \$\endgroup\$Jonathan Frech– Jonathan Frech2017年09月16日 05:33:19 +00:00Commented Sep 16, 2017 at 5:33 -
\$\begingroup\$ 76 bytes (Shortened link, due to TIO being to large for comment box) \$\endgroup\$anon– anon2017年09月16日 11:17:32 +00:00Commented Sep 16, 2017 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*[email protected]})Z%24,60}
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
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)}
function will take initial value and array of tuples and returns final time.
-
\$\begingroup\$ 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 oftypealias. \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年09月16日 09:46:42 +00:00Commented Sep 16, 2017 at 9:46 -
1\$\begingroup\$ By the way, welcome to PPCG! Amazing first answer. \$\endgroup\$Mr. Xcoder– Mr. Xcoder2017年09月16日 09:53:07 +00:00Commented Sep 16, 2017 at 9:53
-
\$\begingroup\$ thank you so much, actually I used print() first... but I forgot after switching between different implementations. Thanks again for your help. \$\endgroup\$Naresh– Naresh2017年09月16日 09:57:50 +00:00Commented Sep 16, 2017 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.
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);}}}
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.
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?
[h, m]format with Quaternary steps. \$\endgroup\$[[initialHour, initialMinute], [hourPressed1, minuitePressed1], [hourPressed2, minuitePressed2], ...]? \$\endgroup\$