斐波那契式矩阵展开


25

对于矩阵的每一行和每一列,我们可以添加一个额外的条目,并加上该行或列中最后两个条目的总和。例如,使用以下输入矩阵:

[ 1 1 1 ]
[ 2 3 4 ]

结果矩阵为:

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

给定整数N的输入和大小至少为2x2的[X,Y]矩阵,请执行上述扩展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 ]

Answers:


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 '16

@Zgarb当然!我怎么想念的?谢谢!!
路易斯·门多

MATL是否具有用于将数字加倍的内置功能?
Zgarb '16

@Zgarb号。您需要2*(后缀符号)。也许它应该内置一个字符,经常使用。也2^(正方形)。但是我用完了代码空间:-)
路易斯·门多

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

3

果冻15 13 12字节

-1字节@ @Dennis

ṫ-S;@"Z
ÇḤ}¡

就像@LuisMendo的MATL答案一样,这会在沿一个轴进行转换之前对数组进行转置。因此,我们需要调用该函数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 2016年

1
@DigitalTrauma:哦,有第三种方法:给主函数起个名字,例如f=在第二行前面加上一个:f=(!!).iterate...,将这两行保存在文件中并通过加载l: <filename.hs>。然后您可以致电f [[1,1,1],[2,3,4]] 3,等等
。– nimi

我不确定我是否将其接受为有效的haskell,最上面的一行是函数定义,需要进行修改才能在REPL中使用,但是第二行只能在REPL中使用。
丹尼尔·希尔

@DanielHill:有一个关于meta主题,它允许依赖全局助手函数的未命名函数。
nimi 2016年

2

CJam,17 16字节

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

输入格式首先是矩阵(作为CJam样式的2D数组),其次是迭代次数。

在这里测试。

说明

事实证明,这与其他所有人的解决方案相同:

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。输出二维列表。

由于某些原因,该版本无法在在线解释器上使用,但可以与挑战前提交一起使用

在线工作的版本,为23个字节:

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

以相反的顺序输入(N,然后输入矩阵)。

在线尝试!

睡一会儿后,我将添加一个解释。解决解释器错误从来都不是一件好事。


1

Pyth,13 12字节

u+Rs>2dCGyEQ

在线尝试。 测试套件。

对大多数答案使用相同的算法。在第一行和n第二行将矩阵作为2D数组作为输入。

说明

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个字节

A(end+1,:)=sum...在弄清楚这种罕见的情况下,简单串联实际上在Matlab中更便宜之前,我首先是在弄乱Matlab的精美索引方法(即)。太糟糕了,我不得不将其转换为实际功能。应该与八度一起工作。

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

我想这是如何创建算法的主要示例。对于A = 2x2,n = 1000,此算法在我的笔记本电脑上已经花费了5秒钟,n = 2000,将近50秒钟!(如果A是gpuArray我值得信赖的Quadro 1000M 的感谢,则大约为30秒)


我没有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提示中-对我有用。
Digital Trauma

如果你这么说!我只使用八度在线网站,所以不知道它应该如何工作。我看看是否可以从那里永久链接
Sanchises

1

Java,2179字节

刚解决:-此代码是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
欢迎来到编程难题和Code Golf!这个问题被标记为代码高尔夫,这意味着答案正在争相用尽可能短的代码(以字节为单位)编写。您的答案可能很好地解决了问题,但是我发现很少尝试“打入”代码(即使其尽可能短)。使用代码执行此操作有很多琐碎的机会,例如,具有1个字符的名称的变量,以及删除不必要的空格。除此之外,您还可以阅读这些技巧,专门针对Java
Digital Trauma

...查看代码高尔夫tag-wiki,尤其是我应该如何回答代码高尔夫球”?有什么提示吗?部分。还要注意,与许多其他语言相比,java众所周知很难精简为短代码。但是,这并不会让您感到困扰-如果您有一个很好的java答案,即使它比所有其他答案都长,它也很可能会很受欢迎。不要被所有弯弯曲曲的简短esolang答案所困扰-这个社区倾向于善于考虑语言障碍。
Digital Trauma '02

@ DigitalTrauma-谢谢...作为新手帮助我...我一定会通过链接并提出新的代码...
Dhruv Govila

由于您是新用户,因此我可以自由地编辑您的答案以获得更好的格式。特别是a)清晰的标题说明语言和字节数,b)代码的代码格式。在所有stackexchange网站上,代码格式化都很容易-只需在所有代码行前添加4个空格即可。实际上,甚至更容易-在编辑框中选择您的代码,然后单击{}编辑框顶部的-这将自动执行此前缀。
Digital Trauma '02

好吧...我将检查一下...
Dhruv Govila '16

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。输出转置后再传递到f第二个go的输出,然后重新转置。输出是元组列表

多亏了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 我给一些错误。我是perl新手-我做错了什么?
Digital Trauma

@DigitalTrauma对不起,我应该写出用法,my &code = ->\c,\m{ … }以明确表明 ->\c,\m{ … }需要用上面的代码替换。我通常使用隐式$_@_显式占位符参数,$^a因为它们通常更短。我只是没有考虑过。还要确保您使用的是足够新的版本($*PERL.compiler.version !before 2015.12
Brad Gilbert b2gills

@DigitalTrauma您也可以在freenode.net 上的#perl6频道上使用camelia (这样)来运行代码(以m:
开头的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.