Objetivo
Escrever uma rotina que aceita uma cadeia de caracteres ASCII imprimíveis, é , e retorna um string contendo os mesmos caracteres que s , reordenadas de modo que não há dois caracteres substring aparece mais de uma vez. O programa deve processar todas as seqüências de referência (veja abaixo) em menos de um minuto cada, em um computador moderno . Também concederei um bônus especial de 50 repetições à resposta de pontuação mais baixa que processa qualquer sequência válida de 30 caracteres em menos de um minuto.
Por exemplo, dada a entrada Mississippi
, uma saída válida seria issiMspiips
(nenhuma substring de dois caracteres aparecerá duas vezes), enquanto uma saída inválida seria ipMsispiiss
(já que a substring is
aparece duas vezes).
A rotina pode assumir a forma de:
- uma leitura completa do programa
stdin
(ou equivalente) ou da linha de comando e saída parastdout
(ou equivalente) - uma função que aceita um argumento de string única e retorna uma string
Você pode assumir que a sequência de entrada sempre admite pelo menos uma saída válida.
O desafio
Sua rotina deve incluir 5 ou mais linhas de código separadas por novas linhas. Linhas vazias (que incluem linhas contendo apenas espaço em branco) são ignoradas em todos os contextos e não contam para a contagem total de linhas.
A troca de duas linhas no seu código-fonte deve gerar um erro fatal. Por "erro fatal", nos referimos a qualquer uma das seguintes condições:
- o código fonte falha ao compilar, com o compilador / intérprete declarando um erro fatal
- a rotina é interrompida com um erro fatal de tempo de execução ou uma exceção de tempo de execução não tratada
- a rotina é forçada a um encerramento abrupto e anormal do programa que não produz nenhum tipo de saída, exceto por uma possível mensagem de erro e / ou despejo de pilha
Como alternativa , blocos contíguos de código que não contêm caracteres de nova linha podem ser usados no lugar de linhas. Esses blocos devem ser exibidos em sua própria linha no arquivo de origem, com o entendimento de que as novas linhas são removidas antes que o código-fonte seja compilado / interpretado.
Por exemplo, o código
aaaa
bbbb
cccc
condensaria a
aaaabbbbcccc
antes de ser avaliado.
Nesse modo, a condição de erro fatal se aplica à troca de dois blocos de código (e, portanto, à troca de linhas no código-fonte antes que as novas linhas sejam removidas). Daí, no exemplo acima as rotinas aaaaccccbbbb
, bbbbaaaacccc
e ccccbbbbaaaa
deve produzir todos os erros fatais, quer no compiletime ou tempo de execução.
Os envios que usam esse modo alternativo devem declarar seu uso.
Pontuação
Seja n o número de linhas de texto não vazias no seu arquivo de origem, com n ≥ 5. Seja c o número de bytes compreendidos pela linha de texto mais longa (pelo comprimento de bytes) no seu arquivo de origem, sem contar nenhuma nova linha à direita.
A pontuação de uma submissão é dada por c ( n + 10).
A finalização com a menor pontuação é a vencedora.
Boa sorte. ;)
Benchmark Strings
Abracadabra Alacazam
Is Miss. Mississauga Missing?
Ask Alaska's Alaskans
GGGGAAAATTTTCCCCgggaaatttccc
A Man A Plan A Canal Panama
CooliO
, saídaoOoCli
?Mspiisiipss
válido, pois a única repetição é aii
que não ocorreMississippi
?Respostas:
PHP, pontuação = 289 (17 × (7 + 10))
As funções integradas do PHP facilitam bastante isso. O código a seguir apenas embaralha a sequência até que um resultado válido seja obtido:
Benchmarks
Tempos médios e máximos de execução calculados usando o seguinte código:
Resultados:
* Alterei
ä
paraa
evitar problemas de vários bytes† Essa foi a string mais difícil de 30 caracteres que eu consegui criar. Na verdade, são os primeiros 30 caracteres da sequência De Bruijn para k = 'abcdef' e n = 2, com o primeiro 'b' movido para evitar uma correspondência instantânea.
fonte
Dyalog APL (11 (5 + 10) = 165)
Prova:
⍵
fora de uma função, que é aSYNTAX ERROR
.b
, portanto, não pode ser trocada por linhas3
ou das4
quais dependemb
. Haveria umVALUE ERROR
. (E isso, obviamente, não pode ser trocado com1
ou5
qualquer um.)c
, portanto, não pode ser trocada por linha4
, da qual dependec
. (E já provamos que nenhuma outra linha pode ser trocada por linha3
.)fonte
APL (Dyalog), 6 (5 + 10) = 90
Estou usando a alternativa, então:
Este é o mesmo algoritmo antigo.
A explicação
2,/⍵
fornece que uma matriz de pares de caracteres na sequência de entrada+/∘.≡⍨
gera uma matriz numérica de quantos pares cada par é igual (incluindo a si próprio)1∧.=
verifica se cada elemento dessa matriz é igual a 1 e AND lógico os resultados juntos:⍵
Se isso for verdade (1
), retorne a string de entrada∇⍵[?⍨⍴⍵]
caso contrário, embaralhe a sequência de entrada e faça uma chamada recursivaTroca
Se a linha 1 é trocada pela linha 2, você acaba com
+/∘.≡⍨{...}
uma bagunça de funções e operadores que forneceSYNTAX ERROR
.Se a linha 1 for trocada pela linha 3 ou 4, você terá
⍵
fora de uma definição de função, e isso é aSYNTAX ERROR
.Se a linha 1 for trocada pela linha 5, somente chaves não-balanceadas causariam
SYNTAX ERROR
, portanto, não se preocupe com os outros quatro erros de sintaxe.Se a linha 5 for trocada pela linha 2/3/4, novamente você terá
⍵
fora de uma definição de função. (SYNTAX ERROR
)Se a linha 2 for trocada pela linha 3, você terminará
1∧.=2,/⍵:⍵
. Essa sintaxe é chamada de guarda (pense nela como condicional). A condição de guarda deve avaliar para0
ou1
ou uma matriz de 1 elemento de0
ou1
. Aqui, ele avalia algo mais complexo que isso (um escalar contendo uma matriz de 2 elementos). Então este é umDOMAIN ERROR
.Se a linha 2 for trocada pela linha 4, você obtém a instrução
1∧.=
, que tenta aplicar a função∧.=
sem o argumento esquerdo necessário. (SYNTAX ERROR
)Se a linha 3 for trocada pela linha 4, novamente você terá uma confusão de funções e operadores (
1∧.=+/∘.≡⍨
)SYNTAX ERROR
.Valores de referência
(números em milissegundos)
Ainda estou pensando em diferentes separações. Também tenho uma maneira sistemática e determinística de executar a tarefa. Eu simplesmente não consigo transformá-lo em um algoritmo (retire a parte criativa de "acertar os números") e não posso garantir que funcione sempre.
fonte
Haskell, 129 = 3x (33 + 10)
isso usa o modo alternativo.
ou de forma legível:
Haskell é uma linguagem muito estrita. por exemplo, o
import
deve vir primeiro; as definições des
devem se unir; todos os tipos devem concordar e não há como lançar entre eles, e assim por diante. isso leva a ter um erro não fatal quase impossível. de fato, ter um erro fatal em tempo de execução é quase quase impossível.note que se
g
é uma função válida, mas tem um tipo errado (qualquer tipo diferente de então[a]->[a]
ouString -> String
similar), isso é um erro fatal, porque é impossível aplicarg
às entradas.saídas:
fonte