Encontre a representação mais curta de um número no SNUSP Modular

10

fundo

Muitas linguagens de programação esotérica não têm números incorporados em literais, portanto você deve calculá-los em tempo de execução; e em muitos desses casos, a representação numérica pode ser bastante interessante. Já tivemos um desafio em representar números para o Underload. Esse desafio é sobre a representação de números no SNUSP modular . (Observe que você não precisa aprender SNUSP para concluir esse desafio - todas as informações necessárias estão na especificação - mas você pode achar interessante o plano de fundo).

A tarefa

Para a finalidade deste desafio, um número SNUSP modular é uma sequência formada pelos caracteres @, +e =, exceto que o último caractere é a #e que o penúltimo caractere deve ser +ou =(não pode ser @). Por exemplo, números válidos incluem @+#, ==#e @@+@=#; Exemplos de números inválidos incluem +=, @@#e +?+#.

O valor de um número SNUSP modular é calculado recursivamente da seguinte maneira:

  • # tem um valor de 0 (este é o caso base).
  • Se o número tiver o formato =x, para qualquer sequência x, seu valor será igual ao valor de x.
  • Se o número tiver a forma +x, para qualquer sequência x, seu valor será igual ao valor de xmais 1.
  • Se o número tiver a forma @cx, para qualquer caractere único ce qualquer sequência x, seu valor será igual ao valor de xmais o valor de cx.

Para esse desafio, você deve escrever um programa que use um número inteiro não negativo como entrada e produza uma string que seja o menor número SNUSP Modular possível que possua um valor igual à entrada.

Esclarecimentos

  • É perfeitamente possível que haja mais de uma string com o mesmo valor e, em particular, para alguns números inteiros, haja um empate para o número SNUSP Modular mais curto com esse valor. Nesse caso, você pode enviar qualquer um dos números envolvidos com o empate.
  • Não há restrição no algoritmo usado para encontrar o número; por exemplo, seqüências de força bruta e avaliá-las é uma tática legal, mas também é algo mais inteligente para reduzir o espaço de pesquisa.
  • Como de costume no PPCG, seu envio pode ser um programa completo ou uma função (escolha o que for mais conciso no seu idioma).
  • Isso não é um problema ao lidar com os formatos de entrada e saída; portanto, você pode usar qualquer meio razoável para inserir um número inteiro não negativo e gerar uma string. Há um guia completo sobre a meta , mas os métodos legais mais usados ​​incluem argumentos / retornos de função, argumentos de linha de comando e entrada / saída padrão.

Casos de teste

Aqui estão as representações mais curtas dos primeiros números:

  • 0 :#
  • 1 :+#
  • 2 :++#
  • 3 : +++#ou@++#
  • 4 : ++++#ou +@++#ou@=++#
  • 5 : @+++#ou@@++#
  • 6 : +@+++#ou +@@++#ou @=+++#ou @=@++#ou@@=++#
  • 7 : @++++#ou@+@++#
  • 8 : @@+++#ou@@@++#
  • 9 : +@@+++#ou +@@@++#ou @+++++#ou @++@++#ou @+@=++#ou @@=+++#ou@@=@++#
  • 10 : @=@+++#ou @=@@++#ou @@@=++#( este é um caso de teste bastante importante para verificar , pois todas as respostas possíveis incluem =)
  • 11 : @+@+++#ou @+@@++#ou @@++++#ou@@+@++#
  • 12 : +@+@+++#ou +@+@@++#ou +@@++++#ou +@@+@++#ou @=+@+++#ou @=+@@++#ou @=@=+++#ou @=@=@++#ou @=@@=++#ou @@=++++#ou @@=+@++#ou@@=@=++#
  • 13 : @@@+++#ou@@@@++#
  • 14 : +@@@+++#ou +@@@@++#ou @=@++++#ou @=@+@++#ou @@+++++#ou @@++@++#ou@@+@=++#
  • 15 : @+@++++#ou @+@+@++#ou @@=@+++#ou @@=@@++#ou @@@=+++#ou@@@=@++#

