Bir tamsayının altınlığı


21

Pozitif bir tam sayı , n , bir şekilde temsil edilebilir tamsayı kenarları dikdörtgen bir , b , öyle ki n = bir * b . Yani, alan sayıyı temsil eder. Genel olarak, a ve b verilen n için benzersiz değildir .

Bilindiği gibi, kenarları altın orandayken bir dikdörtgen özellikle göze hoş geliyor (veya beyin mi?) , Φ = (sqrt (5) +1) / 2 ≈ 1.6180339887 ...

Bu iki olgunun bir araya getiren bu sorun amacı bir tamsayıyı ayrıştırılması için n, iki tamsayı ürüne bir , b olan oranı mümkün olduğunca yakın gibidir cp (ℝ olağan boyutlar ile). Φ irrasyonel olduğu gerçeği, benzersiz bir çözüm çifti olduğu anlamına gelir ( a , b ).

Meydan okuma

Olumlu bir tamsayı n verildiğinde , çıktı pozitif tamsayı a , b , a * b = n olacak ve a / b ve φ arasındaki mutlak fark en aza indirilecektir .

Örnek olarak, n = 12'yi dikkate alın . A * b = n'yi sağlayan çiftler ( a , b ) : (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1). Oranı φ 'ya en yakın olan çift (4,3) olup, 4/3 = 1.333' dür.

kurallar

İşlevler veya programlar kabul edilebilir.

Payı ( a ) görünmelidir birinci çıkış ve payda ( b ) ikinci bir . Bunun dışında, giriş ve çıkış formatları her zamanki gibi esnektir. Örneğin, iki sayı, herhangi bir makul ayırıcıya sahip dizeler olarak veya bir dizi olarak çıkarılabilir.

Kod isteğe bağlı olarak büyük sayılar için teoride çalışmalıdır. Uygulamada, bellek veya veri tipi kısıtlamaları ile sınırlandırılabilir.

Üçüncü ondalık basamağa kadar doğru olduğu sürece φ yaklaşık bir versiyonunu düşünmek yeterlidir . Bu doğru arasındaki mutlak fark cp ve yaklaşık değer 0.0005'i geçmemelidir. Örneğin, 1.618 kabul edilebilir.

Yaklaşık bir, rasyonel sürümünü kullanırken cp çözüm benzersiz olmadığını küçük bir şans var. Bu durumda herhangi bir a , b çiftini çıkartabilirsiniz. en aza indirme kriterini karşılayan .

En kısa kod kazanır.

Test durumları

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

Şüphesiz çoğu cevap φ 'ye rasyonel bir yaklaşım yaklaşımı kullanacaktır, eğer a / bb / a sonucunun cevabını mümkün olduğunca 1'e yakın bir şekilde kabul etmediğiniz sürece .
Neil

@Neil Yorumunuzu anladığımdan emin değilim. Küçültme fikriniz |a/b-b/a-1|ümit verici olsa da, bir ispat düzenli olsa da
Luis Mendo

Bir kanıtı bir yorumda toplayabileceğimden emin değilim, ancak ana hat aşağıdaki gibidir: tüm dikdörtgen temsil eder a/b. Birim karesini kaldırmak, sağdaki küçük dikdörtgeni temsil eder b/a. Altın bir dikdörtgen bu nedenle 1 fark yaratır.
Neil

A ve b, Fibbonacci dizisindeki bitişik rakamlar değilse, testte bunları içeren herhangi bir nokta var mı?
Çilek,

Yani, 1618 x 1000 iyi bir aday gibi görünüyor (ya da referans olarak 809 x 500)
Çilek,

Yanıtlar:


6

Jöle, 16 15 14 bayt

@Miles sayesinde 1 byte kaydedildi.

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

Çevrimiçi deneyin!

açıklama

÷/ạØ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ölen listesinin tersini kendisiyle harmanlayarak bir bayt kaydedebilirsiniz. Kullanılması ÷/ạØp¶ÆDżṚ$ÇÞḢ14 byte için, bir liste döndürür [a, b]verilen nbağımsız değişken olarak.
mil

@miles Cool! Görünüşe göre tamamen özledim /. (Pyth çözümümde yaptığım şey buydu.) Dizüstü bilgisayarıma çıktığımda düzenleme yapacak.
PurkkaKoodari 12:16


6

Matlab, 96 81 bayt

Golf (-15bayt), Luis Mendo'ya sahne

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

Orijinal:

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

Bu, bugüne kadar mükemmel bir çözüm değil, ilk kod-golf girişimi. Ne komik!


2
Eğlenceli olduğunu kabul etti! Siteye Hoşgeldiniz!
DJMcMayhem

1
Sen yerini alabilir nottarafından ~ birkaç byte kaydedin. Ayrıca, ikinci çıktısını kullanarak minkurtulabilirsiniz find:a=find(~(mod(n,1:n)));[~,c]=min(abs(a./(n./a)-1.618));[a(c) n/a(c)]
Luis Mendo

Peki benekli - Bu bazı semboller tıraş!
ptev 12:16

