Adición de la pirámide invertida ... ¡INVERSA!


22

La adición de la pirámide invertida es el proceso de tomar una lista de números y sumarlos consecutivamente hasta llegar a un número.

Cuando se le dan los números 2, 1, 1, ocurre el siguiente proceso:

 2   1   1
   3   2 
     5

Esto termina en el número 5.


TU TAREA

Dado el lado derecho de una pirámide invertida (ascendente), escriba un programa o función que devolverá la lista original.

Nuevo desafío adicional : intente hacer esto en menos de O (n ^ 2)

EJEMPLO

f([5, 2, 1]) => [2, 1, 1]
f([84,42,21,10,2]) => [4,7,3,8,2]

NOTA: La Pirámide invertida nunca estará vacía y siempre consistirá en enteros positivos SOLAMENTE.


66
¡Bienvenido a PP&CG! Este desafío es decente, aunque podría mejorarse. Recomiendo publicar sus desafíos en el Sandbox primero para mejorar la publicación antes de ponerla en main.
Tau

13
Percepción gratuita de que no puedo encontrar un idioma más corto en:
F([una,si,do,re,mi])=[1-4 46 6-4 410 01-33-10 00 01-210 00 00 01-10 00 00 00 01][unasidoremi]
Lynn

44
Solo para tu información, esto es lo mismo que el kata CodeWars .
ggorlen

66
@ggorlen lo sé. Soy el que hizo el kata :)
Whimpers

8
Try doing this in less than O(n)¿seguramente es imposible asignar una matriz de tamaño n o cambiar elementos O (n) en ella más rápido que la complejidad O (n)?
mi pronombre es monicareinstate

Respuestas:


17

JavaScript (ES6),  62 58 49  46 bytes

Guardado 3 bytes gracias a @Oliver

Devuelve la lista como una cadena separada por comas.

f=a=>+a||f(a.map(n=>a-(a=n),a=a.shift()))+[,a]

Pruébalo en línea!

Comentado

f = a =>              // f = recursive function taking the input list a[]
  +a                  // if a[] consists of a single positive integer:
                      //   stop recursion and return this integer
  ||                  // else:
    f(                //   do a recursive call to f:
      a.map(n =>      //     for each value n in a[]:
        a - (a = n),  //       yield the difference between the previous value and n
                      //       and update a to n
        a = a.shift() //       start by removing the first element and saving it in a
                      //       (because of the recursion, it's important here to reuse
                      //       a variable which is defined in the scope of f)
      )               //     end of map()
    )                 //   end of recursive call
    + [, a]           //   append the last entry from a[]

@ Oliver,
Shaggy



6

TI-BASIC, 54 bytes

