ความเป็นทองของจำนวนเต็ม


21

เป็นจำนวนเต็มบวกnสามารถแสดงเป็นรูปสี่เหลี่ยมที่มีด้านจำนวนเต็ม , ดังกล่าวที่n = * ข นั่นคือพื้นที่แสดงถึงจำนวน โดยทั่วไปและจะไม่ซ้ำกันสำหรับให้n

ในฐานะที่เป็นที่รู้จักกันดีสี่เหลี่ยมผืนผ้าเป็นพิเศษเจริญตา (หรือมันคือสมอง?) เมื่อด้านข้างอยู่ในอัตราส่วนทองคำ , φ = (sqrt (5) +1) / 2 ≈ 1.6180339887 ...

รวมทั้งสองข้อเท็จจริงวัตถุประสงค์ของความท้าทายนี้คือการย่อยสลายเป็นจำนวนเต็มnลงในผลิตภัณฑ์ของทั้งสองจำนวนเต็ม, Bซึ่งเป็นอัตราส่วนที่ใกล้ที่สุดเท่าที่เป็นไปได้ที่จะφ (โดยปกติตัวชี้วัดในℝ) ความจริงที่ว่าφนั้นไม่ลงตัวหมายความว่ามีคู่ของการแก้ปัญหาที่ไม่ซ้ำกัน ( a , b )

ความท้าทาย

รับจำนวนเต็มบวกnส่งออกจำนวนเต็มบวกa , bเช่น a * b = nและความแตกต่างที่แน่นอนระหว่างa / bและφถูกย่อให้เล็กสุด

เป็นตัวอย่างให้พิจารณาn = 12 คู่ ( a , b ) ที่ตรงกับ a * b = nคือ: (1, 12), (2,6), (3,4), (4,3), ( 6,2), (12,1) คู่ที่อัตราส่วนใกล้เคียงกับφมากที่สุดคือ (4,3) ซึ่งให้ 4/3 = 1.333

กฎระเบียบ

ฟังก์ชั่นหรือโปรแกรมเป็นที่ยอมรับ

เศษ ( ) ควรจะปรากฏขึ้นเป็นครั้งแรกในการส่งออกและหาร ( ) สอง นอกจากนั้นรูปแบบอินพุตและเอาต์พุตมีความยืดหยุ่นตามปกติ ตัวอย่างเช่นตัวเลขสองตัวสามารถส่งออกเป็นสตริงที่มีตัวคั่นที่เหมาะสมหรือเป็นอาร์เรย์

รหัสควรทำงานในทฤษฎีสำหรับจำนวนมากโดยพล ในทางปฏิบัติอาจถูก จำกัด โดยหน่วยความจำหรือข้อ จำกัด ชนิดข้อมูล

มันเพียงพอที่จะพิจารณารุ่นโดยประมาณของφตราบใดที่มันขึ้นอยู่ที่ถูกต้องกับทศนิยมที่สามหรือดีกว่า นั่นคือความแตกต่างแน่นอนระหว่างความจริงφและมูลค่าโดยประมาณไม่ควรเกิน 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

แน่นอนว่าคำตอบส่วนใหญ่จะใช้การประมาณด้วยเหตุผลบางอย่างเพื่อφเว้นแต่ว่าคุณจะยอมรับเช่นคำตอบที่มีผลลัพธ์ของ/ bb / aใกล้เคียงกับ 1 มากที่สุด
Neil

@ ไม่มีฉันไม่แน่ใจว่าฉันเข้าใจความคิดเห็นของคุณ ความคิดของคุณเกี่ยวกับการย่อขนาด|a/b-b/a-1|นั้นมีแนวโน้มดีแม้ว่าจะมีข้อพิสูจน์ว่าเป็นไปได้
Luis Mendo

ไม่แน่ใจว่าที่ฉันสามารถอัดหลักฐานทั้งหมดลงในความคิดเห็น แต่ร่างเป็นดังนี้: ทั้งสี่เหลี่ยมa/bหมายถึง การถอดหน่วยตารางใบสี่เหลี่ยมเล็ก ๆ b/aบนขวาซึ่งหมายถึง สี่เหลี่ยมสีทองจึงมีความแตกต่าง 1
นีล

หาก a และ b ไม่ใช่ตัวเลขที่อยู่ติดกันในลำดับ Fibbonacci มีประเด็นใดบ้างที่รวมอยู่ในการทดสอบ
สตรอเบอร์รี่

ที่กล่าวว่า 1618 x 1,000 ดูเหมือนว่าเป็นผู้สมัครที่ดี (หรือโดยอ้างอิง 809 x 500)
สตรอเบอร์รี่

คำตอบ:


6

เยลลี่, 16 15 14 ไบต์

บันทึกแล้ว 1 ไบต์ขอบคุณ @miles

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

คุณสามารถบันทึก byte โดยแทรกอินเทอร์เรซกลับของรายการตัวหารด้วยตัวเอง ใช้÷/ạØp¶ÆDżṚ$ÇÞḢสำหรับ 14 ไบต์มันจะส่งกลับรายการที่[a, b]กำหนดnเป็นอาร์กิวเมนต์
ไมล์

