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


11

Конкурс (!): На обраній вами мові напишіть програму, яка буде перетинати дерево каталогів певного каталогу та виводити відповідне йому дерево (тобто масив масивів). Припустимо, що каталог - це заздалегідь визначена змінна D. Найменший перелік символів виграє.

Правила:

  • Ви повинні використовувати рекурсію
  • Див. Правила

Примітка. Припустимо, що немає обмежень глибини рекурсії. Іншими словами, ваш код просто повинен працювати для досить малих дерев каталогів, і в принципі для великих.

Наприклад:

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

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

Вихідне дерево є

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

Перший код гольфу тут, так що я знаю, чи я щось роблю не так.

Приємно :)


7
"Правила: 1. Ви повинні використовувати рекурсію. 2. Див правила" Ах !! ДОПОМОЖУЙТЕ, Я ВСТУПУЙТЕ В БЕЗКОШТОВНИЙ ЛОП!
Джастін

1
Ви можете піти за кількістю символів, або ви можете перейти на найменший розмір у байтах (таким чином програми з символами unicode є більшими, ніж якщо б вони використовували чисту ascii)
Джастін

1
Як глибоко він би пройшов?
ЦеNotALie.

Багато людей оцінюють це, якби ви натомість давали введення файлу (як шлях або щось інше), і вони могли просто вивести його. Крім того, ваш результат здається трохи важким для розуміння. Чи можете ви надати тестовий випадок? Замість використання масиву масивів ми могли б просто надрукувати кожен каталог / файл у своєму власному рядку, але з відступом, щоб показати підпапка? В основному, чи ми повинні виводити у певному форматі (у такому випадку, наводити приклад), чи можемо вибрати формат (доки це однозначно)?
Джастін

3
Я сліпую, розбираю ваш вихідний формат. Це від того, хто любить Лісп.
Даррен Стоун

Відповіді:


6

Математика 120 21 20

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

Явна рекурсія (спасибі алефальфа за збереження однієї картки):

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->(#&)

f=f/@__~FileNames~#&
алефальфа

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 символів

Бере цільовий шлях від stdin.

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 Char

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


Я думаю, що це можливо вдасться зробити трохи краще. Досвідченіші гольфісти хочуть дати йому тріщину?
лочок

Я не знаю, чи дійсно ви потрапили в ціль, до якої ставиться завдання ... але це не велика справа, оскільки кожен, хто відповів, схоже, обрав свою інтерпретацію.
HRRambler

{да! Потрапити ввести випадково. } Якщо говорити, що я не збираюся зачіпати ваше передбачення {} інтерпретації, я просто вкажу на поліпшення, яке ви можете зробити. Перший трюк, який вам не вистачає, - це те, що хост запису не потрібний, якщо ви закінчите свій код даними в конвеєрі, він записується на хост. Другий трюк - автоматичне розширення та конкатенація, що відбувається в межах подвійних лапок. Нарешті, використовуйте get-псевдонім для виявлення хитрощів типу% = foreach. Наступного разу використовуйте стратегію, яка охоплює ваші результати у змінній, а потім закінчується викликом цієї змінної: $ a = gi $ d | лс | % {}; "[$ 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])));}}

Безголівки:

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

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

Вихід стає більшим при кожному запуску цього сценарію.
нечисте

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