L'espansione binaria binaria


9

Normalmente, scomponiamo un numero in cifre binarie assegnandolo con potenze di 2, con un coefficiente di 0o 1per ogni termine:

25 = 1*16 + 1*8 + 0*4 + 0*2 + 1*1

La scelta di 0ed 1è ... non molto binaria. Eseguiremo la vera espansione binaria espandendola con potenze di 2, ma con un coefficiente di 1o -1invece:

25 = 1*16 + 1*8 + 1*4 - 1*2 - 1*1

Ora questo sembra binario.

Dato un numero positivo, dovrebbe essere banale vedere che:

  • Ogni numero dispari ha infinite espansioni binarie reali
  • Ogni numero pari non ha espansioni binarie vere

Quindi, affinché una vera espansione binaria sia ben definita, abbiamo bisogno che l'espansione sia la minima , ovvero con la lunghezza più breve.


Dato un numero intero dispari positivo, nrestituisce la sua vera espansione binaria, dalla cifra più significativa alla cifra meno significativa (o in ordine inverso).

Regole:

  • Dato che si tratta di , dovresti mirare a farlo nel minor numero di byte possibile. Sono ammessi i builtin.
  • Qualsiasi output in grado di rappresentare ed elencare i coefficienti è accettabile: un array, una stringa di coefficienti con separatori, ecc ...
  • Si applicano scappatoie da golf standard.
  • Il tuo programma dovrebbe funzionare per valori all'interno della dimensione intera standard della tua lingua.

Casi test

25 -> [1,1,1,-1,-1]
47 -> [1,1,-1,1,1,1]
1 -> [1]
3 -> [1,1]
1234567 -> [1,1,-1,-1,1,-1,1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,1,1]

Correlato ma abbastanza diverso.
Giuseppe,

4
Algoritmo semplice: converti in base 2, sostituisci 0 con -1, metti l'LSD in primo piano.
Josiah Winslow,

Voile: non stavo spiegando i downvotes, stavo solo delineando un algoritmo per le persone che hanno comandi di conversione di base nella loro lingua.
Josiah Winslow,

Dato che sei così appassionato di essere veramente binario, possiamo restituire il valore come bit compressi con il solito valore di luogo ma la nuova interpretazione dei due stati? cioè elettricamente è solo alta o bassa tensione (o qualsiasi altra cosa), e non è colpa mia se i debugger standard stampano 0invece che -1per lo stato di bassa tensione. Il chiamante che riceve i bit sa cosa significano. (È ancora un esercizio di manipolazione dei bit non banale, poiché una rotazione a destra funziona solo se ha 32 bit significativi. Ad esempio, un numero a 5 bit richiede una larghezza di rotazione di 5.)
Peter Cordes,

L'output deve includere separatori? È 111-1-1un output valido per 25?
Oliver,

Risposte:


7

Japt , 6 byte

¤é r0J

Provalo online!

Spiegazione:

¤é r0J  // Test input:                  25
¤       // Binary the input:            11001
 é      // Rotate 1 chars to the right: 11100
   r0J  // Replace 0s with -1:          111-1-1

1
Ah, la rotazione; ecco perché non ha funzionato per me.
Shaggy,

2
Ruotare??? dagnabbit.
Giuseppe,

3

Pyth ,  12  11 byte

|R_1.>jQ2 1

Provalo qui!


Come?

| R_1.> JQ2 1 Programma completo.

      jQ2 Converte l'input in un elenco binario.
     .> 1 Ruota ciclicamente l'elenco in alto di 1 posizione a destra.
| R_1 Sostituisci 0 con -1.
               Uscita implicita.

Prima di tutto, notiamo che il compito è semplicemente "sostituire le 0s nella scrittura binaria con se -1spostarsi a destra di 1 posto". - È esattamente quello che dovremmo fare! La conversione binaria ci dà un elenco di 0s e 1s. Tutti dobbiamo fare qui è di trovare un modo per convertire Golfy 0a -1. L'operatore bit a |bit (OR bit a bit) è nostro amico. La mappa sopra la rappresentazione binaria si spostava con |e -1. Se il numero corrente è 0, viene convertito in -1.


Non penso che ci sia un modo migliore. ;)
Josiah Winslow,

@JosiahWinslow Lo faccio ... Sto cercando di trovarlo
Mr. Xcoder,

Hm? L'algoritmo sembra ottimale, forse perché non conosco Pyth.
Josiah Winslow,

@JosiahWinslow Trovato il modo migliore. Modo migliore sintattico, non modo algoritmico migliore.
Mr. Xcoder,

@ Mr.Xcoder E ora non c'è davvero nessuno almeno per me.
Erik the Outgolfer,



2

Perl 6 , 72 byte

C'è sicuramente un modo migliore, ma questo è quello che ho ...

->$a {grep {$a==[+] @^a.reverse Z+< ^∞},[X] (1,-1)xx $a.base(2).chars}

Provalo online!

