가우스 정수를 인수 분해합니다


23

가우스 정수는 누구의 실수 부와 허수 부분 정수 복소수이다.

가우시안 정수는 일반적인 정수와 마찬가지로 가우시안 소수의 곱으로 고유 한 방식으로 표현 될 수 있습니다. 여기서 도전은 주어진 가우시안 정수의 주요 성분을 계산하는 것입니다.

입력 : 0과 같지 않고 단위 가 아닌 가우시안 정수 (즉, 1, -1, i 및 -i는 입력으로 제공 될 수 없음). 예를 들어 다음과 같은 적절한 형식을 사용하십시오.

  • 4-5i
  • -5 * j + 4
  • (4, -5)

출력 : 소수 인 가우시안 정수의 목록입니다 (즉, 이들 중 어느 것도 두 개의 비 단위 가우시안 정수의 곱으로 표현 될 수 없음). 곱은 입력 번호와 같습니다. 출력 목록의 모든 숫자는 사소하지 않아야합니다 (예 : 1, -1, i 또는 -i). 모든 합리적인 출력 형식을 사용할 수 있습니다. 반드시 입력 형식과 같을 필요는 없습니다.

출력리스트에 둘 이상의 요소가 있으면 몇 가지 올바른 출력이 가능합니다. 예를 들어, 입력 9의 경우 출력은 [3, 3] 또는 [-3, -3] 또는 [3i, -3i] 또는 [-3i, 3i] 일 수 있습니다.

테스트 사례 ( 이 표 에서 가져옴, 테스트 사례 당 2 줄)

2
1+i, 1-i

3i
3i

256
1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i,1+i

7+9i
1+i,2−i,3+2i

27+15i
1+i,3,7−2i

6840+585i
-1-2i, 1+4i, 2+i, 3, 3, 6+i, 6+i

가우시안 정수를 인수 분해하는 내장 함수는 허용되지 않습니다. 내장 함수로 일반 정수를 인수 분해하는 것이 허용됩니다.


또는 3i로 반환 해야합니까 ? 3,i3i
밸류 잉크

3ii소수가 아니기 때문에 정답 입니다. 테스트 케이스를 더 명확하게하기 위해 업데이트했습니다.
아나톨리 크

-3-2j, 2-1j, -1-1j가 7 + 9j의 인수 분해에 대한 정답입니까?
mdahmoune

4
Wolfram Alpha에 따르면 가우시안 소수가 아닌 6840+585i잘못된 요인 목록이 5있습니다. 대신을 반환합니다 -1-2i, 1+4i, 2+i, 3, 3, 6+i, 6+i. 출처
밸류 잉크

1
참고로, 256=(1+i)**16하지 (1+i)**8때문에 256=2**8=(2i)**8그리고2i=(1+i)**2
Shieru Asakoto

답변:


4

젤리 , 61 55 바이트

