Missing Integer Sequence Detection -- Filesystem

8

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

user53101

Posted 2016-07-26T02:12:44.213

Reputation:

2Can I input an array instead of reading my own files? – Leaky Nun – 2016-07-26T02:16:30.870

5

It seems a rather pointless extra requirement to me.

– Leaky Nun – 2016-07-26T02:18:48.450

2

@A.Danischewski I find the real-world background here is too much of a narrow reference to justify the file requirement.

– xnor – 2016-07-26T02:34:57.967

2Can I just delete all files and print 1? – orlp – 2016-07-26T02:36:03.477

4This 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. – Mego – 2016-07-26T02:53:24.863

14You all complain too much whenever there's a challenge requiring any functionalities other than shuffling integers or strings around. – feersum – 2016-07-26T02:56:06.743

Related, possibly a dupe target since it's mostly the same challenge, but without the unnecessary requirement of doing filesystem I/O. – Mego – 2016-07-26T02:56:49.410

3@feersum We complain when challenges arbitrarily require extra functionality (like filesystem I/O) that don't add anything to the actual challenge. – Mego – 2016-07-26T02:57:47.767

@Mego How do you determine whether a thing is a thing or not a thing? – feersum – 2016-07-26T02:59:43.183

4@feersum How is finding missing integers in sequence related to finding files in directory? – Leaky Nun – 2016-07-26T04:52:53.877

May we output a list of missing names? – Adám – 2016-07-26T05:39:37.820

Can any of the arguments be negative? – Leaky Nun – 2016-07-26T05:47:40.493

Ok so do we have to write IO code or not? I solved the non-IO part of the problem... – applejacks01 – 2016-07-26T14:44:46.400

Answers

5

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

Leaky Nun

Posted 2016-07-26T02:12:44.213

Reputation: 45 011

I detected 2 trailing spaces after your import os that you should take out. – Value Ink – 2016-07-26T05:36:59.747

@KevinLau-notKenny Thanks. – Leaky Nun – 2016-07-26T05:37:31.697

I think if~-n!=t: can be if~t+n:. – xnor – 2016-07-26T05:42:39.853

4

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)

Value Ink

Posted 2016-07-26T02:12:44.213

Reputation: 10 608

4

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

Adám

Posted 2016-07-26T02:12:44.213

Reputation: 37 779

I'm getting (⍕¨(⍳⎕)~⍳⎕-1)~0⎕NINFO⍠1⊢'*' Unknown APL character: ⍠ (U+2360) Non-APL character – None – 2016-07-26T06:16:16.270

@A.Danischewski Which APL are you using? – Adám – 2016-07-26T06:17:21.357

3@A.Danischewski *Dyalog APL* – Adám – 2016-07-26T06:21:14.090

2@A.Danischewski Specifically version 15.0+, which is free, and downloadable with the link I provided. – Adám – 2016-07-26T06:22:51.060

Let us continue this discussion in chat.

– Adám – 2016-07-26T14:18:16.573

@A.Danischewski Please continue in chat. – Adám – 2016-07-26T16:48:15.407

4

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.

Ven

Posted 2016-07-26T02:12:44.213

Reputation: 3 382

this is a function. just put parentheses with the arguments after the closing }. – Ven – 2016-07-26T21:15:14.577

yep :-). hoping to see more people using Perl 6 everywhere, even in golfing! – Ven – 2016-07-26T21:59:48.223

1

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.

mcmurdo

Posted 2016-07-26T02:12:44.213

Reputation: 71

1

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.

apricot boy

Posted 2016-07-26T02:12:44.213

Reputation: 281

3You can submit multiple solutions, but unless they are trivial derivatives of each other, each solution should be in a separate answer. – Mego – 2016-07-26T07:06:44.613

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? – feersum – 2016-07-26T07:07:14.503

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? – apricot boy – 2016-07-27T04:36:05.137

0

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

Magic Octopus Urn

Posted 2016-07-26T02:12:44.213

Reputation: 19 422

0

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

AdmBorkBork

Posted 2016-07-26T02:12:44.213

Reputation: 41 581