Rosetta Stone Challenge: Codificação de Execução v2.0

8

O objetivo do Rosetta Stone Challenge é escrever soluções no maior número possível de idiomas. Mostre seu multilinguismo de programação!

O desafio

Nós fizemos a codificação run-length ser tona mas apenas considerado corridas de um único personagem. Obviamente, às vezes podemos economizar ainda mais se considerarmos a execução de vários caracteres.

Tome aaaxyzxyzxyzddddpor exemplo. Isso pode ser compactado para 3a3{xyz}4d. Sua tarefa é escrever um programa de função que, dada uma sequência de letras e espaços com distinção entre maiúsculas e minúsculas, o comprima de maneira otimizada usando a codificação de comprimento de execução para execuções com vários caracteres.

Você pode receber informações por meio do argumento da função, STDIN ou ARGV e retornar o resultado ou imprimi-lo em STDOUT.

Execuções não devem ser aninhadas, portanto , nãoaaabbbaaabbb devem . Ou seja, a string deve ser codificada (ou decodificada) em uma única passagem.3a3b3a3b 2{3a3b}

Consequências da compressão ideal

Alguns exemplos em que a aplicação ingênua da codificação de duração da execução pode levar a resultados abaixo do ideal:

  • abab não deve ser "compactado" para 2{ab}
  • aaaabcdeabcdenão deve ser compactado, 4abcdeabcdemas em 3a2{abcde}vez disso.

Se houver duas versões ótimas (por exemplo, aae 2aou abcabce 2{abc}), qualquer resultado será bom.

Exemplos

Input              Output

aa                 aa -or- 2a
aaaaaAAAAA         5a5A
ababa              ababa
abababa            a3{ba} -or- 3{ab}a
foo foo bar        2{foo }bar
aaaabcdeabcde      3a2{abcde}
xYzxYz             xYzxYz -or- 2{xYz}
abcabcdefcdef      abcab2{cdef}
pppqqqpppqqq       3p3q3p3q
pppqqqpppqqqpppqqq 3{pppqqq}

Pontuação

Cada idioma é uma competição separada sobre quem pode escrever a entrada mais curta, mas o vencedor geral será a pessoa que vencer a maioria dessas subcompetições. Isso significa que uma pessoa que responde em vários idiomas incomuns pode obter uma vantagem. O código de golfe é principalmente um desempate para quando há mais de uma solução em um idioma: a pessoa com o programa mais curto recebe crédito por esse idioma.

Se houver empate, o vencedor será a pessoa com o maior número de finalizações em segundo lugar (e assim por diante).

Regras, restrições e notas

Mantenha todos os seus diferentes envios contidos em uma única resposta.

Além disso, não há travessuras com basicamente a mesma resposta em dialetos de idiomas ligeiramente diferentes. Eu serei o juiz sobre quais submissões são diferentes o suficiente.

Classificação atual

Esta seção será atualizada periodicamente para mostrar o número de idiomas e quem lidera em cada um.

  • C # (265) - edc65
  • JavaScript (206) - edc65
  • Python (214) - Vontade
  • VB.NET (346) - edc65

Classificação do usuário atual

  1. edc65 (3)
  2. Will (1)
Martin Ender
fonte

Respostas:

1

JavaScript (E6) 206

Quase certo de que é o ideal. Começo a tentar codificar a string mais longa com o ganho máximo e codificamos recursivamente o que resta à esquerda e à direita. Após cada tentativa, mantenho o resultado mais curto.

Notas de golfe (JS específico)

  • Pseudo argumentos em vez de locais (para recursão)
  • Compare comprimentos usando o índice fora dos limites que fornece 'indefinido'
R=(s,n=s,d=s.length>>1,w,i,j,c)=>{
  for(;d;--d){
    for(i=-1;s[d+d+i++];){
      w=s.slice(i,j=i+d);
      for(r=1;w==s.substr(j,d);j+=d)++r;
      c=d>1?r+'{'+w+'}':r+w,
      // c[d*r-1]|| /* uncomment this line (+10 bytes) to have faster response
      n[(c=R(s.slice(0,i))+c+R(s.slice(j))).length]&&(n=c)
    }
  }
  return n
}

