Encuentra el archivo más pequeño

19

Objetivo:

Cree un programa para encontrar el archivo más pequeño en la carpeta actual.

  • El tamaño del archivo puede medirse en bytes o caracteres.
  • Si varios archivos tienen el mismo tamaño, puede elegir uno o mostrarlos todos.
  • Puede suponer que habrá al menos un archivo en la carpeta y que ningún archivo tendrá un tamaño de 0.
  • Suponga que todos los archivos de la carpeta se pueden cargar por el idioma que está utilizando.

  • Suponga que no hay carpetas en el directorio actual.

Entrada:

El programa no debe recibir ninguna entrada del usuario, a menos que:

  • Si su idioma no tiene una "carpeta actual", puede pedirle al usuario un nombre / ruta de carpeta.
  • Si su idioma no puede acceder directamente a los archivos en su computadora, puede permitir que el usuario cargue archivos. (JavaScript, por ejemplo)

Salida:

Se debe mostrar el nombre del archivo más pequeño.

  • Los símbolos iniciales / finales están permitidos, siempre que esté claro qué archivo se ha elegido.
  • (Imprimir una lista de todos los archivos está en contra de las reglas).

Notas:

  • Las lagunas estándar no están permitidas.
  • No puede modificar / crear / eliminar archivos en la carpeta para cambiar el resultado.
  • Este es el ; la respuesta más corta (en bytes) gana.
12Me21
fuente
1
¿Podemos suponer que los archivos pueden tener un tamaño de 0?
Rɪᴋᴇʀ
Además, ¿qué significa "asumir que se puede acceder a todos los archivos de la carpeta"? ¿eso significa que no es necesario mostrar los archivos ocultos?
Rɪᴋᴇʀ
2
¿Puedo suponer que no hay carpetas en la carpeta actual? ¡Hace una gran diferencia si tiene una función de idioma que devuelve archivos y carpetas en lugar de solo archivos!
sergiol
1
No necesariamente. Puede suponer que no hay directorios dentro del directorio actual es inequívoco y no invalida ninguna respuesta.
Dennis
1
(lo siento, no he respondido antes, mi conexión a Internet estuvo inactiva durante unos días) El problema que tengo al permitirle omitir archivos ocultos es que parece abrir muchas lagunas. Permitirle omitir archivos que son "un poco más difíciles de acceder" significaría que las personas podrían hacer algo como solo verificar los primeros 9 archivos porque ahorra unos pocos bytes.
12Me21

Respuestas:

7

Vim 12 bytes

