green_fr (green_fr) wrote,
green_fr
green_fr

Categories:

APL vs MatLab pII

Продолжаем фанфик курса программирования в УБЗ. catpad выкатил игру «Жизнь» одной строчкой на APL:



Потратив некоторое время на поднятие челюсти восхищение чистым разумом, я задумался, как всё это выглядело бы на MatLab. На самом деле, отличия не сильные. Опять же, сохраняя обозначения исходного курса, разобьём на блоки:

M = zeros(5);
M(3, 2 : 4) = 1;
V = {-1, 1};
B2 = cellfun(@circshift, repmat({M}, 1, 4), [V, V], 'UniformOutput', false);
B3 = cellfun(@circshift, B2, [V, fliplr(V)], repmat({2}, 1, 4), 'UniformOutput', false);
B4 = cellfun(@circshift, repmat({M}, 1, 2), V, 'UniformOutput', false);
B5 = cellfun(@circshift, repmat({M}, 1, 2), V, repmat({2}, 1, 2), 'UniformOutput', false);
B6 = sum(reshape(cell2mat(B3), [size(B3{1}), numel(B3)]), 3) + plus(B4{:}) + plus(B5{:});
B7 = B6 == 2;
B8 = B7 & M;
B9 = B6 == 3;
B10 = B8 | B9

Буковок несомненно больше. В первую очередь из-за параметра UniformOutput для cellfun: в MatLab «матрица, содержащая матрицу» — это cell array, и для него операции несколько отличаются от операций с матрицами.

Вторая неприятность заключается в том, что я не умею складывать элементы cell array. Для B4 и B5 всё просто — можно использовать sum, принимающий не более двух элементов, а там их как раз два. Но вот для B3 случается неприятность — я её обхожу переформатированием cell array -> matrix 5×20 -> matrix 5×5x4, которую затем суммирую вдоль третьего измерения. Если кто-нибудь подскажет более элегантный способ суммирования, я буду очень ему крайне признателен.

Сборка результата не отличается практически ничем. Отмечу отсутствие «;» в строке с B10, заставляющее MatLab вывести на экран результат этой операции. Лично я (равно как и встроенный анализ синтаксиса mlint) считаю это крайне порочной практикой и обычно использую для вывода на экран disp.

Теоретически это можно даже собрать в одну строчку, но здесь возникает ещё одна проблема — MatLab не позволяет написать (a + b)(:) (применить оператор индексации не к переменной, а к результату операции). Это обходится через subsref, который, впрочем, я тоже считаю плохой практикой.

Не говоря уже о засовывании всего этого в строку и вызове eval — от одного вида этой функции меня бросает в дрожь, она официально забанена у нас на проекте. Поэтому нет, циклы Жизни можно, конечно, запихнуть в одну длинную строку, но этим я не буду заниматься даже ради фанфика!
Tags: matlab, УБЗ
Subscribe

  • «Хищные вещи века» и «Текст»

    Прослушал «Хищные вещи века» Стругацких. В детстве я их совсем не так понимал. Тогда книга казалось каким-то мрачным детективом: герой куда-то…

  • Акунин, Шекли, Абгарян

    Прочитал очередного Акунина — «Не прощаюсь». Очень хорошая книга. Не общим сюжетом — в очередной раз возродили главного героя, с кем не бывает.…

  • L'Anomalie

    В начале года был выпуск La Conversation Scientifique с совершенно ни о чём не говорящим названием «Que veut dire „être normal“?» (Что такое «быть…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 6 comments