Convertissez les nombres en binaire… mais vous pouvez également utiliser deux

20

Sur la base de la notation "binaire, mais avec deux" mentionnée dans cette vidéo numérique , écrivez une fonction qui prend un seul numéro en entrée et génère toutes les variations de ce nombre dans un système "binaire" où les deux sont autorisés.

Règles

  • Le code ne doit être qu'une fonction / méthode, pas un programme complet
  • L'entrée est un entier transmis comme seul paramètre à la fonction
  • La sortie est toutes les variations valides du nombre d'entrée converties en notation "binaire, mais avec deux"
  • La sortie est la valeur de retour de la fonction, mais peut être dans n'importe quel format qui convient à condition qu'elle soit évidente (par exemple, 3 ints, 3 chaînes, chaîne délimitée par des virgules / espaces, tableau d'ints, etc.), l'ordre est sans importance
  • Dans le cas peu probable où une langue contiendrait une fonction intégrée pour obtenir le résultat, elle est interdite
  • Le code le plus court en octets est le gagnant

Explication de la sortie

Par exemple, si vous passez le nombre 9, vous pouvez le convertir en binaire en tant que 1001, mais si vous avez autorisé 2s dans chaque position, vous pouvez également l'écrire comme 201(ie 2*4 + 0*2 + 1*1), ou 121(ie 1*4 + 2*2 + 1*1), comme indiqué dans ce tableau:

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

Donc, si elle est réussie 9, votre fonction devra renvoyer les trois nombres 1001, 201et 121.

Le format et l'ordre ne sont pas pertinents, tant qu'ils sont évidents (c. [121,201,1001]-à- d . "0201 0121 1001", ("1001","121","201")Sont des résultats valides lorsqu'ils reçoivent une entrée 9)

Exemples

  • 2 => 10, 2
  • 9 => 1001, 201, 121
  • 10 => 1010, 210, 202, 1002, 122
  • 23 => 2111, 10111
  • 37 => 100101, 20101, 100021, 20021, 12101, 12021, 11221
Alconja
la source
1
Deux? En binaire? Est-ce de l'informatique quantique?
Matthew Roh

Réponses:

10

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

GolfScript:

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

Cela crée une fonction anonyme (voir la méta-discussion sur la licéité des fonctions anonymes ).

Démo en ligne

Une traduction directe dans CJam est (avec merci à Martin Büttner pour avoir rasé quelques caractères)

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

Dissection

{             # 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
}

La raison de l'opération de quadrature est que nous devons itérer jusqu'à la plus grande valeur possible dont la représentation ternaire, interprétée en binaire, est égale à ^. Depuis 2 = 10, la représentation binaire "normale" de ^est celle qui compte. Si nous convertissons cela en ternaire, nous constatons que les "pires" cas sont des puissances de 2. Une approche optimale serait de prendre l'argument à la puissance de ln 3/ln 2 ~= 1.585, mais la quadrature est beaucoup plus courte.

Peter Taylor
la source
Je parie qu'une traduction CJam sera beaucoup plus petite.
Optimizer
1
@Optimizer allez-y ;-)
John Dvorak
GolfScript? homme, je suis un tel noob
pythonian29033
8

Python 2 (59 octets)

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

(Un grand merci à @grc, @xnor et @PeterTaylor pour leur aide dans le chat)

Récursivité simple, appel avec S(23)ou similaire.

Explication

L'idée générale est que si nl'expansion binaire de se termine par a 1, alors toute expansion pseudo-binaire ("binaire, mais avec deux") doit également se terminer par a 1. Sinon, cela pourrait se terminer par 0ou 2.

Par conséquent, nous regardons le dernier bit de n, diviser et se ramifier en conséquence.

Dissection

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

Variables:

  • n: Le nombre dont nous voulons trouver les extensions pseudo-binaires de
  • B: Une chaîne pseudo-binaire en cours de construction de droite à gauche
Sp3000
la source
5

Bash + coreutils, 77

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

(C'est un TABcaractère dans l'expression grep.)

Cela plie un peu cette règle:

"Dans le cas peu probable où une langue contiendrait une fonction intégrée pour obtenir le résultat, elle est interdite"

Il s'avère que cela dca l'inverse de ce dont nous avons besoin. Par exemple, si nous définissons la base d'entrée sur 2 et entrons un nombre binaire avec deux, il l'analysera correctement. (De même, si le mode d'entrée est en base 10, les AF sont analysés sous forme de "chiffres" décimaux 10-15).

seqcrée une liste de tous les nombres décimaux jusqu'à la représentation binaire standard de n, analysée comme une décimale. Ensuite, tous les nombres qui contiennent autre chose que {0,1,2} sont filtrés. Ensuite, dcanalyse les nombres restants comme binaires pour voir ceux qui reviennent à n.

Les fonctions Bash ne peuvent que "renvoyer" des entiers scalaires 0-255. Je prends donc la liberté d'imprimer la liste sur STDOUT comme ma façon de "revenir". C'est idiomatique pour les scripts shell.

Production:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$
Traumatisme numérique
la source
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]]

ce n'est qu'une solution de force brute. il est très inefficace, car il devrait traverser 3 ^ n possibilités.

fier haskeller
la source
3

Gelée , 10 octets, défi de postdates de langue

ṗ@3Ḷ¤Ḅ=¥Ðf

Essayez-le en ligne!

Une solution bruteforce jusqu'à un nombre d'hyperbits égal à l'entrée (ce format est appelé "hyperbinaire"). En tant que tel, il est incroyablement inefficace, fonctionnant en O (3 n ).

Explication

ṗ@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}

la source
2

PHP, 138 octets

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);

Panne

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
Jörg Hülsermann
la source
1

C ++, 159 octets

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);}}

Testez-le ici

Johan du Toit
la source
1

k, 21 octets

Utilise la même méthode que la réponse Golfscript de Peter Taylor

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

Exemples:

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)
skeevey
la source