Advanced Code Golf - Festplattenbetrieb und Dateizuordnung

8

Guten Tag Golfgeneers.

Dies ist eine ziemlich lange und detaillierte Frage. Angesichts dessen, was es verlangte, musste es sein. Wenn Sie Fragen haben, stellen Sie diese bitte. Wenn etwas nicht klar ist, benachrichtigen Sie mich bitte, damit ich es beheben kann. Dies ist wahrscheinlich auf der härteren Seite des Codegolfs.

Wir bauen einen leichten Computer und benötigen das leichteste Dateisystem, das möglich ist. Der kürzeste Code wird ausgewählt.

Wir bieten eine innovative 65536-Byte-Festplatte. Für diesen Prototyp handelt es sich um eine direkte Image-Datei, von der Ihr Programm annehmen kann, dass sie existiert, und die sich an einem für Sie geeigneten Speicherort befindet - dh eine Binärdatei, die die gesamte Festplatte darstellt. Sie können davon ausgehen, dass dieses Bild bereits "formatiert" ist - dh. Wenn Ihr Programm darauf angewiesen ist, dass etwas in der Datei funktioniert, kann dies der Fall sein. Wenn der anfängliche leere Zustand etwas anderes als Null sein soll, geben Sie bitte an, was er ist.

Es gibt keine Speicherbeschränkung für den von Ihrer Anwendung verwendeten RAM.

Die Eingabe- und Ausgabebefehle erfordern eine Schnittstelle zur eigentlichen Festplatte. Wie das Disk-Image kann Ihr Programm davon ausgehen, dass die Eingabedatei vorhanden ist und sich dort befindet, wo Sie sie haben möchten. Ebenso kann Ihr Programm überall dort ausgeben, wo es Ihnen passt. Es muss jedoch die Datei schließen, nachdem der Eingabe- oder Ausgabebefehl ausgeführt wurde.

Sie erhalten kein Format, das Sie für das Disc-Image verwenden müssen - Sie können Ihr eigenes Format entwickeln. Es muss in der Lage sein, bis zu 248 Dateien zu speichern. Jede Datei, die größer als 256 Byte ist, kann aufgrund dieser Begrenzung für jeweils 256 Byte oder einen Teil davon als neue Datei gezählt werden. Eine Datei kann bis zu 63488 Byte umfassen. Grundsätzlich muss es so leistungsfähig sein wie eine Festplatte mit 248 Sektoren mit jeweils 256 Bytes.

Der Grund für diese scheinbaren Größen besteht darin, Ihnen 2048 Byte 'Administration' zu geben - um Details der Dateien zu speichern. Auf jede Datei / jeden Ordner muss über einen Namen mit 4 alphanumerischen Zeichen zugegriffen werden. Je nach Wunsch kann zwischen Groß- und Kleinschreibung unterschieden werden. Wenn Ihr Programm Namen mit 4 oder weniger Zeichen unterstützt, gibt es einen Bonus von 0,95.

Ihr Programm muss über stdin die folgenden Befehle akzeptieren. Parameter werden durch ein Leerzeichen getrennt. Der Befehl wird durch eine neue Zeile beendet.

  • L - Listen Sie die Namen aller aktuellen Dateien und ihre Größe in Bytes auf, die durch Zeilenumbrüche getrennt sind.
  • C ab - Datei a in neue Datei kopieren b.
  • D a - Datei löschen a
  • R ab - Benennt Datei a in neuen Namen um. B.
  • I a - Fügt die Eingabedatei (siehe Hinweis oben) als Datei a hinzu
  • O a - Ausgabedatei a in die Ausgabedatei

Die folgenden Fehler können STDOUT oder STDERR als gültige Gründe für die Nichtausführung eines Befehls gemeldet werden. Sie können nur ERR # drucken, wobei # die Nummer des Fehlers ist:

  • 1 - Datei existiert nicht
  • 2 - Datei existiert bereits
  • 3 - Nicht genügend Platz *

* Beachten Sie, dass Ihr Programm dies nicht ausgeben kann, nur weil nicht genügend Speicherplatz vorhanden ist. Wenn noch Sektoren verfügbar sind, müssen Sie die Festplatte defragmentieren, damit sie funktioniert.

Ein Ordnersystem ist optional. Sie erhalten jedoch einen Bonus von 0,8 auf Ihre Punktzahl. Wenn es mehr als 1 Verzeichnisebene unterstützt, erhält es einen Bonus von 0,7 Multiplikatoren (nicht zusätzlich zu 0,8). Für den Bonus müssen Sie haben

  • L, R, C und D funktionieren nur im aktuellen Verzeichnis. L muss Ordner im aktuellen Verzeichnis sowie die Dateien auflisten.
  • Neuer Befehl M ab verschiebt Datei a in Ordner b. Wenn b '.' Ist, wird die Datei an den übergeordneten Direktor verschoben
  • Neuer Befehl G a geht zu Ordner a. Wenn a '.' Ist, wird zum übergeordneten Ordner gewechselt
  • R muss auch Ordner umbenennen
  • D muss auch Ordner und alle darin enthaltenen Dateien / Ordner löschen
  • C muss auch Ordner und alle darin enthaltenen Dateien / Ordner kopieren

