Знайдіть найменший файл


19

Мета:

Створіть програму, щоб знайти найменший файл у поточній папці.

  • Розмір файлу може вимірюватися в байтах або символах.
  • Якщо декілька файлів мають однаковий розмір, ви можете вибрати один або відобразити їх усі.
  • Можна припустити, що в папці буде принаймні один файл, а жоден файл не матиме розмір 0.
  • Припустимо, що всі файли в папці можуть бути завантажені мовою, яку ви використовуєте.

  • Припустимо, що в поточному каталозі немає папок.

Вхід:

Програма не повинна брати будь-які дані від користувача, якщо:

  • Якщо у вашій мові немає "поточної папки", вона може запитати у користувача назву / шлях папки.
  • Якщо ваша мова не може безпосередньо отримати доступ до файлів на вашому комп'ютері, вона може дозволити користувачу завантажувати файли. (JavaScript, наприклад)

Вихід:

Потрібно відобразити найменший файл.

  • Провідні / кінцеві символи дозволені, якщо зрозуміло, який файл був обраний.
  • (Друк списку всіх файлів суперечить правилам).

Примітки:

  • Стандартні лазівки заборонені.
  • Ви не можете змінювати / створювати / видаляти файли в папці, щоб змінити результат.
  • Це ; найкоротша відповідь (у байтах) виграє.

1
Чи можна вважати, що файли можуть мати розмір 0?
Rɪᴋᴇʀ

Крім того, що означає "припускати, що всі файли в папці можуть бути доступні"? це означає, що приховані файли не потрібно показувати?
Rɪᴋᴇʀ

2
Чи можу я припустити, що в поточній папці немає папок? Все має значення, якщо у вас є мовна функція, яка повертає і файли, і папки, а не лише файли!
серхіол

1
Не обов'язково. Ви можете припустити, що в поточному каталозі немає каталогів, що є однозначним і не скасовує жодних відповідей.
Денніс

1
(вибачте, що я не відповів раніше, моє підключення до Інтернету було відключено протягом декількох днів) Проблема, що я маю дозволити пропускати приховані файли, полягає в тому, що, здається, відкривається багато лазівки. Дозволити вам пропустити файли, які "трохи важче отримати доступ" означатиме, що люди можуть зробити щось на зразок лише перевірки перших 9 файлів, оскільки це економить кілька байтів.
12Me21

Відповіді:


7

Vim 12 байт

