Converta números em binários ... mas você também pode usar dois

20

Com base na notação "binária, mas com dois" mencionada neste vídeo numérico , escreva uma função que aceite um único número como entrada e produza todas as variações desse número em um sistema "binário", onde dois são permitidos.

Regras

  • O código deve ser apenas uma função / método, não um programa completo
  • Entrada é um número inteiro passado como único parâmetro para a função
  • Saída é todas as variações válidas do número de entrada convertido para a notação "binária, mas com dois"
  • Saída é o valor de retorno da função, mas pode estar em qualquer formato que seja conveniente, desde que seja óbvio (por exemplo, 3 polegadas, 3 cordas, string delimitada por vírgula / espaço, matriz de entradas, etc.), a ordem não é importante
  • No caso improvável de um idioma conter uma função interna para obter o resultado, não é permitido
  • O código mais curto em bytes é o vencedor

Explicação da saída

Por exemplo, se você passou o número 9, pode convertê-lo em binário como 1001, mas se você permitir 2s em cada posição, também poderá escrevê-lo como 201(ie 2*4 + 0*2 + 1*1) ou 121(ie 1*4 + 2*2 + 1*1), conforme mostrado nesta tabela:

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

Então, se aprovada 9, sua função seria necessário para retornar os três números, 1001, 201e 121.

Formato e ordem são irrelevantes, contanto que é óbvio (ou seja [121,201,1001], "0201 0121 1001", ("1001","121","201")são resultados válidos quando dado uma entrada de 9).

Exemplos

  • 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
fonte
3
Não existem dois.
precisa saber é o seguinte
1
Dois? Em binário? Isso é computação quântica?
Matthew Roh

Respostas:

10

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

GolfScript:

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

Isso cria uma função anônima (consulte a meta-discussão sobre permissibilidade de funções anônimas ).

Demonstração online

Uma tradução direta para o CJam é (com agradecimentos a Martin Büttner por raspar alguns caracteres)

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

Dissecação

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

A razão para a operação quadrática é que precisamos iterar até o maior valor possível cuja representação ternária, interpretada em binário, seja igual a ^. Desde então 2 = 10, a representação binária "normal" de ^é a que importa. Se convertermos isso em ternário, descobriremos que os "piores" casos são potências de 2. Uma abordagem ideal seria levar o argumento ao poder de ln 3/ln 2 ~= 1.585, mas a quadratura é muito menor.

Peter Taylor
fonte
Aposto que uma tradução CJam será muito menor.
Optimizer
1
@Optimizer vá em frente ;-) #
John Dvorak
GolfScript? homem que eu sou tal um noob
pythonian29033
8

Python 2 (59 bytes)

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

(Muito obrigado a @grc, @xnor e @PeterTaylor por ajudarem no bate-papo)

Recursão simples, chamada com S(23)ou similar.

Explicação

A idéia geral é que, se na expansão binária de um arquivo terminar em a 1, qualquer expansão pseudo-binária ("binária, mas com dois") também deverá terminar com a 1. Caso contrário, pode terminar com 0ou 2.

Portanto, olhamos para o último pedaço de n, dividimos e ramificamos de acordo.

Dissecação

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

Variáveis:

  • n: O número que queremos encontrar expansões pseudo-binárias de
  • B: Uma sequência pseudo-binária sendo criada da direita para a esquerda
Sp3000
fonte
5

Bash + coreutils, 77

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

(Esse é um TABcaractere na expressão grep.)

Isso está dobrando um pouco esta regra:

"No caso improvável de que um idioma contenha uma função interna para alcançar o resultado, isso não é permitido"

Acontece que dctem o inverso do que precisamos incorporar. Por exemplo, se definirmos a base de entrada como 2 e inserirmos um número binário com dois, ele será analisado corretamente. (Da mesma forma, se o modo de entrada for a base 10, AF será analisado como "dígitos" decimais 10-15).

seqcria uma lista de todos os números decimais até a representação binária padrão de n, analisada como decimal. Todos os números que contêm algo diferente de {0,1,2} são filtrados. Em seguida, dcanalisa os números restantes como binários para ver qual avaliar de volta para n.

As funções bash podem apenas "retornar" números inteiros escalares de 0 a 255. Então, estou tomando a liberdade de imprimir a lista para STDOUT como minha maneira de "retornar". Isso é idiomático para scripts de shell.

Saída:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$
Trauma Digital
fonte
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]]

isso é apenas uma solução de força bruta. é muito ineficiente, porque é esperado analisar três possibilidades.

orgulhoso haskeller
fonte
3

Geléia , 10 bytes, desafio pós-datas de idiomas

ṗ@3Ḷ¤Ḅ=¥Ðf

Experimente online!

Uma solução bruteforce com até um número de hiperbits igual à entrada (esse formato é conhecido como "hiperbinário"). Como tal, é incrivelmente ineficiente, rodando em O (3 n ).

Explicação

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

fonte
2

PHP, 138 bytes

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

Demolir

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
fonte
1

C ++, 159 bytes

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

Teste aqui

Johan du Toit
fonte
1

k, 21 bytes

Usa o mesmo método da resposta Golfscript de Peter Taylor

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

Exemplos:

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
fonte