フィボナッチスタイルの行列展開


25

マトリックスの各行と列に対して、その行または列の最後の2つのエントリの合計で追加のエントリを追加できます。たとえば、次の入力行列の場合:

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

回答:


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を知りませんが、2N2 N回ループするよりもループ時間を短くした方が良いでしょうか
ズガルブ

@Zgarbもちろん!どうして見逃したの?ありがとう!!
ルイスメンドー

MATLには、数字を2倍にするための組み込み機能がありますか?
ズガルブ

@Zgarbいいえ2*。必要です(後置記法)。おそらく1文字が組み込まれているはずで、よく使用されます。また2^(正方形)。しかし、コードスペースが不足しています:-)
ルイスメンドー

6

J、19バイト

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

これは、副詞を定義します。副詞は、左側に数字を取り、右側にマトリックスを取る動詞を生成します。2番目の例では、

  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バイト

@Dennisによる-1バイト

ṫ-S;@"Z
ÇḤ}¡

@LuisMendoのMATL回答のように、これは1つの軸に沿って変換を行う前に配列を転置します。したがって、関数を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

私はハスケル初心者です。私は、プロンプトを表示sudo apt-get install haskell-platformするghciREPLを実行していPrelude> ます。私はに貼り付けるときにo%m=m++[o(+)(last m)$last$init m]Iを得ます<interactive>:2:4: parse error on input '='。これをソースファイルから実行するか、REPLで実行するための簡単な入門書を教えてください。
デジタル外傷

@DigitalTrauma:o%m=...と呼ばれるファイルに行(およびこの行のみ)を挿入しますfib-matrix.hs。次に、:l fib-matrix.hsコマンドを使用しghciて定義をロードし、使用例で説明したようにメイン関数を呼び出すことができます。-または使用しますlet o%m=... in ( (!!). ... ) [[1,1,1]...] 3
-nimi

1
@DigitalTrauma:ああ、3番目の方法があります。たとえば、メイン関数に名前を付けます。たとえばf=、2行目の前にa を追加f=(!!).iterate...しますl: <filename.hs>。その後f [[1,1,1],[2,3,4]] 3、などを呼び出すことができます
-nimi

これを有効なhaskellとして受け入れるかどうかはわかりません。一番上の行は関数定義であり、REPLで使用するには変更が必要ですが、2行目はREPLでのみ使用できます。
ダニエルヒル

@DanielHill:グローバルヘルパー関数に依存する名前のない関数を許可するメタに関するトピックがあります。
-nimi

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。2Dリストを出力します。

このバージョンは、何らかの理由でオンラインインタープリターでは動作しませんが、このチャレンジ前のコミットでは動作しますます。

23バイトでオンラインで動作するバージョン:

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

入力を逆の順序(N、次にマトリックス)で受け取ります。

オンラインでお試しください!

しばらく寝てから説明を追加します。インタプリタのバグを回避することは決して楽しいことではありません。



1

Matlab、60バイト

A(end+1,:)=sum...このまれなケースでは、単純な連結がMatlabで実際に安価であることを理解する前に、Matlabの派手なインデックス付け方法(つまり)をいじっていました。残念ながら、これを実際の関数に変換する必要がありました。Octaveでも動作するはずです。

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オクターブで実行できますか?もしそうなら、あなたは指示を与えることができますか?
デジタル外傷

1
はい、Octave固有の機能を使用しないため、Matlabと呼びました。それを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プロンプトに貼り付け-私のために動作します。
デジタル外傷

あなたがそう言うなら!私はオクターブのオンラインWebサイトのみを使用しているため、それ以外の場合の動作方法はわかりません。そこからパーマリンクできるかどうかを確認します
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に関するこれらのヒント
デジタル外傷

... code-golfのtag-wiki、特にコードゴルフにどのように答えればよいですか?をご覧ください。ヒントはありますか?セクション。また、他の多くの言語と比較して、javaを短いコードにゴルフするのは難しいことで有名です。しかし、これはあなたを思いとどまらせるべきではありません-あなたがよくゴルフのJavaの答えを持っているなら、それは他のすべての答えよりも長くても、かなり人気がある可能性があります。心を痛めるほど短いエソランの答えに惑わされないでください。このコミュニティは言語障害を考慮に入れるのが得意です。
デジタルトラウマ

@ DigitalTrauma-おかげで...これまでnewbeeとして私を助けて...私は確かにリンクを介して行くよ、新しいコードを思い付く...
Dhruv Govila

あなたは新しいユーザーなので、より良い書式設定のために答えを自由に編集しました。特に、a)言語とバイト数を示す明確なタイトル、b)コードのコードフォーマット。すべてのstackexchangeサイトでは、コードの書式設定は簡単です。すべてのコード行の先頭に4つのスペースを付けるだけです。実際、さらに簡単に-編集ボックスでコードを選択し、編集ボックス{}の上部にあるをクリックすると、このプレフィックスが自動的に付けられます。
デジタル外傷

わかりました...私は...それをチェックアウトします
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。出力は転置されてからf再度渡され、2番目のgoの出力が再転置されます。出力はタプルのリストです

bakuriuのおかげで2バイト節約


1
n>0nあなたは正で始まり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初心者です-何が間違っていますか?
デジタル外傷

@DigitalTrauma申し訳ありませんが、上記のコードで置き換える必要があるmy &code = ->\c,\m{ … }ことを明確にするために 使用法を書いておくべき->\c,\m{ … }でした。私は通常、暗黙的$_または@_明示的なプレースホルダーパラメーターを使用します$^a。私はそれについて考えていませんでした。また、新しい十分なバージョン($*PERL.compiler.version !before 2015.12)を使用していることを確認してください
Brad Gilbert b2gills

@DigitalTraumaまた、上に行くことができます#のPerl6のの freenode.netと使用カメリアのチャンネル(このような)(に先行すると行のコードを実行するために、m: MSGカメリア直接あなたがすることもでき、スペースを)
ブラッド・ギルバートはb2gills
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.