Найменше ціле число як добуток заданих факторів


17

Останнім часом було багато викликів, пов'язаних з основним / основним фактором, тому я подумав, що може бути цікаво піти іншим шляхом.

Подано:

  • додатне ціле число n, і
  • не порожній список натуральних чисел f

написати повну програму або функцію , щоб знайти найменше ціле число iтаке , що i >= nі iє продуктом невід'ємних, цілих ступенів елементів f.

Приклади:

  • Припустимо n = 11, f = [2, 3, 5].

    Перші кілька продуктів:

    1   = 2^0 * 3^0 * 5^0
    2   = 2^1 * 3^0 * 5^0
    3   = 2^0 * 3^1 * 5^0
    5   = 2^0 * 3^0 * 5^1
    4   = 2^2 * 3^0 * 5^0
    6   = 2^1 * 3^1 * 5^0
    10  = 2^1 * 3^0 * 5^1
    9   = 2^0 * 3^2 * 5^0
    15  = 2^0 * 3^1 * 5^1
    25  = 2^0 * 3^0 * 5^2
    8   = 2^3 * 3^0 * 5^0
    12  = 2^2 * 3^1 * 5^0 => smallest greater than (or equal to) 11, so we output it.
    20  = 2^2 * 3^0 * 5^1
    18  = 2^1 * 3^2 * 5^0
    30  = 2^1 * 3^1 * 5^1
    50  = 2^1 * 3^0 * 5^2
    27  = 2^0 * 3^3 * 5^0
    45  = 2^0 * 3^2 * 5^1
    75  = 2^0 * 3^1 * 5^2
    125 = 2^0 * 3^0 * 5^3
    
  • Припустимо n=14, f=[9, 10, 7].

    Знову ж таки, перші кілька продуктів:

    1 = 7^0 * 9^0 * 10^0
    7 = 7^1 * 9^0 * 10^0
    9 = 7^0 * 9^1 * 10^0
    10 = 7^0 * 9^0 * 10^1
    49 = 7^2 * 9^0 * 10^0  => smallest greater than (or equal to) 14, so we output it.
    63 = 7^1 * 9^1 * 10^0
    70 = 7^1 * 9^0 * 10^1
    81 = 7^0 * 9^2 * 10^0
    90 = 7^0 * 9^1 * 10^1
    100 = 7^0 * 9^0 * 10^2
    

Тестові приклади:

n, f -> output
10, [2, 3, 5]              -> 10
17, [3, 7]                 -> 21
61, [3,5,2,7]              -> 63
23, [2]                    -> 32
23, [3]                    -> 27
23, [2, 3]                 -> 24
31, [3]                    -> 81
93, [2,2,3]                -> 96
91, [2,4,6]                -> 96
1,  [2,3,5,7,11,13,17,19]  -> 1
151, [20,9,11]             -> 180
11616, [23,32]             -> 12167
11616, [23,32,2,3]         -> 11664 = 2^4 * 3^6
5050, [3,6,10,15,21,28,36,45,55,66,78,91,105,120,136,153,171,190,210] -> 5103 = 3^6 * 7
12532159, [57, 34, 12, 21] -> 14183424 = 12^5 * 57

Правила

  • Ви можете припустити, що він fбуде містити принаймні один елемент, і що всі елементи елемента fбудуть більшими за 1.
  • Ви можете припустити, що fце сортується у порядку зменшення / збільшення, якщо ви хочете (але вкажіть).
  • Ви можете за бажанням взяти кількість елементів, fякщо хочете.
  • Вихід у вигляді рядка дозволений.
  • Це , тому найкоротша відповідь у байтах на кожній мові виграє!
  • Застосовуються правила вводу / виводу за замовчуванням, а стандартні лазівки заборонені.
  • Пояснення заохочуються.

Відповіді:


10

Лушпиння , 8 байт

ḟṠ€ȯmΠṖṘ

Надзвичайно повільно. Спробуйте в Інтернеті!

Пояснення

ḟṠ€ȯmΠṖṘ  Implicit inputs, say L=[3,4] and n=5.
ḟ         Find the lowest integer k≥n that satisfies:
       Ṙ   Replicate L by k: [3,3,3,3,3,4,4,4,4,4]
      Ṗ    Powerset: [[],[3],[4],..,[3,3,3,3,3,4,4,4,4,4]]
    mΠ     Product of each: [1,3,4,..,248832]
 Ṡ€ȯ       k is in this list.

7

Мова Вольфрама (Mathematica) , 68 65 62 61 байт

