합동을위한 공식


10

중국 잉여는 정리는 모듈러 산술에 매우 유용 할 수 있습니다.

예를 들어, 다음과 같은 합동 관계를 고려하십시오.

합동의 집합

이와 같은 합동 관계 세트의 경우, 모든 염기 ( 3, 5, 7이 예에서)가 서로 공-프라임 인 경우 , 관계를 만족시키는 정수 ( 이 예에서) 와 그 n사이의 단 하나의 정수만 있습니다. .13*5*7 = 105

이 예에서 숫자는 14이 수식으로 생성됩니다.

공식

여기서 2, 4, and 0상기 예와 같다.

70, 21, 15공식 의 계수 이며 염기에 의존합니다 3, 5, 7.

70, 21, 15염기 집합에 대한 공식 계수 ( 예에서) 를 계산하려면 다음 절차를 사용합니다.

a염기 집합의 각 숫자 에 대해 :

  1. 로 표시된 다른 모든 염기의 곱을 찾으십시오 P.
  2. 로 나눈 P나머지가 남은 첫 번째 배수를 찾으십시오 . 의 계수입니다 .1aa

예를 들어, base에 해당하는 계수를 계산하기 3위해 다른 모든 base 의 곱 (즉 5*7 = 35)을 찾은 다음 1base로 나눈 나머지를 남기는 해당 곱의 첫 번째 배수를 찾습니다 .

이 경우 35의 나머지 잎 2에 의해 분할 될 때 3, 그러나 35*2 = 70잎의 나머지 부분 1으로 나눈 경우가 3있으므로, 70에 해당하는 계수이다 3. 마찬가지로, 3*7 = 21의 나머지 잎 1으로 나누었을 때를 5하고 3*5 = 15의 나머지 잎 1으로 나누었을 때를 7.

간단히 말해서

a일련의 숫자로 된 각 숫자 의 경우 :

  1. 로 표시된 다른 모든 숫자의 곱을 찾으십시오 P.
  2. 로 나눈 P나머지가 남은 첫 번째 배수를 찾으십시오 . 의 계수입니다 .1aa

도전

  • 문제는 두 개 이상의 염기 집합에 대해 해당 계수 집합을 찾는 것입니다.
  • 베이스 세트는 페어 단위 코 프라임이어야하며 각베이스는 1보다 큽니다.
  • 입력은 입력 [3,4,5]또는 공백으로 구분 된 문자열 "3 4 5"또는 입력이 작동 하는 정수 목록입니다 .
  • 출력은 정수 목록 또는 계수 세트를 나타내는 공백으로 구분 된 문자열이어야합니다.

테스트 사례

input             output
[3,5,7]           [70,21,15]
[2,3,5]           [15,10,6]
[3,4,5]           [40,45,36]
[3,4]             [4,9]
[2,3,5,7]         [105,70,126,120]
[40,27,11]        [9801,7480,6480]
[100,27,31]       [61101,49600,56700]
[16,27,25,49,11]  [363825,2371600,2794176,5583600,529200]

이 과제를 작성하는 데 도움을 주신 Leaky Nun에게 감사드립니다. 문제가 명확하지 않은 경우 언제든지 알려주십시오. 행운과 좋은 골프!


입력에 항상 3 개의 숫자가 있습니까?
xnor

@xnor 아뇨. 테스트 사례가 수정되었습니다.
Sherlock9

답변:


5

하스켈, 61 55 53 바이트

f x=[[p|p<-[0,product x`div`n..],p`mod`n==1]!!0|n<-x]

f입력을 받아서 출력을 정수 목록으로 제공 하는 함수 를 정의합니다 .

f x=[                                          |n<-x]  (1)
              product x                                (2)
                       `div`n                          (3)

먼저 입력 (1)의 모든 정수를 반복합니다. 그런 다음 모든 정수의 곱 (2)을 n으로 나눠서 n정수 가 아닌 정수 의 곱 P(3) 을 얻습니다 .

           [0,               ..]                       (4)
     [p|p<-                     ,p`mod`n==1]           (5)
                                            !!0        (6)

그런 다음 결과 ( P)를 0에서 시작하는 범위의 단계 값으로 사용합니다 . 결과를 가져 와서 [0, P, 2P, 3P, ...]mod-n 연산의 결과가 1 인 값으로 필터링합니다. 마지막으로, 우리는 게으른 평가 (6) 덕분에 첫 번째 요소를 사용합니다.

@xnor 에게 2 바이트 감사 합니다!


1
하스켈에 오신 것을 환영합니다! 나는 당신의 생각 quot할 수있다 div, 그리고 head할 수 있습니다 !!0.
xnor

4

젤리 , 11 7 바이트

P:*ÆṪ%P

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

배경

하자 PA는 엄격하게 긍정적 수 서로 소의 정수.

의문의 두 단계 - 다수의 발견 P 잎의 나머지 것을 1 로 나눈 A는 다음의 합동 식에 의해 설명 될 수있다 - 다른.

선형 합동 방정식

에 의해 오일러 - 페르마 정리 , 우리가

오일러 페르마 정리

여기서 φ는 오일러의 잠복 기능을 나타냅니다 . 이 결과로부터 우리는 다음을 추론합니다.

선형 합동 방정식의 공식

도전을 계산하기 위해 우리를 필요로하기 때문에 마지막으로, PX를 , 우리는 그것을 관찰

최종 결과를위한 공식

여기서 Pa 는 모든 계수의 곱으로 계산 될 수 있습니다.

작동 원리

P:*ÆṪ%P  Main link. Argument: A (list of moduli)

P        Yield the product of all moduli.
 :       Divide the product by each modulus in A.
   ÆṪ    Apply Euler's totient function to each modulus.
  *      Raise each quotient to the totient of its denominator.
     %P  Compute the remainder of the powers and the product of all moduli.

