Часткові факторизації натурального числа


23

Колекція додатних цілих чисел d_1 d_2 ... d_k- це факторизація натурального числа, nякщо

d_1 * d_2 * ... * d_k = n

Кожне додатне ціле число має унікальну основну факторизацію , але в цілому вони також мають фактори, в яких деякі складові є складовими. Напр

12 = 6 * 2 = 4 * 3 = 3 * 2 * 2

Напишіть програму, функцію, дієслово чи подібне, яке приймає за введення одне додатне ціле число і повертає або друкує повний перелік його різних факторів. Факторизації можуть бути вироблені в будь-якому порядку, і їх умови можуть бути в будь-якому порядку, але жодна з двох не повинна бути перестановкою один одного. Факторизації можуть не включати 1два винятки: для введення nви можете дати факторизацію n*1замість n; а для введення 1ви можете дати факторизацію 1замість порожнього списку.

Можна припустити, що вхід буде знаходитися в діапазоні підписаного 32-бітного цілого числа. Якщо вихідний рядок є рядком, слід чітко розмежовувати розмежування чисел у межах факторизації та розмежування факторизацій, але це не обов'язково (наприклад) для приєднання факторів до *.

Ваш код повинен мати можливість обробляти будь-який дійсний вхід протягом 10 хвилин на розумній настільній машині.

Приклади

1                  [[]]
                or [[1]]
                or [[1 1]]

7                  [[7]]
                or [[7 1]]
                or [[1 7]]

12                 [[12] [6 2] [4 3] [2 3 2]]
                or variants

16                 [[2 2 2 2] [2 2 4] [2 8] [4 4] [16]]
                or variants

901800900          a list of 198091 factorisations

1338557220         a list of 246218 factorisations

Чи можете ви розмістити список факторизацій 901800900та 1338557220десь там, де ми можемо їх перевірити? Мій код дає мені 2048 та 1024 факторизації для цих чисел відповідно, і я не знаю чому.
Шерлок9

@ Sherlock9, зробить це, коли я повернусь додому. Що я можу зробити з генератором в Інтернеті - це дати дійсний вихід на 5336100 .
Пітер Тейлор