!!ls -Sa
Gd{

Pruébalo en línea!

Explicación:

!!es el comando de filtro Canaliza el contenido de la línea actual a un comando del sistema arbitrario y envía la salida de vuelta al búfer. Es útil para usar herramientas externas para cosas en las que bash es mejor que vim, por ejemplo, !!revpara revertir la línea actual o !Gxxdpara hexadecitar el búfer. En nuestro caso, el búfer está vacío, por lo que es equivalente a :r!ls, que solo alimenta la salida del comando en la línea actual.

Ahora el cursor está en la línea 1, y queremos eliminar todas las líneas menos la última. El enfoque ingenuo es

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

Pero lo podemos hacer mejor. Como expliqué en este consejo , generalmente{ puede (pero no siempre) ser equivalente a . Aquí, es aún mejor. Debido a que el movimiento se basa en caracteres , no en líneas como es, no tenemos que subir una línea primero, dejándonos congggg

Gd{
DJMcMayhem
fuente
16

Bash + coreutils, 13 bytes

ls -Sar|sed q

Explicación:

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ɪᴋᴇʀ
fuente
Publiqué esto como mi propia respuesta, pero creo que es demasiado similar a la tuya. ls -1Sa|tail -1es 3 bytes más corto y tiene una salida más limpia.
orlp
@orlp gracias! ..
Rɪᴋᴇʀ
1
No creo que necesite el '-1', la tubería coloca automáticamente un archivo por línea.
GB
@EasterlyIrk Creo que GB tiene razón. si lsdetecta que la salida es al terminal, formateará la salida en varias columnas. Pero si la salida es una tubería, solo hará 1 por línea. Comparar lsvsls|cat
Trauma digital
Dos bytes más cortos:ls -Sar|sed q
Digital Trauma
8

Python 2 3, 94 76 74 54 bytes

-18 bytes gracias a @orlp
-2 bytes gracias a @Jonathan Allan
-20 bytes gracias a un cambio en las especificaciones de desafío

from os import*
print(min(listdir(),key=path.getsize))
ovs
fuente
print min(filter(path.isfile,listdir(".")),key=path.getsize)Es más limpio y sustancialmente más corto.
orlp
Guarde dos bytes moviéndose a Python 3 ya que "."es el valor predeterminado. print(min(filter(path.isfile,listdir()),key=path.getsize))
Jonathan Allan
También cuento 76, no 77.
Jonathan Allan
@JonathanAllan Medí el recuento de bytes con el wcque me dio 1 byte más
ovs
El byte extraño se debería a una nueva línea final, que no es necesaria para Python. Además, dado que el desafío se actualizó para indicar que no hay subdirectorios presentes, todo el filterbit es innecesario. Esto tampoco funciona en Python 3, ya que printes una función. Lo siguiente funcionaría, y sería sustancialmente más corto:print(min(listdir(),key=path.getsize))
Mego
8

PowerShell , 30 24 21 bytes

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

Pruébalo en línea!

lses un alias para Get-ChildItem. Eso se canaliza sort-objectcon el lengthatributo, por lo que los archivos se ordenan por tamaño. Lo indexamos con el (...)[0]para obtener el primero (es decir, el más pequeño), y luego tomamos el .Namemismo. La salida a través de lo implícito Write-Outputocurre al finalizar el programa.

Guardamos 6 bytes ya que estamos garantizados de que solo existen archivos en el directorio. Ahorró 3 adicionales gracias a ConnorLSW.

AdmBorkBork
fuente
2
¿No puede deshacerse de él -fileya que solo los archivos están en el directorio actual?
Mutantoe
@Mutantoe Sí, eso fue editado en el desafío después de que publiqué esta respuesta. ¡Gracias!
AdmBorkBork
puedes usar sort le*para afeitar algunos bytes ya que powershell lo aceptará.
colsw
@ConnorLSW Sí, por supuesto. ¡Gracias!
AdmBorkBork
7

Ruby, 61 40 38 37 bytes

Gracias GB y Value Ink

p Dir[?*,".*"].min_by{|x|File.size x}
dkudriavtsev
fuente
Puedes usar ?. en lugar de Dir.pwd y min_by {} para obtener el archivo más pequeño. Dir.foreach(?.).min_by{|x|File.size x}obtiene el mismo resultado en 38 bytes.
GB
@GB Gracias!
dkudriavtsev
Es una lástima que "todos" los archivos a los que puede acceder el idioma se deben mirar, porque Dir[?*]es mucho más corto pero no incluye archivos Unix ocultos como .bash_profile...
Value Ink
Tal vez Dir [? *, ".? *"] Podría funcionar. No lo he intentado Y es más corto.
GB
@GB En realidad lo sería Dir[?*,".*"]. La cadena global .?*no coincidirá con el archivo .asi existe.
Value Ink
6

Mathematica, 35 bytes

FileNames[]~MinimalBy~FileByteCount

FileNames[]produce una lista de nombres de todos los archivos (y directorios) en el directorio actual; ~MinimalBy~FileByteCountselecciona el nombre del archivo cuyo número de bytes es el más pequeño. FileByteCountarroja un montón de errores cuando se aplica a los directorios, pero los errores no descarrilan el programa.

Greg Martin
fuente
6

Java 7, 149 142 bytes

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;}

Pruébalo en línea!

-7 bytes gracias a CAD97

Dar un toque
fuente
Creo que quieres Archivo :: longitud no File :: getTotalSpace
97 CAD
Java 8 sin probar: ()->java.utils.stream(new java.io.File(".").listFiles()).max((a,b)->a.length()-b.length).get().getName()para 104 bytes
CAD97
@ CAD97 Tienes razón! En qué estaba pensando ...
Empujar
6

SH (Linux / Unix) 15 14 13 14 bytes

ls -aS|tail -1

-S ordena por tamaño (descendente),

-rinvierte y tail -1genera el último archivo de la lista.

@ Dennis Gracias por guardar 1 byte @Dani_l Gracias por guardar 1 byte.

Abel Tom
fuente
Que encuentra el archivo más grande , ¿no?
Dennis
No importa, estoy cansado. Sin tailembargo, podría usar en lugar de invertir, y -1es una abreviatura de -n1.
Dennis
@Dennis Actualizado
Abel Tom
@EasterlyIrk Ahora debería :)
Abel Tom
@AbelTom genial, gracias por arreglarlo.
Rɪᴋᴇʀ
4

MATLAB / Octave, 52 48 bytes

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

Explicación

Esto obtiene una lista de directorio de todos los archivos y carpetas en el directorio actual usando dir. La salida de contiene dirun structnombre de archivo, ya sea un directorio o no, el tamaño (en bytes), etc.

Luego podemos tomar una matriz de los tamaños de cada uno en bytes [d.bytes]y realizar una división por elementos con un valor booleano que indica si es un directorio o no, lo ~[d.isdir]que dará lugar Infdonde es un directorio (división por cero) y el tamaño en bytes de lo contrario (división por 1)

Encontramos el índice del mínimo de esta matriz usando la segunda salida miny la usamos para indexar en la estructura inicial y mostrar el nombre cond(n).name

Suever
fuente
Debe agregar disp(...)alrededor de la salida para imprimirla correctamente. De lo contrario, si por ejemplo hubiera un archivo llamado ansque no sea el más pequeño en la carpeta, la salida no sería clara en cuanto a qué archivo es el más pequeño para cualquier persona que no esté familiarizada con MATLAB.
Tom Carpenter
@TomCarpenter Hmmm Interpreté "Los símbolos iniciales / finales están permitidos, siempre que esté claro qué archivo ha sido elegido" para indicar que ans = está bien
Suever
Me acabo de dar cuenta de que MATLAB agrega lo implícito .(carpeta actual) y ..(carpeta anterior), por lo que no puedo eliminar la comprobación del directorio que parece. Lo siento por eso.
Tom Carpenter
4

Scala, 52 bytes

Versión anterior, 79 bytes

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

Ajustado de acuerdo con los consejos de jaxad0127. Ahora solo tiene 52 bytes.

new java.io.File(".").listFiles.sortBy(_.length)head
Aria Axe
fuente
Usar cabeza en lugar de aplicar (0) es más corto. Además, el método toString de File está bien, no es necesario llamar a get name.
jaxad0127
4

Lote, 43 39 35 bytes

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

La salida incluye un espacio líder por alguna razón, pero afortunadamente está permitido. Editar: ahora suponiendo que no haya directorios para guardar 4 bytes.

Neil
fuente
¡Oh, usando / p así, maldita sea inteligente!
AdmBorkBork
@AdmBorkBork Ah, no me había dado cuenta de que estaba permitido, ¡gracias!
Neil
Le garantizamos que no existen subdirectorios (el desafío se actualizó), por lo que puede eliminar el /a-d.
AdmBorkBork
4

Perl 6 ,  33 32 31  16 bytes

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

Intentalo

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

Intentalo

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

Intentalo

put dir.min: *.s

Intentalo

Expandido:

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
fuente
La forma de la función está dirpredeterminada $*CWD, y la descripción de la tarea dice que puede asumir que no habrá carpetas, por lo que creo que puede acortar eso dir.min(*.s).put.
sonríe el
Cuando escribí esto, decía que el programa debe ignorar las carpetas.
Brad Gilbert b2gills
4

J , 21 20 bytes

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

Salvó un byte gracias a @ Conor .

Explicación

>{.,(/: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
millas
fuente
@ ConorO'Brien Gracias
millas
3

Archivo BATCH, 77 72 63 bytes

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

No hay un equivalente directo de head o tailen BATCH, al menos que yo sepa, así que aquí hay una solución alternativa. (con mucha ayuda de @Neil, ¡gracias!)

El dircomando, con /o-sordenar en tamaño de archivo descendente, y /bgenerar solo los nombres de archivo. Recorremos aquellos con FOR /F, configurando la variable Fcon el nombre del archivo cada vez. Finalmente, sacamos solo el último conECHO %F% .

Ahorré 9 bytes más gracias a Neil y gracias a las garantías de que no hay directorios presentes.

AdmBorkBork
fuente
1
Su FORvariable necesita dos %s para funcionar en un script. De lo contrario, algunos trucos de golf: 1. No lo use @ECHO OFFen guiones cortos, agregue un @a cada línea y después DO. 2. Eliminar el espacio anterior DO. 3. Los espacios :ys no son necesarios en el dircomando.
Neil
1
@Neil Ack, gracias. Lo siento, bastante oxidado ya que he estado haciendo PowerShell ... ¡Gracias!
AdmBorkBork
3

PHP 84 62 bytes

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

Como la pregunta se actualizó con la suposición de que no habrá carpetas en el directorio actual, pude eliminar las cosas de verificación de archivos y reducir esto.


Aquí está mi vieja respuesta:

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

Esto es lo mejor que pude hacer. Tal vez hay una mejor manera en que me estoy perdiendo.

$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
fuente
2

Node.js (usando walk), 114 bytes

Ignorar nueva línea:

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))

Esto invoca un andador que atraviesa el directorio actual ( __dirname) y para cada archivo llama a una función con su estadística sy una función siguiente n()que debe invocarse para continuar el recorrido. Luego en el end, imprime un nombre de archivo con el mínimo sizeen bytes encontrados. s.size>m.sizeregresa falsecuando m.sizees undefined, entonces después de la primera devolución de llamada, mes igual al primer archivo encontrado, y continúa desde allí normalmente.

Patrick Roberts
fuente
2

R, 36 bytes

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

Explicado

file.info()devuelve una data.frame"información de archivo" cuando se le da un carácter o vector de caracteres de nombres de archivo / carpeta que, cuando se usa en la lista de archivos / carpetas en el directorio actual ( dir()), se parece a:

                                                               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

Posteriormente solo tenemos que encontrar el nombre del archivo para el que la sizecolumna (abreviada usando $s) es la más pequeña. En consecuencia, si hay más de un archivo con el tamaño más pequeño, se devolverán todos.

Bonificación: si también quisiéramos ignorar las carpetas en el directorio actual, simplemente podríamos buscar el tamaño cuando isdir == FALSE: x=file.info(y<-dir());y[x$s==min(x$s[!x$i])]que resulta ser 44 bytes.

Billywob
fuente
Un poco tarde, pero file.sizees más corto porque no tienes que hacerlo $sdespués.
JAD
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]

