Espansione matrice in stile Fibonacci


25

Per ogni riga e quindi colonna di una matrice, possiamo aggiungere una voce aggiuntiva con la somma delle ultime due voci in quella riga o colonna. Ad esempio con la seguente matrice di input:

[ 1 1 1 ]
[ 2 3 4 ]

La matrice risultante sarebbe:

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

Dato un input di un numero intero N e una matrice [X, Y] di dimensioni almeno 2x2, eseguire l'espansione N di cui sopra e produrre il risultato. La matrice risultante avrà sempre le dimensioni [X + N, Y + N].

Esempi:

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 ]

Risposte:


8

MATL , 13 14 15 16 20 21 byte

2*:"!tP2:Y)sv

Grazie @Zgarb per aver rimosso 1 byte!

Provalo 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
Non conosco MATL, ma non sarebbe più breve ripetere i cicli piuttosto che ripetere 2Ndue Nvolte?
Zgarb,

@Zgarb Certo! Come mi sono perso? Grazie!!
Luis Mendo,

MATL ha un built-in per raddoppiare un numero?
Zgarb,

@Zgarb No. È necessario 2*(notazione postfix). Forse dovrebbe avere un solo carattere incorporato, è usato spesso. Anche 2^(quadrato). Ma sto esaurendo lo spazio del codice :-)
Luis Mendo,

6

J, 19 byte

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

Questo definisce un avverbio, che prende il numero alla sua sinistra e produce un verbo che prende la matrice alla sua destra. Per il secondo esempio, dà

  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

Spiegazione

(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 byte

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

In azione:

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

Provalo qui .


funziona ancora se rimuovi il {xy}
comando iniziale

3

Gelatina, 15 13 12 byte

-1 byte di @Dennis

ṫ-S;@"Z
ÇḤ}¡

Come la risposta MATL di @ LuisMendo, questo traspone l'array prima di eseguire la trasformazione lungo un asse. Pertanto, è necessario chiamare la funzione 2 * n volte.

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

Provalo qui .


2

ES6, 134 byte

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

Spiegazione:

(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 byte

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

Esempio di utilizzo:

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

Come funziona:

(!!).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

Sono un novizio haskell. Ho raggiunto sudo apt-get install haskell-platforme sto eseguendo il ghciREPL che mi dà un Prelude> prompt. Quando incollo o%m=m++[o(+)(last m)$last$init m]ottengo <interactive>:2:4: parse error on input '='. Puoi darmi un piccolo primer o eseguendolo da un file sorgente o nel REPL?
Trauma digitale il

@DigitalTrauma: o metti la o%m=...linea (e solo questa linea) in un file chiamato, diciamo fib-matrix.hs. Quindi è possibile utilizzare il :l fib-matrix.hscomando in ghciper caricare le definizioni e chiamare la funzione principale proprio come descritto nel mio esempio di utilizzo. - Oppure usa let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
nimi,

1
@DigitalTrauma: oh, c'è un terzo modo: dai un nome alla funzione principale, es. Aggiungi un f=davanti alla seconda riga :, f=(!!).iterate...salva entrambe le righe in un file e caricalo via l: <filename.hs>. Quindi puoi chiamare f [[1,1,1],[2,3,4]] 3, ecc.
nimi,

Non sono sicuro che accetterei questo come haskell valido, la riga superiore è una definizione di funzione e necessita di modifiche per l'uso nella REPL, ma la seconda riga può essere utilizzata solo nella REPL.
Daniel Hill

@DanielHill: c'è un argomento su meta che consente funzioni senza nome che dipendono dalle funzioni di supporto globali.
nimi,

2

CJam, 17 16 byte

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

Il formato di input è prima la matrice (come un array 2D in stile CJam) e successivamente il numero di iterazioni.

Provalo qui.

Spiegazione

Si scopre che questa è la stessa soluzione di tutti gli altri:

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

Scherzi a parte, 20 byte

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

Accetta quindi la matrice (come elenco 2D), quindi N. Emette un elenco 2D.

Questa versione non funziona sull'interprete online per qualche motivo, ma funziona con questo commit pre-challenge .

Una versione che funziona online, per 23 byte:

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

Riceve input nell'ordine opposto ( N, quindi matrice).

Provalo online!

Aggiungerò una spiegazione dopo aver dormito per un po '. Lavorare attorno ai bug degli interpreti non è mai divertente.


1

Pyth, 13 12 byte

u+Rs>2dCGyEQ

Provalo online. Suite di test.

Utilizza lo stesso algoritmo per la maggior parte delle risposte. Accetta come input la matrice come matrice 2D sulla prima riga e nsulla seconda riga.

Spiegazione

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 byte

Prima stavo scherzando con i fantasiosi metodi di indicizzazione di Matlab (cioè, A(end+1,:)=sum...) prima di immaginare che in questo raro caso, la semplice concatenazione in realtà è più economica in Matlab. Peccato che ho dovuto convertirlo in una funzione reale. Dovrebbe funzionare anche con Octave.

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

Suppongo che questo sia un ottimo esempio di come non creare algoritmi. Per A = 2x2, n = 1000 questo algoritmo impiega già 5 secondi sul mio laptop, n = 2000 sono quasi 50 secondi! (o circa 30s se A è un gpuArrayringraziamento al mio fidato Quadro 1000M)


Non ho una copia di Matlab. Posso eseguirlo sotto l'ottava GNU? In tal caso puoi dare istruzioni?
Trauma digitale il

1
Sì, l'ho chiamato Matlab perché non utilizza alcuna funzione specifica di Octave. Basta inserirlo in un file chiamato fm ed eseguirlo come ad esempiof([0,1;2,3],1000)
Sanchises,

Vedo. 1) salva come f.m. 2) Avvia octave. 3) Incolla load f.m; f([1,1,1;2,3,4],3)nel prompt REPL - funziona per me.
Trauma digitale il

