Код Гольф: Дерево каталогов -> Дерево

11

Соревнование (!): На языке по вашему выбору напишите программу, которая будет проходить по дереву каталогов данного каталога и выводить дерево (то есть массив массивов), соответствующее ему. Предположим, каталог является предопределенной переменной D. Наименьшее количество символов выигрывает.

Правила:

  • Вы должны использовать рекурсию
  • Смотрите правила

Примечание. Предположим, что нет пределов глубины рекурсии. Другими словами, ваш код просто должен работать для достаточно маленьких деревьев каталогов, и в принципе для больших.

Например:

Дерево каталогов

dir1
├── dir11
│   ├── file111
│   └── file112
├── dir12
│   ├── file121
│   ├── file122
│   └── file123
├── file11
├── file12
└── file13

Выходное дерево

[[[],[]],[[],[],[]],[],[],[]]

Первый код гольф здесь, так что позвольте мне знать, если я делаю что-то не так.

Повеселись :)

Андрей Одесский
источник
7
«Правила: 1. Вы должны использовать рекурсию 2. См. Правила« Ах! ПОМОГИТЕ Я ВСТРЕТИЛСЯ В БЕСКОНЕЧНОМ ПЕТЛЕ!
Джастин
1
Вы можете идти по количеству символов или по наименьшему размеру в байтах (таким образом, программы с символами Юникода больше, чем если бы они использовали чистый ASCII)
Джастин
1
Насколько глубоко это пройдет?
Это не так.
Многие люди будут благодарны, если вы вместо этого дадите ввод файла (как путь или что-то еще), и они могут просто вывести его. Кроме того, ваш вывод кажется немного сложным для понимания. Можете ли вы предоставить контрольный пример? Вместо того, чтобы использовать массив массивов, мы могли бы просто напечатать каждый каталог / файл в отдельной строке, но с отступом, чтобы показать подпапку? В основном, мы должны выводить в определенном формате (в этом случае, привести пример), или мы можем выбрать формат (если он однозначен)?
Джастин
3
Я ослеп, разбираю ваш выходной формат. Это от кого-то, кто любит Лисп.
Даррен Стоун

Ответы:

6

Mathematica 120 21 20

введите описание изображения здесь

Явная рекурсия (спасибо alephalpha за сохранение одного символа):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

{{{}, {}}, {{}, {}, {}}, {}, {}, {}}

TreeForm[%]

введите описание изображения здесь

Предыдущее слишком сложное решение:

d="~/StackExchange/dir1"

