Зміна масиву в 2048 році


80

Припустимо, ми хочемо зрушити масив так, як це робиться в грі 2048 року : якщо у нас в масиві є два рівні послідовні елементи, об’єднаємо їх у подвійний елемент значення. Shift повинен повернути новий масив, де кожна пара послідовних рівних елементів замінюється їх сумою, а пари не повинні перетинатися. Зсув виконується лише один раз, тому нам не потрібно знову об’єднувати отримані значення. Зауважте, що якщо у нас є три послідовні рівні елементи, ми повинні підсумовувати найправіші елементи, так, наприклад, [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]

Я також дуже зацікавлений у використанні рішення :)


11
Це дуже приємний перший виклик. Ласкаво просимо на сайт!
DJMcMayhem

1
Введення не обов'язково сортується, а числа перевищують нуль, це єдине обмеження на числа. Ми можемо дозволити, що найбільше значення вписується в стандартні межі int32, я думаю. Порожній масив дає в результаті порожній масив. Дякуємо за участь, оцініть це :)
greenwolf

3
Для тих, хто все ще голосує, щоб закрити як неясне, виклик по суті зводиться до цього: Припустимо, у вас є масив додатних цілих чисел. Пройдіться по ньому від кінця до початку. Якщо поточний елемент дорівнює наступному, замініть його на суму обох і перейдіть до елемента після заміни, після чого повторіть цю перевірку на цей елемент і наступний. Повторюйте, поки не буде досягнуто початку масиву.
користувач2428118

1
@Titus "Зауважте, що якщо у нас є 3 послідовних рівних елемента, ми повинні підсумовувати найправіші елементи, тому, наприклад, [2, 2, 2] слід стати [2, 4], а не [4, 2]."
Мартін Ендер

1
Постанова про порожні масиви невдала; це визнало недійсними кілька відповідей, включаючи мою власну.
Денніс

Відповіді:



19

Haskell, 47 57 50 байт