Ḟ,Ċ1ḍP
Ḟ,ĊḤp/-,1p`¤×€×1,ıFs2S€⁸÷ÇÐfỊÐḟ1;Ṫð,÷@\ḟ1
Ç€F$ÐL

온라인으로 사용해보십시오! (머리글 및 바닥 글은 출력 형식을 지정합니다)

@EricTheOutgolfer 덕분에 -6 바이트

작동 원리

Ḟ,Ċ1ḍP  - helper function: determines if a complex number is Gaussian
Ḟ,Ċ       - real, complex components
   1ḍ     - set each to if 1 divides them
     P    - all

Ḟ,ĊḤp/-,1p`¤×€×1,ıFs2S€⁸÷ÇÐfỊÐḟ1;Ṫð,÷@\ḟ1 - helper: outputs a factor pair of the input
Ḟ,ĊḤp/                   - creates a list of possible factors a+bi, a,b>=0
      -,1p`¤×€           - extend to the other three quadrants 
              ×1,ıFs2S€  - convert to  actual complex numbers 
⁸÷                       - get quotient with input complex number
  ÇÐf                    - keep only Gaussian numbers (using helper function)
     ỊÐḟ                 - remove units (i,-i,1,-1)
        1;               - append a 1 to deal with primes having no non-unit factors
          Ṫð,÷@\         - convert to a factor pair
                ḟ1       - remove 1s
Ç€F$ÐL
Ç€      - factor each number
   $    - and
  F     - flatten the list
    ÐL  - until factoring each number and flattening does not change the list


"가우스 만 유지"라고 표시되면 "프라임 만 유지"를 의미합니까?
밝게

@donbright 아니요, 정수 실수 및 복잡한 구성 요소를 갖는 복소수 만 유지하는 것을 의미합니다.
fireflame241

@ fireflame241 아, 지금 보라! 대단히 감사합니다
밝게 돈


5

파이썬 (2) , 250 (239) 223 215 바이트

e,i,w=complex,int,abs
def f(*Z):
 if Z:
	z=Z[0];q=i(w(z));Q=4*q*q
	while Q>0:
 	 a=Q/q-q;b=Q%q-q;x=e(a,b)
 	 if w(x)>1:
		y=z/x
		if w(y)>1 and y==e(i(y.real),i(y.imag)):f(x,y);z=Q=0
 	 Q-=1
	if z:print z
	f(*Z[1:])

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

  • 다중 함수 인수를 사용할 때 -11 바이트
  • 하나의 변수를 사용하여 커플을 구문 분석 할 때 -2² * ² 바이트 (a,b)
  • 탭과 공백을 혼합 할 때 -2³ 바이트 : ov 덕분에

일부 설명 은 분해가 불가능할 때까지 두 복합체로 반복적으로 복합체를 분해합니다 ...


글쎄, 그것은 더 큰 입력에서 TIO에서 시간 초과되지만 내 루비 답변보다 짧습니다 ... 현재 . 또한 def f(Z,s=[])캐릭터를 구해야합니다
Value Ink

@ValueInk 예 루비 솔루션보다 느립니다
mdahmoune

2
들여 쓰기와 흥미로운 패턴 ...
Outgolfer Erik

@ValueInk 다중 함수 인수는 더 많은 바이트를 절약합니다 :)
mdahmoune


3

-212 바이트

use num::complex::Complex as C;fn f(a:&mut Vec<C<i64>>){for _ in 0..2{for x in -999..0{for y in 1..999{for i in 0..a.len(){let b=C::new(x,y);if(a[i]%b).norm_sqr()==0&&(a[i]/b).norm_sqr()>1{a[i]/=b;a.push(b)}}}}}}

이것이 100 % 올바르게 작동하는지 100 % 확신하지는 않지만 광범위한 테스트에 대해서는 올바른 것 같습니다. 이것은 Jelly보다 작지 않지만 최소한 해석 된 언어보다 작습니다 (지금까지). 또한 더 빠른 것처럼 보이며 1 초 안에 10 억 개의 입력을 통해 작동 할 수 있습니다. 예를 들어 1234567890 + 3141592650i는 (-9487 + 7990i) (-1 + -1i) (-395 + 336i) (2 + -1i) (1 + 1i) (3 + 0i) (3 + 0i) (4+ 1i) (-1 + 1i) (-1 + 2i), (wolfram alpha를 테스트하려면 여기를 클릭하십시오)

이것은 정수의 순 인수 분해와 같은 아이디어로 시작하여 문제의 정수 아래의 각 숫자를 통과하여 나누는 지 확인하고 끝날 때까지 반복하십시오. 그런 다음 다른 답변에서 영감을 받아 변형되었습니다 ... 반복적으로 벡터의 항목을 인수로 지정합니다. 이 작업은 여러 번 수행되지만 아무 때나 '완료'되지는 않습니다. 반복 횟수는 합리적인 입력의 좋은 덩어리를 포함하도록 선택되었습니다.

여전히 "(a mod b) == 0"을 사용하여 하나의 정수가 다른 정수를 나누는 지 여부를 테스트합니다 (가우시안의 경우 내장 Rust 가우스 모듈로를 사용하고 "0"을 norm == 0으로 간주 함). a / b)! = 1 '은 "너무 많이"나누는 것을 방지하여 기본적으로 결과 벡터를 소수만 채울 수 있지만 벡터의 어떤 요소도 단일화하지 않습니다 (0-i, 0 + i, -1 + 0i, 1 + 0i) (질문에 의해 금지됨).

for-loop 한계는 실험을 통해 발견되었습니다. y는 0으로 나누기 패닉을 방지하기 위해 1에서 위로 올라가고, 사분면에 대한 가우시안의 미러링으로 인해 x는 -999에서 0으로 갈 수 있습니다 (제 생각에?). 제한 사항과 관련하여 원래 질문은 유효한 입력 / 출력 범위를 나타내지 않았으므로 "합리적인 입력 크기"가 가정됩니다 ... (편집 ...하지만이 숫자를 계산하는 방법을 정확히 모르겠습니다 "실패"하기 시작합니다. 999 이하로 나눌 수 없지만 여전히 나에게 작은 가우시안 정수가 있다고 상상합니다.)

에 다소 ungolfed 버전을 시도 play.rust-lang.org


3

펄 6 , 141124 바이트

-17 바이트에 대한 Jo King 덕분에

sub f($_){{$!=0+|sqrt .abs²-$^a²;{($!=$_/my \w=$^b+$a*i)==$!.floor&&.abs>w.abs>1>return f w&$!}for -$!..$!}for ^.abs;.say}

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


이것은 어떻게 작동합니까? 바닥은 맞춤형 모듈로입니까?
밝게 돈

1
@donbright floor부품이 $_/w(즉, 현재 인자를 숫자로 나눈 값) 정수인지 확인합니다.
Jo King

2

Pyth , 54 51 45 42 36 바이트

 .W>H1cZ
h+.aDf!%cZT1>#1.jM^s_BM.aZ2

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

형태로 입력을 수용 1+2j- 순전히 실수 또는 허수가 다른 구성 요소를 생략 할 수 있습니다 (예를 들어 9, 2j). 출력은 (1+2j)형식적으로, 실제 부분을 생략하는 허수 로 이루어진 개행으로 구분 된 복소수 목록입니다 .

이것은 간단한 트레일 나누기를 사용하여 1보다 크고 현재 값보다 작은 가우시안 정수와 값 자체를 생성합니다. 이것들은 값의 요소 인 것을 유지하기 위해 필터링되며, 가장 작은 크기로 다음 주요 요소로 선택됩니다. 출력되고 다음 반복에 대한 값을 생성하기 위해 값으로 나누어집니다.

또한 Pyth는 Jelly를 때리는 😲 (나는 그것이 지속될 것으로 기대하지는 않는다)

 .W>H1cZ¶h+.aDf!%cZT1>#1.jM^s_BM.aZ2ZQ   Implicit: Q=eval(input())
                                         Newline replaced with ¶, trailing ZQ inferred
 .W                                  Q   While <condition>, execute <inner>, with starting value Q
   >H1                                   Condition function, input H
   >H1                                     Is magnitude of H > 1?
                                           This ensures loop continues until H is a unit, i.e. 1, -1, j, or -j)
      cZ¶h+.aDf!%cZT1>#1.jM^s_BM.aZ2Z    Inner function, input Z
                                .aZ        Take magnitude of Z

                             _BM           Pair each number in 0-indexed range with its negation
                            s              Flatten
                           ^       2       Cartesian product of the above with itself
                        .jM                Convert each pair to a complex number
                      #                    Filter the above to keep those element where...
                     > 1                   ... the magnitude is greater than 1 (removes units)
              f                            Filter the above, as T, to keep where:
                 cZT                         Divide Z by T
                %   1                        Mod real and imaginary parts by 1 separately
                                             If result of division is a gaussian integer, the mod will give (0+0j)
               !                             Logical NOT - maps (0+0j) to true, all else to false
                                           Result of filter are those gaussian integers which evenly divide Z
           .aD                             Sort the above by their magnitudes
          +                         Z      Append Z - if Z is ±1±1j, the filtered list will be empty
         h                                 Take first element, i.e. smallest factor
        ¶                                  Print with a newline
      cZ                                   Divide Z by that factor - this is new input for next iteration
                                         Output of the while loop is always 1 (or -1, j, or -j) - leading space suppesses output

이것은 매우 흥미롭지 만 6840 + 585j에서 타임 아웃 된 것으로 보입니다
밝게

@donbright 처리 제한이 60 초이므로 TIO에서 수행됩니다. 더 많은 시간이 걸리므로 로컬에서 실행하면 문제없이 작동합니다.
Sok
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.