Độ vàng của một số nguyên


21

Một số nguyên dương n có thể được biểu diễn dưới dạng hình chữ nhật với các cạnh nguyên a , b sao cho n = a * b . Đó là, khu vực đại diện cho số lượng. Nói chung, ab không phải là duy nhất cho n .

Như đã biết, một hình chữ nhật được đặc biệt làm hài lòng được bằng mắt (hoặc là nó não?) Khi các cạnh của nó đang trong tỷ lệ vàng , φ = (sqrt (5) +1) / 2 ≈ 1,6180339887 ...

Kết hợp hai sự kiện này, mục đích của thử thách này là để phân hủy một số nguyên n thành tích của hai số nguyên một , b có tỷ lệ là càng gần càng tốt để φ (với số liệu thông thường trên ℝ). Thực tế là φ là không hợp lý ngụ ý rằng có một cặp giải pháp duy nhất ( một , b ).

Các thách thức

Cho một số nguyên dương n , sản lượng nguyên dương một , b như vậy mà một * b = n và sự khác biệt tuyệt đối giữa một / bφ được giảm thiểu.

Ví dụ: xem xét n = 12. Các cặp ( a , b ) thỏa mãn a * b = n là: (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1). Cặp có tỷ lệ gần nhất với φ là (4,3), cho 4/3 = 1.333.

Quy tắc

Chức năng hoặc chương trình được chấp nhận.

Các tử số ( một ) sẽ xuất hiện đầu tiên trong đầu ra, và các mẫu số ( b ) thứ hai . Ngoài ra, các định dạng đầu vào và đầu ra linh hoạt như bình thường. Ví dụ, hai số có thể là đầu ra dưới dạng chuỗi với bất kỳ dấu tách hợp lý nào hoặc dưới dạng một mảng.

Các mã nên làm việc trong lý thuyết cho số lượng lớn tùy ý. Trong thực tế, nó có thể bị giới hạn bởi các hạn chế về bộ nhớ hoặc kiểu dữ liệu.

Đó là đủ để xem xét một phiên bản gần đúng của φ , miễn là nó tùy thuộc chính xác đến chữ số thập phân thứ ba hoặc tốt hơn. Đó là, sự khác biệt tuyệt đối giữa đúng φ và giá trị xấp xỉ không được vượt quá 0,0005. Ví dụ, 1.618 là chấp nhận được.

Khi sử dụng, phiên bản hợp lý tương đối của φ có một cơ hội nhỏ rằng giải pháp không phải là độc đáo. Trong trường hợp đó, bạn có thể xuất bất kỳ cặp a , b nào thỏa mãn tiêu chí tối thiểu hóa.

Mã ngắn nhất sẽ thắng.

Các trường hợp thử nghiệm

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

Chắc chắn hầu hết các câu trả lời sẽ sử dụng một số phép tính gần đúng hợp lý cho, trừ khi bạn chấp nhận, ví dụ: câu trả lời có kết quả là a / bb / a càng gần 1 càng tốt.
Neil

@Neil Tôi không chắc là tôi hiểu bình luận của bạn. Ý tưởng giảm thiểu của bạn |a/b-b/a-1|rất hứa hẹn, mặc dù một bằng chứng sẽ được đưa ra
Luis Mendo

Không chắc chắn rằng tôi có thể nhồi nhét toàn bộ bằng chứng vào một nhận xét, nhưng phác thảo như sau: toàn bộ hình chữ nhật đại diện a/b. Xóa hình vuông đơn vị để lại hình chữ nhật nhỏ bên phải đại diện b/a. Do đó, một hình chữ nhật vàng đạt được mức chênh lệch là 1.
Neil

Nếu a và b không có các số liền kề trong dãy Fftimeacci, có điểm nào bao gồm chúng trong bài kiểm tra không?
Dâu tây

Điều đó nói rằng, 1618 x 1000 có vẻ như là một ứng cử viên tốt (hoặc, theo tham chiếu, 809 x 500)
Dâu tây

Câu trả lời:


6

Thạch, 16 15 14 byte

Đã lưu 1 byte nhờ @miles.

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

Hãy thử trực tuyến!

Giải trình

÷/ạØ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.

Bạn có thể lưu một byte bằng cách xen kẽ đảo ngược danh sách chia. Sử dụng ÷/ạØp¶ÆDżṚ$ÇÞḢcho 14 byte, nó trả về một danh sách [a, b]được cung cấp ndưới dạng đối số.
dặm

@miles Tuyệt! Tôi dường như hoàn toàn bỏ lỡ /. (Đây là những gì tôi đã làm trong giải pháp Pyth của mình.) Sẽ chỉnh sửa khi tôi nhận được trên máy tính xách tay của mình.
PurkkaKoodari


6

Matlab, 96 81 byte

Chơi gôn (-15byte), đạo cụ cho Luis Mendo

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

Nguyên:

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)]

Đây không phải là một giải pháp tuyệt vời, nhưng nỗ lực đầu tiên của tôi về môn đánh gôn. Có gì vui!


2
Đồng ý rằng nó rất vui! Chào mừng đến với trang web!
DJMcMayhem

1
Bạn có thể thay thế notbằng cách ~ lưu một vài byte. Ngoài ra, sử dụng đầu ra thứ hai của minbạn có thể thoát khỏi find:a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo

