기본 -1 + i에 추가


64

가우스 정수 형태의 복소수있는 a+biab모두 정수이다. 기수 -1 + i에서 모든 가우시안 정수는 기호를 나타내는 기호없이 숫자 0와를 사용하여 고유하게 표현할 수 있습니다 1.

예를 들어, 1100-1 + i는 10 진수 2를 나타냅니다.

1*(-1+i)^3 + 1*(-1+i)^2 + 0*(-1+i)^1 + 0*(-1+i)^0
= (2+2i) + (-2i) + 0 + 0
= 2

입력 값은 자리 -1 + i에서 두 개의 가우스 정수로 표시 01됩니다. 이것은 다음 형식 중 하나를 취할 수 있습니다.

  • 두 개의 분리 된 숫자 문자열
  • 01기본 -1 + i 숫자 (예 : 1100기본 -1 + i의 2) 를 나타내는 2 개의 10 진 정수
  • 기본 -1 + i 숫자를 나타내는 2 개의 이진 정수 (예 : 10 진수 12또는 0b1100기본 -1 + i의 2)
  • 영숫자가 아닌 단일 구분자로 두 자리 문자열 / 이진 정수를 분리하는 단일 문자열 (예 : 1100 1100또는 12,122 + 2)

두 가우스 정수의 합을 밑이 -1 + i로 출력하고 숫자를 사용하여 표시합니다 01(입력으로 허용되는 형식 중 하나로 반드시 같은 선택은 아님). 출력에는 유한 숫자의 선행 0이 포함될 수 있습니다.

함수 또는 프로그램은 각각 최대 30 자리의 입력을 위해 2 초 이내에 종료되어야합니다.

추가 설명

  • 입력에 외부 선행 0이 포함되어 있지 않다고 가정 할 수 있습니다. 특수한 0의 경우 0표현으로 또는 빈 문자열을 선택할 수 있습니다 .

테스트 사례

0, 0 => 0                                      # 0 + 0 = 0
0, 1 => 1                                      # 0 + 1 = 1
1, 1 => 1100                                   # 1 + 1 = 2
1100, 1100 => 111010000                        # 2 + 2 = 4
1101, 1101 => 111011100                        # 3 + 3 = 6
110111001100, 1110011011100 => 0               # 42 + (-42) = 0
11, 111 => 0                                   # i + (-i) = 0
11, 110 => 11101                               # i + (-1-i) = -1
10101, 11011 => 10010                          # (-3-2i) + (-2+3i) = (-5+i)
1010100101, 111101 => 1110100000100            # (-19+2i) + (3-4i) = (-16-2i)

더 긴 테스트 사례 :

11011011010110101110010001001, 111100010100101001001010010101 => 0
111111111111111111111111111111, 111111111111111111111111111111 => 100100100100100100100100100100
101101110111011101110111011101, 101101110111011101110111011101 => 11101001010001000100010001000100011100
100100010101001101010110101010, 100010011101001011111110101000 => 110000110010101100001100111100010

숫자 목록이 없습니까?
CalculatorFeline

@CatsAreFluffy 숫자 목록이 없습니다. 죄송합니다.
Sp3000

96
제목에서 로 변경 -1+i하여 1 바이트를 저장할 수 있습니다 i-1.
mbomb007

1
이제 다른 방법으로 변환해야합니다. : P
Rɪᴋᴇʀ

3
세계에는 1100 종류의 사람들이 있습니다. 이진을 이해하는 사람, 모르는 사람, 그것을 삼항으로 혼동하는 사람, 그것을 4 진법과 혼동하는 사람, 5 진법과 혼동하는 사람, -1 + i와 혼동하는 사람, 혼동하는 사람 베이스 6,베이스 7과 혼동하는 사람들베이스 8과 혼동하는 사람들,베이스 9와 혼동하는 사람들 ...
wizzwizz4

답변:


42

파이썬 2, 98 97 91 84 바이트

s=input();L=1
for _ in`s`*8:s+=1098*int(str(s).translate('0011'*64));L*=10
print s%L

