การขยายตัวของเมทริกซ์สไตล์ฟีโบนักชี


25

สำหรับแต่ละแถวแล้วคอลัมน์ของเมทริกซ์เราสามารถเพิ่มรายการพิเศษด้วยผลรวมของสองรายการสุดท้ายในแถวหรือคอลัมน์นั้น ตัวอย่างเช่นอินพุตเมทริกซ์ต่อไปนี้:

[ 1 1 1 ]
[ 2 3 4 ]

เมทริกซ์ที่ได้จะเป็นดังนี้:

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

เมื่อกำหนดอินพุตของจำนวนเต็ม N และเมทริกซ์ [X, Y] ที่มีขนาดอย่างน้อย 2x2 ให้ดำเนินการส่วนขยาย N ข้างต้นและส่งผลลัพธ์ออกมา เมทริกซ์ที่ได้จะเป็นขนาด [X + N, Y + N] เสมอ

ตัวอย่าง:

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 ]

คำตอบ:


8

MATL , 13 14 15 16 20 21ไบต์

2*:"!tP2:Y)sv

ขอบคุณ @Zgarb สำหรับการลบ 1 ไบต์!

ลองออนไลน์!

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
ฉันไม่รู้จัก MATL แต่จะสั้น2Nกว่าการวนซ้ำเป็นสองNเท่าหรือไม่
Zgarb

@Zgarb แน่นอน! ฉันพลาดได้อย่างไร ขอบคุณ !!
Luis Mendo

MATL มีตัวในการเพิ่มจำนวนเป็นสองเท่าหรือไม่?
Zgarb

@Zgarb ไม่คุณต้องการ2*(สัญกรณ์ postfix) บางทีมันควรจะมีตัวละครในตัวมันใช้บ่อย ยัง2^(สี่เหลี่ยม) แต่ฉันมีพื้นที่โค้ดไม่เพียงพอ :-)
Luis Mendo

6

J, 19 ไบต์

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

คำจำกัดความนี้เป็นคำวิเศษณ์ซึ่งใช้จำนวนทางด้านซ้ายและสร้างกริยาที่ใช้เมทริกซ์ทางด้านขวา สำหรับตัวอย่างที่สองมันให้

  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

คำอธิบาย

(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 ไบต์

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

ในการดำเนินการ:

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

ลองมันนี่


มันยังคงใช้งานได้หากคุณลบส่วนนำ{xและส่วนท้ายออกไปy}
ngn 6'18

3

เยลลี่, 15 13 12 ไบต์

-1 ไบต์โดย @Dennis

ṫ-S;@"Z
ÇḤ}¡

เช่นเดียวกับคำตอบ MATLAB ของ @ LuisMendo สิ่งนี้จะเปลี่ยนอาร์เรย์ก่อนที่จะทำการแปลงตามแกนเดียว ดังนั้นเราจำเป็นต้องเรียกใช้ฟังก์ชัน 2 * 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.

ลองมันนี่


2

ES6, 134 ไบต์

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

คำอธิบาย:

