8
\$\begingroup\$

The challenge is to detect missing integer sequences of files or directories. You have a directory filled with files/directories that are named as integers.

The files/directories are generated from multiple threads yet the job did not complete - there are therefore gaps in the sequence.

The input is two integers a start and an end, and your task is detect the starting integer of the next missing sequences. You may presume that all files and directories in the directory where run have only integer named files or directories.

Acceptable answer forms: functions, code snippets - they must run on the command line.
Acceptable start/end input: included on the command line, env variables/argv are okay, parameters to functions, user input is okay.
Shortest code wins.

Update -- Although I managed to squeeze out this one, there were many interesting answers. The idea in apricotboy's Bash answer was used in part to help me design my 35 Byte Bash answer. Best of luck on the next one.

E.g. Presume files 1,2,3,4,7,8,9,10,18 are present, start is 1, end is 20: 

The output should be: 
5
11
19
\$\endgroup\$
  • 5
    \$\begingroup\$ It seems a rather pointless extra requirement to me. \$\endgroup\$ – Leaky Nun Jul 26 '16 at 2:18
  • 4
    \$\begingroup\$ This is absolutely a chameleon challenge - the requirement to take input as file names and/or directories makes this challenge more about working with the filesystem than actually filling in the holes. \$\endgroup\$ – Mego Jul 26 '16 at 2:53
  • 14
    \$\begingroup\$ You all complain too much whenever there's a challenge requiring any functionalities other than shuffling integers or strings around. \$\endgroup\$ – feersum Jul 26 '16 at 2:56
  • 3
    \$\begingroup\$ @feersum We complain when challenges arbitrarily require extra functionality (like filesystem I/O) that don't add anything to the actual challenge. \$\endgroup\$ – Mego Jul 26 '16 at 2:57
  • 4
    \$\begingroup\$ @feersum How is finding missing integers in sequence related to finding files in directory? \$\endgroup\$ – Leaky Nun Jul 26 '16 at 4:52
5
\$\begingroup\$

Python 2, 101 bytes

2 bytes thanks to @xnor.

import os
t=-1
for n in range(input(),input()+1):
 if~-os.path.isfile(str(n)):
  if~t+n:print n
  t=n
\$\endgroup\$
  • \$\begingroup\$ I detected 2 trailing spaces after your import os that you should take out. \$\endgroup\$ – Value Ink Jul 26 '16 at 5:36
  • \$\begingroup\$ @KevinLau-notKenny Thanks. \$\endgroup\$ – Leaky Nun Jul 26 '16 at 5:37
  • \$\begingroup\$ I think if~-n!=t: can be if~t+n:. \$\endgroup\$ – xnor Jul 26 '16 at 5:42
4
\$\begingroup\$

Dyalog APL, 25 24 or 36 bytes

Prompts for lower bound, then upper bound.

It seems from comments to other answers that the OP wanted as short sequences as possible.

{⍵/⍨~⍵∊⍨⍵-1}((⍳⎕)~⍳⎕-1)~⍎¨⎕SH'dir/b'

{
    ⍵/⍨ those where it is
    ~ not true
    ⍵∊⍨ that the set contains
    ⍵-1 their predecessor
} of
(
    (⍳⎕) of the integers until n
    ~ except
    ⍳⎕-1 integers until n-1
)~ except
⍎¨ the evaluation of each of
⎕SH'dir/b' the bare list of names in the current directory


Old answer which returns length-1 sequences:

(⍕¨(⍳⎕)~⍳⎕-1)~⎕SH'dir/b'

(
     string representation
    ¨ of each
    (⍳⎕) of the integers until n
    ~ except
    ⍳⎕-1 integers until n-1
)~ except
⎕SH'dir/b' the bare list of files in current directory

Only works on Windows. A cross platform solution:

(⍕¨(⍳⎕)~⍳⎕-1)~0⎕NINFO⍠1⊢'*'

0 just the filename(s)
⎕NINFO of the Native file(s) INFOrmation
⍠1 using wildcards
⊢'*' on all files

\$\endgroup\$
  • \$\begingroup\$ I'm getting (⍕¨(⍳⎕)~⍳⎕-1)~0⎕NINFO⍠1⊢'*' Unknown APL character: ⍠ (U+2360) Non-APL character \$\endgroup\$ – user53101 Jul 26 '16 at 6:16
  • \$\begingroup\$ @A.Danischewski Which APL are you using? \$\endgroup\$ – Adám Jul 26 '16 at 6:17
  • 3
    \$\begingroup\$ @A.Danischewski Dyalog APL \$\endgroup\$ – Adám Jul 26 '16 at 6:21
  • 2
    \$\begingroup\$ @A.Danischewski Specifically version 15.0+, which is free, and downloadable with the link I provided. \$\endgroup\$ – Adám Jul 26 '16 at 6:22
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ – Adám Jul 26 '16 at 14:18
4
\$\begingroup\$

Ruby, 74 60 45 bytes