이것은 10 진수로 I / O를 수행합니다. 정수는 영숫자가 아닌 문자로 구분해야합니다 +.

2 바이트를 골라 낸 @xnor에게 감사드립니다!

Ideone에서 사용해보십시오 .

작동 원리

에서는 단지베이스 산술 저자는 형태의베이스에서 복소수 승산을 추가하는 방법을 도시 -n + I .

base -1 + i의 경우 추가는 carry를 사용한 일반 이진 추가와 유사하게 수행되며 두 가지 차이점이 있습니다.

  • 1 을 다음 상위 위치 로 운반하는 대신 110 을 다음 3으로 운반 합니다.

  • 캐리 숫자는 무기한으로 전파 될 수 있습니다. 그러나 선행 0이 없으면 합계 a + b 의 최대 ab 보다 최대 8 자리가 더 큽니다 .

다음과 같이 진행합니다.

  1. 먼저, 숫자가 10 진수 인 것처럼 ab 를 더합니다.

    들면 A = 10101B = 11,011 , 이는 범 21,112을 .

  2. 다음으로, 우리 는 1 보다 큰 숫자를 1 로 바꾸고 , 다른 숫자 는 0 으로 바꾸어 새로운 숫자를 만듭니다. 1

    합계 21112의 경우 10001이 됩니다.

  3. 1 보다 큰 각 숫자에 대해 , 우리는 그 숫자에서 2 를 빼고 110 을 다음 3 개의 더 높은 위치로 옮깁니다. 1098 = 10 * 110-2 이기 때문에 2 단계의 결과에 1098 을 곱한 다음 해당 곱을 합계에 더하면됩니다. 2

    합계 21112의 경우 21112 + 1098 * 10001 = 21112 + 10981098 = 11002210이 됩니다.

  4. 우리는 2 단계 와 3 단계를 총 d * 8 번 반복합니다. 여기서 da + b 의 자릿수입니다 .

    초기 합 21112 의 결과는 다음과 같습니다.

                          11002210
                          12210010
                        1220010010
                      122000010010
                    12200000010010
                  1220000000010010
                122000000000010010
              12200000000000010010
            1220000000000000010010
          122000000000000000010010
        12200000000000000000010010
      1220000000000000000000010010
    122000000000000000000000010010
                                 .
                                 .
                                 .
    
  5. 우리는 최종 합 모듈로 10 d + 8을 취하여 마지막 d + 8 자리를 제외한 모든 것을 버립니다.

    초기 합 21112 의 경우 최종 결과는 10010 입니다.


1 translate 로 달성됩니다 . 문자열 0011을 64 번 반복하면 일련의 ASCII 문자 0123 과 하나의 반복이 정렬되어 원하는 대체를 달성합니다.

2 이 합계의 자릿수는 3을 초과 할 수 없습니다 (초기 값 1 + 캐리에서 2 1 ).

3 이것은 d = 1 에서 작동하고 그렇지 않으면 d * 8> d + 8에서 발생 합니다. 이 코드는 단계를 반복 할 수있다 * 8 (d + 1) 이후, 시간 뒤에 갖고 L이 경우 A는 정수.


7
이것은 깊은 마술 이다. 어떤 형식이 필요 input()합니까? ( 21112입력 할 때 얻습니다 10101, 11011.)
Tim Pederick

1
신경 쓰지 마; 그것은 파이썬 3으로 번역 된 버전을 실행 중이었습니다 (실제로 보이지 않습니다) . 파이썬 2에서는 잘 작동합니다 .
Tim Pederick

9
...어떻게. 부디. 설명.
Nic Hartley

@QPaysTaxes 내 답변을 편집했습니다.
Dennis

@Dennis 이제 왜 작동하는지 설명 할 수 있습니까? 예를 들어, 왜 d+8그렇지 d+9않습니까? 어떻게????
Nic Hartley

16

Pyth, 34 바이트

_shM.u,%J/eMeN\12-+PMeNm.B6/J2k,kQ

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트 (시간이 오래 걸립니다). 온라인 컴파일러는 일반 (오프라인) 컴파일러와 비교할 때 속도가 느리기 때문에 시간 제한을 쉽게 충족시켜야합니다.

