Gấp một nửa danh sách


24

Chúng tôi sẽ gấp một danh sách các số nguyên. Quy trình thực hiện như sau, Nếu danh sách có độ dài chẵn, hãy lập danh sách một nửa chiều dài của nó trong đó mục thứ n của danh sách mới là tổng của mục thứ n của danh sách cũ và thứ n đến mục cuối cùng của danh sách cũ. Ví dụ: nếu chúng tôi có danh sách

[1 2 3 4 5 6 7 8]

Chúng tôi sẽ gấp nó như vậy

 [8 7 6 5]
+[1 2 3 4]
__________
 [9 9 9 9]

Nếu danh sách có độ dài lẻ , để gấp nó, trước tiên chúng ta xóa mục ở giữa, gấp nó lại như thể nó là chẵn và nối thêm mục giữa vào kết quả.

Ví dụ: nếu chúng tôi có danh sách

[1 2 3 4 5 6 7]

Chúng tôi sẽ gấp nó như vậy

 [7 6 5]
+[1 2 3]
__________
 [8 8 8]
++     [4]
__________
 [8 8 8 4]

Bài tập

Viết chương trình hoặc hàm lấy danh sách các số nguyên làm đầu vào và đầu ra mà danh sách được gấp lại.

Đây là một câu hỏi vì vậy câu trả lời sẽ được tính bằng byte, với ít byte hơn sẽ tốt hơn.

Mẫu thực hiện

Đây là một triển khai trong Haskell xác định chức năng fthực hiện một nếp gấp.

f(a:b@(_:_))=a+last b:f(init b)
f x=x

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


Khi bạn nói số nguyên, điều này bao gồm số nguyên 0 hay âm?
Neil

1
@Neil Đúng vậy.
Phù thủy lúa mì

2
@ GrzegorzPuławski Bạn không nên sắp xếp danh sách. Bất kỳ bộ sưu tập theo thứ tự được cho phép, ví dụ vector hoặc mảng.
Phù thủy lúa mì

1
@DavidStarkey Hầu hết các danh sách hợp lý sẽ không tràn bộ nhớ hợp lý. Folding không thực sự tăng tổng nên các danh sách sẽ hội tụ thành một số đơn của tổng danh sách ban đầu.
Thuật sĩ lúa mì

2
@WheatWizard Tôi không biết về điều đó, tôi đã nghe nói không thể gấp bất kỳ danh sách nào trong hơn một nửa hơn 7 lần.
Carmeister

Câu trả lời:


9

Python , 46 byte

f=lambda l:l[1:]and[l[0]+l[-1]]+f(l[1:-1])or l

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

Cùng chiều dài:

f=lambda l:l[1:]and[l.pop(0)+l.pop()]+f(l)or l

Một giải pháp ngắn hơn nhiều hoạt động cho các danh sách có độ dài chẵn (30 byte)

lambda l:[x+l.pop()for x in l]

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

Tôi vẫn đang cố gắng tìm một cách ngắn để sửa nó cho độ dài lẻ.


Ồ, tôi đã hết thời _ ÷
Ông Xcoder

Giải pháp "trung dung" f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or lcũng có cùng độ dài ...
Sản phẩm ETH

8

05AB1E , 5 byte

2ä`R+

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!

Giải trình

2ä        # Split the list into two pieces
  `       # Flatten the stack
   R      # Reverse the second element from the list
    +     # Vectorized addition

8

Biểu tượng cảm xúc , 203 byte

🐋🍨🍇🐖🔢🍇🔂i⏩0➗🐔🐕2🍇😀🔡➕🍺🔲🐽🐕i🚂🍺🔲🐽🐕➖🐔🐕➕1i🚂10🍉🍊😛1🚮🐔🐕2🍇😀🔡🍺🔲🐽🐕➗🐔🐕2🚂10🍉🍉🍉

