복소수 이진수


36

하자의 간단한 생성 surjective 에 양의 정수에서 매핑 가우스 정수 이며, 복소수 실수 부와 허수 부분이 정수입니다.

예를 들어 양의 정수가 주어지면 4538선행을 사용하지 않고 이진수로 표현하십시오 0.

4538 base 10 = 1000110111010 base 2

후행을 제거하십시오 0.

100011011101

하나 이상의 실행 교체 0하나와의를 +:

1+11+111+1

모든 교체 1의와 i의 :

i+ii+iii+i

결과 복합 표현식을 평가하고 단순화 된 가우스 정수를 출력하십시오.

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

출력은 전통적인 수학적 방식으로 표현되거나 실수 부분과 복잡한 부분에 대해 두 개의 개별 정수로 제공 될 수 있습니다. 예를 4538들어, 다음 중 하나가 좋습니다.

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

추천 입력 용 29등 mathy 포맷 출력 0, 0i또는 0+0i모든 미세.

언어에 더 자연스러운 경우 j대신 다른 것을 사용 i하는 것이 좋습니다.

바이트 단위의 가장 짧은 코드가 이깁니다.


제목에서 나는 도전이 이진수로 복잡한 숫자에 관한 것이라고 생각했다 4+2j.-> 100+10j...
Erik the Outgolfer

답변:


22

MATL , 7 바이트

BJ*Y'^s

온라인으로 사용해보십시오!

작동 원리

4538예를 들어 입력 을 고려하십시오 .

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에서 7 바이트, 그리고 내가 얻을 수있는 최선 은 MATLAB에서 58입니다 . =)
Stewie Griffin

1
@StewieGriffin은 그래프 또는 플로팅과 관련하여 쇼에서 쉽게 최고를 보여줍니다.
Magic Octopus Urn 12'12

13

젤리 , 8 바이트

BŒgaıP€S

온라인으로 사용해보십시오!

작동 원리

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

파이썬 2, 53 바이트

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

골프를하려고했는데 골프를 타는 것 같지만 아이디어가 부족합니다 ...


1
그것이 (k or 1)최적 인 것 같지는 않지만, 내가 생각할 수있는 유일한 것은 (k+0**k)...
ETHproductions

@ETHproductions 내 생각은 정확하지만 불행히도 0**k복잡한 경우에는 작동하지 않습니다 k...
Sp3000

6

매스 매 티카, 44 38 바이트

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

설명

#~IntegerDigits~2

(기재 (2)에 입력 변환 4538된다 {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0})

I*

곱하기 I( {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0}가 됨 {I, 0, 0, 0, I, I, 0, I, I, I, 0, I, 0})

Split

런으로 나누기 ( {I, 0, 0, 0, I, I, 0, I, I, I, 0, I, 0}가 됨 {{I}, {0, 0, 0}, {I, I}, {0}, {I, I, I}, {0}, {I}, {0}})

1##&@@@ ...

(레벨 2에서 제품을 찾기 {{I}, {0, 0, 0}, {I, I}, {0}, {I, I, I}, {0}, {I}, {0}}가된다 {I, 0, -1, 0, -I, 0, I, 0})

Tr

결과를 합산하십시오. ( {I, 0, -1, 0, -I, 0, I, 0}된다 -1 + I)


