Código avançado Golf - operações de disco e alocação de arquivos

8

Boa tarde Golfgeneers.

Esta é uma pergunta razoavelmente longa e detalhada. Dado o que estava pedindo, precisava ser. Se você tiver alguma dúvida, pergunte a eles. Se houver algo que não esteja claro, me avise para que eu possa corrigi-lo. Provavelmente, este é o lado mais difícil do codegolf.

Estamos construindo um computador leve e precisamos do sistema de arquivos com menor peso possível. O código mais curto será escolhido.

Estamos fornecendo um disco rígido de ponta de 65536 bytes. Para esse protótipo, será um arquivo de imagem direta, que seu programa pode assumir que exista, e esteja no local que melhor lhe convier - ou seja, um arquivo binário representando todo o disco rígido. Você pode assumir que esta imagem já está 'formatada' - ie. se o seu programa depende de algo estar no arquivo para funcionar, pode ser. Se você precisar que o estado vazio inicial seja algo diferente de todos os zeros, indique o que é.

Não há limite de memória para a RAM usada pelo seu aplicativo.

Os comandos de entrada e saída exigirão uma interface para o disco rígido real. Como a imagem do disco, seu programa pode assumir que o arquivo de entrada existe e está onde você deseja. Da mesma forma, seu programa pode ser produzido sempre que for conveniente. No entanto, ele deve fechar o arquivo após executar o comando de entrada ou saída.

Você não está recebendo um formato que deve ser usado para a imagem do disco - você pode desenvolver o seu próprio. Ele deve ser capaz de armazenar até 248 arquivos. Qualquer arquivo com mais de 256 bytes pode contar como um novo arquivo para esse limite a cada 256 bytes ou parte dele. Um arquivo pode ter até 63488 bytes. Basicamente - ele deve ser tão capaz quanto um disco rígido com 248 setores de 256 bytes cada.

O raciocínio por trás desses tamanhos aparentemente é fornecer 2048 bytes de 'administração' - para armazenar detalhes dos arquivos. Cada arquivo / pasta deve estar acessível com um nome de 4 caracteres alfanuméricos, que podem fazer distinção entre maiúsculas e minúsculas ou sem distinção de acordo com sua preferência. Se o seu programa suportar nomes de 4 ou menos caracteres, haverá um bônus de um multiplicador de 0,95.

Seu programa deve aceitar, via stdin, os seguintes comandos. Os parâmetros serão separados por um espaço. O comando será encerrado por uma nova linha.

  • L - Liste os nomes para stdout de todos os arquivos atuais e seus tamanhos em bytes, separados por novas linhas.
  • C ab - Copie o arquivo a para o novo arquivo b.
  • D a - Excluir arquivo a
  • R ab - renomeia o arquivo a para o novo nome b
  • I a - Adiciona o arquivo de entrada (veja a nota acima) como arquivo a
  • O a - Arquivo de saída a para o arquivo de saída

Os seguintes erros podem ser relatados ao STDOUT ou STDERR como motivos válidos para a falha na execução de um comando. Você pode optar por imprimir apenas ERR # onde # é o número do erro:

  • 1 - O arquivo não existe
  • 2 - O arquivo já existe
  • 3 - Sem espaço *

* Observe que seu programa não pode emitir isso apenas porque está sem espaço contínuo. Se você ainda tiver setores disponíveis, deverá desfragmentar o disco para fazê-lo funcionar.

Um sistema de pastas é opcional - no entanto, gera um bônus de um multiplicador de 0,8 na sua pontuação. Se ele suportar mais de um nível de diretório, ele renderá um bônus de um multiplicador de 0,7 (não além do 0,8). Para o bônus, você deve ter

  • L, R, C e D funcionam apenas dentro do diretório atual. L deve listar pastas no diretório atual, bem como os arquivos.
  • Novo comando M ab move o arquivo a para a pasta b. Se b for '.', Move o arquivo para o diretor pai
  • O novo comando G a vai para a pasta a. Se a for '.', Vai para a pasta pai
  • R também deve renomear pastas
  • D também deve excluir pastas e quaisquer arquivos / pastas dentro delas
  • C também deve copiar pastas e quaisquer arquivos / pastas dentro delas

