Un programme skittish


17

Objectif

Vous devez écrire un programme qui reçoit un entier nen entrée (à partir de la ligne de commande) et qui s'incorpore (le programme) ndans l'arborescence des répertoires. Exemple avec n=5:

Exemple avec n = 5

Les noms de dossier peuvent être ceux que vous souhaitez. Les seules conditions requises sont que la profondeur soit correcte et que le programme puisse ensuite être exécuté à nouveau à partir de son nouvel emplacement dans l'arborescence de répertoires, et que le nouveau fichier source conserve le même nom de fichier.

Bonus:

  • Score * 0,9 Si les répertoires ont tous un nom différent (doit être vrai au moins à 1 000 000 de profondeur)
  • Score * 0,5 Si vous ne lisez pas ou ne déplacez pas directement ou indirectement le fichier source, ou n'accédez pas au code source du programme

1
Qu'est-ce qui compte comme " lire la source "? Tu veux dire le fichier? Ou le vrai code source?
GiantTree

2
@unclemeat C'est le cas, car pour déplacer le fichier, vous (ou le système) devez accéder aux données du fichier.
globby

25
On dirait que vous essayez juste de cacher votre cachette porno.
Ablue

3
@globby que diriez-vous de la lncommande dans * nix? Si je ne me trompe pas, cela crée simplement une autre entrée dans l'inode du fichier, et aucun contenu n'est lu du tout.
hjk

7
@globby Pour autant que je sache, le déplacement d'un fichier ne lit pas le contenu, sauf si vous vous déplacez entre des disques durs ou des partitions. Il s'agit simplement de changer certains pointeurs dans le système de fichiers.
Martin Ender

Réponses:


36

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

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

Prend la profondeur comme premier argument. Crée un lien dur vers lui-même dans la structure de répertoires suivante:

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

Le script peut ensuite être exécuté à partir du nouvel emplacement, même s'il rmest exécuté sur l'ancien script.

Explication:

seq -s/ $1renvoie les nombres de 1 à $1(le premier argument), séparés par une barre oblique.

mkdir -p `seq -s` $1crée le répertoire spécifié par seq, en -pcréant tous les répertoires intermédiaires.

ln $0 $_ créer un lien dur vers le script en cours d'exécution dans le répertoire nouvellement créé.

Ancien (30 * 0,9 = 27):

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

Exemple d'exécution (avec 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

Merci à @DigitalTrauma pour la suggestion de remplacer $(..)par`..`

Merci à @hjk pour la suggestion d'utilisation ln.


6
Utilisation brillante de $_!
wchargin

2
Enregistrez un caractère - utilisez des astuces au lieu de $( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma

2
Selon la réponse à mon commentaire sur la question , peut-être le remplacer cppar lnpour obtenir le bonus de 0,5 aussi ...
hjk

2
Eh bien, il y a la mise à jour de l'OP maintenant, et mvest également limité à ce bonus de 0,5. Cela laisse toujours lnen clair, oui?
hjk

2
Oui, ln(vous n'avez pas besoin -s) placerait en fait le programme dans le nouveau répertoire, afin qu'il puisse être exécuté à partir de là, sans jamais lire, déplacer ou accéder à sa source d'origine. Je dis go pour le score FALCON PUNCH de 13,5!
Tobia

12

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

Ma solution en 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)))

Ici sous une forme un peu plus lisible:

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

La vérification si ça marche:

$ 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

Il y a très probablement beaucoup de potentiel de golf dans le code source.


Grande utilisation du préprocesseur!
LeFauve

5

Lot - 48 * 0,9 = 43,2

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

Ce script crée simplement un nouveau répertoire et y déplace le fichier source - nfois.

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

Exemple:

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) (Juste pour mémoire, il échoue pour moi avec bash4.3.11: "erreur de syntaxe près du jeton inattendu"; "". Mais fonctionne très bien avec zsh5.0.2)
manatwork

Pourriez-vous enregistrer un personnage en supprimant l' davant $i?
Canadian Luke REINSTATE MONICA

@CanadianLuke Huh, je ne savais pas que vous pourriez avoir un répertoire nommé 1. Merci
Poignée de porte

Je pense que vous devriez être en mesure d'utiliser des accolades: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry-

@ U2744SNOWFLAKE Merci d'avoir économisé quelques octets. Édité.
Poignée de porte

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]

Non golfé:

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


Version 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]

Non golfé:

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

Empruntant fortement à la grande réponse de @ es1024 , mais celle-ci est une vraie quine, donc elle se qualifie pour les deux 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

En outre, les techniques de shell quine d' ici .


1

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


Un peu long mais je ne peux pas m'empêcher avec ces longs noms de fonction / variable:

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

Appelez-le simplement avec <script/.exe name> <depth>par exemple. script.exe 5.
Cela fonctionnera pour n'importe quelle quantité de répertoires; peut-être même plus que ce que votre système de fichiers peut gérer. :RÉ

Comment ça fonctionne:

C'est juste une simple boucle qui ajoute l'index à une chaîne. Ensuite, le répertoire (et tous les répertoires parents également) est créé et le fichier se copie dans ce répertoire.


1

Node.js, 136133 * 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.linkSynccorrespond au lien d' appel POSIX , ce qui crée un lien dur. Un argument non valide entraînera le plantage du programme.


1

J, 82 * 0,9 = 73,8

Il s'agit principalement d'un port de la réponse la plus votée.

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

Enregistrez sous skittish.ijsou comme vous voulez, et appelez-le à partir de la ligne de commande en utilisant votre version de jconsole. Le mien est lié à 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 octets

J'avais les yeux sur ce défi depuis longtemps, mais je voulais le terminer dans Zsh sans appeler de programmes externes comme mkdiret ln(sinon, ce serait identique à la solution bash). Il s'avère que Zsh peut fournir ses propres versions de ces programmes!

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

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.