Предположим, мы хотим сместить массив, как это делается в игре 2048 : если у нас есть два равных последовательных элемента в массиве, объедините их в два элемента значения. Shift должен возвращать новый массив, где каждая пара последовательных равных элементов заменяется их суммой, и пары не должны пересекаться. Сдвиг выполняется только один раз, поэтому нам не нужно снова объединять полученные значения. Обратите внимание, что если у нас есть 3 последовательных равных элемента, мы должны суммировать самые правые элементы, поэтому, например, [2, 2, 2]
должно стать [2, 4]
, а не [4, 2]
.
Задача состоит в том, чтобы написать кратчайшую функцию, которая принимает массив и возвращает сдвинутый массив.
Вы можете предположить, что все целые числа будут строго положительными.
Примеры:
[] -> []
[2, 2, 4, 4] -> [4, 8]
[2, 2, 2, 4, 4, 8] -> [2, 4, 8, 8]
[2, 2, 2, 2] -> [4, 4]
[4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
[1024, 1024, 512, 512, 256, 256] -> [2048, 1024, 512]
[3, 3, 3, 1, 1, 7, 5, 5, 5, 5] -> [3, 6, 2, 7, 10, 10]
Я также очень заинтересован в решении с использованием Reduce :)
источник
Ответы:
Желе ,
10 98 байтПопробуйтеItOnline или запустите все тесты
Как?
источник
Haskell,
475750 байтИспользует
reduce
(или,fold
как это называется в Haskell, здесь правостороннееfoldr
). Пример использования:map abs.foldr(#)[] $ [2,2,2,4,4,8]
->[2,4,8,8]
.Изменить: +10 байт, чтобы он работал и для несортированных массивов. Объединенные числа вставляются как отрицательные значения, чтобы предотвратить повторное объединение. Они исправлены финалом
map abs
.источник
Brain-Flak ,
15896Попробуйте онлайн!
Объяснение:
1 Перевернуть список (переместить все в другой стек, но это не имеет значения)
2 Выполните шаги 3-6, пока в этом стеке ничего не останется:
3 Дублируйте два верхних элемента (2 3 -> 2 3 2 3)
4 Поместите 1 сверху, если два верхних равны, в противном случае 0 (из вики)
5 Если верхние два были равны (ненулевые сверху), добавьте следующие два и нажмите результат
6 Переместите верхний элемент в другой стек
7 Переключитесь на другой стек и печатайте неявно
источник
PHP, 116 байт
или же
-4 байта, если выходные данные могут быть массивом
print_r
вместо 'json_encode`176 байт, чтобы решить это с помощью регулярного выражения
источник
for($i=count($a=$argv);--$i;)$b[]=($a[$i]==$a[$i-1])?2*$a[$i--]:$a[$i];print_r(array_reverse($b));
та же идея, но короче[]
мне нужно$r=[];
Спасибо за вашу помощьGNU sed,
41 3837Включает +1 для -r
-3 благодаря цифровой травме
-1 благодаря сешумаре
Вход и выход - это строки, разделенные пробелом, в унарном порядке ( на основе этого консенсуса ).
Попробуйте онлайн!
источник
y,!, ,
для сохранения 1 байта.Сетчатка , 32
r
в строке 3 активирует сопоставление регулярных выражений справа налево. А это означает, что\1
ссылка должна находиться перед группой(1+)
захвата, на которую она ссылается.Попробуйте онлайн.
источник
Perl, 41 байт
Включает +1 для
-p
Задайте последовательность ввода в STDIN:
shift2048.pl
:источник
Python, 61 байт
Логическое значение
b
проверяет, должны ли последние два элемента разрушаться, проверяя, чтобы они были равны, таким образом, что это безопасно для списков длиной 1 или 0. Последний элемент затем добавляется с множителем1
для равных или2
для неравных. Он добавляется к рекурсивному результату в списке с множеством элементов, отрубленных до конца. Спасибо Деннису за 1 байт!источник
[l[-1]<<b]
сохраняет байт.l[-2:-1]
это[l[-2]]
Perl, 43 + 1 (
-p
) = 44 байтаТон Хоспел придумал ответ в 41 байт , зацените!
-4 спасибо @Ton Hospel!
Редактировать : добавлено
\b
, так как без него происходил сбой при вводе, как24 4
при выводе28
.Запустить с
-p
флагом:Я не вижу другого способа, кроме как использовать
reverse
двойное сгибание вправо (так же, как сгибаниеs/(\d+) \1/$1*2/ge
влево, т.2 2 2
Е. Становление4 2
вместо2 4
). Итак, 14 байтов потеряно благодаряreverse
... Тем не менее, я думаю, что должен быть другой (лучший) способ (в конце концов, это perl!), Дайте мне знать, если найдете его!источник
reverse reverse
кажется немного длинным Я не специалист по Perl, но есть ли способ, которым вы можете сделать ярлыкreverse
(если не использовать [ab]eval
)?($_)
reverse
выглядит так, чтоreverse
его нельзя вызвать без аргумента (хорошо, примеры показывают, что это может быть, но есть только один прототип:)reverse LIST
, поэтому я забыл$_
, что являюсь аргументом по умолчанию;)LIST
может быть пустым ...$_
качестве аргумента по умолчанию, в документе указывается прототип без параметров (например,print
илиlenght
...). Или, может быть, у меня просто неправильное впечатление.JavaScript (ES6), 68 байт
источник
[1024, 1024, 512, 512, 256, 256]
разрешается как[2048, 512, 1024]
и нет[2048, 1024, 512]
...?Perl 5,10,
6150 байт (49+ 1 для флага)Спасибо Ton Hospel за сохранение 11 байтов!
Решение без регулярных выражений, с
-a
флагом:Попробуй здесь!
источник
@a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"
(50 байтов)JavaScript (ES6),
686558576564 байтаСохранено 1 байт благодаря @ l4m2
Исправлено для несортированных массивов теперь, когда выяснено, что такие входные данные следует ожидать.
источник
a=>(a.reverse()+'').replace(/(.),\1/g,(c,i)=>i*2).split`,`.reverse()
?[1024, 1024, 512, 512, 256, 256]
(я думаю, что этот тестовый пример, возможно, был добавлен позже).f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]
?05AB1E , 26 байт
Попробуйте онлайн!
Обобщенные шаги
источник
Mathematica, 53 байта
объяснение
Разбейте ввод на подсписки, состоящие из прогонов идентичных элементов. то есть
{2, 2, 2, 4, 8, 8}
становится{{2, 2, 2}, {4}, {8, 8}}
.Partition каждый из подсписка в длину разделов больше 2. т.е.
{{2, 2, 2}, {4}, {8, 8}}
становится{{{2, 2}, {2}}, {{4}}, {{8, 8}}}
.Итого по каждому разделу. то есть
{{{2, 2}, {2}}, {{4}}, {{8, 8}}}
становится{{4, 2}, {4}, {16}}
.Отмените результаты, потому что
Partition
команда Mathematica идет слева направо, но мы хотим, чтобы разделы были в другом направлении. то есть{{4, 2}, {4}, {16}}
становится{{2, 4}, {4}, {16}}
.Сгладить результат. то есть
{{2, 4}, {4}, {16}}
становится{2, 4, 4, 16}
.источник
Plus@@@
есть ,Tr/@
и я думаю , что вы можете избежать круглые скобки иJoin@@
если вы используете##&@@
на результатReverse
(не проверял , хотя).Java 7, 133 байта
Ввод представляет собой ArrayList, и он просто возвращается назад, удаляя и удваивая при необходимости.
источник
Long
ссылки в строке 3 с==
. Посмотримa.get(i)-a.get(i-1)==0
.Perl, 37 байт
Включает +4 для
-0n
Запустите с вводом в виде отдельных строк на STDIN:
shift2048.pl:
источник
Haskell, 56 байт
источник
PHP,
86 100 9994 байтатребует PHP 7.0; принимает значения из аргументов командной строки.
Запустите
-nr
или попробуйте онлайн .источник
for($r=[];$v=($p=array_pop)($a=&$_GET[a]);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);
на 1 байт корочеЮлия 205 байт
Функция для вызова
H
например
H([1,2,2,4,8,2,])
Это никоим образом не самый короткий путь сделать это в Джулии. Но это так здорово, что я все равно хотел этим поделиться.
t(a)
является типом значения, представляющим значение (a).s(a)
является экземпляром этого типа значенияg
это функция, которая отправляет значения разности (используя типы значений) и номера своих параметров. И это крутоK
просто оборачиваетg
так чтоОчень крутая часть:
Это определяет
^
оператор для применения к функциям. Так чтоK^s(2)(X)
такое же , какK(K(X))
такH
просто вызываютK
наK
куче раз - достаточное количество раз , чтобы , конечно , разрушатся любой вложенный случайЭто можно сделать намного короче, но так просто весело.
источник
PowerShell v2 +, 81 байт
Принимает входные данные в виде явного массива
$n
, переворачивает его$n[$n.count..0]
,-join
элементы вместе с запятой, затем регулярное выражение-replace
совпадает с парой соответствующих цифр с первым элементом, a*2
, и заключено в скобки. Трубы, которые в результате (которые для ввода@(2,2,4,4)
будут выглядеть(4*2),(2*2)
) переходят кiex
(сокращенноInvoke-Expression
и аналогичноeval
), что преобразует умножение в фактические числа. Сохраняет результирующий массив в$b
, инкапсулирует его в parens, чтобы поместить его в конвейер, а затем переворачивает$b
с[$b.count..0]
. Оставляет полученные элементы в конвейере, а вывод неявным.Тестовые случаи
NB-- В PowerShell концепция «возврата» пустого массива не имеет смысла - он преобразуется в тот момент,
$null
когда он покидает область видимости - и поэтому он эквивалентен возврату ничего, что и делается в первом примере (после некоторых злых многословных ошибок). Кроме того, выходные данные здесь разделены пробелами, так как это разделитель по умолчанию для строковых массивов.источник
Javascript - 103 байта
источник
[2,2,4,4]
выходами[2,2,4,4]
.Brain-Flak , 60 байт
Попробуйте онлайн!
Объяснение:
источник
Python 2, 94 байта
Попробуйте онлайн
источник
Юлия,
7382 байтаИспользуйте правый сгиб, чтобы построить список сзади вперед (можно также использовать сгиб влево и повернуть список в начале и в конце).
Если заголовок текущего списка не равен следующему элементу, который нужно добавить, просто добавьте его.
В противном случае удалите заголовок списка (звучит жестоко) и добавьте элемент раз 2.
пример
источник
Ракетка 166 байт
Ungolfed:
Тестирование:
Выход:
источник
Japt , 12 байт
Попробуйте онлайн!
Распаковано и как это работает
Получил некоторую идею от решения Jonathan Allan's Jelly .
источник
Mathematica, 51 байт
{Longest@a___,x_/;x>0,x_,b___}
сопоставляет список, содержащий два последовательных идентичных положительных числа, и преобразует эти два числа в-2x
.Longest
заставляет спички происходить как можно позже.Процесс иллюстрируется пошагово:
источник
Vim, 28 байт
G@='?\v(\d+)\n\1<C-@>DJ@"<C-A>-@=<C-@>'<CR>
Макрос, который regex ищет в обратном порядке для поиска последовательных чисел и складывает их вместе.
Входной массив должен быть один номер в строке. Этот формат спасает меня от ударов, и это хорошо, но настоящая причина в том, чтобы обходить совпадения с регулярными выражениями. Учитывая строку
222
, если вы/22
будете соответствовать только первой паре, а не перекрывающей второй паре. Правила перекрытия отличаются, когда две пары начинаются на разных строках. В этом вызове[2, 2, 2]
становится[2, 4]
, так что соответствие перекрывающейся пары имеет решающее значение.ПРИМЕЧАНИЕ. Для задания требовался только один проход. По этой причине вам нужно иметь
:set nowrapscan
. С помощью:set wrapscan
я мог бы сделать версию, которая заканчивает работу за несколько проходов, хотя это решение, как написано, не всегда делает это.<C-@>
: Обычно в командной строке для ввода литерала<CR>
без запуска команды вы должны его экранировать<C-V>
. Но вы можете напечатать<C-@>
unescaped, и он будет рассматриваться как<C-J>
/<NL>
, что будет похоже на<CR>
запуск макроса, но не на ввод текста. Попробуйте прочитать:help NL-used-for-Nul
.@=
: В этот раз я не могу легко использовать записанный макрос, потому что есть вероятность, что на входе нет подходящих пар. Если это произойдет во время выполнения макроса, неудачный поиск приведет к сбою макроса. Но если это произойдет во время (неявного первого) прохода записи, остальные команды обычного режима будут запущены, повредив файл. Недостатком@=
является то, что я теряю байт при рекурсивном вызове; иногда вы можете использовать его@@
как рекурсивный вызов, но@"
в этом случае он будет выполняться на 4 байта раньше.DJ@"<C-A>-
:DJ
удаляет строку и помещает число (без новой строки) в регистр, поэтому я могу запустить его как макрос для числового аргумента to<C-A>
. Я должен-
потом, чтобы я не получил второй матч в таких случаях, как[4, 2, 2]
.источник
Perl6, 92 байта
источник
Пролог (SWI) ,
9787 байтПопробуйте онлайн!
источник