!!ls -Sa
Gd{

Спробуйте в Інтернеті!

Пояснення:

!!- це команда фільтра . Він передає вміст поточного рядка довільній команді системи і відправляє вихід назад в буфер. Це корисно для використання зовнішніх інструментів для речей, в яких bash краще, ніж vim, наприклад, !!revдля зворотного перегляду поточного рядка або !Gxxdдля hexdump буфера. У нашому випадку буфер порожній, тому він еквівалентний :r!ls, який просто подає висновок команди в поточний рядок.

Тепер курсор знаходиться у рядку 1, і ми хочемо видалити кожен рядок, окрім останнього. Наївний підхід є

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

Але ми можемо зробити краще. Як я пояснив у цій підказці , {баночка зазвичай (але не завжди) може бути рівнозначною gg. Тут ще краще. Оскільки рух на основі символів , а не на основі ліній, як ggце є, нам не потрібно спочатку йти по лінії, залишаючи нас

Gd{

16

Bash + coreutils, 13 байт

ls -Sar|sed q

Пояснення:

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.         

Опублікував це як свою власну відповідь, але я думаю, що це занадто схоже на вашу. ls -1Sa|tail -1на 3 байти коротше і має більш чистий вихід.
orlp

@orlp спасибі! ..
Rɪᴋᴇʀ

1
Я не думаю, що вам потрібен '-1', труба автоматично ставить один файл на рядок.
ГБ

@EasterlyIrk Я думаю, що ГБ правильно. якщо lsвиявляє вихід до терміналу, він форматуватиме висновок у кілька стовпців. Але якщо вихід - це труба, вона буде робити лише 1 на рядок. Порівняйте lsvsls|cat
Digital Trauma

На два байти коротше:ls -Sar|sed q
Цифрова травма

8

Python 2 3, 94 76 74 54 байт

-18 байт завдяки @orlp
-2 байт завдяки @Jonathan Allan
-20 байт завдяки зміні технічних характеристик

from os import*
print(min(listdir(),key=path.getsize))

print min(filter(path.isfile,listdir(".")),key=path.getsize)чистіший і значно коротший.
orlp

Збережіть два байти, переходячи до Python 3, оскільки "."це за замовчуванням. print(min(filter(path.isfile,listdir()),key=path.getsize))
Джонатан Аллан

Також я рахую 76 не 77.
Джонатан Аллан

@JonathanAllan Я виміряв кількість байтів, за допомогою wcякої я на 1 байт більше
ов

Сторонній байт був би обумовлений новим рядком, який не потрібен Python. Крім того, оскільки виклик було оновлено, щоб стверджувати, що немає підкаталогів, весь filterбіт не є необхідним. Це також не працює в Python 3, оскільки printє функцією. Наступне працювало б і було значно коротшим:print(min(listdir(),key=path.getsize))
Мего,

8

PowerShell , 30 24 21 байт

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

Спробуйте в Інтернеті!

lsпсевдонім для Get-ChildItem. Це пов'язано sort-objectз lengthатрибутом, тому файли сортуються за розміром. Ми вказуємо на це за допомогою, (...)[0]щоб отримати перший (тобто найменший), а потім беремо .Nameйого. Вихід через неявне Write-Outputвідбувається після завершення програми.

Збережено 6 байт, оскільки ми гарантуємо, що в каталозі існують лише файли. Збережено додаткові 3 завдяки ConnorLSW.


2
Ви не можете позбутися, -fileоскільки в поточному каталозі лише файли?
Mutantoe

@Mutantoe Так - це було відредаговано після виклику, коли я опублікував цю відповідь. Спасибі!
AdmBorkBork

ви можете використовувати sort le*для гоління декількох байтів, оскільки паттерншалл це прийме.
colsw

@ConnorLSW Так, звичайно. Спасибі!
AdmBorkBork

7

Рубі, 61 40 38 37 байт

Дякуємо ГБ та чорнило вартості

p Dir[?*,".*"].min_by{|x|File.size x}

Ви можете використовувати ?. замість Dir.pwd та min_by {}, щоб отримати найменший файл. Dir.foreach(?.).min_by{|x|File.size x}отримує такий же результат у 38 байт.
ГБ

@GB Спасибі!
dkudriavtsev

Прикро, що "всі" файли, до яких можна отримати доступ, повинні бути розглянуті, оскільки Dir[?*]вони набагато коротші, але не містять прихованих файлів Unix, таких як .bash_profile...
Value Ink

Може, Дір [? *, ".? *"] Міг би спрацювати. Я не пробував. І це коротше.
ГБ

@GB Це було б насправді Dir[?*,".*"]. Рядок Glob .?*не збігається з файлом, .aякщо він існує.
Значення чорнила

6

Математика, 35 байт

FileNames[]~MinimalBy~FileByteCount

FileNames[]створює список імен усіх файлів (та каталогів) у поточному каталозі; ~MinimalBy~FileByteCountвибирає ім'я файлу, кількість байтів якого найменша. FileByteCountкидає купу помилок, коли вона застосовується до каталогів, але помилки не збивають програму.


6

Java 7, 149 142 байти

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

Спробуйте в Інтернеті!

-7 байт завдяки CAD97


Я думаю, ви хочете, щоб Файл :: length не Файл :: getTotalSpace
CAD97

Неперевірена Java 8: ()->java.utils.stream(new java.io.File(".").listFiles()).max((a,b)->a.length()-b.length).get().getName()на 104 байти
CAD97

@ CAD97 Ти маєш рацію! Про що я думав ...
Пік

6

SH (Linux / Unix) 15 14 13 14 байт

ls -aS|tail -1

-S сортування за розміром (за спаданням),

-rповертає та tail -1виводить останній файл у списку.

@ Dennis Дякуємо за збереження 1 байта @Dani_l Дякуємо за збереження 1 байта.


Це знаходить найбільший файл, ні?
Денніс

Неважливо, я втомився. Ви можете використовувати tailхоч замість реверсу, і -1це скорочення -n1.
Денніс

@Dennis Оновлено
Abel Tom

@EasterlyIrk Зараз має :)
Абель Том

@AbelTom класно, дякую за виправлення.
Rɪᴋᴇʀ

4

MATLAB / Октава, 52 48 байт

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

Пояснення

Це отримує список директорій усіх файлів і папок у поточному каталозі за допомогою dir. Вихідdir є structщо містить ім'я файлу, будь то каталог чи ні, розмір (в байтах) і т.д.

Тоді ми можемо взяти масив розмірів кожного в байтах [d.bytes]і виконати роздільний елемент з булевим значенням, вказуючи, чи це каталог чи ні~[d.isdir] який дасть, Infде це каталог (поділ на нуль) і розмір у байтах інакше (поділ на 1).

Ми знаходимо індекс мінімуму цього масиву за допомогою другого виводу minта використовуємо його для індексації у початковій структурі та відображення імені зd(n).name


Ви повинні додати disp(...)навколо виводу, щоб правильно роздрукувати його. Інакше, якби, наприклад, був файл, який називається, ansякий не є найменшим у папці, з виводу не було б зрозуміло, який файл найменший для всіх, хто не знає MATLAB.
Том Карпентер

@TomCarpenter Hmmm, я інтерпретував "Провідні / кінцеві символи дозволені, якщо зрозуміло, який файл обрано", що означає, що ans = це нормально
Suever

Я щойно зрозумів, що MATLAB додає неявні .(поточна папка) та ..(папка вище), тому не можу зняти перевірку каталогу, здається. Вибач за це.
Том Карпентер

4

Scala, 52 байти

Стара версія, 79 байт

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

Коригується відповідно до порад jaxad0127. Зараз це лише 52 байти.

new java.io.File(".").listFiles.sortBy(_.length)head

Використання головки замість застосування (0) коротше. Також метод файлу toString у файлі прекрасний, не потрібно викликати ім'я для отримання.
jaxad0127

4

Пакетна, 43 39 35 байт

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


Oh, using /p like that, dang clever!
AdmBorkBork

@AdmBorkBork Ah, I hadn't noticed that was allowed, thanks!
Neil

You're guaranteed that no sub-directories exist (the challenge was updated) so you can eliminate the /a-d.
AdmBorkBork

4

Perl 6,  33 32 31  16 bytes

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

Try it

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

Try it

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

Try it

put dir.min: *.s

Try it

Expanded:

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

The function form of dir defaults to $*CWD, and the task description says you can assume there won't be any folders, so I think you can shorten that to dir.min(*.s).put.
smls

When I wrote this, it said the program must ignore folders.
Brad Gilbert b2gills

4

J, 21 20 bytes

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

Saved a byte thanks to @Conor.

Explanation

>{.,(/: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

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


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

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.


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.


Bit late, but file.size is shorter because you don't have to do $s afterwards.
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]

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.


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

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())]);
    }
}

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


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

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.


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.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.