Tal como um caso de teste maior, a saída da entrada 40 deve ser @@@=@@+++#, @@@=@@@++#, @@@@=@+++#, ou @@@@=@@++#.

Condição de vitória

Como um desafio de , o vencedor é a entrada mais curta, medida em bytes.

Comunidade
fonte
11
=otimamente ocorrerá apenas como @=, certo?
orlp
3
A propósito, esse tipo de desafio geralmente é melhor publicado como metagolfo , pois dificilmente haverá uma resposta interessante (apenas avalie a string e o loop sobre todas as strings possíveis).
orlp
3
@orlp: Eu discordo, esse desafio seria muito fácil como um metagolfo, pois encontrar uma resposta ótima é relativamente fácil, e o metagolf não impõe nenhuma outra restrição à pontuação. Espero que a maioria das respostas aqui seja de força bruta, mas a especificação é complexa o suficiente para que a força bruta a) não seja a mais curta eb) provavelmente seja interessante para o golfe por si só. Se você queria uma mudança na condição de vitória, provavelmente o único outro interessante é o código mais rápido , e isso faria mais sentido como um desafio diferente.
Também tivemos um grande número de desafios de golfe para o Brain-flak
somente ASCII

Respostas:

3

Oracle SQL 11.2, 341 262 bytes

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c,i)AS(SELECT'#',0,0,e,1 FROM e UNION ALL SELECT c||s,DECODE(c,'+',1,'@',p,0)+v,v,e,i+1 FROM n,e WHERE i<11)CYCLE s SET y TO 1 DEFAULT 0 SELECT s FROM n WHERE:1=v AND rownum=1;

Versão antiga

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c) AS(SELECT'#',0,0,e FROM e UNION ALL SELECT s||c,CASE c WHEN'+'THEN 1 WHEN'='THEN 0 WHEN'@'THEN p ELSE 0 END+v,v,e FROM n,e WHERE LENGTH(s)<10)CYCLE s SET y TO 1 DEFAULT 0 SELECT MIN(REVERSE(s))KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s))FROM n WHERE v=:1;

: 1 o número a representar no SNUSP modular

Sem golfe:

WITH e AS (SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),  
n(s,v,p,c,i) AS                   
(
  SELECT '#',0,0,e,1 FROM e
  UNION ALL
  SELECT s||c
       , DECODE(c,'+',1,'@',p,0)+v 
       , v
       , e
       , i+1
  FROM n,e
  WHERE i<11
) CYCLE s SET y TO 1 DEFAULT 0
SELECT s FROM n WHERE:1=v AND rownum=1;

Primeiro, crie uma visualização com 3 linhas, uma para cada símbolo usado para representar números, menos #, que é usado apenas no final da sequência:

SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4;    

Então a visão recursiva n gera todas as seqüências possíveis com esses três símbolos, concatena-as em # e as avalia.

Os parâmetros são:

s: a representação SNUSP modular do número que está sendo avaliado
v: o valor decimal de s calculado pela iteração anterior
p: v calculado pela iteração i-2
c: o próximo símbolo a concatenar para s
i: o comprimento de s, apenas necessário para se livrar de dois LENGTH () para fins de golfe

DECODE(c,'+',1,'@',p,0)+v 

Se o último símbolo for +, adicione 1
Se for @, adicione o valor da iteração i-2 . Caso contrário,
o símbolo é # ou =. v é inicializado com 0 na parte init da visualização recursiva, portanto, o novo v é igual ao v anterior em ambos os casos.

WHERE i<11

Cada string possível com os três símbolos é calculada, esta parte garante que a solicitação não seja executada até a grande crise.

CYCLE s SET y TO 1 DEFAULT 0

Como não há regra para a construção das seqüências, duplicatas provavelmente surgirão. Sendo uma visão recursiva, a Oracle interpreta essas duplicatas como ciclos e gera um erro se o caso não for explicitamente resolvido.

SELECT s FROM n WHERE:1=v AND rownum=1;

Retorna a primeira representação SNUSP modular que é avaliada como o número decimal digitado como parâmetro: 1

