Karmaşık İkili Sayılar


36

Gerçek ve hayali parçaların tam sayı olduğu karmaşık sayılar olan pozitif tamsayılardan Gauss tamsayılarına kadar basit, kesin bir haritalama yapalım .

Olumlu bir tamsayı verildiğinde, örneğin 4538, hiçbir öncü olmadan ikili olarak ifade edin 0:

4538 base 10 = 1000110111010 base 2

İzleri silin 0:

100011011101

Bir veya daha fazla herhangi çalışır değiştirin 0tek olan 's +:

1+11+111+1

Tümünü 1ile değiştir i:

i+ii+iii+i

Elde edilen karmaşık ifadeyi değerlendirin ve sadeleştirilmiş Gauss tamsayısının çıktısını alın:

i+ii+iii+i = i+i*i+i*i*i+i = 2i+i^2+i^3 = 2i+(-1)+(-i) = -1+i

Çıktı geleneksel bir matematiksel yolla ifade edilebilir veya gerçek ve karmaşık parçalar için iki ayrı tam sayı olarak verilebilir. İçin 4538örneğin, bunlardan herhangi iyi olurdu:

-1+i
i-1
-1+1i
(-1, 1)
-1 1
-1\n1

Gibi girdileri 29gibi Mathy biçimlendirilmiş çıkışları, 0, 0iya da 0+0itüm ince.

Diliniz için daha doğalsa, jbunun yerine (veya başka bir şey) kullanmak iiyidir.

Bayt cinsinden en kısa kod kazanır.


Başlıktan itibaren, meydan okumaların ikili sayıdaki karmaşık sayılarla ilgili olacağını düşündüm, örneğin 4+2j-> 100+10j...
Outgolfer Erik,

Yanıtlar:


22

MATL , 7 bayt

BJ*Y'^s

Çevrimiçi deneyin!

Nasıl çalışır

4538Örneğin girişi düşünün .

B     % Implicit input. Convert to binary
      % STACK: [1 0 0 0 1 1 0 1 1 1 0 1 0]
J*    % Multiply by 1i
      % STACK: [1i 0 0 0 1i 1i 0 1i 1i 1i 0 1i 0]
Y'    % Run-length encoding
      % STACK: [1i 0 1i 0 1i 0 1i 0], [1 3 2 1 3 1 1 1]
^     % Power, element-wise
      % STACK: [1i 0 -1 0 -1i 0 1i 0]
s     % Sum of array. Implicit display
      % STACK: -1+1i

2
MATL'de 7 bayt, alabileceğim en iyi 58 ise MATLAB'da ... Orada güzel bir dil yaptınız! =)
Stewie Griffin,

1
@StewieGriffin, grafiğe veya çizime gelince, belki de matris aritmetiği için yazdığı harika cevaplardan geldiğinde, kolayca en iyisidir.
Sihirli Ahtapot Urn

13

Jöle , 8 bayt

BŒgaıP€S

Çevrimiçi deneyin!

Nasıl çalışır

BŒgaıP€S  Main link. Argument: n (integer)

B         Convert to binary.
          If n = 4538, this yields [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0].
 Œg       Group equal elements.
          This yields [[1], [0, 0, 0], [1, 1], [0], [1, 1, 1], [0], [1], [0]].
   aı     Logical AND with the imaginary unit.
          This yields [[ı], [0, 0, 0], [ı, ı], [0], [ı, ı, ı], [0], [ı], [0]].
     P€   Product each.
          This yields [ı, 0, -1, 0, -ı, 0, ı, 0].
       S  Sum.
          This yields -1+ı.

10

Python 2, 53 bayt

f=lambda n,k=0:(n and f(n/2,n%2*(k or 1)*1j))+~n%2*k

Bunu golf oynamaya çalışıyordum ve golf oynuyor gibi görünüyor ama fikirleri atmıyorum ...


1
Bu (k or 1)uygun gözükmüyor, ancak aklıma gelen tek şey (k+0**k)...
ETHproductions

@ETHproductions Düşüncelerim tam olarak, ama ne yazık ki 0**kkarmaşık için işe yaramaz k...
Sp3000

6

Mathematica, 44 38 bayt

