Un programma skittish


17

Obbiettivo

Devi scrivere un programma che riceve un numero intero ncome input (dalla riga di comando) e incorpora le ndirectory stesse (il programma) nella struttura della directory. Esempio con n=5:

Esempio con n = 5

I nomi delle cartelle possono essere quelli che desideri. L'unico requisito è che la profondità sia corretta e che il programma possa essere eseguito nuovamente dal suo nuovo punto nella struttura di directory e che il nuovo file di origine mantenga lo stesso nome file.

bonus:

  • Punteggio * 0.9 Se tutte le directory hanno un nome diverso (deve essere vera almeno fino a profondità 1 000 000)
  • Punteggio * 0,5 Se non si legge o sposta direttamente o indirettamente il file sorgente o non si accede al codice sorgente del programma

1
Cosa conta come " leggere la fonte "? Intendi il file? O il vero codice sorgente?
GiantTree

2
@unclemeat Lo fa, perché per spostare il file tu (o il sistema) devi accedere ai dati nel file.
globby

25
Sembra che tu stia solo cercando di nascondere la tua scorta di porno.
Ablue,

3
@globby che ne dici del lncomando in * nix? Se non sbaglio, sta solo creando un'altra voce nell'inode del file e nessun contenuto viene letto affatto.
HJK

7
@globby Per quanto ne so, lo spostamento di un file non legge il contenuto, a meno che non ci si muova tra dischi rigidi o partizioni. Fondamentalmente sta solo cambiando alcuni puntatori nel file system.
Martin Ender,

Risposte:


36

Bash, 30 * 0.9 * 0.5 = 13.5

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

Approfondisce come primo argomento. Crea un collegamento reale a se stesso nella seguente struttura di directory:

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

Lo script può quindi essere eseguito dalla nuova posizione, anche se rmviene eseguito sul vecchio script.

Spiegazione:

seq -s/ $1genera i numeri da 1 a $1(il primo argomento), separati da una barra.

mkdir -p `seq -s` $1crea la directory specificata da seq, con la -pcreazione di tutte le directory intermedie.

ln $0 $_ creare un collegamento reale allo script corrente in esecuzione nella directory appena creata.

Vecchio (30 * 0.9 = 27):

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

Esempio di esecuzione (con 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

Grazie a @DigitalTrauma per il suggerimento di sostituire $(..)con`..`

Grazie a @hjk per il suggerimento da usare ln.


6
Uso brillante di $_!
mercoledì

2
Salva un carattere - usa i backtick invece di $( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma

2
A seconda della risposta al mio commento sulla domanda , magari sostituirlo cpcon lnper ottenere anche il bonus 0,5 ...
hjk

2
Bene, ora c'è l'aggiornamento dall'OP, ed mvè anche limitato da quel bonus di 0,5. Ciò lascia ancora lnin chiaro, sì?
HJK

2
Sì, ln(non è necessario -s) collocherebbe effettivamente il programma nella nuova directory, in modo che possa essere eseguito da lì, senza mai leggere, spostare o accedere alla sua fonte originale. Dico di andare per il punteggio FALCON PUNCH di 13,5!
Tobia,

12

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

La mia soluzione in 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)))

Qui in una forma un po 'più leggibile:

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

Il controllo se funziona:

$ 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

Molto probabilmente c'è molto potenziale di golf nel codice sorgente.


Ottimo uso del preprocessore!
LeFauve,

5

Lotto - 48 * 0.9 = 43.2

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

Questo script crea semplicemente una nuova directory e sposta il file sorgente in essa - nvolte.

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

Esempio:

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) (Solo per la cronaca, non riesce per me con bash4.3.11: "errore di sintassi vicino al token inaspettato`; '”. Ma funziona bene con zsh5.0.2)
manatwork

Potresti salvare un personaggio rimuovendo il dprima $i?
Canadian Luke REINSTATE MONICA

@CanadianLuke Huh, non ho mai saputo che potresti avere una directory chiamata 1. Grazie
Maniglia

Penso che si dovrebbe essere in grado di utilizzare le parentesi graffe: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry,

@ U2744SNOWFLAKE Grazie, che ha salvato alcuni byte. Modificato.
Maniglia della porta

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
]


Versione originale non quine - 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

Prendendo in prestito pesantemente dalla grande risposta di @ es1024 , ma questa è una vera quina, quindi si qualifica per entrambi i 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

Inoltre, le tecniche di shell quine da qui .


1

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


Un po 'lungo ma non posso fare a meno di quei nomi lunghi di funzioni / variabili:

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

Chiamalo semplicemente con <script/.exe name> <depth>es. script.exe 5.
Funzionerà per qualsiasi numero di directory; forse anche più di quanto il tuo file system possa gestire. : D

Come funziona:

È solo un semplice ciclo che aggiunge l'indice a una stringa. Quindi viene creata la directory (e anche tutte le directory principali) e il file si copia in quella directory.


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.linkSyncesegue il mapping al collegamento di chiamata POSIX , che crea un collegamento reale. Un argomento non valido provoca l'arresto anomalo del programma.


1

J, 82 * 0,9 = 73,8

Questa è principalmente una porta della risposta più votata.

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

Salva come skittish.ijso come vuoi e chiamalo dalla riga di comando usando la tua versione di jconsole. Il mio è collegato a 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

Ho avuto gli occhi su questa sfida per molto tempo, ma volevo completarla in Zsh senza chiamare programmi esterni come mkdire ln(altrimenti, sarebbe identica alla soluzione bash). Si scopre che Zsh è in grado di fornire le proprie versioni di questi programmi!

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

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.