30
\$\begingroup\$

Imagine the following 24-hour clock that can be controlled by arrow keys:

╔══╗ ┌──┐
║00║:│00│
╚══╝ └──┘
 HH   mm

Pressing the up arrow twice (↑↑) will increase the currently focused hour input:

╔══╗ ┌──┐
║02║:│00│
╚══╝ └──┘
 HH   mm

Pressing the right arrow () will focus the other input.

┌──┐ ╔══╗
│02│:║00║
└──┘ ╚══╝
 HH   mm

Pressing the down arrow thrice (↓↓↓) will now decrease this input.

┌──┐ ╔══╗
│02│:║57║
└──┘ ╚══╝
 HH   mm

Shortly put:

  • The up arrow () will increase the currently active input.
  • The down arrow () will decrease the active input.
  • The right arrow () will move focus to the right input.
  • The left arrow () will move focus to the left input.
  • Up and down movement will loop around as expected for a time input.
  • Left and right movement don't loop around.

The challenge

The clock starts out at 00:00 with the hour input active (see first schematic). Given a list of input commands, output the resulting time in HH:mm format.
Input can be either a string or a list (or your language equivalent), where the different input directions can be one of the below options:

  • ↑↓←→
  • udlr
  • ^v<>
  • actual arrow key presses if your program has a GUI

Standard loopholes apply.

Test cases

↑↑→↓↓↓ = 02:57
↓→↑←↑→↓ = 00:00
↓→→↓ = 23:59
←←←←→↑ = 00:01
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓→↓ = 23:59
\$\endgroup\$
10
  • 1
    \$\begingroup\$ @JonathanFrech One of the given options, choosing any four unique values (for example 0123) would make the challenge a lot easier in certain languages while not benefitting others. \$\endgroup\$
    – Etheryte
    Jul 18, 2018 at 11:21
  • 1
    \$\begingroup\$ @LuisfelipeDejesusMunoz Yes, that's actually written out under the input rules. \$\endgroup\$
    – Etheryte
    Jul 18, 2018 at 11:45
  • 3
    \$\begingroup\$ I think this would have been more challenging if it included seconds. This would have more logic behind which one is currently in focus \$\endgroup\$
    – Jo King
    Jul 18, 2018 at 12:40
  • 3
    \$\begingroup\$ Missing a special rule to handle Konami code. \$\endgroup\$
    – coredump
    Jul 20, 2018 at 14:02
  • 1
    \$\begingroup\$ @coredump Considered it, but it would probably take more space than the core of the answer in most languages. \$\endgroup\$
    – Etheryte
    Jul 20, 2018 at 18:51

24 Answers 24

40
\$\begingroup\$

HTML on Google Chrome 67 in Chinese (Simplified), 39 bytes

<input type=time value=00:00 autofocus>

Screenshot

Chrome show different UI component in different language. Even a simple time input: AM/PM will be shown if you are using English (US). If you want test this by changing your Chrome's language. Do not mass up how to change it back.

\$\endgroup\$
13
  • 3
    \$\begingroup\$ dudee!! hahah I think is not valid tho \$\endgroup\$ Jul 18, 2018 at 12:35
  • 3
    \$\begingroup\$ Hitting right twice goes to AM/PM for me \$\endgroup\$
    – Jo King
    Jul 18, 2018 at 12:35
  • 1
    \$\begingroup\$ @JoKing I think it's locale/settings dependent? \$\endgroup\$
    – Etheryte
    Jul 18, 2018 at 12:36
  • 1
    \$\begingroup\$ @JoKing That's locale dependent. Maybe have a try by changing your Chrome's language to Chinese Simplify? (Do not mass up how to change it back.) \$\endgroup\$
    – tsh
    Jul 18, 2018 at 12:44
  • 1
    \$\begingroup\$ It works on firefox 61.0.1 \$\endgroup\$ Jul 18, 2018 at 14:10
13
\$\begingroup\$

C (gcc), 117 107 bytes

  • Saved ten bytes thanks to l4m2.
t,i,m[8];e(char*_){for(*m=i=2[m]=0;t=*_++;t<63?i=t%4:(i[m]+=t&8?1:'w'));printf("%02d:%02d",*m%24,2[m]%60);}

Try it online!