(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 ไบต์

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

ตัวอย่างการใช้งาน:

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

มันทำงานอย่างไร:

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

ฉันเป็นสามเณร Haskell ฉันไปไกลถึงตอนนี้sudo apt-get install haskell-platformและกำลังใช้งานghciREPL ซึ่งให้ฉันPrelude> ทันที เมื่อฉันวางในที่ฉันได้รับo%m=m++[o(+)(last m)$last$init m] <interactive>:2:4: parse error on input '='คุณช่วยไพรเมอร์เล็กน้อยให้ฉันใช้ไฟล์นี้จากไฟล์ต้นฉบับหรือใน REPL ได้หรือไม่?
Digital Trauma

@DigitalTrauma: ทั้งใส่o%m=...เส้น (และบรรทัดนี้) fib-matrix.hsในไฟล์ที่เรียกว่าสมมติว่า จากนั้นคุณสามารถใช้:l fib-matrix.hsคำสั่งในghciการโหลดคำจำกัดความและเรียกใช้ฟังก์ชั่นหลักตามที่อธิบายไว้ในตัวอย่างการใช้งานของฉัน - let o%m=... in ( (!!). ... ) [[1,1,1]...] 3หรือการใช้งาน
nimi

1
@DigitalTrauma: โอ้มีวิธีที่ 3: ให้ฟังก์ชั่นหลักของชื่อเช่นเพิ่มf=ในด้านหน้าของบรรทัดที่สอง: บันทึกทั้งสองเส้นในแฟ้มและโหลดผ่านf=(!!).iterate... l: <filename.hs>จากนั้นคุณสามารถโทรหาf [[1,1,1],[2,3,4]] 3ฯลฯ
nimi

ฉันไม่แน่ใจว่าฉันจะยอมรับสิ่งนี้ว่าเป็นฮาเซลที่ถูกต้องบรรทัดบนสุดเป็นนิยามฟังก์ชันและต้องการการปรับเปลี่ยนเพื่อใช้ใน REPL แต่บรรทัดที่ 2 สามารถใช้ได้เฉพาะใน REPL
Daniel Hill

@DanielHill: มีหัวข้อเกี่ยวกับเมตาซึ่งอนุญาตให้ใช้ฟังก์ชันที่ไม่มีชื่อซึ่งขึ้นอยู่กับฟังก์ชันผู้ช่วยทั่วโลก
nimi

2

CJam, 17 16 ไบต์

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

รูปแบบอินพุตเป็นเมทริกซ์แรก (เป็นอาร์เรย์ 2D สไตล์ CJam) และจำนวนการวนซ้ำในภายหลัง

ทดสอบที่นี่

คำอธิบาย

ปรากฎว่านี่เป็นทางออกเดียวกับคนอื่น ๆ :

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

อย่างจริงจัง 20 ไบต์

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

ใช้อินพุตเมทริกซ์ (เป็นรายการ 2D) จากนั้น Nแล้ว ส่งออกรายการ 2D

รุ่นนี้ใช้งานไม่ได้กับล่ามออนไลน์ด้วยเหตุผลบางอย่าง แต่ทำงานได้กับการท้าทายก่อนหน้านี้นี้ก่อนกระทำที่ท้าทาย

เวอร์ชันที่ใช้งานออนไลน์ได้ 23 ไบต์:

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

รับอินพุตตามลำดับตรงกันข้าม ( Nจากนั้นเมทริกซ์)

ลองออนไลน์!

ฉันจะเพิ่มคำอธิบายหลังจากนอนหลับไปซักพัก การแก้ไขข้อบกพร่องล่ามนั้นไม่สนุก


1

Pyth, 13 12 ไบต์

u+Rs>2dCGyEQ

ลองออนไลน์ ชุดทดสอบ

ใช้อัลกอริทึมเดียวกันกับคำตอบส่วนใหญ่ ใช้เป็นอินพุตเมทริกซ์เป็นอาร์เรย์ 2D บนบรรทัดแรกและnที่สอง

คำอธิบาย

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 ไบต์

ฉันสับสนก่อนด้วยวิธีการจัดทำดัชนีแฟนซีของ Matlab (เช่นA(end+1,:)=sum...) ก่อนที่ฉันจะคิดว่าในกรณีที่หายากนี้การต่อข้อมูลอย่างง่าย ๆ นั้นถูกกว่าจริงใน Matlab เสียดายที่ฉันต้องแปลงมันให้เป็นฟังก์ชั่นจริง ควรทำงานกับอ็อกเทฟเช่นกัน

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

ฉันคิดว่านี่เป็นตัวอย่างสำคัญของวิธีที่จะไม่สร้างอัลกอริทึม สำหรับ A = 2x2, n = 1,000 อัลกอริทึมนี้ใช้เวลา 5 วินาทีบนแล็ปท็อปของฉัน, n = 2000 มันเกือบ 50 วินาที! (หรือประมาณ 30 วินาทีถ้า A เป็นการgpuArrayขอบคุณ Quadro 1000M ที่ไว้ใจได้ของฉัน)


ฉันไม่มีสำเนาของ Matlab ฉันสามารถใช้สิ่งนี้ภายใต้ GNU ระดับแปดเสียงได้หรือไม่ ถ้าเป็นเช่นนั้นคุณสามารถให้คำแนะนำ?
Digital Trauma

1
ใช่ฉันเรียกมันว่า Matlab เพราะมันไม่ได้ใช้ฟังก์ชั่นเฉพาะของ Octave เพียงวางไว้ในไฟล์ชื่อ fm และเรียกใช้เช่นf([0,1;2,3],1000)
Sanchises

ฉันเห็น. 1) f.mบันทึกเป็น 2) octaveเริ่มต้น 3) วางload f.m; f([1,1,1;2,3,4],3)ในพรอมต์ REPL - ใช้ได้กับฉัน
บาดเจ็บทางดิจิตอล

ถ้าคุณพูดเช่นนั้น! ฉันใช้เว็บไซต์ออนไลน์ระดับแปดเสียงเท่านั้นดังนั้นจึงไม่มีความคิดว่ามันจะทำงานอย่างไร ฉันจะดูว่าฉันสามารถคิดจากที่นั่น
Sanchises

1

Java, 2179 ไบต์

