Một chương trình Skittish


17

Mục tiêu

Bạn phải viết một chương trình nhận một số nguyên nlàm đầu vào (từ dòng lệnh) và nhúng các nthư mục (chương trình) vào cây thư mục. Ví dụ với n=5:

Ví dụ với n = 5

Tên thư mục có thể là bất cứ điều gì bạn muốn. Yêu cầu duy nhất là độ sâu là chính xác và sau đó chương trình có thể được chạy lại từ vị trí mới của nó trong cây thư mục và tệp nguồn mới vẫn giữ nguyên tên tệp.

Tiền thưởng:

  • Điểm * 0,9 Nếu tất cả các thư mục có một tên khác nhau (ít nhất phải đúng với độ sâu 1 000 000)
  • Điểm * 0,5 Nếu bạn không trực tiếp hoặc gián tiếp đọc hoặc di chuyển tệp nguồn hoặc truy cập mã nguồn của chương trình

1
Điều gì được tính là " đọc nguồn "? Ý bạn là tập tin? Hoặc mã nguồn thực sự?
GiantTree

2
@unclemeat Nó làm như vậy, vì để di chuyển tệp bạn (hoặc hệ thống) phải truy cập dữ liệu trong tệp.
globalby

25
Có vẻ như bạn chỉ đang cố gắng để che giấu stash khiêu dâm của bạn.
Ablue

3
@globby làm thế nào về lnlệnh trong * nix? Nếu tôi không nhầm, đó chỉ là tạo một mục nhập khác cho tệp inode và không có nội dung nào được đọc cả.
hjk

7
@globby Theo như tôi biết, việc di chuyển một tệp không đọc được nội dung, trừ khi bạn di chuyển giữa các ổ đĩa cứng hoặc phân vùng. Về cơ bản, nó chỉ thay đổi một số con trỏ trong hệ thống tệp.
Martin Ender

Câu trả lời:


36

Bash, 30 * 0,9 * 0,5 = 13,5

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

Lấy chiều sâu làm đối số đầu tiên. Tạo một liên kết cứng đến chính nó vào cấu trúc thư mục sau:

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

Tập lệnh sau đó có thể được chạy từ vị trí mới, ngay cả khi rmđược chạy trên tập lệnh cũ.

Giải trình:

seq -s/ $1xuất các số từ 1 đến $1(đối số đầu tiên), được phân tách bằng dấu gạch chéo về phía trước.

mkdir -p `seq -s` $1tạo thư mục được chỉ định bởi seq, với -pviệc tạo tất cả các thư mục trung gian.

ln $0 $_ tạo một liên kết cứng đến tập lệnh đang chạy trong thư mục vừa tạo.

Cũ (30 * 0,9 = 27):

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

Chạy ví dụ (với 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

Cảm ơn @DigitalTrauma đã đề xuất thay thế $(..)bằng`..`

Cảm ơn @hjk đã gợi ý sử dụng ln.


6
Sử dụng tuyệt vời $_!
wchargein

2
Lưu một char - sử dụng backticks thay vì $( ): codegolf.stackexchange.com/a/25572/11259
Chấn thương kỹ thuật số

2
Tùy thuộc vào câu trả lời cho nhận xét của tôi về câu hỏi , có thể thay thế cpbằng lnđể nhận phần thưởng 0,5 quá ...
hjk

2
Wells, hiện tại đã có bản cập nhật từ OP và mvcũng bị hạn chế từ mức thưởng 0,5 đó. Điều đó vẫn còn lntrong sáng, có?
hjk

2
Có, ln(bạn không cần -s) thực sự sẽ đặt chương trình trong thư mục mới, để nó có thể được thực thi từ đó, mà không bao giờ đọc, di chuyển hoặc truy cập vào nguồn ban đầu của nó. Tôi nói hãy cho điểm FALCON PUNCH là 13,5!
Tobia

12

C, 225 * 0,9 * 0,5 = 101,25

Giải pháp của tôi trong 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)))

Ở đây trong một hình thức dễ đọc hơn:

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

Kiểm tra nếu nó hoạt động:

$ 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

Có lẽ có rất nhiều tiềm năng chơi gôn trong mã nguồn.


Công dụng tuyệt vời của tiền xử lý!
LeFauve

5

Mẻ - 48 * 0,9 = 43,2

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

Kịch bản lệnh này chỉ đơn giản là tạo một thư mục mới và di chuyển tệp nguồn tới nó - nlầ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

Thí dụ:

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) (Chỉ dành cho bản ghi, nó không thành công với bash4.3.11: Lỗi cú pháp gần mã thông báo không mong đợi `; ', nhưng hoạt động tốt với zsh5.0.2)
thao tác

Bạn có thể lưu một nhân vật bằng cách loại bỏ dtrước $i?
Luke Luke REINSTATE MONICA của Canada

@CanadianLuke Huh, tôi không bao giờ biết bạn có thể có một thư mục có tên 1. Cảm ơn
Doorknob

Tôi nghĩ bạn sẽ có thể sử dụng dấu ngoặc nhọn : for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry-

@ U2744SNOWFLAKE Cảm ơn, đã lưu một vài byte. Đã chỉnh sửa.
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]

Ung dung:

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


Phiên bản không quine gốc - 90 * 0.9 = 81

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

Ung dung:

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

Vay mượn rất nhiều từ câu trả lời tuyệt vời của @ es1024 , nhưng đây là một câu hỏi thực sự, vì vậy nó đủ điều kiện nhận cả hai phần thưởng.

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

Ngoài ra, kỹ thuật vỏ quine từ đây .


1

AutoIt3, 106 * 0,9 = 95,4 byte


Hơi dài một chút nhưng tôi không thể giúp với các tên hàm / biến dài đó:

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

Đơn giản chỉ cần gọi nó với <script/.exe name> <depth>ví dụ. script.exe 5.
Nó sẽ làm việc cho bất kỳ số lượng thư mục; thậm chí có thể nhiều hơn hệ thống tập tin của bạn có thể xử lý. : D

Làm thế nào nó hoạt động:

Nó chỉ là một vòng lặp đơn giản để thêm chỉ mục vào một chuỗi. Sau đó, thư mục (và tất cả các thư mục mẹ cũng vậy) được tạo và tệp tự sao chép vào thư mục đó.


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ánh xạ tới liên kết cuộc gọi POSIX , tạo ra một liên kết cứng. Một đối số không hợp lệ sẽ khiến chương trình bị sập.


1

J, 82 * 0,9 = 73,8

Đây chủ yếu là một cổng của câu trả lời được bình chọn hàng đầu.

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

Lưu dưới dạng skittish.ijshoặc bất cứ thứ gì bạn muốn và gọi nó từ dòng lệnh bằng phiên bản của bạn jconsole. Của tôi được liên kết với 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 byte

Tôi đã để mắt đến thử thách này trong một thời gian dài, nhưng tôi muốn hoàn thành nó trong Zsh mà không cần gọi bất kỳ chương trình bên ngoài nào như mkdirln(nếu không, nó sẽ giống hệt với giải pháp bash). Hóa ra, Zsh có thể cung cấp các phiên bản riêng của các chương trình đó!

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

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.