유리수의 p-adic 규범을 계산하십시오


11

유리수의 p-adic 규범을 계산하십시오

입력으로 3 개의 정수 m,n,p( p양의 소수) 를 취하는 함수 또는 프로그램을 작성 하여 p로 표시되는 표준 (으로 표시 |m/n|_p)을 (완전히 감소 된) 분수로 출력합니다. Fermat은 매우 작은 여백 만있는 것으로 알려져 있지만, 컴퓨터 화면이 매우 작다는 것입니다. 따라서 Fermat의 화면에 맞게 코드를 가능한 짧게 만드십시오!

정의

주요 감안할 때 p, 각 부분은 m/n고유로 (부호 무시) 쓸 수있는 (a/b)* p^e등의 e정수이고 p분할도 a도를 b. 의 p-adic 규범m/n입니다 p^-e. 분수가 0 인 경우 특별한 경우가 있습니다 |0|_p = 0.

출력 형식은 다음과 같아야합니다 x/y(예 : 1/3정수 10또는 두 정수 모두 10/1허용, 음수의 경우 앞에 빼기-가 있어야 함 -1/3)

세부

프로그램은 stdin / stdout을 사용하거나 합리적인 숫자 또는 문자열을 리턴하는 함수로 구성되어야합니다. 입력 m/n이 완전히 줄어들지 않았다고 가정해야합니다 . p이것이 프라임 이라고 가정 할 수 있습니다 . 이 프로그램은의 정수 처리 할 수 있어야 -2^28까지를 2^28, 그리고 10 초 이상 걸리지 않습니다.

내장 된 인수 분해 및 프라임 검사 기능과 기본 대화 기능은 허용되지 않으며 p-adic 평가 또는 표준을 계산하는 기능이 내장되어 있습니다.

예 ( wikipedia 에서 도난 당함 ) :

x = m/n = 63/550 = 2^-1 * 3^2 * 5^-2 * 7 * 11^-1
|x|_2 = 2
|x|_3 = 1/9
|x|_5 = 25
|x|_7 = 1/7
|x|_11 = 11
|x|_13 = 1

재미있는 퀴즈

(이 도전에 대해 알고 / 읽을 필요는 없지만 동기 부여로 읽는 것이 좋습니다.)

(내가 잘못된 단어를 사용하거나 다른 것이 잘못되면 나를 교정하십시오. 나는 영어로 이것에 대해 이야기하는 데 익숙하지 않습니다.)

유리수를 필드로 고려하면 p-adic 규범은 p-adic 메트릭을 유도합니다 d_p(a,b) = |a-b|_p. 그런 다음 이 메트릭과 관련하여이 필드를 완성 할 수 있습니다. 즉, 모든 코시 시퀀스가 ​​수렴되는 새로운 필드를 구성 할 수 있습니다. 이는 훌륭한 토폴로지 속성입니다. (예를 들어, 유리수에는없는 것이지만 실수에는 있습니다.)이 p-adic 숫자 는 짐작했던 것처럼 숫자 이론에서 많이 사용되었습니다.

또 다른 흥미로운 결과는 기본적으로 합리적인 숫자에 대한 절대 값 (아래 정의 참조)은 다음 세 가지 중 하나 인 Ostrowski의 정리 입니다.

  • 사소한 : |x|=0 iff x=0, |x|=1 otherwise
  • 표준 (실제) : |x| = x if x>=0, |x| = -x if x<0
  • p-adic (우리가 정의한대로).

절대 값 / 메트릭거리를 고려한 것의 일반화입니다 . 절대 값 |.|은 다음 조건을 충족합니다.

  • |x| >= 0 and |x|=0 if x=0
  • |xy| = |x| |y|
  • |x+y| <= |x|+|y|

: 당신은 쉽게 반대의 절대 값과 그에서 메트릭을 구성 할 수 있습니다 |x| := d(0,x)또는 d(x,y) := |x-y|그들은 거의 동일합니다, 그래서 당신이 할 수있는 경우, 추가 / 빼기 / 곱하기 (정역에 있음). 물론이 구조없이보다 일반적인 집합에 대한 메트릭을 정의 할 수 있습니다.