설명:

내 알고리즘은 기본적으로 운반과 함께 추가 구현입니다. 그러나 나르는 대신, 나르고 1있어야합니다 110( 1100기본 -1+i은 기본 과 동일 2합니다 -1+i). 이것은 대부분 잘 작동하지만 무한 루프 인쇄 0에 갇힐 수 있습니다. 예를 들어 당신은 추가하는 경우 111현재 캐리 있습니다 110. 그래서 기본적으로 루프에 갇히고 멈출 때까지 추가합니다. 루프가 항상 0을 인쇄하는 루프이므로 괜찮을 것이라고 생각합니다.

_shM.u,%J/eMeN\12-+PMeNm.B6/J2k,kQ   implicit: Q = input list of strings
                               ,kQ   create the pair ["", Q]
    .u                               modify the pair N (^) until loop:
      ,                                replace N with a new pair containing:
            eN                           N[1] (the remaining summand)
          eM                             take the last digits of each summand
         /    \1                         count the ones
        J                                store the count in J
       %J       2                        J % 2 (this is the first element of the new pair)
                   PMeN                  remove the last digit of each summand
                  +    m   /J2           and add J / 2 new summand:
                        .B6                 with the value "110" (binary of 6)
                 -            k          remove empty summand
    .u                               returns all intermediate results
  hM                                 extract the digits
 s                                   sum them up to a long string
_                                    reverse

13

파이썬 2, 69 67 바이트

f=lambda a,b:a*a+b*b^58and 2*f(a*b%2*6,f(a/2,b/2))|a+b&1if a else b

I / O는 기본 2 정수로 수행됩니다.

-Dennis 감사합니다.


나는 그것을 걸릴 a*a+b*b^58==0ab역원인가? 어떻게 작동합니까?
xnor

@xnor 아니오, a*a+b*b==58그들 중 하나가 3이고 다른 하나가 7 일 때
feersum

1
(3,7)사이클을 제공하고 특별한 케이스가 필요한 유일한 쌍이라는 것은 분명하지 않습니다 . 그것이 사실이라면,로 돌아 가기 (a,b)==(3,7)때문에 실제로 순서대로 확인하면되고, 그 표현이 더 짧을 수도 있습니다. (7,3)(3,7)
xnor

1
이제 이것은 (a) ^지수가 아닌 XOR이거나 (b) XOR의 우선 순위가 +.
Tim Pederick

12

망막 , 100 바이트

r+`(.*)(\d|(?!\4))( .*)(.?)
$2$4:$1$3
T` 0
+`1:11(1*:1*)11
:$1
^:*
:::
}`:(1*:1*:)11
1:1$1
(1)*:
$#1

쉼표로 구분 된 입력을받습니다. 출력은 항상 3 개의 선행 0으로 시작합니다.

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

첫 번째 단계에서 더 짧은 솔루션이 있는지 궁금합니다.


2
아니, 아니, 점수는 그대로 완벽합니다.)
Conor O'Brien

2
-2i의 좋은 점수!
Nic Hartley

와. 내 솔루션을 게시했을 때이 솔루션을 보지 못했습니다 ... 내 솔루션보다 훨씬 우수합니다.
Leaky Nun

@KennyLau 난 그냥 그것을보고 생각했다 "흠, 나는 어떤 시점에서 설명을 추가해야한다고 생각합니다 ..."
Martin Ender

...- 2i? 이것은 십진수이지만 프로그램은 그렇지 않은 밑을 사용합니다.
user75200

12

젤리, 29 28 26 24 21 20 바이트

DBḅ1100ḌµDL+8µ¡Dṣ2ṪḌ

이것은 10 진수로 I / O를 수행합니다. 정수는 영숫자가 아닌 문자로 구분해야합니다 +.

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

배경

에서는 단지베이스 산술 저자는 형태의베이스에서 복소수 승산을 추가하는 방법을 도시 -n + I .