\$\endgroup\$
2
  • 5
    \$\begingroup\$ Nice variable naming. \$\endgroup\$
    – Etheryte
    Jul 18, 2018 at 11:44
  • \$\begingroup\$ # C (gcc), 107 bytes <!-- language-all: lang-c --> t,i,m[8];e(char*_){for(*m=i=2[m]=0;t=*_++;t<63?i=t%4:(i[m]+=t&8?1:119));printf("%02d:%02d",*m%24,2[m]%60);} Try it online! \$\endgroup\$
    – l4m2
    Jul 18, 2018 at 12:06
6
\$\begingroup\$

Stax, 36 35 33 32 bytes

áXò↑─↨√▓|êóÇiU&≡Q#┤Æ⌡⌠╟C▐╜√⌡∟▄╩╠

Run and debug it

Uses lrud.

Explanation:

'l/{'r/Bs$2lmM{${:14-m|+i36*24+%2|zm':* Full program,
'l/                                     Split the string on "l"
   {        m                           Map over the resulting array
    'r/                                   Split at "r"
       B                                  Uncons left, first on TOS (top of stack)
        s                                 Swap to get tail to top
         $                                Flatten; this removes multiple 'r's
          2l                              Listify two items, BOS (bottom of stack) is first element
             M                          Transpose: get [hour commands, minute commands]
              {                    m    Map:
               $                          Flatten
                {    m                    Map over single commands:
                 :1                         Number of set bits: 5 for 'u', 3 for 'd'
                   4-                       Subtract 4: u -> 1, d -> -1
                      |+                  Sum
                        i                 Iteration index: hours -> 0, minutes -> 1
                         36*24+           Multiply by 36, add 24: 0 -> 24, 1 -> 60
                               %          Modulo, this does -5 % 60 = 55
                                2|z       Stringify, left-padding with "0" to length 2
                                    ':* Join on ":"
                                        Implicit output
\$\endgroup\$
6
\$\begingroup\$

Python 2, 105 bytes

h=m=p=0
for c in map(' ^<>'.find,input()):w=1/c;m+=w*p;h+=w-w*p;p=[c-2,p][w]
print'%02d:%02d'%(h%24,m%60)

Try it online!

\$\endgroup\$
5
\$\begingroup\$

JavaScript (Node.js), 103 bytes

Takes input as a string, using udlr.

s=>(Buffer(s).map(n=>n%6?s%4?m+=n%2||59:h+=n%2||23:s=n,h=m=0),g=n=>('0'+n).slice(-2))(h%24)+':'+g(m%60)

Try it online!

\$\endgroup\$
5
\$\begingroup\$

C# (.NET Core), 149 132 bytes

s=>{var p=0;int[]h={0,0};foreach(var c in s)h[p=c<63?c/2%2:p]+=c>62?c>95?-1:1:0;return$"{(h[0]%24+24)%24:D2}:{(h[1]%60+60)%60:D2}";}

Try it online!

Using ^v<>.

This one made me realize that the modulo operator in C# does not work as expected, because in C# -1 % 60 = -1, so I need to do that weird operation at the end.

\$\endgroup\$
3
  • \$\begingroup\$ Can't (h[1]%60+60)%60 be replaced with (h[1]+60)%60 ? \$\endgroup\$
    – IanF1
    Jul 18, 2018 at 18:31
  • 2
    \$\begingroup\$ @IanF1 no you can't. What if the user presses the down button 100 times? Or 1000 times? \$\endgroup\$
    – Charlie
    Jul 18, 2018 at 19:07
  • \$\begingroup\$ thanks for clarifying :) it's surprising to me that this way is shorter than applying the modulo on the fly (with 59 in place of -1). \$\endgroup\$
    – IanF1
    Jul 18, 2018 at 19:12
5
\$\begingroup\$

Lua (love2d framework),311 308 bytes

l,b,d,t,f,a=love,{24,60},{1,-1},{0,0},1,{"left","right","up","down"}function c(n,i)t[f]=(n+d[i])%b[f]end function l.draw()h,m=t[1],t[2]l.graphics.print((h<10 and 0 ..h or h)..":"..(m<10 and 0 ..m or m),0,0)end function l.keypressed(k)for i,n in pairs(a)do f=k==n and(i>2 and(c(t[f],i-2)or f)or i)or f end end

Unscrumbeled version:

--initialize all needed values
l,b,d,t,f,a=love,{24,60},{1,-1},{0,0},1,{"left","right","up","down"}

--increase the numbers depending on the focus and up or down
function c(n,i)
  t[f]=(n+d[i])%b[f]
end 

--draw the time to the screen
function l.draw()
  h,m=t[1],t[2]
  l.graphics.print((h<10 and 0 ..h or h)..":"..(m<10 and 0 ..m or m),0,0)
end

--get the keys and check if it is an arrow key
function l.keypressed(k)
  for i,n in pairs(a)do
    f=k==n and(i>2 and(c(t[f],i-2)or f)or i)or f 
  end 
end

Probably still not 100% easy to read because all the ifs are interchanged with an trinary statement ( ..and ..or) :)

if started in an main.lua with love then it will pop up a window and you can press the arrowkeys to change the numbers

\$\endgroup\$
2
  • \$\begingroup\$ could you also post expanded version for readability \$\endgroup\$ Jul 18, 2018 at 18:20
  • \$\begingroup\$ sure, I added a expanded version no problem :) \$\endgroup\$
    – Lycea
    Jul 19, 2018 at 7:24
4
\$\begingroup\$

MATL, 57 56 55 bytes

1Oi9\"@5<?y@3-ZS*+}wx7@-X^w]]wx&Zjh24 60h\'%02d:%02d'YD

Try it online!

Represents hour and minutes using complex numbers, with the real part being hours and the imaginary part minutes.

With comments:

1     % Push 1 on the stack
      % represents which timer box we're in, starts at hour box
      % imaginary number j would represent minutes box
O     % Push initial hour and minutes 0+0j
i9\   % Fetch input, mod each character's ASCII value by 9.
      % Gives 4 1 8 6 for ^ v > < respectively
"     % iterate through (modded) input
  @5<?     % Push current input, see if it's < 5 
           % if so, it's an up or down time change
    y        % so copy out the box indicator (1 or j)
    @3-      % Subtract 3 from the current input
    ZS       % Take the result's sign (-1 for v, 1 for ^)
    *        % Multiply indicator with that
    +        % Add the result to the time value
  }        % else, it's a right or left arrow
    wx       % so bring out the box indicator and delete it
    7@-      % Subtract current input from 7. 1 for < and -1 for >
    X^       % Take the square root of that. 1 for < and j for >
    w        % switch stack to bring time value on top again
  ]       % end if
]     % end loop
wx    % bring box indicator out, delete it
&Zj   % split the complex time value to real and imaginary
h     % then concatenate them into an array
24 60h\ % mod hour and minute values by 24 and 60 respectively
'%02d:%02d'YD % sprintf the time array with 0-padding
\$\endgroup\$
4
\$\begingroup\$