나는 Mathematica의 PadicNorm기능도 밖에 있다고 가정 합니까? : P
Alex A.

당신은 정확하다고 가정합니다. (여기서 어느 것이 사용됩니까?)
flawr

흥미로운 속성 섹션이 도전 과제를 완료하는 데 유용하지 않는 한, 관심있는 사람들을 위해 해당 정보에 연결하는 것이 좋습니다. 그렇지 않으면 불필요하게 게시물이 복잡해집니다.
Alex A.

분명히하기 위해 출력은 다음과 같아야합니다 |x|_11 = 11. 아니면 11괜찮아? 그리고 x=0사건 을 처리해야 합니까?
Glen O

@GlenO 수정, 그것은 처리해야 않는 x=0경우이 예를 들어, 당신은 출력 할 수 있습니다 11뿐만 아니라 같은 11/1,하지만 당신은 인쇄 할 필요가 없습니다 |x|_11.
flawr

답변:


3

줄리아, 94 80 75 바이트

f(m,n,p)=(k=gcd(m,n)
g(m)=m%p>0?g(m÷p)p:1
m!=0?print(g(n÷k),/,g(m÷k)):0)

참고 : 가독성을 위해 세미콜론 대신 줄 바꿈을 사용하면 어느 쪽이든 동일하게 작동합니다.

이것은 매우 간단합니다 - g(m,n)함수는 재귀과 나머지 (사용 %추출하는) p^n입력의 계수 m와, n=1디폴트로하고 곱하여 p출력 할 것이다 그래서, 재귀의 각 단계에서 p^n. 코드는이를에 적용한 n/gcd(m,n)다음 m/gcd(m,n)적절한 식을 얻습니다. 문자를 저장하기 위해 두 번 k=gcd(m,n)계산하지 않도록하는 데 사용됩니다 gcd(m,n). m!=0경우를 처리하는 테스트 x=0입니다.

출력은 형식 N/1이거나 1/N적절한 위치 N입니다 p^e.


1

J, 35 34 바이트

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:

이것은 소수 p를 왼쪽 인수로, 배열 m n을 오른쪽 인수로 취하는 이진 동사입니다 . 항상 슬래시를 인쇄하고 if를 /반환 0/1합니다 m = 0. 다음과 같이 사용하십시오.

  f =: (,'/'&,)&":/@(%+./)@(]<.^+.|.@])x:
  5 f 63 550
25/1

설명

x:확장 정밀도에 회전은, 이후 우리는 매우 많은 수를 처리하고 있습니다. 나머지 코드는 다음과 같이 작동합니다.

(,'/'&,)&":/@(%+./)@(]<.^+.|.@])
                        ^         Power: this gives the array p^n p^m
                         +.       Take element-wise GCD with
                           |.@]   the rotated array n m; this gives
                                  the largest powers of p that divide n and m
                      <.          Take element-wise minimum with
                     [            The array m n to handle the m=0 case correctly
              %+./                Divide this array by its GCD to get it to lowest terms
        &":/                      Convert both elements to strings
 ,'/'&,                           Insert the slash '/' between them

0

CJam, 42 바이트

q~)\_:*g_sW<o@*28#f{{{_@\%}h;}:G~}_~Gf/'/*

입력 0에 대한 오류 (0을 인쇄 한 후)와 함께 완료됩니다 . CJam 인터프리터 에서 온라인으로 시도하십시오 .


0

Stax , 32 바이트

éE▌ΦΔΘao£╙)ΩuÅI~AAε3∞xC█&½╤%╩▌ïö

실행 및 디버깅

더 짧게 만들 수 있어야합니다. Stax의 분수에 대한 기본 지원은 매우 깔끔합니다.

ASCII 상응 :

hY{y:+y|aEGsG-ys|**}0?}0{^scxHY%Cy/sWd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.