Dịch chuyển mảng giống như năm 2048


80

Giả sử chúng ta muốn dịch chuyển một mảng giống như được thực hiện trong trò chơi năm 2048 : nếu chúng ta có hai phần tử liên tiếp bằng nhau trong mảng, hợp nhất chúng thành hai phần tử giá trị. Shift phải trả về một mảng mới, trong đó mọi cặp phần tử bằng nhau liên tiếp được thay thế bằng tổng của chúng và các cặp không được giao nhau. Việc thay đổi chỉ được thực hiện một lần, vì vậy chúng tôi không cần phải hợp nhất lại các giá trị kết quả. Lưu ý rằng nếu chúng ta có 3 phần tử bằng nhau liên tiếp, chúng ta phải tính tổng các phần tử ngoài cùng, vì vậy, ví dụ, [2, 2, 2]sẽ trở thành [2, 4], không [4, 2].

Nhiệm vụ là viết hàm ngắn nhất trong đó lấy một mảng và trả về một mảng đã dịch chuyển.

Bạn có thể cho rằng tất cả các số nguyên sẽ hoàn toàn tích cực.

Ví dụ:

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

Tôi cũng rất quan tâm đến giải pháp sử dụng giảm :)


11
Đây là một thử thách đầu tiên rất tốt đẹp. Chào mừng đến với trang web!
DJMcMayhem

1
Đầu vào không nhất thiết phải được sắp xếp và số lớn hơn 0, đó là hạn chế duy nhất về số. Chúng tôi có thể để giá trị lớn nhất phù hợp với giới hạn int32 tiêu chuẩn tôi nghĩ. Kết quả là mảng rỗng cho mảng trống là kết quả. Cảm ơn sự tham gia, đánh giá cao điều đó :)
greenwolf

3
Đối với những người vẫn bỏ phiếu đóng cửa không rõ ràng, về cơ bản, thách thức này sẽ giải quyết vấn đề này: Giả sử bạn có một loạt các số nguyên dương. Đi qua nó từ đầu đến cuối. Nếu phần tử hiện tại bằng với phần tử tiếp theo, thay thế nó bằng tổng của cả hai và di chuyển đến phần tử sau khi thay thế, sau đó thực hiện lại kiểm tra này cho phần tử đó và phần tiếp theo. Lặp lại cho đến khi bắt đầu mảng.
dùng2428118

1
@Titus "Lưu ý rằng nếu chúng ta có 3 phần tử bằng nhau liên tiếp, chúng ta phải tính tổng các phần tử ngoài cùng bên phải, vì vậy, ví dụ: [2, 2, 2] sẽ trở thành [2, 4], chứ không phải [4, 2]."
Martin Ender

1
Phán quyết về mảng trống là không may; nó đã làm mất hiệu lực một vài câu trả lời, bao gồm cả câu trả lời của riêng tôi.
Dennis

Câu trả lời:



19

Haskell, 47 57 50 byte

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