PHP, 145 134 133 bytes

(-11 bytes by more golfing)

(-1 byte by using Davіd's loop method)

<?for($h=$m=0,$a=h;$c=$argv[++$i];)$c<l?$$a--:($c>r?$$a++:$a=$c<r?h:m);$h%=24;$m%=60;printf('%02d:%02d',$h<0?$h+24:$h,$m<0?$m+60:$m);

To run it:

php -n -d error_reporting=0 <filename> <command_1> <command_2> ... <command_n>

Example:

php -n -d error_reporting=0 time_setter.php u u r d d d l d

Or Try it online!

Notes:

  • To save some bytes, I have used strings without single/double quotations as the string wrapper. Thus, the error_reporting=0 option is used to not output warnings.
  • Input commands: u d l r
\$\endgroup\$
5
  • \$\begingroup\$ 128 bytes, -6: Try it online! (Nice solution, btw :) \$\endgroup\$
    – Ethan
    Jul 19, 2018 at 6:13
  • \$\begingroup\$ @Davіd: Thanks, but your update has two issues. First on is that $h is not set, so decreasing it on start fails: Try it online! \$\endgroup\$
    – Night2
    Jul 19, 2018 at 8:30
  • \$\begingroup\$ @David: And the second issue happens when we switch hour/minute up or down more than 24/60 times: Try it online! \$\endgroup\$
    – Night2
    Jul 19, 2018 at 8:30
  • \$\begingroup\$ @Davіd: But thanks to your loop method, I could reduce 1 more byte: Try it online! \$\endgroup\$
    – Night2
    Jul 19, 2018 at 8:33
  • \$\begingroup\$ ah, alright, sorry it didn't completely work :) \$\endgroup\$
    – Ethan
    Jul 19, 2018 at 9:03
4
\$\begingroup\$

JavaScript, 104 103 bytes

Takes input as an array of characters, using <>^v.

a=>(a.map(z=>z<"^"?a=z<">":a?x+=z<"v"||23:y+=z<"v"||59,x=y=0),g=n=>`0${n}`.slice(-2))(x%24)+`:`+g(y%60)

Try it online

\$\endgroup\$
3
\$\begingroup\$

Haskell, 236 bytes

f=u 0 0
k _ _ _ _ _ h m[]=z h++':':z m
k a b c d e h m(q:s)=case q of{'^'->e(a h)(b m)s;'v'->e(c h)(d m)s;'>'->v h m s;'<'->u h m s}
u=k(o(+)24)id(o(-)24)id u
v=k id(o(+)60)id(o(-)60)v
o f m x=mod(f x 1)m
z n|n<10='0':show n
z n=show n

f is the main function, and has type String -> String:

*Main> f "^^>vvv"
"02:57"
*Main> f "v>^<^>v"
"00:00"
*Main> f "v>>v"
"23:59"
*Main> f "<<<<>^"
"00:01"
*Main> f "vvvvvvvvvvvvvvvvvvvvvvvvv>v"
"23:59"

Essentially u and v are mutually recursive functions of type Integer -> Integer -> String -> String. They take the hour, the minute and a list of characters over the set {v,^,<,>}, and return the time string. u acts as if the hour dial is highlighted, recursively calling u if the head of the list is in {v,^}, and v if the head of the list is in {<,>}. v is similar but for the minute dial.

Everything else is just saving characters.

\$\endgroup\$
3
\$\begingroup\$

Lua, 132 bytes

loadstring's,t,m=1,{0,0},{24,60}for c in(...):gmatch"."do t[s]=(t[s]+(("d u"):find(c)or 2)-2)%m[s]s=("lr"):find(c)or s end return t'

Try it online!


Explanation

This is an anonymous function (a way to use it is shown on the link).

s=1 -- s will control the selection (1 is hour and 2 min)
t={0,0} -- is the time itself
m={24,60} -- is the maximum for each 'box' (hour or min)
-- I've actually used Lua's multiple variable assignment: s,t,m=1,{0,0},{24,60}

for c in (...):gmatch(".") do -- go through each character of the input
  t[s] = (t[s] + (("d u"):find(c) or 2)-2) % m[s] -- set the current 'box' as
          t[s] +   -- itself plus ...
                  ("d u"):find(c) or 2   -- it's index on the string "d u" (that means it's going to be 1 or 3)
                                         -- or 2 if it wasn't found (if the current character doesn't sum or subtract from the box)
                                       -2   -- this adjusts the result 1, 2 or 3 to being -1, 0 or 1
                                            -- making the inputs 'd' and 'u' as -1 and +1 respectively, and an input different from both as 0
         (                               ) % m[s]   -- modulo of the maximum of the selected 'box'

  s=("lr"):find(c) or s
    ("lr"):find(c)   -- if the current input character is l or r, then set 's' (the 'box' selection) to being 1 or 2.
                   or s   -- else let it as is
