StringTemplate - это шаблонная библиотека для генерации структурированного текста. Имеет функциональные черты, любит чистоту, немножко ленив, но заставляет выносить логику в модель.
Отчёт тут:
http://rsdn.ru/Forum/Message.aspx?mid=2
![]() | You are viewing Log in Create a LiveJournal Account Learn more |
Undesigned unfriendly pageRecent Entries | |||||||||||||||||||||||||||
|
|
You are viewing the most recent 21 entries.
17th August 2007
: StringTemplate креатифчик
StringTemplate - это шаблонная библиотека для генерации структурированного текста. Имеет функциональные черты, любит чистоту, немножко ленив, но заставляет выносить логику в модель. Отчёт тут: http://rsdn.ru/Forum/Message.aspx?mid=2 Current Mood:
22nd May 2007
: Fantasy general
Эхх ностальгия... Пытался скачать сабж с http://free-game-downloads.mosw.com/ Чтобы оттуда скачать, нужно прочитать это
и поступить самым остроумным способом :-)) UPD: Нет, самым остроумным способом поступают товарищи с fgd. Скачиваем даунлоадер (Касперский молчит), и с помощью него скачиваем игру. Current Mood:
1st February 2007
: Тухлятина для дуракоф!
LaPerouse Ай кросавчег, ай да молодец. Так даже Влад не жог: Видите ли, те языки, о которых вы говорите (C++, Pascal) в представлении многих являются классическими процедурными языками, что нет ничего недопустимого в усилении этого термина, которое более предпочтительно по сравнению с введением нового термина – “функциональный язык”. Исходя из того, что сказано мной выше, едва ли справедливо выделять из процедурных группу функциональных языков, тут, скорее, нужно говорить о “функциональном подходе” и о языках, наиболее эффективно поддерживающих этот подход. Все-таки основным критерием функционального подхода является то, о чем я говорил выше – отношение к хранению состояния. Вот он, постамент, на котором зиждется вся теория и практика функционального программирования, тот самый “пятый элемент”, придающий особый колорит этому стилю. Стоит только разрешить изменение переменных в любом “функциональном языке” и внешние ссылки на эти переменные (которое не нужно даже специальным образом вводить), и этот язык неуловимо для глаз превратится в стандартный процедурный язык. Все остальное – синтаксические конструкции, помогающие объявлять вложенные конструкции функций, встроенные в сам язык возможности для обработки списков и т п — все это для дураков, чтобы дать им почувствовать всю “революционность” и крутизну “новейшего” подхода. Да! Я утверждаю, что за роскошной вывеской прячется тухлятина, которой уже как минимум 50 лет. И готов это доказать любому, пусть и придется пожертвовать частью личного времени на восполнение пробелов в чужом образовании. http://rsdn.ru/forum/Message.aspx?mid=2 Даже если и так, я согласен чувствовать себя полным дауном читая не то что протухшие, а наверное уже разложившиеся листы рассылки erlang и haskell cafe. ^_^ Current Mood:
17th December 2006
: О прибыльном говне
Я комплители дизаппоинтед. Мы тут обсуждаем эрланг с его девятью девятками, ищем методы снижения количества ошибок и как можно более раннего их обнаружения (классическая тема для флейма: static vs dynamic typing), тем самым предполагая неявно, что чем меньше ошибок - тем лучше. Но есть места, где это не нужно... Нед слофф Current Mood:
13th December 2006
: Много слов про Эрланг
Сообщение, в котором я пытаюсь обрисовать, то что джавов и дотнетов много, а Эрланг весь такой один. Получилось очень большим. http://rsdn.ru/Forum/Message.aspx?mid=2 В обсуждении уже есть кое-что новенькое:
Я знал, что это возможно, но не знал, что для "всех методов у всех библиотек" достаточно 3-х строчек кода. Разбираюсь, сейчас гляжу в доку по инструментированию JVM. Вижу только горячий апгрейд методов, но магических 3-х строчек не вижу. Попутно жду железобетонных доводов "в реальных задачах такие ужимки и прыжки не нужны, и обычные потоки рулят"... ;-) Current Mood:
10th December 2006
: graphviz
(Пора возрвратить к жизни эту запылившуюся страничку) Есть надежда, что в rsdn скоро можно будет вставлять в сообщения dot-нотацию. То есть то же самое, что и со смайликами, только для включений вроде таких:
То есть вместо этого текста сгенерируется картинка и вставится в сообщение (по крайней мере предполагается так). http://rsdn.ru/Forum/Message.aspx?mid=2 Current Mood:
Current Music: pzycho bitch - sweet kiss
2nd September 2006
: Functional Programming For The Rest Of Us
Мой перевод неплохой на мой взгляд статьи http://www.defmacro.org/ramblings/fp.ht Данная статья достаточно кратко и вполне доступно, используя примеры на Java (!), знакомит читателя с базовыми понятиями функционального программирования. ( Пожалуйте подт кадт ^_^ ) Current Mood:
15th May 2006
: Рекурсивный перебор k-подмножеств
(Уфф, эти срочные проекты вышибли из колеи больше чем на месяц). Хочу наконец закончить эстетствовать с перебором k-элементных подмножеств. Задачу сформулирую в наиболее общем виде: дан список (чего угодно), сформировать список всех его k-элементных подсписков.
Здесь текущее множество формируется из начала B и некоторого куска длины K из списка-конца E. В граничных условиях (когда нужно перебрать все 1-элементные подмножества, или E-элементные подмножества из E) задача решается непосредственным перебором, а в общем случае - рекурсивно. Красивое, компактное, хоть и не самое эффективное решение.
Пока всё на этом. Current Mood:
31st March 2006
: Перебор k-элементных подмножеств n-элементного множества
Да, вот такая простая задача. Везде видел решения рекурсией, но в один прекрасный момент (был он где-то 4 года назад) наткнулся на супербыстрый вариант без рекурсии:
Идея очень проста: увеличиваем элемент с индексом p на единичку, пока он не станет больше n. Когда этот последний элемент станет больше p, мы отодвигаем p биже к началу и заполняем элементы с p-го до k-го последовательно. Этот алгоритм я и попытался изобразить на Эрланге (единственное отличие, что множество пришлось выписывать наоборот, потому что инкрементировать голову намного легче, чем хвост):
Выводит
Current Mood:
21st March 2006
:
Задача: нужно перебрать следующие последовательности, перебор зависит от параметров m и n, где каждый элемент может принимать значения не больше m, всего элементов может быть не больше n, и они невозрастают.
Первый вариант:
Недостаток в том, что это нифига не эффективно, ибо splitwith проезжает по списку при каждом апдейте списка. Плохо. Фторой вариант: фторого варианта пока нет... :-) Тем не менее работает:
Current Mood:
13th March 2006
: Ещё табличка для оформления сорцов
<table border=1 cellspacing=1 bgcolor="lightgrey"><tr><td><pre> Здесь идёт супер-пупер код </pre></td></tr></table> Наверное на этом варианте и остановлюсь. Current Mood:
: Строка для медитации
Я выпал в осадок (довольно давно, надо сказать). Когда растворился обратно и подумал, что ЭТО нужно записать. Такая вот маленькая неприментная строчечка из J4C:
Массив-результат обладает следующим свойством: r[i] это количество элементов равных y[i] с индексами меньшими i. То есть y[1] == 6, и r[1]==1 означает, что до этой шестёрки есть ещё только одна. Генри Рич, комментируя этот глагол, говорит очевидные вещи, а неочевидные - не говорит :-) Так что пришлось самому. В результате многочасового t это порядковый номер соответствующего элемента в y, есть термин такой, "ординал", так вот: t[i] это ординал y[i]-го. Убедиться в этом достаточно просто, скажу только что эта задача в Этюдах не продержалась и одного дня. Всё множество элементов в y делятся на классы эквивалентности, а именно y1 и y2 попадают в один класс тогда и только тогда, когда они равны. t обладает следующим свойством: для каждого класса эквивалентности соответствующие ординалы начинаются с самого левого элемента и идут последовательно. Выделенное было ключом для моего понимания. Смотрите сами: если бы было
то это не противоречило бы определению глагола /:, однако вся конструкция бы рассыпалась. (i.~y) это (y i. y). Важно то, что здесь классы эквивалентности помечаются отдельными числами:
Отмечу свойства x: x[i] <= i (очевидно) и числа-метки есть индекс первого числа соответствующего класса эквивалентности (это следует просто из определения i.). Вот теперь ключевой момент: пусть задан какой-нибудь класс эквивалентности I (множество индексов). Утверждения: Для любого i1, i2 \in I => y[i1]==y[i2]. Есть минимальный индекс im, im \in I. В t значения на этих индексах идут по порядку, t[im] самый маленький. В x значения на этих индексах равны im: x[i]==im для всех i \in I. Следовательно, z =. x { t будет z[i]==t[im] для всех i \in I. Следовательно, разность r = t - z будет принимать последовательные значения r[i] = 0, 1, .. ,k на индексах i \in I. Вот и всё. Спустя некоторое время это станет мегаочевидно, и врядли будет стоить столько слов, сколько я сейчас накатал. Но сейчас оно того стОит! Тацитная форма
Quiz: как избавиться от дублирования ([:/:/:)? Current Mood:
18th January 2006
: Про управление персоналом.
Не хотелось сюда постить околопрограммистские ссылки, но эта зацепила К вопросу об эффективном управлении персоналом (впервые увидел у kmmbvnr, респект!) Current Mood:
16th January 2006
: Какая классная фракталина!
http://www.ewartshaw.co.uk/jwhat.ht
{&'#.' @ (2:<|) @ ((+*:)^:400 0:) (18 %~ i:_20) j.~/ 28 %~ _59+i.75
...........................................................................
...........................................................................
...........................................................#...............
...........................................................................
........................................................#..................
.......................................................##..................
.....................................................######................
.....................................................######................
......................................................####.................
............................................#....##############............
............................................##.##################.###......
.............................................#######################.......
.........................................#.#########################.......
..........................................###########################......
........................................###############################....
...............................#........##############################.....
...........................########....################################....
..........................###########..###############################.....
.........................#############.##############################......
......................#..#############.##############################......
...################################################################........
......................#..#############.##############################......
.........................#############.##############################......
..........................###########..###############################.....
...........................########....################################....
...............................#........##############################.....
........................................###############################....
..........................................###########################......
.........................................#.#########################.......
.............................................#######################.......
............................................##.##################.###......
............................................#....##############............
......................................................####.................
.....................................................######................
.....................................................######................
.......................................................##..................
........................................................#..................
...........................................................................
...........................................................#...............
...........................................................................
...........................................................................
Надо будет как-нить это в пикселях отобразить. Красиво ведь, а! UPD: Под линуксами выдаёт непонятно что! :crash: Нужно поковырять, что к чему... Current Mood:
6th January 2006
: Эксперименты с форматированием
Ruby small piece of code
class Person
attr_accessor :name, :age
def initialize(name, age)
@name = name
@age = age.to_i
end
def inspect
"#@name (#@age)"
end
end
p1 = Person.new('elmo', 4)
p2 = Person.new('zoe', 7)
p1 # -> elmo (4)
p2 # -> zoe (7)
или можно так
второй кусок наверное симпатичнее, ы? <table><tr><td bgcolor="gray"> </td><td> </td><td><pre> тут идёт кусок кода </pre></td></tr></table> Интересно, какому гению в какое место пришёл этот дурацкий синтаксис html: <? Current Mood:
4th January 2006
: Вы думаете я буду про Новый Год? Щазззззз
А я про J. Некоторое время я пребывал в состоянии блаженной уверенности, что любой глагол записанный в явной форме можно записать в неявной. Нужно только немножечко хорошенько подумать. Но оказывается, всё чуть-чуть сложнее: t =. 4 : '0 (x.) } y.' 2 t i.5 0 1 0 3 4 О сколько нам открытий чудных... (А.С.Пушкин) Current Mood:
28th December 2005
: Reverse Engeneering just for fun.
Эту штуку я запнул на rsdn в "Декларативное программирование", но для полноты картины сюда тоже решил. Взять запостить в список рассылки erlang-questions, что ли. Может быть аффтару, Urban Boquist-у будет приятно... Итак, что мы видим сначала? Большую буковку "ё".
-module(e).
-export([main/1]).
-import(lists,[all/2]).
-define(t(A,B),B
andalso A).
f(E,R,L,A,N,G) ->
if E>G->{c,N};L>G->f(E+1,R,R,R,N,G);A>G->c(
R,N,G);true->case g(E,L,N)of g->f(E,R,L+1,R,N,G
);_->b(G,E,A,R,N,L)end end. d(A,B)->h(3#21,B,A). h(
A,B,C)->case f(C, C,C,C,[{C-1,C-1,a}|B],A
+2)of{c,D}->e(A+ 1,TL(lists:sort((D))));
_->fail end. main (A)->d(1,A). b(E,R,L,A,
N,G)when L>E->f( R,A,G,L,N,E);b(L,A,N,G,
E,R)->V=round(math:sqrt(L)),C=fun(I)->(I-1)div V*V end,D=fun
({_,_,Q})->N/=Q end,case?t(all(D,[{I,O,S}||{I,O,S}<-E,A==I]),
?t(all(D,[{I,S,O}||{I,S,O}<-E,R==S]),all(D,lists:filter(fun({
O,S,_})->?t(C(A)
<O,?t(O=<C(A)+V,
?t(C(R)<S,S=<C(R
)+V)))end,E))))of true
->f(A,G,R+1,G,[{A ,R,N}|E
],L);_->b(L,A,N+1, G,E,R)end.
a(D,{C,A})->[[B|| {_,_,B}<-C]|
e(D-1,A)]. e(_,[ ])->[];e(E,L)
->a(E+1,lists:split(E+1,L)). c(_,[{_,_,a}|_],_)->b
;c(B,[{R,K,N}|S],A)->f(R,B,K,N+1,S,A);c(_,[],_)
->b. g(B,A,[{B,A,_}|_])->g;g(_,_,[])->h;g(B
,A,[_|C])->g(B,A,C).
Прекрасно. Ломаем её отступами:
-module(e).
-export([main/1]).
-import(lists, [all/2]).
-define(t(A, B), B andalso A).
f(E, R, L, A, N, G) ->
if
E > G -> {c, N};
L > G -> f(E+1, R, R, R, N, G);
A > G -> c(R, N, G);
true -> case g(E, L, N) of
g -> f(E, R, L+1, R, N, G);
_ -> b(G, E, A, R, N, L)
end
end.
d(A, B) -> h(3#21, B, A).
h(A, B, C) ->
case f(C, C, C, C, [{C - 1, C - 1, a} | B], A + 2) of
{c, D} -> e(A + 1, tl(lists:sort((D))));
_ -> fail
end.
% A is list like [{1,3,8},{1,4,4},{1,7,3},{1,8,5},{2,6,1}, ... ].
main(A) -> d(1, A).
b(E, R, L, A, N, G) when L > E->
f(R, A, G, L, N, E);
b(L, A, N, G, E, R) ->
V = round(math:sqrt(L)),
C = fun(I) -> (I - 1) div V * V end,
D = fun({_, _, Q}) -> N /= Q end,
case
?t(all(D, [{I, O, S} || {I, O, S} <- E, A == I]),
?t(all(D, [{I, S, O} || {I, S, O} <- E, R == S]),
all(D, lists:filter(
fun({O, S, _}) ->
?t(C(A) < O, ?t(O =< C(A) + V, ?t(C(R) < S, S =< C(R) + V)))
end, E))))
of
true -> f(A, G, R + 1, G, [{A, R, N} | E], L);
_ -> b(L, A, N + 1, G, E, R)
end.
a(D, {C, A}) -> [[B || {_, _, B} <- C] | e(D - 1, A)].
e(_, []) -> [];
e(E, L) -> a(E + 1, lists:split(E + 1, L)).
c(_, [{_, _, a} | _], _) -> b;
c(B, [{R, K, N} | S], A) -> f(R, B, K, N + 1, S, A);
c(_, [], _) -> b.
g(B, A, [{B, A, _} | _]) -> g;
g(_, _, []) -> h;
g(B, A, [_|C]) -> g(B, A, C).
Итак, расставили отступы... Дааа, жуть. Ищем main. Спасительной информацией для понимания является то, что main принимает в качестве параметра список троек {Строка, Столбец, Номер}. Функция main на редкость простая. Смотрим дальше: ага, там функция d просто вызывает h. Двигаемся дальше, к определению функции h. Видим, что к первому параметру A прибавляются 1 и 2, но функция h больше нигде не вызывается. Это даёт нам право немного модифицировать вызов функции h и её саму:
main(List) -> h(7 + 2, List, 1).
h(Size, List, I) ->
case f(I, I, I, I, [{I - 1, I - 1, a} | List], Size) of
{c, D} -> e(Size - 1, tl(lists:sort((D))));
_ -> fail
end.
(3#21 это просто число 7, такой вот способ записи, явно для запудривания мозгов). Далее рассматриваем мешанину символов... Вдруг - о! - что-то знакомое: функция g - это явно поиск пары в списке. Эта функция вызывается только из f. Первые 2 параметра у g - это номера строки и столбца ячейки. Следовательно, список параметров f уточняется до: f(Rw, R, Cl, A, L, Size) -> ...Что такое R и A здесь - пока непонятно. Функцию g перепишем в более удобоваримом виде:
find_cell(Rw, Cl, [{Rw, Cl, _} | _]) -> found;
find_cell(_, _, []) -> not_found;
find_cell(Rw, Cl, [_|L]) -> find_cell(Rw, Cl, L).
Смотрим на параметр R у функции f. Он при первом вызове получает значение 1, затем появляется в функции b под именами A (первое "тело") и G (второе "тело") и в функции с под именем B, но при этом никогда не принимает нового значения! Переименовываем его в I (потому что I похожа на единичку) где только можно. Нужно только позаботиться об отсутствии коллизии имён в функции b. Мешает макрос. Макрос в баню, тогда условие в case можно записать так (здесь я уже переименовал A->Rw и R->Cl исходя из соответствия функции f):
all(D, [{I, O, S} || {I, O, S} <- E, Rw == I] andalso
all(D, [{I, S, O} || {I, S, O} <- E, Cl == S] andalso
all(D, lists:filter(
fun({O, S, _}) ->
C(Rw) < O andalso O =< C(Rw) + V andalso C(Cl) < S andalso S =< C(Cl) + V
end, L))
(Чтобы не заставлять читателя лезть в доку: выражение [X || X <-List, P(X)] означает "все X из списка List, для которых предикат P(X) выдаёт true").
Возникает интересное подозрение... Посмотрим, что выдаёт C(X):
1> C=fun(X)->(X-1) div 3 * 3 end. #Fun<erl_eval.6.43886099> 2> lists:map(C, lists:seq(1,9)). [0,0,0,3,3,3,6,6,6] Ага! А функция D проверяет, не равна ли ячейка числу N. Да, это оно! Это условие выражает основное правило Судоку: число в текущей ячейке не должно совпадать ни с одним из чисел в строке, ни в столбце и ни в соответствующем текущей ячейке квадрате. Теперь _очень пристально_ смотрим на параметр A у функции f. Видно, что он используется очень активно и он попадает в функцию b (2 тело) под именем N, на котором и завязано условие. Всё ясно - это номер в текущей ячейке. Далее, переименовываем параметры у функций b и c так, чтобы они соответствовали параметрам f. Получим (опуская несущественные пока детали):
f(Rw, I, Cl, Nm, L, Size) -> ....
b(Size, Rw, Nm, I, L, Cl) -> ....
...
c(I, [{Rw, Cl, Nm} | L], Size) -> f(Rw, I, Cl, Nm + 1, L, Size);
...
Итак, ещё раз: Rw, Cl - координаты текущей ячейки, Nm - текущий номер, L - список троек, Size - в данном случае всегда 9, I - в данном случае всегда 1. Снова пристально смотрим на f, что же она делает: Пристально смотрим на b, что делает она: Теперь по-русски. Функция f двигается по матрице справа налево, сверху вниз. Если в ячейке ещё пусто, то вызывается функция b. Функция b последовательно подбирает номер в текущей ячейке начиная с 1. Подбор заканчивается либо добавлением новой ячейки в список, либо передачей в f параметра Nm == 10. В последнем случае срабатывает условие:
Nm > Size -> c(I, L, Size);
Теперь понятно, что делает функция c. Функция c - это откат. Если головоломка не совсем банальная, то однажды процесс заткнётся тем, что в текущую ячейку невозможно будет вписать никакой номер от 1 до 9. В этом случае происходит откат: от списка "откусывается" головной элемент, и подбор продолжается со следующего номера. Остаются мелочи - функции a и e. e - это просто преобразование списка троек в матрицу. Список троек должен быть полным, иначе функция завалится. Функция a "откусывает" 9 троек и вытягивает их в линейный список. Можно избавиться от E+1, заменив на просто E, но тогда соответственно поменять и вызов в функции h. Долго ли, коротко ли, но окончательный вариант этого рефакторинга превратился в:
-module(e).
-compile(export_all).
%-export([main/1]).
% (1..10), 1, (1..10), (1..10), List, 9
set_cell(Rw, I, Cl, Nm, L, Size) ->
if
Rw > Size -> {done, L};
Cl > Size -> set_cell(Rw+1, I, I, I, L, Size);
Nm > Size -> rollback(I, L, Size);
true -> case find_cell(Rw, Cl, L) of
found -> set_cell(Rw, I, Cl+1, I, L, Size);
_ -> try_number(Size, Rw, Nm, I, L, Cl)
end
end.
% 9, List, 1
start(Size, List, I) ->
case set_cell(I, I, I, I, [{I - 1, I - 1, a} | List], Size) of
{done, L} ->
io:format("~w~n", [lists:sort(L)]), % отсебятина :-)
list2matr(Size, tl(lists:sort((L))));
_ -> fail
end.
% List is list like [{1,3,8},{1,4,4},{1,7,3},{1,8,5},{2,6,1}, ... ].
main(List) -> start(9, List, 1).
try_number(Size, Rw, Nm, I, L, Cl) when Nm > Size ->
set_cell(Rw, I, Cl, Nm, L, Size);
try_number(Size, Rw, Nm, I, L, Cl) ->
V = round(math:sqrt(Size)),
Cvv = fun(X) -> (X - 1) div V * V end,
Neq = fun({_, _, X}) -> Nm /= X end,
case
lists:all(Neq, [{R, C, N} || {R, C, N} <- L, Rw == R]) andalso
lists:all(Neq, [{R, C, N} || {R, C, N} <- L, Cl == C]) andalso
lists:all(Neq, lists:filter(
fun({R, C, _}) ->
Cvv(Rw) < R andalso R =< Cvv(Rw) + V andalso
Cvv(Cl) < C andalso C =< Cvv(Cl) + V
end, L))
of
true -> set_cell(Rw, I, Cl + 1, I, [{Rw, Cl, Nm} | L], Size);
_ -> try_number(Size, Rw, Nm + 1, I, L, Cl)
end.
% L1, L2 - lists, E - integer
extr_row(E, {L1, L2}) -> [[N || {_, _, N} <- L1] | list2matr(E, L2)].
% E - integer, L - list
list2matr(_, []) -> [];
list2matr(E, L) -> extr_row(E, lists:split(E, L)).
% 1, List, 9
rollback(_, [{_, _, a} | _], _) -> fail;
rollback(I, [{Rw, Cl, Nm} | L], Size) -> set_cell(Rw, I, Cl, Nm + 1, L, Size);
rollback(_, [], _) -> fail.
% (1..9), (1..9), List
find_cell(Rw, Cl, [{Rw, Cl, _} | _]) -> found;
find_cell(_, _, []) -> not_found;
find_cell(Rw, Cl, [_|L]) -> find_cell(Rw, Cl, L).
Пара замечаний:
1. Поиск здесь в глубину с возвратом, однако возврат выражается только в удалении новых троек из (текущего) списка. Сами вызовы в течение этого поиска "забираются" всё глубже и глубже в рекурсию. Тем не менее с памятью вообще и стеком в частности всё в порядке, потому что железно работает last call optimization. Слегка непривычно, совсем не так как в С??, где для отката нужно было бы выходить из текущего уровня рекурсии. (Но там и таскать с собой текущий список в качестве параметра тоже не нужно было бы). Хотя есть и альтернативные варианты: сделать так, чтобы функции set_cell и try_number возвращали пару {List, result}, или принимали List, а возвращали result. Тогда глубина рекурсии должна существенно уменьшиться. 2. Даже обфусцированные функциональные программы по-прежнему доступны для понимания, поскольку результат работы функции целиком зависит от параметров и можно на мгновение забыть вообще обо всей программе сконцентрировавшись только на этой функции. Также сильно облегчает анализ неизменность "забинженных" переменных - то бишь прозрачность ссылок (внутри функции куда ни ткни - везде Nm это Nm). Трудности пожалуй могут возникнуть в случаях"большой-пребольшой функции у которой много-премного параметров" и "много-премного переплетённых (взаимно-рекурсивных) функций у которых много-премного параметров". Собстно вот, ду хаст! Current Mood:
26th December 2005
: Маленькое усовершенствование для "домика Пи"
Как и раньше
pitriang =. ([:#~odd) ,/. pilist
pitriang 5
3
141
59265
3589793
238462643
u =. (- @ |."1 @ i.)
pitree = u |."0 1 pitriang
pitree 5
3
141
59265
3589793
238462643
Такой вот юз глагола "|." и рангов можно сказать ради юза. Напоследок ещё пара замечаний: u 5 _4 _3 _2 _1 0 -i.- 5 _4 _3 _2 _1 0 Конечно, второй вариант симпатичнее. Собственно, написал я первый вариант только ради того, чтобы поупражняться с рангами и "|.". Упражнение понравилось :-) Current Mood:
20th December 2005
: Новые, неизведанные глубины в J
Читал вот статью "Functional programming and the J programming language". Какую однака штуку я обнаружил: pprod =: +/ /. @ (*/) 1 2 pprod 1 3 1 1 5 7 2 Да. Всего-навсего. Это перемножение полиномов, заданных вектором коэффициентов. И что? Дальше интереснее. fndisplay выдаёт очевидно x (P Q@R) y +-------------+ |x _P_ Q_ R_ y| +-------------+ NB. в данном случае (+/ это P, /. это Q, */ это R Если мы это дело перепишем в виде (по-честному, со скобочками), получим линейкой по рукам: 1 2 +/ (/. (*/) 1 3 1) |syntax error | 1 2+/( /.(*/)1 3 1) Коробочный вариант однако немного проясняет ситуацию: pprod +----------+-+-----+ |+-----+--+|@|+-+-+| ||+-+-+|/.|| ||*|/|| |||+|/|| || |+-+-+| ||+-+-+| || | | |+-----+--+| | | +----------+-+-----+ Из этой картинки следует, что у нас вилка, согласно определению вилки x (P Q R) y (x _P_ y) _Q_ (x _R_ y) x */ y даёт табличку, затем применяется (+/ /.) к этой табличке, а не к исходным аргументам (почему? возможно из-за @). Ну и полученный вектор выводится на экран.Короче, парсинг строк с причастиями - это какой-то магический кристалл. Неужели предсказать поведение луча света в нём могут только маги? Где тот тайный манускрипт, который бы подробно и обстоятельно раскрыл механизм парсинга выражения J? fndisplay конечно хорошо, но мало. Current Mood:
16th December 2005
: Пи домиком
Какую я красивую штуку нашёл, ну просто...
pi=: [: ": [: <.@o. 10x"_^]
pi_list=: [: pi [: <: [: *: ]
pi_triangle=: ([: #~ odd) ,/. pi_list
odd=: 1: + 2: * i.
pi_tree=: ([: - [: i. -@]) |."0 1 pi_triangle
pi_tree 16
3
141
59265
3589793
238462643
38327950288
4197169399375
105820974944592
30781640628620899
8628034825342117067
982148086513282306647
09384460955058223172535
9408128481117450284102701
938521105559644622948954930
38196442881097566593344612847
5648233786783165271201909145648
Ещё хорошая новость есть - код выше уже не выглядит простым набором символов, и я не впадаю в жёсткий тупняк, когда вижу такое. А даже наоборот, лишь некоторые места непонятны. :super: Последняя хорошая новость. Выложил на RSDN наконец то, что давно хотел выложить, да времени всё не было. Take a look and enjoy. ps: нужно фак читать по форматированию... Current Mood:
14th December 2005
:
Разбираюсь в интерфейсе LJ. Смешно, но тыкаюсь как слепой котёнок. И всё вроде бы легко, и многое непонятно. Нужно будет ещё повспоминать интересы (:-!) и настроить стартовую страницу, а то убого софсем...
Current Mood:
|
||||||||||||||||||||||||||