Expansão da matriz no estilo Fibonacci

25

Para cada linha e depois coluna de uma matriz, podemos adicionar uma entrada extra com a soma das duas últimas entradas nessa linha ou coluna. Por exemplo, com a seguinte matriz de entrada:

[ 1 1 1 ]
[ 2 3 4 ]

A matriz resultante seria:

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

Dada uma entrada de um número inteiro N e uma matriz [X, Y] de tamanho pelo menos 2x2, execute os tempos de expansão N acima e produza o resultado. A matriz resultante sempre será do tamanho [X + N, Y + N].

Exemplos:

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
fonte

Respostas:

8

MATL , 13 14 15 16 20 21 bytes

2*:"!tP2:Y)sv

Obrigado @Zgarb por remover 1 byte!

Experimente online!

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
fonte
1
Eu não sei MATL, mas não seria mais curto para repetir os 2Ntempos do que repetir duas Nvezes?
Zgarb
@ Zgarb Claro! Como eu senti falta disso? Obrigado!!
Luis Mendo
O MATL tem um built-in para dobrar um número?
Zgarb
@Zgarb Não. Você precisa 2*(notação pós-fixada). Talvez deva ter um caractere embutido, é usado com frequência. Também 2^(quadrado). Mas eu estou ficando sem espaço de código :-)
Luis Mendo
6

J, 19 bytes

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

Isso define um advérbio, que pega o número à esquerda e produz um verbo usando a matriz à direita. Para o segundo exemplo, ele fornece

  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

Explicação

(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
fonte
3

K, 23 bytes

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

Em ação:

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

Experimente aqui .

JohnE
fonte
ainda funciona se você remover a guia inicial {xe a finaly}
ngn
3

Geléia, 15 13 12 bytes

-1 byte por @Dennis

ṫ-S;@"Z
ÇḤ}¡

Como a resposta MATL do @ LuisMendo, isso transpõe o array antes de fazer a transformação ao longo de um eixo. Portanto, precisamos chamar a função 2 * n vezes.

ṫ-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.

Experimente aqui .

lirtosiast
fonte
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))

Explicação:

(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
fonte
2

Haskell, 67 bytes

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

Exemplo 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]]

Como 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
fonte
Eu sou um novato haskell. Eu tenho tanto quanto sudo apt-get install haskell-platforme estou executando o ghciREPL, que me dá um Prelude> prompt. Quando colo o%m=m++[o(+)(last m)$last$init m], recebo <interactive>:2:4: parse error on input '='. Você pode me dar uma pequena cartilha executando isso de um arquivo de origem ou no REPL?
Digital Trauma
@ DigitalTrauma: coloque a o%m=...linha (e somente essa linha) em um arquivo chamado, digamos fib-matrix.hs. Em seguida, você pode usar o :l fib-matrix.hscomando ghcipara carregar as definições e chamar a função principal, conforme descrito no meu exemplo de uso. - Ou use let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
Nev
1
@DigitalTrauma: oh, existe uma terceira maneira: dê um nome à função principal, por exemplo, adicione um f=na frente da segunda linha :, f=(!!).iterate...salve as duas linhas em um arquivo e carregue-o via l: <filename.hs>. Então você pode ligar f [[1,1,1],[2,3,4]] 3, etc.
nimi
Não tenho certeza se aceitaria isso como haskell válido, a linha superior é uma definição de função e precisa ser modificada para uso no REPL, mas a segunda linha pode ser usada apenas no REPL.
Daniel Hill
@ DanielHill: há um tópico sobre meta que permite funções sem nome que dependem de funções globais de ajuda.
Nev
2

CJam, 17 16 bytes

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

O formato de entrada é a matriz primeiro (como uma matriz 2D no estilo CJam) e o número de iterações posteriormente.

Teste aqui.

Explicação

Acontece que esta é a mesma solução que todos os outros:

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
fonte
1

Sério, 20 bytes

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

Leva a matriz (como uma lista 2D), então N. Produz uma lista 2D.

Esta versão não funciona no intérprete online por algum motivo, mas funciona com esse commit pré-desafio .

Uma versão que funciona online, por 23 bytes:

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

Recebe a entrada na ordem oposta ( Ne depois na matriz).

Experimente online!

Vou adicionar uma explicação depois de dormir um pouco. Trabalhar com erros de intérprete nunca é divertido.

Mego
fonte
1

Pitão, 13 12 bytes

u+Rs>2dCGyEQ

Experimente online. Suíte de teste.

Usa o mesmo algoritmo para a maioria das respostas. Toma como entrada a matriz como uma matriz 2D na primeira linha e nna segunda linha.