end
return t -- returns 't', a table with hour and minutes respectively
\$\endgroup\$
1
  • \$\begingroup\$ The output should be in the HH:mm format, rather than a table \$\endgroup\$
    – Jo King
    Jul 29, 2018 at 10:40
2
\$\begingroup\$

Java 8, 121 bytes

c->{int i=0,m[]={0,0,0};for(int t:c)if(t<63)i=t%4;else m[i]+=(t&8)>0?1:119;return"".format("%02d:%02d",m[0]%24,m[2]%60);}

Port of Jonathan Frech's C answer. Accepts ^v<>. Try it online here.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 36 bytes

I believe O%5;4ṣ3œṡ€4Z%3’§§%"“ð<‘DŻ€ṫ€-j”: should work for 32, but œṡ seems to currently have a bug.

O%5;4ṣ3i€4$œṖ"$Z%3’§§%"“ð<‘DŻ€ṫ€-j”:

A full program printing the result to STDOUT (as a monadic link it actually returns a mixed list of integers (albeit single digit ones) and characters (the :).

Uses the udlr option for input.

Try it online! Or see a test-suite.

How?

O%5;4ṣ3i€4$œṖ"$Z%3’§§%"“ð<‘DŻ€ṫ€-j”: - Link: list of characters (in 'udlr')
O                                    - to ordinals
 %5                                  - modulo five  ...maps u:2, d:0, l:3, r:4
   ;4                                - concatenate a 4 (to always end up with both hrs & mins - even when no r is ever pressed)
     ṣ3                              - split at threes (the l presses)
       i€4$œṖ"$                      - a replacement for œṡ€4 (split each at first occurrence of)...
              $                      - | last two links as a monad:
          $                          - |   last two links as a monad:
         4                           - |     literal four
       i€                            - |     for €ach get first index of (4) else yield 0
             "                       - |   zip with:
           œṖ                        - |     partition at indices
               Z                     - transpose (to get a list of two lists of lists)
                %3                   - modulo by three. To replace any 4(r) with 1
                                     -  ...while keeping any 0(d) as 0, or 2(u) as 2
                  ’                  - decrement. All r are now 0, d are -1 and u are 1
                   §                 - sum each
                    §                - sum each. Now we have the total increase value as
                                     -    ...integers for each of hrs and mins
                       “ð<‘          - code-page indices list = [24,60]
                      "              - zip with:
                     %               -   modulo
                           D         - to decimal lists
                            Ż€       - prepend each with a zero (to cater for values less than ten)
                              ṫ€-    - tail each from index -1. Keeps rightmost two digits of each only)
                                  ”: - literal character ':'
                                 j   - join
                                     - as full program implicit print (smashes the digits and characters together)
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Classic), 97 84 bytes