Ans→L₁:dim(L₁→dim(L₂:While 1-Ans:L₁(Ans→L₂(Ans:-ΔList(L₁→L₁:dim(Ans:End:L₁(Ans→L₂(Ans:L₂

La entrada es la lista del lado derecho del triángulo Ans, como se describe en el desafío.
La salida es la fila superior de dicho triángulo.

Ejemplos:

{5,2,1
         {5 2 1}
prgmCDGF19
         {2 1 1}
{84,42,21,10,2
 {84 42 21 10 2}
prgmCDGF19
     {4 7 3 8 2}

Explicación:
Esta solución abusa del hecho de que el triángulo formado usando el lado derecho del triángulo como el inicio termina siendo el cambio en cada elemento.

En otras palabras,

2 1 1
 3 2
  5

se convierte en:

5 2 1
 3 1
  2

Por lo tanto, la lista resultante es el lado derecho de este nuevo triángulo, que puede formarse estableciendo el último elemento en el índice de la longitud de su lista principal en la lista resultante.

Ans→L₁          ;store the input list in L₁
dim(L₁→dim(L₂   ;set the length of L₂ to the length of L₁
While 1-Ans     ;while the L₁'s length is not 1
L₁(Ans→L₂(Ans   ;set the last element of L₁ to the corresponding index in L₂
-ΔList(L₁→L₁    ;get the change in each element, then negate
                ; (elements are in descending order so the change in each
                ;  element will be negative)
                ; and store the resulting list in L₁
dim(Ans         ;leave the length of L₁ in "Ans"
End
L₁(Ans→L₂(Ans   ;set the element again
                ; (needed for final step)
L₂              ;leave L₂ in "Ans"
                ;implicit print of "Ans"

Nota: TI-BASIC es un lenguaje tokenizado. El recuento de caracteres no es igual al recuento de bytes.


4

Jalea , 6 bytes

ṚIƬZḢṚ

Un enlace monádico que acepta una lista de enteros que produce una lista de enteros.

Pruébalo en línea!

¿Cómo?

Construye todo el triángulo y luego extrae los elementos requeridos.

ṚIƬZḢṚ - Link: list of integers          e.g.  [84,42,21,10,2]
Ṛ      - reverse                               [2,10,21,42,84]
  Ƭ    - collect & apply until a fixed point:
 I     -   incremental differences            [[2,10,21,42,84],[8,11,21,42],[3,10,21],[7,11],[4],[]]
   Z   - transpose                            [[2,8,3,7,4],[10,11,10,11],[21,21,21],[42,42],[84]]
    Ḣ  - head                                  [2,8,3,7,4]
     Ṛ - reverse                               [4,7,3,8,2]

Tenía una solución casi idéntica pero con Us en lugar de !
Nick Kennedy el

IƬUZḢAtrabajaría con la pregunta dada también; Me pregunto si hay un byte guardado en alguna parte ...
Jonathan Allan

ạƝƬZṪ€funciona también pero nuevamente es un seis.
Nick Kennedy el

Sí, noté esa variante; Tengo menos esperanzas ahora.
Jonathan Allan

Acabo de publicar un 5-byter, pero es un poco diferente a su enfoque con respecto a la parte después de la construcción de la pirámide.
Erik the Outgolfer

4

MathGolf , 14 11 bytes

xÆ‼├│?;∟;]x

Pruébalo en línea!

Explicación

x             reverse int/array/string
 Æ     ∟      do while true without popping using 5 operators
  ‼           apply next 2 operators to TOS
   ├          pop from left of list
    │         get differences of list
     ?        rot3
      ;       discard TOS (removes rest from ├ command)
              loop ends here
        ;     discard TOS (removes empty array from stack)
         ]    wrap stack in array
          x   reverse array



3

Pari / GP , 36 bytes

Basado en el comentario de @Lynn :

F([una,si,do,re,mi])=[1-4 46 6-4 410 01-33-10 00 01-210 00 00 01-10 00 00 00 01][unasidoremi]

Pari / GP tiene una matriz incorporada para Pascal, y su inverso es exactamente la matriz que necesitamos:

[10 00 00 00 0110 00 00 01210 00 013310 014 46 64 41]-1=[10 00 00 00 0-110 00 00 01-210 00 0-13-310 01-4 46 6-4 41]

a->r=Vecrev;r(r(a)/matpascal(#a-1)~)

Pruébalo en línea!


3

R , 69 67 bytes

function(n,x=sum(n|1):1-1,`[`=outer)(x[x,choose]*(-1)^x[x,"+"])%*%n

Pruébalo en línea!

Devuelve un vector de columna.

-2 bytes gracias a Kirill L.

También basado en el comentario de Lynn :

F([una,si,do,re,mi])=[1-4 46 6-4 410 01-33-10 00 01-210 00 00 01-10 00 00 00 01][unasidoremi]

Es más largo que la otra respuesta R, pero fue un enfoque interesante para tomar y tratar de jugar al golf.


2

Javascript (ES6), 127 bytes

f=a=>{for(e=[a],a=[a[l=a.length-1]],i=0;i<l;i++){for(e.push(g=[]),j=-1;j<l;)g.push(e[i][j]-e[i][++j]);r.unshift(g[j])}return r}

Código original

function f(a){
  var e=[a];
  var r=[a[a.length-1]];
  for (var i=1;i<a.length;i++){
    var g=[];
    for (var j=0;j<a.length;j++){
      g.push(e[i-1][j-1]-e[i-1][j]);
    }
    e.push(g);
    r.unshift(g[j-1]);
  }
  return r;
}

Oh, perdí como ... mucho ... a la respuesta anterior ...



2

05AB1E , 12 11 bytes

R.¥.Γ¥}¨ζнR

Puerto de @JonathanAllan jalea respuesta 's , aunque estoy jalea sobre órdenes internas más convenientes de jalea en este caso. ;)
-1 byte gracias a @Emigna .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

R            # Reverse the (implicit) input-list
             #  i.e. [16,7,4,3] → [3,4,7,16]
           # Undelta it (with leading 0)
             #  → [0,3,7,14,30]
    }      # Continue until the result no longer changes, and collect all steps:
     ¥       #  Get the deltas / forward differences of the current list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4],[]]
       ¨     # Remove the trailing empty list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4]]
        ζ    # Zip/transpose; swapping rows/column (with space as default filler)
             #  → [[3,1,2,4],[4,3,6," "],[7,9," "," "],[16," "," "," "]]
         н   # Only leave the first inner list
             #  → [3,1,2,4]
          R  # Revert it back
             #  → [4,2,1,3]
             # (after which it's output implicitly as result)

2
Puede guardar un byte R.¥.Γ¥}¨comenzando desde la lista cuyo delta es la entrada.
Emigna

@Emigna Ah, undelta en un bucle con deltas para guardar un byte en el antecedente. :) ¡Gracias!
Kevin Cruijssen


2

Perl 6 , 37 bytes

{[R,]($_,{@(.[]Z-.skip)}...1)[*;*-1]}

Pruébalo en línea!

Se reduce repetidamente por sustracción por elementos, y luego devuelve el último número de cada lista a la inversa.

Explicación:

{                                  }  # Anonymous code block
      $_,               ...   # Create a sequence starting from the input
         {             }      # Where each element is
            .[]Z-.skip          # Each element minus the next element
          @(          )         # Arrayified
                           1  # Until the list has one element left
 [R,]                                # Reverse the sequence
     (                     )[*;   ]  # For every list
                               *-1   # Take the last element



1

Carbón de leña , 19 bytes

Fθ«PI§θ±¹↑UMθ⁻§θ⊖λκ

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

Fθ«

Recorra una vez por cada término en la lista original.

PI§θ±¹↑

Imprima el último término de la lista, pero mueva el cursor al comienzo de la línea anterior, de modo que los términos se muestren en orden inverso.

UMθ⁻§θ⊖λκ

Calcule los deltas, insertando un valor ficticio al principio para que podamos usar una operación que no cambie la longitud de la lista.




1

C, 76 bytes

i=0;int*f(int*a,int n){for(;i<n;a[i++]=a[i]-a[i+1]);if(!n)return a;f(a,n-1);}  

entrada : (*a = pointer to array, n = last element's index of that array)
salida :return int* = output

Explicación
va del lado derecho hacia arriba, ya que los últimos elementos son los mismos tanto en la entrada como en la salida, la función interior del bucle simplemente encuentra los siguientes números más altos en el triángulo que gradualmente llega a la parte superior dejando la respuesta intacta al final.

sin golf (de C ++)

#include <iostream>
#define SIZE_F 5

int*recFind(int*a, int n) {
    int i = 0;
    while (i < n)
        a[i++] = a[i] - a[i+1];
    if (!n) return a;
        recFind(a, n - 1);
}
int main()
{
    int first[SIZE_F],*n;
    for (int i = 0; i < SIZE_F; i++)
        std::cin >> first[i];

    n = recFind(first, SIZE_F - 1);//size - 1
    for (int i = 0; i < SIZE_F; i++)
        std::cout << n[i];
}

1

Japt , 11 9 bytes

Nc¡=äa
yÌ

Intentalo

2 bytes guardados gracias a Oliver.

12 11 bytes

_äa}hUÊN yÌ

Intentalo

1 byte guardado gracias a Oliver.



@ Oliver, no pensar en usarlo y(f)es bastante malo, ¡pero olvidar completamente la nueva línea es imperdonable! Se actualizará en breve. Gracias :)
Shaggy

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.