Sử dụng reduce(hoặc foldnhư nó được gọi trong Haskell, ở đây là một nếp gấp bên phải foldr). Ví dụ sử dụng: map abs.foldr(#)[] $ [2,2,2,4,4,8]-> [2,4,8,8].

Chỉnh sửa: +10 byte để làm cho nó hoạt động cho các mảng chưa được sắp xếp. Các số được hợp nhất được chèn dưới dạng giá trị âm để ngăn việc hợp nhất thứ hai. Họ được sửa chữa bởi một trận chung kết map abs.


Các mẹo với tiêu cực là thực sự tốt đẹp!
xnor

14

Brain-Flak , 158 96

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

Hãy thử trực tuyến!

Giải trình:

1 Đảo ngược danh sách (di chuyển mọi thứ sang ngăn xếp khác, nhưng điều đó không quan trọng)

{({}<>)<>}<>
{        }   #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 Thực hiện các bước 3-6 cho đến khi không còn gì trên ngăn xếp này:

{                                                                                         }

3 Nhân đôi hai yếu tố trên cùng (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 Đặt 1 trên đầu nếu hai đầu trên bằng nhau, 0 khác (từ wiki)

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

5 Nếu hai đầu trên bằng nhau (khác không trên đầu) thêm hai tiếp theo và đẩy kết quả

{{}(<({}{})>)}{}
{            }   #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 Di chuyển phần tử trên cùng sang ngăn xếp khác

({}<>)<>

7 Chuyển sang ngăn xếp khác và in ngầm

<>

vui lòng thêm dấu phẩy sau tên ngôn ngữ, nếu không, nó sẽ phá vỡ bảng xếp hạng ty: P
ASCII-chỉ

9

PHP, 116 byte

<?$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);

hoặc là

<?$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 Byte nếu đầu ra có thể là một mảng print_rthay vì 'json_encode`

176 byte để giải quyết vấn đề này với Regex

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
Bạn không thể sử dụng sắp xếp vì kết quả không phải lúc nào cũng được sắp xếp: [4, 4, 2, 8, 8, 2] -> [8, 2, 16, 2]
Crypto

@Crypto Bạn ngay sau khi các trường hợp thử nghiệm mới được thêm vào. Trước khi sử dụng sắp xếp là ổn
Jörg Hülsermann

for($i=count($a=$argv);--$i;)$b[]=($a[$i]==$a[$i-1])?2*$a[$i--]:$a[$i];print_r(array_reverse($b));cùng ý tưởng nhưng ngắn
Crypto

@Crypto Tôi không chắc chắn về đầu ra dưới dạng chuỗi đại diện hoặc một mảng. đối với bản thử nghiệm []tôi cần $r=[];Cảm ơn sự giúp đỡ của bạn
Jörg Hülsermann


8

Võng mạc , 32

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

rtrên dòng 3 kích hoạt kết hợp regex từ phải sang trái. Và điều này có nghĩa là \1tham chiếu cần phải đến trước (1+)nhóm bắt giữ mà nó tham chiếu.

Hãy thử trực tuyến.


Đẹp .. Tùy chọn từ phải sang trái để phù hợp là khá tiện dụng! Đây có phải là một phần của .Net regex hoặc tính năng Retina không?
Dada

Tôi vừa mới đăng bài của tôi ở tuổi 26, sử dụng phân tách linefeed làm định dạng đầu vào: retina.tryitonline.net/ Lời tiết kiệm chính đến từ đó và sử dụng chuyển ngữ để loại bỏ thay thế thứ hai.
Martin Ender

@Dada Đó là một tính năng .NET (và nó được sử dụng dưới mui xe để cho phép các giao diện có độ dài tùy ý). Retina chưa có tính năng regex duy nhất nào (mặc dù nó có một số tính năng thay thế duy nhất).
Martin Ender

1
@MartinEnder Ok cảm ơn! .NET regex thật sự rất tuyệt! coder perl ghen phát hiện
Dada

@MartinEnder Tôi giải pháp của bạn đủ khác để đảm bảo một câu trả lời khác
Chấn thương kỹ thuật số

8

Perl, 41 byte

Bao gồm +1 cho -p

Đưa ra chuỗi đầu vào trên 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

Python, 61 byte

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

Boolean bkiểm tra xem hai phần tử cuối cùng có nên thu gọn hay không bằng cách kiểm tra xem chúng có bằng nhau theo cách an toàn cho danh sách có độ dài 1 hoặc 0. Phần tử cuối cùng nếu sau đó được thêm vào một số nhân 1cho bằng hoặc 2không bằng nhau. Nó được thêm vào kết quả đệ quy trong danh sách với nhiều yếu tố bị cắt nhỏ ở cuối. Cảm ơn Dennis cho 1 byte!


[l[-1]<<b]tiết kiệm một byte.
Dennis

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

2
Tôi cần nó để làm việc cho các danh sách kích thước 0 và 1.
xnor

7

Perl, 43 + 1 ( -p) = 44 byte

TonMedel đã đưa ra câu trả lời 41 byte , hãy xem thử!

-4 cảm ơn @TonMedel!

Chỉnh sửa : được thêm vào \b, vì không có nó, nó đã thất bại ở đầu vào như 24 4trên đó đầu ra sẽ có 28.

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

Chạy với -pcờ:

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


Tôi không thấy một cách nào khác ngoài việc sử dụng reversehai lần để gấp phải (như chỉ là s/(\d+) \1/$1*2/gegấp bên trái, tức là 2 2 2sẽ trở thành 4 2thay vì 2 4). Vì vậy, mất 14 byte nhờ reverse... Tuy nhiên, tôi nghĩ rằng phải có một cách khác (tốt hơn) (đó là perl sau tất cả!), Hãy cho tôi biết nếu bạn tìm thấy nó!


reverse reversecó vẻ hơi dài. Tôi không phải là chuyên gia về Perl, nhưng có cách nào bạn có thể tạo một lối tắt đến reverse(nếu không có gì khác, [ab] bằng cách sử dụng eval) không?
Cyoce

Đẹp sexeger. Lưu ý rằng bạn chỉ có thể rời khỏi($_)
TonMedel 6/10/2016

@TonHeach cảm ơn. Thật vậy, tài liệu reversetrông giống như reversekhông thể được gọi mà không có đối số (các ví dụ cho thấy nó có thể, nhưng chỉ có một nguyên mẫu reverse LIST:), vì vậy tôi quên mất việc $_là đối số mặc định;)
Dada