5↑∊{¯3↑'0',':',⍨⍕⍵}¨24 60|A⊣⍎¨'⎕IO←1' '⎕IO←0' 'A[1]+←1' 'A[1]-←1'['←→↑'⍳⍞,'←']⊣A←0 0

Try it online!

Requires ⎕IO←1

\$\endgroup\$
2
\$\begingroup\$

QBasic, 229 bytes

A script that takes input as keystrokes and outputs to the console.

Note: terminal " are included for syntax highlighting only, and do not contribute to the bytecount

z$=CHR$(0)
DO
x=0
y=0
SELECT CASE INKEY$
CASE z$+"K"
r=0
CASE z$+"M"
r=1
CASE z$+"H"
x=1
y=1
CASE z$+"P"
x=23
y=59
END SELECT
IF r THEN m=(m+y)MOD 60ELSE h=(h+x)MOD 24
CLS
?RIGHT$("00000"+LTRIM$(STR$(h*1000+m)),5)
LOCATE 1,3
?":"
LOOP

Commented

z$=CHR$(0)                                      ''  Set var to null char
DO                                              ''
    x=0                                         ''  Set Hours Shift to 0 
    y=0                                         ''  Set Minutes Shift to 0 
    SELECT CASE INKEY$                          ''  Take keystroke input
        CASE z$+"K"                             ''  If is Left Arrow
            r=0                                 ''    Bool to modify right (minutes) 
        CASE z$+"M"                             ''  If is Right Arrow
            r=1                                 ''    Bool to modify left (hours)
        CASE z$+"H"                             ''  If is Up Arrow
            x=1                                 ''    Set Hours Shift to 1 
            y=1                                 ''    Set Minutes Shift to 1
        CASE z$+"P"                             ''  If is Down Arrow
            x=23                                ''    Set Hours Shift to 23 
            y=59                                ''    Set Minutes Shift to 23 
    END SELECT                                  ''
    IF r THEN m=(m+y)MOD 60ELSE h=(h+x)MOD 24   ''  Shift Minutes If `r=1` Else Shift Hours
    CLS                                         ''  Clear Screen
    ?RIGHT$("00000"+LTRIM$(STR$(h*1000+m)),5)   ''  Use math to concat Hours and Minutes 
                                                ''  then Convert to String and prepend 0s 
                                                ''  to a length of 5
    LOCATE 1,3                                  ''  Cursor to the the third digit
    ?":"                                        ''  Overwrite that digit with a `:`
LOOP                                            ''  Loop
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Shouldn't that be (m+y)? \$\endgroup\$
    – Neil
    Jul 18, 2018 at 15:15
  • \$\begingroup\$ In the note, should not does be do? \$\endgroup\$ Jul 18, 2018 at 15:40
  • \$\begingroup\$ @JonathanFrech - Yep it should be. Thanks for keeping my grammar in check \$\endgroup\$ Jul 18, 2018 at 16:26
  • \$\begingroup\$ Sorry, I thought m was for minutes for some reason... I see your commented version is more readable. \$\endgroup\$
    – Neil
    Jul 18, 2018 at 18:49
