Постановка проблемы
Учитывая набор уникальных последовательных простых чисел (необязательно включая 2), генерируют произведения всех комбинаций первых степеней этих простых чисел - например, без повторов - а также 1. Например, учитывая набор {2, 3, 5, 7}, вы производите {1, 2, 3, 5, 6, 7, 10, 14, 15, 21, 30, 35, 42, 70, 105, 210}, потому что:
1 = 1
2 = 2
3 = 3
5 = 5
6 = 2 x 3
7 = 7
10 = 2 x 5
14 = 2 x 7
15 = 3 x 5
21 = 3 x 7
30 = 2 x 3 x 5
35 = 5 x 7
42 = 2 x 3 x 7
70 = 2 x 5 x 7
105 = 3 x 5 x 7
210 = 2 x 3 x 5 x 7
Обратите внимание, что если количество элементов вашего входного набора равно k, это даст вам 2 ^ k членов в вашем выходном наборе.
Правила / условия
- Вы можете использовать любой язык. Стремитесь к наименьшему количеству символов исходного кода.
- Ваше решение должно быть либо полной программой, либо полной функцией. Функция может быть анонимной (если ваш язык поддерживает анонимные функции).
- Ваше решение должно поддерживать продукты как минимум до 2 ^ 31. Не беспокойтесь об обнаружении или обработке целочисленного переполнения, если вам передают числа, чей продукт слишком велик для представления. Однако, пожалуйста, укажите пределы ваших расчетов.
- Вы можете принять список или набор и создать список или набор. Вы можете предположить, что вход отсортирован, но вы не обязаны производить отсортированный вывод.
Задний план
Когда или почему это полезно? Одним из мест, где это очень полезно, является создание таблицы множителей для параллельного состязания в алгоритме целочисленного факторинга, известном как факторизация квадратов, Там каждый нечетный множитель, который вы пробуете, уменьшает вероятность сбоя алгоритма (чтобы найти фактор) примерно на 50% на жестких полупростых числах. Таким образом, с набором порождающих простых чисел {3, 5, 7, 11}, который генерирует набор из 16 пробных множителей для параллельного состязания, алгоритм терпит неудачу примерно в 2 ^ –16 раз на жестких полуприцепах. Добавление 13 к списку простых чисел дает набор из 32 пробных множителей, снижая вероятность неудачи примерно до 2–32, что дает резкое улучшение результата без дополнительных вычислительных затрат (поскольку даже при увеличении вдвое большего числа множителей параллельно в среднем он все равно находит ответ в том же общем количестве шагов).
источник
1 0
bash --version
CJam, 13 байтов
Читает массив (например,
[2 3 5 7]
) из STDIN. Попробуйте онлайн.Анонимная функция будет иметь тот же счетчик байтов:
Пример запуска
Как это устроено
источник
Хаскелл, 22
решение является анонимной функцией:
пример использования:
Объяснение:
(:[1])
это функция, которая с указанным номеромx
возвращает список[x,1]
.mapM(:[1])
является функцией, которая предоставляет список чисел, отображает функцию(:[1])
над ними и возвращает все возможные способы выбора элемента из каждого списка. например,mapM(:[1]) $ [3,4]
сначала сопоставляет функцию для получения[[3,1] , [4,1]]
. тогда возможный выбор[3,4]
(выбор первого числа обоих),[3,1]
[1,4]
и[1,1]
поэтому он возвращается[[3,4],[3,1],[1,4],[1,1]]
.затем
map product
сопоставляет все варианты и возвращает их продукты, которые являются желаемым результатом.эта функция полиморфна по своему типу, что означает, что она может работать со всеми типами чисел. Вы можете ввести его в список
Int
и результат будет список,Int
но также может быть применен к списку типаInteger
и вернуть списокInteger
. это означает, что поведение переполнения определяется не этой функцией, а типом ввода (экспрессивная система типов yay Haskell :))источник
Integer
- это целочисленный тип без ограничений. ТакжеInt
есть 32-разрядное целое число, но это в основном просто наследие.Mathematica,
1817 байтЭто анонимная функция. Назови это как
источник
×@@@𝒫@#
должно быть непобедимым.(*/@#~2#:@i.@^#)
16 символов в J;)Обновление: C (функция f), 92
Даже как функция, это все еще самая длинная запись здесь. Я впервые передал массив неизвестной длины в качестве аргумента функции в C, и, очевидно, у функции C нет возможности узнать длину переданного ей массива, поскольку аргумент передается как указатель ( независимо от используемого синтаксиса). Следовательно, второй аргумент необходим для указания длины.
Я сохранил вывод в stdout, потому что установка целочисленного массива и его возврат почти наверняка будут дольше.
Спасибо Деннису за советы.
См. Функцию
f
(92 символа, исключая ненужные пробелы) в тестовых программах ниже.Вывод через printf
Вывод через указатель массива
С (программа), 108
исключая ненужные пробелы.
Ввод из командной строки, вывод в stdout. Си не выиграет здесь, но, возможно, я попытаюсь перейти к функции завтра.
В основном мы перебираем все
1<<c
комбинации простых чисел, причем каждый битi/c
связан с наличием или отсутствием определенного простого числа в произведении. «Внутренний цикл»i%c
проходит через простые числа, умножая их в соответствии со значением,i/c.
когда значениеi%c
достигает 0, продукт выводится, а затем устанавливается на 1 для следующей «внешней» итерации.любопытно, что
printf("%d ",p,p=1)
это не работает (всегда печатает 1.) Я не первый раз наблюдаю странное поведение, когда значение используется вprintf
и присваивается позже в той же скобке. В этом случае возможно, что вторая запятая рассматривается не как разделитель аргументов, а как оператор.использование
источник
-Wsequence-point
или-Wall
, GCC будет жаловаться.c-=1
кc--
или даже использовать ,i=--c<<c
если вы не возражаете UB (это , кажется, работает с GCC). 2. Оба варианта использования||
могут быть заменены троичными операторами:p=i%c?p:!!printf("%d ",p)
иp*=(i/c>>i%c)&1?1:atoi(v[i%c+1])
c-=1
это такая простая игра в гольф, которую я не должен был пропустить, но это было быстрое исправление ошибки, потому что я забыл, что в argv (название программы) есть одна дополнительная строка,i=..c<<c
работающая на GCC / cygwin, но я оставил свой оригинал запрограммируйте как есть и перейдите к функции. Итак, я только что узнал, чтоsizeof
не работает с массивами, переданными в качестве аргументов функции. Я включил ваши предложения для троичных операторов в функцию. Я остановился на выводе в stdout, так как не вижу короткого способа вернуть массив.Haskell, 27 байт
Это реализация Haskell ответа CJam @ sudo как анонимной функции. Он не побьет потрясающее решение @proud haskeller на Haskell, но я все равно оставлю его здесь.
Объяснение:
foldr
принимает двоичную функцию, значение и список. Затем он заменяет каждую ячейку минусов в списке путем применения функции, и конец списка по значению, например:foldr f v [a,b,c] == f a (f b (f c v))
. Наше значение - это одноэлементный список, содержащий1
двоичную функциюf = (=<<)(++).map.(*)
. Теперьf
берет числоn
, делает функцию,(n*)
которая умножается наn
, делает из нее функцию,g = map(n*)
которая применяет эту функцию ко всем элементам списка и передает эту функцию(=<<)(++)
. Здесь(++)
функция конкатенации, и(=<<)
является монадическим связывают , которая в данном случае принимает(++)
иg
, и дает функцию , которая принимает в списке, применяетсяg
к его копии, и объединяет их.Вкратце: начните с
[1]
и для каждого числаn
в списке ввода возьмите копию текущего списка, умножьте все наn
и добавьте ее в текущий список.источник
Питон: 55 символов
Рекурсивно генерирует продукты, выбирая включить или исключить каждое число по очереди.
источник
and
если вы напишите сумму наоборот?PARI / GP , 26 байт
Более длинные версии включают
(30 байт) и
(31 байт).
Обратите внимание, что если бы ввод был матрицей факторизации, а не набором, 18 байтов можно было бы сохранить, используя
divisors
один. Но преобразование набора в матрицу факторизации, кажется, занимает более 18 байтов. (Я могу сделать это в 39 байтах напрямуюv->concat(Mat(v~),Mat(vectorv(#v,i,1)))
или в 24 байта путем умножения и перефакторингаv->factor(factorback(v))
, кто-нибудь может сделать лучше?)источник
Мудрец -
3634По сути, так же, как решение Мартина Бюттнера , если я правильно понимаю. Как я уже упоминал в комментарии, я мог бы также опубликовать это как ответ.
Это анонимная функция, которую, например, можно вызвать следующим образом:
источник
J (20)
Это оказалось дольше, чем я надеялся или ожидал. Тем не менее: короче, чем haskel!
Использование:
Это работает для любого набора чисел, а не только для простых чисел. Кроме того, простые числа могут быть неограниченного размера, если массив имеет постфикс
x
:2 3 5 7x
источник
*/@#~2#:@i.@^#
является альтернативой для 14 байтов.05AB1E , 2 байта
Попробуйте онлайн!
объяснение
источник
R, 56 байт
Я рассматриваю здесь, что s - это множество (и список). Я уверен, что это можно сделать еще короче. Я увижу.
источник
PHP, 97 байт
источник