@miles สุดยอด! /เห็นได้ชัดว่าผมพลาดอย่างสมบูรณ์ใน (นี่คือสิ่งที่ฉันทำในโซลูชัน Pyth ของฉัน) จะแก้ไขเมื่อฉันไปถึงแล็ปท็อป
PurkkaKoodari


6

Matlab, 96 81 ไบต์

Golfed (-15bytes) ไปที่Luis Mendo

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

1
คุณสามารถทำให้มันสั้นลงโดยใช้n=input('');แทนจากfunction w(n);นั้นคุณมีคู่ของ()รอบmodพิเศษ
ข้อบกพร่อง


5

Mathematica, 51 ไบต์

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

ตัวดำเนินการ postfix ของ Mathematica สำหรับการขนย้าย (แสดงเป็นตัวยกTใน Mathematica)

Mathematica ได้ในตัวGoldenRatioแต่ 1.618 N@เป็นจำนวนมากที่สั้นลงโดยเฉพาะอย่างยิ่งเพราะในอดีตนอกจากนี้ยังต้อง


5

Pyth, 21 20 18 ไบต์

hoacFN.n3C_Bf!%QTS

ลองออนไลน์ ชุดทดสอบ

คำอธิบาย

  1. รับช่วง inclu Sive ตั้งแต่ 1 ถึงอินพุต
  2. filter !%QTสำหรับตัวเลขสำหรับแบ่งว่าการป้อนข้อมูล
  3. [that list, that list reversed] _Bได้รับ ตัวหารที่กลับกันของตัวเลขนั้นเป็นรายการเดียวกับหมายเลขที่หารด้วยตัวหารแต่ละตัว
  4. [numerator, denominator]ย้ายรายการที่จะได้รับคู่ของ
  5. S ort คู่โดยaความแตกต่าง bsolute ของอัตราส่วนของทั้งคู่และอัตราส่วนทองคำcFN.n3
  6. รับคู่ (ต่ำสุด) แรกhและพิมพ์

5

Javascript (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 ซึ่งn / φ> a²
  • b = ตัวหารต่ำสุดของ n ซึ่งn / φ <b²

จากนั้นการแก้ปัญหาคือทั้ง[a, n / a]หรือ[b, n / b] เราเปรียบเทียบn / φ - a²กับb² - n / φเพื่อหาว่านิพจน์ใดใกล้เคียงกับศูนย์มากที่สุด

สูตรที่ใช้จริงในรหัสที่อยู่บนพื้นฐานของφ / 2 ซึ่งสามารถเขียนได้ในทางที่สั้นกว่าφที่มีความแม่นยำเดียวกัน: VS.8091.618

ดังนั้น:

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

และ:

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

ความซับซ้อน

จำนวนการวนซ้ำอย่างมากขึ้นอยู่กับจำนวนปัจจัยของ n กรณีที่เลวร้ายที่สุดเกิดขึ้นเมื่อ n เป็นไพรม์เพราะเราต้องทำการวนซ้ำทั้งหมดจาก 1 ถึง n เพื่อค้นหาตัวหาร 2 ตัวเท่านั้น นี่คือสิ่งที่เกิดขึ้นกับ 199999 ในทางกลับกัน 9699690 เป็น 19-smooth

กรณีทดสอบ

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 ไบต์

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 ) ซึ่งลดค่าสัมบูรณ์ของa / b - b / a -1 แต่วิธีนี้ใช้ได้กับทุกกรณีทดสอบอย่างน้อยที่สุดถึงแม้ว่าฉันเดาว่าฉันสามารถบันทึก 4 ไบต์โดยใช้การทดสอบ 1.618 แทน .


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: แปลง int เป็น float โดยแปลงกลับด้าน

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

จากความอยากรู้: เป็นφตัวอักษรที่กำหนดไว้ล่วงหน้าใน Brachylog หรือไม่? หรือมันถูกกำหนดไว้ในรหัส?
Luis Mendo

1
โอ้ฉันเพิ่งเห็น:$A
Luis Mendo

2
@LuisMendo AสำหรับAu;)
ทำให้เสียชีวิต

อ้าดีมาก!
Luis Mendo


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 ไม่จำเป็นเมื่อรหัสสามารถเรียกใช้เป็นphp -r '…'(ที่-rฟรี) และไม่จำเป็นต้องมีรูปแบบยาวเช่นเดียวกับที่short_open_tagเป็นค่าเริ่มต้น
จัดการ

เท่าที่ฉันรู้ $ argv ไม่ทำงานกับ -r ดังนั้นมันจึงไม่สามารถทำงานได้เช่นนั้น ที่กล่าวว่าการเปลี่ยนเป็น readline () หรือ fgets (STDIN) หากคุณอยู่บน windows และทำงานโดยไม่มีแท็ก
user59178

-rและ$argvทำงานร่วมกันได้ดี: pastebin.com/vcgb5pT2
จัดการ

ฮะ. มันไม่ทำงานสำหรับฉันฉันเพิ่งได้รับประกาศตัวแปรที่ไม่ได้กำหนดฉันสงสัยว่ามันเป็นการตั้งค่าหรือถ้ามันเป็นเพียงหน้าต่างตามปกติ
user59178

คุณยังสามารถแทนที่<?phpด้วย<?เพื่อบันทึกสามไบต์
Paul Schmitz

1

Python 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 นั้นยาวกว่าหนึ่งไบต์

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.