Se lo dici tu! Uso solo il sito Web di ottava online, quindi non ho idea di come dovrebbe funzionare diversamente. Vedrò se posso permalink da lì
Sanchises,

1

Java, 2179 byte

Appena risolto: - Questo codice è in linguaggio 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
Benvenuti in Puzzle di programmazione e Code Golf! La domanda è taggata code-golf, il che significa che le risposte sono in competizione per essere scritte nella più breve quantità possibile di codice (in byte). La tua risposta potrebbe risolvere il problema, ma vedo pochi tentativi di "golfare" il codice (ovvero renderlo il più breve possibile). Ci sono molte banali opportunità per farlo con il tuo codice, ad es. Variabili con nomi a 1 carattere e rimozione di spazi bianchi non necessari. Inoltre puoi leggere questi suggerimenti, in particolare per java
Digital Trauma,

... Dai un'occhiata al tag-wiki per code-golf , in particolare il Come devo rispondere a un codice golf? Qualche suggerimento? sezione. Si noti inoltre che java è notoriamente difficile da golfare fino al codice funzione, rispetto a molte altre lingue. Questo non dovrebbe dissuaderti però: se hai una risposta java ben giocata, è probabile che sia abbastanza popolare, anche se è più lungo di tutte le altre risposte. Non lasciarti scoraggiare da tutte le risposte esolang brevemente strazianti: questa comunità tende ad essere brava a tenere conto degli handicap linguistici.
Trauma digitale il

@ DigitalTrauma- Grazie ... per avermi aiutato come novizio di questo ... Sicuramente esaminerò i collegamenti e
creerò

Dato che sei un nuovo utente, mi sono preso la libertà di modificare la tua risposta per una migliore formattazione. In particolare a) un titolo chiaro che indica la lingua e il numero di byte, b) la formattazione del codice del codice. Su tutti i siti di stackexchange, la formattazione del codice è semplice: basta aggiungere un prefisso a tutte le righe di codice con 4 spazi. In effetti, è ancora più semplice: nella casella di modifica, seleziona il tuo codice, quindi fai clic su {}nella parte superiore della casella di modifica: questo farà automaticamente questo prefisso.
Trauma digitale il

Ok ... lo controllerò ...
Dhruv Govila,

1

Python, 103 105 byte

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 funzione anonima prende l'elenco dell'elenco e passa alla funzione ricorsiva f . L'output viene trasposto e quindi passato fnuovamente a, quindi l'output del secondo go viene nuovamente trasposto. L'output è un elenco di tuple

Risparmiato due byte grazie a Bakuriu


1
n>0potrebbe semplicemente essere n, dal momento che si inizia con un positivo ne quando si raggiunge il 0suo valore è falso.
Bakuriu,


0

Perl 6 ,  87 73  71 byte

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

Incollare questo in perl6 mi dà alcuni errori . Sono un perl novizio - cosa sto facendo di sbagliato?
Trauma digitale il

@DigitalTrauma Mi dispiace che avrei dovuto scrivere l'uso my &code = ->\c,\m{ … }per chiarire che è ->\c,\m{ … }necessario sostituire il codice sopra. Di solito uso parametri segnaposto impliciti $_o @_espliciti $^aperché tendono ad essere più brevi. Non ci ho pensato. Assicurati anche di utilizzare una versione abbastanza nuova ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills il

@DigitalTrauma Puoi anche andare sul canale # perl6 su freenode.net e usare camelia (come questo) per eseguire il codice (precedere le linee con m: e uno spazio) Puoi anche mandare direttamente
camelia
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.