Doblar una lista por la mitad

24

Vamos a doblar una lista de enteros. El procedimiento para hacerlo es el siguiente: si la lista tiene una longitud par, haga una lista de la mitad de su longitud donde el enésimo elemento de la nueva lista es la suma del enésimo elemento de la lista anterior y el enésimo Último elemento de la lista anterior. Por ejemplo si tuviéramos la lista

[1 2 3 4 5 6 7 8]

Lo doblaríamos así

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

Si la lista tiene una longitud impar , para doblarla primero eliminamos el elemento del medio, doblarlo como si fuera par y agregar el elemento del medio al resultado.

Por ejemplo si tuviéramos la lista

[1 2 3 4 5 6 7]

Lo doblaríamos así

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

Tarea

Escriba un programa o función que tome una lista de enteros como entradas y salidas que se pliegan.

Esta es una pregunta de , por lo que las respuestas se puntuarán en bytes, con menos bytes mejor.

Implementación de muestra

Aquí hay una implementación en Haskell que define una función fque realiza un pliegue.

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

Pruébalo en línea!

Asistente de trigo
fuente
Cuando dices enteros, ¿esto incluye cero o enteros negativos?
Neil
1
@Neil Sí, lo hace.
Wheat Wizard
2
@ GrzegorzPuławski No debe ordenar la lista. Se permite cualquier colección ordenada, por ejemplo, vector o matriz.
Wheat Wizard
1
@DavidStarkey Las listas más razonables no se desbordarán con una cantidad razonable de memoria. El plegado en realidad no aumenta la suma, por lo que las listas convergerán en un singleton de la suma de la lista original.
Wheat Wizard
2
@WheatWizard No sé sobre eso, he oído que es imposible doblar una lista por la mitad más de 7 veces.
Carmeister el

Respuestas:

9

Python , 46 bytes

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

Pruébalo en línea!

Mismo largo:

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

Una solución mucho más corta funciona para listas de longitud par (30 bytes)

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

Pruébalo en línea!

Todavía estoy tratando de encontrar una forma corta de corregirlo para una longitud impar.

xnor
fuente
Oh, me asusté terriblemente ÷ _ ÷
Sr. Xcoder
La solución del "término medio" f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or ltambién tiene la misma longitud ...
ETHproductions
8

05AB1E , 5 bytes

Código

2ä`R+

Utiliza la codificación 05AB1E . Pruébalo en línea!

Explicación

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

Emojicode , 203 bytes

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

Esta fue la respuesta más dolorosa de Emojicode al código para mí. La longitud innecesaria: /

Pruébalo en línea!

Betseg
fuente
4

Japt , 21 18 16 bytes


l
íUj°V/2V w)mx

¡Pruébalo en línea!

Completamente horrible Ligeramente menos horrible gracias a @Oliver . BRB después de implementar más funciones integradas y corregir algunos errores ...

ETHproducciones
fuente
3

Gaia , 7 bytes

e2÷ev+†

Explicación

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.
Gato de negocios
fuente
2

Mathematica, 88 bytes

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

Mathematica 57 Bytes

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

Inserta un cero en el punto medio, agrega la lista a su reverso y toma la longitud adecuada.

Kelly Lowder
fuente
2

Jalea , 7 bytes

œs2U2¦S

Pruébalo en línea!

-2 gracias a ETHproductions ... y me di cuenta antes.

Erik el Outgolfer
fuente
ETH tenía razón, 7 bytes
Sr. Xcoder
@ETHproductions Gracias, aunque ya me había dado cuenta después de apagar mi computadora.
Erik the Outgolfer
2

R , 81 70 68 57 bytes

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

Pruébalo en línea!

función anónima; Devuelve el resultado.

Giuseppe
fuente
1

JavaScript (ES6), 41 bytes

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

Rick Hitchcock
fuente
1

MATL , 9 bytes

`6L&)swtn

Pruébalo en línea!

