โปรแกรมขี้ตกใจ


17

วัตถุประสงค์

คุณจะต้องเขียนโปรแกรมที่รับจำนวนเต็มnเป็นอินพุต (จากบรรทัดคำสั่ง) และฝังตัวเอง (โปรแกรม) nไดเรกทอรีลงในไดเรกทอรีต้นไม้ ตัวอย่างด้วยn=5:

ตัวอย่างด้วย n = 5

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

โบนัส:

  • คะแนน * 0.9หากไดเรกทอรีทั้งหมดมีชื่อแตกต่างกัน (อย่างน้อยต้องเป็นความลึก 1 000 000)
  • คะแนน * 0.5หากคุณไม่ได้อ่านหรือย้ายไฟล์ต้นฉบับโดยตรงหรือโดยอ้อมหรือเข้าถึงซอร์สโค้ดของโปรแกรม

1
อะไรคือ " การอ่านต้นฉบับ " คุณหมายถึงไฟล์ หรือรหัสต้นฉบับจริง
GiantTree

2
@ unclemeat มันทำเพราะการย้ายไฟล์ที่คุณ (หรือระบบ) ต้องเข้าถึงข้อมูลในไฟล์
globby

25
ดูเหมือนว่าคุณกำลังพยายามซ่อนที่ซ่อนของสื่อลามก
Ablue

3
@globby เกี่ยวกับlnคำสั่งใน * nix อย่างไร หากฉันไม่เข้าใจผิดมันเป็นเพียงการสร้างรายการอื่นไปยังไฟล์ inode และไม่มีการอ่านเนื้อหาเลย
hjk

7
@globby เท่าที่ฉันทราบการย้ายไฟล์ไม่ได้อ่านเนื้อหาเว้นแต่ว่าคุณกำลังย้ายระหว่างฮาร์ดไดรฟ์หรือพาร์ติชัน มันเป็นเพียงแค่การเปลี่ยนพอยน์เตอร์ในระบบไฟล์
Martin Ender

คำตอบ:


36

Bash, 30 * 0.9 * 0.5 = 13.5

mkdir -p `seq -s/ $1`;ln $0 $_

ใช้ความลึกเป็นอาร์กิวเมนต์แรก สร้างฮาร์ดลิงก์ไปยังตัวเองในโครงสร้างไดเร็กทอรีต่อไปนี้:

1/2/3/4/5/.../n

สคริปต์อาจถูกเรียกใช้จากตำแหน่งใหม่แม้ว่าrmจะทำงานกับสคริปต์เก่าก็ตาม

คำอธิบาย:

seq -s/ $1ส่งออกตัวเลขตั้งแต่ 1 ถึง$1(อาร์กิวเมนต์แรก) คั่นด้วยเครื่องหมายสแลช

mkdir -p `seq -s` $1สร้างไดเรกทอรีที่ระบุโดยseqมี-pการสร้างไดเรกทอรีกลางทั้งหมด

ln $0 $_ สร้างฮาร์ดลิงก์ไปยังสคริปต์ที่กำลังใช้งานอยู่ในไดเรกทอรีที่สร้างขึ้นใหม่

เก่า (30 * 0.9 = 27):

mkdir -p `seq -s/ $1`;cp $0 $_

ตัวอย่างการรัน (ด้วย ln):

$ ls -lGR
.:
total 1
-rwx------+ 1 ducks 41 Jan  5 15:00 test.sh

$ ./test.sh 4

$ ls -lgR
.:
total 1
drwxr-xr-x+ 1 ducks  0 Jan  5 15:01 1
-rwx------+ 2 ducks 41 Jan  5 15:00 test.sh

./1:
total 0
drwxr-xr-x+ 1 ducks 0 Jan  5 15:01 2

./1/2:
total 0
drwxr-xr-x+ 1 ducks 0 Jan  5 15:01 3

./1/2/3:
total 0
drwxr-xr-x+ 1 ducks 0 Jan  5 15:01 4

./1/2/3/4:
total 1
-rwx------+ 2 ducks 41 Jan  5 15:00 test.sh

$ rm ./test.sh

$ ls -lg
total 0
drwxr-xr-x+ 1 ducks 0 Jan  5 15:01 1

$ ls -lg 1/2/3/4
total 1
-rwx------+ 1 ducks 41 Jan  5 15:00 test.sh

ขอบคุณ @DigitalTrauma สำหรับคำแนะนำในการแทนที่$(..)ด้วย`..`

ขอขอบคุณที่ @hjk lnสำหรับข้อเสนอแนะเพื่อการใช้งาน


6
การใช้ที่ยอดเยี่ยม$_!
wchargin