Os seguintes erros adicionais podem ser relatados ao STDOUT ou STDERR como motivos válidos para a falha na execução de um comando.

  • 4 - Pasta não existe
  • 5 - Arquivo, não é necessário pasta - onde, I e O exigem nomes de arquivo, e uma pasta foi fornecida

Sua pontuação é:

  • O tamanho, em bytes, do seu código-fonte
  • Multiplicado por

    • 0,95 se você suportar nomes de 4 ou menos caracteres
    • 0.8 se você suportar um único nível de pastas
    • 0,7 se você suportar vários níveis de pastas
    • 0,95 se você suportar comandos (não necessariamente nomes de arquivos) em letras minúsculas ou maiúsculas

Boa sorte.

Lochok
fonte
Estou disposto a conceder licenças para idiomas que não suportam algo exigido por esse desafio. Infelizmente, acho que não posso fazê-lo funcionar apenas através dos parâmetros da linha de comando do GolfScript.
lochok
2
Parece complexo o suficiente para precisar de um bom conjunto de testes.
Peter Taylor
Vou começar a trabalhar em um - mas pode não ser hoje feito
lochok
Os multiplicadores de pontuação são compostos?
Jdstankosky
Composto. Observe que você só pode obter um nível único ou vários níveis de pastas.
lochok

Respostas:

3

Ruby, 505,4 pontos (560 caracteres)

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

Notas:

  • O sistema de arquivos está localizado no arquivo Fno diretório atual. Fdeve existir e podem ser criados / formatado através do seguinte comando: IO.write('F',(([""]*248)+([0]*248)+[""]).pack('A4'*248+'s'*248+'A63488')).
  • O arquivo de entrada Itambém está sempre no diretório atual, o arquivo de saída está O.
  • Como não era necessário verificar erros, digite os comandos corretos (por exemplo, sem comandos não suportados, sem argumentos ausentes, nomes de arquivos muito longos).
  • A implementação do sistema de arquivos é extremamente simples - para cada comando, o disco rígido completo é lido na memória e reconstruído após a conclusão (bem-sucedida).

Bônus:

  • Os nomes de arquivos podem ter de 1 a 4 caracteres
  • Os comandos podem estar em maiúsculas ou minúsculas

O código ainda não está totalmente disponível, mas já mostra que, para uma pontuação substancialmente melhor, eu tentaria uma abordagem completamente diferente.

Sessão de teste (apenas STDIN / STDOUT é mostrado, mas é claro que cada comando é anexado ao chamar o programa acima):

> 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
fonte
3

Tcl, pontuação 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]]}

Bônus (precisa pegar todos):

  • suporta nomes de arquivos com 4 bytes ou menos - ou mais. Eu não ligo 0,95
  • suporte a pastas multinível 0,7
  • suporta comandos em maiúsculas e minúsculas 0,95

Limitações conhecidas:

  • O sistema de arquivos Fjá deve existir. Espaço vazio ou em branco está bom.
  • Não verifico o tamanho do sistema de arquivos - não me importo.
  • O arquivo de entrada é i, o arquivo de saída é oe o sistema de arquivos está emF
  • Erros travarão o programa.
  • Não verifica se existe arquivo / diretório, pode haver um erro.
  • Não há diferença entre um arquivo e um diretório. Sim, você pode escrever um diretório para saída e usá-lo como sistema de arquivos.
  • Usar um arquivo como diretório que não é um sistema de arquivos válido resultará em um erro.
  • Nenhuma validação de entrada. Comandos inválidos podem gerar um erro. Ou não:eval puts [expr 1+2]
  • Nenhum comando para criar um diretório (não foi minha ideia), mas será criado implícito por I(também não é minha ideia e Gnão cria)
  • G não valida o diretório.
  • Os nomes de arquivos podem conter espaços, mas a interface não os suporta.
  • A modificação simultânea do mesmo sistema de arquivos não é suportada.

Alguns hacks:

  • eval puts $c -> diretório atual, separado por espaços.
  • exit - sem comentários.
  • lappend c . -> alterna para o subdiretório .
Johannes Kuhn
fonte
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)

O disco é salvo no formato pickle do Python: para criar um disco vazio, é necessário colocar esses dois bytes '}.' no início e, opcionalmente, 65534 preenchem os bytes posteriormente. Suporta nomes de arquivos grandes arbitrários (* 0,95), comandos em maiúsculas e minúsculas (* 0,95) e links físicos (:-).

Daniel
fonte