Piega un elenco a metà


24

Stiamo per piegare un elenco di numeri interi. La procedura per farlo è la seguente, se l'elenco è di lunghezza pari, crea un elenco della metà della sua lunghezza in cui l'ennesimo elemento del nuovo elenco è la somma dell'ennesimo elemento del vecchio elenco e dall'ennesimo al ultimo elemento del vecchio elenco. Ad esempio se avessimo l'elenco

[1 2 3 4 5 6 7 8]

Vorremmo piegarlo in questo modo

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

Se l'elenco ha una lunghezza dispari , per piegarlo rimuoviamo prima l'elemento centrale, piegalo come se fosse pari e aggiungiamo l'elemento centrale al risultato.

Ad esempio se avessimo l'elenco

[1 2 3 4 5 6 7]

Vorremmo piegarlo in questo modo

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

Compito

Scrivi un programma o una funzione che accetta un elenco di numeri interi come input e output che l'elenco è piegato.

Questa è una domanda di quindi le risposte verranno classificate in byte, con un numero minore di byte migliori.

Implementazione di esempio

Ecco un'implementazione in Haskell che definisce una funzione fche esegue una piega.

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

Provalo online!


Quando dici numeri interi, questo include zero o negativi?
Neil,

1
@Neil Sì.
Wheat Wizard

2
@ GrzegorzPuławski Non è necessario ordinare l'elenco. È consentita qualsiasi raccolta ordinata, ad es. Vettore o matrice.
Wheat Wizard

1
@DavidStarkey Gli elenchi più ragionevoli non traboccano con una quantità ragionevole di memoria. La piegatura in realtà non aumenta la somma, quindi gli elenchi convergeranno in un singleton della somma dell'elenco originale.
Wheat Wizard

2
@WheatWizard Non lo so, ho sentito che è impossibile piegare qualsiasi elenco a metà più di 7 volte.
Carmeister,

Risposte:


9

Python , 46 byte

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

Provalo online!

Stessa lunghezza:

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

Una soluzione molto più breve funziona per elenchi di lunghezza pari (30 byte)

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

Provalo online!

Sto ancora cercando di trovare un modo breve per correggerlo per una lunghezza dispari.


Oh, mi sono terribilmente superato per gran lunga ÷ _ ÷
Mr. Xcoder il

Anche la soluzione "via di mezzo" f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or lha la stessa lunghezza ...
ETHproductions

8

05AB1E , 5 byte

Codice

2ä`R+

Utilizza la codifica 05AB1E . Provalo online!

Spiegazione

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

8

Emojicode , 203 byte

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

Questa è stata la risposta Emojicode più dolorosa al codice per me. La lunghezza non necessaria: /

Provalo online!



3

Gaia , 7 byte

e2÷ev+†

Spiegazione

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

Mathematica, 88 byte

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

2

Mathematica 57 byte

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

Inserisce uno zero nel punto medio, aggiunge l'elenco al suo rovescio e prende la lunghezza appropriata.





2

R , 81 70 68 57 byte

function(l)c((l+rev(l))[1:(w=sum(l|1)/2)],l[w+1][!!w%%1])

Provalo online!

funzione anonima; restituisce il risultato.




1

JavaScript, 75 71 byte

a=>a.slice(0,n=a.length/2).map(b=>b+a[--z],z=n*2).concat(n%1?a[n|0]:[])

Provalo online

Risparmiato 2 byte grazie a ETHproductions


1

JavaScript (ES6), 41 byte

f=a=>1/a[1]?[a.shift()+a.pop(),...f(a)]:a


1

MATL , 9 byte

`6L&)swtn

Provalo online!

Come funziona

Dato un array [a b c ... x y z], [a z]chiamiamolo il subarray "crosta" e[b c ... y z] il "core".

Il codice consiste in un ciclo che rimuove la crosta, calcola la sua somma e sposta il nucleo in cima allo stack, pronto per la successiva iterazione. La condizione del loop è il numero di elementi nel subarray principale

`       % 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))

Il conteggio dei byte include anche

using System.Linq;

Provalo online!

Come input si prega di utilizzare numeri separati da virgole ( ,) o spazio. Spiegazione:

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

È possibile salvare byte impostando la lunghezza su una variabile e passando a un ritorno esplicito?
TheLethalCoder

@TheLethalCoder purtroppo è più lungo
Grzegorz Puławski

1

Perl, 42 38 caratteri

sub f {@ a = map {$ + pop} splice @ , 0, @ / 2; @ a, @ }

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

Prova ad esempio in questo modo:

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

1
Risolto un errore che si insinuava a causa del mio attaccamento emotivo e professionale alle variabili. Rifiuta di essere superato da JS: P
bytepusher il

1

Pyth, 18 17 13 byte

V.Tc2Q aYsN;Y

Il mio approccio originale era

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

-1 byte grazie a Mr. Xcoder

-4 byte grazie a FryAmTheEggman


Prova a usare c2<list>per dividere un elenco a metà. Un altro comando che potrebbe essere utile è .T.
FryAmTheEggman,


1

C ++ 17, 75 73 71 byte

Come lambda senza nome, accettando un contenitore come vectoro list, ritorna modificando l'input:

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

Utilizzando il noto operatore 'vai a' <--e il triplo plus+++

Ungolfed ed esempio:

#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) , SBCS da 21 byte

-3 byte grazie a @ Adám.

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

Provalo online!

Spiegazione:

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



1

Lisp comune, 106 byte

(lambda(l)(setf(values a b)(floor(length l)2))`(,@(#1=subseq(mapcar'+ l(reverse l))0 a),@(#1#l a(+ a b))))

Provalo online!



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

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

Salvato 3 byte con ispirazione da Asaf .


Bello. È possibile modificare '1 / c [0]' in '[] + c' per salvare 2 byte.
Asaf,

@Asaf In realtà penso che funzioni c+cper il terzo byte.
Neil,

0

Java 8, 93 byte

Doppie cifre! Questo è un lambda che prende un int[]e restituisce un 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 ungolfed

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

Abbastanza semplice. Piega la seconda metà in posizione sulla prima metà dell'input e restituisce una copia solo della prima metà.

Sorprendentemente, la copia dell'array nell'istruzione return sembra essere il modo più economico per gestire la stranezza dell'elemento finale per input di lunghezza dispari.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.