Texto de sabor
O baseado em pilha esolang Underload tem alguns laços interessantes para programação funcional. Um deles é o tratamento do tipo de dados numérico - como o cálculo lambda, você representa o número natural N por uma função que executa uma ação N vezes.
Para simplificar, consideraremos apenas o seguinte subconjunto de comandos Underload:
:
- Este comando duplica o item superior da pilha.*
- Este comando concatena os dois principais itens da pilha em um único item.
Definimos um número N de Subcarga como uma string :
e *
que, quando executado, consome o item superior na pilha e produzimos N cópias desse item concatenadas juntas. Alguns exemplos:
- Não há números de carga insuficiente 0, -1, 1/2, π.
- A cadeia vazia
é o número 1 de Carga insuficiente, porque deixa a pilha intocada.
:*
é o número 2 de Carga insuficiente, porque duplica o item superior e concatena essas duas cópias juntas em um único item:(A):*
=(A)(A)*
=(AA)
.::**
é o número 3 da subcarga:(A)::**
=(A)(A):**
=(A)(AA)*
=(AAA)
.:::***
é o número de Underload 4.:*:*
é também o número 4 da carga insuficiente:(A):*:*
=(AA):*
=(AA)(AA)*
=(AAAA)
.
Em geral, você encontrará que, se M
e N
são os números M de Subcarga M e N, então :N*
é o número N + 1 e MN
é o número M × N.
O desafio
Sua tarefa é escrever o programa mais curto (recebendo entrada em STDIN) ou a função (recebendo entrada por argumento) que produz a representação mais curta do número de Underload para sua entrada como uma string. Ou seja, se a entrada for um número natural positivo N> 1, você deverá produzir um número N de Subcarga N cujo comprimento em caracteres seja menor ou igual ao de qualquer outro número de Underload N.
Entradas e saídas de amostra: ("Input - OUTPUT
.")
- 1 -
.
- 2 -
:*
. - 5 -
::*:**
(2 × 2 + 1). - 7 -
::*::***
(2 × 3 + 1) ou:::**:**
(3 × 2 + 1). - 33 -
::*:*:*:*:**
(2 × 2 × 2 × 2 × 2 + 1). - 49 -
::*:*:*:*::***
(16 × 3 + 1, comprimento 14), mas não::*::***::*::***
(7 × 7, comprimento 16).
Se a entrada não for um número natural positivo, você poderá retornar um erro, produzir um comportamento indefinido ou até falhar ao finalizar. Uma explicação do método do seu envio de encontrar a resposta é apreciada.
Aplicam-se restrições de brecha padrão: nenhuma entrada extra, nenhuma solicitação da Web, valor de saída / retorno deve ser exatamente a resposta e não um fluxo aleatório infinito de :
e *
etc.
x
é2*A117498(x)
onde A117498 fornece a combinação ideal de métodos binários e de fatores para encontrar uma cadeia de adição.Respostas:
GolfScript (
61 60 55 5453 caracteres)Isso é menos complicado do que minha versão anterior e adota uma abordagem um pouco diferente, mas ainda é uma força bruta. Sabemos que essa
':'X*'*'X*+
é uma solução candidata; portanto, se gerarmos todas as seqüências de caracteres bem equilibradas até esse comprimento e tomarmos a menor que avaliar a coisa certa, podemos encontrar uma.Graças a Howard, de cuja solução eu roubei alguns ajustes de 1 caractere.
fonte
.&
logo após o loop interno (ou seja, entre~}%
e}*
.GolfScript (
5453 caracteres)Essa é uma abordagem que está no espírito de Howard (construa cadeias que avaliam o valor correto e selecionam a força mais curta, em vez de bruta, através de cadeias candidatas para encontrar aquelas que avaliam o valor correto), mas é suficientemente diferente que eu acho Pertence a uma resposta separada.
A demonstração online não está disponível porque executa uma versão com erros do intérprete.
fonte
3+
por)
(explorando o fato de que[]0=
não deixa nada na pilha) se não fosse isso[]2>
leva a um erro.[]2>
produz[]
sem erro.'1'
.((=
vez de-1=
.Python 2.7 -
878492Explicação:
Esta é uma solução bastante direta. Ele testa recursivamente todas as representações possíveis de n como o produto de dois números ou como
:(n-1)*
e, em seguida, encontra a solução de comprimento mínimo. o intervalo (2, n) é necessário para que a recursão tenha profundidade delimitada, e n <2 fornece o caso base.Notas:
i e n / i são os dois fatores de n. O ... e ... ou ... substituto para ... se ... mais ... não funcionar porque '' é avaliado como falso. min de strings fornece uma das strings mais curtas. Python 2.7 salva 1 caractere usando / em vez de //.
Editar: moveu o caso base para a parte de trás da expressão, permitindo-me usar ... e ... ou ... e raspar alguns espaços.
Casos de teste:
fonte
key=len
. Ele fornece a cadeia lexicograficamente mais antiga. ( Exemplo ). Como'*' < ':'
isso significa que você tem uma tendência para soluções que envolvam potências de 2, mas elas sempre são as mais curtas?u(33)
, para os quais a classificação lexicograficamente dá o 14-char::**::*::*:***
mas a classificação por comprimento dá o 12-char::*:*:*:*:**
GolfScript,
635856 caracteresO código recebe entrada no STDIN e imprime o resultado.
Exemplos:
Você pode testar seus próprios casos online .
fonte
:x(=
pouco. Além disso, +1 por ser capaz de executar 49 em um período de tempo razoável.x,2>{x\%!},
dá todos os verdadeiros divisores dex
,{.v=x@/v=+}/
em seguida, concatena as soluções parad
ex/d
para todos os divisoresd
.{,}$
classifica-os por comprimento e0=
leva o menor deles (mais o:(x-1)*
caso inicial ).Brachylog 2 , 30 (talvez até 26) bytes, desafio de pós-datas no idioma
Aqui está uma função que funciona com a implementação atual do Brachylog 2 (e retorna uma lista de códigos de caracteres porque a implementação atual está tendo alguns problemas com o tratamento de strings):
Experimente online!
A linguagem ainda é muito nova. Aqui está uma versão de 26 bytes do programa que deve funcionar de acordo com a especificação, mas usa alguns recursos não implementados e, portanto, ainda não é válido, mas talvez seja no futuro (também é ainda menos eficiente):
Explicação
A idéia básica é bastante simples: alternamos entre decompor o número em (1 ou mais) fatores (não necessariamente fatores primos, mas fatores de 1 não são permitidos) e expressar cada um deles como 1 + (uma representação obtida de um método recursivo). ligar). Isso garante a pesquisa de todas as representações possíveis de Underload do número (podemos aplicar um estágio de multiplicação "duas vezes seguidas" multiplicando juntos mais de 2 números e um estágio de incremento duas vezes seguidas, separando-os com um estágio de multiplicação que multiplica juntos apenas um número). Não precisamos de um caso base explícito, porque decompor 1 em fatores primos nos fornece uma lista vazia e, portanto, a construímos com um estágio de multiplicação que multiplica zero números juntos.
O programa é bastante ineficiente, principalmente porque a dica de ordem de avaliação que eu dei (gere respostas do menor ao maior em termos do tamanho da saída final), enquanto resolve a parte "mais curta" da pergunta, não é tão boa assim em termos de na verdade, concluir o programa rapidamente (uma dica muito mais útil seria "gerar apenas a resposta mais curta em cada estágio recursivo", mas isso exige mais bytes ...). Além disso,
ḋp~c×ᵐ
pode gerar partições multiplicativas várias vezes cada, fazendo com que o programa faça muito trabalho redundante.fonte
J - 81 char
Para a posteridade, foi o melhor que pude fazer em J.
Criamos uma lista de resultados, começando com duas cadeias vazias (que são
,~
ea:
) representando 0 (nunca usadas) e 1 e, em seguida, iteramos um verbo sobre elas (uso furtivo de ganchos, trens e&
) que acrescenta a representação mais curta do próximo número.O verbo real que iteramos usa o comprimento da lista como um indicador de qual número estamos operando. Primeiro, fatoramos esse número em pares de fatores (
#(#~]-:"1<.)@(],.%)2}.i.@#
) e recuperamos cada par puxando da matriz ({~
). Transformamos cada um desses pares (pode haver 0 deles se o número for primo) em cadeias simples (<@;"1
).Em seguida, anexamos a essa lista a entrada do resultado anterior entre colchetes por
:
e*
, e classificamos essa lista por length ((/:#&>)
). Finalmente, pegamos o primeiro resultado dessa lista (0{
) e o anexamos ao final da matriz base ([,
). Quando o loop termina de iterar, temos uma lista de comprimento 2 a mais do que a entrada, começando em 0. Portanto, o que temos de retornar é a penúltima string (_2{::
).fonte
Geleia , 33 bytes, desafio de pós-datas de idiomas
Experimente online!
Uma solução simples de força bruta.
Explicação
Programa principal
O programa principal usa a função auxiliar para enumerar todas as maneiras possíveis de produzir o valor por multiplicação, depois tenta produzir o valor por adição e retorna a menor possibilidade. Ele também lida com o caso base (uma entrada de
1
).Função auxiliar
A função auxiliar tenta todos os métodos possíveis de expressar a entrada como uma multiplicação de dois números e chama recursivamente o programa principal para obter suas representações mais curtas.
fonte
GNU Prolog, 96 bytes
A primeira linha é uma gramática que implementa a avaliação de Subcarga e funciona na direção inversa (na verdade, ela não funciona na direção direta devido à
A#<B
restrição; mude isso paraA#<N
para um programa mais lento que funciona nos dois sentidos). A segunda linha define o predicado semelhante à funçãos
(que é a função implementada como uma solução para este programa) que encontra a string mais curta possível que avalia o número fornecido como entrada (isso é frustrantemente detalhado para o que é uma tarefa relativamente simples, mas isso é Prolog para você ...).O programa deve ser bastante auto-explicativo, uma vez que é mais ou menos uma tradução direta da especificação para uma gramática e, em seguida, para a sintaxe do Prolog; a definição de
v
diz queN
é 1 em uma sequência vazia, ouN
éA
×B
(comA
menos queB
menos queN
) e a sequência é a concatenação dev(A)
ev(B)
, ouN
éM
+ 1 e a sequência é:
concatenada comv(M)
concatenada com*
. A segunda linha é um pouco mais sutil;length(S,_)
significa "S tem algum comprimento", mas especificar isso como a primeira coisa na linha funciona como uma dica para a implementação do Prolog de que ele deve verificar primeiro os comprimentos mais curtos (o que significa que obteremos o menor comprimento possível para um valor de retorno) .fonte