Tr[1##&@@@Split[I*#~IntegerDigits~2]]&

açıklama

#~IntegerDigits~2

Girişi üs 2'ye dönüştürün. ( 4538Olur {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0})

I*

İle çarp I(( {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0}olur {I, 0, 0, 0, I, I, 0, I, I, I, 0, I, 0})

Split

Koşularla ayır ( {I, 0, 0, 0, I, I, 0, I, I, I, 0, I, 0}olur {{I}, {0, 0, 0}, {I, I}, {0}, {I, I, I}, {0}, {I}, {0}})

1##&@@@ ...

Ürünü 2. seviyede bulun. ( {{I}, {0, 0, 0}, {I, I}, {0}, {I, I, I}, {0}, {I}, {0}}Olur {I, 0, -1, 0, -I, 0, I, 0})

Tr

Sonucu toplayın. ( {I, 0, -1, 0, -I, 0, I, 0}olur -1 + I)


eksi 1 bayt:Tr[Times@@@(I*Split@RealDigits[#,2][[1]])]&
martin

1
@martin Peki, Iilk önce çarpma fikrinizi kullandım , ancak IntegerDigitsdaha kısa oldu.
JungHwan Min

evet - çok daha iyi :)
martin


5

JavaScript (ES6), 67 64 bayt

f=(n,q=0,a=[0,0])=>q|n?f(n/2,n&1?q+1:q&&0*(a[q&1]+=1-(q&2)),a):a
<input oninput="O.innerHTML=f(this.value)" type="number" step=1 min=0 value="4538">
<pre id=O></pre>

2 elemanlı bir dizi olarak çıktı verir.

açıklama

JavaScript hayali sayılara sahip olmadığından, gerçek ve hayali kısımları ayrı değişkenlerde izlememiz gerekir. Bunu yapmanın en kolay yolu, önce gerçek kısmı olan tek bir dizidedir. I ile temsil edilir : [0,1] , i 2 (ya da -1 ) halinde [-1,0] , i 3 (ya da -I gibi) [0, -1] , ve i 4 (veya 1 ) ve [1 , 0] .

İlk önce, sayıların her birini ikili gösterimlerinde toplayarak sayıyı 2'ye bölün. Her seferinde , n için olanlar tekabül i n . Bu , iki öğeli dizideki n & 1 dizinindeki öğeye 1 - (n & 2) eklenmesine karşılık gelir . Yani biz yapıyoruz.

Muhtemelen daha fazla açıklama eklemeliyim, ama başka ne açıklaması gerektiğini düşünemiyorum. Aklınıza gelebilecek herhangi bir soru ile yorum yapmaktan çekinmeyin.


5

Python, 199 129 124 116 94 90 71 63 61 bayt

print sum(1j**len(s)for s in bin(input())[2:].split('0')if s)

Giriş sadece sayının kendisidir.
Çıktı, hayali birimin (a+bj)olduğu biçimindedir j. 0jyerine çıkacak(0+0j)

İlk önce ikiliye dönüştürün. Kapatın '0b'. Sondaki sıfırları öldür. Sınırlayıcı olarak bir sıfır bloğu kullanarak bölün. Her bloğu ile eşle 1j ** len. Ardından, her şeyin toplamını alın.

Artıları dönüştürerek -70 bayt .
-5 bayt regex kısa.
-8 bayt , sadece bir kez çağrılan gereksiz iki değişkenden kurtularak.
-22 garip şey yerine karmaşık sayıları kullanarak bayt . @Dennis 'in bana karmaşık sayıları bildirdiği cevabı sayesinde!
-4 bayt bunun mapuzun süre hariç, liste kavramalarını yapmanın sadece süslü bir yolu olduğunu fark ederek .
-19 byte , hatalardan j ** 0kaçınmak ve regex'ten kaçınmak için hafif bir arcane yöntemine geçerek . @ Griffin tarafından yapılan yorumdan ilham alınmıştır. Teşekkürler! :)
Parçayıif sonuna kadar hareket ettirerek -8 bayt .
-2 bayt Bunun yerine bir jeneratör ifadesi yapmak için köşeli parantezleri kaldırarak 2 bayt tasarruf için @Griffin'e teşekkürler!


Oldukça benzer bir şey aldım, bu yüzden ayrı cevaplar sum(1j**x.count('1')for x in bin(input()).split('0')if x)
Griffin

@Griffin Güzel. Ayrı bir cevap gönderebilmenizin yeterince farklı olduğunu düşünüyorum çünkü 1blokları saymak için farklı bir yöntem kullanıyor ve benimki gibi regex kullanmıyor. Ayrıca, kodumu sizden çalmak istemiyorum çünkü sürümümden çok daha iyi. :)
HyperNeutrino,

@Griffin Uzunluğundan 1ziyade s saymak yerine sizin çözümünüzle aynı uzunlukta başka bir çözüm buldum , 0xilk önce parçayı alır . ifSonuna gitme fikri için teşekkürler ; Aksi takdirde işe yaradığını asla bilemezdim!
HyperNeutrino,

liste kavramasına gerek yok. Bir jeneratör ifadesi yapmak için köşeli parantezleri çıkarın
Griffin

@Griffin Oh. Tamam teşekkürler! Gelecekteki golf
oynamak

4

MATLAB, 58 bayt

@(x)eval([strrep(strrep(dec2bin(x),48,43),49,'i*1'),'.0'])

dec2bin(x) % converts the decimal value to a binary string of 1s and 0s.
strrep(dec2bin(x),48,43) % Substitutes ASCII character 48 with 43 (0s become +)
strrep(___,49,'i*1')     % Substitutes ASCII character 49 with 'i*1'
                         % 1s become 'i*1' (this is the gem)
eval([___,'.0']          % Appends .0 in the end and evaluates the expression.   

285Süreci göstermek için kullanalım :

temp1 = dec2bin(285)
      = 100011101

temp2 = strrep(temp1,48,43)
      = 1+++111+1

Neyse ki 1+++1tıpkı davranır 1+1yukarıdaki değerlendirir böylece için MATLAB'da: 1+111+1.

temp3 = strrep(temp2,49,'i*1')
      = i*1+++i*1i*1i*1+i*1

Şimdi bu strrep-Call gerçek mücevher! Ekleyerek i*1için 1gerçekten güzel bir şey olsun. Sadece bir tane varsa 1, biz sadece almak i*1olan i. Daha varsa bir sonra daha i*1tekrarlanır ve bir dizi halinde birleştirilmiş olur: i*1i*1i*1i*1. Yana i==1iMATLAB'te ve 1i*1==ibu basitçe: i*i*i*i.

temp4 = [temp3,'.0']
      = i*1+++i*1i*1i*1+i*1.0

Eklemeye .0burada gereksiz görünüyor, ancak son karakteri eğer ihtiyaç duyulan temp3bir olduğunu +. Sadece sıfır ekleyemiyoruz, çünkü bu i*10yukarıdaki durumda ve dolayısıyla yanlış sonuçta ortaya çıkacaktır .

Ve sonunda:

eval(temp4)
0.0000 + 1.0000i

Bu Octave'de birkaç nedenden dolayı işe yaramıyor. strrepASCII değerlerini girdi olarak alamaz, gerçek karakterlere ihtiyaç duyar ( '0'yerine 48). Ayrıca, +++sadece değerlendirmek değil +o arttırma / azaltma kısayolları kırmak gibi, Octave x++ve x--.


1
Kullanmak için her zaman +1 eval:-P Kullanmak 1iyerine kullanamaz 1*imısınız?
Luis Mendo,

1
Oh, farklı kullanıyorsunuz. Çok zeki!
Luis Mendo,

Teşekkürler :-) Kabul etmeliyim ki, i*1kısımdan oldukça memnun kaldım ...
Stewie Griffin


2

Mathematica, 84 bayt

ToExpression[#~IntegerString~2~StringTrim~"0"~StringReplace~{"0"..->"+","1"->"I "}]&

Anonim işlev Girdi olarak bir sayı alır ve çıktı olarak karmaşık bir sayı döndürür.


6
Vay canına, Mathematica'nın bunun için yerleşik bir özelliği olmadığı için şaşırdım!
HyperNeutrino,

2

Mathematica, 75 bayt

ToExpression[#~IntegerString~2~StringReplace~{"1"->"I ","0"..->"+"}<>"-0"]&

Bağımsız bir şekilde, LegionMammal978'in 23 dakika önce yayınladığı çözümün aynısı oldu! (Mathematica'nın -1'in karekökü için dahili sembolüdür) 1ile değiştirilir , I çünkü boşluklar komşu ifadelerin çarpımı olarak değerlendirilir. Diğer çözümde kaydettiğim yer, yani ihtiyaçtan kaçınılarak, StringTrimdaima eklenir -0: eğer ikili sayı sona ererse 1, o zaman bu ifade ...I-0, değerini etkilemeyecek şekilde biter ; İkili sayı '0' ile bitiyorsa, o zaman bu ifade ...+-0“negatif 0 ekle” olarak ayrıştırılır ve böylece izleyen artı işaretinden kurtulur.


2

Matlab, 99 Bayt

function c=z(b)
c=0;b=strsplit(dec2bin(b),'0');for j=1:numel(b)-isempty(b{end});c=c+i^nnz(b{j});end

Test durumları:

z(656) = 3i
z(172) = -1 + 2i
z(707) = -2 + i
z(32)  = i
z(277) = 4i

2

Haskell, 102 91 89 87 bayt

0%a=a
n%c@[a,b]|odd n=div n 2%[-b,a]|d<-div n 2=zipWith(+)c$d%[mod d 2,0]
(%[0,0]).(*2)

Tekrar tekrar ikiye böler ve biti kontrol eder. i^(number of odds)Nerede ve olduğu a+b*igibi kodlanmış bir akümülatörü tutar (90 derece döndürme). İlk , ilk bit için bir arama yapmaktan kaçınmaktır.[a,b]*i[a,b]↦[-b,a](*2)

Kullanım (örnekler için @OwenMorgan sayesinde):

(%[0,0]).(*2)<$>[656,172,707,32,277]
[[0,3],[-1,2],[-2,1],[0,1],[0,4]]

1

Java, 172 bayt

l->{int i=0,j=i;for(String x:l.toString(2).split("0")){int a=x.length();j+=a&1>0?(a&3>2?(a-3)/-4+1:(a-3)/4+1):0;i+=a&1<1?(a&3>1?(a-3)/4+1:(a-3)/-4+1):0;}return i+"|"j+"i";}

1

Clojure, 183 bayt

#(loop[x(clojure.string/split(Integer/toString % 2)#"0+")y[0 0]a 0](if(= a(count x))y(recur x(let[z([[1 0][0 1][-1 0][0 -1]](mod(count(x a))4))][(+(y 0)(z 0))(+(y 1)(z 1))])(inc a))))

Bunu yapmama izin var mı?

İşlevini şu şekilde kullanın:

(#(...) {num}) -> (Wrap the # function in brackets first!)

1

Aslında , 35 bayt

├'0' aÆô' @s"j+"j'jo`"1j*1"'1τ(Æ`Y≡

Çevrimiçi deneyin!

Açıklama:

├'0' aÆô' @s"j+"j'jo`"1j*1"'1τ(Æ`Y≡
├                                    binary representation of input
 '0' aÆ                              replace 0s with spaces
       ô                             trim leading and trailing spaces
        ' @s                         split on spaces
            "j+"j                    join with "j+"
                 'jo                 append "j"
                    `"1j*1"'1τ(Æ`Y   do until the string stops changing (fixed-point combinator):
                     "1j*1"'1τ(Æ       replace "11" with "1j*1"
                                  ≡  evaluate the resulting string to simplify it

Kabaca eşdeğer Python 3 kodu:

a='j+'.join(bin(eval(input()))[2:].replace('0',' ').strip().split())+'j'
b=0
while a!=b:b,a=a,a.replace("11","1j*1")
print(eval(a))

Çevrimiçi deneyin!


'0'lara bölmek '0@sve ``░takip eden boş dizeleri kesmek için kullanmak size dört bayt kazandırmalıdır.
Sherlock 9

1

Jöle , 10 bayt

Bu Dennis'in Jelly cevabından daha iyi değil ama yine de bir Jelly cevabında elimi denemek istedim. Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

BŒrm2Ṫ€ı*S

Ungolfing

BŒrm2Ṫ€ı*S   Main link. Argument: n (integer)

B            Convert n to binary.
 Œr          Run-length encode the binary list.
   m2        Every 2nd element of the run_length encoding, getting only the runs of 1s.
     Ṫ€      Tail each, getting only the lengths of the runs.
       ı*    The imaginary unit raised to the power of each run (as * is vectorized).
         S   Sum it all into one complex number.

Yukarıdaki bağlantıda, 1j girişi 1j girişi 2 2 dönüşü 1j ... Bu doğru mu?
RosLuP,

@RosLuP Evet, doğru mu? İzleyen 0'ı kaldırdığımızdan 1 => 1 => 1j, eşdeğerdir 2 => 10 => 1 => 1j.
Sherlock 9

1

Aslında 15 bayt

Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

├'0@s``░`lïⁿ`MΣ

Ungolfing:

         Implicit input n.
├        Convert n to binary.
'0@s     Split by '0's.
``░      Filter out non-truthy values.
`...`M   Map over the filtered result, a list of runs of '1's.
  l        Yield the length of the run of '1's.
  ïⁿ       Yield the imaginary unit to the power of that length.
Σ        Sum all of this into one complex number.

0

Aksiyom, 140, 131, 118 108 bayt

b(x)==(s:=0;repeat(x=0=>break;r:=x rem 2;repeat(x rem 2=1=>(r:=r*%i;x:=x quo 2);break);s:=s+r;x:=x quo 2);s)

% i hayali kostanttır.

sb(x:NNI):Complex INT==
  r:Complex INT;s:Complex INT:=0
  repeat
    x=0=>break
    r:=x rem 2
    repeat
       x rem 2=1=>(r:=r*%i;x:=x quo 2)
       break
    s:=s+r
    x:=x quo 2
  s

Sonuçlar

(3) -> b 4538
   The type of the local variable r has changed in the computation.
   We will attempt to interpret the code.
   (3)  - 1 + %i
                                                    Type: Complex Integer
(4) -> b 29
   (4)  0
                                                    Type: Complex Integer
(5) -> sb 299898979798233333333333333339188888888888888888222
   Compiling function sb with type NonNegativeInteger -> Complex Integer
   (5)  - 7 + 12%i
                                                    Type: Complex Integer
(6) -> b 299898979798233333333333333339188888888888888888222
   (6)  - 7 + 12%i
                                                    Type: Complex Integer

0

Perl 6 ,  40  46 bayt

Bunu oldukça hızlı bir şekilde buldum

*.base(2).comb(/1+/).map(i***.chars).sum

Ne yazık ki şu anda yanlış Rakudo üzerinde uygulanması MoarVM .
say i ** 3; # -1.83697019872103e-16-1i

Bu yüzden sonraki en iyi şeyi yapmak zorunda kaldım:

*.base(2).comb(/1+/).map({[*] i xx.chars}).sum

Expanded:

*\             # Whatever lambda
.base(2)       # convert to a Str representation in base 2
.comb(/ 1+ /)  # get a list of substrings of one or more 「1」s
.map({         # for each of those

  [*]            # reduce using 「&infix:<**>」
    i xx .chars    # 「i」 list repeated by the count of the characters matched

}).sum          # sum it all up

Ölçek:

.say for (4538, 29).map:

    *.base(2).comb(/1+/).map({[*] i xx.chars}).sum

# -1+1i
# 0+0i


0

PHP, 87 bayt

for($n=$argv[1];$n|$i;$n>>=1)$n&1?$i++:($i?$i=0*${$i&1}+=1-($i&2):0);echo"(${0},${1})";

Neredeyse ETHproductions'un çözümü ile aynı; özyinelemeli yerine sadece yinelemeli.
Komut satırından girdi alır, değişkenleri ayarlar ${0}ve ${1}.


0

TI-Basic (TI-84 Plus CE), 70 bayt

Prompt X
0→S
0→N
While X
If remainder(X,2
Then
N+1→N
int(X/2→X
Else
S+i^Nnot(not(N→S
X/2→X
0→N
End
End
S+i^Nnot(not(N

İkili bir dizgeye dönüştürülecek hiçbir yerleşik yapı yoktur (bir dize ayrıştırmak için de yoktur), bu nedenle bu program elle 2'ye bölünür, her 1 gördüğünde N artar ve i ^ N'ye S (N> 0) eklenir ve sıfırlanır N sıfır görürse.



0

R , 54 bayt

function(n,x=rle(n%/%2^(0:log2(n))%%2))sum(1i^x$l*x$v)

Çevrimiçi deneyin!

n%/%2^(0:log2(n))%%2İkili basamakların bir vektörünü hesaplar. Çalışma uzunluğu kodlamasını kullanarak, complexuygun toplamı hesaplamak için R'in tipini, x$valuessıfırların çıkarılmasıyla çarparak kullanırız.

complexBir elemanın vektörünü döndürür .

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.