Die folgenden zusätzlichen Fehler können STDOUT oder STDERR als gültige Gründe für die Nichtausführung eines Befehls gemeldet werden.

  • 4 - Ordner existiert nicht
  • 5 - Datei, kein Ordner erforderlich - wobei für I und O Dateinamen erforderlich sind und ein Ordner angegeben wurde

Dein Ergebnis ist:

  • Die Größe Ihres Quellcodes in Byte
  • Multipliziert mit

    • 0,95, wenn Sie Namen mit 4 oder weniger Zeichen unterstützen
    • 0.8, wenn Sie eine einzelne Ordnerebene unterstützen
    • 0.7 wenn Sie mehrere Ordnerebenen unterstützen
    • 0,95, wenn Sie Befehle (nicht unbedingt Dateinamen) in Klein- oder Großbuchstaben unterstützen

Viel Glück.

Lochok
quelle
Ich bin bereit, Sprachen zu berücksichtigen, die etwas nicht unterstützen, was für diese Herausforderung erforderlich ist. Leider glaube ich nicht, dass ich es nur über Befehlszeilenparameter für GolfScript zum Laufen bringen kann.
Lochok
2
Sieht komplex genug aus, um eine gute Testsuite zu benötigen.
Peter Taylor
Ich werde anfangen, an einem zu arbeiten - aber heute vielleicht nicht fertig
Lochok
Sind die Punktemultiplikatoren zusammengesetzt?
jdstankosky
Zusammengesetzt. Beachten Sie, dass Sie jedoch nur eine oder mehrere Ordnerebenen abrufen können.
Lochok

Antworten:

3

Ruby, Punktzahl 505,4 (560 Zeichen)

