Ранее я определил процесс дробления массива
В раздавленном состоянии мы читаем массив слева направо. Если в какой-то момент мы встречаем два одинаковых элемента подряд, мы удаляем первый и удваиваем второй.
Например, вот процесс дробления следующего массива
[5,2,2,4]
^
[5,2,2,4]
^
[5,2,2,4]
^
[5,4,4]
^
[5,4,4]
^
[5,8]
^
Обратите внимание, что один и тот же элемент может быть свернут несколько раз. В примере 2,2,4
был свернут в 8
один проход.
Теперь дробить массивы легко, а трудно их дробить. Ваша задача - взять массив положительных целых чисел в качестве входных данных и вывести наибольший массив, который может сформировать входные данные при неоднократном дроблении. Например, массив [4]
образован дроблением, [2,2]
который, в свою очередь, образован дроблением [1,1,1,1]
. Так как мы не можем иметь нецелые значения[1,1,1,1]
может быть мы не можем больше их раздавить, и поэтому наш ответ.
Вы никогда не получите 0
входной массив, потому что такие массивы могут быть расширены до бесконечности. Вы также никогда не получите случай с двумя одинаковыми нечетными числами рядом друг с другом, такие случаи не могут быть результатом дробления.
Это код-гольф поэтому ответы будут оцениваться с размером их источника, измеренным в байтах, с меньшим количеством байтов, тем лучше.
Прежде чем начать делать свой ответ, я просто хочу сказать, что этот вызов значительно сложнее, чем кажется. По мере продвижения проверяйте свою интуицию и убедитесь, что ваш ответ прошел все контрольные тесты.
Тестовые случаи
[] -> []
[5] -> [5]
[6] -> [3,3]
[8] -> [1,1,1,1,1,1,1,1]
[4,8] -> [1,1,1,1,1,1,1,1,1,1,2]
[2,8] -> [1, 1, 1, 1, 2, 1, 1, 1, 1]
[4,4] -> [1,1,1,1,1,1,1,1]
источник
[1,1,1,1,1,1,1,1,1,1,2]
производить[4, 8]
вместо[8, 4]
? это должно быть[1,>1,1,1,1,1,1,1,1,1,2]
,[2,1,>1,1,1,1,1,1,1,2]
,[2,>2,1,1,1,1,1,1,2]
,[4,1,>1,1,1,1,1,2]
,[4,2,1,>1,1,1,2]
,[4,2,>2,1,1,2]
,[4,>4,1,1,2]
,[8,1,>1,2]
,[8,2,>2]
,[8,4]
?[1,>1,1,1,1,1,1,1,1,1,2]
,[2,>1,1,1,1,1,1,1,1,2]
,[2,1,>1,1,1,1,1,1,1,2]
,[2,2,>1,1,1,1,1,1,2]
,[2,2,1,>1,1,1,1,1,2]
,[2,2,2,>1,1,1,1,2]
,[2,2,2,1,>1,1,1,2]
,[2,2,2,2,>1,1,2]
,[2,2,2,2,1,>1,2]
,[2,2,2,2,2,>2]
,[2,2,2,2,4>]
, второй проход:[2,>2,2,2,4]
,[4,>2,2,4]
,[4,2,>2,4]
,[4,4,>4]
,[4,8>]
. Надеюсь, это прояснит ситуацию. Если вы хотите, чтобы какой-то код смотрел на предыдущий вопрос, есть ответы, которые реализуют функцию дробления.[4, 4]
должен быть удален, так как мы никогда не сможем получить этот массив после последовательности stretch => crush, так как это закончится[8]
Ответы:
JavaScript (Node.js) ,
237221213186 байтПопробуйте онлайн!
Этот алгоритм вычисляет оптимальные растянутые массивы, растягивая каждое число до максимума, а затем, если необходимо, он сжимает пару чисел в нужном месте, эффективно создавая «блокировщик дробления», прерывая последовательность дробления предыдущего числа.
Например:
[1, 1, 1, 1, 1, 1]
дает[4,2]
один раз раздавлен, но[1, 1, 1, 1, 2]
приводит к[2, 4]
Задача состоит в том, чтобы определить, где именно должен находиться блокатор дробления, чтобы дробление полученного массива давало правильный результат:
[2, 4]
требуется блокиратор раздавливания (растянутое число1
повторяется и[1, 1]
короче[1,1,1,1]
), но[4, 2]
и[2, 6]
не требуетсяn
предыдущую растянутую последовательность и если вышеуказанное условие проверяется, то текущая последовательность является повторениемn
последовательности. Чтобы прервать последовательность дробления предыдущего числа, нам нужно поместить блокатор раздавливания в конце второйn
последовательности текущего числа, чтобы растянуть. Пример:[2, 8] => [(1, 1)=n, (1, 1) + (2) + (1, 1) + ...]
или[4, 8] => [(1, 1, 1, 1)=n, (1, 1, 1, 1) + (1, 1, 2) + ...]
источник
Желе , 42 байта
Попробуйте онлайн!
Полная программа. Крайне неэффективно, но работает.
источник
Python 2 ,
230228226 байтРаботает путем итерации всех возможных списков с той же суммой, что и входной. Удаляя те, которые не равны входному массиву в каком-то раздавленном состоянии, выбираем самый длинный.
Изменить: -2 байта, удалив
if
в основной функцииИзменить: -2 байта, удалив две ненужные квадратные скобки
Попробуйте онлайн!
объяснение
Основная функция, отвечающая за поиск всех возможных решений и выбор самого длинного
Функция дробления, которая проверяет, равен ли y одному из дроблений.
Генерация всех возможных перестановок с заданной суммой
источник
05AB1E ,
4137 байтПопробуйте онлайн!
Порт моего решения Javascript.
Пояснения:
источник