Converti i numeri in binario ... ma puoi usare anche due


20

Sulla base della notazione "binaria, ma con due" menzionata in questo video file numerico , scrivere una funzione che accetta un singolo numero come input e genera tutte le variazioni di quel numero in un sistema "binario" in cui sono consentiti due.

Regole

  • Il codice deve essere solo una funzione / metodo, non un programma completo
  • L'input è un numero intero passato come unico parametro alla funzione
  • L'output è tutte le variazioni valide del numero di input convertito in notazione "binaria, ma con due"
  • L'output è il valore restituito della funzione, ma può essere in qualsiasi formato sia conveniente finché è ovvio (ad es. 3 ints, 3 stringhe, stringa delimitata da virgola / spazio, array di ints, ecc.), L'ordine non è importante
  • Nel caso improbabile che una lingua contenga una funzione integrata per ottenere il risultato, non è consentita
  • Il codice più breve in byte è il vincitore

Spiegazione dell'output

Ad esempio, se ti viene passato il numero 9, puoi convertirlo in binario come 1001, ma se hai permesso 2s in ogni posizione, puoi anche scriverlo come 201(ie 2*4 + 0*2 + 1*1) o 121(ie 1*4 + 2*2 + 1*1), come mostrato in questa tabella:

+----+----+----+----+
| 8s | 4s | 2s | 1s |
+----+----+----+----+
|  1 |  0 |  0 |  1 |
|  0 |  2 |  0 |  1 |
|  0 |  1 |  2 |  1 |
+----+----+----+----+

Quindi, se approvata 9, la funzione avrebbe bisogno di restituire i tre numeri, 1001, 201e 121.

Formato e ordine sono irrilevanti, purché sia ovvio (cioè [121,201,1001], "0201 0121 1001", ("1001","121","201")sono risultati validi quando dato un ingresso 9).

Esempi

  • 2 => 10, 2
  • 9 => 1001, 201, 121
  • 10 => 1010, 210, 202, 1002, 122
  • 23 => 2111, 10111
  • 37 => 100101, 20101, 100021, 20021, 12101, 12021, 11221


1
Due? In binario? Questo calcolo quantistico?
Matthew Roh,

Risposte:


10

GolfScript (25 byte) / CJam ( 19 17 byte)

GolfScript:

{:^.*,{3base}%{2base^=},}

Questo crea una funzione anonima (vedi meta discussione sull'ammissibilità di funzioni anonime ).

Demo online

Una traduzione diretta in CJam è (grazie a Martin Büttner per aver rasato un paio di personaggi)

{:X_*,3fb{2bX=},}

Dissezione

{             # Function boilerplate
  :^          # Store parameter as variable ^
  .*          # Square parameter - see detailed explanation below
  ,{3base}%   # Produce an array of 0 to ^*^-1 in ternary
  {2base^=},  # Filter to those which evaluate to ^ in binary
}

Il motivo dell'operazione di quadratura è che dobbiamo ripetere il valore più grande possibile la cui rappresentazione ternaria, interpretata in binario, è uguale ^. Da allora 2 = 10, la "normale" rappresentazione binaria di ^è quella che conta. Se lo convertiamo in ternario, scopriamo che i casi "peggiori" sono poteri di 2. Un approccio ottimale sarebbe quello di portare l'argomento al potere di ln 3/ln 2 ~= 1.585, ma la quadratura è molto più breve.


Scommetto che una traduzione CJam sarà molto più piccola.
Ottimizzatore

1
@Optimizer vai avanti ;-)
John Dvorak il

GolfScript? amico, sono un tale noob
pythonian29033,

8

Python 2 (59 byte)

S=lambda n,B="":[B][n:]or~n%2*S(n/2-1,"2"+B)+S(n/2,`n&1`+B)

