Mở rộng ma trận theo kiểu Fibonacci


25

Đối với mỗi hàng và sau đó là cột của một ma trận, chúng ta có thể thêm một mục nhập bổ sung với tổng của hai mục cuối trong hàng hoặc cột đó. Ví dụ với ma trận đầu vào sau:

[ 1 1 1 ]
[ 2 3 4 ]

Ma trận kết quả sẽ là:

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

Cho đầu vào của một số nguyên N và ma trận [X, Y] có kích thước ít nhất là 2x2, thực hiện việc mở rộng N lần trên và đưa ra kết quả. Ma trận kết quả sẽ luôn có kích thước [X + N, Y + N].

Ví dụ:

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 ]

Câu trả lời:


8

MATL , 13 14 15 16 20 21 byte

2*:"!tP2:Y)sv

Cảm ơn @Zgarb đã xóa 1 byte!

Hãy thử trực tuyến!

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
Tôi không biết MATL, nhưng sẽ không ngắn hơn thời gian lặp 2Nhơn là lặp hai Nlần?
Zgarb

@Zgarb Tất nhiên rồi! Làm thế nào tôi bỏ lỡ điều đó? Cảm ơn!!
Luis Mendo

MATL có tích hợp sẵn để nhân đôi số không?
Zgarb

@Zgarb Số Bạn cần 2*(ký hiệu hậu tố). Có lẽ nó nên có một ký tự tích hợp, nó được sử dụng thường xuyên. Ngoài ra 2^(hình vuông). Nhưng tôi sắp hết dung lượng mã :-)
Luis Mendo

6

J, 19 byte

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

Điều này xác định một trạng từ, lấy số ở bên trái của nó và tạo ra một động từ lấy ma trận ở bên phải của nó. Ví dụ thứ hai, nó cho

  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

Giải trình

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

Trong hành động:

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

Hãy thử nó ở đây .


nó vẫn hoạt động nếu bạn xóa phần đầu {xvà dấuy}
ngn

3

Thạch, 15 13 12 byte

-1 byte bởi @Dennis

ṫ-S;@"Z
ÇḤ}¡

Giống như câu trả lời MATL của @ LuisMendo, điều này hoán chuyển mảng trước khi thực hiện chuyển đổi dọc theo một trục. Do đó, chúng ta cần gọi hàm 2 * n lần.

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

Hãy thử nó ở đây .


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

Giải trình:

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

Ví dụ sử dụng:

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

Làm thế nào nó hoạt động:

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

Tôi là một người mới làm quen. Tôi đã đi xa sudo apt-get install haskell-platformvà đang chạy ghciREPL, điều đó cho tôi một Prelude> dấu nhắc. Khi tôi dán vào o%m=m++[o(+)(last m)$last$init m]tôi nhận được <interactive>:2:4: parse error on input '='. Bạn có thể cho tôi một chút mồi hoặc chạy nó từ tệp nguồn hoặc trong REPL không?
Chấn thương kỹ thuật số

@DigitalTrauma: hoặc đặt o%m=...dòng (và chỉ dòng này) trong một tệp có tên, giả sử fib-matrix.hs. Sau đó, bạn có thể sử dụng :l fib-matrix.hslệnh ghciđể tải các định nghĩa và gọi hàm chính như được mô tả trong ví dụ sử dụng của tôi. - Hoặc sử dụng let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
nimi

1
@DigitalTrauma: oh, có cách thứ 3: đặt tên cho hàm chính, ví dụ: thêm một dòng f=phía trước dòng thứ hai : f=(!!).iterate..., lưu cả hai dòng trong một tệp và tải nó qua l: <filename.hs>. Sau đó, bạn có thể gọi f [[1,1,1],[2,3,4]] 3, v.v.
nimi

Tôi không chắc chắn tôi sẽ chấp nhận điều này là haskell hợp lệ, dòng trên cùng là định nghĩa hàm và cần sửa đổi để sử dụng trong REPL, nhưng dòng thứ 2 chỉ có thể được sử dụng trong REPL.
Đồi Daniel

@DanielHill: có một chủ đề về meta cho phép các chức năng không tên phụ thuộc vào chức năng của trình trợ giúp toàn cầu.
nimi

2

CJam, 17 16 byte

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

Định dạng đầu vào là ma trận đầu tiên (dưới dạng mảng 2D kiểu CJam) và số lần lặp sau đó.

Kiểm tra nó ở đây.

Giải trình

Hóa ra đây là giải pháp giống như mọi người khác:

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

Nghiêm túc, 20 byte

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

Đưa đầu vào ma trận (dưới dạng danh sách 2D), sau đó N. Xuất ra một danh sách 2D.

Phiên bản này không hoạt động trên trình thông dịch trực tuyến vì một số lý do, nhưng không hoạt động với cam kết trước thách thức này .

Một phiên bản hoạt động trực tuyến, với 23 byte:

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

Đưa đầu vào theo thứ tự ngược lại ( N, sau đó là ma trận).

Hãy thử trực tuyến!

Tôi sẽ thêm một lời giải thích sau khi tôi ngủ một chút. Làm việc xung quanh lỗi phiên dịch là không bao giờ vui vẻ.


1

Bình thường, 13 12 byte

u+Rs>2dCGyEQ

Hãy thử trực tuyến. Bộ thử nghiệm.

Sử dụng cùng một thuật toán cho hầu hết các câu trả lời. Lấy đầu vào là ma trận dưới dạng mảng 2D trên dòng đầu tiên và ntrên dòng thứ hai.

Giải trình

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

