Codice Golf: Directory Tree -> Tree


11

Contest (!): Nella lingua che preferisci, scrivi un programma che attraverserà l'albero delle directory di una data directory e produrrà un albero (cioè una matrice di array) corrispondente ad essa. Supponiamo che la directory sia una variabile predefinita D. Il conteggio dei caratteri più piccolo vince.

Regole:

  • È necessario utilizzare la ricorsione
  • Vedi le regole

Nota: supponiamo che non ci siano limiti di profondità di ricorsione. In altre parole, il codice deve solo funzionare per alberi di directory sufficientemente piccoli e, in linea di principio, per alberi di dimensioni maggiori.

Per esempio:

L'albero delle directory è

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

L'albero di output è

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

Il primo codice golf qui, quindi fammi sapere se sto facendo qualcosa di sbagliato.

Divertiti :)


7
"Regole: 1. Devi usare la ricorsione 2. Vedi le regole" Ah !! AIUTO CHE SONO STUCK IN UN LOOP INFINITO!
Justin

1
Potresti seguire il conteggio dei caratteri, o potresti andare dalla dimensione più piccola in byte (in questo modo i programmi con caratteri unicode sono più grandi di se usassero ascii puri)
Justin

1
Quanto in profondità attraverserebbe?
It'sNotALie.

Molte persone lo apprezzerebbero se invece fornissi un input di un file (come percorso o qualcos'altro) e potrebbero semplicemente emetterlo. Inoltre, l'output sembra un po 'difficile da capire. Potete fornire un caso di prova? Invece di utilizzare una matrice di array, potremmo semplicemente stampare ogni directory / file sulla sua riga, ma indentato per mostrare la sottocartella? Fondamentalmente, dobbiamo produrre in un determinato formato (nel qual caso, fare un esempio) o possiamo scegliere un formato (purché non ambiguo)?
Justin

3
Sto diventando cieco, analizzando il tuo formato di output. Questo, da qualcuno a cui piace Lisp.
Darren Stone,

Risposte:


6

Mathematica 120 21 20

inserisci qui la descrizione dell'immagine

Ricorsione esplicita (grazie alephalpha per aver salvato un carattere):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

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

TreeForm[%]

inserisci qui la descrizione dell'immagine

Soluzione complicata precedente:

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

Rubino, 38 caratteri

Se non ti dispiace alcuni spazi bianchi in più nell'output:

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

Esempio di utilizzo:

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

Produzione:

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

Se non riesco ad avere gli spazi bianchi, qualcosa del genere per la seconda riga:

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

2

Python 2.7, 111 caratteri

Prende il percorso target dallo 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)

Abbastanza semplice. Potrebbe essere ridotto di 10 caratteri se le virgole non fossero necessarie. Prende input da $ D (come indicato nella domanda), restituisce output su STD-Out come nell'esempio nella domanda.

Desiderando davvero che gli alias possano usare le opzioni! Sono stato ucciso dall'host di scrittura -NoNewline!


Penso che potrebbe essere fatto un po 'meglio. I golfisti più esperti vogliono provare?
Lochok,

Non so se hai effettivamente raggiunto l'obiettivo a cui punta la sfida ... ma non è un grosso problema dal momento che tutti coloro che hanno risposto sembrano aver scelto la propria interpretazione.
HRRambler,

{doh! Hit entra per caso. } Detto questo, non toccherò la tua interpretazione foreach {}, sto solo per indicare un miglioramento che puoi apportare. Il primo trucco di PowerShell che manca è che l'host di scrittura non è necessario, se si termina il codice con i dati nella pipeline, questo viene scritto sull'host. Il secondo trucco è l'espansione e la concatenazione automagiche che si verificano tra virgolette doppie. Infine usa get-alias per identificare trucchi come% = foreach. La prossima volta usa una strategia che racchiuda i risultati all'interno di una variabile, quindi termina chiamando quella variabile: $ a = gi $ d | ls | % {}; "[$ a]"
HRRambler

1

C # 200 caratteri

Emissione di una stringa, non di un array reale. Prende un percorso come primo argomento.

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

Il mio primo tentativo di golf, e C # è un linguaggio piuttosto prolisso. Tutto il consiglio sarebbe apprezzato.
Bob

0

C ++, 318 byte

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

Ecco una versione leggermente non golfata:

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

Si noti che poiché - per istruzioni - D si presume che sia una variabile predefinita, il codice non viene creato senza in qualche modo fornire D. Ecco un modo per creare:

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

0

Script batch - 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%

Corri con:

scriptfile.cmd folderroot

L'output diventa più grande ad ogni esecuzione di questo script.
salato

1
Sì, non è stato molto amichevole per la sessione, ma dovrebbe essere migliore ora
Robert Sørlie il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.