Rozszerzenie macierzy Fibonacciego

25

Dla każdego wiersza, a następnie kolumny macierzy, możemy dodać dodatkowy wpis z sumą dwóch ostatnich wpisów w tym wierszu lub kolumnie. Na przykład z następującą matrycą wejściową:

[ 1 1 1 ]
[ 2 3 4 ]

Otrzymana macierz wyglądałaby następująco:

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

Biorąc pod uwagę liczbę całkowitą N i macierz [X, Y] o wielkości co najmniej 2x2, wykonaj powyższe rozszerzenie N razy i wyślij wynik. Otrzymana macierz będzie zawsze miała rozmiar [X + N, Y + N].

Przykłady:

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 ]
Cyfrowa trauma
źródło

Odpowiedzi:

8

MATL , 13 14 15 16 20 21 bajtów

2*:"!tP2:Y)sv

Dzięki @Zgarb za usunięcie 1 bajtu!

Wypróbuj 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
źródło
1
Nie znam MATL-a, ale czy nie byłoby krótsze zapętlenie 2Nrazy niż zapętlenie dwa Nrazy?
Zgarb
@Zgarb Oczywiście! Jak mi tego brakowało? Dzięki!!
Luis Mendo,
Czy MATL ma wbudowaną funkcję podwojenia liczby?
Zgarb
@Zgarb Nie. Potrzebujesz 2*(notacja postfiksowa). Może powinien mieć wbudowaną jedną postać, jest często używany. Również 2^(kwadrat). Ale brakuje mi miejsca na kod :-)
Luis Mendo,
6

J, 19 bajtów

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

Definiuje przysłówek, który bierze liczbę po lewej stronie i tworzy czasownik przyjmujący macierz po prawej stronie. W drugim przykładzie daje

  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

Wyjaśnienie

(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
źródło
3

K, 23 bajty

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

W akcji:

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

Wypróbuj tutaj .

JohnE
źródło
nadal działa, jeśli usuniesz wiodące {xi końcowey}
ngn
3

Galaretka, 15 13 12 bajtów

-1 bajt @Dennis

ṫ-S;@"Z
ÇḤ}¡

Podobnie jak odpowiedź MATL @ LuisMendo, transponuje tablicę przed transformacją wzdłuż jednej osi. Dlatego musimy wywołać funkcję 2 * n razy.

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

Wypróbuj tutaj .

lirtosiast
źródło
2

ES6, 134 bajty

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

Wyjaśnienie:

(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
źródło
2

Haskell, 67 bajtów

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

Przykład użycia:

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

Jak to działa:

(!!).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
źródło
Jestem nowicjuszką Haskell. Mam do tej pory sudo apt-get install haskell-platformi korzystam z ghciREPL, co daje mi Prelude> monit. Kiedy wklejam o%m=m++[o(+)(last m)$last$init m], dostaję <interactive>:2:4: parse error on input '='. Czy możesz dać mi trochę primera, uruchamiając to z pliku źródłowego lub w REPL?
Cyfrowy uraz
@DigitalTrauma: albo umieść o%m=...linię (i tylko tę linię) w pliku o nazwie, powiedzmy fib-matrix.hs. Następnie możesz użyć :l fib-matrix.hspolecenia in, ghciaby załadować definicje i wywołać funkcję główną, tak jak opisano w moim przykładzie użycia. - Lub użyj let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
nimi
1
@DigitalTrauma: och, jest trzeci sposób: nadaj głównej funkcji nazwę, np. Dodaj f=przed drugą linię: f=(!!).iterate...zapisz obie linie w pliku i załaduj ją l: <filename.hs>. Potem możesz zadzwonić f [[1,1,1],[2,3,4]] 3itp.
nimi
Nie jestem pewien, czy zaakceptowałbym to jako prawidłowy haskell, górny wiersz jest definicją funkcji i wymaga modyfikacji w celu użycia w REPL, ale drugiej linii można użyć tylko w REPL.
Daniel Hill,
@DanielHill: istnieje temat meta, który pozwala na korzystanie z nienazwanych funkcji zależnych od funkcji globalnego pomocnika.
nimi
2

CJam, 17 16 bajtów

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

Format wejściowy to najpierw matryca (jako tablica 2D typu CJam), a następnie liczba iteracji.

Sprawdź to tutaj.

Wyjaśnienie

Okazuje się, że jest to to samo rozwiązanie, co wszystkich innych:

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
źródło
1

Poważnie, 20 bajtów

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

Następnie przyjmuje macierz (jako listę 2D) N. Generuje listę 2D.

Ta wersja z jakiegoś powodu nie działa z tłumaczem online, ale działa z tym zatwierdzeniem przed wyzwaniem .

Wersja działająca online dla 23 bajtów:

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

Pobiera dane wejściowe w odwrotnej kolejności ( Nnastępnie macierz).

Wypróbuj online!

Dodam wyjaśnienie po krótkiej chwili snu. Praca z błędami tłumacza nigdy nie jest przyjemna.

Mego
źródło
1

Pyth, 13 12 bajtów

u+Rs>2dCGyEQ

Wypróbuj online. Zestaw testowy.

Używa tego samego algorytmu do większości odpowiedzi. Pobiera jako dane wejściowe macierz jako tablicę 2D w pierwszym wierszu i nw drugim wierszu.

Wyjaśnienie

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
źródło
1

Matlab, 60 bajtów

Po raz pierwszy bawiłem się fantazyjnymi metodami indeksowania Matlaba (tj. A(end+1,:)=sum...), Zanim zorientowałem się, że w tym rzadkim przypadku prosta konkatenacja jest w Matlabie tańsza. Szkoda, że ​​musiałem przekonwertować to na rzeczywistą funkcję. Powinien również współpracować z Octave.

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

Przypuszczam, że jest to doskonały przykład tego, jak nie tworzyć algorytmów. Dla A = 2x2, n = 1000 ten algorytm zajmuje już 5 sekund na moim laptopie, n = 2000 to prawie 50 sekund! (lub około 30 sekund, jeśli A to gpuArraydzięki mojemu zaufanemu Quadro 1000M)

Sanchises
źródło
Nie mam kopii Matlaba. Czy mogę uruchomić to w oktawie GNU? Jeśli tak, czy możesz podać instrukcje?
Cyfrowa trauma
1
Tak, nazwałem to Matlab, ponieważ nie używa żadnych funkcji specyficznych dla Octave. Wystarczy umieścić go w pliku o nazwie fm i uruchomić jako np.f([0,1;2,3],1000)
Sanchises,
Widzę. 1) zapisz jako f.m. 2) Uruchom octave. 3) Wklej load f.m; f([1,1,1;2,3,4],3)do monitu REPL - działa dla mnie.
Cyfrowy uraz
Skoro tak mówisz! Używam tylko strony internetowej oktawy, więc nie mam pojęcia, jak inaczej powinno działać. Zobaczę, czy mogę stamtąd
link bezpośredni
1