Lần đầu tiên tôi đã nhầm lẫn với các phương pháp lập chỉ mục ưa thích của Matlab (tức là A(end+1,:)=sum...) trước khi tôi nhận ra rằng trong trường hợp hiếm hoi này, việc ghép nối đơn giản thực sự rẻ hơn trong Matlab. Quá tệ, tôi đã phải chuyển đổi nó thành một chức năng thực tế. Nên làm việc với Octave là tốt.

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

Tôi cho rằng đây là một ví dụ điển hình về cách không tạo ra các thuật toán. Với A = 2x2, n = 1000 thuật toán này đã mất 5 giây trên máy tính xách tay của tôi, n = 2000 là gần 50 giây! (hoặc khoảng 30 giây nếu A là gpuArraynhờ Quadro 1000M đáng tin cậy của tôi)


Tôi không có bản sao Matlab. Tôi có thể chạy cái này dưới GNU octave không? Nếu vậy bạn có thể đưa ra hướng dẫn?
Chấn thương kỹ thuật số

1
Có, tôi gọi nó là Matlab vì nó không sử dụng bất kỳ chức năng cụ thể nào của Octave. Đơn giản chỉ cần đặt nó trong một tập tin gọi là fm và chạy như ví dụf([0,1;2,3],1000)
Sanchises

Tôi hiểu rồi. 1) lưu dưới dạng f.m. 2) Bắt đầu octave. 3) Dán load f.m; f([1,1,1;2,3,4],3)vào dấu nhắc REPL - hoạt động với tôi.
Chấn thương kỹ thuật số

Nếu bạn nói vậy! Tôi chỉ sử dụng trang web trực tuyến quãng tám nên không biết làm thế nào nó nên hoạt động khác. Tôi sẽ xem liệu tôi có thể permalink từ đó không
Sanchises 5/2/2016

1

Java, 2179 byte

Chỉ cần làm việc với nó: - Mã này là trên Ngôn ngữ 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
Chào mừng bạn đến với Câu đố lập trình và Code Golf! Câu hỏi được gắn thẻ mã golf , có nghĩa là các câu trả lời đang cạnh tranh để được viết với số lượng mã ngắn nhất có thể (tính bằng byte). Câu trả lời của bạn có thể giải quyết tốt vấn đề, nhưng tôi thấy rất ít nỗ lực để "đánh gôn" mã (tức là làm cho nó càng ngắn càng tốt). Có rất nhiều cơ hội tầm thường để làm điều này với mã của bạn, ví dụ: các biến có tên 1 char và loại bỏ khoảng trắng không cần thiết. Ngoài ra, bạn có thể đọc các mẹo này, đặc biệt dành cho java
Chấn thương kỹ thuật số

... Hãy xem tag-wiki cho code-golf , đặc biệt là Làm thế nào tôi nên trả lời golf code? Có gợi ý nào không? phần. Cũng lưu ý rằng java nổi tiếng là khó chơi golf với mã ngắn, so với nhiều ngôn ngữ khác. Điều này không nên can ngăn bạn - nếu bạn có một câu trả lời java được chơi tốt, nó có thể khá phổ biến, ngay cả khi nó dài hơn tất cả các câu trả lời khác. Đừng bỏ qua tất cả các câu trả lời esolang ngắn có đầu óc - cộng đồng này có xu hướng rất giỏi trong việc tính đến các khuyết tật ngôn ngữ.
Chấn thương kỹ thuật số

@ DigitalTrauma- Cảm ơn ... vì đã giúp tôi làm người mới về vấn đề này ... Tôi chắc chắn sẽ truy cập các liên kết và đưa ra một mã mới ...
Dhruv Govila

Vì bạn là người dùng mới, tôi đã tự do chỉnh sửa câu trả lời của bạn để định dạng tốt hơn. Cụ thể a) một ngôn ngữ rõ ràng tiêu đề và số byte, b) định dạng mã của mã của bạn. Trên tất cả các trang web stackexchange, định dạng mã rất dễ dàng - chỉ cần tiền tố tất cả các dòng mã của bạn với 4 khoảng trắng. Trong thực tế thậm chí còn dễ dàng hơn - trong hộp chỉnh sửa, chọn mã của bạn, sau đó nhấp vào {}đầu hộp chỉnh sửa - điều này sẽ tự động thực hiện tiền tố này.
Chấn thương kỹ thuật số

Được rồi ... Tôi sẽ kiểm tra xem ...
Dhruv Govila 5/2/2016

1

Con trăn, 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)))))

Hàm ẩn danh có danh sách danh sách và chuyển đến hàm đệ quy f . Đầu ra được hoán vị và sau đó được chuyển sang fmột lần nữa, sau đó đầu ra của lần thứ hai được chuyển đổi lại. Đầu ra là một danh sách các bộ dữ liệu

Đã lưu hai byte nhờ bakuriu


1
n>0có thể chỉ đơn giản là n, vì bạn bắt đầu bằng số dương nvà khi bạn đạt đến 0giá trị của nó là sai.
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
}

Sử dụng:

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

Dán cái này vào perl6 cho tôi một số lỗi . Tôi là một người mới làm quen - tôi đang làm gì sai?
Chấn thương kỹ thuật số

@DigitalTrauma Tôi xin lỗi, tôi nên viết cách sử dụng my &code = ->\c,\m{ … }để làm rõ rằng ->\c,\m{ … }cần phải thay thế bằng mã ở trên. Tôi thường sử dụng một tham số giữ chỗ ngầm định $_hoặc @_rõ ràng $^abởi vì chúng có xu hướng ngắn hơn. Tôi chỉ không nghĩ về nó. Ngoài ra, hãy đảm bảo rằng bạn đang sử dụng một phiên bản đủ mới ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills

@DigitalTrauma Bạn cũng có thể truy cập kênh # perl6 trên freenode.net và sử dụng camelia (như thế này) để chạy mã (các dòng có trước m: và một khoảng
trắng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.