Code Golf: Verzeichnisbaum -> Baum

11

Wettbewerb (!): Schreiben Sie in der Sprache Ihrer Wahl ein Programm, das den Verzeichnisbaum eines bestimmten Verzeichnisses durchläuft und einen entsprechenden Baum (dh ein Array von Arrays) ausgibt. Angenommen, das Verzeichnis ist eine vordefinierte Variable D. Die kleinste Zeichenanzahl gewinnt.

Regeln:

  • Sie müssen die Rekursion verwenden
  • Siehe Regeln

Hinweis: Angenommen, es gibt keine Rekursionstiefenbeschränkungen. Mit anderen Worten, Ihr Code muss nur für ausreichend kleine Verzeichnisbäume und im Prinzip für größere funktionieren.

Zum Beispiel:

Verzeichnisbaum ist

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

Ausgabebaum ist

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

Erster Code Golf hier, damit ich weiß, ob ich etwas falsch mache.

Habe Spaß :)

Andrew Odesky
quelle
7
"Regeln: 1. Sie müssen Rekursion verwenden 2. Siehe Regeln" Ah !! HILFE, dass ich in einer unendlichen Schleife stecke!
Justin
1
Sie können sich an der Anzahl der Zeichen orientieren oder an der kleinsten Größe in Bytes (auf diese Weise sind Programme mit Unicode-Zeichen größer als bei Verwendung von reinem ASCII)
Justin
1
Wie tief würde es gehen?
wahr.
Viele Leute würden es begrüßen, wenn Sie stattdessen eine Eingabe einer Datei (als Pfad oder etwas anderes) geben würden und sie diese einfach ausgeben könnten. Außerdem scheint Ihre Ausgabe etwas schwer zu verstehen. Können Sie einen Testfall bereitstellen? Könnten wir, anstatt ein Array von Arrays zu verwenden, einfach jedes Verzeichnis / jede Datei in einer eigenen Zeile drucken, aber eingerückt, um die Unterfolie anzuzeigen? Müssen wir grundsätzlich in einem bestimmten Format ausgeben (in diesem Fall geben Sie ein Beispiel an), oder können wir ein Format auswählen (solange es eindeutig ist)?
Justin
3
Ich werde blind und analysiere dein Ausgabeformat. Dies von jemandem, der Lisp mag.
Darren Stone

Antworten:

6

Mathematica 120 21 20

Geben Sie hier die Bildbeschreibung ein

Explizite Rekursion (danke alephalpha für das Speichern eines Zeichens):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

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

TreeForm[%]

Geben Sie hier die Bildbeschreibung ein

Vorherige überkomplizierte Lösung:

d="~/StackExchange/dir1"

f@{x___,Longest@s:{y_,___}..,z___}:=f@{x,f@Drop[{s},1,1],z}
f[FileNameSplit/@FileNames[__,SetDirectory@d;"",∞]]/.f->(#&)
ybeltukov
quelle
f=f/@__~FileNames~#&
Alephhalpha
2

Ruby, 38 Zeichen

Wenn Ihnen zusätzliche Leerzeichen in der Ausgabe nichts ausmachen:

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

Anwendungsbeispiel:

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

Ausgabe:

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

Wenn ich das Leerzeichen nicht haben kann, so etwas für die zweite Zeile:

puts"#{f[D]}".tr' ',''
Paul Prestidge
quelle
2

Python 2.7, 111 Zeichen

Nimmt den Zielpfad von 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())
Bob
quelle
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)

Ziemlich Einfach. Könnte um 10 Zeichen reduziert werden, wenn die Kommas nicht benötigt würden. Nimmt Eingaben von $ D (wie in Frage angegeben) entgegen und gibt die Ausgabe auf STD-Out zurück, wie im Beispiel in der Frage angegeben.

Ich wünschte wirklich, Aliase könnten Optionen verwenden! Ich werde von den 'Write-Host-NoNewline's' getötet!

Lochok
quelle
Ich denke, es könnte ein bisschen besser gemacht werden. Ein erfahrener Golfer möchte es knacken?
Lochok
Ich weiß nicht, ob Sie tatsächlich das Ziel erreicht haben, auf das die Herausforderung abzielt ... aber das ist keine große Sache, da jeder, der geantwortet hat, seine eigene Interpretation gewählt zu haben scheint.
HRRambler
{doh! Drücken Sie versehentlich die Eingabetaste. } Davon abgesehen werde ich Ihre foreach {} Interpretation nicht berühren, ich werde nur auf eine Verbesserung hinweisen, die Sie vornehmen können. Der erste Powershell-Trick, den Sie vermissen, ist, dass Write-Host nicht erforderlich ist. Wenn Sie Ihren Code mit Daten in der Pipeline beenden, wird er auf den Host geschrieben. Der zweite Trick ist das automatische Erweitern und Verketten, das in doppelten Anführungszeichen erfolgt. Verwenden Sie schließlich get-alias, um Tricks wie% = foreach zu identifizieren. Verwenden Sie das nächste Mal eine Strategie, die Ihre Ergebnisse in eine Variable einschließt, und rufen Sie dann diese Variable auf: $ a = gi $ d | ls | % {}; "[$ a]"
HRRambler
1

C # 200 Zeichen

Ausgabe eines Strings, kein tatsächliches Array. Nimmt einen Pfad als erstes Argument.

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])));
    }
}
Bob
quelle
Mein erster Golfversuch und C # ist eine ziemlich ausführliche Sprache. Jeder Rat wäre dankbar.
Bob
0

C ++, 318 Bytes

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

Hier ist eine leicht ungolfed Version:

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

Bitte beachten Sie, dass - gemäß den Anweisungen - D als vordefinierte Variable angenommen wird, der Code nicht erstellt wird, ohne D anzugeben. Hier ist eine Möglichkeit zum Erstellen:

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

Batch-Skript - 146, 157, 152, 127 Byte

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%

Laufen Sie mit:

scriptfile.cmd folderroot
Robert Sørlie
quelle
Die Ausgabe wird mit jedem Durchlauf dieses Skripts größer.
Unclemeat
1
Ja, es war nicht sehr sitzungsfreundlich, sollte aber jetzt besser sein
Robert Sørlie