İkili İkili Genişleme


9

Normalde, bir sayıyı her bir terim için 0veya 1her bir terim için katsayısı olan 2 güçle atayarak ikili sayılara ayırırız :

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

Seçim 0ve 1... çok ikili değil. Gerçek ikili genişlemeyi 2'lik güçlerle genişleterek gerçekleştiririz , ancak katsayısı 1veya -1yerine:

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

Şimdi bu ikili görünüyor.

Herhangi bir pozitif sayı göz önüne alındığında, aşağıdakileri görmek önemsiz olmalıdır:

  • Her tek sayının sonsuz sayıda gerçek ikili açılımı vardır
  • Her çift sayının gerçek ikili genişletmesi yoktur

Dolayısıyla, gerçek bir ikili genişlemenin iyi tanımlanması için, genişlemenin en az , yani en kısa uzunlukta olması gerekir.


Herhangi bir pozitif, tek tamsayı göz önüne alındığında n, gerçek ikili genişlemesini, en anlamlı basamaktan en az anlamlı basamağa (veya ters sırada) döndürün.

Kurallar:

  • Bu olduğu gibi , bunu mümkün olan en kısa bayt sayısında yapmayı hedeflemelisiniz . Yerleşiklere izin verilir.
  • Katsayıları temsil edebilen ve listeleyebilen herhangi bir çıktı kabul edilebilir: bir dizi, ayırıcılı bir katsayı dizisi, vb.
  • Standart golf sahaları geçerlidir.
  • Programınız, dilinizin standart tamsayı boyutundaki değerler için çalışmalıdır.

Test Durumları

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]

İlgili ama oldukça farklı.
Giuseppe

4
Basit algoritma: Taban 2'ye dönüştürün, 0'ları -1'lerle değiştirin, LSD'yi öne yerleştirin.
Josiah Winslow

Vual: Aşağı oyları açıklamıyordum, sadece kendi dillerinde taban dönüşüm komutları olan insanlar için bir algoritma özetliyordum.
Josiah Winslow

Gerçekten ikili olmaya çok hevesli olduğunuz için, değeri her zamanki yer değeriyle, ancak iki eyaletin yeni yorumuyla paketlenmiş bitler olarak döndürebilir miyiz? yani elektriksel olarak sadece yüksek veya düşük voltaj (veya her neyse) ve düşük voltaj durumu 0yerine standart hata ayıklayıcılar yazdırılırsa benim hatam değil -1. Bitleri alan arayan ne demek istediğini bilir. (Hala önemsiz olmayan bir bit manipülasyon egzersizi, çünkü bir döndürme hakkı sadece 32 önemli bite sahipse çalışır. Örneğin 5 bitlik bir sayı 5'lik bir döndürme genişliğine ihtiyaç duyar.)
Peter Cordes

Çıktının ayırıcılar içermesi gerekiyor mu? Mi 111-1-1için geçerli bir çıkış 25?
Oliver

Yanıtlar:


7

Japt , 6 bayt

¤é r0J

Çevrimiçi deneyin!

Açıklama:

¤é 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, dönme; bu yüzden benim için çalışmıyor.
Shaggy

2
Döndürme ??? dagnabbit.
Giuseppe

3

Pyth ,  12  11 bayt

|R_1.>jQ2 1

Burada deneyin!


Nasıl?

| R_1.> JQ2 1 Tam program.

      jQ2 Girdiyi ikili listeye dönüştürür.
     .> 1 Yukarıdaki listeyi sağa doğru 1 yer döndürerek döndürün.
| R_1 0 ile -1 değiştirin.
               Örtük olarak çıktı.

Öncelikle, görevin sadece " 0ikili yazıdaki -1s'yi s ile değiştirmek ve sağa 1 yer değiştirmek " olduğunu fark ediyoruz . - Tam olarak bunu yapmalıyız! İkili dönüşüm bize bir 0s ve 1s listesi verir . Burada tek yapmamız gereken dönüştürmek 0için golf bir yol bulmak -1. Bitsel operatör |(bitwise VEYA) arkadaşımızdır. İkili gösterim üzerindeki harita |ve ile değiştirildi -1. Geçerli sayı ise 0, dönüştürülür -1.


Daha iyi bir yol olduğunu sanmıyorum. ;)
Josiah Winslow

@JosiahWinslow Yapıyorum ... Bulmaya çalışıyorum
Bay Xcoder

Hımm? Algoritma optimal görünüyor, belki de Pyth'i bilmiyorum.
Josiah Winslow

@JosiahWinslow Daha iyi bir yol buldum. Sözdizimsel olarak daha iyi bir yol, algoritmik değil daha iyi bir yol.
Bay Xcoder

@ Mr.Xcoder Ve şimdi gerçekten en azından benim için bir şey yok.
Outgolfer Erik


3

JavaScript (ES6), 35 34 bayt

