コードゴルフ:ディレクトリツリー->ツリー


11

コンテスト(!):選択した言語で、指定されたディレクトリのディレクトリツリーを走査し、それに対応するツリー(配列の配列)を出力するプログラムを作成します。ディレクトリが事前定義された変数Dであると仮定します。最小の文字数が優先されます。

ルール:

  • 再帰を使用する必要があります
  • ルールを見る

注:再帰の深さの制限がないと仮定します。言い換えれば、コードは十分に小さなディレクトリツリーで動作する必要があり、原則として大きなディレクトリツリーで動作します。

例えば:

ディレクトリツリーは

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

出力ツリーは

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

ここで最初にゴルフをコーディングしてください。

楽しんで :)


7
「ルール:1.再帰を使用する必要があります。2。ルールを参照してください」Ah !! 私は無限ループに夢中です!
ジャスティン14年

1
文字数で移動することも、バイト単位の最小サイズで移動することもできます(このように、ユニコード文字を使用するプログラムは、純粋なASCIIを使用した場合よりも大きくなります)
ジャスティン14年

1
どれくらい深く行きますか?
それはNotALieです。

代わりにファイルの入力(パスなど)を与え、単純に出力することができれば、多くの人が感謝します。また、出力を理解するのは少し難しいようです。テストケースを提供できますか?配列の配列を使用するのではなく、単純に各ディレクトリ/ファイルを独自の行に印刷しますが、サブフォルダーを示すためにインデントしますか?基本的に、特定の形式で出力する必要があります(その場合、例を挙げます)、または形式を選択できますか(明確である限り)。
ジャスティン14年

3
あなたの出力フォーマットを解析し、盲目になります。これは、Lispを楽しんでいる人から。
ダレンストーン14年

回答:


6

Mathematica 120 21 20

ここに画像の説明を入力してください

明示的な再帰(1文字を保存してくれたalephalphaに感謝):

f=f/@__~FileNames~#&

f["~/StackExchange/dir1"]

{{{}、{}}、{{}、{}、{}}、{}、{}、{}}

TreeForm[%]

ここに画像の説明を入力してください

以前の複雑すぎるソリューション:

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 14年

2

ルビー、38文字

出力の余分な空白を気にしない場合:

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

使用例:

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

出力:

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

空白を取得できない場合は、2行目に次のように入力します。

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

2

Python 2.7、111文字

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文字

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)

かなり簡単です。コンマが不要な場合は、10文字減らすことができます。(質問で述べたように)$ Dから入力を受け取り、質問の例が行ったようにSTD-Outに出力を返します。

本当に希望するエイリアスはオプションを使用できます!私は 'write-host -NoNewline'sに殺されています!


少し良くできるかもしれないと思います。より経験豊富なゴルファーは、それにクラックを与えたいですか?
lochok 14年

チャレンジが目指している目標を実際に達成したかどうかはわかりませんが、それは大したことではありません。応答した人は皆、自分の解釈を選んだようです。
HRランブラー

{ど!誤ってエンターキーを押してください。}私はあなたのforeach {}の解釈に触れるつもりはないと言われていますが、あなたができる改善を指し示すだけです。欠落している最初のPowerShellトリックは、ホストに書き込まれたパイプライン内のデータでコードを終了する場合、書き込みホストが不要であることです。2番目のトリックは、二重引用符内で発生する自動マジック拡張および連結です。最後にget-aliasを使用して、%= foreachなどのトリックを識別します。次回は、結果を変数に入れて、その変数を呼び出すことで終了する戦略を使用します。$ a = gi $ d | ls | %{}; 「[$ a]」
HRランブラー

1

C#200文字

実際の配列ではなく、文字列を出力します。最初の引数としてパスを取ります。

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

ゴルフをしていない:

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

私の最初のゴルフの試みであり、C#はかなり冗長な言語です。アドバイスをいただければ幸いです。
ボブ

0

C ++、318バイト

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

以下は、わずかに未使用のバージョンです。

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

-命令ごとに-Dは事前定義された変数であると想定されているため、コードは何らかの方法でDを提供しないとビルドされないことに注意してください。

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

0

バッチスクリプト-146、157、152 127バイト

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%

で実行:

scriptfile.cmd folderroot

このスクリプトを実行するたびに出力が大きくなります。
無修正14年

1
ええ、それはあまりセッションフレンドリーではありませんでしたが、今は良くなっているはずです
ロバートソーリー14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.