Spiegazione : È una funzione che accetta un argomento ( ->$a). Otteniamo prima il numero di coefficienti necessari ( $a.base(2).chars= numero di caratteri nella rappresentazione di base 2), quindi realizziamo un prodotto cartesiano ( X) di tante coppie (1,-1). (Il [X]mezzo: riduci il seguente elenco con X.) Quindi otteniamo un elenco di tutte le possibili combinazioni di 1s e -1s. Quindi filtriamo ( grep) solo gli elenchi che codificano il numero indicato $a. Ce n'è solo uno, quindi otteniamo un elenco di un elenco con i coefficienti.

Il blocco grep fa questo: prende il suo argomento come un elenco ( @^a), lo inverte e lo zip con un elenco infinito 0,1,2,...usando l'operatore "spostamento bit sinistro" +<. Lo zipping si interrompe non appena viene esaurito l'elenco più breve (buono per noi!) Quindi sommiamo tutti i risultati e li confrontiamo con il numero indicato. Abbiamo dovuto usarlo .reverseperché il PO richiede che i coefficienti siano nell'ordine dal più significativo al meno significativo.




1

J, 11 byte

1-~2*_1|.#:

Provalo online!

Grazie a @JosiahWinslow per l'algoritmo.

Qualche idea su come ridurre la conversione? I miei pensieri sono di usare!. -fit (nvm, cambia solo la tolleranza della conversione).

L'uso di {-take è più lungo di 1 carattere.

_1 1{~_1|.#:

1

Java 8, 101 byte

n->{String s=n.toString(n,2);return(s.charAt(s.length()-1)+s.replaceAll(".$","")).replace("0","-1");}

Porto di @Oliver Japt risposta s' , con un paio di più byte ..;)

Può sicuramente essere giocato a golf usando un approccio matematico invece di questo approccio String.

Spiegazione:

Provalo qui.

n->{                             // Method with Integer parameter and String return-type
  String s=n.toString(n,2);      //  Convert the Integer to a binary String
  return(s.charAt(s.length()-1)  //  Get the last character of the binary String
    +s.replaceAll(".$","")       //   + everything except the last character
   ).replace("0","-1");          //  Then replace all zeroes with -1, and return the result
}                                // End of method

1

R , 90 88, 46 byte

function(n)c((n%/%2^(0:log2(n))%%2)[-1],1)*2-1

Provalo online!

Implementa l'algoritmo di Oliver , ma restituisce le cifre in ordine inverso. Dal momento che ci viene garantito che nnon è mai pari, il bit meno significativo (il primo) è sempre 1, quindi lo rimuoviamo e aggiungiamo un 1alla fine per simulare la rotazione in R. Grazie a Shaggy per avermi permesso di sistemare la mia matematica .

Mettere semplicemente rev( )le chiamate di funzione nel piè di pagina dovrebbe restituire i valori nello stesso ordine.

risposta originale, 88 byte:

function(n,b=2^(0:log2(n)))(m=t(t(expand.grid(rep(list(c(-1,1)),sum(b|1))))))[m%*%b==n,]

Funzione anonima; restituisce i valori in ordine inverso con i nomi delle colonne allegati.

Provalo online!

Spiegazione:

function(n){
 b <- 2^(0:log2(n))         # powers of 2 less than n
 m <- expand.grid(rep(list(c(-1,1)),sum(b|1))) # all combinations of -1,1 at each position in b, as data frame
 m <- t(t(m))               # convert to matrix
 idx <- m%*%b==n            # rows where the matrix product is `n`
 m[idx,]                    # return those rows
}

Non considero tale output valido; suggerire di chiedere conferma all'autore della sfida.
Shaggy,

L'ordine inverso di @Shaggy è esplicitamente consentito: from the most significant digit to the least significant digit (or in reversed order).quindi questo dovrebbe essere perfettamente accettabile.
Giuseppe,

1
Reversed ordine , non invertito segni. Significato uscita valida per 25, ad esempio, potrebbe essere [1,1,1,-1,-1]o [-1,-1,1,1,1].
Shaggy

1
@Shaggy ah, hai ragione, ho fatto male alla matematica! dovrebbe essere 2*bits - 1invece di 1-2*bits. Grazie.
Giuseppe,




0

Golfscript, 14 13 14 byte

-1 byte perché ho dimenticato che %esistesse. +1 byte perché ho anche dimenticato che l'input è una stringa.

~2base{.+(}%)\

1
Se supponi che l'input arrivi come un numero intero, dovresti racchiudere il codice {}per renderlo un blocco. I programmi completi possono ottenere input solo come stringhe.
Peter Taylor,

Ehm, cosa? Intendevo dire che il numero viene inviato come numero intero anziché come stringa contenente un numero.
Josiah Winslow,

In tal caso la tua risposta non è un programma completo, e quindi deve essere una "funzione" , o nel caso di GolfScript un blocco. Pertanto è {2base{.+(}%\}per 15 byte. Allo stesso modo la tua risposta CJam.
Peter Taylor,

Questo è un programma completo. L'input in Golfscript viene implicitamente inserito nello stack all'inizio del programma e l'input in CJam viene specificato prima dell'esecuzione e vi si accede con il comando q.
Josiah Winslow,

Ho una certa familiarità con GolfScript . ( E CJam ). Se vuoi affermare che si tratta di un programma completo devi prefissarlo ~.
Peter Taylor,
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.