Написання раціональних чисел як відношення факторіалів простих чисел


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!).
Цифрова травма

@DigitalTrauma Ні; однак 4 не є простим, тому другий не був би дійсним. Я вважаю (і можу написати доказ у запитанні, якщо ви хочете), що будь-яке представлення є унікальним.
Карл Шільдкраут

Чи добре брати введення як дріб, 10/9а не пару чисел 10і 9?
Міша Лавров

@MishaLavrov Звичайно. Я відредагую це питання, щоб це відобразити.
Карл Шильдкраут

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

Спробуйте в Інтернеті!

Як це працює

Це склад двох функцій. Перший, який унгольфи до

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! е .

(Раніше у мене була більш розумна стратегія, яка дозволяє уникати великих чисел, дивлячись на попереднє просте число до p, але 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 байт

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, оскільки ви можете замінити кілька пробілів вкладками в відступі
Містер Xcoder


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.