Dobre uma lista ao meio


24

Vamos dobrar uma lista de números inteiros. O procedimento para fazer isso é o seguinte: Se a lista tiver tamanho uniforme, faça uma lista com metade do comprimento, onde o enésimo item da nova lista é a soma do enésimo item da lista antiga e do enésimo ao último item da lista antiga. Por exemplo, se tivéssemos a lista

[1 2 3 4 5 6 7 8]

Nós dobraríamos assim

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

Se a lista tiver um comprimento ímpar , para dobrá-la, primeiro removemos o item do meio, dobre-o como se fosse par e anexemos o item do meio ao resultado.

Por exemplo, se tivéssemos a lista

[1 2 3 4 5 6 7]

Nós dobraríamos assim

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

Tarefa

Escreva um programa ou função que tenha uma lista de números inteiros como entrada e saídas que listam como dobradas.

Esta é uma questão de para que as respostas sejam pontuadas em bytes, com menos bytes sendo melhores.

Implementação de amostra

Aqui está uma implementação no Haskell que define uma função fque executa uma dobra.

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

Experimente online!


Quando você diz números inteiros, isso inclui números zero ou negativos?
315 Neil

11
@ Neil Sim, sim.
Assistente de trigo

2
@ GrzegorzPuławski Você não deve classificar a lista. Qualquer coleção ordenada é permitida, por exemplo, vetor ou matriz.
Assistente de trigo

11
@DavidStarkey A maioria das listas razoáveis ​​não transbordará com uma quantidade razoável de memória. Dobrar, na verdade, não aumenta a soma, portanto as listas convergem para um singleton da soma da lista original.
Assistente de trigo

2
@WheatWizard Eu não sei, ouvi dizer que é impossível dobrar qualquer lista pela metade mais de 7 vezes.
Carmeister

Respostas:


9

Python , 46 bytes

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

Experimente online!

Mesmo comprimento:

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

Uma solução muito mais curta funciona para listas de tamanho par (30 bytes)

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

Experimente online!

Ainda estou tentando encontrar uma maneira curta de corrigi-lo por comprimentos ímpares.


Oh, eu fiquei terrivelmente outgolfed ÷ _ ÷
Mr. Xcoder

A solução "meio termo" f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or ltambém tem o mesmo comprimento ...
ETHproductions

8

05AB1E , 5 bytes

Código

2ä`R+

Usa a codificação 05AB1E . Experimente online!

Explicação

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

8

Emojicode , 203 bytes

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

Esta foi a resposta mais dolorosa do Emojicode para codificar para mim. O comprimento desnecessário: /

Experimente online!



3

Gaia , 7 bytes

e2÷ev+†

Explicação

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 bytes

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

2

Mathematica 57 Bytes

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

Insere um zero no ponto médio, adiciona a lista ao seu reverso e leva o comprimento apropriado.








1

JavaScript, 75 71 bytes

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

Experimente online

Economizou 2 bytes graças a ETHproductions


1

JavaScript (ES6), 41 bytes

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


1

MATL , 9 bytes

`6L&)swtn

Experimente online!

Como funciona

Dada uma matriz [a b c ... x y z], vamos [a z]chamar de sub- matriz "crosta" e[b c ... y z] "core".

O código consiste em um loop que remove a crosta, calcula sua soma e move o núcleo para o topo da pilha, pronto para a próxima iteração. A condição do loop é o número de elementos na sub-matriz principal

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

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

A contagem de bytes também inclui

using System.Linq;

Experimente online!

Como entrada, use números separados por vírgulas ( ,) ou espaço. Explicação:

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

Você pode salvar bytes definindo o comprimento para uma variável e alternando para um retorno explícito?
TheLethalCoder

@TheLethalCoder, infelizmente, é mais longo
Grzegorz Puławski

1

Perl, 42 38 caracteres

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

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

Tente, por exemplo, o seguinte:

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

11
Corrigido um erro que entrava devido ao meu apego emocional e profissional às variáveis. Recuse-se a ser derrotado por JS: P
bytepusher

1

Pitão, 18 17 13 bytes

V.Tc2Q aYsN;Y

Minha abordagem original foi

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

-1 byte graças ao Sr. Xcoder

-4 bytes graças a FryAmTheEggman


Tente usar c2<list>para dividir uma lista ao meio. Outro comando que pode ser útil é .T.
FryAmTheEggman 31/07


1

C ++ 17, 75 73 71 bytes

Como lambda sem nome, aceitar um contêiner como vector ou listretorna com a modificação da entrada:

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

Usando o conhecido operador 'go-to' <--e o triple plus+++

Ungolfed e exemplo:

#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 de 21 bytes

-3 bytes graças a @ Adám.

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

Experimente online!

Explicação:

(⌊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 comum, 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))))

Experimente online!



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)

0

Mathematica , 52

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

0

JavaScript (ES6), 46 43 bytes

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

Salvou 3 bytes com inspiração em Asaf .


Agradável. Você pode alterar '1 / c [0]' para '[] + c' para economizar 2 bytes.
Asaf

@Asaf Na verdade, acho que c+cfunciona para o terceiro byte.
315 Neil

0

Java 8, 93 bytes

Dois digitos! Este é um lambda que pega um int[]e retorna um 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);
}

Bem direto. Dobra a segunda metade no lugar da primeira metade da entrada e retorna uma cópia apenas da primeira metade.

Surpreendentemente, a cópia da matriz na declaração de retorno parece ser a maneira mais barata de lidar com a peculiaridade do elemento final para entradas de tamanho ímpar.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.