Un programa asustadizo


17

Objetivo

Debe escribir un programa que reciba un número entero ncomo entrada (desde la línea de comando) y que incorpore los ndirectorios (el programa) en el árbol de directorios. Ejemplo con n=5:

Ejemplo con n = 5

Los nombres de las carpetas pueden ser lo que desee. Los únicos requisitos son que la profundidad sea correcta, y que el programa pueda ejecutarse nuevamente desde su nuevo lugar en el árbol de directorios, y que el nuevo archivo fuente conserve el mismo nombre de archivo.

Bonificaciones:

  • Puntuación * 0.9 Si todos los directorios tienen un nombre diferente (debe ser verdadero al menos hasta la profundidad de 1 000 000)
  • Puntuación * 0.5 Si no lee o mueve directa o indirectamente el archivo fuente, o no accede al código fuente del programa

1
¿Qué cuenta como " leer la fuente "? ¿Te refieres al archivo? ¿O el código fuente real?
GiantTree

2
@unclemeat lo hace, porque para mover el archivo usted (o el sistema) tiene que acceder a los datos en el archivo.
globby

25
Parece que solo estás tratando de ocultar tu escondite porno.
Ablue el

3
@globby, ¿qué tal el lncomando en * nix? Si no me equivoco, solo está creando otra entrada al inodo del archivo, y no se lee ningún contenido.
hjk

77
@globby Hasta donde yo sé, mover un archivo no lee el contenido, a menos que se mueva entre discos duros o particiones. Básicamente, solo está cambiando algunos punteros en el sistema de archivos.
Martin Ender

Respuestas:


36

Bash, 30 * 0.9 * 0.5 = 13.5

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

Toma profundidad como primer argumento. Crea un enlace rígido a sí mismo en la siguiente estructura de directorios:

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

El script se puede ejecutar desde la nueva ubicación, incluso si rmse ejecuta en el script anterior.

Explicación:

seq -s/ $1genera los números del 1 al $1(primer argumento), separados por una barra diagonal.

mkdir -p `seq -s` $1crea el directorio especificado por seq, con la -pcreación de todos los directorios intermedios.

ln $0 $_ cree un enlace fijo al script actual en ejecución en el directorio recién creado.

Viejo (30 * 0.9 = 27):

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

Ejemplo de ejecución (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

Gracias a @DigitalTrauma por la sugerencia de reemplazar $(..)con`..`

Gracias a @hjk por su sugerencia de uso ln.


66
Uso brillante de $_!
wchargin

2
Ahorre una char - use backticks en lugar de $( ): codegolf.stackexchange.com/a/25572/11259
Digital Trauma

2
Dependiendo de la respuesta a mi comentario sobre la pregunta , tal vez reemplace cpcon lnpara obtener el bono 0.5 también ...
hjk

2
Wells, ahora está la actualización del OP, y mvtambién está restringido de ese bono de 0.5. Eso todavía queda lnen claro, ¿sí?
hjk

2
Sí, ln(no es necesario -s) colocaría el programa en el nuevo directorio, de modo que se pueda ejecutar desde allí, sin leer, mover o acceder a su fuente original. ¡Digo ve por el puntaje FALCON PUNCH de 13.5!
Tobia

12

C, 225 * 0.9 * 0.5 = 101.25

Mi solución 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)))

Aquí en una forma algo más legible:

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

El cheque si funciona:

$ 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

Lo más probable es que haya mucho potencial de golf en el código fuente.


Gran uso del preprocesador!
LeFauve

5

Lote - 48 * 0.9 = 43.2

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

Este script simplemente crea un nuevo directorio y mueve el archivo fuente a él, varias nveces.

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

Ejemplo:

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) (Sólo para que conste, se produce un error para mí con bash4.3.11: “error de sintaxis cerca inesperada símbolo`; '”Pero funciona bien con. zsh5.0.2)
manatwork

¿Podrías salvar a un personaje eliminando el dantes $i?
Canadian Luke REINSTATE MONICA

@CanadianLuke Huh, nunca supe que podría tener un directorio llamado 1. Gracias
Pomo de la puerta

Creo que debería ser capaz de utilizar llaves: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry-

@ U2744SNOWFLAKE Gracias, eso ahorró algunos bytes. Editado
Pomo de la puerta

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]

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


Versión original no quine - 90 * 0.9 = 81

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

Sin 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

Tomando mucho de la gran respuesta de @ es1024 , pero esta es una verdadera quine, por lo que califica para ambos bonos.

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

Además, las técnicas de shell quine de aquí .


1

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


Un poco largo pero no puedo ayudar con esos nombres largos de funciones / variables:

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

Simplemente llámalo con <script/.exe name> <depth>eg.script.exe 5.
Funcionará para cualquier cantidad de directorios; tal vez incluso más de lo que su sistema de archivos puede manejar. :RE

Cómo funciona:

Es solo un bucle simple que agrega el índice a una cadena. Luego, se crea el directorio (y también todos los directorios principales) y el archivo se copia en ese directorio.


1

Nodo.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.linkSyncse asigna al enlace de llamada POSIX , que crea un enlace duro. Un argumento no válido hará que el programa se bloquee.


1

J, 82 * 0.9 = 73.8

Esto es principalmente un puerto de la respuesta más votada.

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

Guarde como skittish.ijso lo que quiera, y llámelo desde la línea de comandos usando su versión de jconsole. El mío está vinculado 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 bytes

Estuve atento a este desafío durante mucho tiempo, pero quería completarlo en Zsh sin llamar a ningún programa externo como mkdiry ln(de lo contrario, sería idéntico a la solución bash). Resulta que Zsh puede proporcionar sus propias versiones de esos programas.

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

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.