e#l|a:b<-l,e==a= -2*a:b|1<2=e:l
map abs.foldr(#)[]

Використання reduce(або foldяк його називають у Haskell, тут праворуч foldr). Приклад використання: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Редагувати: +10 байт, щоб він також працював для несортованих масивів. Об'єднані числа вставляються як негативні значення, щоб запобігти повторному злиття. Вони виправляються фіналом map abs.


Трюк з негативом справді приємний!
xnor

14

Мозг-Флак , 158 96

{({}<>)<>}<>{(({}<>)<><(({})<<>({}<>)>)>)({}[{}]<(())>){((<{}{}>))}{}{{}(<({}{})>)}{}({}<>)<>}<>

Спробуйте в Інтернеті!

Пояснення:

1 Зворотний список (переміщення всього в інший стек, але це не має значення)

{({}<>)<>}<>
{        }   #keep moving numbers until you hit the 0s from an empty stack
 ({}<>)      #pop a number and push it on the other stack
       <>    #go back to the original stack
          <> #after everything has moved, switch stacks

2 Виконайте кроки 3-6, поки в цьому стеку не залишиться нічого:

{                                                                                         }

3 Скопіюйте два верхні елементи (2 3 -> 2 3 2 3)

(({}<>)<><(({})<<>({}<>)>)>)

(({}<>)<>                   #put the top number on the other stack and back on the very top
         <(({})             #put the next number on top after:
               <<>({}<>)>   #copying the original top number back to the first stack
                         )>)

4 Поставте 1 зверху, якщо два верхні рівні, а 0 в іншому випадку (з вікі)

({}[{}]<(())>){((<{}{}>))}{}

5 Якщо перші два були рівними (не нульовими у верхній частині), додайте наступні два та натисніть результат

{{}(<({}{})>)}{}
{            }   #skip this if there is a 0 on top
 {}              #pop the 1
   (<      >)    #push a 0 after:
     ({}{})      #pop 2 numbers, add them together and push them back on 
              {} #pop off the 0

6 Перемістіть верхній елемент до іншої стопки

({}<>)<>

7 Перейдіть на інший стек і друкуйте неявно

<>

pls додайте кому після назви мови, інакше вона порушує лідери ty: P
ASCII-тільки

9

PHP, 116 байт

<?$r=[];for($c=count($a=$_GET[a]);$c-=$x;)array_unshift($r,(1+($x=$a[--$c]==$a[$c-1]))*$a[$c]);echo json_encode($r);

або

<?$r=[];for($c=count($a=$_GET[a]);$c--;)$r[]=$a[$c]==$a[$c-1]?2*$a[$c--]:$a[$c];echo json_encode(array_reverse($r));

-4 байти, якщо вихід може бути масивом print_rзамість 'json_encode'

176 байт, щоб вирішити це за допомогою регексу

echo preg_replace_callback("#(\d+)(,\\1)+#",function($m){if(($c=substr_count($m[0],$m[1]))%2)$r=$m[1];$r.=str_repeat(",".$m[1]*2,$c/2);return trim($r,",");},join(",",$_GET[a]));

1
Ви не можете використовувати сортування, оскільки результат не завжди сортується: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto

@Crypto Ви відразу після додавання нових тестових випадків. До вживання сорту було все нормально
Йорг Гюльсерманн

for($i=count($a=$argv);--$i;)$b[]=($a[$i]==$a[$i-1])?2*$a[$i--]:$a[$i];print_r(array_reverse($b));та ж ідея, але коротша
Crypto

@Crypto Я не впевнений у виході як представленні рядків або масиві. за тестування []мені потрібна $r=[];
подяка

9

GNU sed, 41 38 37

Включає +1 для -r
-3 Завдяки цифровій травмі
-1 завдяки seshoumara

:
s,(.*)(1+) \2\b,\1!\2\2!,
t
y,!, ,

Введення та вихід - це рядки, розділені пробілом, унарними ( виходячи з цього консенсусу ).

Спробуйте в Інтернеті!


Використовуйте y,!, ,для збереження 1 байта.
seshoumara

@seshoumara Да ... Чому я не придумав цього. Дякую!
Райлі

8

Сітківка , 32

\d+
$*
r`\b\1 (1+)\b
$1$1
1+
$.&

rу рядку 3 активується відповідність правильного та лівого регулярних виразів. А це означає, що \1посилання має ставитись перед (1+)групою захоплення, на яку вона посилається.

Спробуйте в Інтернеті.


Приємно .. Цей варіант зліва наліво, щоб відповідати, досить зручний! Це частина викладу .Net або функція сітківки?
Дада

Я ось-ось збирався розмістити шахту в 26, використовуючи linefeed-separation як формат введення: retina.tryitonline.net/… основна економія виходить від цього і використовуючи транслітерацію, щоб позбутися другої заміни.
Мартін Ендер

@Dada Це функція .NET (і вона використовується під кришкою, щоб увімкнути відстань довільної довжини). Сітківка ще не має унікальних функцій регулярного виведення (хоча вона має деякі унікальні функції заміщення).
Мартін Ендер

1
@MartinEnder Добре дякую! .NET regex справді чудові! заздрісним кодером Perl помічено
Дада

@MartinEnder Я ваше рішення досить інший, щоб отримати ще одну відповідь
Digital Trauma

8

Perl, 41 байт

Включає +1 для -p

Наведіть послідовність введення на STDIN:

shift2048.pl <<< "2 2 2 4 4 8 2"

shift2048.pl:

#!/usr/bin/perl -p
s/.*\K\b(\d+) \1\b/2*$1.A/e&&redo;y/A//d

8

Пітон, 61 байт

def f(l):b=l[-2:-1]==l[-1:];return l and f(l[:~b])+[l[-1]<<b]

Булева bперевіряє, чи повинні два останні елементи згортатися, перевіряючи, чи є вони рівними таким чином, що безпечно для списків довжиною 1 або 0. Останній елемент, якщо потім додається до мультиплікатора 1рівного чи 2нерівного. Він додається до рекурсивного результату в списку, при цьому багато елементів порубані в кінці. Дякуємо Деннісу за 1 байт!


[l[-1]<<b]зберігає байт.
Денніс

l[-2:-1]є[l[-2]]
mbomb007

2
Мені це потрібно для роботи зі списками розмірів 0 та 1.
xnor

7

Perl, 43 + 1 ( -p) = 44 байти

Тон Hospel придумав 41 байт відповіді , перевірити це!

-4 спасибі @Ton Hospel!

Редагувати : додано \b, так як без цього він не вдавався при введенні, як би 24 4на виході був би 28.

$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge

Виконати з -pпрапором:

perl -pe '$_=reverse reverse=~s/(\b\d+) \1\b/$1*2/rge' <<< "2 2 2 4 4"


Я не бачу іншого способу, ніж використовувати reverseдва рази для правого згину (як s/(\d+) \1/$1*2/geби просто ліворуч, тобто 2 2 2став би 4 2замість 2 4). Отже, 14 байтів втрачено завдяки reverse... Все-таки я думаю, що повинен бути ще один (кращий) спосіб (все-таки перл!), Дайте мені знати, якщо ви знайдете його!


reverse reverseздається трохи затяжним. Я не знаю Perl, але чи можна зробити ярлик reverse(якщо нічого іншого, [ab] використовуючи eval)?
Кіос

Гарний сексгер. Зауважте, що ви можете просто залишити($_)
Тон Євангелія

@TonHospel дякую. Дійсно, документ, reverseсхожий, reverseне можна назвати без аргументу (ну приклади показують, що це може бути, але є лише один прототип:) reverse LIST, тож я забув про $_аргумент за замовчуванням;)
Дада

А LISTможе бути порожнім ...
Тон Євангелія

@TonHospel справді, але зазвичай, коли оператор використовує $_як аргумент за замовчуванням, doc вказує прототип без параметрів (наприклад, printабо lenght...). А може, це просто неправильне враження у мене.
Дада

7

JavaScript (ES6), 68 байт

f=a=>a.reduceRight((p,c)=>(t=p[0],p.splice(0,c==t,c==t?c+t:c),p),[])
    
console.log([
  [],
  [2, 2, 4, 4],
  [2, 2, 2, 4, 4, 8],
  [2, 2, 2, 2],
  [4, 4, 2, 8, 8, 2],
  [1024, 1024, 512, 512, 256, 256],
  [3, 3, 3, 1, 1, 7, 5, 5, 5, 5],
].map(f))


2
Непогано, але згідно з виконаним фрагментом: [1024, 1024, 512, 512, 256, 256]вирішується як [2048, 512, 1024]і не [2048, 1024, 512]...?
WallyWest

7

Perl 5.10, 61 50 байт ( 49 + 1 для прапора)

Завдяки Тонові Євангелії за збереження 11 байт!

Рішення без Regex, з -aпрапором:

@a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"

Спробуйте тут!


Хороший альтернативний метод. Шкода масивів майже завжди програє рядкам в перл. Тим не менш, ви можете трохи наблизитись, погравши в свій код до @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 байт)
Тон Госпел

@TonHospel Дійсно, я схильний уникати рядкових рішень (просто щоб показати, що Perl може зробити більше, ніж це!). Я не граю, щоб виграти все одно: D Дякую за поради щодо гольфу!
Пол Пікар

7

JavaScript (ES6), 68 65 58 57 65 64 байт

Збережено 1 байт завдяки @ l4m2

Виправлено для несортованих масивів тепер, коли було з’ясовано, що таких входів слід очікувати.

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]

console.log(f([2, 2, 4, 4]));
console.log(f([2, 2, 2, 4, 4, 8]));
console.log(f([2, 2, 2, 2]));
console.log(f([4, 2, 2]));


1
Я збирався запропонувати
редакцію,

a=>(a.reverse()+'').replace(/(.),\1/g,(c,i)=>i*2).split`,`.reverse()?
l4м2

@ l4m2 Це працює для одноцифрових входів, але не вдасться [1024, 1024, 512, 512, 256, 256](я думаю, цей тестовий випадок може бути доданий пізніше).
Арнольд

@Arnauld Ну і твої теж не виходять ...
l4m2

f=(a,l=[],m)=>(x=a.pop())*!m-l?f(a,x).concat(l):x?f(a,2*x,1):[l]?
l4м2

6

05AB1E , 26 байт

D¥__X¸«DgL*ê¥X¸«£vy2ôO})í˜

Спробуйте в Інтернеті!

Узагальнені кроки

  1. Зменшіть віднімання, щоб знайти, де відрізняються послідовні елементи
  2. Зменшіть віднімання на показники цих місць, щоб знайти довжину послідовних елементів
  3. Розбийте введення на шматки цих довжин
  4. Розбийте шматки на пари
  5. Підсумовуйте кожну пару
  6. Перевернути кожен підсумований шматок
  7. Вирівняти до одновимірного списку

5

Математика, 53 байти

Join@@(Reverse[Plus@@@#~Partition~UpTo@2]&/@Split@#)&

Пояснення

Split@#

Розбийте вхід на підсписи, що складаються з прогонів однакових елементів. тобто {2, 2, 2, 4, 8, 8}стає {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Розділіть кожен із підспілів на довжину розділів максимум на 2. тобто {{2, 2, 2}, {4}, {8, 8}}стає {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Усього кожного розділу. тобто {{{2, 2}, {2}}, {{4}}, {{8, 8}}}стає {{4, 2}, {4}, {16}}.

Reverse

Зворотні результати, тому що Partitionкоманда Mathematica йде зліва направо, але ми хочемо, щоб розділи були в іншому напрямку. тобто {{4, 2}, {4}, {16}}стає {{2, 4}, {4}, {16}}.

Join@@

Вирівняти результат. тобто {{2, 4}, {4}, {16}}стає {2, 4, 4, 16}.


Привіт JHM! Дякую за відповідь. Я не дуже добре розумію Mathematica, тому ви можете додати трохи пояснень щодо того, що відбувається?
isaacg

Plus@@@є, Tr/@і я думаю, ви можете уникнути дужок, і Join@@якщо ви використовуєте ##&@@результат Reverse(ще не перевіряли його).
Мартін Ендер

5

Java 7, 133 байти

Object f(java.util.ArrayList<Long>a){for(int i=a.size();i-->1;)if(a.get(i)==a.get(i-1)){a.remove(i--);a.set(i,a.get(i)*2);}return a;}

Вхід - це ArrayList, і він просто петлює назад, видаляючи та подвоюючи, де це необхідно.

Object f(java.util.ArrayList<Long>a){
    for(int i=a.size();i-->1;)
        if(a.get(i)==a.get(i-1)){
            a.remove(i--);
            a.set(i,a.get(i)*2);
        }
    return a;
}

Ви порівнюєте Longпосилання на рядок 3 із ==. Розглянемо a.get(i)-a.get(i-1)==0.
Якоб

4

Perl, 37 байт

Включає +4 для -0n

Виконати з введенням у вигляді окремих рядків на STDIN:

perl -M5.010 shift2048.pl
2
2
2
4
4
8
2
^D

shift2048.pl:

#!/usr/bin/perl -0n
s/\b(\d+
)(\1|)$//&&do$0|say$1+$2


4

PHP, 86 100 99 94 байт

for($r=[];$v=+($p=array_pop)($a=&$argv);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);

вимагає PHP 7.0; приймає значення з аргументів командного рядка.

Запустіть -nrабо спробуйте в Інтернеті .


2
[2, 2, 2] повертає [4,2] замість [2,4]
крипто

for($r=[];$v=($p=array_pop)($a=&$_GET[a]);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);на 1 байт коротше
Йорг Гюльсерманн

3

Джулія 205 байт

t(x)=Val{x}
s(x)=t(x)()
f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))
g()=[]
g{a}(::t(a))=[a]
g{a}(::t(a),B...)=[a;g(B...)]
g{a}(::t(a),::t(a),B...)=[2a;g(B...)]
K(A)=g(s.(A)...)
H(A)=(K^s(length(A)))(A)

Функція, яку потрібно викликати, - це H

напр H([1,2,2,4,8,2,])

Це в жодному разі не найкоротший спосіб зробити це в Джулії. Але це так круто, що я хотів поділитися цим.

  • t(a) - тип значення, що представляє значення (a).
  • s(a) є екземпляром цього типу значення
  • g- це функція, яка передає значення різниці (використовуючи типи значень) та числа його параметрів. І це класно
  • Kпросто обгортає gтак

Додаткова класна частина:

f^::t(1)=f
^{y}(f,::t(y))=x->f(((f^s(y-1))(x)))

Це визначає ^оператора, який потрібно застосувати до функцій. Так що K^s(2)(X)таке ж , як K(K(X)) так Hпросто викликають Kна Kкупі раз - достатня кількість разів , щоб , звичайно , зруйнуються будь вкладений випадок

Це можна зробити набагато коротше, але цей спосіб просто такий цікавий.


3

PowerShell v2 +, 81 байт

param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count..0]

Приймає введення як явний масив $n, реверсує його $n[$n.count..0], -joins елементи разом із комою, потім regex -replacesa збігається цифрова пара з першим елементом, a *2та оточується паренами. Труби, які отримують результат (який для введення @(2,2,4,4)буде схожий ), перетворюються (4*2),(2*2)на iex(короткий Invoke-Expressionі схожий eval), який перетворює множення у фактичні числа. Зберігає отриманий масив у $b, інкапсулює цей параметр, щоб розмістити його на конвеєрі, а потім обертається $bна [$b.count..0]. Залишає отримані елементи на трубопроводі, а вихід неявний.


Випробування

Примітка. У PowerShell поняття "повернення" порожнього масиву є безглуздим - воно перетворюється на те,$nullяк тільки воно покине область, і тому воно є еквівалентом повернення нічого, що робиться тут у першому прикладі (після деяких злісних багатослівних помилок). Крім того, висновок тут розділений пробілом, так як це роздільник за замовчуванням для строфікованих масивів.

PS C:\Tools\Scripts\golfing> @(),@(2,2,4,4),@(2,2,2,4,4,8),@(2,2,2,2),@(4,4,2,8,8,2),@(1024,1024,512,512,256,256),@(3,3,3,1,1,7,5,5,5,5)|%{"$_ --> "+(.\2048-like-array-shift.ps1 $_)}
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:67
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+                                                                   ~~~
    + CategoryInfo          : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

Cannot index into a null array.
At C:\Tools\Scripts\golfing\2048-like-array-shift.ps1:7 char:13
+   param($n)($b=$n[$n.count..0]-join','-replace'(\d+),\1','($1*2)'|iex)[$b.count. ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

 --> 
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

3

Javascript - 103 байти

v=a=>{l=a.length-1;for(i=0;i<l;i++)a[l-i]==a[l-1-i]?(a[l-i-1]=a[l-i]*2,a.splice(l-i,1)):a=a;return a}

Збережено 16 байт завдяки підказкам @MayorMonty на цій сторінці
Alexis_A

Це не працює. Тестування з [2,2,4,4]урожайністю [2,2,4,4].
Conor O'Brien

1
Так. Вузол v6.2.1
Conor O'Brien

Моє погано .. Я запускав його з іншим кодом JS в тому ж файлі, і глобальні змінні змішалися.
Alexis_A

3

Мозок-Флак , 60 байт

{({}<>)<>}<>{(({}<>)<>[({})]){((<{}>))}{}{({}<>{})(<>)}{}}<>

Спробуйте в Інтернеті!

Пояснення:

{({}<>)<>}<>   Reverse stack

{   While input exists
  (
    ({}<>)   Push copy of last element to the other stack
    <>[({})] And subtract a copy of the next element
  )   Push the difference
  {   If the difference is not 0
    ((<{}>)) Push two zeroes
  }{}  Pop a zero
  {   If the next element is not zero, i.e the identical element
    ({}<>{})  Add the element to the copy of the previous element
    (<>)      Push a zero
  }{}    Pop the zero
}<>  End loop and switch to output stack


2

Юлія, 73 82 байт

f(l)=l==[]?[]:foldr((x,y)->y[]==x?vcat(2x,y[2:end]):vcat(x,y),[l[end]],l[1:end-1])

Використовуйте праву складку для складання списку спиною вперед (можна також використовувати складну ліву та перевернути список на початку та в кінці).

Якщо заголовок поточного списку не дорівнює наступному елементу для попередньої підготовки, то просто додайте його.

В іншому видаліть голову списку (звучить якось жорстоко) і додайте елемент 2 рази.

Приклад

f([3,3,3,1,1,7,5,5,5,5]) 
returns a new list:
[3,6,2,7,10,10]

2

Ракетка 166 байт

(λ(l)(let g((l(reverse l))(o '()))(cond[(null? l)o][(=(length l)1)(cons(car l)o)]
[(=(car l)(second l))(g(drop l 2)(cons(* 2(car l))o))][(g(cdr l)(cons(car l)o))])))

Безумовно:

(define f
  (λ (lst)
    (let loop ((lst (reverse lst)) 
               (nl '()))
      (cond                            ; conditions: 
        [(null? lst)                   ; original list empty, return new list;
               nl]
        [(= (length lst) 1)            ; single item left, add it to new list
              (cons (first lst) nl)]
        [(= (first lst) (second lst))  ; first & second items equal, add double to new list
              (loop (drop lst 2) 
                    (cons (* 2 (first lst)) nl))]
        [else                          ; else just move first item to new list
              (loop (drop lst 1) 
                    (cons (first lst) nl))]  
        ))))

Тестування:

(f '[])
(f '[2 2 4 4]) 
(f '[2 2 2 4 4 8]) 
(f '[2 2 2 2]) 
(f '[4 4 2 8 8 2])
(f '[1024 1024 512 512 256 256]) 
(f '[3 3 3 1 1 7 5 5 5 5])
(f '[3 3 3 1 1 7 5 5 5 5 5])

Вихід:

'()
'(4 8)
'(2 4 8 8)
'(4 4)
'(8 2 16 2)
'(2048 1024 512)
'(3 6 2 7 10 10)
'(3 6 2 7 5 10 10)

1

Japt , 12 байт

ò¦ ®ò2n)mxÃc

Спробуйте в Інтернеті!

Розпаковано та як це працює

Uò!= mZ{Zò2n)mx} c

Uò!=    Partition the input array where two adjacent values are different
        i.e. Split into arrays of equal values
mZ{     Map the following function...
Zò2n)     Split into arrays of length 2, counting from the end
          e.g. [2,2,2,2,2] => [[2], [2,2], [2,2]]
mx        Map `Array.sum` over it
}
c       Flatten the result

Отримав якусь ідею від рішення Джонатана Аллана з желе .


0

Математика, 51 байт

Abs[#//.{Longest@a___,x_/;x>0,x_,b___}:>{a,-2x,b}]&

{Longest@a___,x_/;x>0,x_,b___}відповідає списку, що містить два послідовних однакових додатних числа, і перетворить ці два числа в -2x. Longestзмушує матчі відбуватися якомога пізніше.

Процес ілюструється поетапно:

   {3, 3, 3, 1, 1, 7, 5, 5, 5, 5}
-> {3, 3, 3, 1, 1, 7, 5, 5, -10}
-> {3, 3, 3, 1, 1, 7, -10, -10}
-> {3, 3, 3, -2, 7, -10, -10}
-> {3, -6, -2, 7, -10, -10}
-> {3, 6, 2, 7, 10, 10}

0

Vim, 28 байт

G@='?\v(\d+)\n\1<C-@>DJ@"<C-A>-@=<C-@>'<CR>

Макрос, який регулярно виражає пошук, шукає відповідні послідовні числа, і додає їх разом.

Вхідний масив повинен бути одним числом на рядок. Цей формат врятує мене від ударів, що приємно, але справжня причина полягає в тому, щоб працювати над перекриваючими регекс-матчами. З огляду на рядок 222, якщо ви /22будете відповідати лише першій парі, а не другому, що перекривається. Правила перекриття різні, коли дві пари починаються на різних лініях. У цьому виклик [2, 2, 2]стає [2, 4], тому відповідність пари, що перекривається, є критично важливою.

ПРИМІТКА. Проблема вимагала лише одного проходу. З цієї причини вам потрібно мати :set nowrapscan. З :set wrapscanмого я можу зробити версію, яка закінчує роботу в декількох пропусках, хоча це рішення, як написано, не завжди це робитиме.

  • <C-@>: Зазвичай у командному рядку набирайте літерал <CR>без запуску команди, з якою вам доведеться уникнути цього <C-V>. Але ви можете ввести <C-@>незмінене зображення, і воно буде розглядатися як <C-J>/ <NL>, що буде як <CR>під час запуску макросу, але не під час введення. Спробуйте прочитати :help NL-used-for-Nul.
  • @=: Я не можу легко використати записаний макрос на даний момент, оскільки існує можливість, що вхід може не мати пар, що відповідають. Якщо це трапиться під час запуску макроса, невдалий пошук не вдасться виконати макрос. Але якщо це трапиться під час пропуску (неявного першого), решта команд звичайного режиму запускаються, пошкоджуючи файл. Мінусом @=є те, що я втрачаю байт при рекурсивному дзвінку; іноді ви можете використовувати @@в якості рекурсивного дзвінка, але @"в цьому випадку це буде працювати на 4 байти раніше.
  • DJ@"<C-A>-: DJвидаляє рядок і додає число (немає нового рядка) в реєстр, тому я можу запустити його як макрос для аргументу числа <C-A>. Мені доведеться -після цього, щоб не отримати другого матчу у таких випадках [4, 2, 2].

0

Perl6, 92 байти

{my @b;loop ($_=@^a-1;$_>=0;--$_) {@b.unshift($_&&@a[$_]==@a[$_-1]??2*@a[$_--]!!@a[$_])};@b}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.