If[#^#2<=1,1~Max~-Log@#2,Min[#0[#,#2-1,##4],#0[#/#3,##2]#3]]&

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

Як це працює

Приймає введення як [n,k,f1,f2,f3,...,fk](наприклад, [11,3,2,3,5]): перше значення - ціль n, друге - кількість факторів, і всі наступні фриктори.

Інші виклики з теорії чисел останнім часом усі склалися для фантазійних вбудованих модулів (принаймні, вони використовувались FactorInteger), тому я подумав, що спробую щось, що використовує лише основні інструменти. Це рішення в основному говорить про те, що, щоб записати nяк добуток факторів, ми або використовуємо перший коефіцієнт f1(і повторюємо n/f1, потім множимо на f1), або не (і повторюємо в більш короткому списку факторів), а потім беремо хв.

Рекурсія закінчується, коли ціль менша за 1 або коли кількість факторів дорівнює 0, на що ми перевіряємо #^#2<=1відразу, а потім генеруємо 1 у першому випадку, а Infinityв другому з 1~Max~-Log@#2.

Функція дає цілу купу попереджень (але все ще працює), якщо ви не запускаєте її Quiet, оскільки вона врешті-решт повторюється у випадках, коли їх #3немає, що робить невикористану другу гілку Ifсумною.


-3 байти: прийняття кількості факторів як вхідних.

-3 байти завдяки @ngenisis: використання .

-1 байт, і двозначності немає : #^#2чек.


2
Дуже хороша! зберігає 3байти на -Log@0 (doesn't work on TIO, but works fine on desktop Mathematica). Also, Tr [1 ^ {##}] `- байт коротший за Length@{##}.
ngenisis

Я не зовсім впевнений, як мені здається використовувати оптимізацію TIO не подобається, але впевнений, додам це. І #2навіть коротше, ніж Tr[1^{##}]. :)
Міша Лавров

1
Я думаю, вам слід Quietввести основний код. Цей відповідь видає занадто багато неправильних повідомлень. Принаймні запитайте ОП, чи з ним все гаразд
J42161217

2
Схоже, те саме, що ігнорування STDERR було б іншою мовою, що є прийнятою практикою .
Міша Лавров

2
Проблема , як видається, помилка. Я спробую це виправити.
Денніс

6

Python 2 , 91 88 84 байт

f=lambda n,l:n<2or any(n%x<1and f(n/x,l)for x in l)
g=lambda n,l:n*f(n,l)or g(n+1,l)

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

Функція fрекурсивно перевіряє, чи nє продуктом повноважень елементів у l, gце лише обгортка для управління ітерацією



4

Желе , 13 байт

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ

Дьядічне посилання, що містить список, fзліва та число, nправоруч, яке дає число.

Спробуйте в Інтернеті! Голліфти неефективні - будуть ігноровані витрати на більш високіnта / або довшіf.

Як?

Ми знаємо, що повноваження окремих (строго позитивних) факторів ніколи не будуть перевищувати n-1
... тому давайте просто перевіримо всі можливі способи!

L⁹ṗ’⁸*P€ḟ⁹Ḷ¤Ṃ - Link: list, f; number, n
 ⁹            - chain's right argument, n
L             - length of f
  ṗ           - Cartesian power  ...e.g.: len(f)=2; n=3 -> [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
   ’          - decrement (vectorises)
    ⁸         - chain's left argument, f
     *        - exponentiate (vectorises) - that is [f1^a, f2^b, ...] for each [a, b, ...] in the list formed from the Cartesian power
      P€      - product for €ach - that is f1^a * f2^b * ... for each [a, b, ...] in the list formed from the Cartesian power
           ¤  - nilad followed by link(s) as a nilad:
         ⁹    -   chain's right argument, n
          Ḷ   -   lowered range -> [0,1,2,3,...,n-1]
        ḟ     - filter discard - that is remove values less than n
            Ṃ - minimum

2

Сітківка , 76 байт

\d+
$*
1+;
$&$&
{+`;(1+)(\1)*(?=;.*\b\1\b)
;1$#2$*1
}`(1+);11+;
1$1;1$1;
\G1

Спробуйте в Інтернеті! Посилання виключає найповільніші тестові випадки, але це все-таки трохи повільно, тому намагайтеся не забивати сервер @ Dennis.



2

Математика, 85 байт

Min@Select[Flatten[1##&@@(s^#)&/@Tuples[0~Range~⌈Log[Min[s=#],d=#2]⌉,#3]],#>=d&]&

Вхідні дані

[{список f}, n, кількість елементів f]
[{57, 34, 12, 21}, 12532159, 4]


{d,s}Min@Select[Flatten[1##&@@(s^#)&/@0~Range~9~Tuples~Tr[1^s]],#>=d&]
ngenisis

@ngenisis що таке символ, який не відображається? Чи можете ви зробити замість TIO посилання?
J42161217

Ніколи не думав побачити день, коли "Mathematica" і "TIO" використовувались в одній і тій же посаді: P
caird coinheringaahing

@Jenny_mathy Це U+F4A1, довге ім'я \[Function].
ngenisis

Використання 0~Range~9здається дуже консервативним. Чи g[{2,3,5},1001]справді слід пропуститись 1024та повернутися 1080? Це не особливо великий вклад.
Міша Лавров

2

Japt , 10 байт

_k e!øV}aU

Перевірте це в Інтернеті!

Не працює на останньому тестовому випадку через обмеження ітерації, призначене для того, щоб перекладач не працював назавжди (хоча тут не дуже допомогло, оскільки він заморозив мій браузер на годину ...)

Пояснення

_k e!øV}aU    Implicit: U = input integer, V = array of factors
_      }aU    Starting at U, find the next integer Z where
 k              the factors of Z
   e            are such that every factor
    !øV         is contained in V (e!øV -> eX{VøX}, where VøX means "V contains X").
              Implicit: output result of last expression



1

Математика, 73 байти

1±_=1>0;n_±f_:=Or@@(#∣n&&n/#±f&/@f);n_·f_:=NestWhile[#+1&,n,!#±f&]

За суті порт Rod Python «s відповідь . Визначає два двійкові оператори ±та ·. n±fповертає Trueif nє продуктом елементів fта Falseінакше. n·fдає найменше ціле число i. Якщо хтось може знайти спосіб усунення тесту на роздільність, я міг би зберегти 10 байт за допомогою кодування ISO 8859-1.

Пояснення

1±_=1>0;                         (* If the first argument is 1, ± gives True. *)
n_±f_:=Or@@(#∣n&&n/#±f&/@f);     (* Recursively defines ±. *)
                                 (* For each element of f, check to see if it divides n. *)
                                 (* For each element # that does, check if n/# is a product of elements of f. *)
n_·f_:=NestWhile[#+1&,n,!#±f&]   (* Starting with n, keep incrementing until we find an i that satisfies i±f. *)

1

R , 52 байти

function(n,f)min((y=(x=outer(f,0:n,"^"))%o%x)[y>=n])

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

Минуло 3 тижні, тому я подумав, що нарешті викладу власне рішення. Це підхід грубої сили.

Однак є вбудований:

R , 5 байт

nextn

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

З Документів R:

nextnповертає найменше ціле число, більше або дорівнює n, яке можна отримати як добуток потужностей значень, що містяться в factors. nextnпризначений для використання для пошуку підходящої довжини для нульового прокладки аргументу fftдо, щоб перетворення обчислювалося швидко. За замовчуванням factorsце забезпечує це.

Деякі тестування виявили помилку в реалізації, як показує посилання TIO вище.

nextn(91,c(2,6))повинен повернути 96, але повертає 128 замість цього. Це, очевидно, відбувається лише тоді, коли factorsне всі відносно просто між собою. Дійсно, код C, який лежить в основі, показує, що nextnжадібно намагається розділити кожного factorпо черзі, поки не 1буде досягнуто:

static Rboolean ok_n(int n, int *f, int nf)
{
    int i;
    for (i = 0; i < nf; i++) {
    while(n % f[i] == 0) {
        if ((n = n / f[i]) == 1)
        return TRUE;
    }
    }
    return n == 1;
}

static int nextn0(int n, int *f, int nf) { while(!ok_n(n, f, nf)) n++; return n; }

Це можна вирішити, приймаючи вклад у зменшенному порядку.


1

JavaScript (ES6), 53 50 байт

Збережено 3 байти завдяки @DanielIndie

Здійснює введення в синтаксис currying (n)(a).

n=>m=a=>(g=k=>k<n?a.map(x=>g(k*x)):k>m?0:m=k)(1)|m

Тестові справи

Як?

n => a => (                 // given n and a
  g = k =>                  // g = recursive function taking k
    k < n ?                 // if k is less than n:
      a.map(x => g(k * x))  //   recursive calls to g with x * k for each x in a
    :                       // else:
      k > m ?               //   if k is greater than m and m is not set to NaN:
        0                   //     ignore this result
      :                     //   else:
        m = k               //     update m to k
  )(                        // initial call to g with:
    1,                      //   k = 1
    m = +a                  //   m = either NaN or the single integer contained in a
  ) | m                     // return m

n => m = a => (g = k => k <n? a.map (x => g (k * x)): k> m? 0: m = k) (1) | mm = функція завжди створює помилку під час першого запуску, тож це в основному те саме, що ставити + a, зараз це 51 байт
DanielIndie

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