2
บันทึกตัวอักษรแบ็คคิกใช้แทนการ$( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma

2
ทั้งนี้ขึ้นอยู่กับคำตอบสำหรับความคิดเห็นของฉันในคำถามอาจแทนที่cpด้วยlnเพื่อรับโบนัส 0.5 เกินไป ...
hjk

2
เวลส์มีการอัปเดตจาก OP ตอนนี้และmvยังถูก จำกัด จากโบนัส 0.5 นั้น ที่ยังคงออกlnในที่ชัดเจนใช่มั้ย
hjk

2
ใช่ln(คุณไม่ต้องการ-s) จะวางโปรแกรมลงในไดเรกทอรีใหม่เพื่อให้สามารถดำเนินการได้จากที่นั่นโดยไม่ต้องอ่านย้ายหรือเข้าถึงแหล่งต้นฉบับ ฉันว่าไปสำหรับคะแนน FALCON PUNCH ที่ 13.5!
เบีย

12

C, 225 * 0.9 * 0.5 = 101.25

ทางออกของฉันใน C:

$ cat d.c
#define R(x)#x
#define T(x)R(x)
#define S(p)b[9];main(i,v)char**v;{for(i=atoi(v[1]);i--;sprintf(b,"%i",i),mkdir(b),chdir(b));fputs("#define R(x)#x\n#define T(x)R(x)\n#define S(p)"p"\nS(T(S(p)))",fopen("d.c","w"));}
S(T(S(p)))

ที่นี่ในรูปแบบที่อ่านได้ค่อนข้างมาก:

#define R(x) #x
#define T(x) R(x)
#define S(p) char b[9];\
             main(int i,char**v) { \
                for(i=atoi(v[1]); i--; sprintf(b,"%i",i), \
                                       mkdir(b), \
                                       chdir(b)); \
                fputs("#define R(x) #x\n" \
                      "#define T(x) R(x)\n" \
                      "#define S(p) " p "\n" \
                      "S(T(S(p)))", \
                      fopen("d.c", "w")); \
             }
S(T(S(p)))

ตรวจสอบว่ามันทำงาน:

$ gcc -o d d.c
# a lot of warning and notes from gcc ... 
$ ./d 10
$ diff -s d.c 9/8/7/6/5/4/3/2/1/0/d.c
Files d.c and 9/8/7/6/5/4/3/2/1/0/d.c are identical

มีความเป็นไปได้มากที่สุดในการเล่นกอล์ฟในซอร์สโค้ด


การใช้งานพรีโปรเซสเซอร์ดีเยี่ยม!
LeFauve

5

รุ่นที่ - 48 * 0.9 = 43.2

for /l %%a in (1,1,%1)do md %%a&cd %%a&move..\%0

สคริปต์นี้สร้างไดเรกทอรีใหม่และย้ายไฟล์ต้นฉบับไป - nครั้ง

H:\MyDocuments\uprof\top>embed.bat 5

     ...

H:\MyDocuments\uprof\top>tree /f
Folder PATH listing for volume DATA009_HOMES
Volume serial number is B88B-384C
H:.
└───1
    └───2
        └───3
            └───4
                └───5
                        embed.bat

5

Zsh, 63 60 58 52 * 0.9 = 56.7 54 52.2 46.8

s=$(<$0);for i in {1..$1};{mkdir $i;cd $i};echo $s>f

ตัวอย่าง:

llama@llama:...Code/misc/foo$ zsh f 5
llama@llama:...Code/misc/foo$ ls -R
.:
d1  f

./d1:
d2

./d1/d2:
d3

./d1/d2/d3:
d4

./d1/d2/d3/d4:
d5

./d1/d2/d3/d4/d5:
f
llama@llama:...Code/misc/foo$ cat d1/d2/d3/d4/d5/f 
s=$(cat $0);for i in {1..$1};do;mkdir d$i;cd d$i;done;echo $s>f
llama@llama:...Code/misc/foo$ cat f
s=$(cat $0);for i in {1..$1};do;mkdir d$i;cd d$i;done;echo $s>f
llama@llama:...Code/misc/foo$ diff f d1/d2/d3/d4/d5/f
llama@llama:...Code/misc/foo$

UUOC s=$(<$0) (สำหรับบันทึกนั้นมันล้มเหลวสำหรับฉันด้วยbash4.3.11: "ข้อผิดพลาดทางไวยากรณ์ใกล้กับโทเค็นที่ไม่คาดคิด`; '"แต่ทำงานได้ดีกับzsh5.0.2)
จัดการ

คุณสามารถบันทึกตัวละครโดยการลบออกdก่อนหน้า$i?
Canadian Luke ติดตั้ง MONICA ใหม่

@CanadianLuke 1ฮะผมไม่เคยรู้ว่าคุณจะได้ไดเรกทอรีชื่อ ขอบคุณ
Doorknob

for i in {1..$1};{mkdir $i;cd $i};echo $s>fฉันคิดว่าคุณควรจะสามารถใช้วงเล็บปีกกา:
Ry-

@ U2744SNOWFLAKE ขอบคุณที่บันทึกไว้สองสามไบต์ แก้ไข
Doorknob

3

Rebol - 114 * 0.9 * 0.5 = 51.3

do b:[d: copy %./ repeat n do input[mkdir repend d[n"/"]]write join d s: system/options/script join"do b: "mold b]

Ungolfed:

do b: [
    d: copy %./
    repeat n do input [
        mkdir repend d [n "/"]
    ]
    write join d s: system/options/script join "do b: " mold b
]


เวอร์ชั่นที่ไม่ใช่ควินดั้งเดิม - 90 * 0.9 = 81

d: %./ repeat n do input[mkdir repend d[n"/"]write join d s: system/options/script read s]

Ungolfed:

d: %./
repeat n do input [
    mkdir repend d [n "/"]
]
write join d s: system/options/script read s

2

Bash 167 * 0.5 * 0.9 = 75.15

การยืมอย่างหนักจากคำตอบที่ยอดเยี่ยมของ @ es1024แต่อันนี้เป็นจริงอย่างแท้จริงดังนั้นจึงมีคุณสมบัติสำหรับโบนัสทั้งสอง

b=\' c=\\ a='d=`seq -s/ $1`;mkdir -p $d;echo b=$c$b c=$c$c a=$b$a$b>>$d/$0;echo $a>>$d/$0'
d=`seq -s/ $1`;mkdir -p $d;echo b=$c$b c=$c$c a=$b$a$b>>$d/$0;echo $a>>$d/$0

นอกจากนี้เปลือกเทคนิคควินจากที่นี่


1

AutoIt3, 106 * 0,9 = 95,4 ไบต์


ค่อนข้างยาว แต่ฉันไม่สามารถช่วยชื่อฟังก์ชัน / ตัวแปรเหล่านั้นได้:

$f = @WorkingDir
For $i = 1 To $CmdLine[1]
    $f &= "\" & $i
Next
DirCreate($f)
FileCopy(@ScriptFullPath, $f)

เพียงแค่เรียกมันด้วย<script/.exe name> <depth>เช่น script.exe 5.
มันจะทำงานในจำนวนไดเรกทอรีใด ๆ ; อาจมากกว่าระบบไฟล์ของคุณสามารถจัดการได้ : D

มันทำงานอย่างไร:

มันเป็นเพียงลูปธรรมดาที่เพิ่มดัชนีลงในสตริง จากนั้นไดเรกทอรี (และไดเรกทอรีหลักทั้งหมดด้วย) จะถูกสร้างขึ้นและไฟล์จะคัดลอกตัวเองไปยังไดเรกทอรีนั้น


1

Node.js, 136 133 * 0.9 * 0.5 = 61.2 59.85

r=require,f=r('fs'),p=__dirname;while(i=process.argv[2]--)f.mkdirSync(p+='/'+i);f.linkSync(a=__filename,p+'/'+r('path').basename(a))

fs.linkSyncแม็พกับลิงก์โทร POSIX ซึ่งสร้างลิงก์ถาวร อาร์กิวเมนต์ที่ไม่ถูกต้องจะทำให้โปรแกรมขัดข้อง


1

J, 82 * 0.9 = 73.8

นี่เป็นส่วนหนึ่งของคำตอบที่ได้รับการโหวตสูงสุด

exit (1!:1[1{A) 1!:2 <] (s,'/',>1{A)[fpathcreate s=:' /'charsub":1+i.".>{:A=:ARGV

บันทึกเป็นskittish.ijsหรืออะไรก็ตามที่คุณต้องการและเรียกมันจากบรรทัดคำสั่งโดยใช้เวอร์ชันของjconsoleคุณ ฉันเป็น symlinked ไปที่jc:

$ jc skittish.ijs 20
$ ls 1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/skittish.ijs 
1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/20/skittish.ijs

0

Zsh , 55 * 0.9 * 0.5 = 24.75 ไบต์

ฉันรอดูความท้าทายนี้มานาน แต่ฉันต้องการทำให้สำเร็จใน Zsh โดยไม่ต้องเรียกโปรแกรมภายนอกใด ๆ เช่นmkdirและln(ไม่เช่นนั้นมันจะเหมือนกับโซลูชัน bash) ปรากฎว่า Zsh สามารถจัดทำโปรแกรมเหล่านั้นในเวอร์ชั่นของตัวเอง!

zmodload zsh/files
mkdir -p ${(j:/:):-{1..$1}}
ln $0 $_

ลองออนไลน์!

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