Program Skittish

17

Objektif

Anda harus menulis sebuah program yang menerima integer nsebagai input (dari baris perintah), dan menyematkan dirinya sendiri (program) ndirektori ke bawah pohon direktori. Contoh dengan n=5:

Contoh dengan n = 5

Nama folder mungkin apa pun yang Anda inginkan. Satu-satunya persyaratan adalah bahwa kedalamannya benar, dan bahwa program kemudian dapat dijalankan kembali dari tempat barunya di pohon direktori, dan bahwa file sumber baru mempertahankan nama file yang sama.

Bonus:

  • Nilai * 0,9 Jika semua direktori memiliki nama yang berbeda (harus benar setidaknya hingga kedalaman 1 000 000)
  • Nilai * 0,5 Jika Anda tidak secara langsung atau tidak langsung membaca atau memindahkan file sumber, atau mengakses kode sumber program
globby
sumber
1
Apa yang dianggap sebagai " membaca sumber "? Maksudmu file itu? Atau kode sumber yang sebenarnya?
GiantTree
2
@unclemeat Tidak, karena untuk memindahkan file Anda (atau sistem) harus mengakses data dalam file.
Globby
25
Sepertinya Anda hanya berusaha menyembunyikan simpanan porno Anda.
Ablue
3
@globby bagaimana dengan lnperintah di * nix? Jika saya tidak salah, itu hanya membuat entri lain ke file inode, dan tidak ada konten yang dibaca sama sekali.
hjk
7
@ globby Sejauh yang saya ketahui, memindahkan file tidak membaca konten, kecuali jika Anda bergerak di antara hard drive atau partisi. Ini pada dasarnya hanya mengubah beberapa petunjuk dalam sistem file.
Martin Ender

Jawaban:

36

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

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

Membawa kedalaman sebagai argumen pertama. Membuat tautan keras ke dirinya sendiri ke dalam struktur direktori berikut:

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

Skrip kemudian dapat dijalankan dari lokasi baru, bahkan jika rmdijalankan pada skrip lama.

Penjelasan:

seq -s/ $1menampilkan angka dari 1 hingga $1(argumen pertama), dipisahkan oleh garis miring.

mkdir -p `seq -s` $1membuat direktori yang ditentukan oleh seq, dengan -pmembuat semua direktori perantara.

ln $0 $_ buat tautan keras ke skrip berjalan saat ini di direktori yang baru dibuat.

Lama (30 * 0,9 = 27):

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

Contoh run (with 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

Berkat @DigitalTrauma untuk saran untuk mengganti $(..)dengan`..`

Terima kasih kepada @hjk atas saran untuk menggunakan ln.

es1024
sumber
6
Penggunaan brilian $_!
wchargin
2
Simpan char - gunakan backticks alih-alih $( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma
2
Bergantung pada jawaban atas komentar saya pada pertanyaan , mungkin ganti cpdengan lnuntuk mendapatkan bonus 0,5 juga ...
hjk
2
Wells, ada pembaruan dari OP sekarang, dan mvjuga dibatasi dari 0,5 bonus itu. Itu masih menyisakan lnjelas, ya?
hjk
2
Ya, ln(Anda tidak perlu -s) akan benar-benar menempatkan program di direktori baru, sehingga dapat dijalankan dari sana, tanpa pernah membaca, memindahkan, atau mengakses sumber aslinya. Saya katakan pergi untuk skor FALCON PUNCH 13,5!
Tobia
12

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

Solusi saya di 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)))

Di sini, dalam bentuk yang agak lebih mudah dibaca:

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

Cek apakah berfungsi:

$ 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

Kemungkinan besar ada banyak potensi golf dalam kode sumber.

MarcDefiant
sumber
Penggunaan preprocessor yang luar biasa!
LeFauve
5

Gelombang - 48 * 0,9 = 43.2

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

Script ini hanya membuat direktori baru, dan memindahkan file sumber ke sana - nkali.

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
hapus clemeat
sumber
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

Contoh:

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$
Gagang pintu
sumber
UUOC s=$(<$0) (Hanya untuk catatan, itu gagal bagi saya dengan bash4.3.11: "kesalahan sintaks dekat token tak terduga`; '". Tapi berfungsi dengan baik dengan zsh5.0.2)
manatwork
Bisakah Anda menyimpan karakter dengan menghapus dsebelumnya $i?
Luke Kanada REINSTATE MONICA
@ CanadianLuke Huh, saya tidak pernah tahu Anda bisa memiliki direktori bernama 1. Terima kasih
Gagang Pintu
Saya pikir Anda harus dapat menggunakan kurung keriting: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry-
@ U2744SNOWFLAKE Terima kasih, itu menghemat beberapa byte. Diedit.
Gagang Pintu
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]

Tidak Disatukan:

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


Versi non-quine asli - 90 * 0,9 = 81

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

Tidak Disatukan:

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

Bash 167 * 0,5 * 0,9 = 75,15

Meminjam banyak dari jawaban hebat @ es1024 , tapi yang ini adalah quine yang sebenarnya, sehingga memenuhi syarat untuk kedua bonus.

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

Juga, teknik shell quine dari sini .

Trauma Digital
sumber
1

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


Agak panjang tapi saya tidak bisa membantu dengan nama fungsi / variabel panjang itu:

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

Sebut saja dengan <script/.exe name> <depth>mis. script.exe 5.
Ini akan bekerja untuk sejumlah direktori; mungkin bahkan lebih dari yang dapat ditangani oleh sistem file Anda. : D

Bagaimana itu bekerja:

Itu hanya loop sederhana yang menambahkan indeks ke string. Kemudian direktori (dan semua direktori induk juga) dibuat dan file menyalin dirinya ke direktori itu.

GiantTree
sumber
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.linkSyncpeta ke tautan panggilan POSIX , yang menciptakan tautan keras. Argumen yang tidak valid akan menyebabkan program macet.

cPu1
sumber
1

J, 82 * 0,9 = 73,8

Ini sebagian besar merupakan port dari jawaban terpilih teratas.

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

Simpan sebagai skittish.ijsatau apa pun yang Anda inginkan, dan panggil dari baris perintah menggunakan versi Anda jconsole. Milik saya disinkronkan dengan 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
hoosierEE
sumber
0

Zsh , 55 * 0,9 * 0,5 = 24,75 byte

Saya sudah lama melihat tantangan ini, tetapi saya ingin menyelesaikannya di Zsh tanpa memanggil program eksternal seperti mkdirdan ln(jika tidak, itu akan identik dengan solusi bash). Ternyata, Zsh dapat menyediakan versi programnya sendiri!

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

Cobalah online!

Fungsi Gamma
sumber