f=n=>n?[...f(n>>=1),!n|n%2||-1]:[]

Test snippet'i


2

Perl 6 , 72 bayt

Kesinlikle daha iyi bir yol var, ama sahip olduğum şey bu ...

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

Çevrimiçi deneyin!

Açıklama : Bir argüman ( ->$a) alan bir işlevdir . Önce gerekli katsayıların sayısını ( $a.base(2).chars= temel 2 gösterimindeki karakter sayısını) alırız, sonra Xbu çiftlerin bir Kartezyen ürününü ( ) yaparız (1,-1). ( Anlamı [X]: aşağıdaki listeyi azaltın X.) Böylece 1s ve -1'lerin tüm olası kombinasyonlarının bir listesini alırız. Sonra grepyalnızca verilen sayıyı kodlayan listeleri filtreleriz ( )$a . Sadece bir tane var, bu yüzden katsayıları olan bir liste listesi alıyoruz.

Grep bloğu bunu yapar: argümanını list ( @^a) olarak alır , tersine çevirir ve 0,1,2,..."sol bit kaydırma" operatörünü kullanarak sonsuz bir listeyle sıkıştırır +<. Daha kısa liste biter bitmez zipping durur (bizim için iyi!) Sonra tüm sonuçları toplayıp verilen sayı ile karşılaştırırız. Kullanmak zorunda kaldık .reverseçünkü OP, katsayıların en önemliden en önemliye doğru olmasını istiyor.




1

J, 11 bayt

1-~2*_1|.#:

Çevrimiçi deneyin!

Algoritma için @JosiahWinslow'a teşekkürler.

Dönüşümü kısaltmaya ilişkin düşünceleriniz var mı? Düşüncelerim !.-fit kullanmaktır (nvm, sadece dönüşümün toleransını değiştirir).

Kullanılması {-Al 1 karakteriyle uzundur.

_1 1{~_1|.#:

1

Java 8, 101 bayt

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

Port of @Oliver'in Japt cevabı , birkaç bayt daha ile ..;)

Bu String yaklaşımı yerine matematiksel bir yaklaşım kullanılarak kesinlikle golf yapılabilir.

Açıklama:

Burada deneyin.

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 bayt

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

Çevrimiçi deneyin!

Oliver'ın algoritmasını uygular , ancak basamakları ters sırada döndürür. nAsla eşit olmadığından emin olduğumuzdan , en az önemli olan bit (ilk) her zaman olur 1, bu yüzden onu kaldırırız ve 1R'deki dönüşü simüle etmek için sonuna ekleriz .

Basitçe koyarak rev( )aynı sırayla değerleri dönmelidir altbilgideki işlev çağrıları etrafında.

orijinal cevap, 88 bayt:

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

Anonim işlev; sütun adları eklenmiş olarak değerleri ters sırada döndürür .

Çevrimiçi deneyin!

Açıklama:

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
}

Bu çıktının geçerli olduğunu düşünmezdim; meydan okuma yazarından onay istemenizi öneririz.
Shaggy

@Shaggy ters siparişine açıkça izin verilir: from the most significant digit to the least significant digit (or in reversed order).bu nedenle bu tamamen kabul edilebilir olmalıdır.
Giuseppe

1
Ters düzen , ters işaretler değil. 25Örneğin için geçerli çıktı anlamına gelir [1,1,1,-1,-1]veya [-1,-1,1,1,1].
Shaggy

1
@Shaggy ah, haklısın, matematiği yanlış yaptım! 2*bits - 1yerine olmalıdır 1-2*bits. Teşekkür ederim.
Giuseppe




0

Golfscript, 14 13 14 bayt

-1 bayt çünkü %var olduğumu unuttum . +1 bayt çünkü ben de girdi bir dize unuttum.

~2base{.+(}%)\

1
Girişin bir tamsayı olarak geldiğini varsayacaksanız, {}bir blok yapmak için kodu sarmanız gerekir . Tam programlar yalnızca dize olarak girdi alabilir.
Peter Taylor

Um ... neyi? Demek istediğim, sayı bir sayı içeren bir dize yerine bir tamsayı olarak itiliyor.
Josiah Winslow

Bu durumda cevabınız tam bir program değildir ve bu nedenle bir "işlev" veya GolfScript söz konusu olduğunda bir blok olmalıdır. Bu nedenle {2base{.+(}%\}15 bayt içindir. Benzer şekilde CJam cevabınız.
Peter Taylor

Bu tam bir program. Golfscript'teki giriş, programın başlangıcında yığına dolaylı olarak itilir ve yürütmeden önce CJam'deki giriş belirtilir ve q komutu ile erişilir.
Josiah Winslow

GolfScript'e biraz aşinayım var . ( Ve CJam ). Bunun tam bir program olduğunu iddia etmek istiyorsanız, ön ek yapmanız gerekir ~.
Peter Taylor
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.