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 ]

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

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

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 .


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 .


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

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

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.

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.


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

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)


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

}

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


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

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