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.