base -1 + i의 경우 추가는 carry를 사용한 일반 이진 추가와 유사하게 수행되며 두 가지 차이점이 있습니다.

  • 1 을 다음 상위 위치 로 운반하는 대신 110 을 다음 3으로 운반 합니다.

  • 캐리 숫자는 무기한으로 전파 될 수 있습니다. 그러나 선행 0이 없으면 합계 a + b 의 최대 ab 보다 최대 8 자리가 더 큽니다 .

다음과 같이 진행합니다.

  1. 먼저, 숫자가 10 진수 인 것처럼 ab 를 더합니다.

    들면 A = 10101B = 11,011 , 이는 범 21,112을 .

  2. 1 보다 큰 각 숫자에 대해 , 우리는 그 숫자에서 2 를 빼고 110 을 다음 3 개의 더 높은 위치로 옮깁니다. 우리는 각 10 진수를 이진수로 변환하고 결과 이진 배열을 기본 1100 에서 정수로 변환하고 0 , 1 , 11001101 의 결과 목록을 비정규 기본 10으로 해석하여 이를 달성 할 수 있습니다 번호. 1

    합계 21112의 경우 21112 + 1098 * 10001 = 21112 + 10981098 = 11002210이 됩니다.

  3. 우리는 2 단계 를 총 d + 8 번 반복합니다 . 여기서 da + b 의 자릿수입니다 .

    초기 합 21112 의 결과는 다음과 같습니다.

                          11002210
                          12210010
                        1220010010
                      122000010010
                    12200000010010
                  1220000000010010
                122000000000010010
              12200000000000010010
            1220000000000000010010
          122000000000000000010010
        12200000000000000000010010
      1220000000000000000000010010
    122000000000000000000000010010
    
  4. 최종 결과에서 마지막 d + 8 자리를 제외한 모든 것을 버립니다 . 이것은 마지막 2 이후의 모든 것을 버림으로써 달성됩니다 . 2

    초기 합 21112 의 경우 최종 결과는 10010 입니다.

작동 원리

DBḅ1100ḌµDL+8µ¡Dṣ2ṪḌ  Main link. Argument: a + b (implicit sum)

        µ    µ¡       Execute the chain before the first µ n times, where n is
                      the result of executing the chain before the second µ.
         D            Convert a + b to base 10.
          L           Length; count the decimal digits.
           +8         Add 8 to the number of digits.
D                     Convert the initial/previous sum to base 10.
 B                    Convert each digit (0 - 3) to binary.
  ḅ1100               Convert each binary array from base 1100 to integer.
       Ḍ              Interpret the resulting list as a base 10 number.
               D      Convert the final sum to base 10.
                ṣ2    Split at occurrences of 2.
                  Ṫ   Select the last chunk.
                   Ḍ  Convert from base 10 to integer.

1 이 합계의 자릿수는 3을 초과 할 수 없습니다 (초기 값 1 + 캐리에서 2 1 ).

2 취소 할 마지막 숫자가 3이 될 수 없기 때문에 작동합니다 .


6

파이썬 3, 289 바이트

이것은 가장 작은 자릿수에서 가장 중요한 자릿수 (즉, 초등학교에서 가르친 것과 정확히 동일한 알고리즘)까지 자릿수 덧셈을 수행합니다. 차이점은 (a) 십진수가 아닌 이진수로되어 있기 때문에 숫자가 2 이상일 때마다 (b) 1 + 1 = 1100, 그렇지 않다는 것 10입니다.

실제로, 11 + 111 = 0또는 0이되어야하는 합계는 절대 종료되지 않습니다.

from collections import*
def a(*s,p=0):
 r=defaultdict(int,{0:0})
 for S in s:
  n=0
  for d in S[::-1]:r[n]+=d=='1';n+=1
 while p<=max(r):
  while r[p]>1:
   r[p]-=2
   if r[p+1]>1<=r[p+2]:r[p+1]-=2;r[p+2]-=1
   else:r[p+2]+=1;r[p+3]+=1
  p+=1
 return str([*map(r.get,sorted(r))])[-2::-3]

더 많은 골프가 가능합니다.


"제로 디텍터"가 충분하다고 얼마나 확신하십니까?
Yakk

