Trouver le plus petit fichier

19

Objectif:

Créez un programme pour trouver le plus petit fichier dans le dossier actuel.

  • La taille du fichier peut être mesurée en octets ou en caractères.
  • Si plusieurs fichiers ont la même taille, vous pouvez en choisir un ou les afficher tous.
  • Vous pouvez supposer qu'il y aura au moins un fichier dans le dossier et qu'aucun fichier n'aura une taille de 0.
  • Supposons que tous les fichiers du dossier peuvent être chargés dans la langue que vous utilisez.

  • Supposons qu'il n'y ait aucun dossier dans le répertoire actuel.

Contribution:

Le programme ne doit recevoir aucune entrée de l'utilisateur, sauf si:

  • Si votre langue n'a pas de "dossier actuel", il peut demander à l'utilisateur un nom / chemin d'accès au dossier.
  • Si votre langue ne peut pas accéder directement aux fichiers sur votre ordinateur, cela peut permettre à l'utilisateur de télécharger des fichiers. (JavaScript, par exemple)

Production:

Le nom du plus petit fichier doit être affiché.

  • Les symboles de début / fin sont autorisés, tant qu'il est clair quel fichier a été choisi.
  • (L'impression d'une liste de tous les fichiers est contraire aux règles).

Remarques:

  • Les échappatoires standard ne sont pas autorisées.
  • Vous ne pouvez pas modifier / créer / supprimer des fichiers dans le dossier pour changer le résultat.
  • C'est ; la réponse la plus courte (en octets) l'emporte.
