정수의 황금


21

양의 정수 N은 A와 표현할 수있는 정수 양쪽 직사각형 , B 되도록 N = * B . 즉, 영역은 숫자를 나타냅니다. 일반적으로 ab 는 주어진 n에 대해 고유하지 않습니다 .

잘 알려진 바와 같이, 사각형이 측면이 황금비 일 때 직사각형은 눈을 즐겁게 (또는 뇌입니까?) φ = (sqrt (5) +1) / 2 ≈ 1.6180339887 ...

이 두 가지 사실 결합이 문제의 목적은 정수를 분해하는 N 개의 정수의 곱으로 , B 그 비율에 가능한 한 가깝게이다 φ (ℝ에 통상 메트릭). 사실 φ가 불합리 고유 용액 쌍 (있다는 것을 의미 , B는 ).

도전

양수 주어 N 출력 양수 , B 되도록 * B = N 사이의 차분 절대 /의 Bφ가 최소화된다.

예를 들어, n = 12를 고려하십시오 . a * b = n 을 만족 하는 쌍 ( a , b ) 은 (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1). 비율이 φ에 가장 가까운 쌍 은 (4,3)이며 4/3 = 1.333입니다.

규칙

기능 또는 프로그램이 허용됩니다.

분자는 ( ) 나타나야 출력에, 상기 분모 ( B ) . 그 외에는 입력 및 출력 형식이 평소처럼 유연합니다. 예를 들어, 두 개의 숫자는 합리적인 구분 기호가있는 문자열 또는 배열로 출력 될 수 있습니다.

코드는 이론적으로 임의로 많은 숫자로 작동해야합니다. 실제로 메모리 나 데이터 형식 제한에 의해 제한 될 수 있습니다.

소수점 이하 세 번째 까지 정확하다면 대략적인 φ 버전을 고려하면 충분합니다 . 즉, 실제 φ 와 근사값 의 절대 차이는 0.0005를 초과하지 않아야합니다. 예를 들어 1.618이 허용됩니다.

대략적인 합리적인 버전의 φ 를 사용하면 솔루션이 고유하지 않을 가능성이 적습니다. 이 경우 최소화 기준을 만족하는 모든 쌍 a , b 를 출력 할 수 있습니다 .

가장 짧은 코드가 승리합니다.

테스트 사례

1        ->  1    1
2        ->  2    1 
4        ->  2    2
12       ->  4    3
42       ->  7    6
576      ->  32   18
1234     ->  2    617
10000    ->  125  80
199999   ->  1    199999
9699690  ->  3990 2431

예를 들어 a / bb / a 의 결과에 대한 답변이 가능한 한 1에 가까워 지지 않는 한 대부분의 답변은 φ에 대한 일종의 합리적인 근사치를 사용합니다.
Neil

@Neil 나는 당신의 의견을 이해하지 못합니다. |a/b-b/a-1|증거가 필요하지만 최소화에 대한 당신의 아이디어 는 유망합니다.
Luis Mendo

전체 증거를 주석에 넣을 수 있는지 확실하지 않지만 개요는 다음과 같습니다. 전체 사각형이 나타납니다 a/b. 단위 사각형을 제거하면 오른쪽에 작은 사각형이 나타납니다 b/a. 따라서 황금 사각형은 1의 차이를 달성합니다.
Neil

만약 피보나치 수열에서 a와 b가 인접하지 않으면, 시험에서 그것들을 포함하여 어떤 점이 있습니까?
딸기

즉, 1618 x 1000은 좋은 후보 인 것 같습니다 (또는 참고로 809 x 500)
Strawberry

답변:


6

젤리, 16 15 14 바이트

@ 마일 덕분에 1 바이트를 절약했습니다.

÷/ạØp
ÆDżṚ$ÇÞḢ

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

설명

÷/ạØp         Helper link, calculates abs(a/b - phi). Argument: [a, b]
÷/            Reduce by division to calculate a/b.
  ạØp         Calculate abs(a/b - phi).

ÆDżṚ$ÇÞḢ      Main link. Argument: n
ÆD            Get divisors of n.
  żṚ$         Pair the items of the list with those of its reverse. The reversed
              divisors of a number is the same list as the number divided by each
              of the divisors.
     ÇÞ       Sort by the output of the helper link of each pair.
       Ḣ      Get the first element [a, b] and implicitly print.

