Code Golf: Diretório Árvore -> Árvore

11

Concurso (!): No idioma de sua escolha, escreva um programa que percorra a árvore de diretórios de um determinado diretório e produza uma árvore (ou seja, uma matriz de matrizes) correspondente a ele. Suponha que o diretório seja uma variável predefinida D. A menor contagem de caracteres vence.

Regras:

  • Você deve usar recursão
  • Ver Regras

Nota: Suponha que não haja limites de profundidade de recursão. Em outras palavras, seu código só precisa funcionar para árvores de diretório suficientemente pequenas e, em princípio, para árvores maiores.

Por exemplo:

A árvore de diretórios é

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

A árvore de saída é

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

Primeiro código de golfe aqui, então deixe-me saber se estou fazendo algo errado.

Diverta-se :)

Andrew Odesky
fonte
7
"Regras: 1. Você deve usar a recursão 2. Veja as regras" Ah !! AJUDA Estou preso em um laço infinito!
Justin
1
Você poderia ir pela contagem de caracteres, ou você poderia ir de menor tamanho em bytes (desta forma os programas com caracteres Unicode são maiores do que se eles usaram ascii pura)
Justin
1
Quão profundo ele atravessaria?
caso.
Muitas pessoas gostariam que você desse uma entrada de um arquivo (como um caminho ou qualquer outra coisa) e elas simplesmente pudessem produzi-lo. Além disso, sua saída parece um pouco difícil de entender. Você pode fornecer um caso de teste? Em vez de usar uma matriz de matrizes, poderíamos simplesmente imprimir cada diretório / arquivo em sua própria linha, mas recuado para mostrar a subpasta? Basicamente, devemos produzir em um determinado formato (nesse caso, dar um exemplo) ou podemos escolher um formato (desde que não seja ambíguo)?
Justin
3
Estou ficando cego, analisando seu formato de saída. Isto, de alguém que gosta de Lisp.
Darren Pedra

Respostas:

6

Mathematica 120 21 20

insira a descrição da imagem aqui

Recursão explícita (obrigado alephalpha por salvar um caractere):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

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

TreeForm[%]

insira a descrição da imagem aqui

Solução supercomplicada anterior:

d="~/StackExchange/dir1"

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

Ruby, 38 caracteres

Se você não se importa com algum espaço em branco extra na saída:

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

Exemplo de uso:

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

Resultado:

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

Se eu não puder ter o espaço em branco, algo assim para a segunda linha:

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

Python 2.7, 111 caracteres

Pega o caminho de destino de 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())
Prumo
fonte
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)

Relativamente simples. Pode ser reduzido em 10 caracteres se as vírgulas não forem necessárias. Recebe entrada de $ D (como declarado na pergunta), retorna a saída em STD-Out como foi o exemplo da pergunta.

Realmente desejando aliases poderiam usar opções! Estou sendo morto pelos 'write-host -NoNewline's!

Lochok
fonte
Eu acho que pode ser feito um pouco melhor. Um golfista mais experiente quer dar uma chance?
Locok
Não sei se você realmente atingiu o objetivo que o desafio está buscando ... mas isso não é grande coisa, já que todos que responderam parecem ter escolhido sua própria interpretação.
precisa saber é o seguinte
{doh! Pressione Enter por acidente. } Dito isto, não vou tocar na sua interpretação {}, apenas apontarei para uma melhoria que você pode fazer. O primeiro truque do PowerShell que você está perdendo é que o host de gravação é desnecessário, se você encerrar seu código com dados no pipeline que ele gravou no host. O segundo truque é a expansão e concatenação de automagia que acontece entre aspas duplas. Por fim, use get-alias para identificar truques como% = foreach. Da próxima vez, use uma estratégia que envolva seus resultados em uma variável e termine chamando a variável: $ a = gi $ d | ls | % {}; "[$ a]"
HRRambler 23/01
1

Caracteres C # 200

Saída de uma string, não de uma matriz real. Toma um caminho como o primeiro argumento.

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])));
    }
}
Prumo
fonte
Minha primeira tentativa de golfe e C # é uma linguagem bastante detalhada. Qualquer conselho seria apreciado.
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());}

Aqui está uma versão ligeiramente não-destruída:

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

Observe que, como - por instruções - D é assumida como uma variável predefinida, o código não é construído sem fornecer de alguma forma o D. Aqui está uma maneira de criar:

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

Script em lote - 146, 157, 152 127 bytes

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%

Correr com:

scriptfile.cmd folderroot
Robert Sørlie
fonte
A saída aumenta em cada execução deste script.
unclemeat
1
Sim, não foi muito amigável para as sessões, mas deve ser melhor agora
Robert Sørlie 13/01