3
Це нагадує мені завдання ProjectEuler (на жаль, я не пам'ятаю, який). Але там вам довелося порахувати кількість факторизацій, а не перераховувати їх.
flawr

Пов'язані OEIS: A001055
Sherlock9

Відповіді:


12

Haskell, 56 байт

_!1=[[]]
i!n=[j:f|j<-[i..n],mod n j<1,f<-j!div n j]
(2!)

(2!)(1338557220::Int)друкується за п'ять хвилин на моєму ноутбуці, коли компілюється з ghc -O3.

Haskell, 62 байти, але набагато швидше

i!n|i*i>n=[[n]]|0<1=[i:f|mod n i<1,f<-i!div n i]++(i+1)!n
(2!)

(2!)(1338557220::Int)друкується через чверть секунди на моєму ноутбуці, коли компілюється з ghc -O3.


Як це перевірити? ghcдає мені Parse error: naked expression at top levelі ghciдарує меніparse error on input `='
Пітер Тейлор

@PeterTaylor Замініть функцію (2!)програмою main = print ((2!) (1338557220::Int)), компілюйте ghc -O3 factor.hsі запускайте ./factor.
Anders Kaseorg

7

Pyth, 29 байт

Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2

M                                def g(G, H):
                   @H2             square root of H
                  S                1-indexed range up to floor
                 >    tG           all but first G − 1 elements
            f                      filter for elements T such that:
              %HT                    H mod T
             !                       is false (0)
   m                               map for elements d:
       gd/Hd                         g(d, H/d)
    +Ld                              prepend d to each element
  a                     ]]H        append [[H]]
 s                                 concatenate
                           g2Q   print g(2, input)

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

Працює за двадцять секунд для 1338557220мого ноутбука.


@PeterTaylor Звичайний спосіб: pyth factor.pyth(або pyth -c 'Msam+Ldgd/Hdf!%HT>S@H2tG]]Hg2'), надаючи 16stdin. Переконайтеся, що ви використовуєте поточну версію Pyth; неявна Qбула додана в березні. Я не уявляю, як ти можеш отримати ділення на нуль.
Anders Kaseorg

Arrrrgh. Я використовував "замість ', а bash розширював !%щось інше.
Пітер Тейлор

6

Пітона , 252 313 312 311 145 141 137 135 103 84 83 байт

Це багато в чому ґрунтується на відповіді Піра Андерса Касеорга . Будь-які пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

Редагувати: 19 байт у гольф завдяки Деннісу Виправлено помилку в коді та додано посилання TIO.

g=lambda n,m=2:[[n]]+[j+[d]for d in range(m,int(n**.5)+1)if n%d<1for j in g(n/d,d)]

Безголівки:

def g(n, m=2):
    a = [[n]]
    s = int(n**.5) + 1
    for d in range(m, s):
        if n%d == 0:
            for j in g(n/d, d):
                a.append([d]+j)
    return a

1
**.5позбавляється від імпорту.
Денніс

4

JavaScript (ES6), 83 байти

f=(n,a=[],m=2,i=m)=>{for(;i*i<=n;i++)n%i<1&&f(n/i,[...a,i],i);console.log(...a,n)}

Лише запозичений квадратний кореневий трюк @ AndersKaseorg, оскільки він в цілому врятував мені байти. Друкується 1для введення даних 1, інакше не друкується 1s.


1

Ruby 1.9+, 87 89 87 байт

Ця відповідь ґрунтується на Pyth відповіді Андерса Касеорга . Цей код працює лише для версій після Ruby 1.9, як стійкі лямбда-> були представлені лише в 1.9. Будь-які пропозиції щодо гольфу вітаються.

g=->n,m=2{(m..Math.sqrt(n)).select{|i|n%i<1}.flat_map{|d|g[n/d,d].map{|j|[d]+j}}+[[n]]}

Безголівки:

def g(n, m=2)
  a = [[n]]
  s = (m..Math.sqrt(n))
  t = s.select{|i|n%i<1}
  t.each do |d|
    g[n/d,d].each do |j|
      a.push([d]+j)
    end
  end
  return a
end

Для цього потрібна певна версія Ruby? З 1.8.7 я отримую скаргу на g[n/d,d]:wrong number of arguments (0 for 1)
Пітер Тейлор

Очевидно стійкі лямбда ->були представлені в Ruby 1.9. Я відредагую відповідь, щоб показати необхідний номер версії.
Шерлок9

Добре, дякую. Мені все ще цікаво g[n/d,d]. g(n/d,d)є більш сумісним назад.
Пітер Тейлор

1
Ах, f[n]потрібно називати стійкі лямбди і рум’яні лямбда взагалі. f(n)і f nдзвінки вимагають defі end. Більше інформації тут і тут
Sherlock9

1

J, 52 байти

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:

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

Спробуйте в Інтернеті!(Але намагайтеся, щоб вхідні значення були невеликими).

На моєму робочому столі встановлені таймінги

   f =: [:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:
   timex 'r =: f 1338557220'
3.14172
   # r
246218
   timex 'r =: f 901800900'
16.3849
   # r
198091

Пояснення

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

[:~.q:<@/:~@(*//.)"$~#@q:_&(;@]<@(,~"{~0,#\@~.)"1)}:  Input: integer n
                                                  }:  Curtail, forms an empty array
                       q:                             Prime factorization
                     #@                               Length, C = count prime factors
                         _&(                     )    Repeat that many times on x = []
                                 (            )"1       For each row
                                            ~.            Unique
                                         #\@              Enumerate starting at 1
                                       0,                 Prepend 0
                                  ,~"{~                   Append each of those to a
                                                          copy of the row
                               <@                         Box it
                            ;&]                         Set x as the raze of those boxes
                                                      These are now the restricted growth
                                                      strings of order C
    q:                                                Prime factorization
            (    )"$~                                 For each RGS
               /.                                       Partition it
             */                                         Get the product of each block
        /:~@                                            Sort it
      <@                                                Box it
[:~.                                                  Deduplicate
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.