Code Golf: ไดเรกทอรีต้นไม้ -> ต้นไม้


11

การประกวด (!): ในภาษาที่คุณเลือกให้เขียนโปรแกรมที่จะสำรวจทรีไดเรกทอรีของไดเรกทอรีที่กำหนดและส่งออกทรี (เช่นอาร์เรย์ของอาร์เรย์) ที่สอดคล้องกับมัน สมมติว่าไดเรกทอรีเป็นตัวแปรที่กำหนดไว้ล่วงหน้า D. จำนวนตัวอักษรที่เล็กที่สุดชนะ

กฎ:

  • คุณต้องใช้การสอบถามซ้ำ
  • ดูกฎ

หมายเหตุ: สมมติว่าไม่มีการจำกัดความลึกของการเรียกซ้ำ กล่าวอีกนัยหนึ่งรหัสของคุณต้องทำงานกับไดเรกทอรีต้นไม้ขนาดเล็กและในหลักการสำหรับต้นไม้ใหญ่

ตัวอย่างเช่น

ต้นไม้ไดเรกทอรีคือ

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

ต้นไม้ออกคือ

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

กอล์ฟรหัสแรกที่นี่เพื่อทราบว่าฉันกำลังทำอะไรผิด

มีความสุข :)


7
"กฎ: 1. คุณต้องใช้การเรียกซ้ำ 2. ดูกฎ" อ่า !! ช่วยฉันติดอยู่ในวงอินฟินิท!
Justin

1
คุณสามารถไปโดยนับจำนวนตัวอักษรหรือคุณอาจจะไปตามขนาดที่เล็กที่สุดในไบต์ (โปรแกรมนี้ทางกับอักขระ Unicode มีขนาดใหญ่กว่าถ้าพวกเขาใช้ ASCII บริสุทธิ์)
จัสติน

1
มันจะลึกแค่ไหน?
It'sNotALie

หลาย ๆ คนจะซาบซึ้งถ้าคุณให้อินพุตไฟล์ (เป็นพา ธ หรืออย่างอื่น) แทนและพวกเขาก็สามารถเอาท์พุทได้ นอกจากนี้ผลลัพธ์ของคุณดูเหมือนยากที่จะเข้าใจ คุณสามารถให้กรณีทดสอบได้หรือไม่? แทนที่จะใช้อาร์เรย์ของอาร์เรย์เราสามารถพิมพ์แต่ละไดเรกทอรี / ไฟล์บนบรรทัดของมันเอง แต่เยื้องเพื่อแสดงโฟลเดอร์ย่อยหรือไม่? โดยทั่วไปแล้วเราจะต้องส่งออกในรูปแบบที่แน่นอน (ในกรณีนี้ให้ตัวอย่าง) หรือเราสามารถเลือกรูปแบบ (ตราบใดที่มันไม่ชัดเจน)?
Justin

3
ฉันจะตาบอดแยกวิเคราะห์รูปแบบผลลัพธ์ของคุณ สิ่งนี้จากคนที่ชอบเสียงกระเพื่อม
Darren Stone

คำตอบ:


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

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]

เอาท์พุท:

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

ถ้าฉันไม่สามารถมีช่องว่างอะไรบางอย่างเช่นนี้สำหรับบรรทัดที่สอง:

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 ตามตัวอย่างในคำถามที่เกิดขึ้น

นามแฝงที่ต้องการจริงๆสามารถใช้ตัวเลือก! ฉันถูกฆ่าโดย 'เขียน - โฮสต์ - ไม่มีของใหม่!


ฉันคิดว่ามันน่าจะทำได้ดีกว่านี้สักหน่อย นักกอล์ฟที่มีประสบการณ์มากขึ้นต้องการที่จะให้มันแตก?
394 lochok

ฉันไม่รู้ว่าถ้าคุณเข้าถึงกลุ่มเป้าหมายที่ท้าทายกำลังมุ่งไปที่ ... แต่นั่นไม่ใช่เรื่องใหญ่เพราะทุกคนที่ตอบโต้ดูเหมือนจะเลือกการตีความของตัวเอง
HRRambler

{DOH! กด Enter โดยไม่ได้ตั้งใจ } ที่ถูกกล่าวว่าฉันจะไม่สัมผัส foreach ของคุณ {} การตีความฉันแค่จะชี้ไปที่การปรับปรุงที่คุณสามารถทำได้ เคล็ดลับ PowerShell แรกที่คุณหายไปคือการเขียนโฮสต์ไม่จำเป็นถ้าคุณจบรหัสด้วยข้อมูลในขั้นตอนที่เขียนไปยังโฮสต์ เคล็ดลับที่สองคือการขยายและต่อเชื่อมอัตโนมัติที่เกิดขึ้นภายในเครื่องหมายคำพูดคู่ สุดท้ายใช้ get-alias เพื่อระบุลูกเล่นเช่น% = foreach ครั้งต่อไปใช้กลยุทธ์ที่เข้ารหัสผลลัพธ์ของคุณภายในตัวแปรแล้วสิ้นสุดโดยการเรียกตัวแปรนั้น: $ a = gi $ d | ls | % {}; "[$ a]"
HRRambler

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

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

ความพยายามเล่นกอล์ฟครั้งแรกของฉันและ C # เป็นภาษาที่ค่อนข้างละเอียด คำแนะนำใด ๆ ที่จะได้รับการชื่นชม.
Bob

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

ผลลัพธ์จะยิ่งใหญ่ขึ้นในการรันสคริปต์นี้ทุกครั้ง
ลุง

1
ใช่มันไม่ได้เป็นมิตรกับเซสชั่น แต่ควรจะดีกว่าตอนนี้
Robert Sørlie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.