Solo mira los TXT:archivos, ya que los DAT:archivos no se pueden cargar a menos que ya conozca su tamaño, lo que hace imposible cargar uno aleatorio.

12Me21
fuente
¿Cómo se carga un DAT: archivo? ¿Podría forzar la fuerza bruta de cada nombre / tamaño de archivo en la carpeta?
Pavel
Intentar cargar un DAT:archivo tridimensional en una matriz bidimensional (por ejemplo) causará un error, por lo que no puede forzarlo. Solo tiene que saber el número de dimensiones de antemano, lo que normalmente haría.
12Me21
¿Podría cargar un DAT: archivo 2-d en una matriz 3-d? Entonces podría crear una matriz de tamaño máximo. ¿Y no puedes detectar errores de ninguna manera?
Pavel
No, eso causará un error de desajuste de tipo. Y tampoco hay forma de detectar errores.
12Me21
1

Groovy , 49 bytes

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

Pruébalo en línea!

Cierre, uso: m(new File("location"))

Urna de pulpo mágico
fuente
1

C #, 277 bytes

No es el más corto, pero ¿qué esperarías de 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())]);}}

Sin golf

//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
fuente
1

Röda , 32 31 bytes

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

Es una función anónima que clasifica los archivos en el directorio actual por longitud de archivo y luego selecciona el primer archivo con pull.