Input is in command line, run it like ruby f.rb 0 20. Only works in current directory.

-1 byte from unpacking the ARGV into variables, and -13 bytes from replacing the select and grep with a set subtraction.

V3: -5 bytes from using a substitution for Dir.glob in an old Ruby answer to another filesystems challenge, as suggested by @PatrickOscity. -10 from remembering some quirks in Ruby's String#next function.

a,b=$*
f=[*a..b]-Dir[?*]
puts f-f.map(&:next)
\$\endgroup\$
4
\$\begingroup\$

Perl 6, 47 bytes

{my \c;.say if .IO.e??(c=0)!!!c++ for $^a..$^b}

Explanation:

{my \c;.say if .IO.e??(c=0)!!!c++ for $^a..$^b}
{                                               } # A function. Arguments: $^a and $^b (implicitly)
 my \c;                                           # A variable without prefix (\ is needed only here)
                                  for $^a..$^b    # For each number between $^a and $^b 
       .say if                                    # Print the number if the result is truthy:
               .IO.e??(c=0)!!!c++                 # If the file exists, reset the sequence (don't print this one), otherwise, return the `!(c++)` result (is it the first time we're incrementing)

Tried to use flipflops. Didn't manage to :P.

\$\endgroup\$
  • \$\begingroup\$ this is a function. just put parentheses with the arguments after the closing }. \$\endgroup\$ – Ven Jul 26 '16 at 21:15
  • \$\begingroup\$ yep :-). hoping to see more people using Perl 6 everywhere, even in golfing! \$\endgroup\$ – Ven Jul 26 '16 at 21:59
1
\$\begingroup\$

PHP, 64 bytes

<?=implode("\n",array_diff(range($argv[1],$argv[2]),glob("*")));

Run like this:

php -f golf.php 1 20

Note:

  • Only does the current directory.

  • No trailing newline on the output.

  • This requires the <?= to be allowed in php.ini. Which I think is default but I'm not sure.

Bash, 31 bytes

a(){(seq $@;ls)|sort|uniq -u;}

Run as a 1 20. Again, only does the current dir.

Can I submit two? Hope so. This is my first post to Code Golf so I'm not too sure of the etiquette. Hope I'm counting my bytes correctly, too.

\$\endgroup\$
  • 3
    \$\begingroup\$ You can submit multiple solutions, but unless they are trivial derivatives of each other, each solution should be in a separate answer. \$\endgroup\$ – Mego Jul 26 '16 at 7:06
  • \$\begingroup\$ You're only supposed to print the first element of each missing range, but the PHP code looks like it would print all of the missing numbers, is this correct? \$\endgroup\$ – feersum Jul 26 '16 at 7:07
  • \$\begingroup\$ Ah, my bad. I misunderstood it and just aimed to get the output in the question, without reading into it enough. Should I take my submission down? \$\endgroup\$ – apricot boy Jul 27 '16 at 4:36
1
\$\begingroup\$

I see now this is an old question, but still, I like it...

PowerShell, 70 bytes

for($m,$n=$args;$m-le$n;$m++){$w=$a;$a=Test-Path $m;if(!$a-and$w){$m}}

Run as a script from the command line, eg .\misso.ps1 1 20.

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

PowerShell v4+, 62 bytes

param($x,$y)$x..$y|?{$_-notin($a=(ls ".\").Name)-and$_-1-in$a}

Save as a script in the desired directory and call it locally (see example below). Takes input $x and $y and constructs a range .., then pipes that to a Where-Object (the |?{...}) which is basically a filter. Here we're only selecting items where the current element $_ is -notin the .Name collection of the current directory, but the previous element is -in that collection (i.e., only the start of a missing range).

The ls is an alias for Get-ChildItem and is basically what you'd expect. Requires v4 for the encapsulation-select of .Name, otherwise you'd need $a=ls ".\"|select Name.

Example

PS C:\Tools\Scripts\golfing\misd> ls .\

    Directory: C:\Tools\Scripts\golfing\misd

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         7/26/2016   7:48 AM          8 1
-a---         7/26/2016   7:48 AM         10 10
-a---         7/26/2016   7:54 AM          0 18
-a---         7/26/2016   7:48 AM          8 2
-a---         7/26/2016   7:48 AM          8 3
-a---         7/26/2016   7:48 AM          8 4
-a---         7/26/2016   7:48 AM         10 7
-a---         7/26/2016   7:48 AM          8 8
-a---         7/26/2016   7:48 AM          8 9
-a---         7/26/2016   8:18 AM        365 misd.ps1

PS C:\Tools\Scripts\golfing\misd> .\misd.ps1 1 20
5
11
19
\$\endgroup\$
0
\$\begingroup\$

Groovy, 53 bytes

{f,s,e->(s..e)-f.listFiles().collect{it.name as int}}

I had an explanation and screenshots, but I didn't post that version and left the page... Either that or I posted the answer to a random S.O. thread about the "best way to stat a directory in Groovy".

\$\endgroup\$

Your Answer

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