12
\$\begingroup\$

Your program / function, etc. will take 2 inputs. The first will be a list of who came to my party and when. Example:

Kevin 13:02  
Ruby 5  
Sam 3  
Lisa 6  
Bob 12  

What does that mean? It means that Kevin got to my party first (at 13:02, 24-hour time), then Ruby 5 minutes later, then Sam 3 minutes later, then Lisa 6 minutes later, and last Bob 12 minutes later.

The second input will be when my party started. Example:

13:15

(24-hour time). Your output must be the list of people who were late. (Anyone exactly on time is fine.) Example calculations (just for example, don't output these)

Kevin 13:02
Ruby 13:07
Sam 13:10
Lisa 13:16
Bob 13:28

Lisa and Bob arrived after 13:15, therefore this program should print "Lisa,Bob".

Input assumptions

  • Input 1 will always be a name (regex [A-Z][a-z]*), then a space, then a 24-hour time in the form hours:minutes on the first line, then a name, a space, and a positive integer (number of minutes later) on the next lines. There will always be at least 1 line.
  • If you would like, you may take input 1 with any other character instead of a line break.
  • Input 2 will be in the format hours:minutes.
  • You may take your inputs as one string separated by any character if you want. This is optional.
  • Don't worry about day crossover. My parties never to after 23:59.

Output rules

  • Output can be a function return value or a string echoed to STDIN, a file, etc. You must return a string or an array / list.
    • If you return a string, it must be each person who was late (order does not matter), separated by any non-alphanumeric delimiter.
    • If you return an array / list, it must be a list of everyone who was late.
\$\endgroup\$
  • 2
    \$\begingroup\$ Is the strict input format necessary? Could, for example, the first input be a list of lists, each being a "line" containing the two data items? \$\endgroup\$ – Jonathan Allan Apr 14 '17 at 19:24
  • \$\begingroup\$ "Input 1 will always be a name (regex [A-Z][a-z]*)" Does this suggest that names can be empty? \$\endgroup\$ – HyperNeutrino Apr 14 '17 at 19:45
  • 2
    \$\begingroup\$ I assume you meant "yes the strict input format is necessary". \$\endgroup\$ – Jonathan Allan Apr 14 '17 at 19:54
  • 2
    \$\begingroup\$ Strict input format makes this challenge less interesting \$\endgroup\$ – Luis Mendo Apr 14 '17 at 22:35
  • 3
    \$\begingroup\$ "My parties never to after 11:59." do you mean 23:59? \$\endgroup\$ – tsh Apr 15 '17 at 4:32

17 Answers 17

3
\$\begingroup\$

MATL, 31 bytes

jYb1L&)1&)XUYs1440/0whwYO+jYO>)

The first input uses space instead of line break (allowed by the challenge).

Output uses line break as separator.

Try it online!

Explanation

j       % Input first string
Yb      % Split at spaces. Gives cell array of strings
1L&)    % Separate into subarrays with odd and even indices. Odd are names, even
        % are time and increments in minutes
1&)     % Separate the subarray of even indices into first entry and remaining
        % entries. The first is a string representing the time of first arrival,
        % the rest are strings representing increments in minutes
XU      % Convert strings representing increments into the actual numbers
Ys      % Cumulative sum
1440/   % Divide by 1440 (number of minutes in a day)
0wh     % Prepend a 0
w       % Swap. Bring the string with time of first arrival to the top
YO      % Convert to serial date number. Fractional part indicates time
+       % Add. This gives all arrivals as serial date numbers
j       % Input second string
YO      % Convert to serial date number
>       % Less than?, element-wise
)       % Index: select the names for which the comparison gave true
        % Implicitly display
\$\endgroup\$
6
\$\begingroup\$

JavaScript (ES6), 98 97 bytes

Saved 1 byte thanks to Neil

Takes the list of guests l and the party time h in currying syntax (l)(h). Expects a trailing linebreak on the list. Returns a space-separated list of names such as Lisa Bob.

l=>h=>l.replace(/(.* )(.*)\n/g,(_,a,b)=>(t-=T(b))<0?a:'',t=(T=h=>eval(h.replace(/:/,'*60+')))(h))

Formatted and commented

