Sayıları ikiliye dönüştür… ancak ikişer ikişer de kullanabilirsiniz


20

Bu numberphile videoda bahsedilen "ikili, ancak ikişer" gösterimi temelinde , tek bir sayıyı girdi olarak alan ve ikiye izin verilen bir "ikili" sistemde bu sayının tüm varyasyonlarını çıktılayan bir işlev yazın .

kurallar

  • Kod tam bir program değil, sadece bir işlev / yöntem olmalıdır
  • Girdi, işleve tek parametre olarak iletilen bir tam sayıdır
  • Çıktı, "ikili, ancak ikişerli" gösterimine dönüştürülen giriş numarasının tüm geçerli varyasyonlarıdır
  • Çıktı, işlevin dönüş değeridir, ancak açık olduğu sürece (ör. 3 inç, 3 dize, virgül / boşlukla ayrılmış dize, dizi dizisi, vb.) Uygun olan herhangi bir biçimde olabilir, sıra önemsizdir
  • Bir dilin sonucu elde etmek için yerleşik bir işlev içermesi olası bir durumda, izin verilmez
  • Bayt cinsinden en kısa kod kazanır

Çıktının açıklaması

Örneğin, sayıyı geçtiyseniz, 9bunu ikili olarak dönüştürebilirsiniz 1001, ancak 2her konumda s'ye izin verdiyseniz , bu tabloda gösterildiği gibi 201(ie 2*4 + 0*2 + 1*1) veya 121(ie 1*4 + 2*2 + 1*1) olarak da yazabilirsiniz :

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

Bu nedenle, geçilirse 9, işlevinizin üç sayıyı döndürmesi gerekir 1001, 201ve 121.

Biçim ve sipariş kadar uzun, çok açık olarak (yani alakasız [121,201,1001], "0201 0121 1001", ("1001","121","201")bir girdi verildiğinde geçerli sonuçlardır 9).

Örnekler

  • 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
İki? İkili mi? Bu kuantum hesaplama mı?
Matthew Roh

Yanıtlar:


10

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

GolfScript:

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

Bu, anonim bir işlev oluşturur (anonim işlevlerin izin verilebilirliği hakkında meta tartışmaya bakın ).

Çevrimiçi demo

CJam'a doğrudan çeviri ( birkaç karakteri tıraş ettiği için Martin Büttner sayesinde )

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

teşrih

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

Kareleme işleminin nedeni, ikili gösterimde ikili olarak yorumlanan eşit en büyük değere kadar yinelememiz gerektiğidir ^. Çünkü 2 = 10, "normal" ikili temsili ^önemlidir. Bunu üçlüğe dönüştürürsek, "en kötü" vakaların 2'nin gücü olduğunu buluruz. İdeal bir yaklaşım, argümanı iktidara götürmek olacaktır ln 3/ln 2 ~= 1.585, ancak kareleme çok daha kısadır.


Eminim bir CJam çevirisi çok daha küçük olacaktır.
Doktor

1
@Optimizer go ;-)
John Dvorak

GolfScript? adamım böyle bir
çaylağım

8

Python 2 (59 bayt)

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

(@Grc, @xnor ve @PeterTaylor'a sohbete yardımcı oldukları için çok teşekkürler)

Basit özyineleme, ile çağrı S(23) veya benzeri.

açıklama

Genel fikir şudur: eğer nikili genişleme a ile bitiyorsa 1, sözde ikili ("ikili, ancak ikişerli") genişleme de a ile bitmelidir 1. Aksi takdirde 0veya ile bitebilir 2.

Bu yüzden son parçaya bakıyoruz n , böleriz ve buna göre dallanırız.

teşrih

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

Değişkenler:

  • n: Sözde ikili açılımları bulmak istediğimiz sayı
  • B: Sağdan sola oluşturulmuş sahte ikili bir dize

5

Bash + coreutils, 77

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

(Bu bir TAB grep ifadesindeki karakterdir.)

Bu, bu kuralı biraz büküyor:

"Bir dilin sonuca ulaşmak için yerleşik bir işlev içermesi olası bir durumda, buna izin verilmiyor"

İçinde ihtiyacımız olanın tersinedc sahip olduğu ortaya çıkıyor . Örneğin, giriş tabanını 2'ye ayarlarsak ve ikililerle ikili bir sayı girersek, doğru şekilde ayrıştırır. (Benzer şekilde giriş modu temel 10 ise, AF ondalık "basamak" 10-15 olarak ayrıştırılır).

seqondalık olarak ayrıştırılan n'nin standart ikili gösterimine kadar tüm ondalık sayıların bir listesini oluşturur. Ardından, {0,1,2} dışında bir şey içeren tüm sayılar filtrelenir. Sonra dcn'yi geri değerlendirdiğini görmek için kalan sayıları ikili olarak ayrıştırır.

Bash fonksiyonları sadece 0-255 skaler tamsayılarını "geri" döndürebilir. Bu yüzden listeyi "geri dönme" yöntemim olarak STDOUT'a basma özgürlüğünü alıyorum. Bu kabuk betikleri için deyimseldir.

Çıktı:

$ 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]]

bu sadece kaba kuvvetli bir çözümdür. çok verimsizdir, çünkü 3 ^ n olasılıktan sıkılması beklenmektedir.


3

Jelly , 10 bayt, dil postdates zorluğu

ṗ@3Ḷ¤Ḅ=¥Ðf

Çevrimiçi deneyin!

Girişe eşit sayıda hiper bite kadar bir bruteforce çözümü (bu format "hiperbiner" olarak bilinir). Bu nedenle, O (3 n ) 'de çalışan inanılmaz derecede verimsiz .

açıklama

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

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

Yıkmak

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 bayt

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

Burada test edin


1

k, 21 bayt

Peter Taylor'ın Golfscript cevabı ile aynı yöntemi kullanır

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

Örnekler:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.