Viết số hữu tỉ theo tỷ lệ của các yếu tố của số nguyên tố


19

Lưu ý: thử thách này đã được đăng trên hộp cát .

Giới thiệu

Thử thách này được lấy cảm hứng từ năm 2009 Putnam B1 , một vấn đề trong một cuộc thi toán học đại học. Vấn đề như sau:

Cho thấy rằng mọi số hữu tỷ dương có thể được viết dưới dạng thương số của các sản phẩm của các yếu tố (không nhất thiết phải khác biệt). Ví dụ,

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

Thử thách

Thử thách của bạn là lấy một cặp số nguyên dương tương đối nguyên tố, đại diện cho tử số và mẫu số của một số hữu tỷ dương (hoặc chỉ chính số hữu tỷ) làm đầu vào và xuất ra hai danh sách (hoặc mảng, v.v.) của các số nguyên tố sao cho số hữu tỷ được nhập bằng với tỷ lệ của sản phẩm của các giai thừa của các số nguyên tố trong danh sách đầu tiên với sản phẩm của các yếu tố của các số nguyên tố trong danh sách thứ hai.

Ghi chú

  • Có thể không có bất kỳ số nguyên tố nào chứa cả trong danh sách đầu tiên và trong danh sách thứ hai; tuy nhiên, một số nguyên tố có thể xuất hiện nhiều lần như một mong muốn trong một trong hai danh sách.
  • Các đầu vào có thể được giả định cho mỗi được (không giới hạn) trong khoảng từ 1 đến 65535; tuy nhiên, không thể giả định rằng các giai thừa của các số bạn sẽ cần xuất sẽ nằm trong phạm vi này.

Ví dụ đầu vào và đầu ra

Dưới đây là ví dụ về đầu vào và đầu ra hợp pháp.

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],[]

Các đầu vào (2,2), (0,3), (3.0), (3,6) và (1.65536) là các đầu vào bất hợp pháp (tức là chương trình của bạn không cần phải hành xử theo bất kỳ cách cụ thể nào đối với chúng ). Dưới đây là một số ví dụ về đầu ra bất hợp pháp:

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)

Chấm điểm

Đây là , vì vậy điểm số thấp nhất tính bằng byte sẽ thắng!


Có một số loại giảm thiểu hợp lý cần phải được đưa ra trong trường hợp có nhiều cách để thể hiện câu trả lời? Ví dụ 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!).
Chấn thương kỹ thuật số

@DigitalTrauma Không; tuy nhiên, 4 không phải là số nguyên tố, vì vậy cái thứ hai sẽ không hợp lệ. Tôi tin rằng (và có thể viết ra một bằng chứng trong câu hỏi nếu bạn muốn) rằng bất kỳ đại diện nào là duy nhất.
Carl Schildkraut

Có thể lấy đầu vào là phân số 10/9chứ không phải là một cặp số 109?
Misha Lavrov

@MishaLavrov Chắc chắn rồi. Tôi sẽ chỉnh sửa câu hỏi để phản ánh điều đó.
Carl Schildkraut

@CarlSchildkraut Cảm ơn - vâng điều đó có ích - Tôi nghĩ rằng tôi đã bỏ lỡ điều gì đó
Chấn thương kỹ thuật số

Câu trả lời:


5

05AB1E , 54 53 48 46 40 35 33 32 28 byte

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

Hãy thử trực tuyến! Chỉnh sửa: Đã lưu 2 byte chỉ nhờ @ ASCII. Đã lưu 1 2 3 4 byte nhờ @Emigna. (Tôi chỉ cần lưu thêm một lần nữa và tôi giảm xuống còn một nửa số byte ban đầu của mình!) Giải thích:

[       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

Tôi yêu các kịch bản "tình cảm" -¦D
RedClover



5

Toán học, 175 177 169 154 108 byte

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

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

Làm thế nào nó hoạt động

Đây là thành phần của hai chức năng. Đầu tiên, mà ungolf

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

là một hàm đệ quy để thực sự tính toán hệ số mong muốn. Cụ thể, với một đầu vào hợp lý x, chúng tôi tính các số nguyên tố mà các giai thừa của nó phải nằm trong tử số và mẫu số, và trả về phân số với tất cả các số nguyên tố đó được nhân với nhau. (Ví dụ: về đầu vào 10/9 = 2!*5!/(3!*3!*3!), chúng tôi trả lại 10/27 = 2*5/(3*3*3).)

Chúng tôi thực hiện điều này bằng cách xử lý hệ số nguyên tố lớn nhất ở mỗi bước: nếu p e xảy ra trong hệ số của x, chúng tôi đảm bảo p! e xảy ra trong thừa số nhân tử và lặp lại trên x chia cho p! e .

(Trước đó, tôi đã có một chiến lược thông minh hơn để tránh các số lớn bằng cách nhìn vào số nguyên tố trước đó trước p, nhưng Mathicala có thể xử lý các số lớn như 65521! Vì vậy, không có điểm nào. Phiên bản cũ bạn có thể tìm thấy trong lịch sử là nhanh hơn nhiều: trên máy tính của tôi, phải mất 0,05 giây cho các đầu vào mà phiên bản này xử lý trong 1,6 giây.)

Hàm thứ hai biến đầu ra của hàm thứ nhất thành danh sách các số nguyên tố.

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

Đối với s=1(quyền hạn tích cực) và s=-1(quyền hạn tiêu cực) và đối với mỗi thuật ngữ {prime,exponent}trong hệ số hóa r@#, chúng tôi lặp lại số nguyên tố prime exponent*snhiều lần.

Phiên bản không lọc với 109 62 byte

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

Tương tự như trên, nhưng thay vì đưa ra đầu ra dưới dạng một danh sách, đưa ra đầu ra dưới dạng một biểu thức, sử dụng toán tử (vì nó không có nghĩa tích hợp) như là một thay thế cho các giai thừa. Do đó, một đầu vào 10/9cung cấp một đầu ra của (∇2*∇5)/(∇3)^3đại diện (2!*5!)/(3!)^3.

Cái này ngắn hơn vì chúng ta bỏ qua phần thứ hai của hàm.


+2 byte: việc gán f=Firstphải được thực hiện ở đúng nơi để Mathicala không bị khó chịu.

-8 byte: đã sửa một lỗi cho đầu ra số nguyên, điều này thực sự làm cho mã ngắn hơn.

-15 byte: FactorIntegertrả về đầu ra được sắp xếp, mà chúng ta có thể tận dụng.

-46 byte: chúng ta không thực sự cần phải thông minh.


2

Python 2, 220 202 195 183 byte

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

Hãy thử trực tuyến! Chỉnh sửa: Đã lưu 18 25 byte nhờ @ Mr.Xcoder. Đã lưu 12 byte nhờ @JonathanFrech.



Bạn có thể rút ngắn nó nhiều hơn trong Python 2, vì bạn có thể thay thế nhiều khoảng trắng bằng các tab trong vết lõm
Ông Xcoder


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.