Java, 2179 bajtów

Właśnie to wypracowałem: - Ten kod jest w języku 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
źródło
1
Witamy w Programowaniu zagadek i Code Golf! Pytanie jest oznaczone kodem golfowym, co oznacza, że ​​odpowiedzi konkurują o napisanie możliwie najkrótszą ilością kodu (w bajtach). Twoja odpowiedź może rozwiązać problem, ale widzę niewielką próbę „gry w golfa” (tj. Uczynienia go możliwie najkrótszym). Istnieje wiele trywialnych możliwości, aby to zrobić za pomocą kodu, np. Zmienne o nazwach 1-znakowych oraz usuwanie niepotrzebnych białych znaków. Poza tym możesz przeczytać te wskazówki, szczególnie dla java
Digital Trauma
... Spójrz na tag-wiki dla golfa kodowego , zwłaszcza Jak odpowiedzieć na golfa kodowego? Jakieś wskazówki? Sekcja. Zauważ też, że java jest bardzo trudna do gry w skróty do krótkiego kodu, w porównaniu do wielu innych języków. Nie powinno cię to jednak zniechęcać - jeśli masz dobrze golfową odpowiedź w języku Java, prawdopodobnie będzie ona dość popularna, nawet jeśli jest dłuższa niż wszystkie inne odpowiedzi. Nie zniechęcaj się wszystkimi zadziwiająco krótkimi odpowiedziami esolang - ta społeczność zazwyczaj dobrze bierze pod uwagę niedogodności językowe.
Cyfrowy uraz
@ DigitalTrauma- Dzięki ... że pomogłeś mi jako nowicjusz w tej sprawie ... Na pewno przejdę przez linki i
wymyślę
Ponieważ jesteś nowym użytkownikiem, mogłem edytować swoją odpowiedź w celu lepszego formatowania. W szczególności a) czytelny tytuł określający język i liczbę bajtów, b) formatowanie kodu twojego kodu. Na wszystkich stronach wymiany stosów formatowanie kodu jest łatwe - wystarczy poprzedzić wszystkie linie kodu 4 spacjami. W rzeczywistości jeszcze łatwiej - w polu edycji wybierz swój kod, a następnie kliknij {}u góry pola edycji - spowoduje to automatyczne prefiksowanie.
Cyfrowy uraz
Okej ...
Sprawdzę
1

Python, 103 105 bajtów

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

Funkcja anonimowa pobiera listę i przechodzi do funkcji rekurencyjnej f. Dane wyjściowe są transponowane, a następnie przekazywane fponownie, a następnie dane wyjściowe drugiego uruchomienia są ponownie transponowane. Dane wyjściowe to lista krotek

Zaoszczędź dwa bajty dzięki bakuriu

wnnmaw
źródło
1
n>0może po prostu być n, ponieważ zaczynasz od pozytywu, na kiedy osiągasz, 0jego wartość jest fałszywa.
Bakuriu
0

Perl 6 ,  87 73  71 bajtów

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

Stosowanie:

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
źródło
Wklejenie tego perl6 powoduje błędy . Jestem początkującym perlem - co robię źle?
Cyfrowy uraz
@DigitalTrauma Przykro mi, że powinienem napisać użycie, my &code = ->\c,\m{ … }aby wyjaśnić, że ->\c,\m{ … }należy zastąpić powyższym kodem. Zwykle używam niejawnych $_lub @_jawnych parametrów zastępczych, $^aponieważ są one zwykle krótsze. Po prostu o tym nie myślałem. Upewnij się także, że używasz wystarczająco nowej wersji ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills
@DigitalTrauma Możesz także przejść na kanał # perl6 na freenode.net i użyć kamelii (w ten sposób), aby uruchomić kod (poprzedzać wiersze m: znakiem spacją). Możesz także msg camelia bezpośrednio
Brad Gilbert b2gills