1
Bunun n=input('');yerine kullanarak kısaltabilirsiniz, function w(n);daha sonra ()etrafında fazladan bir çift vardır mod.
kusur


5

Mathematica, 51 bayt

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

(Bir üst simge olarak görüntülenir aktarılması için Mathematica adlı postfix operatörü olan TMathematica).

Mathematica'nın yerleşik GoldenRatiobir yeri var, ancak 1.618, özellikle de eskilerin gerektirdiği için çok daha kısa N@.


5

Pyth, 21 20 18 bayt

hoacFN.n3C_Bf!%QTS

Çevrimiçi deneyin. Test odası.

açıklama

  1. S1'den girişe dahil olmak üzere ive aralığını alın .
  2. fBunun için ilter için ilter girişi bölmek !%QT .
  3. Almak [that list, that list reversed] _B . Bir sayının ters çevrilmiş bölenleri, bölenlerin bölünmüş sayılarıyla aynıdır.
  4. Çiftleri almak için listeyi çevir [numerator, denominator].
  5. S otarafından çiftleri oda sıcaklığına açiftinin oranının bsolute farkı cFNve altın oranı .n3.
  6. İlk (en düşük) çifti al hve yazdır.

5

Javascript (ES6), 73 bayt

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

Bakarız:

  • a = n / φ> a² olan n'in en yüksek böleni
  • b = n / φ <b² olan n'in en düşük böleni

Ardından, çözelti [a, n / a] veya [b, n / b] . Biz karşılaştırmak a² - n / φ ile b² - n / φ sıfıra yakın olduğu ifade öğrenmek için.

Kodda kullanılan asıl formül, aynı hassasiyetle are'den daha kısa bir şekilde yazılabilen φ / 2 tabanlıdır: .809vs1.618 .

Bu nedenle:

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

ve:

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

karmaşa

Yineleme sayısı büyük ölçüde n'nin faktör sayısına bağlıdır. En kötü durum n'nin asal olduğu durumlarda ortaya çıkar, çünkü sadece 2 bölücüyü bulmak için 1'den n'ye kadar olan tüm tekrarlamaları yapmamız gerekir. 199999'da olan budur. Öte yandan, 9699690 19 düzgündür ve kırılma noktasının the (n / φ) ≈ 2448 iki tarafındaki hızlıca iki bölen buluruz.

Test durumları

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 bayt

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>

Aslında a / b - b / a -1 mutlak değerini en aza indiren ( a , b ) çiftini döndürür , ancak bunun yerine en az 1.618 testi kullanarak 4 bayt kaydedebildiğim halde, tüm test durumlarında işe yarar. .


3

Brachylog , 41 bayt

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

Çevrimiçi deneyin!

açıklama

  • Ana tahmin:

    :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
    
  • Yüklem 1: Çıktı bir çift [A:B]olacak şekildeA*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
    
  • Tahmini 2: A/Bve φ arasındaki mesafeyi hesaplayın .

    :3a            Convert A and B to floats
       /           Divide A by B
        :$A-       Subtract φ
            $|     Absolute value
    
  • Tahmin 3: Tersini ters çevirerek int değerini float'a dönüştür

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

Meraktan: φBrachylog'da önceden tanımlanmış bir değişmez mi? Veya kodda nerede tanımlanır?
Luis Mendo,

1
Oh, az önce gördüm:$A
Luis Mendo

2
@LuisMendo Aiçin Au);
Fatalize

Aaah, çok hoş!
Luis Mendo


2

php, 103 bayt

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

Atanmamış $ i hakkında bir bildirim (bu yürütmeyi kesintiye uğratmaz) üretir; bu nedenle bildirimleri susturan bir ortamda çalıştırılmalıdır.


Kodun çalıştırılabildiği durumlarda PHP açık etiketinin sayılması gerekli değildir php -r '…'( -rücretsizdir). Ve kesinlikle short_open_tagvarsayılan olarak açık olduğu gibi uzun forma gerek yok .
Manatwork 12:16

Bildiğim kadarıyla $ argv -r ile çalışmaz, bu yüzden bu şekilde çalıştırılamaz. Bu, eğer penceredeyseniz ve etiketsiz çalışıyorsanız onu readline () veya fgets (STDIN) olarak değiştirmenin muhtemelen daha kısa olduğu söyleniyor.
user59178

-rve $argvbirlikte iyi çalışıyoruz: pastebin.com/vcgb5pT2
manatwork

Huh. Benim için işe yaramıyor, sadece tanımsız değişken bildirimleri alıyorum, bir ayar mı yoksa her zamanki gibi sadece pencere mi olduğunu merak ediyorum.
user59178 12:16

Üç bayttan tasarruf <?phpetmek <?için hala ile değiştirebilirsiniz .
Paul Schmitz

1

Python 3, 96 bayt

Oldukça basit bir çözüm. Markalar kullanımı bu SO cevap .

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]

Çevrimiçi deneyin

Python 2'deki aynı çözüm bir bayt daha uzundur.

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]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.