빼기 1 바이트 :Tr[Times@@@(I*Split@RealDigits[#,2][[1]])]&
martin

1
@ martin 글쎄, 나는 당신의 곱셈에 대한 아이디어를 I먼저 사용 했지만 IntegerDigits결국 더 짧아졌습니다.
JungHwan Min

yes-훨씬 낫다 :)
martin


5

자바 스크립트 (ES6), 67 64 바이트

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 요소 배열로 출력합니다.

설명

JavaScript에는 허수가 없기 때문에 실수와 허수 부분을 별도의 변수로 추적해야합니다. 이 작업을 수행하는 가장 쉬운 방법은 실제 배열이 먼저 인 단일 배열입니다. i[0,1] , i 2 (또는 -1 )을 [-1,0]으로 , i 3 (또는 -i )를 [0, -1]으로 , i 4 (또는 1 )을 [1 , 0] .

먼저 숫자를 2로 반복해서 나누고 이진 표현으로 각 런을 수집합니다. n 개의 각 런은 i n에 해당합니다 . 이는 두 항목 배열 에서 인덱스 n & 1 의 항목에 1-(n & 2) 를 추가하는 것에 해당합니다 . 우리는 그렇게합니다.

아마도 더 많은 설명을 추가해야하지만 설명이 필요한 다른 것을 생각할 수 없습니다. 궁금한 점이 있으면 언제든지 의견을 말하십시오.


5

파이썬 199 129 124 116 94 90 71 63 61 바이트

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

입력은 숫자 자체입니다.
출력 형식이고 (a+bj), j허수 단위이다. 0j대신에 출력됩니다(0+0j)

먼저 이진으로 변환하십시오. '0b'끄기를 자릅니다 . 후행 0을 죽입니다. 0 블록을 구분 기호로 사용하여 분할하십시오. 각 블록을에 매핑하십시오 1j ** len. 그런 다음 전체의 합계를 가져옵니다.

플러스로 변환하지 않음으로써 -70 바이트
-5 바이트 정규식이 더 짧습니다. 한 번만 호출 된 불필요한 두 변수를 제거하여
-8 바이트 이상한 대신 복잡한 숫자를 사용하여
-22 바이트 . 복잡한 숫자를 알려주는 @Dennis의 답변에 감사드립니다!
-4 바이트 그 실현에 의해 map이상을 제외하고, 지능형리스트 일을 그냥 멋진 방법입니다. 정규식으로 오류를 피하고 피하는 약간 간결한 방법으로 전환하여
-19 바이트j ** 0 . @Griffin의 의견에서 영감을 얻었습니다. 감사! :)
-8 바이트if파트를 끝 으로 이동합니다 .
-2 바이트 대신 대괄호를 제거하여 생성기 표현식으로 2 바이트를 절약 한 @Griffin에게 감사드립니다!


나는 꽤 비슷한 것을 얻었으므로 별도의 답변을 게시하지는 않지만 조금 더 짧습니다.sum(1j**x.count('1')for x in bin(input()).split('0')if x)
Griffin

@ 그리핀 니스. 1블록 을 계산하는 다른 방법을 사용하고 내 것과 같이 정규 표현식을 사용하지 않기 때문에 별도의 답변을 게시 할 수있을 정도로 다르다고 생각합니다 . 또한 코드가 내 버전보다 훨씬 우수하기 때문에 코드를 훔치고 싶지 않습니다. :)
HyperNeutrino

@Griffin 나는 길이가 1아닌 s 를 계산하는 것을 제외하고는 솔루션과 동일한 길이의 다른 솔루션을 찾았 습니다 0x. if끝까지 이동한다는 아이디어에 감사드립니다 . 나는 그것이 다른 방식으로 작동한다는 것을 결코 알지 못했을 것입니다!
HyperNeutrino

당신은 목록 이해가 필요하지 않습니다. 대괄호를 제거하여 발전기 식으로 만듭니다
Griffin

@ 그리핀 오. 괜찮 감사! 나는 미래의 골프를 위해 기억할 것입니다
HyperNeutrino

4

MATLAB, 58 바이트

@(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.   

285프로세스를 설명하는 데 사용합시다 :

temp1 = dec2bin(285)
      = 100011101

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

운 좋게 MATLAB에서 1+++1와 같이 동작 1+1하므로 위의 값은 다음과 같습니다 1+111+1.

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

이제이 strrep전화는 진짜 보석입니다! 삽입 i*1하여 1우리는 정말 멋진 것을 얻습니다. 하나만 있다면 1, 우리는 단순히 얻을 i*1이다 i. 둘 이상이 있으면 i*1반복되고 시퀀스로 연결됩니다 i*1i*1i*1i*1. i==1iMATLAB 부터는 다음 과 1i*1==i같습니다 i*i*i*i.

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

추가는 .0여기에 불필요한 보이지만의 마지막 문자는 경우가 필요한 temp3입니다 +. i*10위의 경우에 0을 추가 할 수 없으므로 잘못된 결과가 발생합니다.

그리고 마지막으로:

eval(temp4)
0.0000 + 1.0000i

몇 가지 이유로 옥타브에서는 작동하지 않습니다. strrep그것은 (실제 문자가 필요, 입력으로 ASCII-값을받을 수 없어 '0'대신을 48). 또한, +++단지로 평가하지 않는 +즉, 증가 / 감소 바로 가기를 파괴하는 것처럼, 옥타브에 x++x--.


1
eval:-P 사용을 위해 항상 +1 ? 1i대신 사용할 수 없습니까 1*i?
Luis Mendo

1
오, 당신은 그것을 다르게 사용하고 있습니다. 매우 영리한!
Luis Mendo

감사합니다 :-) 인정해야합니다, 나는 그 i*1부분 에 꽤 만족했습니다 ...
Stewie Griffin