2
\$\begingroup\$

Powershell, 109 103 bytes

-6 byte thanks AdmBorkBork

$t=0,0
$args|%{$t[+$i]+=. @{l={$i=0};r={$i=1};u={1};d={119}}.$_}
"{0:00}:{1:00}"-f($t[0]%24),($t[1]%60)

Test script:

$f = {

$t=0,0
$args|%{$t[+$i]+=. @{l={$i=0};r={$i=1};u={1};d={119}}.$_}
"{0:00}:{1:00}"-f($t[0]%24),($t[1]%60)

}

@(
    ,('02:57',('u','u','r','d','d','d'))
    ,('00:00',('d','r','u','l','u','r','d'))
    ,('23:59',('d','r','r','d'))
    ,('00:01',('l','l','l','l','r','u'))
    ,('23:59',('d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','d','r','d'))
) | % {
    $e, $c = $_
    $r = &$f @c
    "$($r-eq$e): $r"
}

Output:

True: 02:57
True: 00:00
True: 23:59
True: 00:01
True: 23:59

Explanation

Basic idea is to use a [hashtable], which keys are control commands and values are scriptblocks. The code execute the scriptblock for each command from arguments.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can get rid of $i=0 by casting your array index like $t[+$i] to save some bytes. Try it online! \$\endgroup\$ Jul 20, 2018 at 19:35
2
\$\begingroup\$

Perl 6, 101 91 89 86 bytes

{$/=[];$!=0;$_>2>($!=$_-3)||($/[$!]+=$_-1)for .ords X%5;($0%24,$1%60).fmt("%02d",":")}

Try it online!

Anonymous code block that takes a string of uldr characters and returns in the given format

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

perl -F// -E, 72 bytes

$x=H;/u/?$$x++:/d/?$$x--:($x=/l/?H:M)for@F;printf"%02d:%02d",$H%24,$M%60
\$\endgroup\$
1
\$\begingroup\$

Python, 120 bytes

o,i=[0,0],0
for s in list(input()):i=(i+(s=='r')-(s=='l')>=1);o[i]+=(s=='u')-(s=='d')
print'%02d:%02d'%(o[0]%24,o[1]%60)
\$\endgroup\$
8
  • \$\begingroup\$ This looks like a snippet taking input in a variable. As a general rule, we require answers to present either a full program (taking input from program arguments or standard input) or a function (taking input from function parameters). \$\endgroup\$ Jul 19, 2018 at 9:51
  • 1
    \$\begingroup\$ Also, won't this run into a wall when an input of, say, ld or rru causes i to leave the range (0,1) and o[i] is accessed afterwards? \$\endgroup\$ Jul 19, 2018 at 11:49
  • \$\begingroup\$ @O.O.Balance oh thanks for reminding me that you need function or unput(). From requirements I figured that L and R actions will never loop around (i.e. no LL) \$\endgroup\$ Jul 19, 2018 at 14:14
  • \$\begingroup\$ @aaaaaa No looping means lll isn't the same as r. Having ll or rr is valid input, it's also in the test-cases, see the third one for example. \$\endgroup\$
    – Etheryte
    Jul 19, 2018 at 14:21
  • \$\begingroup\$ This answer currently has an IndexError on the 3rd test case instead of outputting 23:59. Try it online! \$\endgroup\$
    – 0 '
    Jul 19, 2018 at 14:31
1
\$\begingroup\$

Haskell, 186 bytes