Teste no console do FireFox / FireBug

;['aa','aaaaaAAAAA','ababa','abababa','foo foo bar', 'aaaabcdeabcde',
  'xYzxYz', 'abcabcdefcdef', 'pppqqqpppqqq','pppqqqpppqqqpppqqq']
.forEach(x=>console.log(x+' -> '+R(x)))

Resultado

aa -> aa
aaaaaAAAAA -> 5a5A
ababa -> ababa
abababa -> 3{ab}a
foo foo bar -> 2{foo }bar
aaaabcdeabcde -> 3a2{abcde}
xYzxYz -> xYzxYz
abcabcdefcdef -> abcab2{cdef}
pppqqqpppqqq -> 3p3q3p3q
pppqqqpppqqqpppqqq -> 3{pppqqq}

C # (.NET 4.0) 265

Exatamente o mesmo algoritmo

string R(string s)
{
  string n=s,c,w;
  int l=s.Length,d=l/2,i,j,r;
  for(;d>0;--d)
  {
    for(i=0;d+d+i<=l;i++)
    {
      w=s.Substring(i,d);
      for(j=i+d,r=1;j+d<=l&&w==s.Substring(j,d);j+=d)++r;
      c=d>1?r+"{"+w+"}":r+w;
      // if(c.Length<d*r){ // uncomment this line for faster execution
        c=R(s.Substring(0,i))+c+R(s.Substring(j));
        n=c.Length<n.Length?c:n;
      //} // and this one of course
    }
  }
  return n;
}

Teste no LinqPad, modo 'programa C #', adicione um main após a função R

void Main()
{
  string[] test = {"aa","aaaaaAAAAA","ababa","abababa","foo foo bar","aaaabcdeabcde",
  "xYzxYz","abcabcdefcdef","pppqqqpppqqq","pppqqqpppqqqpppqqq"};
  test.Select(x => new { x, r=R(x) }).Dump("Result");
}

Mesma saída

VB.Net (.NET 4) 346 (provavelmente)

Mesmo algoritmo e mesma biblioteca, mas a linguagem é diferente o suficiente

Não tenho certeza sobre a contagem de bytes, pois o Visual Studio continua reformatando o código e adicionando espaços.

Notas de golfe: melhor usar outra coisa

function R(s as string)

  dim n=s,c,w
  dim l=s.Length,i,j,d
  for d=l\2 to 1 step-1
    for i=0 to l-d-d
      w=s.Substring(i,d)
      j=i+d
      r=1
      do while (j+d<=l andalso w=s.Substring(j,d))
        r=r+1
        j=j+d
      loop
      c=if(d>1,r & "{" & w & "}",r & w)
      if(c.Length<d*r) then
        c=R(s.Substring(0,i))+c+R(s.Substring(j))
        if c.Length<n.Length then n=c
      end if
    next
  next
  return n

end function
edc65
fonte
Você pode desfazer a adição de espaços. Se você digitar um caractere que o reformate, pressione ctrl-z para desfazer a formatação. Significa dois caracteres em vez de um de vez em quando, mas é melhor do que remover todos os espaços e feeds de linha posteriormente.
Jerry Jeremiah
3

Python 214

def t(s):
 b=s;l=len;r=range(1,l(s))
 for i in r:
  p=s[:i];b=min(b,p+t(s[i:]),key=l);x=1
  for j in r:k=i*j+i;x*=p==s[i*j:k];b=min(b,(b,''.join((`j+1`,"{"[i<2:],p,"}"[i<2:],t(s[k:]))))[x],key=l)           
 return b

(recuo do segundo nível é tab)

Como esse é o , essa é a abordagem recursiva ingênua sem saída antecipada, portanto é realmente muito lenta.

Vai
fonte