Cómo funciona

Dado un conjunto [a b c ... x y z] , [a z]se llamará el subconjunto "corteza"[b c ... y z] el "núcleo".

El código consiste en un bucle que elimina la corteza, calcula su suma y mueve el núcleo a la parte superior de la pila, listo para la próxima iteración. La condición del bucle es el número de elementos en el subconjunto central

`       % 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)
Luis Mendo
fuente
1

WendyScript , 72 bytes

<<f=>(l){<<r=[]<<b=l.size#i:0->b/2r+=l[i]+l[b-i-1]?b%2!=0r+=l[(b/2)]/>r}

f([1,2,3,4,5,6,7,8]) // => [9,9,9,9]
f([1,2,3,4,5,6,7]) // => [8,8,8,4]

Pruébalo en línea!

Felix Guo
fuente
1

C # (.NET Core) , 118111 bytes

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

El recuento de bytes también incluye

using System.Linq;

Pruébalo en línea!

Como entrada, utilice números separados por comas ( ,) o espacios. Explicación:

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
);
Grzegorz Puławski
fuente
¿Puede guardar bytes configurando la longitud a una variable y cambiando a un retorno explícito?
TheLethalCoder
@TheLethalCoder desafortunadamente es más largo
Grzegorz Puławski
1

Perl, 42 38 caracteres

sub f {@ a = mapa {$ + pop} empalme @ , 0, @ / 2; @ a, @ }

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

Intenta, por ejemplo, así:

perl -e 'my @input=(1..9); sub f{(map{$_+pop}splice@_,0,@_/2),@_}  print join(",",f(@input));
bytepusher
fuente
1
Se corrigió un error que se infiltró debido a mi apego emocional y profesional a las variables. Se niega a ser superado por JS: P
bytepusher
1

Pyth, 18 17 13 bytes

V.Tc2Q aYsN;Y

Mi enfoque original fue

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

-1 byte gracias al Sr. Xcoder

-4 bytes gracias a FryAmTheEggman

Dave
fuente
Intenta usar c2<list>para dividir una lista a la mitad. Otro comando que podría ser útil es .T.
FryAmTheEggman
17 bytes:WtQ aY+.)Q.(Q0;+Y
Sr. Xcoder
1

C ++ 17, 75 73 71 bytes

Como lambda sin nombre, aceptar un contenedor como vectoro list, regresa modificando la entrada:

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

Usando el conocido operador 'go-to' <--y el triple plus+++

Ungolfed y ejemplo:

#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);
}
Karl Napf
fuente
1

APL (Dyalog Unicode) , SBCS de 21 bytes

-3 bytes gracias a @ Adám.

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

Pruébalo en línea!

Explicación:

(⌊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
halcón vacío
fuente
Dyalog Extended, 18 bytes:+⌿(⌊2÷⍨≢)(↑↑⍮⌽⍤↓)⊢
Adám
Entrenamiento, 21 bytes: (⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢`
Adám
1

Lisp común, 106 bytes

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

Pruébalo en línea!

Renzo
fuente
0

Scala, 91 bytes

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

Mathematica , 52

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

JavaScript (ES6), 46 43 bytes

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

Guardado 3 bytes con la inspiración de Asaf .

Neil
fuente
Agradable. Puede cambiar '1 / c [0]' a '[] + c' para guardar 2 bytes.
Asaf
@Asaf En realidad creo c+c funciona para el tercer byte.
Neil
0

Java 8, 93 bytes

¡Doble dígitos! Esta es una lambda que toma un int[]y devuelve 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 sin golf

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

Bastante sencillo. Dobla la segunda mitad en su lugar en la primera mitad de la entrada y devuelve una copia de solo la primera mitad.

Sorprendentemente, la copia de la matriz en la declaración de devolución parece ser la forma más barata de manejar la peculiaridad del elemento final para entradas de longitud impar.

Jakob
fuente