12Me21
la source
1
Pouvons-nous supposer que les fichiers peuvent avoir une taille de 0?
Rɪᴋᴇʀ
En outre, que signifie "supposer que tous les fichiers du dossier sont accessibles"? cela signifie-t-il que les fichiers cachés n'ont pas besoin d'être affichés?
Rɪᴋᴇʀ
2
Puis-je supposer qu'il n'y a aucun dossier dans le dossier actuel? Cela fait toute la différence si vous avez une fonction de langue qui renvoie à la fois des fichiers et des dossiers au lieu de seulement des fichiers!
sergiol
1
Pas nécessairement. Vous pouvez supposer qu'il n'y a pas de répertoires à l'intérieur du répertoire actuel sans ambiguïté et n'invalide aucune réponse.
Dennis
1
(désolé, je n'ai pas répondu plus tôt, ma connexion Internet a été coupée pendant quelques jours) Le problème que j'ai avec vous permettre d'ignorer les fichiers cachés est qu'il semble ouvrir beaucoup de failles. Vous permettre d'ignorer les fichiers qui sont "légèrement plus difficiles d'accès" signifierait que les gens pourraient faire quelque chose comme ne vérifier que les 9 premiers fichiers car cela économise quelques octets.
12Me21

Réponses:

7

Vim 12 octets

!!ls -Sa
Gd{

Essayez-le en ligne!

Explication:

!!est la commande de filtrage . Il redirige le contenu de la ligne actuelle vers une commande système arbitraire et renvoie la sortie dans le tampon. Il est utile pour utiliser des outils externes pour des choses où bash est meilleur que vim, par exemple !!revpour inverser la ligne actuelle ou !Gxxdpour vider le tampon hexadécimal. Dans notre cas, le tampon est vide, il est donc équivalent à :r!ls, ce qui alimente simplement la sortie de la commande dans la ligne actuelle.

Maintenant, le curseur est sur la ligne 1, et nous voulons supprimer toutes les lignes sauf la dernière. L'approche naïve est

G       " Go to the last line
 k      " Go up one line
  d     " Delete:
   gg   "   Everything up to the first line

Mais nous pouvons faire mieux. Comme je l'ai expliqué dans cette astuce , le {peut généralement (mais pas toujours) être équivalent à gg. Ici, c'est encore mieux. Parce que le mouvement est basé sur des caractères , et non sur des lignes comme ggc'est le cas, nous n'avons pas besoin de remonter une ligne en premier, nous laissant avec

Gd{
DJMcMayhem
la source
16

Bash + coreutils, 13 octets

ls -Sar|sed q

Explication:

ls -Sar|sed q
ls            # list files
   -S         # sorted, biggest first
     a        # show hidden files
      r       # reversed (smallest first)
       |sed q # q is quit at first line that matches given regex, 
              # given regex is empty so guaranteed match.         
Rɪᴋᴇʀ
la source
Posté comme ma propre réponse, mais je pense qu'elle est trop similaire à la vôtre. ls -1Sa|tail -1est de 3 octets plus court et a une sortie plus propre.
orlp
@orlp thanks! ..
Rɪᴋᴇʀ
1
Je ne pense pas que vous ayez besoin du '-1', pipe met automatiquement un fichier par ligne.
GB
@EasterlyIrk Je pense que GB a raison. si la lssortie est détectée sur le terminal, elle formatera la sortie en plusieurs colonnes. Mais si la sortie est un tube, elle n'en fera qu'un par ligne. Comparer lsvsls|cat
Digital Trauma
Deux octets plus court:ls -Sar|sed q
Digital Trauma
8

Python 2 3, 94 76 74 54 octets

-18 octets grâce à @orlp
-2 octets grâce à @Jonathan Allan
-20 octets grâce à une modification des spécifications du défi

from os import*
print(min(listdir(),key=path.getsize))
ovs
la source
print min(filter(path.isfile,listdir(".")),key=path.getsize)est plus propre et sensiblement plus court.
orlp
Enregistrez deux octets en passant à Python 3 car "."c'est la valeur par défaut. print(min(filter(path.isfile,listdir()),key=path.getsize))
Jonathan Allan
Je compte aussi 76 pas 77.
Jonathan Allan
@JonathanAllan J'ai mesuré le nombre de comptages d'octets avec wclequel m'a donné 1 octet de plus
ovs
L'octet étranger serait dû à une nouvelle ligne de fin, qui n'est pas requise pour Python. De plus, étant donné que le défi a été mis à jour pour indiquer qu'il n'y a aucun sous-répertoire présent, le filterbit entier est inutile. Cela ne fonctionne pas non plus en Python 3, car printc'est une fonction. Les éléments suivants fonctionneraient et seraient considérablement plus courts:print(min(listdir(),key=path.getsize))
Mego
8

PowerShell , 30 24 21 octets

(ls|sort le*)[0].Name

Essayez-le en ligne!

lsest un alias pour Get-ChildItem. C'est lié à sort-objectl' lengthattribut, donc les fichiers sont triés par taille. Nous indexons cela avec le (...)[0]pour obtenir le premier (c'est-à-dire le plus petit), puis prenons .Namecelui - ci. La sortie via implicite Write-Outputse produit à la fin du programme.

6 octets enregistrés car nous sommes garantis que seuls les fichiers existent dans le répertoire. Enregistré 3 supplémentaires grâce à ConnorLSW.

AdmBorkBork
la source
2
Ne pouvez-vous pas vous débarrasser de -filepuisque seuls les fichiers se trouvent dans le répertoire actuel?
Mutantoe
@Mutantoe Oui - qui a été modifié dans le défi après avoir posté cette réponse. Merci!
AdmBorkBork
vous pouvez utiliser sort le*pour raser certains octets car powershell l'acceptera.
colsw
@ConnorLSW Oui, bien sûr. Merci!
AdmBorkBork
7

Rubis, 61 40 38 37 octets

Merci GB et Value Ink

p Dir[?*,".*"].min_by{|x|File.size x}
dkudriavtsev
la source
Vous pouvez utiliser ?. au lieu de Dir.pwd et min_by {} pour obtenir le plus petit fichier. Dir.foreach(?.).min_by{|x|File.size x}obtient le même résultat en 38 octets.
GB
@GB Merci!
dkudriavtsev
Il est dommage que "tous" les fichiers auxquels la langue puisse accéder doivent être examinés, car ils Dir[?*]sont beaucoup plus courts mais n'incluent pas les fichiers Unix cachés comme .bash_profile...
Value Ink
Peut-être que Dir [? *, ".? *"] Pourrait fonctionner. Je n'ai pas essayé. Et c'est plus court.
GB
@GB Ce serait en fait Dir[?*,".*"]. La chaîne Glob .?*ne correspondra pas au fichier .as'il existe.
Value Ink
6

Mathematica, 35 octets

FileNames[]~MinimalBy~FileByteCount

FileNames[]produit une liste de noms de tous les fichiers (et répertoires) du répertoire courant; ~MinimalBy~FileByteCountsélectionne le nom du fichier dont le nombre d'octets est le plus petit. FileByteCountjette un tas d'erreurs lorsqu'il est appliqué aux répertoires, mais les erreurs ne font pas dérailler le programme.

Greg Martin
la source
6

Java 7, 149 142 octets

String f(){String n="";long s=-1>>>1,p;for(java.io.File f:new java.io.File(".").listFiles())if((p=f.length())<s){n=f.getName();s=p;}return n;}

Essayez-le en ligne!

-7 octets grâce à CAD97

Poussée
la source
Je pense que vous voulez File :: length not File :: getTotalSpace
CAD97
Java 8 non testé: ()->java.utils.stream(new java.io.File(".").listFiles()).max((a,b)->a.length()-b.length).get().getName()pour 104 octets
CAD97
@ CAD97 Vous avez raison! A quoi je pensais ...
Poke
6

SH (Linux / Unix) 15 14 13 14 octets

ls -aS|tail -1

-S trie par taille (décroissant),

-rinverse ettail -1 sort le dernier fichier de la liste.

@ Dennis Merci d'avoir économisé 1 octet @Dani_l Merci d'avoir enregistré 1 octet.

Abel Tom
la source
Qui trouve le plus gros fichier, non?
Dennis
Peu importe, je suis fatigué. Vous pouvez utiliser tailcependant au lieu d'inverser, et -1c'est un raccourci pour -n1.
Dennis
@Dennis Mis à jour
Abel Tom
@EasterlyIrk Maintenant, ça devrait :)
Abel Tom
@AbelTom cool, merci pour la fixation.
Rɪᴋᴇʀ
4

MATLAB / Octave, 52 48 octets

d=dir;[~,n]=min([d.bytes]./~[d.isdir]);d(n).name

Explication

Cela obtient une liste de répertoires de tous les fichiers et dossiers du répertoire en cours à l'aide de dir. La sortie de direst un structcontenant le nom du fichier, que ce soit un répertoire ou non, la taille (en octets), etc.

Nous pouvons ensuite prendre un tableau des tailles de chacun en octets [d.bytes]et effectuer une division élément par élément avec un booléen indiquant s'il s'agit d'un répertoire ou non ~[d.isdir]qui donneraInf où il est un répertoire (division par zéro) et la taille en octets sinon (division par 1).

Nous trouvons l'index du minimum de ce tableau en utilisant la deuxième sortie de minet l'utilisons pour indexer dans la structure initiale et afficher le nom avecd(n).name

Suever
la source
Vous devez ajouter disp(...)autour de la sortie pour l'imprimer correctement. Sinon, s'il y avait par exemple un fichier appelé ansqui n'est pas le plus petit du dossier, la sortie ne serait pas claire quant au fichier le plus petit pour quiconque ne connaît pas MATLAB.
Tom Carpenter
@TomCarpenter Hmmm J'ai interprété "Les symboles de début / fin sont autorisés, tant qu'il est clair quel fichier a été choisi" pour signifier que tout ans = va bien
Suever
Je viens de réaliser que MATLAB ajoute l'implicite .(dossier actuel) et ..(dossier ci-dessus), donc je ne peux pas supprimer la vérification du répertoire, il semble. Désolé pour ça.
Tom Carpenter
4

Scala, 52 octets

Ancienne version, 79 octets

new java.io.File(".").listFiles.map(a=>a.getName->a.length)sortBy(_._2)apply(0)

Ajusté selon les conseils de jaxad0127. Il ne fait plus que 52 octets maintenant.

new java.io.File(".").listFiles.sortBy(_.length)head
Aria Axe
la source
L'utilisation de head au lieu de apply (0) est plus courte. De plus, la méthode toString de File est très bien, pas besoin d'appeler get name.
jaxad0127
4

Lot, 43 39 35 octets

@dir/b/os|(set/pf=&call echo %%f%%)

Output includes a leading space for some reason, but fortunately that's allowed. Edit: Now assuming there are no directories to save 4 bytes.

Neil
la source
Oh, en utilisant / p comme ça, dang intelligent!
AdmBorkBork
@AdmBorkBork Ah, je n'avais pas remarqué que c'était autorisé, merci!
Neil
Vous êtes assuré qu'aucun sous-répertoire n'existe (le défi a été mis à jour) afin que vous puissiez éliminer le /a-d.
AdmBorkBork du
4

Perl 6 ,  33 32 31  16 octets

'.'.IO.dir.grep(*.f).min(*.s).put

Essayez-le

put '.'.IO.dir.min:{try .s//Inf}

Essayez-le

put $*CWD.dir.min:{try .s//Inf}

Essayez-le

put dir.min: *.s

Essayez-le

Étendu:

put        # print with trailing newline
dir        # the list of files in the current directory
.min:      # find the minimum by
  *.s      # calling the `s` method (size) in a Whatever lambda
Brad Gilbert b2gills
la source
La forme de fonction par dirdéfaut est $*CWD, et la description de la tâche indique que vous pouvez supposer qu'il n'y aura pas de dossiers, donc je pense que vous pouvez raccourcir cela en dir.min(*.s).put.
smls
Quand j'ai écrit cela, il a dit que le programme doit ignorer les dossiers.
Brad Gilbert b2gills
4

J , 21 20 bytes

>{.,(/:2&{"1)1!:0'*'

Un octet enregistré grâce à @Conor.

Explication

>{.,(/:2&{"1)1!:0'*'
                 '*' Glob all files in current directory
             1!:0    Table of file metadata in that directory
       2&{"1         Get the file size of each
     /:              Sort the files by that
   ,                 Flatten
 {.                  Get the first value
>                    Unbox
miles
la source
@ConorO'Brien Thanks
miles
3

BATCH File, 77 72 63 bytes

@FOR /F "tokens=*" %%G IN ('dir/o-s/b') DO @SET F=%%G
@ECHO %F%

There's no direct equivalent of head or tail in BATCH, at least to my knowledge, so here's a kludgy work-around. (with much assistance from @Neil - thanks!)

The dir command, with /o-s to sort in descending file size, and /b to output only the file names. We loop through those with FOR /F, setting the variable F to the file name each time. Finally, we output just the last one with ECHO %F%.

Saved 9 more bytes thanks to Neil and thanks to guarantees that no directories are present.

AdmBorkBork
la source
1
Your FOR variable needs two %s to work in a script. Otherwise, a few golfing tricks: 1. Don't use @ECHO OFF on short scripts, add a @ to each line and after DO. 2. Delete the space before DO. 3. The spaces and :s aren't needed in the dir command.
Neil
1
@Neil Ack, thanks. Sorry, pretty rusty since I've been doing PowerShell... Thanks!
AdmBorkBork
3

PHP, 84 62 bytes

$t=array_map(filesize,$g=glob('*'));asort($t);echo$g[key($t)];

Since the question was updated with the assumption that there will be no folders in the current directory, I was able to remove the file check stuff and golf this down.


Here is my old answer:

$t=array_map(filesize,$g=array_filter(glob('*'),is_file));asort($t);echo$g[key($t)];

This is the best I could do. Maybe there is a better way I'm missing.

$t=array_map(              # visit each array element and...
    filesize,              # map each filename to its filesize...
    $g=array_filter(       # using an array of...
        glob('*'),         # all files and directories...
        is_file            # filtered by files...
    )                      # 
);                         # 
asort($t);                 # sort the array of filesizes, then...
echo$g[key($t)];           # print element from the array of files using the first key of the sorted array as an index
Kodos Johnson
la source
2

Node.js (using walk), 114 bytes

Ignore newline:

require('walk').walk(__dirname).on('file',(r,s,n)=>
(m=s.size>m.size?m:s,n()),m=0).on('end',_=>console.log(m.name))

This invokes a walker that traverses through the current directory (__dirname) and for each file calls a function with its stat s and a function next n() that must be invoked to continue the traversal. Then at the end, it prints a filename with the minimum size in bytes found. s.size>m.size returns false when m.size is undefined, so after the first callback, m is equal to the first file found, and continues from there normally.

Patrick Roberts
la source
2

R, 36 bytes

x=file.info(y<-dir())$s;y[x==min(x)]

Explained

file.info() returns a data.frame of "file information" when given a character or character vector of file/folder names which when used on the list of files/folders in the current directory (dir()), looks something like:

                                                               size isdir mode               mtime               ctime               atime exe
Polyspace_Workspace                                               0  TRUE  777 2014-11-28 17:29:25 2014-11-28 17:29:25 2014-11-28 17:29:25  no
Python Scripts                                                    0  TRUE  777 2016-03-21 23:59:41 2016-03-21 23:59:41 2016-03-21 23:59:41  no
R                                                                 0  TRUE  777 2015-12-23 20:11:02 2015-12-23 20:11:02 2015-12-23 20:11:02  no
Rockstar Games                                                    0  TRUE  777 2015-04-14 12:23:05 2015-04-14 12:23:03 2015-04-14 12:23:05  no
TrackmaniaTurbo                                                   0  TRUE  777 2016-03-24 17:15:05 2016-03-24 13:13:48 2016-03-24 17:15:05  no
ts3_clientui-win64-1394624943-2014-06-11 03_18_47.004772.dmp 314197 FALSE  666 2014-06-11 02:18:47 2014-06-11 02:18:47 2014-06-11 02:18:47  no

Subsequently we just have the find the name of the file for which the size column (abbreviated using $s) is the smallest. Consequently, if there are more than one file with the smallest size, all will be returned.

Bonus: if we also wanted to disregard folders in the current directory we could simply search for size when isdir == FALSE: x=file.info(y<-dir());y[x$s==min(x$s[!x$i])] which turns out to be 44 bytes.

Billywob
la source
Bit late, but file.size is shorter because you don't have to do $s afterwards.
JAD
2

Tcl, 88 bytes

set s Inf
lmap f [glob -ty f *] {if [set m [file si $f]]<$s {set n $f
set s $m}}
puts $n

Try it online!

sergiol
la source
2

SmileBASIC, 110 bytes

DIM F$[0]FILES"TXT:",F$FOR I=0TO LEN(F$)-1F$[I][0]="TXT:
S=LEN(LOAD(F$[I],0))IF!Z||S<Z THEN Z=S:B=I
NEXT?F$[B]

Only looks at TXT: files, since DAT: files cannot be loaded unless you already know their size, making it impossible to load a random one.

12Me21
la source
How do you load a DAT: file? Could you brute-force every name/file size in the folder?
Pavel
Trying to load a 3-dimensional DAT: file into a 2-dimensional array (for example) will cause an error, so you can't brute force it. You just have to know the number of dimensions beforehand, which you normally would.
12Me21
Could you load a 2-d DAT: file into a 3-d array? Then you could create a maximum size array. And you can't catch errors in any way?
Pavel
Nope, that will cause a Type mismatch error. And there's no way to catch errors either.
12Me21
1

Groovy, 49 bytes

m={f->f.listFiles().sort{it.length()}[0].getName()}

Try it online!

Closure, usage: m(new File("location"))

Magic Octopus Urn
la source
1

C#, 277 bytes

Not the shortest, but what would you expect from C#?

Golfed

using System.Linq;using static System.IO.Directory;class P{static void Main(){var x=GetFiles(GetCurrentDirectory());var d=new long[]{}.ToList();foreach(var s in x){var b=new System.IO.FileInfo(s).Length;if(!d.Contains(b))d.Add(b);}System.Console.Write(x[d.IndexOf(d.Min())]);}}

Ungolfed

//Linq using for List.Min()
using System.Linq;
//Static using to save bytes on GetCurrentDirectory() and GetFiles()
using static System.IO.Directory;

class P
{
    static void Main()
    {
        //String array containing file paths
        var x = GetFiles(GetCurrentDirectory());
        //Creating a Long array and converting it to a list, less bytes than "new System.Collections.Generic.List<long>()"
        var d = new long[] { }.ToList();
        foreach (var s in x) //Loop through all file paths
        {
            //Getting file size in bytes
            var b = new System.IO.FileInfo(s).Length;
            if (!d.Contains(b))
                //If there isn't already a file with this size in our List, add the file path to list
                d.Add(b);

        }
        //Get index of the smallest Long in our List, which is also the index of the file path to the smallest file, then write that path
        System.Console.Write(x[d.IndexOf(d.Min())]);
    }
}
Metoniem
la source
1

Röda, 32 31 bytes

{ls""|sort key=fileLength|pull}

It's an anonymous function that sorts the files in the current directory by file length and selects then the first file with pull.

Use it like this: main{ {ls""|sort key=fileLength|pull} }

fergusq
la source
Apparently ls"" works just as well as ls".". I think you can save a byte from that
Kritixi Lithos
@KritixiLithos It seems to. Thanks!
fergusq
0

SmileBASIC 3, 105 bytes (competing?)

Beats 12Me21's answer but still suffers from inability to load DAT files (which feels very cruel to be disqualifying considering the circumstances.)

DIM F$[0],T[0]FILES"TXT:",F$FOR I=0TO LEN(F$)-1F$[I][0]="TXT:
PUSH T,LEN(LOAD(F$[I]))NEXT
SORT T,F$?F$[0]

The shorter version above is annoying and prompts you on every file to load, but it does work. For two bytes more you can suppress the prompt; change line 2 to this:

PUSH T,LEN(LOAD(F$[I],0))NEXT
snail_
la source
0

Batch File, 33 bytes

Batch files are moderately competitive this time, oddly enough.

@dir/os/b>..\q&set/pa=<..\q&"%a%.

Output

enter image description here


Find a way to stop the creation of q prior to dir/os/b being run and you'll save a maximum of 6 bytes by not needing to put the output file in a separate directory.

@dir/os/b>q&set/pa=<q&"%a%

Will always output q as the smallest file (unless tied for another 0 byte file) as it is created as an empty file before dir/b/os gathers a list of files.

BDM
la source
0

C++17 (gcc), 180 bytes

#include<filesystem>
using namespace std::filesystem;auto f(){std::error_code e;path r;size_t m=-1,s;for(auto&p:directory_iterator(".")){s=file_size(p,e);if(s<m)m=s,r=p;}return r;}

Try it online!

Requires a recent standard library that implements std::filesystem.

G. Sliepen
la source