A LISTcó thể trống rỗng ...
TonMedel 6/10/2016

@TonH Phúc thực sự, nhưng thông thường khi một toán tử sử dụng $_làm đối số mặc định, tài liệu chỉ định một nguyên mẫu không có tham số (như printhoặc lenght...). Hoặc có thể đó chỉ là một ấn tượng sai mà tôi có.
Dada

7

JavaScript (ES6), 68 byte

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
Không tệ, nhưng theo đoạn trích được thực hiện: [1024, 1024, 512, 512, 256, 256]đang giải quyết [2048, 512, 1024]và không [2048, 1024, 512]...?
WallyWest

7

Perl 5.10, 61 50 byte ( 49 + 1 cho cờ)

Cảm ơn TonMedel vì đã tiết kiệm 11 byte!

Giải pháp miễn phí Regex, với -acờ:

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

Thử ở đây!


Phương pháp thay thế đẹp. Một mảng đáng tiếc hầu như luôn thua các chuỗi trong perl. Tuy nhiên, bạn có thể tiến gần hơn một chút bằng cách đánh mã số của mình tới @a=($F[-1]-$b?$b:2*pop@F,@a)while$b=pop@F;say"@a"(50 byte)
TonMedel

@TonH Phúc Thật vậy, tôi có xu hướng tránh các giải pháp dựa trên chuỗi (chỉ để chứng minh rằng Perl có thể làm được nhiều hơn thế!). Dù sao thì tôi cũng không chơi để giành chiến thắng: D Cảm ơn các mẹo chơi gôn!
Paul Picard

7

JavaScript (ES6), 68 65 58 57 65 64 byte

Đã lưu 1 byte nhờ @ l4m2

Đã sửa lỗi cho các mảng chưa được sắp xếp, hiện đã được làm rõ rằng các đầu vào như vậy sẽ được mong đợi.

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
Tôi chuẩn bị đề xuất bản chỉnh sửa bạn vừa thực hiện :)
ETHproductions

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

@ l4m2 Điều đó không hoạt động đối với các đầu vào một chữ số, nhưng sẽ thất bại [1024, 1024, 512, 512, 256, 256](Tôi nghĩ trường hợp thử nghiệm này có thể đã được thêm vào sau).
Arnauld

@Arnauld Vâng, bạn cũng thất bại ...
l4m2

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

6

05AB1E , 26 byte

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

Hãy thử trực tuyến!

Các bước tổng quát

  1. Giảm bằng phép trừ để tìm nơi các phần tử liên tiếp khác nhau
  2. Giảm bằng cách trừ trên các chỉ số của những nơi đó để tìm độ dài của các phần tử liên tiếp
  3. Chia đầu vào thành các đoạn có độ dài
  4. Chia khối thành từng cặp
  5. Tính tổng mỗi cặp
  6. Đảo ngược từng khúc tổng
  7. Làm phẳng danh sách 1 chiều

5

Toán học, 53 byte

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

Giải trình

Split@#

Chia đầu vào thành các danh sách con bao gồm các phần tử giống hệt nhau. tức là {2, 2, 2, 4, 8, 8}trở thành {{2, 2, 2}, {4}, {8, 8}}.

#~Partition~UpTo@2

Phân vùng mỗi danh sách con thành chiều dài phân vùng nhiều nhất là 2. tức là {{2, 2, 2}, {4}, {8, 8}}trở thành {{{2, 2}, {2}}, {{4}}, {{8, 8}}}.

Plus@@@

Tổng cộng mỗi phân vùng. tức là {{{2, 2}, {2}}, {{4}}, {{8, 8}}}trở thành {{4, 2}, {4}, {16}}.

Reverse

