Скільки способів записати N як добуток М цілих чисел?


12

Давши ціле число N , порахуйте, скільки способів воно може бути виражене як добуток M цілих чисел> 1.

Вхід просто N і M , а вихід - загальна кількість різних цілих груп. Значить, ви можете використовувати ціле число не один раз, але кожна група повинна бути розрізненою ( 3 x 2 x 2не враховуватиметься, якщо 2 x 2 x 3вона присутня).

Обмеження

1 < N <2 31
1 < М <30

Приклади

Введення 30 2дає вихід 3, оскільки його можна виразити 3 способами:

2 x 15
3 x 10
5 x 6

Введення 16 3дає результат 1, оскільки існує лише одна окрема група:

2 x 2 x 4

Вхід 2310 4дає вихід 10:

5 x 6 x 7 x 11
3 x 7 x 10 x 11
3 x 5 x 11 x 14
3 x 5 x 7 x 22
2 x 7 x 11 x 15
2 x 5 x 11 x 21
2 x 5 x 7 x 33
2 x 3 x 11 x 35
2 x 3 x 7 x 55
2 x 3 x 5 x 77

Введення 15 4дає вихід 0, оскільки це неможливо зробити.

Правила

Застосовуються стандартні лазівки для гольфу, поряд зі стандартними визначеннями для введення / виводу. Відповіді можуть бути функцією або повною програмою. Вбудовані функції для факторизації та / або розділення заборонені, але інші добре. Код рахується в байтах.


Що ви маєте на увазі під розділенням?
Оптимізатор

@Optimizer Групування списку в підписи, що не збігаються. У деяких мовах це вбудовано, наприклад, Mathematica .
Геобіт

Чи існує обмеження часу? Особливо наївний алгоритм може зайняти століття для великого значення М. Прості речі, такі як зауваження, можуть бути лише на один фактор, більший за sqrt (N).
Річка рівня Св.

1
@steveverrill Враховуючи верхню межу N , має бути лише 30 (простих) факторів максимум, що значно прискорює роботу. Однак сміливо проявляйте наївність. Якщо ваш алгоритм, ймовірно, не дасть відповіді протягом декількох годин, добре пояснене підтвердження концепції може допомогти виборцям прийняти рішення.
Геобіт

вбудований, в якому ви можете робити декартовий продукт із двох списків?
Оптимізатор

Відповіді:


5

Pyth - 24 23 22 21 байт

Не складне рішення. Буде більше гольфу. Просто бере декартовий продукт списків і фільтрів. Та ж стратегія, що і @optimizer (я здогадуюсь через його коментар, насправді не розшифрував цей CJam) Завдяки @FryAmTheEggman за 2 байти та хитрість з М.

