การเขียนจำนวนตรรกยะเป็นอัตราส่วนของแฟกทอเรียลของช่วงเวลา


19

หมายเหตุ: ความท้าทายนี้ได้รับการโพสต์บนกล่องเครื่องมือ

บทนำ

ความท้าทายนี้ได้รับแรงบันดาลใจมาจาก2009 Putnam B1ซึ่งเป็นปัญหาในการแข่งขันคณิตศาสตร์ระดับปริญญาตรี ปัญหาดังต่อไปนี้:

แสดงให้เห็นว่าทุกจำนวนตรรกยะที่เป็นบวกสามารถเขียนได้เป็นผลหารของผลคูณของแฟกทอเรียลของช่วง (ไม่จำเป็นต้องชัดเจน) ตัวอย่างเช่น,

$ \ frac {10} 9 = \ frac {2! \ cdot 5!} {3! \ cdot 3! \ cdot 3!}. $

ท้าทาย

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

หมายเหตุ

  • อาจไม่มีช่วงเวลาที่มีทั้งในรายการแรกและในรายการที่สอง อย่างไรก็ตามนายกอาจปรากฏหลายครั้งตามที่ปรารถนาในรายการใดรายการหนึ่ง
  • อินพุตสามารถสันนิษฐานได้ว่าแต่ละค่า (ไม่ จำกัด ) ระหว่าง 1 ถึง 65535 อย่างไรก็ตามไม่สามารถสรุปได้ว่าแฟกทอเรียลของตัวเลขที่คุณจะต้องใช้ในการส่งออกจะอยู่ในช่วงนี้

ตัวอย่างอินพุตและเอาต์พุต

นี่คือตัวอย่างของอินพุตและเอาต์พุตทางกฎหมาย

input=>output
10,9 => [2,5],[3,3,3]
2,1 => [2],[]
3,1 => [3],[2]
1,5 => [2,3,2],[5]     (elements of a list may be in any order)
3,2 => [3],[2,2]
6,1 => [3],[]

อินพุต (2,2), (0,3), (3,0), (3,6) และ (1,65536) เป็นอินพุตที่ผิดกฎหมาย (เช่นโปรแกรมของคุณไม่จำเป็นต้องทำงานในลักษณะเฉพาะใด ๆ กับพวกเขา ) นี่คือตัวอย่างของผลลัพธ์ที่ผิดกฎหมาย:

1,2 => [2],[2,2] (2 is in both returned lists)
5,2 => [5],[2,4] (4 is not prime)
2,1 => [2],[1] (1 is not prime either)
3,2 => [3],[2] (3!/2! = 3, not 3/2)

เกณฑ์การให้คะแนน

นี่คือดังนั้นคะแนนต่ำสุดเป็นไบต์ชนะ!


จำเป็นต้องให้เหตุผลที่มีเหตุผลลดลงน้อยที่สุดในกรณีที่มีคำตอบหลายวิธีหรือไม่? ตัวอย่าง10/9= [2*5]/[3*3]= [(2!/1!) * (5!/4!)] / [(3!/2!) * (3!/2!)]= =[2! * 5! * 2! * 2!] / [3! * 3! * 1! * 4!] (2! * 2! * 2! *5!) / (3! * 3! * 4!)
Digital Trauma

@ DigitalTrauma No; อย่างไรก็ตาม 4 ไม่ใช่เฉพาะดังนั้นอันที่สองจะไม่ถูกต้อง ฉันเชื่อ (และสามารถเขียนหลักฐานในคำถามหากคุณต้องการ) ว่าการเป็นตัวแทนใด ๆ ที่ไม่ซ้ำกัน
Carl Schildkraut

มันจะถูกใช้การป้อนข้อมูลเป็นเศษ10/9มากกว่าคู่ของตัวเลข10และ9?
Misha Lavrov

@MishaLavrov แน่นอน ฉันจะแก้ไขคำถามเพื่อสะท้อนว่า
Carl Schildkraut

@CarlSchildkraut ขอบคุณ - ใช่ที่ช่วย - ฉันคิดว่าฉันขาดอะไร
Digital Trauma

คำตอบ:


5

05AB1E , 54 53 48 46 40 35 33 32 28 ไบต์