x,a,b=gets.chomp.split
f=IO.read('F')
e=f[0,4*X=248].unpack 'A4'*X
s=f[4*X,2*X].unpack 's'*X
d=f[6*X..-1].unpack 'A'+s*'A'
u,v,w,y=[[N=nil,q=e.index(a),!t=e.index(""),"e[t]=a;s[t]=(d[t]=IO.binread('I')).size"],[!q,r=e.index(b),!t,"e[t]=b;d[t]=d[q];s[t]=s[q]"],[!q,N,N,"e[q]=d[q]='';s[q]=0"],[!q,r,N,"e[q]=b"],[!q,N,N,"IO.binwrite('O',d[q])"],[N,N,N,'X.times{|i|e[i]>""&&puts(e[i]+" #{s[i]}")}']]['ICDROL'=~/#{x}/i]
u&&$><<"ERR1\n"||v&&$><<"ERR2\n"||w&&$><<"ERR3\n"||eval(y)
d=d*""
d.size>63488&&$><<"ERR3\n"||IO.write('F',(e+s+[d]).pack('A4'*X+'s'*X+'A63488'))

Anmerkungen:

  • Das Dateisystem befindet sich in der Datei Fim aktuellen Verzeichnis. Fmuss vorhanden sein und kann über den folgenden Befehl erstellt / formatiert werden : IO.write('F',(([""]*248)+([0]*248)+[""]).pack('A4'*248+'s'*248+'A63488')).
  • Die Eingabedatei befindet sich immer Iauch im aktuellen Verzeichnis, die Ausgabedatei ist O.
  • Da es nicht erforderlich war, Fehler zu überprüfen, müssen Sie die richtigen Befehle eingeben (dh keine nicht unterstützten Befehle, keine fehlenden Argumente, zu lange Dateinamen).
  • Die Implementierung des Dateisystems ist äußerst einfach: Für jeden Befehl wird die vollständige Festplatte in den Speicher eingelesen und nach (erfolgreichem) Abschluss neu erstellt.

Boni:

  • Dateinamen können 1-4 Zeichen sein
  • Befehle können in Groß- oder Kleinschreibung geschrieben werden

Der Code ist noch nicht vollständig golfen, zeigt aber bereits, dass ich für eine wesentlich bessere Punktzahl einen völlig anderen Ansatz ausprobieren würde.

Testsitzung (nur STDIN / STDOUT wird angezeigt, aber natürlich wird jedem Befehl durch Aufrufen des obigen Programms vorangestellt):

> L
> I F001
> L
F001 558
> I F001
ERR2
> C F002 F003
ERR1
> C F001 F003
> L
F001 558
F003 558
> C F001 F003
ERR2
> R F002 F003
ERR1
> R F001 F003
ERR2
> R F001 F002
> L
F002 558
F003 558
> O F001
ERR1
> O F002
> L
F002 558
F003 558
> D F001
ERR1
> D F002
> L
F003 558
> C F003 F001
> L
F001 558
F003 558
> D F001
> L
F003 558
> D F003
> L
Howard
quelle
3

Tcl, Punktzahl 487.711 (772 Bytes)

{*}[set a {interp alias {}}] s {} dict se f
{*}$a u {} dict un f
{*}$a h {} dict g
proc 0 {} {return -level 1}
proc p {n a b} {foreach l $n {proc $l $a "global f c;$b;S"}}
p L\ l {} {puts [join [dict k [h $f {*}$c]] \n]}
p C\ c a\ b {s {*}$c $b [h $f {*}$c $b]}
p D\ d a {u {*}$c $a}
p R\ r a\ b {s {*}$c $a [h $f {*}$c $b];u {*}$c $b}
p I\ i a {set i [open i rb];s {*}$c $a [read $i];close $i}
p O\ o a {set o [open o wb];chan puts $o [h $f {*}$c $a];close $o}
p M\ m a\ b {set d $c;if {$b eq "."} {set d [lrange $c 0 end-1]};s {*}$d $a [h $f {*}$c $a];u {*}$c $a}
p G\ g a {if {$a eq "."} {set c [lrange $c 0 end-1]} {lappend c $a}}
p S {} {puts [set o [open F wb]] $f;close $o;return}
set f [read [set i [open F rb]]]
close $i
set c {}
while 1 {{*}[split [gets stdin]]}

Boni (müssen sie alle fangen):

  • Unterstützt Dateinamen mit 4 Byte oder weniger - oder mehr. Es ist mir egal. 0,95
  • Unterstützung von mehrstufigen Ordnern 0.7
  • Unterstützung von Klein- und Großbuchstaben 0,95

Bekannte Einschränkungen:

  • Das Dateisystem Fmuss bereits vorhanden sein. Leer oder Leerzeichen sind in Ordnung.
  • Ich überprüfe nicht die Größe des Dateisystems - es ist mir egal.
  • Eingabedatei ist i, Ausgabedatei ist ound das Dateisystem ist inF
  • Fehler führen zum Absturz des Programms.
  • Keine Überprüfung, ob Datei / Verzeichnis vorhanden ist, könnte ein Fehler sein.
  • Kein Unterschied zwischen einer Datei und einem Verzeichnis. Ja, Sie können ein Verzeichnis für die Ausgabe schreiben und dieses als Dateisystem verwenden.
  • Die Verwendung einer Datei als Verzeichnis, das kein gültiges Dateisystem ist, führt zu einem Fehler.
  • Keine Eingabevalidierung. Ungültige Befehle können einen Fehler auslösen. Oder nicht:eval puts [expr 1+2]
  • Kein Befehl zum Erstellen eines Verzeichnisses (war nicht meine Idee), wird aber implizit von erstellt I(auch nicht meine Idee und Gwird nicht erstellt)
  • G überprüft das Verzeichnis nicht.
  • Dateinamen können Leerzeichen enthalten, die Schnittstelle unterstützt sie jedoch nicht.
  • Die gleichzeitige Änderung desselben Dateisystems wird nicht unterstützt.

Einige Hacks:

  • eval puts $c -> aktuelles Verzeichnis, durch Leerzeichen getrennt.
  • exit - kein Kommentar.
  • lappend c . -> wechselt in das Unterverzeichnis .
Johannes Kuhn
quelle
3

Python 2.7 373 (413 Bytes)

from pickle import*
E=exit;o=open;D,I,W='DIw'
def T(i):w[i]in d and E('ERR2')
d=load(o(D))
w=raw_input().split();b=w[0].upper()
if b=='L':
 for k in d:print k,len(d[k])
elif b==I:T(1);d[w[1]]=o(I).read()
else:
 a=w[1];a in d or E('ERR1')
 if b in'RC':T(2);d[w[2]]=(b<D and d.get or d.pop)(a)
 if b==D:d.pop(a)
 if b=='O':o(I,W).write(d[a])
d=dumps(d,-1)
x=65536-len(d)
x>-1or E('ERR3')
o(D,W).write(d+I*x)

Die Festplatte wird im Python-Pickle-Format gespeichert: Um eine leere Festplatte zu erstellen, müssen Sie diese beiden Bytes '}' einfügen. am Anfang und optional 65534 Bytes danach füllen. Unterstützt beliebig große Dateinamen (* 0,95), Groß- und Kleinbuchstaben (* 0,95) und Hardlinks (:-).

Daniel
quelle