代码高尔夫:目录树->树


11

竞赛(!):使用您选择的语言,编写一个程序,该程序将遍历给定目录的目录树并输出与之对应的树(即数组数组)。假定目录是一个预定义的变量D。以最少的字符数为准。

规则:

  • 您必须使用递归
  • 见规则

注意:假定没有递归深度限制。换句话说,您的代码只需要为足够小的目录树工作,原则上就可以为更大的目录树工作。

例如:

目录树是

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

输出树是

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

这里的第一个代码高尔夫,让我知道我做错了什么。

玩得开心 :)


7
“规则:1.您必须使用递归2.请参阅规则”啊!帮助我陷入无限循环!
贾斯汀

1
您可以按字符数进行计算,也可以按字节最小进行计算(这样,使用unicode字符的程序将比使用纯ascii的程序更大)
贾斯汀

1
它会走多深?
不是。

如果您改为输入文件(作为路径或其他内容),而他们可以简单地输出文件,那么许多人将不胜感激。另外,您的输出似乎有点难以理解。您可以提供一个测试用例吗?除了使用数组数组,我们可以简单地将每个目录/文件打印在自己的行上,但缩进显示子文件夹吗?基本上,我们必须以某种格式输出(在这种情况下,举个例子),还是可以选择一种格式(只要它是明确的)?
贾斯汀

3
我要瞎了,解析您的输出格式。这来自喜欢Lisp的人。
达伦·斯通

Answers:


6

Mathematica 120 21 20

在此处输入图片说明

显式递归(感谢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 2014年

2

Ruby,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]

输出:

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

如果我没有空格,请在第二行中输入以下内容:

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上的输出。

真希望别名可以使用选项!我被“写主机-NoNewline”杀死了!


我认为可能可以做得更好。一个经验丰富的高尔夫球手想给它一个裂缝吗?
lochok 2014年

我不知道您是否真的达到了挑战所针对的目标……但这并不是什么大问题,因为每个做出回应的人似乎都选择了自己的解释。
HRRambler 2015年

{道!误按Enter键。}话虽如此,但我不会触动您的foreach {}解释,我只是指出您可以做出的改进。您缺少的第一个powershell技巧是,不需要写主机,如果您在流水线中将代码写入主机后结束代码。第二个技巧是在双引号内自动展开和连接。最后使用get-alias来识别%= foreach之类的技巧。下次使用将结果包含在变量中的策略,然后通过调用该变量结束:$ a = gi $ d | ls | %{}; “ [$ a]”
HRRambler 2015年

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

每次运行此脚本时,输出都会变大。
2014年

1
是的,它不是非常适合会议,但现在应该更好
RobertSørlie2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.