Expansión de matriz estilo Fibonacci

25

Para cada fila y luego columna de una matriz, podemos agregar una entrada adicional con la suma de las dos últimas entradas en esa fila o columna. Por ejemplo con la siguiente matriz de entrada:

[ 1 1 1 ]
[ 2 3 4 ]

La matriz resultante sería:

[ 1 1 1 2 ]
[ 2 3 4 7 ]
[ 3 4 5 9 ]

Dada una entrada de un entero N y una matriz [X, Y] de tamaño de al menos 2x2, realice la expansión N veces anterior y genere el resultado. La matriz resultante siempre será de tamaño [X + N, Y + N].

Ejemplos:

Input:                     Output:

2, [ 0 0 ]                 [ 0 0 0 0 ]
   [ 0 0 ]                 [ 0 0 0 0 ]
                           [ 0 0 0 0 ]
                           [ 0 0 0 0 ]


3, [ 1 1 1 ]               [ 1  1  1  2  3  5 ]
   [ 2 3 4 ]               [ 2  3  4  7 11 18 ]
                           [ 3  4  5  9 14 23 ]
                           [ 5  7  9 16 25 41 ]
                           [ 8 11 14 25 39 64 ]
Trauma digital
fuente

Respuestas:

8

MATL , 13 14 15 16 20 21 bytes

2*:"!tP2:Y)sv

¡Gracias @Zgarb por eliminar 1 byte!

Pruébalo en línea!

2*         % implicitly input number N and multiply by 2
:          % create vector [1,2,...,2*N]
"          % for loop: do this 2*N times
  !        %   transpose. Implicitly input matrix in the first iteration
  tP       %   duplicate and flip vertically
  2:       %   vector [1,2]
  Y)       %   pick submatrix formed by the first two rows
  s        %   sum of each column
  v        %   append as a new row
           % end for
           % implicit display
Luis Mendo
fuente
1
No sé MATL, pero ¿no sería más corto recorrer los 2Ntiempos que recorrer dos Nveces?
Zgarb
@ Zgarb ¡Por supuesto! ¿Cómo extrañé eso? ¡¡Gracias!!
Luis Mendo
¿MATL tiene una función incorporada para duplicar un número?
Zgarb
@ Zgarb No. Necesitas 2*(notación postfix). Tal vez debería tener un carácter integrado, se usa con frecuencia. También 2^(cuadrado). Pero me estoy quedando sin espacio de código :-)
Luis Mendo
6

J, 19 bytes

