Keemasan bilangan bulat


21

Bilangan bulat positif n dapat direpresentasikan sebagai persegi panjang dengan sisi bilangan bulat a , b sedemikian rupa sehingga n = a * b . Artinya, area mewakili angka. Secara umum, a dan b tidak unik untuk yang diberikan n .

Seperti diketahui, persegi panjang secara khusus menyenangkan mata (atau apakah itu otak?) Ketika sisinya berada dalam rasio emas , φ = (sqrt (5) +1) / 2 ≈ 1.6180339887 ...

Menggabungkan dua fakta ini, tujuan dari tantangan ini adalah untuk menguraikan bilangan bulat n menjadi produk dari dua bilangan bulat a , b yang rasionya sedekat mungkin dengan φ (dengan metrik biasa pada ℝ). Fakta bahwa φ tidak rasional menyiratkan bahwa ada pasangan solusi yang unik ( a , b ).

Tantangan

Dengan bilangan bulat positif n , bilangan bulat keluaran positif a , b sehingga a * b = n dan perbedaan absolut antara a / b dan φ diminimalkan.

Sebagai contoh, perhatikan n = 12. Pasangan ( a , b ) yang memenuhi a * b = n adalah: (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1). Pasangan yang rasionya paling dekat dengan φ adalah (4,3), yang memberikan 4/3 = 1,333.

Aturan

Fungsi atau program dapat diterima.

The pembilang ( a ) harus muncul pertama pada output, dan penyebut ( b ) kedua . Selain itu, format input dan output fleksibel seperti biasa. Sebagai contoh, dua angka bisa berupa string dengan pemisah yang masuk akal, atau sebagai array.

Kode harus bekerja secara teori untuk jumlah besar yang sewenang-wenang. Dalam praktiknya, ini mungkin dibatasi oleh memori atau batasan tipe data.

Cukup untuk mempertimbangkan versi perkiraan φ , asalkan akurat hingga desimal ketiga atau lebih baik. Artinya, perbedaan absolut antara φ benar dan nilai perkiraan tidak boleh melebihi 0,0005. Misalnya, 1.618 dapat diterima.

Saat menggunakan perkiraan, versi rasional φ ada kemungkinan kecil bahwa solusinya tidak unik. Dalam hal ini Anda dapat menampilkan pasangan apa pun a , b yang memenuhi kriteria minimalisasi.

Kode terpendek menang.

Uji kasus

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

Tentunya sebagian besar jawaban akan menggunakan semacam pendekatan rasional untuk φ, kecuali jika Anda menerima mis. Jawaban dengan hasil a / bb / a sedekat mungkin dengan 1.
Neil

@Neil Saya tidak yakin saya mengerti komentar Anda. Gagasan Anda untuk meminimalisir |a/b-b/a-1|itu menjanjikan, meskipun ada bukti yang mendukung
Luis Mendo

Tidak yakin bahwa saya bisa menjejalkan seluruh bukti menjadi komentar, tetapi garis besarnya adalah sebagai berikut: seluruh kotak mewakili a/b. Menghapus unit persegi meninggalkan persegi panjang kecil di sebelah kanan yang mewakili b/a. Oleh karena itu, persegi panjang emas menghasilkan perbedaan 1.
Neil

Jika a dan b bukan angka yang berdekatan dalam urutan Fibbonacci, apakah ada titik termasuk mereka dalam tes?
Strawberry

Yang mengatakan, 1618 x 1000 sepertinya kandidat yang baik (atau, dengan referensi, 809 x 500)
Strawberry

Jawaban:


6

Jelly, 16 15 14 byte

Disimpan 1 byte berkat @miles.

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

Cobalah online!

Penjelasan

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

Anda dapat menyimpan byte dengan menyisipkan kebalikan dari daftar pembagi dengan dirinya sendiri. Menggunakan ÷/ạØp¶ÆDżṚ$ÇÞḢuntuk 14 byte, ia mengembalikan daftar yang [a, b]diberikan nsebagai argumen.
miles

@miles Cool! Saya tampaknya benar-benar ketinggalan /. (Ini yang saya lakukan dalam solusi Pyth saya.) Akan mengedit ketika saya mendapatkan di laptop saya.
PurkkaKoodari


6

Matlab, 96 81 byte

Golf (-15bytes), alat peraga untuk Luis Mendo

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

Asli:

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

Sejauh ini ini bukan solusi yang bagus, tetapi upaya pertama saya di kode-golf. Apanya yang seru!


2
Setuju bahwa itu menyenangkan! Selamat datang di situs ini!
DJMcMayhem

1
Anda dapat mengganti notdengan ~ untuk menyimpan beberapa byte. Juga, dengan menggunakan output kedua minAnda dapat menyingkirkan find:a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo

Terlihat dengan baik - yang memangkas beberapa simbol!
ptev