제수 목록의 뒷면을 자체와 인터리빙하여 바이트를 저장할 수 있습니다. ÷/ạØp¶ÆDżṚ$ÇÞḢ14 바이트를 사용 하여 인수로 [a, b]제공된 목록을 리턴합니다 n.
마일

@ 마일리지 쿨! 나는 분명히 완전히 놓쳤다 /. (이것은 내 Pyth 솔루션에서 한 일입니다.) 랩탑을 타면 편집합니다.
PurkkaKoodari


6

MATLAB, 96 81 바이트

골프 (15 바이트), 루이스 멘도의 소품

function w(n);a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]

기발한:

function w(n)
a=find(not(mod(n,1:n)));b=abs(a./(n./a)-1.618);c=find(not(b-min(b)));[a(c) n/a(c)]

이것은 훌륭한 해결책은 아니지만 코드 골프에 대한 첫 번째 시도입니다. 무슨 재미!


2
재미 있다고 동의했습니다! 사이트에 오신 것을 환영합니다!
DJMcMayhem

1
당신은 대체 할 수 있습니다 not에 의해 ~ 몇 바이트를 저장합니다. 또한 두 번째 출력을 사용하여 다음을 min제거 할 수 있습니다 find.a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo

잘 발견-그것은 꽤 많은 상징을 깎습니다!
ptev September

1
당신은 사용하여 짧게 만들 수 있습니다 n=input('');대신에 function w(n);다음의 추가 쌍의가 ()주위에를 mod.
flawr


5

수학, 51 바이트

#&@@SortBy[{x=Divisors@#,#/x},Abs[#/#2-1.618]&]&

그만큼 (위첨자로 표시된 전위 용 매쓰의 후위 연산자 T티카하여).

Mathematica에는 빌트인 기능이 GoldenRatio있지만 1.618이 훨씬 짧습니다. 특히 전자가 필요하기 때문 N@입니다.


5

Pyth, 21 20 18 바이트

hoacFN.n3C_Bf!%QTS

온라인으로 사용해보십시오. 테스트 스위트.

설명

  1. 의 inclu 받기 S1에서 입력 필자 범위를.
  2. f입력 값을 나누는 숫자를 찾습니다 !%QT.
  3. 도망 [that list, that list reversed] _B . 숫자의 역 제수는 각 제수로 나눈 숫자와 동일한 목록입니다.
  4. 쌍을 얻기 위해 목록을 바꿉니다. [numerator, denominator] .
  5. S는 o에 의해 쌍을 실온 a쌍의 비율 bsolute 차이 cFN와 황금비.n3 .
  6. 첫 번째 (가장 낮은) 페어 h를 가져 와서 인쇄하십시오.

5

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

n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

우리는 다음을 찾습니다.

  • a = n / φ> a²n 의 최대 제수
  • b = n / φ <b²n 의 최소 ​​제수

그런 다음 해는 [a, n / a] 또는 [b, n / b] 입니다. n / φ-a²b²-n / φ 와 비교 하여 0에 가장 가까운 식을 찾습니다.

다음 코드에 사용되는 실제 화학식 동일한 정밀도 φ보다 짧은 방법으로 기록 될 수있다 φ / 2를 기반으로 .8091.618.

따라서:

n / φ> a² ⇔ n / (φ / 2)> 2a²

과:

n / φ-a²> b²-n / φ ⇔ 2n / φ-a²> b² ⇔ n / (φ / 2)-a²> b²

복잡성

반복 횟수는 n의 요인 수에 따라 크게 달라집니다. 최악의 경우는 n이 소수 일 때 발생합니다. 1에서 n까지의 모든 반복을 수행하여 2 개의 제수 만 찾으면되기 때문입니다. 반면에 9999는 1999로 매끄럽고 우리는 브레이크 포인트 √ (n / φ) ≈ 2448의 양쪽에서 두 개의 제수를 빠르게 찾습니다.

테스트 사례

let f =
n=>{for(b=0,k=n/.809;n%++b||k>b*b*2&&(a=b););return[b=k-a*a>b*b?b:a,n/b]}