(v"1@v=.,[+&{:}:)^:

Esto define un adverbio, que toma el número a su izquierda y produce un verbo que toma la matriz a su derecha. Para el segundo ejemplo, da

  3 ((v"1@v=.,[+&{:}:)^:) 2 3 $ 1 1 1 2 3 4
1  1  1  2  3  5
2  3  4  7 11 18
3  4  5  9 14 23
5  7  9 16 25 41
8 11 14 25 39 64

Explicación

(v"1@v=.,[+&{:}:)^:  Left argument x, right argument y
(               )^:  Repeat x times:
     v=.               Bind the following verb to v, and apply to y:
         [    }:         y and y-without-last-item
          +&{:           Sum of their last items
        ,                Append that to y
                       (v automatically threads to rows)
 v"1@                  then apply v to columns
Zgarb
fuente
3

K, 23 bytes

{x(2({x,+/-2#x}'+)/)/y}

En acción:

  {x(2({x,+/-2#x}'+)/)/y}[3;(1 1 1;2 3 4)]
(1 1 1 2 3 5
 2 3 4 7 11 18
 3 4 5 9 14 23
 5 7 9 16 25 41
 8 11 14 25 39 64)

Probarlo aquí .

JohnE
fuente
todavía funciona si quita el {xy}
inicio
3

Jalea, 15 13 12 bytes

-1 byte por @Dennis

ṫ-S;@"Z
ÇḤ}¡

Al igual que la respuesta MATL de @ LuisMendo, esto transpone la matriz antes de hacer la transformación a lo largo de un eje. Por lo tanto, necesitamos llamar a la función 2 * n veces.

ṫ-S;@"Z       Helper link. Input: x (2D array)
 -              Numeric literal: -1
ṫ               Get x[-1:], i.e. last two rows in x
  S             Sum
   ;@"          Append each to x. " is 'zipWith'; @ switches argument order.
      Z         Transpose the array.
ÇḤ}¡          Main link. Input: a, n
Ç               Call the last link on a
 Ḥ}             2n
   ¡            times.

Probarlo aquí .

lirtosiast
fuente
2

ES6, 134 bytes

(n,a)=>[...a.map(b=>[...b,...Array(n)].map(c=>(c<1/0?0:c=a+d,d=a,a=c))),...Array(n)].map(b=>(b?0:b=[...a].map((c,j)=>c+d[j]),d=a,a=b))

Explicación:

(n,a)=> // arguments n is number to expand, a is original array
    [...
        a.map(b=> // for each row in a
            [...b,...Array(n)] // append n elements to the row
            .map(c=>(c<1/0?0:c=a+d,d=a,a=c))) // scan the elements and fill the new ones by summing the previous two
        ,...Array(n)] // append n rows
    .map(b=>(b?0:b=[...a].map((c,j)=>c+d[j]),d=a,a=b)) // scan the rows and fill the new rows by summing the previous two rows
Neil
fuente
2

Haskell, 67 bytes

o%m=m++[o(+)(last m)$last$init m]
(!!).iterate(map(id%).(zipWith%))

Ejemplo de uso:

*Main> ( (!!).iterate(map(id%).(zipWith%)) ) [[1,1,1],[2,3,4]] 3
[[1,1,1,2,3,5],[2,3,4,7,11,18],[3,4,5,9,14,23],[5,7,9,16,25,41],[8,11,14,25,39,64]]

Cómo funciona:

(!!).iterate(    ...         )  -- repeatedly apply ... to the first agrument and
                                -- pick the iteration defined by the second arg
                   (zipWith%)   -- for one iteration add a new row and
          map(id%)              -- then a new element at the end of each each row

o%m                             -- add row or element at the end of a row resp.
                                -- argument o is a "modify function"
                                --          m the whole matrix or a row
 m++[    (last m)(last$init m)] -- take m and append the result of combining the
                                -- last and 2nd last element of m
     o(+)                       -- with a modified version of (+)
                                -- modification is none (aka. id) when adding an
                                -- element to the end of a row and
                                -- zipping elementwise (zipWith) when adding a row
nimi
fuente
Soy un novato de Haskell. Llegué sudo apt-get install haskell-platformy estoy ejecutando el ghciREPL, que me da un Prelude> aviso. Cuando pego o%m=m++[o(+)(last m)$last$init m]me sale <interactive>:2:4: parse error on input '='. ¿Me puede dar un pequeño manual ya sea ejecutando esto desde un archivo fuente o en el REPL?
Trauma digital
@ DigitalTrauma: pon la o%m=...línea (y solo esta línea) en un archivo llamado, digamos fib-matrix.hs. Luego puede usar el :l fib-matrix.hscomando ghcipara cargar las definiciones y llamar a la función principal tal como se describe en mi ejemplo de uso. - O uso let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
nimi
1
@DigitalTrauma: oh, hay una tercera forma: asigne un nombre a la función principal, por ejemplo, agregue un f=delante de la segunda línea: f=(!!).iterate...guarde ambas líneas en un archivo y cárguelo a través de l: <filename.hs>. Entonces puedes llamar f [[1,1,1],[2,3,4]] 3, etc.
nimi
No estoy seguro de que acepte esto como haskell válido, la línea superior es una definición de función y necesita modificación para su uso en REPL, pero la segunda línea solo se puede usar en REPL.
Daniel Hill
@DanielHill: hay un tema sobre meta que permite funciones sin nombre que dependen de las funciones de ayuda global.
nimi
2

CJam, 17 16 bytes

q~2*{~_2$.+]z}*p

El formato de entrada es la matriz primero (como una matriz 2D de estilo CJam) y el número de iteraciones posteriores.

Pruébalo aquí.

Explicación

Resulta que esta es la misma solución que todos los demás:

q~      e# Read and evaluate input.
2*      e# Double the iteration count.
{       e# Run this block that many times...
  ~     e#   Dump all rows on the stack.
  _     e#   Copy the last row.
  2$    e#   Copy the penultimate row.
  .+    e#   Vectorised addition.
  ]     e#   Wrap all rows in a new array.
  z     e#   Transpose such that the next iteration processes the other dimension.
}*
p       e#   Pretty-print.
Martin Ender
fuente
1

En serio, 20 bytes

,,τ"┬`;d@d@X+@q`M"£n

Toma entrada de la matriz (como una lista 2D), entonces N. Emite una lista 2D.

Esta versión no funciona en el intérprete en línea por alguna razón, pero funciona con este compromiso previo al desafío .

Una versión que funciona en línea, para 23 bytes:

,τ",┬`;d@d@X+@q`M"nkΣ£ƒ

Toma entrada en el orden opuesto ( N, luego matriz).

Pruébalo en línea!

Agregaré una explicación después de dormir un poco. Trabajar con errores de intérprete nunca es divertido.

Mego
fuente
1

Pyth, 13 12 bytes

u+Rs>2dCGyEQ

Pruébalo en línea. Banco de pruebas.

Utiliza el mismo algoritmo para la mayoría de las respuestas. Toma como entrada la matriz como una matriz 2D en la primera línea y nen la segunda línea.

Explicación

u        yEQ     do 2*N times, starting with input matrix:
       CG          transpose
 +R                append to each row:
   s                 sum of
    >2d              last 2 elements of row
PurkkaKoodari
fuente
1

Matlab, 60 bytes

Primero estaba jugando con los elegantes métodos de indexación de Matlab (es decir, A(end+1,:)=sum... ) antes de darme cuenta de que en este caso raro, la concatenación simple es realmente más barata en Matlab. Lástima que tuve que convertir esto en una función real. Debería funcionar con Octave también.

function A=f(A,n)
for i=1:2*n
A=[A;sum(A(end-1:end,:))]';end

Supongo que este es un excelente ejemplo de cómo no hacer algoritmos. Para A = 2x2, n = 1000, este algoritmo ya lleva 5 segundos en mi computadora portátil, n = 2000 ¡son casi 50 segundos! (o aproximadamente 30 s si A es un gpuArrayagradecimiento a mi confiable Quadro 1000M)

Sanchises
fuente
No tengo una copia de Matlab. ¿Puedo ejecutar esto bajo octava GNU? Si es así, ¿puedes dar instrucciones?
Trauma digital
1
Sí, lo llamé Matlab porque no usa ninguna función específica de Octave. Simplemente póngalo en un archivo llamado fm y ejecútelo como, por ejemplof([0,1;2,3],1000)
Sanchises
Veo. 1) guardar como f.m. 2) Comience octave. 3) Pegar load f.m; f([1,1,1;2,3,4],3)en el indicador REPL: funciona para mí.
Trauma digital
¡Si tú lo dices! Solo uso el sitio web en línea de octava, así que no tengo idea de cómo debería funcionar de otra manera.
Veré
1

Java, 2179 bytes

Lo resolví: - Este código está en lenguaje Java.

import java.util.Scanner;

public class FebonnaciMatrix {
        static Scanner scan=new Scanner(System.in);

        public static void main(String[] args) {

        int x,y;
        System.out.println("For the Array to Work Upon:- ");

        System.out.println("Enter the Row:- ");
        int row=scan.nextInt();
        System.out.println("Enter the Column:- ");
        int col=scan.nextInt();

        int inpArr[][]=new int[row][col];

        System.out.println("Enter the values");
        inpArr=inpValues(row,col);

        System.out.println("The Input Array is:- ");
        display(inpArr,row,col);

        System.out.println("Input the Array size of Febonacci Array ");

        System.out.println("Enter the Row");
        int frow=scan.nextInt();
        System.out.println("Enter the Column");
        int fcol=scan.nextInt();

        int febArr[][]=new int[frow][fcol];
        febArr=copyValue(inpArr,febArr,row,col);

        for(x=0;x<row;x++)
        {
            for(y=col;y<fcol;y++)
                febArr[x][y]=febArr[x][y-2]+febArr[x][y-1];
        }

        for(x=row;x<frow;x++)
        {
            for(y=0;y<fcol;y++)
                febArr[x][y]=febArr[x-2][y]+febArr[x-1][y];
        }

        System.out.println();
        System.out.println("The Febonacci Array:-");
        display(febArr,frow,fcol);
    }

    static void display(int[][] arr,int row,int col)
    {
        int x,y;
        for(x=0;x<row;x++)
        {
            for(y=0;y<col;y++)
                System.out.print(arr[x][y]+"\t");
            System.out.println();
        }
    }

    static int[][] inpValues(int row,int col)
    {
        int arr[][]=new int[row][col];
        int x,y;
        for(x=0;x<row;x++)
        {
            for(y=0;y<col;y++)
            {
                System.out.print("Enter the value:- ");
                arr[x][y]=scan.nextInt();
            }
        }
        return arr;
    }

    static int[][] copyValue(int[][] old, int[][] ne, int row,int col)
    {
        int x,y;    
        for(x=0;x<row;x++)
        {
            for(y=0;y<col;y++)
                ne[x][y]=old[x][y];

        }
        return ne;
    }

}
Dhruv Govila
fuente
1
¡Bienvenido a Programming Puzzles y Code Golf! La pregunta está etiquetada como code-golf, lo que significa que las respuestas compiten para escribirse en la menor cantidad de código posible (en bytes). Es posible que su respuesta resuelva el problema, pero veo pocos intentos de "jugar" el código (es decir, hacerlo lo más breve posible). Hay muchas oportunidades triviales para hacer esto con su código, por ejemplo, variables con nombres de 1 carácter y eliminación de espacios en blanco innecesarios. Más allá de eso, puede leer estos consejos, específicamente para Java
Digital Trauma
... Eche un vistazo al tag-wiki para code-golf , especialmente el ¿Cómo debo responder a un código golf? ¿Alguna pista? sección. También tenga en cuenta que Java es notoriamente difícil de jugar golf en código corto, en comparación con muchos otros idiomas. Sin embargo, esto no debería disuadirlo: si tiene una respuesta de Java bien desarrollada, es probable que sea bastante popular, incluso si es más larga que todas las otras respuestas. No se desanime por todas las respuestas de esolang alucinantemente cortas: esta comunidad tiende a ser buena para tener en cuenta las desventajas del lenguaje.
Trauma digital
@ DigitalTrauma- Gracias ... por ayudarme como un novato a esto ... seguramente revisaré los enlaces y encontraré un nuevo código ...
Dhruv Govila
Como eres un usuario nuevo, me tomé la libertad de editar tu respuesta para un mejor formato. En particular a) un título claro que indica el idioma y el número de bytes, b) el formato del código de su código. En todos los sitios de stackexchange, el formato de código es fácil: simplemente prefije todas sus líneas de código con 4 espacios. De hecho, aún más fácil: en el cuadro de edición, seleccione su código, luego haga clic {}en en la parte superior del cuadro de edición; esto automáticamente hará este prefijo.
Trauma digital
De acuerdo ... lo comprobaré ...
Dhruv Govila
1

Python, 103 105 bytes

f=lambda n,L:f(n-1,[l+[sum(l[-2:])]for l in L])if n else L
lambda n,L:zip(*f(n,map(list,zip(*f(n,L)))))

La función anónima toma la lista de la lista y pasa a la función recursiva f. La salida se transpone y luego se pasa de fnuevo, luego la salida de la segunda vuelta se vuelve a transponer. La salida es una lista de tuplas

Guardado dos bytes gracias a bakuriu

wnnmaw
fuente
1
n>0podría ser simplemente n, ya que comienzas con un positivo ny cuando alcanzas 0su valor es falso.
Bakuriu
0

Perl 6 ,  87 73  71 bytes

->\c,\m{for ^c {.[+*]=[+] .[*X-1,2]for m;m.push: [map {[+] m[*X-1,2;$_]},m[0].keys]};m}
->\c,\m{for ^c {.[+*]=[+] .[*X-1,2]for m;m[+*]=[m[*-2;*] »+«m[*-1]]};m}
->\c,\m{for ^c {.[+*]=[+] .[*X-1,2]for m;m[+*]=[m[*-2;*]Z+m[*-1;*]]};m}
-> \c, \m {
  for ^c { # 0 ..^ c

    # each row
    .[+*]                            # new column at the end of row ($_)
          = [+] .[ * X- 1,2 ]        # add up the last two entries in row ($_)
                              for m; # for every row

    # too bad this was longer than the above code
    # m[*;+*]=map *+*,m[*;*-2,*-1]

    # each column
    m[ +* ]                 # add new row
            = [             # make it an Array rather than a List
                m[ *-2; * ] # the second to last row
                »+«         # added columnwise with
                m[ *-1 ]    # the last row
              ]
  };

  m # return the result
}

Uso:

use v6.c;
# give it a lexical name
my &code = ->\c,\m{  }

my @return = code 3,[[1,1,1],[2,3,4]];

put '[ ', $_».fmt('%2d'), ' ]' for @return;

put '';

put @return.perl ~~ {S:g/' '//};
[  1  1  1  2  3  5 ]
[  2  3  4  7 11 18 ]
[  3  4  5  9 14 23 ]
[  5  7  9 16 25 41 ]
[  8 11 14 25 39 64 ]

[[1,1,1,2,3,5],[2,3,4,7,11,18],[3,4,5,9,14,23],[5,7,9,16,25,41],[8,11,14,25,39,64]]
Brad Gilbert b2gills
fuente
Pegar esto perl6 me da algunos errores . Soy un novato perl, ¿qué estoy haciendo mal?
Trauma digital
@DigitalTrauma Lo siento, debería haber escrito el uso my &code = ->\c,\m{ … }para dejar en claro que ->\c,\m{ … }es necesario reemplazarlo con el código anterior. Por lo general, uso parámetros de marcador de posición implícitos $_o @_explícitos $^aporque tienden a ser más cortos. Simplemente no lo pensé. También asegúrese de estar usando una versión lo suficientemente nueva ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills
@DigitalTrauma También puede ir al canal # perl6 en freenode.net y usar camelia (como este) para ejecutar el código (líneas anteriores m: y un espacio) También puede enviar mensajes directamente a camelia
Brad Gilbert b2gills