Đảo ngược kết quả vì Partitionlệnh của Mathicala đi từ trái sang phải, nhưng chúng tôi muốn các phân vùng ở hướng khác. tức là {{4, 2}, {4}, {16}}trở thành {{2, 4}, {4}, {16}}.

Join@@

Làm phẳng kết quả. tức là {{2, 4}, {4}, {16}}trở thành {2, 4, 4, 16}.


Xin chào! Cảm ơn câu trả lời. Tôi không hiểu rõ về Mathicala, vì vậy bạn có thể thêm một chút giải thích về những gì đang xảy ra không?
isaacg

Plus@@@Tr/@và tôi nghĩ rằng bạn có thể tránh các dấu ngoặc đơn và Join@@nếu bạn sử dụng ##&@@kết quả của Reverse(mặc dù chưa thử nghiệm nó).
Martin Ender

5

Java 7, 133 byte

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

Đầu vào là một ArrayList và nó chỉ lặp lại, loại bỏ và nhân đôi khi cần thiết.

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

Bạn đang so sánh các Longtài liệu tham khảo trên dòng 3 với ==. Hãy xem xét a.get(i)-a.get(i-1)==0.
Jakob

4

Perl, 37 byte

Bao gồm +4 cho -0n

Chạy với đầu vào là các dòng riêng biệt trên STDIN:

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

ca2048.pl:

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

4

Haskell, 56 byte

g(a:b:r)|a==b=a+b:g r|l<-b:r=a:g l
g x=x
r=reverse
r.g.r

4

PHP, 86 100 99 94 byte

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

yêu cầu PHP 7.0; lấy các giá trị từ các đối số dòng lệnh.

Chạy với -nrhoặc thử trực tuyến .


2
[2, 2, 2] trở lại [4,2] thay vì [2,4]
Crypto

for($r=[];$v=($p=array_pop)($a=&$_GET[a]);)array_unshift($r,end($a)-$v?$v:2*$p($a));print_r($r);ngắn hơn 1 Byte
Jörg Hülsermann

3

Julia 205 byte

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)

Chức năng được gọi là H

ví dụ H([1,2,2,4,8,2,])

Đây không phải là cách ngắn nhất để làm điều này trong julia. Nhưng nó thật tuyệt, đến nỗi tôi muốn chia sẻ nó.

  • t(a) là một loại giá trị, đại diện cho giá trị (a).
  • s(a) là một thể hiện của loại giá trị đó
  • glà một hàm gửi các giá trị chênh lệch (sử dụng các loại giá trị) và số tham số của nó. Và điều đó thật tuyệt
  • Kchỉ kết thúc tốt đẹp gđể

Phần tuyệt vời:

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

Điều này xác định ^toán tử để áp dụng cho các chức năng. Vì vậy, đó K^s(2)(X)là tương tự như K(K(X)) vậy Hchỉ được gọi Kvào Kmột loạt các lần - đủ thời gian để chắc chắn sụp đổ bất kỳ trường hợp lồng nhau

Điều này có thể được thực hiện ngắn hơn nhiều, nhưng cách này chỉ là rất vui vẻ.


3

PowerShell v2 +, 81 byte

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

Đưa đầu vào thành một mảng rõ ràng $n, đảo ngược nó $n[$n.count..0], -joins các phần tử cùng với dấu phẩy, sau đó regex -replacesa cặp chữ số phù hợp với phần tử đầu tiên, a *2và được bao quanh trong các ô. Các ống dẫn đến kết quả (mà đầu vào @(2,2,4,4)sẽ trông giống như (4*2),(2*2)) iex(viết tắt Invoke-Expressionvà tương tự eval), chuyển đổi phép nhân thành số thực. Lưu trữ mảng kết quả vào $b, đóng gói nó trong parens để đặt nó trên đường ống, sau đó đảo ngược $bvới [$b.count..0]. Để lại các yếu tố kết quả trên đường ống và đầu ra là ẩn.


Các trường hợp thử nghiệm

NB-- Trong PowerShell, khái niệm "trả về" một mảng trống là vô nghĩa - nó được chuyển đổi$nullngay khi nó rời khỏi phạm vi - và do đó, nó tương đương với việc trả về không có gì, đó là những gì được thực hiện ở đây trong ví dụ đầu tiên (sau một số lỗi dài dòng xấu xa). Ngoài ra, đầu ra ở đây được phân tách bằng dấu cách, vì đó là dấu phân cách mặc định cho các mảng được xâu chuỗi.

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 byte

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}