console.log(JSON.stringify(f(12)));       // [ 3, 4 ]
console.log(JSON.stringify(f(42)));       // [ 6, 7 ]
console.log(JSON.stringify(f(576)));      // [ 18, 32 ]
console.log(JSON.stringify(f(1234)));     // [ 2, 617 ]
console.log(JSON.stringify(f(10000)));    // [ 80, 125 ]
console.log(JSON.stringify(f(199999)));   // [ 1, 199999 ]
console.log(JSON.stringify(f(9699690)));  // [ 2431, 3990 ]


4

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

f=
n=>{p=r=>Math.abs(r/n-n/r-1);for(r=i=n;--i;)r=n%i||p(i*i)>p(r*r)?r:i;return[r,n/r]}
;
<input type=number min=1 oninput=[a.value,b.value]=f(+this.value)><input readonly id=a><input readonly id=b>

실제로 a / b - b / a -1 의 절대 값을 최소화 하는 ( a , b ) 쌍을 반환 하지만 적어도 1.618 테스트를 사용하여 4 바이트를 절약 할 수는 있지만 모든 테스트 사례에서 작동합니다. .


3

Brachylog , 41 바이트

:1fL:2a:Lzoht
,A:B#>.*?!,.=
:3a/:$A-$|
//

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

설명

  • 주요 술어 :

    :1fL           L is the list of all couples [A:B] such that A*B = Input (see Pred. 1)
        :2a        Compute the distance between all As/Bs and φ (see Pred. 2)
           :Lz     Zip those distances to L
              o    Sort the zip on the distances
               ht  Take the couple [A:B] of the first element of the sorted list
    
  • 술어 1 : 출력은 다음 [A:B]과 같은 커플 입니다.A*B = Input

    ,A:B           The list [A:B]
        #>         Both A and B are strictly positive
          .        Output = [A:B]
           *?      A*B = Input
             !,    Discard other choice points
               .=  Assign a value to A and B that satisfy the constraints
    
  • 술어 2 : A/B와 φ 사이의 거리를 계산합니다 .

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • 술어 3 : 역수를 뒤집어 정수를 부동 소수점으로 변환

    /              1/Input
     /             Output = 1/(1/Input)
    

호기심에서 : φBrachylog에서 사전 정의 된 리터럴입니까? 아니면 코드에서 어디에 정의되어 있습니까?
Luis Mendo

1
아, 방금 봤어요 :$A
Luis Mendo

2
;)를 A위한 @LuisMendoAu
Fatalize

아아, 아주 좋아요!
Luis Mendo

2

하스켈 (Lambdabot), 86 바이트

f(x,y)=abs$(x/y)-1.618
q n=minimumBy((.f).compare.f)[(x,y)|x<-[1..n],y<-[1..n],x*y==n]

2

PHP, 103 바이트

<?php for($s=$a=$argv[1];++$i<$a;)if($a%$i==0&&$s>$t=abs($i*$i/$a-1.618)){$n=$i;$s=$t;}echo"$n ".$a/$n;

할당되지 않은 $ i에 대한 알림을 생성합니다 (이는 실행을 방해하지 않습니다). 알림을 끄는 환경에서 실행해야합니다.


코드를 php -r '…'( -r무료로) 실행할 수있는 경우 PHP 오픈 태그를 계산할 필요가 없습니다 . short_open_tag기본적으로 켜져 있으므로 긴 형식이 필요하지 않습니다 .
manatwork

내가 아는 한 $ argv는 -r과 함께 작동하지 않으므로 어쨌든 실행할 수 없습니다. 그것은 당신이 창에 있고 태그없이 실행한다면 readline () 또는 fgets (STDIN)으로 변경하는 것이 어쨌든 짧을 것이라고 말했습니다.
user59178

-r$argv함께 잘 작동 : pastebin.com/vcgb5pT2
manatwork

허. 글쎄, 그것은 나를 위해 작동하지 않습니다, 나는 단지 정의되지 않은 변수 통지를 얻습니다. 설정인지 또는 평소와 같이 창인지 궁금합니다.
user59178

당신은 여전히 대체 할 수 <?php<?할인율 3 바이트.
Paul Schmitz

1

파이썬 3, 96 바이트

아주 간단한 해결책. 차종은의 사용 이 SO의 대답 .

lambda n:min([((i,n//i),abs(1.618-i/(n//i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]

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

Python 2의 동일한 솔루션은 1 바이트 더 깁니다.

lambda n:min([((i,n/i),abs(1.618-1.*i/(n/i)))for i in range(1,n+1)if n%i<1],key=lambda x:x[1])[0]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.