Частичные факторизации натурального числа


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 факторизации для этих чисел соответственно, и я не уверен почему.
Sherlock9

@ 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.
Андерс Касеорг

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') предоставление 16на stdin. Убедитесь, что вы используете текущую версию Pyth; неявный Qбыл добавлен в марте. Я не могу представить, как вы можете получить деление на ноль, хотя.
Андерс Касеорг

Arrrrgh. Я использовал "вместо ', а bash расширял что- !%то еще.
Питер Тейлор

6

Python , 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)]

Ungolfed:

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 байт

Этот ответ основан на ответе Питера Андерса Касерга . Этот код работает только для версий после 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]]}

Ungolfed:

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 были введены стабильные лямбды . Я отредактирую ответ, чтобы показать требуемый номер версии.
Sherlock9

Хорошо спасибо. Мне все еще интересно 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.