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


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 Конечно! Как я это пропустил? Благодарность!!
Луис Мендо

Есть ли в MATL встроенная функция удвоения числа?
Згарб

@ Згарб Нет. Вам нужно 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
ÇḤ}¡

Как и в ответе @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

Я новичок в Хаскеле. Я получил 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?
Цифровая травма

@DigitalTrauma: либо поместите o%m=...строку (и только эту строку) в файл с именем, скажем так fib-matrix.hs. Затем вы можете использовать :l fib-matrix.hsкоманду, ghciчтобы загрузить определения и вызвать функцию main, как описано в моем примере использования. - Или использовать let o%m=... in ( (!!). ... ) [[1,1,1]...] 3.
Ними

1
@DigitalTrauma: о, есть третий способ: дать главной функции имя, например, добавить f=перед второй строкой: f=(!!).iterate...сохранить обе строки в файле и загрузить его через l: <filename.hs>. После этого вы можете позвонить f [[1,1,1],[2,3,4]] 3и т.д.
Ними

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

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

2

CJam, 17 16 байтов

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

Формат ввода - это сначала матрица (в виде двумерного массива в стиле 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

Попробуйте онлайн. Тестирование.

Использует тот же алгоритм для большинства ответов. Принимает в качестве входных данных матрицу в виде двумерного массива в первой строке и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. Жаль, что мне пришлось преобразовать это в реальную функцию. Должен работать и с 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 - у меня работает.
Цифровая травма

Если ты так говоришь! Я использую только веб-сайт octave, так что понятия не имею, как это должно работать в противном случае Я посмотрю, смогу ли я оттуда
связаться

1

Ява, 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! Вопрос помечен как code-golf, что означает, что ответы конкурируют друг с другом и пишутся в кратчайшем объеме кода (в байтах). Ваш ответ вполне может решить проблему, но я вижу небольшую попытку «поиграть» в код (т.е. сделать его как можно короче). Существует множество тривиальных возможностей сделать это с вашим кодом, например, переменные с именами из 1 символа и удаление ненужных пробелов. Кроме того, вы можете прочитать эти советы, специально для Java
Digital Trauma

... Посмотрите на tag-wiki для code-golf , особенно Как мне ответить на code golf? Есть намеки? раздел. Также обратите внимание на то, что в java общеизвестно, что в коротком коде сложно играть в гольф по сравнению со многими другими языками. Это не должно вас отговаривать - если у вас хороший ответ на Java, он, вероятно, будет очень популярен, даже если он длиннее всех других ответов. Не отчаивайтесь на все изумительно короткие ответы esolang - это сообщество, как правило, хорошо учитывает языковые недостатки.
Цифровая травма

@ DigitalTrauma- Спасибо ... за то, что помогли мне как новичку в этом ... Я обязательно пройду по ссылкам и
придумаю

Поскольку вы новый пользователь, я позволил себе отредактировать ваш ответ для лучшего форматирования. В частности, а) четкий заголовок с указанием языка и количества байтов, б) форматирование кода вашего кода. На всех сайтах обмена стеками форматирование кода легко - просто поставьте перед всеми строками кода префикс 4 пробела. На самом деле это даже проще - в поле редактирования выберите свой код, а затем щелкните {}в верхней части окна редактирования - это автоматически сделает этот префикс.
Цифровая травма

Хорошо ... Я просто проверю это ...
Дхрув Говила

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

Сохранено два байта благодаря 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 - что я делаю не так?
Цифровая травма

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

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