27
\$\begingroup\$

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
asked Sep 15, 2017 at 23:13
\$\endgroup\$
6
  • 4
    \$\begingroup\$ Heavily related \$\endgroup\$ Commented Sep 15, 2017 at 23:16
  • \$\begingroup\$ Test cases in [h, m] format with Quaternary steps. \$\endgroup\$ Commented Sep 15, 2017 at 23:39
  • \$\begingroup\$ Is an input format of the two sets of data as one list acceptable? For example [[initialHour, initialMinute], [hourPressed1, minuitePressed1], [hourPressed2, minuitePressed2], ...]? \$\endgroup\$ Commented Sep 16, 2017 at 17:04
  • \$\begingroup\$ @JonathanAllan Yes. \$\endgroup\$ Commented Sep 16, 2017 at 17:07
  • \$\begingroup\$ What does 1200am mean in normal digital time? \$\endgroup\$ Commented Sep 18, 2017 at 6:41

17 Answers 17

8
\$\begingroup\$

Jelly, 13 bytes

_`+Ạ}?/%24,60

Try it online!

answered Sep 16, 2017 at 10:48
\$\endgroup\$
2
  • \$\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\$ Commented 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\$ Commented Sep 16, 2017 at 17:16
7
\$\begingroup\$

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.

answered Sep 16, 2017 at 5:38
\$\endgroup\$
3
  • 1
    \$\begingroup\$ -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) \$\endgroup\$ Commented Sep 16, 2017 at 12:36
  • 1
    \$\begingroup\$ 73 bytes \$\endgroup\$ Commented Sep 17, 2017 at 11:45
  • \$\begingroup\$ lambda(h,m),(d,e): is this pattern matching in Python!? \$\endgroup\$ Commented Sep 18, 2017 at 14:38
6
\$\begingroup\$

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!

answered Sep 15, 2017 at 23:28
\$\endgroup\$
0
6
\$\begingroup\$

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)
answered Sep 16, 2017 at 1:28
\$\endgroup\$
1
  • \$\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\$ Commented Sep 16, 2017 at 17:07
5
\$\begingroup\$

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.

answered Sep 16, 2017 at 0:31
\$\endgroup\$
4
\$\begingroup\$

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

Try it online!

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

answered Sep 16, 2017 at 4:25
\$\endgroup\$
3
  • \$\begingroup\$ You may be able to replace (m[0]+1) with -~m[0] and if m[0]<23 else 0 with *(m[0]<23). \$\endgroup\$ Commented Sep 16, 2017 at 5:08
  • \$\begingroup\$ Also, as b and c are always boolean values, you can replace b+c>1 with b&c. \$\endgroup\$ Commented Sep 16, 2017 at 5:33
  • \$\begingroup\$ 76 bytes (Shortened link, due to TIO being to large for comment box) \$\endgroup\$ Commented Sep 16, 2017 at 11:17
4
\$\begingroup\$

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)].

answered Sep 16, 2017 at 8:26
\$\endgroup\$
4
\$\begingroup\$

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}

answered Sep 16, 2017 at 0:50
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 40 bytes

{.reduce({(@^a Z+@^b)X*[email protected]})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.

answered Sep 16, 2017 at 0:45
\$\endgroup\$
3
\$\begingroup\$

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
answered Sep 16, 2017 at 3:23
\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\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 of typealias. \$\endgroup\$ Commented Sep 16, 2017 at 9:46
  • 1
    \$\begingroup\$ By the way, welcome to PPCG! Amazing first answer. \$\endgroup\$ Commented 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\$ Commented Sep 16, 2017 at 9:57
1
\$\begingroup\$

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 :(

LyricLy
3,7432 gold badges20 silver badges40 bronze badges
answered Sep 16, 2017 at 4:47
\$\endgroup\$
1
\$\begingroup\$

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.

answered Sep 16, 2017 at 15:44
\$\endgroup\$
1
\$\begingroup\$

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!

answered Sep 18, 2017 at 14:49
\$\endgroup\$
1
\$\begingroup\$

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.

answered Sep 19, 2017 at 17:16
\$\endgroup\$
0
\$\begingroup\$

Pyth, 22 bytes

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

Try it here.

answered Sep 16, 2017 at 14:56
\$\endgroup\$
0
\$\begingroup\$

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!

answered Sep 18, 2017 at 12:48
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.