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 :)


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->(#&)

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' ',''

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())

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!


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

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

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.