(Mille grazie a @grc, @xnor e @PeterTaylor per l'aiuto nella chat)

Ricorsione semplice, chiamata con S(23)o simile.

Spiegazione

L'idea generale è che se nl'espansione binaria termina con a 1, allora anche qualsiasi espansione pseudo-binaria ("binaria, ma con due") deve terminare con a 1. Altrimenti potrebbe finire con 0o 2.

Quindi guardiamo l'ultimo pezzo di n, dividiamo e ramifichiamo di conseguenza.

Dissezione

S=lambda n,B="":           # Lambda expression
[B][n:]or                  # Short circuit, return [B] if n==0 else what follows
~n%2*                      # Keep next list result if n is even else turn into []
S(n/2-1,"2"+B)             # Add a "2" to B, recurse
+
S(n/2,`n&1`+B)             # Add "0" or "1" to B depending on n's last bit, recurse

variabili:

  • n: Il numero di cui vogliamo trovare espansioni pseudo-binarie
  • B: Una stringa pseudo-binaria in fase di creazione da destra a sinistra

5

Bash + coreutils, 77

f()(seq `dc -e2o$1p`|sed '/[3-9]/d;s/.*/&n9P2i&pAi/'|dc|grep -Po ".*(?= $1)")

(Questo è un TABpersonaggio nell'espressione grep.)

Questo sta piegando un po 'questa regola:

"Nel caso improbabile che una lingua contenga una funzione integrata per ottenere il risultato, non è consentita"

Si scopre che dcha il contrario di ciò di cui abbiamo bisogno. Ad esempio, se impostiamo l'input base su 2 e inseriamo un numero binario con due, lo analizzerà correttamente. (Allo stesso modo se la modalità di input è base 10, AF vengono analizzati come "cifre" decimali 10-15).

seqcrea un elenco di tutti i numeri decimali fino alla rappresentazione binaria standard di n, analizzata come decimale. Quindi tutti i numeri che contengono qualcosa diverso da {0,1,2} vengono filtrati. Quindi dcanalizza i numeri rimanenti come binari per vedere quale valutazione torna a n.

Le funzioni di Bash possono solo "restituire" numeri interi scalari 0-255. Quindi mi prendo la libertà di stampare l'elenco su STDOUT come il mio modo di "tornare". Questo è idiomatico per gli script di shell.

Produzione:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$

4

Haskell, 82

t n=[dropWhile(==0)s|s<-mapM(\_->[0..2])[0..n],n==sum[2^(n-i)*v|(i,v)<-zip[0..]s]]

questa è solo una soluzione a forza bruta. è molto inefficiente, perché dovrebbe sgretolarsi attraverso 3 ^ n possibilità.


3

Gelatina , 10 byte, sfida postdatati in lingua

ṗ@3Ḷ¤Ḅ=¥Ðf

Provalo online!

Una soluzione bruteforce fino a un numero di hyperbit pari all'input (questo formato è noto come "hyperbinary"). Come tale, è incredibilmente inefficiente, in esecuzione in O (3 n ).

Spiegazione

ṗ@3Ḷ¤Ḅ=¥Ðf
ṗ@            Construct all lists with the given length, and elements taken from
  3Ḷ¤         the list [0,1,2]
        Ðf    then take only those elements which
     Ḅ=¥      when interpreted as binary, equal {the original number}

2

PHP, 138 byte

function p($v,$i=0,$r=""){global$a;if($v==0)$a[]=$r?:0;elseif($v>0)for(;$l<3;)p($v-2**$i*$l,$i+1,+$l++.$r);}p($argv[1]);echo join(",",$a);

Abbattersi

function p($v,$i=0,$r=""){
    global$a;
    if($v==0)$a[]=$r?:0;  # fill result array
    elseif($v>0) # make permutations
        for(;$l<3;)
            p($v-2**$i*$l,$i+1,+$l++.$r); #recursive
}
p($argv[1]);
echo join(",",$a); # Output

1

C ++, 159 byte

void c(int x,string r){int i,t=0,s=r.size();if(s<8){if(r[0]>48){for(i=0;i<s;i++)t+=(r[s-i-1]-48)*1<<i;if(t==x)cout<<r<<" ";}for(char n=48;n<51;n++)c(x,r+n);}}

Provalo qui


1

k, 21 byte

Utilizza lo stesso metodo della risposta Golfscript di Peter Taylor

{X@&x=2/:'X:3\:'!x*x}

Esempi:

k) {X@&x=2/:'X:3\:'!x*x}9
(1 2 1;2 0 1;1 0 0 1)
k) {X@&x=2/:'X:3\:'!x*x}10
(1 2 2;2 0 2;2 1 0;1 0 0 2;1 0 1 0)
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.