Explicação

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
fonte
1

Matlab, 60 bytes

Eu estava brincando com os métodos sofisticados de indexação do Matlab (ie A(end+1,:)=sum...) antes de concluir que, nesse caso raro, a concatenação simples é realmente mais barata no Matlab. Pena que tive que converter isso em uma função real. Também deve funcionar com o Octave.

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

Suponho que este seja um excelente exemplo de como não criar algoritmos. Para A = 2x2, n = 1000, esse algoritmo já leva 5 segundos no meu laptop, n = 2000, são quase 50 segundos! (ou aproximadamente 30s se A for um gpuArrayagradecimento ao meu fiel Quadro 1000M)

Sanchises
fonte
Eu não tenho uma cópia do Matlab. Posso executar isso na oitava do GNU? Se sim, você pode dar instruções?
Digital Trauma
1
Sim, chamei-o de Matlab porque não usa nenhuma função específica do Octave. Basta colocá-lo em um arquivo chamado fm e executado como por exemplof([0,1;2,3],1000)
Sanchises
Entendo. 1) salvar como f.m. 2) Iniciar octave. 3) Cole load f.m; f([1,1,1;2,3,4],3)no prompt do REPL - funciona para mim.
Digital Trauma
Se você diz! Eu só uso o site on-line da oitava, então não faço ideia de como deve funcionar de outra maneira. Vou ver se consigo permalink a partir daí
Sanchises
1

Java, 2179 bytes

Apenas resolvi: - Este código está na linguagem 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
fonte
1
Bem-vindo à Programação de Puzzles e Code Golf! A pergunta é marcada como code-golf, o que significa que as respostas estão competindo para serem escritas na menor quantidade de código possível (em bytes). Sua resposta pode muito bem resolver o problema, mas vejo poucas tentativas de "jogar golfe" no código (ou seja, torná-lo o mais curto possível). Existem muitas oportunidades triviais para fazer isso com seu código, por exemplo, variáveis ​​com nomes de 1 caractere e remoção de espaço em branco desnecessário. Além disso, você pode ler estas dicas, especificamente para java
Digital Trauma
... Dê uma olhada no tag-wiki para code-golf , especialmente em Como devo responder a um code-golf? Alguma dica? seção. Observe também que o java é notoriamente difícil de obter código curto, em comparação com muitos outros idiomas. Porém, isso não deve dissuadi-lo - se você tiver uma resposta java bem treinada, é provável que seja bastante popular, mesmo que seja mais longa que todas as outras respostas. Não se deixe levar por todas as respostas esolang curtas e curiosas - essa comunidade tende a ser boa em levar em consideração as desvantagens do idioma.
Digital Trauma
@ DigitalTrauma- Obrigado ... por me ajudar como um newbee para isso ... Eu certamente vou através dos links e chegar a um novo código ...
Dhruv Govila
Como você é um novo usuário, tomei a liberdade de editar sua resposta para obter uma melhor formatação. Em particular a) um título claro indicando o idioma e o número de bytes, b) a formatação do código do seu código. Em todos os sites de troca de pilha, a formatação do código é fácil - basta prefixar todas as suas linhas de código com 4 espaços. De fato, ainda mais fácil - na caixa de edição, selecione seu código e clique {}no topo da caixa de edição - isso fará esse prefixo automaticamente.
Digital Trauma
Ok ... eu vou apenas dar uma olhada ...
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)))))

Função anônima pega a lista da lista e passa para a função recursiva f. A saída é transposta e depois passada para fnovamente; a saída da segunda passagem é re-transposta. Saída é uma lista de tuplas

Economizou dois bytes graças a bakuriu

wnnmaw
fonte
1
n>0poderia ser simplesmente n, já que você começa com um positivo ne quando atinge 0seu valor é falso.
Bakuriu 5/02/16
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
fonte
Colar isso perl6 me dá alguns erros . Sou iniciante em perl - o que estou fazendo de errado?
Digital Trauma
@DigitalTrauma Me desculpe, eu deveria ter escrito o uso my &code = ->\c,\m{ … }para deixar claro que ele ->\c,\m{ … }precisa ser substituído pelo código acima. Eu geralmente uso parâmetros de espaço reservado implícitos $_ou @_explícitos, $^aporque eles tendem a ser mais curtos. Eu simplesmente não pensei nisso. Também certifique-se que você está usando uma nova versão suficiente ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills
@DigitalTrauma Você também pode ir no # perl6 canal no freenode.net e uso Camelia (como este) para executar o código (linhas precedido de m: e um espaço) Você também pode camelia msg diretamente
Brad Gilbert b2gills