2

J, 13 바이트

*/|5&p:^~*/%]

@Dennis의 놀라운 답변을 기반으로 합니다.

용법

일부 테스트 케이스에는 접미사가있는 확장 정수로 입력해야합니다 x.

   f =: */|5&p:^~*/%]
   f 3 5 7
70 21 15
   f 40x 27 11
9801 7480 6480
   f 16x 27 25 49 11
363825 2371600 2794176 5583600 529200

설명

*/|5&p:^~*/%]  Input: list B
         */    Reduce B using multiplication to get the product of the values
            ]  Identity function, get B
           %   Divide the product by each value in B, call the result M
   5&p:        Apply the totient function to each value in B, call the result P
       ^~      Raise each value in M to the power of its corresponding value in P
*/             The product of the values in B
  |            Compute each power modulo the product and return

여기에서 시도하십시오.




1

젤리, 14 13 바이트

P:×"Ḷð%"’¬æ.ḷ

@ Dennis 덕분에 바이트를 절약했습니다 !

챌린지 사양에 설명 된 프로세스를 사용합니다. 입력은 염기의 목록이고 출력은 계수의 목록입니다.

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명

P:×"Ḷð%"’¬æ.ḷ  Input: a list B
P              Get the product of the list
 :             Divide it by each value in the B, call it M
    Ḷ          Get a range from 0 to k for k in B
  ×"           Vectorized multiply, find the multiples of each M
     ð         Start a new dyadic chain. Input: multiples of M and B
      %"       Vectorized modulo, find the remainders of each multiple by B
        ’      Decrement every value
               If the remainder was 1, decrementing would make it 0
         ¬     Logical NOT, zeros become one and everything else becomes 0
            ḷ  Get the multiples of M
          æ.   Find the dot product between the modified remainders and the multiples
               Return

1

자바 스크립트 (ES6), 80 바이트

a.map(e=>[...Array(e).keys()].find(i=>p*i/e%e==1)*p/e,p=a.reduce((i,j)=>i*j))

확장 유클리드 알고리즘을 시도했지만 98 바이트가 걸립니다.

a=>a.map(e=>(r(e,p/e)+e)%e*p/e,p=a.reduce((i,j)=>i*j),r=(a,b,o=0,l=1)=>b?r(b,a%b,t,o-l*(a/b|0)):o)

값이 모두 소수이면 ES7은 56 바이트로이를 수행 할 수 있습니다.

a=>a.map(e=>(p/e%e)**(e-2)%e*p/e,p=a.reduce((i,j)=>i*j))

1

Python + SymPy, 71 바이트

from sympy import*
lambda x:[(prod(x)/n)**totient(n)%prod(x)for n in x]

이것은 Jelly 답변 의 알고리즘을 사용합니다 . I / O는 SymPy 번호 목록 형식입니다.


1

파이썬 2, 87 84 바이트

알고리즘의 간단한 구현. 골프 제안을 환영합니다.

a=input();p=1
for i in a:p*=i
print[p/i*j for i in a for j in range(i)if p/i*j%i==1]

전체 프로그램은 3 바이트를 절약 할 수 있습니다.
Dennis

1

체다 , 64 바이트

n->n.map(i->(|>i).map(j->(k->k%i>1?0:k)(n.reduce((*))/i*j)).sum)

나는 배열을위한 .product것을 추가해야한다 .reduce((*))...
Downgoat

0

간격 , 51 바이트

GAP에는를 사용하여 동기 부여 예제를 계산할 수있는 기능이 ChineseRem([2,5,7],[2,4,0])있지만 여전히 계수를 얻는 것이 쉽지는 않습니다. n 번째 위치에 1을 포함하고 다른 위치에 0을 두 번째 인수로 사용하여 목록을 사용하여 n 번째 계수를 얻을 수 있습니다. 따라서이 목록을 작성하고 모든 기능을 적용해야합니다.

l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))

0

배치, 148 바이트

@set p=%*
@set/ap=%p: =*%
@for %%e in (%*)do @for /l %%i in (1,1,%%e)do @call:l %%e %%i
@exit/b
:l
@set/an=p/%1*%2,r=n%%%1
@if %r%==1 echo %n%

0

실제로 14 바이트

이것은 Dennis 's Jelly answer의 알고리즘을 사용합니다 . 내 파이썬 답변을 기반으로 한 다른 답변이 곧 나옵니다. 골프 제안을 환영합니다. 온라인으로 사용해보십시오!

;π;)♀\;♂▒@♀ⁿ♀%

작동 원리

                 Implicit input a.
;                Duplicate a.
 π;)             Take product() of a, duplicate and rotate to bottom.
    ♀\           Integer divide the product by each element of a. Call this list b.
      ;♂▒        Take that list, duplicate, and get the totient of each element.
         @♀ⁿ     Swap and take pow(<item in b>, <corresponding totient>)
            ♀%   Modulo each item by the remaining duplicate product on the stack.
                 Implicit return.

22 바이트의 파이썬 답변을 기반으로 한 또 다른 답변. 골프 제안을 환영합니다. 온라인으로 사용해보십시오!

;π╖`╝╛╜\╛r*"╛@%1="£░`M

작동 원리

            Implicit input a.
;π╖         Duplicate, take product of a, and save to register 0.
`...`M      Map over a.
  ╝           Save the item, b, in register 1.
  ╛╜\         product(a) // b. Call it P.
  ╛r          Take the range [0...b].
  *           Multiply even item in the range by P. Call this list x.
  "..."£░     Turn a string into a function f.
              Push values of [b] where f returns a truthy value.
    ╛@%         Push b, swap, and push <item in x> % b.
    1=          Does <item> % b == 1?
            Implicit return.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.