Ein scheußliches Programm


17

Zielsetzung

Sie müssen ein Programm schreiben, das eine Ganzzahl nals Eingabe empfängt (von der Befehlszeile) und sich selbst (das Programm) nVerzeichnisse im Verzeichnisbaum einbettet . Beispiel mit n=5:

Beispiel mit n = 5

Die Ordnernamen können beliebig sein. Die einzigen Voraussetzungen sind, dass die Tiefe korrekt ist und dass das Programm an seiner neuen Stelle im Verzeichnisbaum erneut ausgeführt werden kann und dass die neue Quelldatei denselben Dateinamen behält.

Boni:

  • Punktzahl * 0.9 Wenn die Verzeichnisse alle einen anderen Namen haben (muss mindestens bis zur Tiefe 1 000 000 zutreffen)
  • Punktzahl * 0,5 Wenn Sie die Quelldatei nicht direkt oder indirekt lesen, verschieben oder auf den Quellcode des Programms zugreifen

1
Was zählt als " Lesen der Quelle "? Du meinst die Akte? Oder der echte Quellcode?
GiantTree

2
@unclemeat Tut es, weil Sie (oder das System) auf die Daten in der Datei zugreifen müssen, um die Datei zu verschieben.
Globby

25
Scheint, als würdest du nur versuchen, deinen Pornostack zu verstecken.
Ablue

3
@globby wie wäre es mit dem lnbefehl in * nix? Wenn ich mich nicht irre, wird nur ein weiterer Eintrag für die Datei inode erstellt, und es wird überhaupt kein Inhalt gelesen.
hjk

7
@globby Wenn Sie eine Datei verschieben, wird der Inhalt meines Wissens nicht gelesen, es sei denn, Sie wechseln zwischen Festplatten oder Partitionen. Im Grunde werden nur einige Zeiger im Dateisystem geändert.
Martin Ender

Antworten:


36

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

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

Nimmt Tiefe als erstes Argument. Erstellt eine feste Verknüpfung zu sich selbst in der folgenden Verzeichnisstruktur:

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

Das Skript kann dann am neuen Speicherort ausgeführt werden, auch wenn rmes mit dem alten Skript ausgeführt wird.

Erläuterung:

seq -s/ $1gibt die Zahlen von 1 bis $1(das erste Argument) aus, getrennt durch einen Schrägstrich.

mkdir -p `seq -s` $1erstellt das von angegebene Verzeichnis seq, -pwobei alle Zwischenverzeichnisse erstellt werden.

ln $0 $_ Erstellen Sie eine feste Verknüpfung zum aktuell ausgeführten Skript im neu erstellten Verzeichnis.

Alt (30 * 0,9 = 27):

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

Beispiellauf (mit 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

Vielen Dank an @DigitalTrauma für den Vorschlag zum Ersetzen $(..)durch`..`

Danke an @hjk für den Vorschlag ln.


6
Genialer Einsatz von $_!
wchargin

2
Speichern Sie ein Zeichen - verwenden Sie Backticks anstelle von $( ): codegolf.stackexchange.com/a/25572/11259
Digitales Trauma

2
Abhängig von der Antwort auf meinen Kommentar zu der Frage , ersetzen Sie sie vielleicht cpmit ln, um auch den 0,5-Bonus zu erhalten ...
hjk

2
Nun, es mvgibt jetzt das Update vom OP und der Bonus von 0,5 ist ebenfalls eingeschränkt. Das bleibt doch lnklar, ja?
hjk

2
Ja, ln(Sie brauchen es nicht -s) würde das Programm tatsächlich in das neue Verzeichnis stellen, so dass es von dort ausgeführt werden kann, ohne jemals seine ursprüngliche Quelle zu lesen, zu verschieben oder darauf zuzugreifen. Ich sage, gehen Sie für den FALCON PUNCH Score von 13,5!
Tobia

12

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

Meine Lösung 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)))

Hier in etwas besser lesbarer Form:

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

Die Prüfung, ob es funktioniert:

$ 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

Im Quellcode steckt höchstwahrscheinlich viel Potenzial zum Golfen.


Großartige Nutzung des Präprozessors!
LeFauve,

5

Charge - 48 × 0,9 = 43,2

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

Dieses Skript erstellt einfach ein neues Verzeichnis und verschiebt die Quelldatei in dieses Verzeichnis 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

Beispiel:

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) (Nur zur bashVeranschaulichung , es schlägt für mich mit 4.3.11 fehl: "Syntaxfehler in der Nähe von unerwartetem Token"; ". Funktioniert aber gut mit zsh5.0.2)
manatwork

Könnten Sie ein Zeichen speichern die durch Entfernen dvor $i?
Kanadier Luke REINSTATE MONICA

@CanadianLuke Huh, ich hätte nie gedacht, dass du ein Verzeichnis mit dem Namen haben könntest 1. Danke
Türklinke

Ich glaube , Sie sollten in der Lage sein , geschweifte Klammern zu verwenden: for i in {1..$1};{mkdir $i;cd $i};echo $s>f.
Ry

@ U2744SNOWFLAKE Danke, das hat ein paar Bytes gespart. Bearbeitet
Türklinke

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
]


Ursprüngliche nicht quine Version - 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


1

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


Ein bisschen lang, aber ich kann nicht mit diesen langen Funktions- / Variablennamen helfen:

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

Rufen Sie es einfach mit <script/.exe name> <depth>zB. script.exe 5.
Es funktioniert für eine beliebige Anzahl von Verzeichnissen. Vielleicht sogar mehr, als Ihr Dateisystem verarbeiten kann. : D

Wie es funktioniert:

Es ist nur eine einfache Schleife, die den Index zu einer Zeichenfolge hinzufügt. Dann wird das Verzeichnis (und auch alle übergeordneten Verzeichnisse) erstellt und die Datei kopiert sich in dieses Verzeichnis.


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.linkSyncKarten zu dem POSIX Anruf Link , der eine feste Verbindung schafft. Ein ungültiges Argument führt zum Absturz des Programms.


1

J 82 * 0,9 = 73,8

Dies ist größtenteils ein Port der am häufigsten gewählten Antwort.

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

Speichern skittish.ijsSie die Datei wie gewünscht und rufen Sie sie über die Befehlszeile mit Ihrer Version von auf jconsole. Meins ist verbunden mit 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

Ich hatte diese Herausforderung lange im Auge, aber ich wollte sie in Zsh abschließen, ohne externe Programme wie mkdirund aufzurufen ln(ansonsten wäre sie identisch mit der Bash-Lösung). Es stellte sich heraus, dass Zsh seine eigenen Versionen dieser Programme zur Verfügung stellen kann!

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

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.