f@{x___,Longest@s:{y_,___}..,z___}:=f@{x,f@Drop[{s},1,1],z}
f[FileNameSplit/@FileNames[__,SetDirectory@d;"",∞]]/.f->(#&)
ybeltukov
источник
f=f/@__~FileNames~#&
alephalpha 13.01.14
2

Рубин, 38 символов

Если вы не возражаете против лишних пробелов в выводе:

f=->n{Dir[n+'/*'].map{|c|f[c]}}
p f[D]

Пример использования:

D='C:/work/dir1'
f=->n{Dir[n+'/*'].map{|c|f[c]}}
p f[D]

Выход:

[[[], []], [[], [], []], [], [], []]

Если у меня не может быть пробела, что-то вроде этого для второй строки:

puts"#{f[D]}".tr' ',''
Пол Престиж
источник
2

Python 2,7, 111 символов

Принимает целевой путь от стандартного ввода.

import os
def R(d):return[R(f)for f in[d+'/'+e for e in os.listdir(d)]if os.path.isdir(f)]
print R(raw_input())
боб
источник
2

Powershell - 182 символа

function A([string]$b){write-host -NoNewline '['; ls -path $b|foreach{if($_.PSIsContainer){A($_.FullName)}ELSE{write-host -NoNewline $f'[]';$f=', '}};write-host -NoNewline ']'};A($D)

Довольно просто. Может быть уменьшено на 10 символов, если запятые не требуются. Принимает входные данные от $ D (как указано в вопросе), возвращает выходные данные на STD-Out, как в примере в вопросе.

Действительно желающие псевдонимы могут использовать параметры! Я был убит хозяином записи -NoNewline!

lochok
источник
Я думаю, что это может быть сделано немного лучше. Более опытные игроки в гольф хотят дать ему трещину?
lochok
Я не знаю, достигли ли вы цели, к которой стремится задача ... но это не имеет большого значения, так как все, кто ответил, похоже, выбрали свою собственную интерпретацию.
HRRambler
{DOH! Хит войти случайно. } При этом я не буду касаться вашей интерпретации foreach {}, я просто укажу на улучшение, которое вы можете внести. Первый трюк PowerShell, который вам не хватает, заключается в том, что запись-хост не нужна, если вы заканчиваете свой код данными в конвейере, который записывается на хост. Второй трюк - автоматическое расширение и объединение, которое происходит в двойных кавычках. Наконец, используйте get-alias для определения трюков, таких как% = foreach. В следующий раз используйте стратегию, которая заключает ваши результаты в переменную, затем завершается вызовом этой переменной: $ a = gi $ d | ls | % {}; «[$ a]»
HRRambler
1

C # 200 символов

Вывод строки, а не фактического массива. Принимает путь в качестве первого аргумента.

using D=System.IO.DirectoryInfo;class P{static string R(D d){var r="[";foreach(D e in d.GetDirectories())r+=R(e);return r+"]";}static void Main(string[] a) {System.Console.WriteLine(R(new D(a[0])));}}

Ungolfed:

using D = System.IO.DirectoryInfo;

class P
{
    static string R(D d)
    {
        var r = "[";
        foreach (D e in d.GetDirectories())
            r += R(e);
        return r + "]";
    }

    static void Main(string[] a)
    {
        System.Console.WriteLine(R(new D(a[0])));
    }
}
боб
источник
Моя первая попытка игры в гольф, и C # - довольно многословный язык. Любой совет будет принят во внимание.
Боб
0

C ++, 318 байт

#include <cstdio>
#include <dirent.h>
#include <string>
#define s std::string
#define n e->d_name
s l(s p){s r;dirent*e;DIR*d;if(d=opendir(p.c_str())){int c=0;while(e=readdir(d))if(s("..")!=n&s(".")!=n)r+=&",["[!c++]+(e->d_type==DT_DIR?l(p+'/'+n):"")+"]";closedir(d);}return r;}main(){puts((s("[")+l(D)+"]").c_str());}

Вот немного неутешительная версия:

#include <cstdio>
#include <dirent.h>
#include <string>

#define s std::string
#define n e->d_name

s l(s p) {
    s r;
    dirent*e;
    DIR*d;
    if (d=opendir(p.c_str())) {
        int c=0;
        while (e=readdir(d))
            if (s("..")!=n&s(".")!=n)
                r+=&",["[!c++]+(e->d_type==DT_DIR?l(p+'/'+n):"")+"]";
        closedir(d);
    }
    return r;
}

main() {
    puts((s("[")+l(D)+"]").c_str());
}

Обратите внимание, что, поскольку - согласно инструкциям - D предполагается заранее определенной переменной, код не собирается без какого-либо предоставления D. Вот один из способов построения:

g++ -Dmain="s D=\".\";main" -o tree golfed.cpp
treamur
источник
0

Пакетный скрипт - 146, 157, 152, 127 байт.

set x=
:a
set x=%x%,[
cd %1
goto %errorlevel%
:0
for /f %%a in ('dir/b') do call:a %%a
cd..
:1
set x=%x:[,=[%]
cls
@echo %x:~1%

Бежать с:

scriptfile.cmd folderroot
Роберт Сёрли
источник
Выходные данные увеличиваются при каждом запуске этого скрипта.
unclemeat
1
Да, это было не очень дружелюбно по отношению к
сессиям