Trova la rappresentazione più breve di un numero in SNUSP modulare


10

sfondo

Molti linguaggi di programmazione esoterica non hanno numeri integrati in valori letterali, quindi è necessario calcolarli in fase di esecuzione; e in molti di questi casi, la rappresentazione numerica può essere piuttosto interessante. Abbiamo già avuto una sfida a rappresentare i numeri per Underload. Questa sfida riguarda la rappresentazione di numeri in SNUSP modulare . (Nota che non è necessario imparare SNUSP per completare questa sfida - tutte le informazioni di cui hai bisogno sono nelle specifiche - ma potresti trovare interessante lo sfondo.)

L'obiettivo

Ai fini di questa sfida, una serie Modular SNUSP è una stringa formata fuori dei personaggi @, +e =, tranne che l'ultimo carattere è una #, e che il personaggio deve essere penultima +o =(non può essere @). Ad esempio, i numeri validi includono @+#, ==#e @@+@=#; esempi di numeri non validi includono +=, @@#e +?+#.

Il valore di un numero SNUSP modulare viene calcolato in modo ricorsivo come segue:

  • # ha un valore di 0 (questo è il caso base).
  • Se il numero ha la forma =x, per qualsiasi stringa x, il suo valore è uguale al valore di x.
  • Se il numero ha la forma +x, per qualsiasi stringa x, il suo valore è uguale al valore di x, più 1.
  • Se il numero ha la forma @cx, per ogni singolo carattere ce qualsiasi stringa x, il suo valore è uguale al valore di x, più il valore di cx.

Per questa sfida, è necessario scrivere un programma che accetta come input un numero intero non negativo e genera una stringa che è il numero SNUSP modulare più breve possibile che ha un valore uguale all'input.

chiarimenti

  • È del tutto possibile che ci sia più di una stringa con lo stesso valore e, in particolare, per alcuni numeri interi ci sarà un pareggio per il numero SNUSP modulare più corto con quel valore. In tal caso, è possibile generare uno qualsiasi dei numeri coinvolti con il pareggio.
  • Non ci sono restrizioni sull'algoritmo che usi per trovare il numero; ad esempio, forzare le stringhe e valutarle è una tattica legale, ma allo stesso modo sta facendo qualcosa di più intelligente per ridurre lo spazio di ricerca.
  • Come al solito su PPCG, il tuo invio può essere un programma completo o una funzione (scegli quello più conciso nella tua lingua).
  • Questo non è un problema sulla gestione dei formati di input e output, quindi puoi usare qualsiasi mezzo ragionevole per inserire un numero intero non negativo e produrre una stringa. C'è una guida completa su meta , ma i metodi legali più comunemente usati includono argomenti / restituzioni di funzioni, argomenti della riga di comando e input / output standard.

Casi test

Ecco le rappresentazioni più brevi dei primi numeri:

  • 0 :#
  • 1 :+#
  • 2 :++#
  • 3 : +++#o@++#
  • 4 : ++++#oppure +@++#oppure@=++#
  • 5 : @+++#o@@++#
  • 6 : +@+++#oppure +@@++#oppure @=+++#oppure @=@++#oppure@@=++#
  • 7 : @++++#o@+@++#
  • 8 : @@+++#o@@@++#
  • 9 : +@@+++#oppure +@@@++#oppure @+++++#oppure @++@++#oppure @+@=++#oppure @@=+++#oppure oppure@@=@++#
  • 10 : @=@+++#oppure @=@@++#oppure @@@=++#( questo è un caso di test abbastanza importante da controllare , poiché tutte le possibili risposte includono =)
  • 11 : @+@+++#oppure @+@@++#oppure @@++++#oppure@@+@++#
  • 12 : +@+@+++#oppure +@+@@++#oppure +@@++++#oppure +@@+@++#oppure @=+@+++#oppure @=+@@++#oppure @=@=+++#oppure @=@=@++#oppure @=@@=++#oppure @@=++++#oppure @@=+@++#oppure oppure@@=@=++#
  • 13 : @@@+++#o@@@@++#
  • 14 : +@@@+++#oppure +@@@@++#oppure @=@++++#oppure @=@+@++#oppure @@+++++#oppure @@++@++#oppure oppure@@+@=++#
  • 15 : @+@++++#oppure @+@+@++#oppure @@=@+++#oppure @@=@@++#oppure @@@=+++#oppure@@@=@++#

Come un banco di prova più grande, l'uscita dall'input 40 dovrebbe essere @@@=@@+++#, @@@=@@@++#, @@@@=@+++#, o @@@@=@@++#.

Condizione di vittoria

Come sfida di , il vincitore è l'ingresso più breve, misurato in byte.