Nos meus testes, a primeira linha é sempre uma das mais curtas representações.

Caso seu banco de dados não atue da mesma maneira, a última cláusula deve ser substituída por

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY i)FROM n WHERE:1=v
Jeto
fonte
2

JavaScript (ES6), 100 bytes

n=>eval("for(a=[['#',0,0]];[[s,t,p],...a]=a,t-n;)a.push(['='+s,t,t],['+'+s,t+1,t],['@'+s,t+p,t]);s")

Algoritmo de busca simples em termos de força bruta.

Neil
fonte
Para 40, ele retorna "@@@@@@ = ​​++ #", que é avaliado em 42
aditsu encerrado porque SE é MAU
Mesmo para 12, "@@@ +++ #" é avaliado como 13
aditsu é encerrado porque o SE é MAU 24/01
Hmm, eu acho que a mudança t<npara t-no trabalho poder ...
Neil
2

Pitão, 41 bytes

L?b+ytb@[yttb001)Chb0+hfqQyTs^L"+@="UhQ\#

Suíte de teste

Como funciona:

Existem duas partes. Uma função recursiva que calcula o valor de uma expressão SNUSP sem a sequência #e uma rotina de força bruta.

Avaliação:

L?b+ytb@[yttb001)Chb0
L                        Define the function y(b) as follows
 ?b                      If b is nonempty
   +ytb                  The sum of y(tail(b)) and   # tail(b) = b[1:]
   @[       )            The element in the list at location
   Chb                   Character values of the first character.
                         Modular indexing means that 
                         + -> 3
                         @ -> 0
                         = -> 1
                         Index 2 is filler.
    [yttb001)            @ adds y(tail(tail(b)). Tail suppresses the error when
                         called on an empty list, so this treats @# as zero, but
                         this can't lead to problems because removing the @ will
                         always make the expression shorter.
                         + adds 1, = adds 0.
 0                       If b is the empty string, return 0

Força bruta:

+hfqQyTs^L"+@="UhQ\#
               UhQ      0 ... Q     # Q is the input
        ^L"+@="         Map that list to all strings formed from the characters
                        "+@=", with that many characters.
       s                Concatenate
  fqQyT                 Filter for strings which evaluate to the input
 h                      Take the first success, which is the shortest due to
                        the order the strings were generated.
+                 \#    Add a '#' and output
isaacg
fonte
1

CJam, 58

ri:M;'#0_]]{_{M&}#_)!}{;{~[2,+1$f+"@=+"\]z\f+\af.+~}%}w=0=

Força bruta, com um pouco de inspiração da resposta de Neil. Experimente online

Versão eficiente, 107

ri0"#"a{_{:B\:A={'=A0j+}{A(B={'+B0j+}{AB>{BAB-j_N={'@\+}|}N?}?}?}{;_(0j'+\+a\,1>_W%.{j}Na-'@\f++{,}$0=}?}2j

Experimente online

Isso usa programação dinâmica.

aditsu sair porque SE é MAU
fonte
1

Haskell , 89 86 bytes

EDITAR:

  • -3 bytes: o zíper foi menor que a indexação.

Outra solução de força bruta que acabou com muita inspiração da resposta de Neil. (Embora tenha funcionado mais como o Pyth de isaacg antes de o golfe apresentar o l.)

f n=[s|(a,_,s)<-l,a==n]!!0
l=(0,0,"#"):[(a+c,a,d:s)|(a,b,s)<-l,(c,d)<-zip[0,1,b]"=+@"]

Experimente online!

  • f é a função principal, que pega um número inteiro e retorna uma string.
  • lé uma lista infinita de tuplas (a,b,s), as representações mais curtas sprimeiro, juntamente com seu valor ae o valor bda representação com o primeiro caractere retirado. (como outros também notaram / notaram, é inofensivo tratar o último como 0 #).
  • Os elementos lque não sejam o primeiro são gerados recursivamente com uma compreensão da lista. dé o caractere que deve ser anexado para sgerar uma nova representação na lista e 'c' é o incremento correspondente a a.
Ørjan Johansen
fonte