Розширення матриці в стилі Фібоначчі


25

Для кожного рядка, а потім стовпця матриці ми можемо додати додатковий запис із сумою останніх двох записів у цьому рядку чи стовпці. Наприклад, із такою вхідною матрицею:

[ 1 1 1 ]
[ 2 3 4 ]

Отриманою матрицею буде:

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

З огляду на введення цілого числа N та матрицю [X, Y] розміром не менше 2х2, виконайте вищенаведене розширення 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 Звичайно! Як я пропустив це? Спасибі!!
Луїс Мендо

Чи вбудований MATL для подвоєння числа?
Згарб

@ 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

К, 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}
СПП

3

Желе, 15 13 12 байт

-1 байт від @Dennis

ṫ-S;@"Z
ÇḤ}¡

Як і відповідь MATL @ 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

Я новачок хаскелл. Я отримав, наскільки sudo apt-get install haskell-platformя і запускаю відповідь, ghciяка дає мені Prelude> підказку. Коли я вставляю, o%m=m++[o(+)(last m)$last$init m]я отримую <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.
німі

1
@DigitalTrauma: о, є третій спосіб: дайте ім'я головній функції, наприклад, додайте a f=перед другим рядком: f=(!!).iterate...збережіть обидва рядки у файлі та завантажте його через l: <filename.hs>. Тоді ви можете зателефонувати f [[1,1,1],[2,3,4]] 3і т. Д.
nimi

Я не впевнений, що прийняв би це як дійсний haskell, верхній рядок - це визначення функції та потребує модифікації для використання в REPL, але другий рядок може бути використаний лише в REPL.
Даніель Хілл

@DanielHill: є мета про тему, яка дозволяє неназваних функцій, які залежать від глобальних допоміжних функцій.
німі

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

Приймає введення матриці (як двовимірний список), потім N. Виводить двовимірний список.

Ця версія чомусь не працює в Інтернетному перекладачі, але працює з цим зобов'язанням перед викликом .

Версія, яка працює в Інтернеті, на 23 байти:

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

Вводить в зворотному порядку ( N, потім матриця).

Спробуйте в Інтернеті!

Я додам пояснення після того, як я спатиму трохи часу. Робота навколо помилок інтерпретатора ніколи не є цікавою.


1

Pyth, 13 12 байт

u+Rs>2dCGyEQ

Спробуйте в Інтернеті. Тестовий набір.

Для більшості відповідей використовується той же алгоритм. Приймає як вхід матрицю як двовимірний масив у першому і 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

Матлаб, 60 байт

Я вперше возився з фантазійними методами індексації Матлаба (тобто A(end+1,:)=sum...), перш ніж зрозумів, що в цьому рідкісному випадку просте конкатенація насправді дешевше в 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 секунд! (або приблизно 30-х років, якщо A - це gpuArrayзавдяки моєму надійному Quadro 1000M)


У мене немає копії Matlab. Чи можу я запустити це під октавою GNU? Якщо так, чи можете ви дати інструкції?
Цифрова травма

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 - працює для мене.
Цифрова травма

Якщо ти так кажеш! Я використовую лише веб-сайт октави, тому не маю уявлення, як це має працювати інакше. Я побачу, чи зможу я там
поправитись

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
Ласкаво просимо до головоломки програмування та коду для гольфу! Питання позначене кодом-гольф, що означає, що відповіді змагаються, щоб писати якомога меншою кількістю коду (у байтах). Ваша відповідь цілком може вирішити проблему, але я бачу невелику спробу "гольфу" коду (тобто зробити його якомога коротшим). Існує маса тривіальних можливостей зробити це за допомогою вашого коду, наприклад, змінні з 1-знаковими іменами та видалення зайвого пробілу. Крім цього, ви можете прочитати ці поради, спеціально для java
Digital Trauma

... Погляньте на теги-вікі для коду-гольфу , особливо як я повинен відповісти на код-гольф? Якісь підказки? розділ. Також зауважте, що java, як відомо, важко гольфу до короткого коду, порівняно з багатьма іншими мовами. Це не повинно вас переконувати - якщо у вас добре знайдеться відповідь на Java, вона, ймовірно, буде досить популярною, навіть якщо вона довша за всі інші відповіді. Не відштовхуйтесь від усіх стислих коротких відповідей на esolang - ця громада, як правило, добре враховує мовні обмеження.
Digital Trauma

@ DigitalTrauma- Спасибі ... за те, що я допомогла мені як новачка у цьому ... Я обов'язково перейду посилання та придумаю новий код ...
Dhruv Govila

Оскільки ви новий користувач, я зумів відредагувати вашу відповідь для кращого форматування. Зокрема а) чіткий заголовок із зазначенням мови та кількості байтів, б) форматування коду вашого коду. На всіх сайтах stackexchange форматування коду легко - просто приставте всі кодові рядки з 4 пробілами. Насправді ще простіше - у полі редагування виберіть свій код, а потім натисніть {}на верхню частину поля редагування - це автоматично зробить цю префіксацію.
Цифрова травма

Гаразд ... я просто перевірю це ...
Dhruv Govila

1

Пітон, 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знову, потім результат другого переходу повторно транспонируется. Вихід - це список кортежів

Збережено два байти завдяки бакуріу


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 дає мені деякі помилки . Я початківець, що я задумався - що я роблю не так?
Цифрова травма

@DigitalTrauma Вибачте, що я повинен був записати використання, my &code = ->\c,\m{ … }щоб зрозуміти, що ->\c,\m{ … }потрібно замінити кодом вище. Зазвичай я використовую неявні $_або @_явні параметри заповнювача, $^aоскільки вони, як правило, коротші. Я просто не думав про це. Також переконайтеся, що ви використовуєте достатньо нову версію ( $*PERL.compiler.version !before 2015.12)
Бред Гілберт b2gills

@DigitalTrauma Ви також можете перейти на канал # perl6 на freenode.net і використовувати камелю (як це) для запуску коду (попередні рядки з m: пробілом) Ви також можете безпосередньо
надіслати
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.