1
=accadrà in modo ottimale solo come @=, giusto?
orlp,

3
A proposito, questo tipo di sfide è solitamente meglio pubblicato come metagolf , in quanto difficilmente ci sarà una risposta interessante (basta valutare la stringa e passare su tutte le possibili stringhe).
orlp,

3
@orlp: Non sono d'accordo, questa sfida sarebbe troppo facile come metagolf, poiché trovare una risposta ottimale è relativamente facile e metagolf non pone altre restrizioni sul punteggio. Mi aspetto che la maggior parte delle risposte qui siano forza bruta, ma le specifiche sono abbastanza complesse che la forza bruta a) potrebbe non essere la più breve, e b) è probabilmente interessante per il golf a sé stante. Se volessi un cambiamento nella condizione di vittoria, probabilmente l'unico altro interessante è il codice più veloce , e questo avrebbe più senso come una sfida diversa.

Abbiamo anche avuto una sfida di golf numero per Brain-flak
ASCII, solo

Risposte:


3

Oracle SQL 11.2, 341 262 byte

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;

Vecchia versione

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 il numero da rappresentare in SNUSP modulare

Non golfato:

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;

Innanzitutto crea una vista con 3 linee, una per ogni simbolo usato per rappresentare i numeri, meno # che viene usato solo alla fine della stringa:

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

Quindi la vista ricorsiva n genera ogni stringa possibile con quei 3 simboli, li concatena a # e li valuta.

I parametri sono:

s: la rappresentazione SNUSP modulare del numero da valutare
v: il valore decimale di s calcolato dall'iterazione precedente
p: v calcolato dall'iterazione i-2
c: il simbolo successivo da concatenare a i
i: la lunghezza di s, solo necessario per sbarazzarsi di due LENGTH () a scopo di golf

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

Se l'ultimo simbolo è +, allora aggiungi 1
Se è @ aggiungi il valore dell'iterazione i-2
Altrimenti il ​​simbolo è # o =. v viene inizializzato con 0 nella parte init della vista ricorsiva, quindi in entrambi i casi la nuova v è uguale alla v precedente.

WHERE i<11

Viene calcolata ogni stringa possibile con i 3 simboli, questa parte assicura che la richiesta non venga eseguita fino al grande scricchiolio.

CYCLE s SET y TO 1 DEFAULT 0

Poiché non esiste alcuna regola per la costruzione delle stringhe, i duplicati sono destinati a sorgere. Essere in una vista ricorsiva Oracle interpreta quei duplicati come cicli e genera un errore se il caso non viene risolto in modo esplicito.

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

Restituisce la prima rappresentazione SNUSP modulare che valuta il numero decimale immesso come parametro: 1

Nei miei test quella prima riga è sempre una delle rappresentazioni più brevi.

Nel caso in cui il tuo database non agisse allo stesso modo, allora l'ultima clausola dovrebbe essere sostituita con

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

2

JavaScript (ES6), 100 byte

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 di ricerca semplice per ampiezza della forza bruta.


Per 40 restituisce "@@@@@@ = ​​++ #" che
restituisce

Anche per 12 dà "@@@ +++ #" che
indica

Hmm, penso che il passaggio t<na t-npotrebbe funzionare ...
Neil

2

Pyth, 41 byte

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

Suite di test

Come funziona:

Ci sono due parti. Una funzione ricorsiva che calcola il valore di un'espressione SNUSP senza trascinamento #e una routine di forza bruta.

evalutaion:

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

Forza 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

1

CJam, 58

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

Forza bruta, con un po 'di ispirazione dalla risposta di Neil. Provalo online

Versione efficiente, 107

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

Provalo online

Questo utilizza una programmazione dinamica.


1

Haskell , 89 86 byte

MODIFICARE:

  • -3 byte: zippare era più breve dell'indicizzazione.

Un'altra soluzione di forza bruta che si è ispirata molto alla risposta di Neil. (Anche se ha funzionato più come Pyth di isaacg prima che il golf introducesse il 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]"=+@"]

Provalo online!

  • f è la funzione principale, che accetta un numero intero e restituisce una stringa.
  • lè un elenco infinito di tuple (a,b,s), sprima le rappresentazioni più brevi , insieme al loro valore ae al valore bdella rappresentazione con il primo carattere rimosso. (come altri hanno anche notato / notato, è innocuo trattare quest'ultimo come 0 per #.)
  • Gli elementi ldiversi dal primo vengono generati in modo ricorsivo con una comprensione dell'elenco. dè il carattere che deve essere anteposto per sgenerare una nuova rappresentazione nell'elenco e 'c' è l'incremento corrispondente a a.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.