Цепи Гозинты
(Вдохновлено проектом Эйлер # 606 )
Цепочка gozinta для n - это последовательность, в {1,a,b,...,n}
которой каждый элемент правильно делит следующий. Например, существует восемь различных цепочек козинта на 12:
{1,12}, {1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}.
Соревнование
Напишите программу или функцию, которая принимает положительное целое число ( n > 1
) и выводит или возвращает все различные цепочки козинты для данного числа.
- Порядок в цепях имеет значение (по возрастанию), порядок цепочек не имеет.
- На случай, если он существует, вы не можете использовать встроенную функцию, которая решает проблему.
- Это код-гольф .
Редактировать: удаление 1
в качестве потенциального ввода.
code-golf
sequence
arithmetic
Зонтик
источник
источник
[[1]]
я бы сказал, что если[1,1]
это gozinta,1
то[1,1,12]
это gozinta,12
как есть,[1,1,1,12]
и теперь мы можем больше не "возвращай все ..."2|4
читается "два идет в четыре", ака "два gozinta четыре".Ответы:
Python 3 ,
6865 байтРедактировать: -3 байта благодаря @notjagan
Попробуйте онлайн!
объяснение
Каждая цепочка козинты состоит из числа
x
в конце цепочки, по крайней мере с одним делителем слева от нее. Для каждого делителяk
изx
цепей[1,...,k,x]
различны. Таким образом , мы можем для каждого делителяk
найти все его различные gozinta цепей и присоединятьx
к концу них, чтобы получить всю различную gozinta цепь сk
непосредственно слеваx
. Это делается рекурсивно до тех пор ,x = 1
когда[[1]]
не возвращается, так как все gozinta цепь начинается с 1, то есть рекурсией нижнего предела.Код становится таким коротким из-за понимания списка Python, допускающего двойную итерацию. Это означает, что найденные значения
f(k)
могут быть добавлены в один и тот же список для всех различных делителейk
.источник
Шелуха , 13 байт
Несколько иной подход к H.PWiz , хотя все еще грубой силой. Попробуйте онлайн!
объяснение
Основная идея состоит в том, чтобы объединить все подпоследовательности
[1,...,n]
и разбить результат на подсписки, где каждый элемент делит следующий. Из них мы оставляем те, которые начинаются с1
, заканчиваютсяn
и не содержат дубликатов. Это делается с помощью встроенной функции rangify…
. Затем остается отказаться от дубликатов.источник
Желе ,
98 байтПопробуйте онлайн!
Использует технику, аналогичную моему ответу Japt , и поэтому очень быстро работает на больших тестовых примерах .
Как это работает
источник
Mathematica, 77 байт
Формирует a,
Graph
где вершины являютсяDivisors
входными данными#
, а ребра представляют правильную делимость, а затем находятAll
пути от вершины1
к вершине#
.источник
Желе , 12 байт
Монадическая ссылка, принимающая целое число и возвращающая список списков целых чисел.
Попробуйте онлайн!
Как?
Мы хотим, чтобы все отсортированные списки уникальных целых чисел от одного до N были такими, что первый - это один, последний - это N, и все пары делятся. Код достигает этого фильтра, проверяя, что критерии парного деления удовлетворяются по набору мощности рассматриваемого диапазона, но выбираются только те, у которых максимальные суммы приращенной разности (те, которые начинаются с одного и заканчиваются на N, будут иметь сумма инкрементных разностей N-1, у других будет меньше).
источник
<slice>2<divisible>\<each>
: PƝ
вместо `2` 11 байт .Japt , 17 байт
Проверьте это онлайн!
Как ни странно, генерация вывода в виде строки была намного проще, чем генерация в виде массива массивов ...
объяснение
источник
¬
трюк! : p¬
- одна из причин, по которой я реализовал набор функций, которые в основном «делают X без аргументов или Y с достоверным аргументом»: PMathematica, 60 байт
Использование недокументированных мульти-Arg формы
Divisible
, гдеDivisible[n1,n2,...]
возвращается ,True
еслиn2∣n1
,n3∣n2
и так далее, и вFalse
противном случае. Мы принимаем всеSubsets
из спискаDivisors
входных данных#
, а затем вернутьCases
формы{1,___,#}
таким образом, чтоDivisible
даетTrue
дляReverse
д последовательности делителей.источник
Divisible
является ли встроенным средством проверки цепочки gozinta?Haskell, 51 байт
Рекурсивно находи козинты цепочки правильных делителей и добавляй
n
.Попробуйте онлайн!
источник
1
. Поскольку мы коллективно пришли к выводу об освобождении1
, не могли бы вы сэкономить 10 байтов, удалив это дело?1
не является частным случаем для этого алгоритма, он необходим в качестве базового случая для рекурсии. Само по себе второе определяющее уравнение может возвращать только пустой список.[[1]]
в качестве базы.Haskell (Lambdabot),
9285 байтТребуется Lambdabot Haskell, так как
guard
требуетControl.Monad
импорта. Основная функция - это анонимная функция, которая, как мне сказали, разрешена и сбрасывает пару байтов.Спасибо Лайкони за сохранение семи байтов.
Объяснение:
Монады очень удобны.
Это наша рекурсивная функция, которая выполняет всю реальную работу.
x
это число, которое мы накапливаем (произведение делителей, которые остаются в значении), иy
следующее число, которое мы должны попытаться разделить на него.Если
x
равно,y
то мы закончили повторение. Просто используйтеx
в качестве конца текущей цепочки gozinta и вернуть его.Haskell golf-ism для "True". То есть это случай по умолчанию.
Сейчас мы работаем внутри монады списка. В монаде списка у нас есть возможность сделать несколько вариантов одновременно. Это очень полезно при поиске «всего возможного» чего-либо путем истощения. В
guard
заявлении говорится: «Рассматривайте следующий выбор только в том случае, если условие истинно». В этом случае рассмотрите только следующий выбор, еслиy
делитx
.Если
y
есть делениеx
, у нас есть выбор добавленияy
в цепочку gozinta. В этом случае рекурсивно вызывайте(#)
, начинаяy = 2
сx
равнымx / y
, так как мы хотим «вычеркнуть» то, чтоy
мы только что добавили в цепочку. Затем, каким бы ни был результат этого рекурсивного вызова, умножьте его значения на значения, которыеy
мы толькоy
что проанализировали, и официально добавьте в цепочку gozinta.Рассмотрим также следующий выбор. Это просто складывает два списка вместе, но монадически мы можем думать об этом, как о «выборе между выполнением этой вещи ИЛИ этой другой вещью».
Другой вариант - просто продолжить рекурсию и не использовать значение
y
. Еслиy
не делится,x
то это единственный вариант. Еслиy
делится,x
то будет выбран этот вариант, а также другой вариант, и результаты будут объединены.Это основная функция gozinta. Он начинает рекурсию с вызова
(#)
аргумента. A1
добавляется к каждой цепочке gozinta, потому что(#)
функция никогда не помещает их в цепочки.источник
mod x y==0
можно сократить доmod x y<1
. Поскольку анонимные функции разрешены, ваша основная функция может быть записана как pointfree asmap(1:).(#2)
.Хаскелл,
10710095 байтМожет быть, есть лучшее условие завершения (пробовал что-то вроде
но это дольше). Проверка
1
кажется благоразумной, как очистка повторов1
или дубликатов (nub
не вPrelude
) больше байтов.Попробуйте онлайн.
источник
(>>=h)
для(concatMap h)
u
JavaScript (Firefox 30-57), 73 байта
Удобно
n%0<1
это ложь.источник
Желе , 17 байт
Попробуйте онлайн!
источник
1
неожиданно, хотя. Мне не удалось найти окончательный результат1
, но я предположил, что это было[[1]]
. Я не могу точно сказать, что[1,1]
это неправильно, за исключением того, что все остальные результаты увеличиваются. Мысли?;€
на;Q¥€
).Mathematica, 104 байта
источник
FreeQ[...]
может статьAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Developer
PartitionMap :: nlen: - Текст сообщения не найден - >> `почему?BlockMap
используетDeveloper`PartitionMap
функцию внутри, но так как это функция разработчика, у нее нет сообщений об ошибках. Ошибка вызвана списками, которые имеют 1 или 0 элементов, с которыми вы не можете сделать 2-разделение.Mathematica, 72 байта
объяснение
Найти все делители ввода.
Создайте все подмножества этого списка.
Выберите все случаи, которые соответствуют шаблону ...
Начиная с 1 и заканчивая
<input>
...и удовлетворяет условию ...
Левый элемент делит правый элемент на все 2 раздела списка, смещение 1.
источник
TI-BASIC, 76 байт
объяснение
Я мог бы сохранить еще 5 байтов, если разрешено завершать с ошибкой, а не изящно, удалив проверку Ans> 1 и условие цикла. Но я не уверен, что это разрешено.
источник
Mathematica
8677 байтГрубая сила по определению.
Желая был более короткий способ сделать попарно последовательное сравнение элементов списка.
Спасибо @Jenny_mathy и @JungHwanMin за предложения по экономии 9 байт
источник
FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&]
(в качестве второго аргумента) для перехода к 82 байтамAnd@@BlockMap[#∣#2&@@#&,#,2,1]
Шелуха ,
1716 байт-1 байт, спасибо Zgarb
Попробуйте онлайн!
источник
50
вход, и он истек. В чем суть вашего подхода?o`:⁰:1
может быть`Je1⁰
PHP
147141Отредактировано для удаления лишнего теста
Разъяснение:
15 символов шаблона :(
Инициируйте набор результатов,
[[1]]
поскольку каждая цепочка начинается с 1. Это также приводит к поддержке 1 в качестве входа.Для каждого числа от 2 до
$i
, мы собираемся расширить каждую цепочку в нашем наборе на текущее число, если оно идет , а затем добавить расширенную цепочку в наш набор результатов.Отфильтруйте наши промежуточные цепочки, которые не дошли до
$i
10 символов шаблона :(
источник
Mathematica
Ответ кешируется для дополнительных звонков.
источник