l => h =>                         // given a list of guests l and a party time h
  l.replace(                      // for each guest in l:
    /(.* )(.*)\n/g,               //   extract the name a and arrival time b
    (_, a, b) =>                  //   subtract the arrival time from the time counter
      (t -= T(b)) < 0 ?           //   if the result is negative:
        a                         //     the guest is late: keep the name
      :                           //   else:
        '',                       //     the guest is on time: remove this entry
    t = (                         //   initialize the time counter t
      T = h =>                    //   define T():
        eval(                     //     a function that takes either a time
          h.replace(/:/, '*60+')  //     in hh:mm format or an amount of minutes
        )                         //     and returns an amount of minutes   
    )(h)                          //   call it with the party time
  )                               // end of replace()

Demo

let f =

l=>h=>l.replace(/(.* )(.*)\n/g,(_,a,b)=>(t-=T(b))<0?a:'',t=(T=h=>eval(h.replace(/:/,'*60+')))(h))

console.log(f(`Kevin 13:02
Ruby 5
Sam 3
Lisa 6
Bob 12
`)('13:15'))

\$\endgroup\$
  • \$\begingroup\$ Clever solution! +1. Mine is way far.......:( \$\endgroup\$ – Arjun Apr 15 '17 at 7:07
  • \$\begingroup\$ Doesn't (.*) (.*)\n work? \$\endgroup\$ – Neil Apr 15 '17 at 10:42
  • \$\begingroup\$ @Neil Being greedy by default, the first (.*) would match the entire line. \$\endgroup\$ – Arnauld Apr 15 '17 at 10:44
  • \$\begingroup\$ Then what would the space match? \$\endgroup\$ – Neil Apr 15 '17 at 10:45
  • \$\begingroup\$ @Neil Oh, sorry, you're right. \$\endgroup\$ – Arnauld Apr 15 '17 at 10:47
6
\$\begingroup\$

PHP, 118 98 95 91 bytes

while($n=$argv[++$i])$i&1?$p=$n:($t=($f=strtotime)($n)?:$t+60*$n)<=$f(end($argv))?:print$p;

takes input from command line arguments (you may interprete that as lines separated by spaces if you like); prints names without a delimiter. Run with -r or test it online.

edit 1: saved 20 bytes with direct printing
edit 2: saved 3 bytes by removing the delimiter
edit 3: saved 4 bytes by exploiting that plain integers are no valid dates for strtotime

breakdown

while($n=$argv[++$i])       # loop through arguments, skip [0]
    $i&1                        # if index is odd   
    ?   $p=$n                   # then assign name to $p
    :   ($t=                    # else $t =
        ($f=strtotime)($n)          # if $n is a valid time, parse it
        ?:$t+60*$n                  # else add $n minutes to current $t
        )<=$f(end($argv))           # if $t <= parsed party start
        ?                           # then do nothing
        :print$p;                   # else print name
\$\endgroup\$
6
\$\begingroup\$

c, 178 bytes

main(c,o,d,e,g,O,l,f,x,y)char**o,d[80],*O,*l,*f;{for(sscanf(o[2],"%d:%d",&e,&g),x=e*60+g,l=";",f=o[1];O=strtok(f,l);f=0)(y=sscanf(O,"%s%d:%d",d,&e,&g)^2?e*60+g:y+e)>x?puts(d):0;}

Try it online

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

JavaScript ES6, 185 bytes

l=>t=>l.split`
`.map(p=>p.split` `).map((p,i,a)=>[p[0],i?d(a[0][1])+a.slice(1,i+1).reduce((a,p)=>a+=+p[1],0)*6e4:(d=x=>Date.parse(`2017T${x}`))(p[1])]).filter(p=>p[1]>d(t)).map(p=>p[0])

Try it online!

const f = l=>t=>l.split`
`.map(p=>p.split` `).map((p,i,a)=>[p[0],i?d(a[0][1])+a.slice(1,i+1).reduce((a,p)=>a+=+p[1],0)*6e4:(d=x=>Date.parse(`2017T${x}`))(p[1])]).filter(p=>p[1]>d(t)).map(p=>p[0])


console.log(f('Kevin 13:02\nRuby 5\nSam 3\nLisa 6\nBob 12')('13:15'))

\$\endgroup\$
  • \$\begingroup\$ As far as I can tell from the spec the input form may be more strict. \$\endgroup\$ – Jonathan Allan Apr 14 '17 at 19:22
  • \$\begingroup\$ I think it is correct now. \$\endgroup\$ – powelles Apr 14 '17 at 19:24
  • \$\begingroup\$ Yep - I have also asked about input strictness. \$\endgroup\$ – Jonathan Allan Apr 14 '17 at 19:25
  • \$\begingroup\$ ...actually you have the times in your input, not the offsets it should be f('Kevin 13:02\nRuby 5\nSam 3... \$\endgroup\$ – Jonathan Allan Apr 14 '17 at 19:28
  • 1
    \$\begingroup\$ @JonathanAllan Thanks. Got it now. \$\endgroup\$ – powelles Apr 14 '17 at 20:00
4
\$\begingroup\$

PowerShell, 215 196 180 bytes

param($a,$b)$x,[array]$a=$a-split',';$z=@{};$i,$j=-split$x;$z[$i]=($y=date $j);0..($a.count-1)|%{$i,$j=-split$a[$_];$z[$i]=($y=$y|% *es $j)};($z|% *or|?{$_.value-gt(date $b)}).Name

Try it online!

Roughly 1/3rd of this is input parsing, so I'm not sure how much further I can golf it.

Takes input $a as a comma-delimited string of names and times/minutes, and $b as hh:mm as a string. First, we -split $a on ,, store the first result into $x and the remaining into $a, with an explicit re-cast of $a as an array (so that the loop later works properly). We the initialize our hashtable $z, set $i and $j to be $x -split on whitespace, and set $z[$i] to be the date of $j (stored into $y for use later).

Then we loop through the remaining $a. Each iteration, we do similar -- -split the string on whitespace, set the appropriate $z index to be that many more minutes beyond where we're currently at. This uses a shortened property name trick to save some bytes, using |% *es $j instead of .AddMinutes($j).

Finally, we .GetEnumerator() (again using the trick) of our hashtable, and Where-Object select those entries with a value that's -greaterthan $b (i.e., they're late to the party). We then select just the .Names thereof. Output is as an implicit array, which the default Write-Output inserts newlines between.

Saved a bunch thanks to briantist for reminding me that [array] is a thing. And a bunch more for shortened property name tip.

\$\endgroup\$
  • \$\begingroup\$ I admit I did minimal reading and testing of this, but, couldn't you just do $x,[array]$a=$a-split','? \$\endgroup\$ – briantist Apr 14 '17 at 21:20
  • 1
    \$\begingroup\$ @briantist Yes, thank-you. I kept trying to find a way to use the comma-operator in the multiple-assignment, and it just was not working. I had completely forgotten that [array] is a valid cast. Haha. Too much golfing, I guess. \$\endgroup\$ – AdmBorkBork Apr 15 '17 at 0:47
  • \$\begingroup\$ I'm on mobile so out would be difficult to test but I think GetEnumerator and AddMinutes are good candidates for the % method syntax \$\endgroup\$ – briantist Apr 15 '17 at 1:32
  • \$\begingroup\$ @briantist Yep. Saves another 16. Thanks! \$\endgroup\$ – AdmBorkBork Apr 17 '17 at 12:45
4
\$\begingroup\$

Python 2, 140,148,144 bytes

t,h,n=map(str.split,input().replace(':','').split(';')),100,0
for a,v in t[:-1]:
 n+=int(v)
 if n%h/60:n=n/h*h+n%h%60+h
 if`n`>t[-1][0]:print a,

Try it online!

Input Format:

'Kevin 13:02;Ruby 5;Sam 3;Lisa 6;Bob 12;13:15'
\$\endgroup\$
  • \$\begingroup\$ Doesn't correctly handle minute overflow: 'Kevin 13:47;Ruby 5;Sam 3;Lisa 6;Bob 12;14:00' prints nothing, even though Lisa and Bob are still late. \$\endgroup\$ – L3viathan Apr 19 '17 at 10:56
  • 1
    \$\begingroup\$ oh yeah. There was a glitch! Fixed it. Thanks you! \$\endgroup\$ – Keerthana Prabhakaran Apr 19 '17 at 16:12
3
\$\begingroup\$

Bash, 135 124 115 bytes

a=($1)
for i in `seq 3 2 ${#a[@]}`
do((v+=a[i]))
((`date -d${a[1]} +%s`+v*60>`date -d$2 +%s`))&&echo ${a[i-1]}
done

Try it online!

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

CJam, 66 54 58 54 51 49 46 bytes

{{':/60b}:K~)rSrKs++q+S/2/z~:i[{1$+}*]2$+$@#>}

Input 1 is given through STDIN, input 2 is given as a string on the stack. Output is an array on the stack. Separator for input 1 is a space, e.g. Kevin 13:02 Ruby 5 Sam 3 Lisa 6 Bob 12.

Stack trace:

         e# Stack:               | "13:15"
{        e# Define K and run it:
  ':/    e#   Split on colon:    | ["13" "15"]
  60b    e#   From base 60:      | 795
}:K~     e# End def
)        e# Increment:           | 796
r        e# Read token:          | 796 "Kevin"
S        e# Push space:          | 796 "Kevin" " "
r        e# Read another token:  | 796 "Kevin" " " "13:02"
K        e# K()                  | 796 "Kevin" " " 782
s        e# Convert to string:   | 796 "Kevin" " " "782"
++       e# Add together:        | 796 "Kevin 782"
q        e# Read rest of input:  | 796 "Kevin 782" " Ruby 5 Sam 3 Lisa 6 Bob 12"
+        e# Add together:        | 796 "Kevin 782 Ruby 5 Sam 3 Lisa 6 Bob 12"
S/       e# Split on spaces:     | 796 ["Kevin" "782" "Ruby" "5" "Sam" "3" "Lisa" "6" "Bob" "12"]
2/       e# Group by 2:          | 796 [["Kevin" "782"] ["Ruby" "5"] ["Sam" "3"] ["Lisa" "6"] ["Bob" "12"]]
z        e# Transpose:           | 796 [["Kevin" "Ruby" "Sam" "Lisa" "Bob"] ["782" "5" "3" "6" "12"]]
~        e# Unpack:              | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] ["782" "5" "3" "6" "12"]
:i       e# Convert all to int:  | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] [782 5 3 6 12]
[{1$+}*] e# Accumulate:          | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] [782 787 790 796 808]
2$       e# Copy back element:   | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] [782 787 790 796 808] 796
+        e# Add into array:      | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] [782 787 790 796 808 796]
$        e# Sort:                | 796 ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] [782 787 790 796 796 808]
#        e# Find index:          | ["Kevin" "Ruby" "Sam" "Lisa" "Bob"] 3
>        e# Slice:               | ["Lisa" "Bob"]

Explanation:

  • The procedure K converts between a time hh:mm and a number representing how many minutes that is since midnight.
  • We read the first person and replace their time with K(their time). We then add this to the front of the input.
  • We then preform some string operations to get a list of names and a list of times, like [782 5 3 6 12].
  • By accumulating this list, we get [782 787 790 796 808], which gives the times that everybody came.
  • The shortest way to find who is late is to insert the start time into the array and then re-sort it to place it where it should be. We then find the index to figure out where it places, and then slice the list of names from that index.
\$\endgroup\$
2
\$\begingroup\$

JavaScript, 285 283 bytes

Takes the list of guests i and the party time p in currying syntax (i)(p). Returns a comma-separated list of names such as Lisa,Bob.

i=>p=>{n=i.split`
`,a=new Date(0,0,0,...n[0].split` `[1].split`:`),y=new Date(0,0,0,...p.split`:`),t=[a];w=a;n.slice(1).map((j,k,l)=>{h=l[k].split` `[1]*6e4;t.push(new Date(w.getTime()+h));w=new Date(w.getTime()+h)});return n.filter((j,k,l)=>t[k]>y).map(j=>j.split` `[0]).join()}

I know it's pretty long and currently at last place by a fair margin, but that's what I could come up with.

f=i=>p=>{n=i.split`
`,a=new Date(0,0,0,...n[0].split` `[1].split`:`),y=new Date(0,0,0,...p.split`:`),t=[a];w=a;n.slice(1).map((j,k,l)=>{h=l[k].split` `[1]*6e4;t.push(new Date(w.getTime()+h));w=new Date(w.getTime()+h)});return n.filter((j,k,l)=>t[k]>y).map(j=>j.split` `[0]).join()}

console.log(f(`Kevin 13:02
Ruby 5
Sam 3
Lisa 6
Bob 12
`)('13:15'))

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

C#, 269 267 bytes


Golfed

(l,t)=>{var h=System.DateTime.MinValue;var s=System.DateTime.ParseExact(t,"HH:mm",null);var o="";foreach(var p in l.Split('\n')){var i=p.Split(' ');h=h.Ticks<1?System.DateTime.ParseExact(i[1],"HH:mm",null):h.AddMinutes(int.Parse(i[1]));if(h>s)o+=i[0]+" ";}return o;};

Ungolfed

( l, t ) => {
   var h = System.DateTime.MinValue;
   var s = System.DateTime.ParseExact( t, "HH:mm", null );
   var o = "";

   foreach( var p in l.Split( '\n' ) ) {
      var i = p.Split( ' ' );

      h = h.Ticks < 1
         ? System.DateTime.ParseExact( i[ 1 ], "HH:mm", null )
         : h.AddMinutes( int.Parse( i[ 1 ] ) );

      if( h > s )
         o += i[ 0 ] + " ";
   }

   return o;
};

Ungolfed readable

( l, t ) => {
   // var to check the time of arrival
   var h = System.DateTime.MinValue;

   // var to store the start time of the party
   var s = System.DateTime.ParseExact( t, "HH:mm", null );

   // var with the names of those who arrived late
   var o = "";

   // Cycle through which line
   foreach( var p in l.Split( '\n' ) ) {
      // Split the name and time
      var i = p.Split( ' ' );

      // Check if the time of arrival still has the initial value
      h = h.Ticks < 1

         // If so, grab the time of the first person
         //   Expects to have a time format of 'hh:mm'
         ? System.DateTime.ParseExact( i[ 1 ], "HH:mm", null )

         // Otherwise, add the difference to the var
         : h.AddMinutes( int.Parse( i[ 1 ] ) );

      // Check if the current time is later than the party start time
      if( h > s )

         // If so, add the name to the list
         o += i[ 0 ] + " ";
   }

   // Return the names of the persons who arrived late
   return o;
};

Full code

using System;
using System.Collections.Generic;

namespace Namespace {
   class Program {
      static void Main( String[] args ) {
         Func<String, String, String> f = ( l, t ) => {
            var h = System.DateTime.MinValue;
            var s = System.DateTime.ParseExact( t, "HH:mm", null );
            var o = "";

            foreach( var p in l.Split( '\n' ) ) {
               var i = p.Split( ' ' );

               h = h.Ticks < 1
                  ? System.DateTime.ParseExact( i[ 1 ], "HH:mm", null )
                  : h.AddMinutes( int.Parse( i[ 1 ] ) );

               if( h > s )
                  o += i[ 0 ] + " ";
            }

            return o;
         };

         List<KeyValuePair<String, String>>
            testCases = new List<KeyValuePair<String, String>> {
               new KeyValuePair<String, String>(
                  "Kevin 13:02\nRuby 5\nSam 3\nLisa 6\nBob 12",
                  "13:15"
               ),
               new KeyValuePair<String, String>(
                  "Kevin 13:15\nRuby 5\nSam 3\nLisa 6\nBob 12",
                  "13:15"
               ),
            };

         foreach( KeyValuePair<String, String> testCase in testCases ) {
            Console.WriteLine( $" Input:\n{testCase.Key}\n\n{testCase.Value}\n\nOutput:\n{f( testCase.Key, testCase.Value )}\n" );
         }

         Console.ReadLine();
      }
   }
}

Releases

  • v1.1 - - 2 bytes - Thanks to VisualMelon
  • v1.0 - 269 bytes - Initial solution.

Notes

  • Output format: Outputs the names separated by spaces
\$\endgroup\$
  • \$\begingroup\$ You can save a few bytes by adding a using D=System.DateTime; directive (don't forget to replace the vars!). You should really provide types for the lambda parameters to make this code completely unambiguous (i.e. (string l,string f)). I also think there is a slight bug, you need h>s rather than h>=s (1byte saving!) as per "(Anyone exactly on time is fine.)". Can you do h.Ticks<1 ? You may find a nullable DateTime cheaper than using DateTime.Min, but I've not checked the full implications here. With the using clause, ==D.Min should work also. \$\endgroup\$ – VisualMelon Apr 17 '17 at 18:05
  • \$\begingroup\$ About the using I doubt I could still pull off a lambda expression with it. I'm pretty sure I can't add it in mid-code. Explicit lambda types are another thing that I haven't seen people doing it, and I went with that -- if it is illegal, say so, but even the mods haven't said anything, maybe it's ok?. h>s I'll do that one. h.Ticks<1 and this one too. \$\endgroup\$ – auhmaan Apr 17 '17 at 20:35
  • \$\begingroup\$ I'm confident we allow usings and such with lambdas, I can't find anything saying this explicitly on meta, but this question strongly suggests it is permitted. There is a reasonable consensus that explicit parameter types should be required (I should add that I'm firmly in favour). By the by, Mods are there to keep things civil from SE's perspective, not to enforce PPCG's own rules. \$\endgroup\$ – VisualMelon Apr 17 '17 at 22:21
  • \$\begingroup\$ I'm kinda against the usings, mostly because I would then feel that it would require a full code, hence me saying that I doubt I could pull off a function as a solution -- maybe adding two blocks, one for usings and another for the lambda function? About the consensus, I think adding the missing Func<...> f = ...; would solve it, although it should be specified the full name System.Func<...> f = ...; \$\endgroup\$ – auhmaan Apr 18 '17 at 9:39
  • \$\begingroup\$ You might be better off just having a well named function (only adds string s with C#7 (6? I can't remember) syntax) if you'd rather not mix lambdas and usings. \$\endgroup\$ – VisualMelon Apr 18 '17 at 9:44
2
\$\begingroup\$

CJam, 43 41 bytes

q~':/60b:Y;Sf/()':/60b+a\+{)iT+:TY>{;}|}%

Try it online!

Explanation

q~        e# Read and eval all input.

':/       e# Split the start time on colons.
60b       e# Convert the result from base 60, to get the start time in minutes.
:Y;       e# Store this time in variable Y, and discard it from the stack.

Sf/       e# Split each string in the guest list on spaces.
(         e# Pull out the first guest from the list.
)         e# Pull out the time from the guest.
':/60b+   e# Convert the time to a number of minutes (same way as before), then add it back
          e#   to the guest.
a\+       e# Add the guest back to the start of the guest list.

          e# At this point, the first guest has his/her arrival time in minutes, and everyone
          e#  else still has their original number.

{         e# Apply this block to each guest:
 )i       e#  Pull out the number and cast it to an integer.
 T+       e#  Add the value of variable T to it (T is initially 0).
 :T       e#  Store the result back into T.
 Y>{;}|   e#  If the resulting number of minutes is not after the start time, delete the 
          e#    guest's name.
}%        e# (end of block)

          e# Implicit output.
\$\endgroup\$
2
\$\begingroup\$

Lua, 211 206 Bytes

First codegolf of the year for me, should still be golfable.

Edit: Saved 5 Bytes by using a shorthand for string.match

function f(l,T)m=T.match
r=function(X)return
m(X,"^%d+")*3600+60*m(X,"%d+$")end
T=r(T)z={}y=0
for i=1,#l do
h=m(l[i],"%d.*")h=i>1 and y+h*60or r(h)y=h
z[#z+1]=h>T and m(l[i],"%u%l*")or nil
end return z end

Explanations

function f(l,T)                         -- declare the function f(list,partyTime)
  r=function(X)                         -- declare a function r that convert hh:mm in seconds
    return X:match("^%d+")*3600         -- return the sum of seconds the hours
          +60*X:match("%d+$")           -- and in the seconds
  end                                   
  T=r(T)                                -- convert the partyTime in seconds
  z={}                                  -- create the shameList for late partygoers
  y=0                                   -- y will keep us updated on the second count
  for i=1,#l                            -- iterate over l
  do                                    
    h=l[i]:match("%d.*")                -- h is a shorthand for the time of arrival
    h=i>1                               -- if we're on the second line at least
        and y+h*60                      -- update h with the time of arrival in second
      or r(h)                           -- else use r()(for the first partygoer only)
    y=h                                 -- update our reference for adding time
    z[#z+1]=h>T                         -- if the last partygoer was late
                and l[i]:match("%u%l*") -- add its name to the shameList
              or nil                    -- else, don't do anything
  end                                   
  return z                              -- return the shameList
end                                 

if you want to try this code, you can use the following snippet

function f(l,T)r=function(X)return
X:match("^%d+")*3600+60*X:match("%d+$")end
T=r(T)z={}y=0
for i=1,#l do
h=l[i]:match("%d.*")h=i>1 and y+h*60or r(h)y=h
z[#z+1]=h>T and l[i]:match("%u%l*")or nil
end return z end

retour = f({"Kevin 13:02","Ruby 5","Sam 3","Lisa 6","Bob 12"},"13:15")
for i=1,#retour
do
  print(retour[i])
end
\$\endgroup\$
2
\$\begingroup\$

Java, 346 304 284 275 bytes

  • -9 bytes, thanks to @KevinCruijssen
void g(int m,String[]n,String[]a,int M){for(int i=0;i<n.length;i++)if((M+=i>0?p(a[i]):0)>m)System.out.print(n[i]);}
int p(String n){return new Short(n);}
int h(String t){return p(t.split(":")[0])*60+p(t.split(":")[1]);}
void f(String[]n,String[]a,String b){g(h(b),n,a,h(a[0]));}

Detailed Live

public static void g(int m, String[] n, String[] a, int M)
{
    for(int i = 0; i < n.length; i++)
    {
        if((M += i>0 ? p(a[i]) : 0) > m)
        {
            System.out.println(n[i]);
        }
    } 
}

public static int p(String n)
{
    return Integer.parseInt(n);
}

public static int h(String t)
{
    return p(t.split(":")[0])*60+p(t.split(":")[1]);
}

public static void f(String[] n, String[] a, String b)
{
    g(h(b),n,a,h(a[0]));
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice golfing (for Java.) Do you need the space between String[] n, and String[] a? \$\endgroup\$ – programmer5000 Apr 17 '17 at 11:12
  • \$\begingroup\$ @programmer5000 no, I also removed the hours variable & accumulated them as minutes. \$\endgroup\$ – Khaled.K Apr 17 '17 at 11:42
  • 1
    \$\begingroup\$ You can replace Integer.parseInt(n) with new Short(n). And based on the comments of the challenge, LisaBob is also a valid output, so you can change the println to print. \$\endgroup\$ – Kevin Cruijssen May 12 '17 at 7:00
1
\$\begingroup\$

Batch, 163 bytes

@set/pp=
@set/ap=%p::=*60+%
:l
@set g=
@set/pg=
@if "%g%"=="" exit/b
@set t=%g:* =%
@set/ap-=%t::=*60+%
@for %%g in (%g%)do @(if %p% lss 0 echo %%g)&goto l

Takes input on STDIN. First line is the start time of the party, then the list of guests. Uses @Arnauld's trick to convert the hh:mm into minutes.

Batch's preferred input for this would be as a series of command-line parameters (starting with the time of the party, then each guest and time as separate arguments). This would only take 129 bytes:

@set p=%1
@set/ap=%p::=*60+%
:l
@set t=%3
@set/ap-=%t::=*60+%
@if %p% lss 0 echo %2
@shift
@shift
@if not "%2"=="" goto l
\$\endgroup\$
1
\$\begingroup\$

Groovy, 121 bytes

{g,t->y={Date.parse('hh:mm',it)};u=y(t);d=y(g.remove(0)[1]);g.find{z=it[1];use(groovy.time.TimeCategory){d+z.minutes}>u}}
\$\endgroup\$
1
\$\begingroup\$

PowerShell, 170 160 bytes

select-string '(?m)^((\w*) )?((\d\d):)?(\d?\d)$'-a|% matches|%{,$_.groups[2,4,5].value}|%{}{$b+=($c=60*$_[1]+$_[2]);$a+=,@{n=$_[0];t=$b}}{$a|? n|? t -gt $c|% n}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Better late than never! \$\endgroup\$ – programmer5000 Apr 17 '17 at 17:08
  • \$\begingroup\$ I'm in rest today therefore have a some time for a some fun \$\endgroup\$ – Andrei Odegov Apr 17 '17 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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