Expansion de matrice de style Fibonacci


25

Pour chaque ligne puis colonne d'une matrice, nous pouvons ajouter une entrée supplémentaire avec la somme des deux dernières entrées de cette ligne ou colonne. Par exemple avec la matrice d'entrée suivante:

[ 1 1 1 ]
[ 2 3 4 ]

La matrice résultante serait:

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

Étant donné une entrée d'un entier N et une matrice [X, Y] de taille au moins 2x2, effectuez l'expansion N ci-dessus et sortez le résultat. La matrice résultante sera toujours de taille [X + N, Y + N].

Exemples:

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 ]

Réponses:


8

MATL , 13 14 15 16 20 21 octets

2*:"!tP2:Y)sv

Merci @Zgarb d'avoir supprimé 1 octet!

Essayez-le en ligne!

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
Je ne connais pas MATL, mais ne serait-il pas plus court de boucler des 2Ntemps que de boucler deux Nfois?
Zgarb

@Zgarb Bien sûr! Comment ai-je pu manquer ça? Merci!!
Luis Mendo

MATL a-t-il une fonction intégrée pour doubler un nombre?
Zgarb

@Zgarb Non. Vous avez besoin 2*(notation postfixée). Peut-être qu'il devrait avoir un caractère intégré, il est souvent utilisé. Aussi 2^(carré). Mais je manque d'espace de code :-)
Luis Mendo

6

J, 19 octets

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

Cela définit un adverbe, qui prend le nombre à sa gauche, et produit un verbe prenant la matrice à sa droite. Pour le deuxième exemple, il donne

  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

Explication

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

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

En action:

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

Essayez-le ici .


cela fonctionne toujours si vous supprimez le {xy}
début

3

Gelée, 15 13 12 octets

-1 octet par @Dennis

ṫ-S;@"Z
ÇḤ}¡

Comme la réponse MATL de @ LuisMendo, cela transpose le tableau avant de faire la transformation le long d'un axe. Par conséquent, nous devons appeler la fonction 2 * n fois.

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

Essayez-le ici .


2

ES6, 134 octets

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

Explication:

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

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

Exemple d'utilisation:

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

Comment ça marche:

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

Je suis un novice haskell. Je suis allé jusque sudo apt-get install haskell-platformet exécute le ghciREPL qui me donne une Prelude> invite. Quand je colle, o%m=m++[o(+)(last m)$last$init m]je reçois <interactive>:2:4: parse error on input '='. Pouvez-vous me donner une petite introduction soit en exécutant cela à partir d'un fichier source ou dans le REPL?
Digital Trauma

@DigitalTrauma: soit mettez la o%m=...ligne (et seulement cette ligne) dans un fichier appelé, disons fib-matrix.hs. Ensuite, vous pouvez utiliser la :l fib-matrix.hscommande in ghcipour charger les définitions et appeler la fonction principale comme décrit dans mon exemple d'utilisation. - Ou utiliser let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
nimi

1
@DigitalTrauma: oh, il y a une 3ème façon: donnez un nom à la fonction principale, par exemple ajoutez un f=devant la deuxième ligne :, f=(!!).iterate...enregistrez les deux lignes dans un fichier et chargez-le via l: <filename.hs>. Ensuite, vous pouvez appeler f [[1,1,1],[2,3,4]] 3, etc.
nimi

Je ne suis pas sûr que j'accepterais cela comme haskell valide, la ligne supérieure est une définition de fonction et doit être modifiée pour être utilisée dans le REPL, mais la 2e ligne ne peut être utilisée que dans le REPL.
Daniel Hill

@DanielHill: il y a un sujet sur la méta qui autorise les fonctions sans nom qui dépendent des fonctions d'assistance globales.
nimi

2

CJam, 17 16 octets

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

Le format d'entrée est la matrice en premier (sous forme de tableau 2D de type CJam) et le nombre d'itérations par la suite.

Testez-le ici.

Explication

Il s'avère que c'est la même solution que tout le monde:

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

Sérieusement, 20 octets

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

Prend alors la matrice (comme une liste 2D) N. Génère une liste 2D.

Cette version ne fonctionne pas sur l'interpréteur en ligne pour une raison quelconque, mais fonctionne avec cette validation préalable au défi .

Une version qui fonctionne en ligne, pour 23 octets:

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

Prend l'entrée dans l'ordre opposé ( N, puis matrice).

Essayez-le en ligne!

J'ajouterai une explication après un peu de sommeil. Travailler autour des bogues de l'interpréteur n'est jamais amusant.


1

Pyth, 13 12 octets

u+Rs>2dCGyEQ

Essayez-le en ligne. Suite de tests.

Utilise le même algorithme pour la plupart des réponses. Prend en entrée la matrice comme un tableau 2D sur la première ligne et nsur la deuxième ligne.

Explication

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 octets

