O StickStack é uma linguagem de programação muito simples, baseada em pilha, com apenas duas instruções:
|
empurra o comprimento da pilha para a pilha-
exibe os dois principais elementos da pilha e diminui a diferença (second topmost - topmost
)
Detalhes do idioma
- A pilha está vazia no início do programa.
- Todas as instruções são executadas seqüencialmente da esquerda para a direita.
- Se houver menos de 2 números na pilha, a
-
instrução é ilegal. - No final da execução, a pilha deve conter exatamente um número .
Qualquer número inteiro pode ser gerado por um programa StickStack. Por exemplo:
|||--||-- generates the number 2 through the following stack states:
[]
[0]
[0, 1]
[0, 1, 2]
[0, -1]
[1]
[1, 1]
[1, 1, 2]
[1, -1]
[2]
Para avaliar seu código StickStack, você pode usar este avaliador online (CJam) . (Obrigado por @Martin pelo código.)
A tarefa
Você deve escrever um programa ou função que tenha fornecido um número inteiro como saída ou retorne uma string que representa um programa StickStack que gera o número fornecido.
Pontuação
- Sua pontuação principal é a duração total dos programas StickStack para os casos de teste abaixo. Menor pontuação é melhor.
- Seu envio é válido apenas se você executou seu programa em todos os casos de teste e contou sua pontuação.
- Sua pontuação secundária (desempate) é a duração do seu programa ou função de geração.
Casos de teste de entrada
(Cada número é um caso de teste diferente.)
-8607 -6615 -6439 -4596 -4195 -1285 -72 12 254 1331 3366 3956 5075 5518 5971 7184 7639 8630 9201 9730
Seu programa deve funcionar para quaisquer números inteiros (que seu tipo de dados possa manipular) e não apenas para os casos de teste fornecidos. As soluções para os números de teste não devem ser codificadas no seu programa. Se houver dúvida de codificação, os números de teste serão alterados.
fonte
Respostas:
Python 2 - 5188
Bastante eficiente em termos de tempo e parece (provavelmente) a solução ideal. Eu observei que um padrão como
|||||-|||-|-|-|------
(uma solução ideal para 25)pode ser delineado como
onde cada valor total no final é a soma de (o valor de cada nível multiplicado pelo número de '|'). Então, por exemplo acima, nós temos
-1*1 + 2*1 - 3*1 + 4*2 - 5*1 + 6*4 = 25
. Usando isso, escrevi esta solução que produz resultados semelhantes a outras respostas e em uma quantidade trivial de tempo.Acredito que esta é a solução ideal, pois testo todas as alturas ideais possíveis (na verdade, testo muito mais que o necessário) e tenho certeza de que a solução sempre envolve no máximo uma camada com dois '|' s além do último (eu posso garanta isso para números positivos, mas não 100% certo de negativos).
Aqui está o código que eu usei para testá-lo
fonte
Java, 5208
524053066152Essa é uma função recursiva que se aproxima do alvo, com casos básicos para quando chega a 5 (o que geralmente é apenas uma etapa).
Basicamente, você pode obter
(a*b)+(a/2)
para(a+b)*2
varas com um padrão simples. Sea
for ímpar, o resultado será negativo, o que leva a uma lógica estranha.Isso leva um minuto ou mais para 2 31 -1, com uma duração de 185.367 como resultado. Porém, ele funciona quase instantaneamente em todos os casos de teste. Ele pontua
4*(sqrt|n|)
em média. O caso de teste individual mais longo é o9730
que resulta em uma pilha de 397 pés:Atualizar:
Foi encontrada uma maneira mais curta de adicionar / subtrair do padrão básico. De volta à liderança (por enquanto)!
Com um chicote de fios e casos de teste:
Golf (mais) no improvável evento de um empate exato.
fonte
JavaScript (ES6) 5296
6572Editar Como eu disse na minha explicação, não sou bom em resolver equações inteiras. Meu palpite sobre o valor de b não foi tão bom, então ampliei o intervalo de valores para tentar.
E (uau) eu estou liderando agora.Editar 2 Correção de bug, mesmos resultados. Eu tenho uma ideia, mas não posso dizer nada.
Bytes: ~ 460, bastante jogado. Funciona em números inteiros de 32 bits, com tempo de execução próximo de 0.
O código é a função F (oculta no snippet) abaixo.
Execute o snippet para testar (no FireFox).
Mostrar snippet de código
Explicação
Números positivos, para começar. Comece com uma "base" (tente no CJam, se quiser, espaços permitidos)
Resumo: 1 stick, depois b * 2 sticks e, em seguida, b * 2 traços
Em seguida, tente adicionar um ou mais '- |' na divisão do meio. Cada um adiciona um incremento fixo que é duas vezes a base inicial e pode ser repetido várias vezes. Portanto, temos uma fórmula, com b = base er = incremento do fator de repetição
Vejo? O valor dos addes aumenta rapidamente e cada adição ainda tem apenas 2 caracteres. O incremento base fornece mais 4 caracteres por vez.
Dado v e nossa fórmula v = b + r * 2 * b, precisamos encontrar 2 ints b e r. Não sou especialista nesse tipo de equação, mas b = int sqrt (v / 2) é um bom palpite inicial.
Então temos um r e b que juntos dão um valor próximo de v. Atingimos v exatamente com incremento repetido (|| -) ou decremento (| -).
Siga o mesmo raciocínio para números negativos, infelizmente a fórmula é semelhante, mas não é igual.
fonte
JavaScript, 398710
94 bytes / caracteres de código
Eu vim com uma solução! ... e depois leia a resposta de Sparr e era exatamente a mesma.
Imaginei que eu publicaria de qualquer maneira, já que o js permite um pouco menos de caracteres.
Aqui está uma versão não minificada do código:
fonte
Python, 398710 (71 bytes)
Solução mais simples possível, eu acho. Usa 4 * n (+/- 1) caracteres do stickstack para representar n.
fonte