4
@ Yak : 동료 검토 저널에 1의 규모로, 아마도 카운터 예제를 제공하지 않습니까?
Tim Pederick

2

망막, 157 151 134 133 124 123 바이트

Martin Büttner 덕분에 1 바이트 할인.

(.+),(.+)
$.1$*0$2,$.2$*0$1,
1
0x
+`(0x*)(,.*)0(x*),
$2,$1$3
{`,

(^|0x0xx0xx)
000
(0x*)(0x*)(0x*0)xx
$1x$2x$3
)`^0+
0
0x
1

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

단항으로 변환 한 후 다음 교체를 반복합니다 (10 진수로 표시).

122 -> 000
0002 -> 1100 (this can also be 0012 -> 1110 and 1112 -> 2210 or even 2222 -> 3320 or even 3333 -> 4431)

기본적으로, 2보다 큰 경우 : 2 개를 빼고 이전 숫자에 아무것도 추가하지 않고 1을 이전 숫자에 추가 한 다음 하나를 이전 숫자에 추가하십시오.

의사 코드에서 :

if(a[n]>2):
    a[n] -= 2;
    a[n-2] += 1;
    a[n-3] += 1;

단항 구현 :

각 숫자 (예 :) 3x (S) (예 xxx) 다음 접두사 0.

예를 들어 1234 로 표현됩니다 0x0xx0xxx0xxxx.

이 잎 0 으로, 변경 101에 의해 표현 될 것이다 0x00x.

처음부터 마지막으로, 단지 거기 0하고 1, 변환을 쉽게 수행 할 수1->0x0x->1.

모든 단계를 보려면 여기를 클릭하십시오 .


1

자바 스크립트 (ES6) 146 126 바이트

r=n=>n&&n%2-r(n>>=1)-i(n)
i=n=>n&&r(n>>=1)-i(n)
g=(x,y,b=(x^y)&1)=>x|y&&b+2*g(b-x+y>>1,b-x-y>>1)
(x,y)=>g(r(x)+r(y),i(x)+i(y))

g베이스로 가우시안 정수 (실수 부 및 허수 부)로 변환 i-1반면 ri 베이스 변환 i-1(각각 실수 부 및 허수 부) 가우시안 정수로 정수. 변환이 완료되면 산술 만하면됩니다.

편집 : 실수와 허수 부분을 별도로 계산하여 20 바이트를 절약했습니다.


1

C ++ 416 바이트 + #include <vector>\n#include <algorithm>\n(또 다른 40)

using I=int;using v=std::vector<I>;void r(v&x){v r{rbegin(x),rend(x)};x=r;}v a(v L,v R){r(L);r(R);L.resize(std::max(L.size(),R.size()));for(int&r:R)L[&r-R.data()]+=r;while(1){L.resize(L.size()+3);auto it=find(rbegin(L),rend(L),2);if(it==rend(L))break;I i=-1+it.base()-begin(L);i&&L[i+1]&&L[i-1]/2?L[i+1]=L[i]=L[i-1]=0:(++L[i+2],++L[i+3],L[i]=0);}L.erase( std::find(rbegin(L),rend(L),1).base(),end(L));r(L);return L;}

또는 더 많은 공백이 있습니다.

using I=int;
using v=std::vector<I>;

void r(v&x){v r{rbegin(x),rend(x)};x=r;}
v a(v L,v R) {
  r(L);r(R);
  L.resize(std::max(L.size(),R.size()));
  for(int&r:R)
    L[&r-R.data()]+=r;
  while(1) {
    L.resize(L.size()+3);
    auto it=find(rbegin(L), rend(L), 2);
    if(it==rend(L)) break;
    I i=-1+it.base()-begin(L);
    i&&L[i+1]&&L[i-1]/2?
      L[i+1]=L[i]=L[i-1]=0
    :
      (++L[i+2],++L[i+3],L[i]=0);
  }
  L.erase( std::find(rbegin(L),rend(L),1).base(), end(L));
  r(L);
  return L;
}

간신히 골프를 쳤다. 입력 값을 정수 벡터로 취하고 정수 벡터를 반환합니다.

라이브 예 .

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