เพิ่งทำงานออก: - รหัสนี้เป็นภาษาจาวา

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
ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ! คำถามถูกติดแท็กcode-golfซึ่งหมายความว่าคำตอบแข่งขันกันเพื่อเขียนในจำนวนที่สั้นที่สุดของรหัสที่เป็นไปได้ (เป็นไบต์) คำตอบของคุณอาจแก้ปัญหาได้ดี แต่ฉันเห็นความพยายามเพียงเล็กน้อยในการ "เขียนรหัส" (เช่นทำให้สั้นที่สุด) มีโอกาสเล็กน้อยที่จะทำเช่นนี้กับโค้ดของคุณเช่นตัวแปรที่มีชื่อ 1 อักขระและการลบช่องว่างที่ไม่จำเป็นออก นอกเหนือจากนั้นคุณสามารถอ่านเคล็ดลับเหล่านี้โดยเฉพาะสำหรับจาวา
Digital Trauma

... ดูtag-wiki ของ code-golfโดยเฉพาะฉันจะตอบ code golf ได้อย่างไร? คำใบ้ใด ๆ มาตรา. นอกจากนี้โปรดทราบว่าจาวานั้นยากต่อการเล่นรหัสสั้น ๆ เมื่อเทียบกับภาษาอื่น ๆ สิ่งนี้ไม่ควรทำให้คุณผิดหวัง - ถ้าคุณมีคำตอบจาวาอย่างดีก็มีแนวโน้มที่จะได้รับความนิยมแม้ว่ามันจะยาวกว่าคำตอบอื่น ๆ ก็ตาม อย่าถูกไล่ออกจากคำตอบทั้งหมดของ esolang สั้น ๆ ที่น่าเหลือเชื่อ - ชุมชนนี้มีแนวโน้มที่จะเก่งเรื่องการใช้ภาษา
Digital Trauma

@ DigitalTrauma- ขอบคุณ ... ที่ช่วยฉันในฐานะ newbee สำหรับเรื่องนี้ ... ฉันจะผ่านการเชื่อมโยงและสร้างรหัสใหม่ขึ้นมา ...
Dhruv Govila

เนื่องจากคุณเป็นผู้ใช้ใหม่ฉันใช้เสรีภาพในการแก้ไขคำตอบของคุณเพื่อการจัดรูปแบบที่ดีขึ้น โดยเฉพาะอย่างยิ่งก) ชื่อเรื่องที่ชัดเจนระบุภาษาและจำนวนไบต์ b) การจัดรูปแบบรหัสของรหัสของคุณ ในทุกไซต์ stackexchange การจัดรูปแบบโค้ดนั้นง่ายเพียงแค่นำหน้าโค้ดทั้งหมดของคุณด้วยช่องว่าง 4 ช่อง ในความเป็นจริงยิ่งง่ายขึ้น - ในกล่องแก้ไขเลือกรหัสของคุณจากนั้นคลิก{}ที่ด้านบนของกล่องแก้ไข - สิ่งนี้จะทำการนำหน้านี้โดยอัตโนมัติ
Digital Trauma

โอเค ... ฉันจะตรวจสอบมันออกไป ...
Dhruv Govila

1

Python, 103 105ไบต์

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

ฟังก์ชั่นที่ไม่ระบุชื่อใช้รายการของรายการและส่งผ่านไปยังฟังก์ชั่นซ้ำ fฟังก์ชั่นที่ไม่ระบุชื่อรับรายการของรายการและส่งผ่านไปยังฟังก์ชันเวียนเอาท์พุทเป็น transposed แล้วส่งผ่านไปfอีกครั้งแล้วเอาท์พุทของไปที่สองจะถูกเปลี่ยนอีกครั้ง ผลลัพธ์คือรายการของสิ่งอันดับ

บันทึกสองไบต์ด้วยbakuriu


1
n>0อาจเป็นnเพราะคุณเริ่มต้นด้วยการบวกnและเมื่อคุณถึง0ค่าของมันเป็นเท็จ
บาคุริว


0

Perl 6 ,  87 73  71 ไบต์

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

การใช้งาน:

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

วางลงในนี้ทำให้ผมมีข้อผิดพลาดบางperl6 ฉันเป็นนักเล่นเพอร์เซลล์ - ฉันทำผิดอะไร
Digital Trauma

@ DigitalTrauma ฉันขอโทษฉันควรจะเขียนการใช้งานmy &code = ->\c,\m{ … }เพื่อให้ชัดเจนว่า ->\c,\m{ … }จำเป็นต้องเปลี่ยนด้วยรหัสข้างต้น ฉันมักจะใช้พารามิเตอร์ตัวแทนโดยนัย$_หรือ@_หรือชัดเจน$^aเพราะพวกเขามีแนวโน้มที่จะสั้นกว่า ฉันไม่ได้คิดเรื่องนี้ นอกจากนี้ตรวจสอบให้แน่ใจว่าคุณใช้รุ่นใหม่เพียงพอ ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills

@DigitalTrauma คุณสามารถไปที่# perl6 channel บน freenode.net และใช้ camelia (เช่นนี้)เพื่อเรียกใช้โค้ด (นำหน้าบรรทัดด้วยm: และช่องว่าง) คุณยังสามารถ msg camelia ได้โดยตรง
Brad Gilbert b2gills
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.