2

수학, 84 바이트

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

익명의 기능. 숫자를 입력으로 사용하고 복소수를 출력으로 반환합니다.


6
와우, Mathematica에 내장 된 것이 없다는 것에 놀랐습니다!
HyperNeutrino

2

Mathematica, 75 바이트

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

LegionMammal978이 23 분 전에 게시 한 것과 거의 동일한 솔루션을 독립적으로 개발했습니다! 공백은 이웃 식의 곱셈으로 취급되므로 (Mathematica의 내부 제곱근 -1에 대한)로 대체 1하면 I 작동합니다. 내가 즉 필요성을 피함으로써, 다른 솔루션에 저장된 장소는 StringTrim항상 추가하는 것입니다 -0:의 진수 종료하면 1, 다음 식의 끝이에 ...I-0있는 값에 영향을주지 않습니다; 이진수가 '0'으로 끝나는 경우이 표현식은 끝나고 ...+-0"음수 0 추가"로 구문 분석되어 후행 더하기 부호를 제거합니다.


2

MATLAB, 99 바이트

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

테스트 사례 :

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

2

하스켈, 102 91 89 87 바이트

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)

반복해서 2로 나누고 비트를 확인합니다. 어큐뮬레이터의 유지 i^(number of odds)a+b*i으로 부호화를 [a,b]하고 *i있다 [a,b]↦[-b,a](90도 회전). 초기에는 (*2)첫 번째 비트에 대한 조회를 피하는 것이다.

사용법 (예를 들어 @OwenMorgan 덕분에) :

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

1

자바, 172 바이트

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

클로저, 183 바이트

#(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))))

내가 할 수 있습니까?

다음과 같이 기능을 사용하십시오.

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

1

실제로 35 바이트

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

온라인으로 사용해보십시오!

설명:

├'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

대략 동등한 Python 3 코드 :

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

온라인으로 사용해보십시오!


와 '공의에 분할 '0@s하고 사용 ``░하면 4 바이트를 저장해야 후행 빈 문자열을 트리밍 할 수 있습니다.
Sherlock9

1

젤리 , 10 바이트

이것은 Dennis의 Jelly 답변보다 낫지는 않지만 어쨌든 Jelly 답변에 손을 대고 싶었습니다. 골프 제안을 환영합니다! 온라인으로 사용해보십시오!

BŒrm2Ṫ€ı*S

언 골핑

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.

위의 링크에서 입력 1 반환 1j 입력 2 반환 1j .... 맞습니까?
RosLuP

@RosLuP 네, 맞습니까? 우리는 후행 0을 제거하기 때문에 1 => 1 => 1j와 같습니다 2 => 10 => 1 => 1j.
Sherlock9

1

실제로 15 바이트

골프 제안을 환영합니다! 온라인으로 사용해보십시오!

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

풀기 :

         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

공리, 140, 131, 118 108 바이트

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는 가상의 비용입니다.

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

결과

(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

펄 6 ,  40  46 바이트

나는 이것을 상당히 빨리 생각해 냈습니다.

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

불행히도 현재 MoarVMRakudo 구현 에서는 정확하지 않습니다 .
say i ** 3; # -1.83697019872103e-16-1i

그래서 나는 다음으로 최선을 다해야했습니다.

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

넓히는:

*\             # 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

테스트:

.say for (4538, 29).map:

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

# -1+1i
# 0+0i


0

PHP, 87 바이트

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

ETHproductions 솔루션과 거의 동일합니다. 재귀 대신 반복적입니다.
명령 라인 세트 변수의 입력 값을 사용 ${0}하고 ${1}.


0

TI 기본 (TI-84 Plus CE), 70 바이트

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

이진 문자열로 변환 할 내장 기능이 없으므로 (문자열을 구문 분석하지 않아도 됨)이 프로그램은 수동으로 2로 나누고 1이 표시 될 때마다 N을 증가시키고 i ^ N을 S에 추가하고 (N> 0) 재설정 0이 보이면 N입니다.



0

R , 54 바이트

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

온라인으로 사용해보십시오!

n%/%2^(0:log2(n))%%2이진수의 벡터를 계산합니다. 실행 길이 인코딩을 사용하여 R의 complex유형을 사용하여 적절한 합계를 계산하고 x$values0을 제거하기 위해를 곱합니다 .

complex하나의 요소로 구성된 벡터를 반환합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.