Ml{m`Sdfqu*GHT1G^r2GH

Визначає функцію gз args GтаH

M                    function definition of g with args G and H
 l                   length of
  {                  set (eliminates duplicates)
   m                 map
    `Sd              repr of sorted factors so can run set (on bash escape ` as \`)
    f                filter
     q      G        equals first arg
      u*GHT1         reduce by multiplication
     ^     H         cartesian product by repeat second arg
       r2G           range 2 to first arg

Працював над усіма тестовими аргументами, окрім останнього, надто повільно, але не було визначено обмеження в часі.


Введення в цьому форматі добре.
Геобіт

1
Підказка Pyth Golf: якщо ви отримуєте 2 аргументи, зазвичай використовувати коротше, Mяке визначає функцію g2 аргументів, Gі H. Це те , що я отримую за це: Ml{msdfqu*GHT1G^r2GH. Завжди приємно бачити іншого користувача Pyth :)
FryAmTheEggman

@FryAmTheEggman оновив подяку за пораду.
Мальтісен

1
Це, здається, дає неправильну відповідь на вхід 72 3, який повертає 5, але насправді є 6 відповідей,(2, 2, 18), (2, 3, 12), (2, 4, 9), (2, 6, 6), (3, 3, 8)
isaacg

1
@isaacg о добре, я поверну його до моєї версії 21 char. Я не думав, що підсумовування буде спрацьовувати, але здавалося, що я повернусь до перевидання. Дякую за улов.
Малтісен

9

Пітон 3, 59

f=lambda N,M,i=2:i<=N and f(N/i,M-1,i)+f(N,M,i+1)or-~M==N<2

Ми підраховуємо потенційних дільників i. З додатковим аргументом iяк найнижчим дозволеним дільником, основне рекурсивне відношення

f(N,M,i)=f(N/i,M-1,i)+f(N,M,i+1)

Для кожного iми або вирішимо включити його (можливо, як повтор), і в цьому випадку ділимо потрібний продукт Nна iдекремент M. Якщо цього не зробимо, ми збільшимо iна 1, але тільки якщо i<N, оскільки немає використання перевіряючих дільників більше, ніж N.

Коли мінімальний дільник iперевищує N, потенційних ділителів більше немає. Отже, ми перевіряємо, чи досягли ми успіху, побачивши, якщо M==0 and N==1, або, що еквівалентно, M+1==N==1або M+1==N<2, з тих пір, коли M+1==Nвзаємне значення гарантовано буде додатним цілим числом (завдяки FryAmTheEggman за цю оптимізацію).

Цей код спричинить переповнення стека Nприблизно на 1000 у більшості систем, але ви можете запустити його в Stackless Python, щоб уникнути цього. Більше того, він надзвичайно повільний через експоненціальне рекурсивне розгалуження.


Я думаю, ви можете використовувати-~M==N<2
FryAmTheEggman

@FryAmTheEggman Я думав, що це дасть помилкові позитиви, але справді це працює, завдяки спільним обмеженням щодо Mта N. Дякую!
xnor

4

Рубі, 67

f=->n,m,s=2,r=0{m<2?1:s.upto(n**0.5){|d|n%d<1&&r+=f[n/d,m-1,d]}&&r}

Насправді досить ефективно для рекурсивного визначення. Для кожної пари дільниць [d,q]n, dбудучи меншою, підсумовуємо результат f[q,m-1]. Складна частина полягає в тому, що у внутрішніх дзвінках ми обмежуємо фактори величиною d або дорівнює d, щоб ми не закінчилися подвійним підрахунком.

1.9.3-p327 :002 > f[30,2]
 => 3 
1.9.3-p327 :003 > f[2310,4]
 => 10 
1.9.3-p327 :004 > f[15,4]
 => 0 
1.9.3-p327 :005 > f[9,2]
 => 1 

2

CJam, 48 байт

Це може бути набагато коротше, але я додав певні чеки, щоб він працював на пристойну кількість Mонлайн-компілятора.

q~\:N),2>{N\%!},a*{_,2/)<m*{(+$}%}*{1a+:*N=},_&,

Спробуйте його онлайн тут


Це баггі. Спробуйте ввести 2 1. Очікуваний вихід: 1. Фактичний вихід: 0.
Пітер Тейлор

@PeterTaylor Зітхання. Виправлено.
Оптимізатор

2

T-SQL 456 373

Я впевнений, що це зламається, коли входи навіть близькі до великих.

Завдяки @MickyT за те, що він допомагає зберегти багато символів за допомогою CONCAT та SELECTING замість кількох SET.

CREATE PROC Q(@N INT,@M INT)AS
DECLARE @ INT=2,@C VARCHAR(MAX)='SELECT COUNT(*)FROM # A1',@D VARCHAR(MAX)=' WHERE A1.A',@E VARCHAR(MAX)=''CREATE TABLE #(A INT)WHILE @<@N
BEGIN
INSERT INTO # VALUES(@)SET @+=1
END
SET @=1
WHILE @<@M
BEGIN
SELECT @+=1,@C+=CONCAT(',# A',@),@D+=CONCAT('*A',@,'.A'),@E+=CONCAT(' AND A',@-1,'.A<=A',@,'.A')END
SET @C+=CONCAT(@D,'=',@N,@E)EXEC(@C)

Я хотів би підтримати це, але не можу знайти простий спосіб перевірити це. Будь-які ідеї? Сторонне підтвердження того, що він працює, теж добре.
Геобіц

Я отримую пару помилок конверсії, я запускаю його (2012). Вони, мабуть, виходять з цих тверджень SET @C+=',# A'+@іSET @D+='*A'+@+'.A'SET @E+=' AND A'+(@-1)+'.A<=A'+@+'.A'
MickyT

Вам також потрібно буде виправити SET @C+=@D+'=@N'+@E+' SELECT @'. Значення @Nзнаходиться всередині лапок, що робить його поза рамками при виконанні @C. Також я думаю, ви закінчите підрахунок дублікатів
MickyT

Зараз я перевірив це на 2012 році. Це повинно працювати.
позначки

2
Зараз добре працює :) Пара місця, де можна поголити деяких персонажів. Спробуйте використовувати CONCATдля створення своїх рядків. Тоді ви можете кинути CONVERTs. Спробуйте SELECT @+=1,@C+=CONCAT(...),@D+=CONCAT(...),@E+=CONCAT(...)в своєму WHILEциклі. Якщо вам врятують розумну кількість
MickyT
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.