Cũng phát hiện ra - mà loại bỏ khá nhiều biểu tượng!
ptev

1
Bạn có thể làm cho nó ngắn hơn bằng cách sử dụng n=input('');thay vì function w(n);sau đó bạn có thêm một cặp ()xung quanh mod.
flawr


5

Toán học, 51 byte

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

Các nhà điều hành postfix Mathematica cho chuyển vị (hiển thị như một superscript Ttrong Mathematica).

Mathematica có tích hợp sẵn GoldenRatio, nhưng 1.618 ngắn hơn rất nhiều, đặc biệt là vì trước đây cũng yêu cầu N@.


5

Pyth, 21 20 18 byte

hoacFN.n3C_Bf!%QTS

Hãy thử trực tuyến. Bộ thử nghiệm.

Giải trình

  1. Lấy Sphạm vi inclu ive từ 1 đến đầu vào.
  2. filter cho các số cho phân chia đầu vào !%QT.
  3. Nhận [that list, that list reversed] _B. Các ước số đảo ngược của một số là cùng một danh sách với số chia cho mỗi ước số.
  4. Chuyển danh sách để có được cặp [numerator, denominator].
  5. S ort các cặp theo achênh lệch bsolute của tỷ lệ của cặp cFNvà tỷ lệ vàng .n3.
  6. Lấy cặp đầu tiên (thấp nhất) hvà in.

5

Javascript (ES6), 73 byte

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]}

Chúng tôi tìm kiếm:

  • a = ước số cao nhất của n mà n /> a²
  • b = ước số thấp nhất của n mà n / <b²

Sau đó, giải pháp là [a, n / a] hoặc [b, n / b] . Chúng tôi so sánh n / - a² với b² - n / φ để tìm ra biểu thức nào gần nhất với số không.

Công thức thực tế sử dụng trong mã dựa trên φ / 2 mà có thể được viết một cách ngắn hơn φ với độ chính xác như nhau: .809vs 1.618.

Vì thế:

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

và:

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

Phức tạp

Số lần lặp phụ thuộc rất nhiều vào số lượng các yếu tố của n. Trường hợp xấu nhất xảy ra khi n là số nguyên tố, bởi vì chúng ta phải thực hiện tất cả các lần lặp từ 1 đến n để tìm 2 ước số duy nhất của nó. Đây là những gì xảy ra với 199999. Mặt khác, 9699690 là 19-mịn và chúng tôi nhanh chóng tìm thấy hai ước số ở hai bên của điểm phá vỡ (n /) 2448.

Các trường hợp thử nghiệm

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

JavaScript (ES6), 83 byte

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>

Trên thực tế trả về cặp ( a , b ) tối thiểu hóa giá trị tuyệt đối của a / b - b / a -1, nhưng điều này hoạt động cho tất cả các trường hợp thử nghiệm ít nhất, mặc dù tôi đoán rằng tôi có thể lưu 4 byte bằng cách sử dụng thử nghiệm 1.618 thay thế .


3

Brachylog , 41 byte

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

Hãy thử trực tuyến!

Giải trình

  • Vị ngữ chính:

    :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
    
  • Vị ngữ 1: Đầu ra là một vài [A:B]ví dụ mà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
    
  • Vị ngữ 2: Tính khoảng cách giữa A/Bvà.

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • Vị ngữ 3: Chuyển đổi một int thành một float bằng cách đảo ngược nghịch đảo của nó

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

Vì tò mò: là φmột nghĩa đen được xác định trước trong Brachylog? Hoặc nó được định nghĩa ở đâu trong mã?
Luis Mendo

1
Ồ, tôi vừa thấy:$A
Luis Mendo

2
@LuisMendo Afor Au;)
Gây tử vong vào

Aaah, rất tốt đẹp!
Luis Mendo

2

Haskell (Lambdabot), 86 byte

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 byte

<?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;

Tạo một thông báo (điều này không làm gián đoạn thực thi) về $ i chưa được gán vì vậy nên được chạy trong một môi trường im lặng thông báo.


Đếm thẻ mở PHP là không cần thiết khi mã có thể được chạy dưới dạng php -r '…'(nơi -rmiễn phí). Và chắc chắn không cần hình thức dài, như short_open_tagmặc định.
manatwork

Theo như tôi biết $ argv không hoạt động với -r vì vậy dù sao thì điều này không thể chạy như thế. Điều đó nói rằng việc thay đổi nó thành readline () hoặc fgets (STDIN) nếu bạn đang ở trên windows và chạy mà không có thẻ có thể ngắn hơn.
dùng59178

-r$argvđang làm việc tốt với nhau: pastebin.com/vcgb5pT2
manatwork

Huh. Vâng, nó không hoạt động đối với tôi, tôi chỉ nhận được các thông báo biến không xác định, tôi tự hỏi liệu đó có phải là cài đặt hay nếu nó chỉ là cửa sổ như bình thường.
dùng59178

Bạn vẫn có thể thay thế <?phpbằng <?để lưu ba byte.
Paul Schmitz

1

Python 3, 96 byte

Giải pháp khá đơn giản. Làm cho việc sử dụng câu trả lời SO này .

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]

Dùng thử trực tuyến

Giải pháp tương tự trong Python 2 dài hơn một byte.

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]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.