Code Golf: Drzewo katalogów -> Drzewo


11

Konkurs (!): W wybranym języku napisz program, który przejdzie przez drzewo katalogów danego katalogu i wyświetli odpowiadające mu drzewo (tj. Tablicę tablic). Załóżmy, że katalog jest predefiniowaną zmienną D. Wygrywa najmniejsza liczba znaków.

Zasady:

  • Musisz użyć rekurencji
  • Zobacz zasady

Uwaga: Załóżmy, że nie ma limitów głębokości rekurencji. Innymi słowy, twój kod musi po prostu działać dla wystarczająco małych drzew katalogów, i zasadniczo dla większych.

Na przykład:

Drzewo katalogów to

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

Drzewo wyjściowe to

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

Pierwszy kod golfowy, więc daj mi znać, czy robię coś źle.

Baw się dobrze :)


7
„Zasady: 1. Musisz użyć rekurencji 2. Zobacz zasady„ Ach !! POMÓŻ, ŻE STUCKUJĘ W NIESKOŃCZONEJ PĘTLI!
— Justin

1
Możesz przejść według liczby znaków lub możesz przejść według najmniejszego rozmiaru w bajtach (w ten sposób programy ze znakami Unicode są większe niż gdyby używały czystego ascii)
— Justin

1
Jak głęboko przemieściłby się?
— It'sNotALie.

Wiele osób doceniłoby to, gdyby zamiast tego podano dane wejściowe pliku (jako ścieżkę lub coś innego), a oni po prostu mogliby je wyprowadzić. Wydaje się również, że twoje wyniki są nieco trudne do zrozumienia. Czy możesz podać przypadek testowy? Czy zamiast korzystać z tablicy tablic, moglibyśmy po prostu wydrukować każdy katalog / plik w osobnym wierszu, ale z wcięciem, aby pokazać podfolder? Zasadniczo, czy musimy wyprowadzać dane wyjściowe w określonym formacie (w takim przypadku podać przykład), czy możemy wybrać format (o ile jest to jednoznaczne)?
— Justin

3
Staję się ślepy, analizując format wyjściowy. To od kogoś, kto lubi Lisp.
— Darren Stone

Odpowiedzi:


6

Mathematica 120 21 20

wprowadź opis zdjęcia tutaj

Jawna rekurencja (dzięki alephalpha za uratowanie jednego znaku):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

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

TreeForm[%]

wprowadź opis zdjęcia tutaj

Poprzednie skomplikowane rozwiązanie:

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~#&
— alephalpha

2

Ruby, 38 znaków

Jeśli nie przeszkadza ci dodatkowe spacje w danych wyjściowych:

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

Przykładowe użycie:

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

Wynik:

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

Jeśli nie mogę mieć spacji, coś takiego w drugiej linii:

puts"#{f[D]}".tr' ',''

2

Python 2.7, 111 znaków

Bierze ścieżkę docelową ze standardowego wejścia.

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)

Dość proste. Można zmniejszyć o 10 znaków, jeśli przecinki nie są wymagane. Pobiera dane wejściowe z $ D (jak podano w pytaniu), zwraca dane wyjściowe w STD-Out, jak w przykładzie podanym w pytaniu.

Naprawdę pragnące aliasy mogłyby skorzystać z opcji! Zostaję zabity przez 'host-write -NoNewline's!


Myślę, że można to zrobić trochę lepiej. Bardziej doświadczeni golfiści chcą spróbować?
— lochok

Nie wiem, czy rzeczywiście osiągnąłeś cel, do którego dąży wyzwanie ... ale to nie jest wielka sprawa, ponieważ wydaje się, że każdy, kto odpowiedział, wybrał własną interpretację.
— HRRambler

{doh! Wciśnij enter przez przypadek. } Biorąc to pod uwagę, nie zamierzam dotykać twojej interpretacji foreach {}, zamierzam jedynie wskazać ulepszenie, które możesz wprowadzić. Pierwszą sztuczką typu PowerShell, której brakuje, jest to, że host do zapisu nie jest potrzebny, jeśli kod zakończy się danymi w potoku, zostanie on zapisany na hoście. Druga sztuczka to automagiczne rozwijanie i łączenie, które ma miejsce w podwójnych cudzysłowach. Na koniec użyj get-alias do identyfikacji sztuczek, takich jak% = foreach. Następnym razem zastosuj strategię, która otacza twoje wyniki zmienną, a następnie kończy przez wywołanie tej zmiennej: $ a = gi $ d | ls | % {}; „[$ a]”
— HRRambler

1

C # 200 znaków

Wyprowadzanie ciągu, a nie rzeczywistej tablicy. Jako pierwszy argument przyjmuje ścieżkę.

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

Nie golfowany:

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

Moja pierwsza próba gry w golfa, a C # jest raczej pełnym językiem. Wszelkie porady będą mile widziane.
— Bob

0

C ++, 318 bajtów

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

Oto nieco niestosowana wersja:

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

Zauważ, że ponieważ - zgodnie z instrukcjami - D jest założoną zmienną predefiniowaną, kod nie buduje się bez podania D. Oto jeden ze sposobów budowania:

g++ -Dmain="s D=\".\";main" -o tree golfed.cpp

0

Skrypt wsadowy - 146, 157, 152 127 bajtów

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%

Biegnij z:

scriptfile.cmd folderroot

Wydajność rośnie z każdym uruchomieniem tego skryptu.
— nieprzyzwoite

1
Tak, nie był zbyt przyjazny dla sesji, ale powinien być lepszy
— Robert Sørlie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.