green_fr: (Default)
[personal profile] green_fr
Продолжаем фанфик курса программирования в УБЗ. [livejournal.com profile] 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 — от одного вида этой функции меня бросает в дрожь, она официально забанена у нас на проекте. Поэтому нет, циклы Жизни можно, конечно, запихнуть в одну длинную строку, но этим я не буду заниматься даже ради фанфика!

Date: 2017-07-12 10:54 am (UTC)
From: [identity profile] cross-join.livejournal.com
Что делает запись на APL? Цикл ввода-вывода-то хоть есть?
На специализированном языке "Жизнь" программа была бы еще короче.

Date: 2017-07-12 10:59 am (UTC)
From: [identity profile] catpad.livejournal.com
Вообще там на странице всё подробно написано.

Насчёт специализированного языка. Можно, конечно, создать специальный язык, в котором будет встроенная функция Life(M, N), которая печатает N поколений исходной матрицы M. Это будет самая короткая реализация Жизни на свете!

Date: 2017-07-12 11:05 am (UTC)
From: [identity profile] cross-join.livejournal.com
Сравнивать надо сравнимое. APL специализированный язык для многомерных массивов, "Жизнь" туда входит прекрасно. MathLab менее специфичный (но все еще специализированный), запись на нем длиннее. Наконец, взяв языки общего назначения (универсальные) Паскаль, Питон или <подставьте свое> вы получите еще более длинную запись.

Date: 2017-07-12 11:37 am (UTC)
From: [identity profile] catpad.livejournal.com
Ну да, я и не спорю.

Date: 2017-07-13 09:04 pm (UTC)
From: [identity profile] xxxxx.livejournal.com
а зачем вы вообще матлабом пользуетесь? ну в смысле если уж питон не нравится, а нравится этот язык, есть же октав, в нём (a + b)(:) и подобная хрень работает

Date: 2017-07-13 10:24 pm (UTC)
From: [identity profile] green-fr.livejournal.com
Это долгий и бесплодный разговор :-) В двух словах - исторически сложилось именно так, а даже самые оптимистические аргументы других языков пока не перевешивают затраты на переучивание с переписыванием.

Profile

green_fr: (Default)
green_fr

March 2026

S M T W T F S
1234567
8 91011121314
15161718192021
22232425262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 11th, 2026 11:07 pm
Powered by Dreamwidth Studios