Skittish Program


17

Cel

Masz napisać program, który otrzymuje liczbę całkowitą njako dane wejściowe (z wiersza poleceń) i osadza nkatalogi (program) w drzewie katalogów. Przykład z n=5:

Przykład z n = 5

Nazwy folderów mogą być dowolne. Jedyne wymagania to to, że głębokość jest prawidłowa, a program można następnie uruchomić ponownie z nowego miejsca w drzewie katalogów, a nowy plik źródłowy zachowuje tę samą nazwę pliku.

Bonusy:

  • Wynik * 0,9 Jeśli wszystkie katalogi mają inną nazwę (musi być prawdziwe przynajmniej do głębokości 1 000 000)
  • Wynik * 0,5 Jeśli nie czytasz bezpośrednio ani pośrednio pliku źródłowego, nie przenosisz go ani nie uzyskujesz dostępu do kodu źródłowego programu

1
Co liczy się jako „ czytanie źródła ”? Masz na myśli plik? Czy prawdziwy kod źródłowy?
GiantTree,

2
@ unclemeat Tak, ponieważ aby przenieść plik, ty (lub system) musisz uzyskać dostęp do danych w pliku.
globby,

25
Wygląda na to, że po prostu próbujesz ukryć swoją skrytkę porno.
Ablue,

3
@globby co powiesz na lnpolecenie w * nix? Jeśli się nie mylę, to po prostu tworzy kolejny wpis do i-węzła pliku i nie czyta się żadnej treści.
hjk

7
@globby O ile mi wiadomo, przenoszenie pliku nie odczytuje zawartości, chyba że przenosisz się między dyskami twardymi lub partycjami. To po prostu zmiana niektórych wskaźników w systemie plików.
Martin Ender

Odpowiedzi:


36

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

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

Pierwszym argumentem jest głębia. Tworzy twarde łącze do siebie w następującej strukturze katalogów:

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

Skrypt można następnie uruchomić z nowej lokalizacji, nawet jeśli rmjest on uruchamiany na starym skrypcie.

Wyjaśnienie:

seq -s/ $1wypisuje liczby od 1 do $1(pierwszy argument), oddzielone ukośnikiem.

mkdir -p `seq -s` $1tworzy katalog określony przez seq, -ptworząc wszystkie pośrednie katalogi.

ln $0 $_ utwórz twardy link do bieżącego działającego skryptu w nowo utworzonym katalogu.

Stare (30 * 0,9 = 27):

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

Przykład uruchomienia (z 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

Dzięki @DigitalTrauma do sugestii do wymiany $(..)z`..`

Dzięki @hjk za sugestię użycia ln.


6
Świetne wykorzystanie $_!
wchargin

2
Oszczędź char - użyj backticks zamiast $( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma

2
W zależności od odpowiedzi na mój komentarz na pytanie , może zamienić cpsię lndostać premię 0,5 zbyt ...
HJK

2
Wells, jest teraz aktualizacja OP, a mvtakże jest ograniczona do tej premii 0,5. To wciąż pozostaje lnjasne, tak?
hjk

2
Tak, ln(nie potrzebujesz -s) umieściłby program w nowym katalogu, aby można go było uruchomić stamtąd, bez czytania, przenoszenia ani uzyskiwania dostępu do jego oryginalnego źródła. Mówię, aby przejść do wyniku FALCON PUNCH 13,5!
Tobia,

12

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

Moje rozwiązanie w 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)))

Tutaj w nieco bardziej czytelnej formie:

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

Sprawdź, czy to działa:

$ 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

W kodzie źródłowym istnieje prawdopodobnie duży potencjał golfowy.


Świetne wykorzystanie preprocesora!
LeFauve,

5

Partia - 48 * 0,9 = 43,2

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

Ten skrypt po prostu tworzy nowy katalog i przenosi do niego plik źródłowy 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

Przykład:

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) (Dla przypomnienia , dla mnie nie działa z bash4.3.11: „błąd składni w pobliżu nieoczekiwanego zsh
tokena`

Czy możesz zapisać postać, usuwając dwcześniej $i?
Kanadyjczyk Luke REINSTATE MONICA

@CanadianLuke Huh, nigdy nie wiedziałem, że możesz mieć katalog o nazwie 1. Dzięki
Klamka

Myślę, że powinieneś być w stanie korzystać z nawiasów klamrowych: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry-

@ U2744SNOWFLAKE Dzięki, dzięki temu zaoszczędziłem kilka bajtów. Edytowane.
Klamka

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]

Nie golfowany:

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


Oryginalna wersja inna niż quine - 90 * 0,9 = 81

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

Nie golfowany:

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

Pożyczając dużo od świetnej odpowiedzi @ es1024 , ale ta jest prawdziwym quine, więc kwalifikuje się do obu bonusów.

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

Również techniki quine muszli stąd .


1

AutoIt3, 106 * 0,9 = 95,4 bajtów


Trochę długi, ale nie mogę pomóc z długimi nazwami funkcji / zmiennych:

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

Po prostu zadzwoń, używając <script/.exe name> <depth>np. script.exe 5.
Będzie działał dla dowolnej liczby katalogów; może nawet więcej niż twój system plików może obsłużyć. :RE

Jak to działa:

To tylko prosta pętla, która dodaje indeks do łańcucha. Następnie katalog (i wszystkie katalogi nadrzędne) zostaje utworzony, a plik kopiuje się do tego katalogu.


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.linkSyncodwzorowuje łącze wywołania POSIX , które tworzy stałe łącze. Nieprawidłowy argument spowoduje awarię programu.


1

J, 82 * 0,9 = 73,8

Jest to głównie część najczęściej głosowanej odpowiedzi.

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

Zapisz jako skittish.ijslub cokolwiek chcesz i wywołuj to z wiersza poleceń, używając swojej wersji jconsole. Mój jest dowiązany do 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 bajtów

Długo patrzyłem na to wyzwanie, ale chciałem je ukończyć w Zsh bez wywoływania programów zewnętrznych takich jak mkdiri ln(w przeciwnym razie byłoby to identyczne z rozwiązaniem bash). Okazuje się, że Zsh może dostarczać własne wersje tych programów!

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

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.