Úselo así: main{ {ls""|sort key=fileLength|pull} }

fergusq
fuente
Aparentemente ls""funciona tan bien como ls".". Creo que puedes salvar un byte de eso
Kritixi Lithos
@KritixiLithos Parece que sí. ¡Gracias!
fergusq
0

SmileBASIC 3, 105 bytes (¿compitiendo?)

Supera la respuesta de 12Me21 pero aún sufre la incapacidad de cargar archivos DAT (lo que se siente muy cruel por ser descalificador teniendo en cuenta las circunstancias).

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]

La versión más corta anterior es molesta y le solicita que cargue cada archivo, pero funciona. Para dos bytes más, puede suprimir la solicitud; cambie la línea 2 a esto:

PUSH T,LEN(LOAD(F$[I],0))NEXT
caracol_
fuente
0

Archivo por lotes, 33 bytes

Los archivos por lotes son moderadamente competitivos esta vez, por extraño que parezca.

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

Salida

ingrese la descripción de la imagen aquí


Encuentre una manera de detener la creación qantes de dir/os/bejecutarse y ahorrará un máximo de 6 bytes al no tener que colocar el archivo de salida en un directorio separado.

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

Siempre saldrá qcomo el archivo más pequeño (a menos que esté vinculado por otro archivo de 0 bytes) ya que se crea como un archivo vacío antes de dir/b/osreunir una lista de archivos.

BDM
fuente
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;}

Pruébalo en línea!

Requiere una biblioteca estándar reciente que implemente std::filesystem.

G. Sliepen
fuente