Đã lưu 16 byte nhờ các mẹo @MayorMonty trên trang này
Alexis_A

Điều này không hoạt động. Thử nghiệm với [2,2,4,4]sản lượng [2,2,4,4].
Conor O'Brien

1
vâng Nút v6.2.1
Conor O'Brien

Thật tệ .. Tôi đã chạy nó với một mã JS khác trong cùng một tệp và các biến toàn cục đã bị xáo trộn.
Alexis_A

3

Brain-Flak , 60 byte

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

Hãy thử trực tuyến!

Giải trình:

{({}<>)<>}<>   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

Julia, 73 82 byte

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

Sử dụng gấp phải để xây dựng danh sách từ sau ra trước (người ta cũng có thể sử dụng gấp bên trái và đảo ngược danh sách ở đầu và cuối).

Nếu phần đầu của danh sách hiện tại không bằng phần tử tiếp theo để trả trước, thì chỉ cần trả trước nó.

Khác loại bỏ phần đầu của danh sách (nghe có vẻ tàn nhẫn) và chuẩn bị phần tử lần 2.

Thí dụ

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

2

Vợt 166 byte

(λ(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))])))

Ung dung:

(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))]  
        ))))

Kiểm tra:

(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])

Đầu ra:

'()
'(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 byte

ò¦ ®ò2n)mxÃc

Hãy thử trực tuyến!

Giải nén & Cách thức hoạt động

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

Có một số ý tưởng từ giải pháp Jelly của Jonathan Allan .


0

Toán học, 51 byte

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

{Longest@a___,x_/;x>0,x_,b___}khớp với một danh sách chứa hai số dương giống hệt nhau liên tiếp và biến đổi hai số này thành -2x.Longestbuộc các trận đấu diễn ra càng muộn càng tốt.

Quá trình này được minh họa từng bước:

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

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

Một macro mà regex tìm kiếm ngược để khớp các số liên tiếp và cộng chúng lại với nhau.

Mảng đầu vào cần phải là một số trên mỗi dòng. Định dạng này giúp tôi tiết kiệm các nét, rất hay, nhưng lý do thực sự là để làm việc xung quanh các kết hợp regex chồng chéo. Đưa ra chuỗi 222, nếu bạn /22sẽ chỉ khớp cặp đầu tiên, không phải cặp thứ hai chồng chéo. Các quy tắc chồng chéo là khác nhau khi hai cặp bắt đầu trên các dòng khác nhau. Trong thử thách này [2, 2, 2]trở thành [2, 4], do đó, việc ghép cặp chồng chéo là rất quan trọng.

LƯU Ý: Thử thách chỉ yêu cầu một lần vượt qua. Vì lý do đó, bạn cần phải có :set nowrapscan. Với :set wrapscantôi có thể tạo một phiên bản hoàn thành công việc trên nhiều lượt, mặc dù giải pháp này bằng văn bản sẽ không luôn luôn làm điều đó.

  • <C-@>: Thông thường, trong một dòng lệnh, để nhập một chữ <CR>mà không chạy lệnh bạn phải thoát nó bằng <C-V>. Nhưng bạn có thể gõ không <C-@>thoát và nó sẽ được coi là <C-J>/ <NL>, sẽ giống như <CR>khi bạn chạy macro chứ không phải khi bạn gõ. Hãy thử đọc :help NL-used-for-Nul.
  • @=: Tôi không thể sử dụng macro được ghi lại dễ dàng vào lúc này vì có khả năng đầu vào có thể không có cặp tương ứng. Nếu điều đó xảy ra trong khi chạy macro, tìm kiếm không thành công sẽ thất bại macro. Nhưng nếu nó xảy ra trong quá trình ghi (ẩn trước), phần còn lại của các lệnh chế độ thông thường sẽ chạy, làm hỏng tệp. Nhược điểm của @=tôi là mất một byte trong cuộc gọi đệ quy; đôi khi bạn có thể sử dụng @@như một cuộc gọi đệ quy, nhưng điều đó sẽ chạy @"từ 4 byte trước đó trong trường hợp này.
  • DJ@"<C-A>-: DJxóa dòng và đặt số (không có dòng mới) vào một thanh ghi, vì vậy tôi có thể chạy nó dưới dạng macro cho một đối số số <C-A>. Tôi phải -sau đó vì vậy tôi không có được một trận đấu thứ hai trong trường hợp như thế [4, 2, 2].

0

Perl6, 92 byte

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.