1
Anda dapat membuatnya lebih pendek dengan menggunakan n=input('');daripada function w(n);kemudian Anda memiliki pasangan ekstra di ()sekitar mod.
flawr


5

Mathematica, 51 byte

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

Ini adalah operator postfix Mathematica untuk transposisi (ditampilkan sebagai superscript Tdalam Mathematica).

Mathematica memiliki built-in GoldenRatio, tetapi 1.618 jauh lebih pendek, terutama karena yang pertama juga membutuhkan N@.


5

Pyth, 21 20 18 byte

hoacFN.n3C_Bf!%QTS

Cobalah online. Suite uji.

Penjelasan

  1. Dapatkan Srentang inklusif dari 1 hingga input.
  2. filter untuk angka untuk membagi input !%QT.
  3. Dapatkan [that list, that list reversed] _B. Pembagi nomor yang dibalik adalah daftar yang sama dengan nomor yang dibagi oleh masing-masing pembagi.
  4. Ubah urutan daftar untuk mendapatkan pasangan [numerator, denominator].
  5. S ort pasangan dengan aperbedaan bsolute dari rasio dari pasangan cFNdan rasio emas .n3.
  6. Dapatkan pasangan ( hcetak ) pertama dan cetak.

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

Kami mencari:

  • a = pembagi tertinggi n yang n / φ> a²
  • b = pembagi terendah n yang n / φ <b²

Kemudian, solusinya adalah [a, n / a] atau [b, n / b] . Kami membandingkan n / φ - a² dengan b² - n / φ untuk mengetahui ekspresi mana yang paling dekat dengan nol.

Rumus yang sebenarnya digunakan dalam kode didasarkan pada φ / 2 yang dapat ditulis dengan cara lebih pendek dari φ dengan presisi yang sama: .809vs 1.618.

Karena itu:

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

dan:

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

Kompleksitas

Jumlah iterasi sangat tergantung pada jumlah faktor n. Kasus terburuk terjadi ketika n adalah prima, karena kita harus melakukan semua iterasi dari 1 ke n untuk menemukan hanya 2 pembagi. Inilah yang terjadi dengan 199999. Di sisi lain, 9699690 adalah 19-halus dan kami dengan cepat menemukan dua pembagi di kedua sisi titik pemecah √ (n / φ) ≈ 2448.

Uji kasus

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>

Sebenarnya mengembalikan pasangan ( a , b ) yang meminimalkan nilai absolut dari a / b - b / a -1, tetapi ini bekerja untuk semua kasus uji setidaknya, meskipun saya kira saya bisa menghemat 4 byte dengan menggunakan tes 1,618 sebagai gantinya .


3

Brachylog , 41 byte

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

Cobalah online!

Penjelasan

  • Predikat utama:

    :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
    
  • Predikat 1: Output adalah pasangan [A:B]sedemikian rupaA*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
    
  • Predikat 2: Hitung jarak antara A/Bdan φ.

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • Predikat 3: Konversi int menjadi float dengan membalikkan kebalikannya

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

Karena penasaran: apakah φliteral yang sudah ditentukan sebelumnya ada di Brachylog? Atau di mana itu didefinisikan dalam kode?
Luis Mendo

1
Oh, saya baru saja melihat:$A
Luis Mendo

2
@LuisMendo Auntuk Au;)
Fatalkan

Aaah, sangat bagus!
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;

Menghasilkan pemberitahuan (ini tidak mengganggu eksekusi) tentang $ i yang belum ditetapkan sehingga harus dijalankan di lingkungan yang membungkam pemberitahuan.


Menghitung tag terbuka PHP tidak diperlukan saat kode dapat dijalankan sebagai php -r '…'(di mana -rgratis). Dan jelas tidak perlu untuk bentuk panjang, seperti short_open_tagyang diaktifkan secara default.
manatwork

Sejauh yang saya tahu $ argv tidak berfungsi dengan -r jadi ini tidak bisa dijalankan seperti itu. Yang mengatakan mengubahnya ke readline () atau fgets (STDIN) jika Anda menggunakan windows dan menjalankannya tanpa tag mungkin lebih pendek.
user59178

-rdan $argvbekerja sama dengan baik: pastebin.com/vcgb5pT2
manatwork

Hah. Yah itu tidak bekerja untuk saya, saya hanya mendapatkan pemberitahuan variabel yang tidak terdefinisi, saya ingin tahu apakah itu pengaturan atau apakah itu hanya windows seperti biasa.
user59178

Anda masih bisa mengganti <?phpdengan <?untuk menyimpan tiga byte.
Paul Schmitz

1

Python 3, 96 byte

Solusi yang cukup sederhana. Manfaatkan jawaban SO ini .

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]

Cobalah online

Solusi yang sama di Python 2 adalah satu byte lebih lama.

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]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.