f(0,0)'<'
f t i('^':r)=f(i#t$1)i r
f t i('v':r)=f(i#t$ -1)i r
f t i(x:r)=f t x r
f(h,m)_ _=s h++':':s m
('<'#(h,m))n=(mod(24+n+h)24,m)
(_#(h,m))n=(h,mod(60+n+m)60)
s n=['0'|n<10]++show n

Try it online!

\$\endgroup\$
1
\$\begingroup\$

R, 368 355 bytes

f=function(){C=as.character
i=ifelse
p=paste0
r=1:10
h=C(0:23);m=C(0:59)
h[r]=p(0,h[r])
m[r]=p(0,m[r])
x=y=z=1
while(T){print(p(h[x],":",m[y]))
v=1
n="[UDLRS]"
while(!grepl(n,v))v=toupper(readline(n))
if(v=="L")z=1 else if(v=="R")z=0
if(v=="S")T=F
if(v=="U")if(z)x=i(x==24,1,x+1)else y=i(y==60,1,y+1)
if(v=="D")if(z)x=i(x==1,24,x-1)else y=i(y==1,60,y-1)}}

Definitely not the best approach, but works.

Functionality: Run function, type each letter to (in/de)crease or move left/right, typing "s" ends the "game". The catch is that it will accept one and only one letter at a time.

-13 bytes Consolidated some values into one row, overwrote T as F instead of using break, found several spaces to eliminate, and a string stored in a variable instead

f=function(){C=as.character                             # Abbreviate functions
i=ifelse
p=paste0
r=1:10                                                  # Initialize and format values
h=C(0:23);m=C(0:59)
h[r]=p(0,h[r])
m[r]=p(0,m[r])
x=y=z=1
while(T){print(p(h[x],":",m[y]))                        # Begin while loop and print time
v=1                                                     # Initial value reset each iteration to retrieve a new direction
n="[UDLRS]"                                             # Used for verification and request
while(!grepl(n,v))v=toupper(readline(n))                # Will only accept proper directions or stopping rule
if(v=="L")z=1 else if(v=="R")z=0                        # Evaluate for hour or minute
if(v=="S")T=F                                           # Stopping rule, overwrite True to False
if(v=="U")if(z)x=i(x==24,1,x+1)else y=i(y==60,1,y+1)    # Rules for Up
if(v=="D")if(z)x=i(x==1,24,x-1)else y=i(y==1,60,y-1)}}  # Rules for Down

I am also editing an alternate format to accept an R string and/or vector, will post next week.

\$\endgroup\$
1
\$\begingroup\$

SmileBASIC, 123 bytes

@L
B=BUTTON(2)D=(B==1)-(B==2)S=S+!S*(B>7)-S*(B==4)H=(H+D*!S+24)MOD 24WAIT
M=(M+D*S+60)MOD 60?FORMAT$("%02D:%02D",H,M)GOTO@L

BUTTON() returns an integer where each bit represents a button

1 = up
2 = down
4 = left
8 = right
...

BUTTON(2) returns only the buttons that were just pressed (not being held)

WAIT is required because BUTTON only updates once per frame (1/60 of a second). Otherwise the same button press would be detected multiple times.

This can definitely be shorter

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 38 37 32 bytes

'l¡'rδ¡0ζć‚R€S„0uskOŽ9¦2ä%T‰J':ý

Uses udlr for the directions, but could also use ^v<> for the same byte-count (the characters ↑↓←→ are not part of 05AB1E's codepage, so using those would increase the byte-count by a lot, since the encoding should be changed).

Try it online or verify all test cases.

Explanation:

'l¡          '# Split the (implicit) input on "l"
              #  i.e. "lllrurulddd" → ["","","","ruru","ddd"]
     δ        # Map each item to:
   'r ¡      '#  Split the item on "r"
              #   → [[""],[""],[""],["","u","u"],["ddd"]]
       0ζ     # Zip/transpose; swapping rows/columns, with 0 as filler
              #  → [["","","","","ddd"],[0,0,0,"u",0],[0,0,0,"u",0]]
ć             # Head extracted: pop and push the remainder and head-item to the stack
              #  → [[0,0,0,"u",0],[0,0,0,"u",0]] and ["","","","","ddd"]
 ‚R           # Pair the head and remainder back together, and reverse the pair
              # (so the remainder portion is basically wrapped in a list now)
              #  → [["","","","","ddd"],[[0,0,0,"u",0],[0,0,0,"u",0]]]
   €S         # Convert each item to a list of characters
              # (implicitly flattens and removes empty strings)
              #  → [["d","d","d"],[0,0,0,"u",0,0,0,0,"u",0]]
      „0usk   # Index each character into the string "0u"
              # (0 remains 0; "u" becomes 1; "d" becomes -1 since it's not in this string)
              #  → [[-1,-1,-1],[0,0,0,1,0,0,0,0,1,0]]
           O  # Then take the sum of each inner list
              #  → [-3,2]
Ž9¦           # Push compressed integer 2460
   2ä         # Split into two parts: [24,60]
     %        # Modulo the two lists
              #  → [21,2]
      T‰      # Divmod each with 10
              #  → [[2,1],[0,2]]
        J     # Join each inner list together
              #  → ["21","02"]
         ':ý '# Join the list with ":" delimiter
              #  → "21:02"
              # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ž9¦ is 2460.

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