Simulate My Stupid Old Alarm Clock

26

3

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

fireflame241

Posted 2017-09-15T23:13:23.823

Reputation: 7 021

4Heavily related – Stephen – 2017-09-15T23:16:26.897

Test cases in [h, m] format with Quaternary steps. – Justin Mariner – 2017-09-15T23:39:10.613

Is an input format of the two sets of data as one list acceptable? For example [[initialHour, initialMinute], [hourPressed1, minuitePressed1], [hourPressed2, minuitePressed2], ...]? – Jonathan Allan – 2017-09-16T17:04:40.327

@JonathanAllan Yes. – fireflame241 – 2017-09-16T17:07:58.223

What does 1200am mean in normal digital time? – Ferrybig – 2017-09-18T06:41:14.770

@Ferrybig 12:00am is the same as 0:00 (This is expanded upon in the "Task" section but I'll update at the top) – fireflame241 – 2017-09-18T13:59:19.820

Answers

8

Jelly, 13 bytes

_`+Ạ}?/%24,60

Try it online!

Erik the Outgolfer

Posted 2017-09-15T23:13:23.823

Reputation: 38 134

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 – 2017-09-16T17:15:36.490

@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 – 2017-09-16T17:16:17.127

7

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.

Chas Brown

Posted 2017-09-15T23:13:23.823

Reputation: 8 959

1-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 – 2017-09-16T12:36:41.653

173 bytes – Halvard Hummel – 2017-09-17T11:45:26.093

lambda(h,m),(d,e): is this pattern matching in Python!? – Quelklef – 2017-09-18T14:38:00.130

6

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!

Steadybox

Posted 2017-09-15T23:13:23.823

Reputation: 15 798

6

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)

Jonathan Allan

Posted 2017-09-15T23:13:23.823

Reputation: 67 804

-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 – 2017-09-16T17:07:46.927

5

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.

Neil

Posted 2017-09-15T23:13:23.823

Reputation: 95 035

4

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}

Justin Mariner

Posted 2017-09-15T23:13:23.823

Reputation: 4 746

4

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

LyricLy

Posted 2017-09-15T23:13:23.823

Reputation: 3 313

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 – 2017-09-16T05:08:02.140

Also, as b and c are always boolean values, you can replace b+c>1 with b&c. – Jonathan Frech – 2017-09-16T05:33:19.377

76 bytes (Shortened link, due to TIO being to large for comment box) – Halvard Hummel – 2017-09-16T11:17:32.603

4

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

Laikoni

Posted 2017-09-15T23:13:23.823

Reputation: 23 676

3

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.

nwellnhof

Posted 2017-09-15T23:13:23.823

Reputation: 10 037

3

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

Xcali

Posted 2017-09-15T23:13:23.823

Reputation: 7 671

3

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.

Naresh

Posted 2017-09-15T23:13:23.823

Reputation: 131

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 – 2017-09-16T09:46:42.667

1By the way, welcome to PPCG! Amazing first answer. – Mr. Xcoder – 2017-09-16T09:53:07.550

thank you so much, actually I used print() first... but I forgot after switching between different implementations. Thanks again for your help. – Naresh – 2017-09-16T09:57:50.520

1

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

Adrian Zhang

Posted 2017-09-15T23:13:23.823

Reputation: 199

1

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.

LegionMammal978

Posted 2017-09-15T23:13:23.823

Reputation: 15 731

1

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!

Giuseppe

Posted 2017-09-15T23:13:23.823

Reputation: 21 077

1

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.

jkelm

Posted 2017-09-15T23:13:23.823

Reputation: 441

0

Pyth, 22 bytes

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

Try it here.

Erik the Outgolfer

Posted 2017-09-15T23:13:23.823

Reputation: 38 134

0

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!

V. Courtois

Posted 2017-09-15T23:13:23.823

Reputation: 868