Đây là câu trả lời Emojicode đau đớn nhất để viết mã cho tôi. Độ dài không cần thiết: /

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



3

Gaia , 7 byte

e2÷ev+†

Giải trình

e        Eval the input (push the list).
 2÷      Split it in half. The first half will be longer for an odd length.
   e     Dump the two halves on the stack.
    v    Reverse the second.
     +†  Element-wise addition. If the first half has an extra element, it is simply appended.

2

Toán học, 88 byte

(d=Array[s[[#]]+s[[-#]]&,x=⌊t=Length[s=#]/2⌋];If[IntegerQ@t,d,d~AppendTo~s[[x+1]]])&

2

Toán học 57 byte

(#+Reverse@#)[[;;d-1]]&@Insert[#,0,d=⌈Length@#/2⌉+1]&

Chèn một số 0 ở điểm giữa, thêm danh sách ngược lại và lấy độ dài phù hợp.










1

MATL , 9 byte

`6L&)swtn

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

Làm thế nào nó hoạt động

Cho một mảng [a b c ... x y z], hãy [a z]gọi là phân đoạn "lớp vỏ" và phân [b c ... y z]đoạn "lõi".

Mã này bao gồm một vòng lặp loại bỏ lớp vỏ, tính tổng của nó và di chuyển lõi lên đỉnh của ngăn xếp, sẵn sàng cho lần lặp tiếp theo. Điều kiện vòng lặp là số lượng phần tử trong phân đoạn lõi

`       % Do...while
  6L    %   Push [2 -1+1j]. As an index, this is interpreted as 2:end-1
  &)    %   2-output reference indexing: pushes a subarray with the indexed 
        %   elements (core) and another with the ramaining elements (crust)
  s     %   Sum of (crust) subarray
  w     %   Swap. Moves the core subarray to the top
  t     %   Duplicate
  n     %   Number of elements.
        % End (implicit). Procced with next iteration if top of the stack is
        % nonzero; else exit
        % Display stack (implicit)


1

C # (.NET Core) , 118 111 byte

a=>a.Reverse().Zip(a,(c,d)=>c+d).Take(a.Length/2).Concat(a.Skip(a.Length/2).Take(a.Length%2))

Số lượng byte cũng bao gồm

using System.Linq;

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

Là đầu vào, vui lòng sử dụng các số được phân tách bằng dấu phẩy ( ,) hoặc dấu cách. Giải trình:

a =>                                  // Take one input parameter (array)
a.Reverse()                           // Reverse it
.Zip(a, (c, d) => c + d)              // Take every corresponding member of reversed
                                      //    and original, and add them together
.Take(a.Length / 2)                   // Get first half of the collection
.Concat(                              // Add another collection
    a.Skip(a.Length / 2)              // Take input and leave out first half of it
    .Take(a.Length % 2)               // If length is odd, take first element (so the middle)
                                      //    otherwise create an empty collection
);

Bạn có thể lưu byte bằng cách đặt độ dài cho một biến và chuyển sang trả về rõ ràng không?
TheLethalCoder

@TheLethalCoder không may là nó dài hơn
Grzegorz Puławski

1

Perl, 42 38 ký tự

phụ f {@ a = map {$ + pop} mối nối @ , 0, @ / 2; @ a, @ }

sub f{(map{$_+pop}splice@_,0,@_/2),@_} 

Hãy thử ví dụ như vậy:

perl -e 'my @input=(1..9); sub f{(map{$_+pop}splice@_,0,@_/2),@_}  print join(",",f(@input));

1
Đã sửa lỗi xuất hiện do sự gắn bó tình cảm và chuyên nghiệp của tôi với các biến. Từ chối bị vượt qua bởi JS: P
bytepizer

1

Bình thường, 18 17 13 byte

V.Tc2Q aYsN;Y

Cách tiếp cận ban đầu của tôi là

WtQ aY+.)Q.(Q0;+Y

-1 byte nhờ ông Xcoder

-4 byte nhờ FryAmTheEggman


Hãy thử sử dụng c2<list>để chia một danh sách một nửa. Một lệnh khác có thể hữu ích là .T.
FryAmTheEggman


1

C ++ 17, 75 73 71 byte

Như lambda không tên, chấp nhận một container như vector hoặc list, trả về thông qua sửa đổi đầu vào:

[](auto&L){for(auto a=L.begin(),b=L.end();a<--b;L.pop_back())*a+++=*b;}

Sử dụng toán tử 'go-to' nổi tiếng <--và bộ ba cộng+++

Ungolfed và ví dụ:

#include<iostream>
#include<vector>

using namespace std;

auto f=
[](auto&L){
 for(
  auto a=L.begin(),b=L.end();
  a<--b;
  L.pop_back()
 )
 *a+++=*b;
}
;

void test(auto L) {
 for(auto x:L)cout << x << ", ";
 cout << endl;
 f(L);
 for(auto x:L)cout << x << ", ";
 cout << endl << endl;
}

int main() { 
 vector<int> A = {1,2,3,4,5,6,7,8}, B = {1,2,3,4,5,6,7};
 test(A);
 test(B);
}


1

APL (Dyalog Unicode) , 21 byte SBCS

-3 byte nhờ @ Adám.

(⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢

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

Giải trình:

(⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢   Monadic function train
(⌊2÷⍨≢)                   Left portion:
                         Take the length of the input...
  2÷⍨                     Divide it by two...
                         And floor it. This gives our midpoint index. Call it "X"
                         Right portion: return the original input. Call it "Y"
       (↑{+⌿↑⍺⍵}∘⌽↓)    Midddle portion: takes X and Y as arguments
                        Take and drop Y by X. Essentially splits Y in half
                          Presents the two halves to the next function
                 ∘⌽      Reverse the second half
         {+⌿↑⍺⍵}        Final function, takes first half and reversed second half
              ⍺⍵         Construct a nested list of first and second halves...
                        ...and "mix" them into a matrix. Has the nice property that
                         it will pad the first half with a zero if needed.
          +⌿            Sum the matrix along the columns, return resulting vector

Dyalog mở rộng, 18 byte:+⌿(⌊2÷⍨≢)(↑↑⍮⌽⍤↓)⊢
Adám




0

Scala, 91 byte

(s:Seq[Int])=>(s.take(s.size/2),s.reverse).zipped.map(_+_)++s.drop(s.size/2).take(s.size%2)

0

Toán học , 52

(a=#;i=0;(i++;a[[i;;-i]]*=x)&/@a;(Tr@a+O@x^i)[[3]])&

0

JavaScript (ES6), 46 43 byte

f=(a,[b,...c]=a)=>c+c?[b+c.pop(),...f(c)]:a

Đã lưu 3 byte với cảm hứng từ Asaf .


Tốt đẹp. Bạn có thể thay đổi '1 / c [0]' thành '[] + c' để lưu 2 byte.
Asaf

@Asaf Thật ra tôi nghĩ c+clàm việc cho byte thứ ba.
Neil

0

Java 8, 93 byte

Hai chữ số! Đây là một lambda có một int[]và trả lại một int[].

l->{int n=l.length,i=0;for(;i<n/2;)l[i]+=l[n-++i];return java.util.Arrays.copyOf(l,n/2+n%2);}

Lambda

l -> {
    int n = l.length, i = 0;
    for (; i < n / 2; )
        l[i] += l[n - ++i];
    return java.util.Arrays.copyOf(l, n / 2 + n % 2);
}

Khá đơn giản. Nó gập nửa thứ hai vào vị trí của nửa đầu vào và trả về một bản sao của nửa đầu.

Đáng ngạc nhiên, bản sao mảng trong câu lệnh return dường như là cách rẻ nhất để xử lý phần tử cuối cùng cho các đầu vào có độ dài lẻ.


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.