J'étais d'abord en train de jouer avec les méthodes d'indexation sophistiquées de Matlab (c'est-à-dire A(end+1,:)=sum...) avant de penser que dans ce cas rare, la concaténation simple est en fait moins chère dans Matlab. Dommage que j'ai dû convertir cela en une fonction réelle. Devrait également fonctionner avec Octave.

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

Je suppose que c'est un excellent exemple de la façon de ne pas créer d'algorithmes. Pour A = 2x2, n = 1000 cet algorithme prend déjà 5 secondes sur mon portable, n = 2000 c'est presque 50 secondes! (ou environ 30s si A est un gpuArraymerci à mon fidèle Quadro 1000M)


Je n'ai pas de copie de Matlab. Puis-je l'exécuter sous GNU octave? Si oui, pouvez-vous donner des instructions?
Digital Trauma

1
Oui, je l'ai appelé Matlab car il n'utilise aucune fonction spécifique à Octave. Mettez-le simplement dans un fichier appelé fm et exécutez comme par exemplef([0,1;2,3],1000)
Sanchises

Je vois. 1) enregistrer sous f.m. 2) Commencez octave. 3) Coller load f.m; f([1,1,1;2,3,4],3)dans l'invite REPL - fonctionne pour moi.
Digital Trauma

Si tu le dis! J'utilise uniquement le site Web d'octave en ligne, donc je ne sais pas comment cela devrait fonctionner autrement. Je vais voir si je peux faire un permalien à partir de là
Sanchises

1

Java, 2179 octets

Juste travaillé: - Ce code est en langage 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
Bienvenue dans Programmation d'énigmes et Code Golf! La question est étiquetée code-golf, ce qui signifie que les réponses sont en compétition pour être écrites dans le plus petit nombre de codes possible (en octets). Votre réponse pourrait bien résoudre le problème, mais je vois peu de tentative de "jouer au golf" le code (c'est-à-dire le rendre aussi court que possible). Il existe de nombreuses opportunités triviales pour le faire avec votre code, par exemple des variables avec des noms à 1 caractère et la suppression des espaces inutiles. Au-delà de cela, vous pouvez lire ces conseils, spécifiquement pour java
Digital Trauma

... Jetez un œil au tag-wiki pour code-golf , en particulier le Comment dois-je répondre à un code golf? Des indices? section. Notez également que Java est notoirement difficile à jouer au short code, en comparaison avec de nombreuses autres langues. Cela ne devrait cependant pas vous dissuader - si vous avez une réponse java bien gérée, elle sera probablement très populaire, même si elle est plus longue que toutes les autres réponses. Ne vous laissez pas rebuter par toutes les réponses esolang extrêmement courtes - cette communauté a tendance à bien prendre en compte les handicaps linguistiques.
Digital Trauma

@ DigitalTrauma- Merci ... de m'avoir aidé en tant que débutant ... Je vais sûrement parcourir les liens et trouver un nouveau code ...
Dhruv Govila

Puisque vous êtes un nouvel utilisateur, j'ai pris la liberté de modifier votre réponse pour un meilleur formatage. En particulier a) un titre clair indiquant la langue et le nombre d'octets, b) le formatage du code de votre code. Sur tous les sites stackexchange, le formatage du code est facile - il suffit de préfixer toutes vos lignes de code avec 4 espaces. En fait, c'est encore plus simple - dans la zone d'édition, sélectionnez votre code, puis cliquez sur {}en haut de la zone d'édition - cela fera automatiquement ce préfixe.
Digital Trauma

D'accord ... je vais juste le vérifier ...
Dhruv Govila

1

Python, 103 105 octets

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

La fonction anonyme prend la liste des listes et passe à la fonction récursive f. La sortie est transposée puis frepassée, puis la sortie du second go est re-transposée. La sortie est une liste de tuples

Sauvegardé deux octets grâce à Bakuriu


1
n>0pourrait simplement l'être n, puisque vous commencez avec un positif net que lorsque vous atteignez 0sa valeur est faux.
Bakuriu


0

Perl 6 ,  87 73  71 octets

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

Usage:

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

Coller cela dans perl6 me donne quelques erreurs . Je suis un novice en Perl - que fais-je de mal?
Digital Trauma

@DigitalTrauma Je suis désolé, j'aurais dû écrire l'utilisation my &code = ->\c,\m{ … }pour indiquer clairement que les ->\c,\m{ … }besoins doivent être remplacés par le code ci-dessus. J'utilise généralement un paramètre d'espace réservé implicite $_ou @_explicite, $^acar il a tendance à être plus court. Je n'y ai tout simplement pas pensé. Assurez-vous également que vous utilisez une version suffisamment récente ( $*PERL.compiler.version !before 2015.12)
Brad Gilbert b2gills

@DigitalTrauma Vous pouvez également aller sur le canal # perl6 sur freenode.net et utiliser camelia (comme celui-ci) pour exécuter le code (précéder les lignes avec m: et un espace) Vous pouvez également msg camelia directement
Brad Gilbert b2gills
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.