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
\$\endgroup\$
6
  • 4
    \$\begingroup\$ Heavily related \$\endgroup\$
    – Stephen
    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\$
    – Ferrybig
    Commented Sep 18, 2017 at 6:41

17 Answers 17

8
\$\begingroup\$

Jelly, 13 bytes

_`+Ạ}?/%24,60

Try it online!

\$\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.

\$\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\$
    – Quelklef
    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!

\$\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)...

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)
\$\endgroup\$
1
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.

\$\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].

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

\$\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}

\$\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.

\$\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
\$\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\$
    – Mr. Xcoder
    Commented Sep 16, 2017 at 9:46
  • 1
    \$\begingroup\$ By the way, welcome to PPCG! Amazing first answer. \$\endgroup\$
    – Mr. Xcoder
    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\$
    – Naresh
    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 :(

\$\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.

\$\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!

\$\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.

\$\endgroup\$
0
\$\begingroup\$

Pyth, 22 bytes

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

Try it here.

\$\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!

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.