[D¿÷Z#DÓ€gZD<ØŠQ*DˆR!*]¯øεʒĀ

ลองออนไลน์! แก้ไข: บันทึก 2 ไบต์ด้วย @ ASCII เท่านั้น บันทึกแล้ว1 2 3 4 ไบต์ขอบคุณ @Emigna (ฉันต้องการประหยัดอีกหนึ่งและฉันเหลือครึ่งไบต์ของฉัน!) คำอธิบาย:

[       Begin an infinite loop
D¿÷     Reduce to lowest terms
Z#      Exit the loop if the (largest) value is 1
DÓ€g    Find the index of the largest prime factor of each value
Z       Take the maximum
D<ØŠ    Convert index back to prime and save for later
Q       Convert to an pair of which value had the largest prime factor
*       Convert to an pair with that prime factor and zero
Dˆ      Save the pair in the global array for later
R!*     Multiply the other input value by the factorial of the prime
]       End of infinite loop
¯ø      Collect all the saved primes
εʒĀ     Forget all the saved 0s

ฉันรักสคริปต์ "อารมณ์" -¦D
RedClover



5

Mathematica, 175 177 169 154 108 ไบต์

Join@@@Table[x[[1]],{s,{1,-1}},{x,r@#},x[[2]]s]&@*(If[#==1,1,{p,e}=Last@(r=FactorInteger)@#;p^e#0[p!^-e#]]&)

ลองออนไลน์!

มันทำงานอย่างไร

นี่คือองค์ประกอบของสองฟังก์ชั่น ครั้งแรกซึ่ง ungolfs ไป

If[# == 1,
  1,
  {p,e} = Last[FactorInteger[#]];
  p^e * #0[p!^-e * #]
]&

เป็นฟังก์ชันแบบเรียกซ้ำสำหรับการคำนวณการแยกตัวประกอบที่ต้องการ โดยเฉพาะเมื่อได้รับข้อมูลที่มีเหตุผลxเราจะคำนวณจำนวนเฉพาะที่มีแฟคทอเรียลควรเป็นตัวเศษและส่วนและคืนเศษส่วนด้วยจำนวนเฉพาะทั้งหมดที่คูณด้วยกัน (ตัวอย่างเช่นในอินพุต10/9 = 2!*5!/(3!*3!*3!)เราจะส่งคืน10/27 = 2*5/(3*3*3))

เราทำสิ่งนี้โดยการจัดการกับปัจจัยสำคัญที่ใหญ่ที่สุดในทุกขั้นตอน: ถ้า p eเกิดขึ้นในการแยกตัวประกอบของ x เราจะทำให้แน่ใจว่า p! eเกิดขึ้นในแฟคตอเรียลแฟคเตอไรเซชันและชดเชยด้วย x หารด้วย p! e .

(ก่อนหน้านี้ฉันมีกลยุทธ์ที่ฉลาดกว่าที่จะหลีกเลี่ยงจำนวนมากโดยดูที่หมายเลขเฉพาะก่อนหน้านี้ก่อนหน้านี้ แต่ Mathematica สามารถจัดการตัวเลขที่มีขนาดใหญ่ถึง 65521 ได้อย่างง่ายดายดังนั้นจึงไม่มีประเด็นรุ่นเก่าที่คุณสามารถหาได้ในประวัติศาสตร์คือ เร็วกว่ามาก: ในคอมพิวเตอร์ของฉันใช้เวลา 0.05 วินาทีสำหรับอินพุตที่รุ่นนี้จัดการได้ใน 1.6 วินาที)

ฟังก์ชันที่สองเปลี่ยนเอาท์พุตของฟังก์ชันแรกให้เป็นรายการของช่วงเวลา

Join @@@ 
  Table[x[[1]],
    {s,{1,-1}},
    {x,FactorInteger[#]},
    x[[2]]*s
  ]&

สำหรับs=1(พลังบวก) และs=-1(พลังลบ) และสำหรับแต่ละเทอม{prime,exponent}ในการแยกตัวประกอบr@#เราจะทำซ้ำจำนวนเฉพาะprime exponent*sหลายครั้ง

รุ่นที่ไม่ใช่รุ่นที่มี109 62 ไบต์

If[#==1,∇1=1,{p,e}=Last@FactorInteger@#;(∇p)^e#0[p!^-e#]]&

เหมือนข้างบน แต่แทนที่จะให้เอาต์พุตเป็นรายการให้เอาต์พุตเป็นนิพจน์โดยใช้โอเปอเรเตอร์ ((เพราะไม่มีความหมายในตัว) เป็นสแตนเลสสำหรับแฟคทอเรียล ดังนั้นการป้อนข้อมูลของ10/9จะช่วยให้การส่งออกของเพื่อเป็นตัวแทนของ(∇2*∇5)/(∇3)^3(2!*5!)/(3!)^3

สิ่งนี้สั้นกว่าเพราะเราข้ามส่วนที่สองของฟังก์ชั่น


+2 ไบต์: การมอบหมายf=Firstจะต้องทำในสถานที่ที่เหมาะสมเพื่อป้องกันไม่ให้ Mathematica อารมณ์เสีย

-8 ไบต์: แก้ไขข้อผิดพลาดสำหรับผลลัพธ์จำนวนเต็มซึ่งจริง ๆ แล้วทำให้รหัสสั้นลง

-15 ไบต์: FactorIntegerส่งคืนเอาต์พุตที่เรียงลำดับซึ่งเราสามารถใช้ประโยชน์ได้

-46 ไบต์: เราไม่จำเป็นต้องฉลาดจริง ๆ


2

Python 2, 220 202 195 183 bytes

g=lambda a,b:a and g(b%a,a)or b;n,d=input();m=c=()
while n+d>2:
 t=n*d;f=p=2
 while t>p:
	if t%p:p+=1;f*=p
	else:t/=p
 if n%p:c+=p,;n*=f
 else:m+=p,;d*=f
 t=g(n,d);n/=t;d/=t
print m,c

ลองออนไลน์! แก้ไข: บันทึกแล้ว18 25 ไบต์ขอบคุณ @ @ Mr.Xcoder บันทึก 12 ไบต์ด้วย @JonathanFrech



คุณสามารถย่อให้สั้นลงได้อีกใน Python 2 เนื่องจากคุณสามารถแทนที่ช่องว่างหลาย ๆ อันด้วยแท็บในการเยื้อง
Mr. Xcoder

189 ไบต์
Jonathan Frech

183 ไบต์
Jonathan Frech
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.