<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CTAPbIu_MABP&#039;s BLOG &#187; algorithms</title>
	<atom:link href="http://mabp.kiev.ua/tag/algorithms/feed/" rel="self" type="application/rss+xml" />
	<link>http://mabp.kiev.ua</link>
	<description>энтузиазм = 1/опыт © Старый Мавр</description>
	<lastBuildDate>Thu, 26 Jan 2012 10:34:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>поменять переменные значениями</title>
		<link>http://mabp.kiev.ua/2011/05/24/swap-two-variables/</link>
		<comments>http://mabp.kiev.ua/2011/05/24/swap-two-variables/#comments</comments>
		<pubDate>Tue, 24 May 2011 13:24:47 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[perfomance]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1363</guid>
		<description><![CDATA[Поменять переменные значениями, в одну строку, без введения третьей переменной. var a = 1, b = 3; a = [b, b = a][0]; console.log(a, b); хз правда сколько при этом выделяется памяти на создание массива.]]></description>
			<content:encoded><![CDATA[<p>Поменять переменные значениями, в одну строку, без введения третьей переменной.</p>

<span id="more-1363"></span>

<pre><code class="javascript">
var a = 1, b = 3;
a = [b, b = a][0];
console.log(a, b);
</code></pre>

<p>хз правда сколько при этом выделяется памяти на создание массива.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2011/05/24/swap-two-variables/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hypotrochoid</title>
		<link>http://mabp.kiev.ua/2010/10/24/hypotrochoid/</link>
		<comments>http://mabp.kiev.ua/2010/10/24/hypotrochoid/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 20:19:11 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[2d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1276</guid>
		<description><![CDATA[Много чего полезного принес мне конкурс JS1k. Вот и сегодня разбирая одну из работ я приготовил материал для статьи. На самом деле стоило бы дать линк на эту работу но я его не знаю. То есть как, автор приготовил это для конкурса, но линк на работу не дал. В общем по результатам разбора примера, найден [...]]]></description>
			<content:encoded><![CDATA[<p>Много чего полезного принес мне конкурс <a href="http://js1k.com/home" rel="nofollow external">JS1k</a>. Вот и сегодня разбирая одну из работ я приготовил материал для статьи.</p>
<span id="more-1276"></span>

<script src="/content/source/hypotrochoid.js" type="text/javascript"></script> 
<script src="/content/js/hypotrochoid.js" type="text/javascript"></script>

<p>На самом деле стоило бы дать линк на эту работу но я его не знаю. То есть как, автор приготовил <a href="http://mudcu.be/labs/JS1k/BreathingGalaxies.html" rel="nofollow external">это</a> для конкурса, но линк на работу не дал.</p>
<p>В общем по результатам разбора примера, найден проеб. При попытке оптимизировать отрисовку, оптимизация не случилась :)</p>
<p>То есть автор сделал как-то так</p>

<pre><code class="javascript">
setInterval(function(){
	while(25--){
		c.beginPath();
		x = ...
		y = ...
		if(a){
			c.moveTo(a, b);
			c.lineTo(x, y);
		}
		a = x
		b = y
		c.stroke()
	}
}, 16); 
</code></pre>

<p>пытаясь запихнуть в один интервал отрисовку нескольких линий, а надо было выкинуть beginPath и stroke за цикл</p>

<pre><code class="javascript">
setInterval(function(){
	c.beginPath();
	while(25--){
		x = ...
		y = ...
		с[!!a?"lineTo":"moveTo"](x, y);
		a = x
		b = y
	}
	c.stroke()
}, 16)
</code></pre>

<p>Но я не об этом. Я тут приготовил пример на поиграться :)</p>

<div style="margin:auto;width:400px;height:400px;" id="hypotrochoid"></div>
<div style="text-align:center;">
<label for="outerRadius">радиус</label>
<input type="text" name="outerRadius" id="outerRadius" value="0.4005"/><br/>
<label for="">цвет HSL</label>
<input type="text" name="hue" id="hue" value="100"/><br/>
<input type="button" id="apply" value="зафигачить"/>
</div>

<p>Радиус, это дробное число до 0,5. Почему до 0,5? Потому что 0,2 = 0,8 и 0,4 = 0,6. Ну вы поняли они зеркальные. Чтобы звездочка начала крутиться советую добавить 0,005. Наслаждайтесь :)</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2010/10/24/hypotrochoid/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Кубик Маврика</title>
		<link>http://mabp.kiev.ua/2009/07/13/mabps-cube/</link>
		<comments>http://mabp.kiev.ua/2009/07/13/mabps-cube/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 09:33:58 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1089</guid>
		<description><![CDATA[Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже квадрат на плоскости развернуть. Но терпение и труд все перетрут, наверное ;) Вторая редакция кубика не имеет ничего общего с первой. Все полностью переделано. Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера был на редкость плодотворный день, я таки дописал свой кубик. напомню что сначала я не мог даже <a href="http://mabp.kiev.ua/2009/07/10/square-mavrevicha/">квадрат</a> на плоскости развернуть. Но терпение и труд все перетрут, наверное ;)</p>
<span id="more-1089"></span>
<p>Вторая редакция кубика не имеет ничего общего с <a href="http://mabp.kiev.ua/2009/07/12/cube-mauritius/">первой</a>. Все полностью переделано.  Теперь вместо того чтобы высчитывать углы наклонов и поворотов рёбер от угла поворота куба, я решил сделать так, как делается в нормальнйо трехмерной графике. Нарисовать сцену, положить в координаты [0,0,0] центр куба, по векторам высчитать вершины и нарисовать между ними линии. Что собственно с успехом и реализовал.</p>

<script type="text/javascript" src="/content/source/cube/cube-0.2.js"></script>
<script type="text/javascript" src="/content/source/excanvas.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>теперь как видите ничего нигде не точит и все прекрасно отображается. пришлось конешно пошаманить, прописать все углы, ребра и векторы но зато теперь все идеально. Куб можно изменять в размерах, отдалять и приближать "камеру", красить в произвольный цвет и все это при помощи настроек.</p>

<p>По просьбе Adw0rd'a выкладываю сырцы которые все это генерируют:</p>

<pre><code class="javascript">
Cube = function(options){
	this.init(options);
}

Cube.prototype = {
	
	color : "#000000", // цвет граней
	plot : null, // 2d context
	size : 10, // размер куба
	focalLens : 0, // расстояние от центра куба до камеры
	theta : [0,0], // углы поворотов по осям в радианах
	V2d : [[],[]], // вектора в двухмерной проекции
	
	T : [], // Translation vector
	E : [[],[]], // Edges
	R : [[],[],[]], // Rotation matrix
	V : [[],[],[]], // Vertices

	init : function(options){
		
		for (var i in options)
			this[i] = options[i];
			
		if(!this.focalLens)
			this.focalLens = this.plot.canvas.width;
			
		var self = this;
		document.onmousemove = function(event){
			self.theta = [event.clientX / 100, event.clientY / 100];
			self.draw();
		}			
			
		this.createScene();
		this.draw();
	},
	
	createScene : function (){
		var s = this.size;
		
		this.V = [
			[-s, s, s,-s,-s, s, s,-s],
			[-s,-s, s, s,-s,-s, s, s],
			[-s,-s,-s,-s, s, s, s, s],
		];
		
		this.E = [
			[0,1,2,3,4,5,6,7,0,1,2,3],
			[1,2,3,0,5,6,7,4,4,5,6,7],
		];
		
		this.R = [
			[1,0,0],
			[0,1,0],
			[0,0,1],
		];
		
		this.T = [0,0,0];
	},

	updVertices : function (){
		var x, y, z;
		
		for(var i=0;i&lt;8;i++){
			x=this.R[0][0]*this.V[0][i]+this.R[0][1]*this.V[1][i]+this.R[0][2]*this.V[2][i]+this.T[0];
			y=this.R[1][0]*this.V[0][i]+this.R[1][1]*this.V[1][i]+this.R[1][2]*this.V[2][i]+this.T[1];
			z=this.R[2][0]*this.V[0][i]+this.R[2][1]*this.V[1][i]+this.R[2][2]*this.V[2][i]+this.T[2];

			this.V2d[0][i]=this.plot.canvas.width/2+x*this.focalLens/z;
			this.V2d[1][i]=this.plot.canvas.height/2+y*this.focalLens/z;
		}
	},


	setTransformation : function (x, y, z, anglex, angley){
		var 
		sx = Math.sin(anglex),
		cx = Math.cos(anglex),
		sy = Math.sin(angley),
		cy = Math.cos(angley);
		
		this.R = [
			[ cx   , 0 ,  sx],
			[ sx*sy, cy, -cx*sy],
			[-sx*cy, sy,  cx*cy],
		];
		this.T = [x,y,z];
	},

	drawModel : function (){
		this.plot.beginPath();
		this.plot.strokeStyle=this.color;
		for(var i=0;i&lt;12;i++){
			this.plot.moveTo(this.V2d[0][this.E[0][i]],this.V2d[1][this.E[0][i]]);
			this.plot.lineTo(this.V2d[0][this.E[1][i]],this.V2d[1][this.E[1][i]]);
			this.plot.stroke();
		}
	},
	
	drawCells : function(){
		this.plot.fillStyle="black";
		for(var i=100,l=this.plot.canvas.width;i&lt;l;i+=100){
			this.plot.fillRect(0,i,l,1);
			this.plot.fillRect(i,0,1,l);
		}
	
	},

	draw : function (){
		var self = this;

		this.plot.clearRect(0,0,this.plot.canvas.width,this.plot.canvas.height);
		this.setTransformation(0.0, 0.0, 40.0, this.theta[0], this.theta[1]);
		this.updVertices();
		this.drawCells();
		this.drawModel();
	},
}


window.onload=function(){
	var plot = document.getElementById("cube").getContext("2d"),
	
	cube = new Cube({plot:plot,color:"#00FF00",size:10});
}
</code></pre>


<p>И еще три строчки HTML:</p>

<pre><code class="html">
&lt;script type="text/javascript" src="/content/source/cube-0.2.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="/content/source/excanvas.js"&gt;&lt;/script&gt;
&lt;div style="text-align:center;"&gt;&lt;canvas  id="cube" width="500" height="500"/&gt;&lt;/div&gt;
</code></pre>

<p>но это не конец, в следующей версии планируется натяжка текстур на грани и добавление света, или раскраска сторон с добавлением полупрозрачности, я еще не решил что буду делать.</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/13/mabps-cube/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Куб Маврикия</title>
		<link>http://mabp.kiev.ua/2009/07/12/cube-mauritius/</link>
		<comments>http://mabp.kiev.ua/2009/07/12/cube-mauritius/#comments</comments>
		<pubDate>Sun, 12 Jul 2009 13:56:20 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[cube]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1088</guid>
		<description><![CDATA[Название изначально задумывалось как "Кубик Маврика", на подобие с Кубиком Рубика, но Google перевел его как "cube mauritius", что означает "Куб Маврикия", так и оставил. После записи о вращении квадрата я немного полистал учебники по геометрии, и даже "основы учебного академического рисунка", и поднабрался знаний по поводу того что и как должно быть. И вот [...]]]></description>
			<content:encoded><![CDATA[<p>Название изначально задумывалось как "Кубик Маврика", на подобие с Кубиком Рубика, но <a href="http://mabp.kiev.ua/tag/google/">Google</a> перевел его как "cube mauritius", что означает "Куб Маврикия", так и оставил.</p>

<p>После записи о <a href="http://mabp.kiev.ua/2009/07/10/square-mavrevicha/">вращении квадрата</a> я немного полистал учебники по геометрии, и даже "основы учебного академического рисунка", и поднабрался знаний по поводу того что и как должно быть. И вот пришло время поделится этим с вами.</p>
<span id="more-1088"></span>

<p>Я решил что до того как рисовать красивые полупрозрачные грани неплохо было бы научится вращать вершины. Чем собственно и занялся. Четыре точки вращаются в трех плоскостях. Но там немного хитро по оси OX вращение происходит при передвижении мышки вперед назад, а по оси OY и/или OZ происходит при передвижении мышки из стороны в сторону и зависит от того на какой грани лежит куб.</p>

<p>Развлекаемся:</p>
<script type="text/javascript" src="/content/source/cube/cube-0.1.js"></script>
<script type="text/javascript" src="/content/source/excanvas.js"></script>
<div style="text-align:center;"><canvas  id="cube" width="500" height="500"/></div>

<p>Весь код показывать не буду, если захотите посмотрите, но главную функцию, которая рассчитывает позиции вершин обязательно надо показать.</p>

<pre><code class="javascript">
function(){
	var data = [],
	dim = this.dimension,
	o = this.theta;
	for (var x = -dim; x <= dim; x += 2 * dim)
		for (var y = -dim; y <= dim; y += 2 * dim)
			for (var z = -dim; z <= dim; z += 2 * dim){
				var 
				a = x * Math.cos(o.x) - y * Math.sin(o.x),
				b = x * Math.sin(o.x) + y * Math.cos(o.x),
				c = b * Math.cos(o.y) - z * Math.sin(o.y),
				d = b * Math.sin(o.y) + z * Math.cos(o.y);
				data.push({
					left : 250 + a * (d + 2) * 50,
					top  : 250 + c * (d + 2) * 50,
				});
			}
	return data;
}
</code></pre>

<p>Единственным недостатком такого способа расчета координат есть то, что если поставить куб так чтобы взгляд шел сразу по двум граням, то дальняя вершина, которая должна сливаться с передней (то есть взгляд должен идти по ребру) сильно выходит за рамки куба. Но я так понял что я не первый кто пользуется этим способом, так что думаю что ничего страшного.</p>
<p>В планах на ближайшее будущее новый куб у которого ничего никуда не вылазит.</p>

]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/12/cube-mauritius/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Code WTF: JavaScript HTML entities</title>
		<link>http://mabp.kiev.ua/2009/07/06/code-wtf-javascript-html-entities/</link>
		<comments>http://mabp.kiev.ua/2009/07/06/code-wtf-javascript-html-entities/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 20:14:32 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1083</guid>
		<description><![CDATA[Увидел у Вадима Войтюка в блоге задачку и задело. Это ж делается в одну строку! Ну максимум в две. 10 десять минут дела и один профтык с функцией escape() и все готово. В общем вот что получилось: var text = "'s&#60;d\"f&#62;g'q".replace(new RegExp("['\"&#60;&#62;\&#38;]", 'g'), function(s) { return {'':'&#38;gt;','&#38;':'&#38;amp;','"':'&#38;quot;','\'':'&#38;#039;'}[s]; }); alert(text); // &#38;#039;s&#38;lt;d&#38;quot;f&#38;gt;g&#38;#039;q А запостил тут, потому [...]]]></description>
			<content:encoded><![CDATA[<p>Увидел у <a href="http://voituk.kiev.ua/2009/07/02/javascript-html-entities/" rel="nofollow external">Вадима Войтюка</a> в блоге задачку и задело. Это ж делается в одну строку! Ну максимум в две. 10 десять минут дела и один профтык с функцией escape() и все готово.</p>
<span id="more-1083"></span>
<p>В общем вот что получилось:</p>
<pre><code class="javascript">
var text = "'s&lt;d\"f&gt;g'q".replace(new RegExp("['\"&lt;&gt;\&amp;]", 'g'), function(s) {
	return {'<':'&amp;lt;','>':'&amp;gt;','&amp;':'&amp;amp;','"':'&amp;quot;','\'':'&amp;#039;'}[s]; 
});
alert(text); // &amp;#039;s&amp;lt;d&amp;quot;f&amp;gt;g&amp;#039;q
</code></pre>

<p>А запостил тут, потому что воевать с парсером каментов у него в блоге мне лень.</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/06/code-wtf-javascript-html-entities/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Максимум-минимум</title>
		<link>http://mabp.kiev.ua/2009/07/02/maximum-minimum/</link>
		<comments>http://mabp.kiev.ua/2009/07/02/maximum-minimum/#comments</comments>
		<pubDate>Thu, 02 Jul 2009 09:08:30 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1080</guid>
		<description><![CDATA[Из названия можно подумать что я собираюсь грузить вас высшей математикой, на самом деле нет. Задача стояла простая, есть два элемента: внешний который задает область и внутренний, обозначающий предмет. При клике на внешнем надо было ставить внутренний центров в место клика. Если клик был слишком близко к краю внешнего элемента внутренний должен стать вплотную к [...]]]></description>
			<content:encoded><![CDATA[<p>Из названия можно подумать что я собираюсь грузить вас высшей математикой, на самом деле нет.</p>
<p>Задача стояла простая, есть два элемента: внешний который задает область и внутренний, обозначающий предмет. При клике на внешнем надо было ставить внутренний центров в место клика. Если клик был слишком близко к краю внешнего элемента внутренний должен стать вплотную к краю, а не вышел краем за пределы внешнего.</p>
<p>Вот живая демонстрация, только тут для наглядности добавлен еще один элемент он отмечает область в которой внутренний элемент будет "прилипать" к краю внешнего.</p>
<span id="more-1080"></span>

<link rel="stylesheet" type="text/css" media="screen" href="/content/css/maximum-minimum.css"/>
<script type="text/javascript" src="/content/js/maximum-minimum.js"></script>

<div id="outer">
	<div id="color"></div>
	<div id="inner"></div>
</div>

<div style="height:400px;"></div>
<p>Не смотря на то что там всего пара строчек кода, их написание заняло у меня очень много времени(((</p>

<pre><code class="javascript">
jQuery(document).ready(function($){
	$("#outer").mousedown(function(e){
		var elt = $("#inner"),
		self = $(this),
		top = Math.min(Math.max(0, e.pageY - self.offset().top - elt.height() / 2), self.height() - elt.height()),
		left = Math.min(Math.max(0, e.pageX - self.offset().left - elt.width() / 2), self.width() - elt.width());
		elt.css({top:top,left:left});
		//console.log({top:top,left:left});
	});
});
</code></pre>

<p>Разберу самую интересную строчку</p>

<pre><code class="javascript">
top = Math.min(Math.max(0, e.pageY - self.offset().top - elt.height() / 2), self.height() - elt.height())
</code></pre>

<p>Её можно расписать как</p>
<pre><code class="javascript">
var
// относительная координата нажатия
pointY = e.pageY - self.offset().top,
// верхний отступ
// если половина высоты внутреннего больше 
// расстояния от края до клика, то берем 0,
// иначе берем точку клика минус половину высоты
max = Math.max(0, pointY - elt.height() / 2),
// нижний отступ
// если высота внешнего элемента минус высота внутреннего
// меньше точки клика, то берем ее, иначе точку клика
top = Math.min(max, self.height() - elt.height());
</code></pre>
<p>Можно еще переписать на ифах, но так вообще не красиво</p>
<pre><code class="javascript">
var pointY = e.pageY - self.offset().top,
top = 0;

if(top < pointY - elt.height() / 2)
	top = pointY - elt.height() / 2;

if(top > self.height() - elt.height())
	top = self.height() - elt.height();
</code></pre>

<p>Все тоже самое действительно и для координат по оси X</p>
]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/07/02/maximum-minimum/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Дата Пасхи</title>
		<link>http://mabp.kiev.ua/2009/04/17/date-of-easter/</link>
		<comments>http://mabp.kiev.ua/2009/04/17/date-of-easter/#comments</comments>
		<pubDate>Fri, 17 Apr 2009 09:57:06 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[applet]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=1061</guid>
		<description><![CDATA[Попалась мне как-то на глаза цитата с баша (из бездны) "Пасха рассчитывается по формуле Гаусса: a = [(19 * [Y / 19] + 15) / 30], где Y - год, [] - остаток от деления; b = [(2 * [Y / 4] + 4 * [Y / 7] + 6 * a + 6) / [...]]]></description>
			<content:encoded><![CDATA[<p>Попалась мне как-то на глаза цитата с баша (из бездны)</p>
<pre>
"Пасха рассчитывается по формуле Гаусса:
a = [(19 * [Y / 19] + 15) / 30], где Y - год, [] - остаток от деления;
b = [(2 * [Y / 4] + 4 * [Y / 7] + 6 * a + 6) / 7];
Если (a + b) > 10, то Пасха будет (a + b - 9) апреля ст. стиля, в противном случае — (22 + a + b) марта ст. стиля. Дата Пасхи может попадать в период от 22 марта до 25 апреля по ст. стилю (от 4 апреля до 8 мая по н. стилю)."
Гаусс не только великий ученый но и священный математик =)
</pre>
<span id="more-1061"></span>
<p>Я, как известно, человек не очень религиозный, но меня это заинтересовало. Тем более что паска не за горами. Алгоритм уже есть, осталось только его реализовать, а это всего пару строчек кода. Затык был только один - преход с Юлианского календаря на Григорианский. Согласно википедии переход на <a href="http://ru.wikipedia.org/wiki/Григорианский_календарь" rel="nofollow external">Григорианский календарь</a> был произведен папой римским Григорием XIII 4 октября 1582. Но не все поддержали эту инициативу и переход длился 346 лет с 1582 по 1928 год. Вот это нихуясебе не могли договориться! Но поскольку Пасхой заведует папа то я решил что моментом перехода будет считаться 1582 год, Пасха в котором была по "старому" стилю.</p>
<p>Чтобы алгоритм с цифрами не смотрелся совсем одиноко я оформил небольшой апплет, который высчитывает Пасху в нашей эре, тоесть время до рождества не доступно, да и собственно не нужно, потому что Пасху тогда не отмечали. Сначала вы посмотрите код, а потом сможете посчитать когда была Пасха например в год вашего рождения.</p>

<pre><code class="java">
package ua.kiev.mabp;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Date;
import java.text.SimpleDateFormat;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 17.04.2009
 * Time: 10:15:29
 */

public class Easter extends Applet  implements ActionListener {

    private String date;
    private TextField tf;

    public void init() {
        setSize(300,100);
        String year = new SimpleDateFormat("yyyy").format(new Date());
        date = calculate(Integer.parseInt(year));
        tf = new TextField (year, 20);
        add(tf);
        Button btn = new Button("Calculate!");
        btn.addActionListener(this);
        add(btn);
    }

    public void paint(Graphics g) {
        g.drawString(date, 40, 50);
    }

    public void actionPerformed(ActionEvent event) {
        String year = tf.getText().replaceAll("[^\\d]","");
        tf.setText(year);
        date = !year.isEmpty() ? calculate(Integer.parseInt(year)) : "Enter valid year, please!";
        repaint();
    }

    public static String calculate(int year){

        int a = (19 * (year % 19) + 15) % 30;
        int b = ( 2 * (year % 4) + 4 * (year % 7) + 6 * a + 6) % 7;

        int oldDate = (a + b) > 9 ? (a + b - 9) : (22 + a + b);
        String oldMonth = (a + b) > 9 ? " april" : " march";

        int newDate;
        String newMonth;
        if((a + b) > 9){ // апрель
            newDate = oldDate + 13 > 30 ? oldDate + 13 - 30 : oldDate + 13;
            newMonth = oldDate + 13 > 30 ? " may" : " april";
        }else{ // март
            newDate = oldDate + 13 > 31 ? oldDate + 13 - 31 : oldDate + 13;
            newMonth = oldDate + 13 > 31 ? " april" : " march";
        }
        return year > 1582 ? newDate + newMonth : oldDate + oldMonth;
    }
}
</code></pre>

<p>Итак смотрите что у меня получилось в результате:</p>

<div style="text-align:center">
<APPLET CODEBASE="/content/source/" CODE= "ua.kiev.mabp.Easter" archive="Easter.jar" WIDTH="300" HEIGHT="100" ALT="Java не включена!">
</APPLET>
</div>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/04/17/date-of-easter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Счастливый билетик</title>
		<link>http://mabp.kiev.ua/2009/03/07/lucky-coupon/</link>
		<comments>http://mabp.kiev.ua/2009/03/07/lucky-coupon/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 12:03:26 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=813</guid>
		<description><![CDATA[Вчера речь зашла о 'счастливых талончиках', если кто на общественном транспорте не ездит то это такие талончики у которых серийный номер состоит из 6 цифр и сумма первых трёх равна сумме последних трёх. Так вот стало очень интересно какая вероятность того что тебе попадется 'счастливый талончик', для этого я решил написать функцию на PHP, но [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера речь зашла о 'счастливых талончиках', если кто на общественном транспорте не ездит то это такие талончики у которых серийный номер состоит из 6 цифр и сумма первых трёх равна сумме последних трёх. Так вот стало очень интересно какая вероятность того что тебе попадется 'счастливый талончик', для этого я решил написать функцию на <a href="http://mabp.kiev.ua/category/programming/php/">PHP</a>, но Apache под руками не оказалось и я написал на <a href="http://mabp.kiev.ua/category/programming/javascript/">JavaScript</a>. Сначала я думал что оптимальный алгоритм это разделение строки на две части, сложение цифр первой и второй половины, и сравнение.</p>
<span id="more-813"></span>
<pre><code class="javascript">
function is_lucky(num){
	num = num.toString(); // на всякий случай
	var l = num.length, part = [], sum = [0,0];
	if (l%2 || !/^[0-9]+$/.test(num))
		return false;
	part[0] = num.substring(0,l/2).split("");
	part[1] = num.substring(l/2,l).split("");
	for(var i in part)
		for(var j in part[i])
			sum[i] += parseInt(part[i][j]);
	return sum[0] == sum[1];
}
</code></pre>

<p>Но потом когда я думал как бы это выглядело на <a href="http://mabp.kiev.ua/category/programming/java/">Java</a>, я нашел способ попроще. Достаточно сложить все числа первой половины и отнять от полученного все числа второй половины, если в результате ноль то билетик счастливый.</p>

<pre><code class="javascript">
function is_lucky(num){
	var l = num.length, sum = 0;
	if (l%2 || !/^[0-9]+$/.test(num))
		return false;
	for(var i in num)
		sum += parseInt(num[i]) * (i&lt;l/2?1:-1);
	return !sum;
}
</code></pre>
<p>Реализация на PHP</p>
<pre><code class="php">
function is_lucky($num){
	$l = strlen($num);
	$sum = 0;
	if ($l%2 || !preg_match("/^[0-9]+$/", $num))
		return false;
	for($i=0;$i&lt;$l;$i++)
		$sum += $num[$i] * ($i&lt;$l/2?1:-1);
	return !$sum;
}
</code></pre>
<p>А еще я подумал что раз уж <a href="http://mabp.kiev.ua/category/programming/php/">PHP</a> и <a href="http://mabp.kiev.ua/category/programming/javascript/">JavaScript</a> языки нетипизированные то стоит проверять что засунули в функцию и добавил туда регулярку /^[0-9]+$/</p>

<p>Реализация на Java</p>
<pre><code class="java">
package ua.kiev.mabp;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 07.03.2009
 * Time: 11:40:21
 */

public class LuckyCoupon {
    public static void main(String[] args) {
        System.out.print(isLucky(463571));
    }

    public static Boolean isLucky(Integer num) {
        char[] c = num.toString().toCharArray();
        int sum=0;
        for (int i=0,l=c.length;i&lt;l;i++)
            sum += c[i] * (i&lt;l/2?1:-1);
        return sum==0;
    }
}
</code></pre>
<p>Но вернемся к тому зачем нам это нужно было, а нужно было посчитать количество счастливых билетиков. Для этого чуть усложним наш класс добавив в метод main цикл и дополнительный метод который из числа в формате '123' сделает число в формате '000123' и передаст на обработку уже имеющемуся методу для проверки.</p>
<pre><code class="java">
package ua.kiev.mabp;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 07.03.2009
 * Time: 11:40:21
 */

public class LuckyCoupon {
    public static void main(String[] args) {
        int counter = 0;
        for(int i=0;i&lt;1000000;i++)
            if (isLucky(i))
                counter++;
        System.out.print(counter);
    }

    public static Boolean isLucky(Integer num) {
        int l = 6 - num.toString().length();
        String str = "";
        for (int i=0;i&lt;l;i++)
            str += "0";
        return isLucky(str+num);
    }

    public static Boolean isLucky(String num) {
        char[] c = num.toCharArray();
        int sum=0, i=0, l=c.length;
        while (i&lt;l)
            sum += c[i] * (i++&lt;l/2?1:-1);
        return sum==0;
    }
}
</code></pre>
<p>В результате получим число 55252, далее пользуясь только калькулятором узнаем что 55252/1000000*100 = 5,5252% . То есть вероятность получить из рук кондуктора счастливый билетик чуть более чем пять с половиной процентов, а те кто играет в линейку или вов знают что это достаточно большой шанс.</p>

<p>Но удивляет другое удивляет симметричность появления таких числе, я хотел нарисовать график, но подумал что график на 1000 позиций будет очень большим поэтому приведу тут только часть матрицы. Ах да матрицы... Матрица получается в том случаи если посчитать сколько 'счастливых талончиков' в каждой тысяче, и записывать в ряд делая обрыв строки после каждого значения. В общем не с моим талантом объяснять смотрите и запускайте код. Этим надо заменить метод main из прошлого примера.</p>

<pre><code class="java">
    public static void main(String[] args) {
        int counter = 0;
        Integer[] num = new Integer[1000];
        for(int i=0;i&lt;1000000;i++)
            if (isLucky(i)){
                counter++;
                Integer d = ((Double)Math.floor(i++/1000)).intValue();
                if (num[d] == null)
                    num[d] = 0;
                num[d]++;
            }
        for (int i=0;i&lt;1000;i++){
            String str = num[i].toString();
            System.out.print((str.length()&lt;2?"0"+str:str) + (i%10==9?"\n":" "));
        }
    }
</code></pre>

<p>Так вот вернемся к матрице, она получаеться вот такая</p>

<pre>
01 03 06 10 15 21 28 36 45 55
03 06 10 15 21 28 36 45 55 63
06 10 15 21 28 36 45 55 63 69
10 15 21 28 36 45 55 63 69 73
15 21 28 36 45 55 63 69 73 75
21 28 36 45 55 63 69 73 75 75
28 36 45 55 63 69 73 75 75 73
36 45 55 63 69 73 75 75 73 69
45 55 63 69 73 75 75 73 69 63
55 63 69 73 75 75 73 69 63 55
</pre>

<p>Cледующая часть будет начинаться с 03 (06, 10, 15 ...) и заканчиваться на 63 (69, 73, 75...), тоесть самый правый столбик с каждым цыклом переходит в первый ряд и так пока 01 не окажеться в правом нижнем углу.</p>

<p>А в школе мне математика была не интересна...</p>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/03/07/lucky-coupon/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>HashMap Comparator</title>
		<link>http://mabp.kiev.ua/2009/02/20/hashmap-comparator/</link>
		<comments>http://mabp.kiev.ua/2009/02/20/hashmap-comparator/#comments</comments>
		<pubDate>Fri, 20 Feb 2009 15:58:19 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=779</guid>
		<description><![CDATA[Небольшое напоминание себе, чтоб не забыть, а то вот уже третий раз не могу найти этот код в проекте (потому что он большой и хреново структурированный), поэтому пишу его четвертый раз и выкладываю тут чтоб не забыть. Это пример как отсортировать HashMap по значениям, а еще это пример использования double braces initialization, хоть это никому, [...]]]></description>
			<content:encoded><![CDATA[<p>Небольшое напоминание себе, чтоб не забыть, а то вот уже третий раз не могу найти этот код в проекте (потому что он большой и хреново структурированный), поэтому пишу его четвертый раз и выкладываю тут чтоб не забыть. Это пример как отсортировать HashMap по значениям, а еще это пример использования double braces initialization, хоть это никому, по большому счету, и не надо.</p>
<span id="more-779"></span>
<pre><code class="java">
package com.incom;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 20 лют 2009 Time: 15:18:40
 */

public class HashMapComparatorTest {
	public static void main(String[] args) {
	Map map = new HashMap() {{
		put("one","first");
		put("two","second");
		put("three","third");
		put("four","fourth");
		put("five","fifth");
	}};
	List entryList = new ArrayList(map.entrySet());
	Collections.sort(entryList, new Comparator() {
		public int compare(Object o1, Object o2) {
			Map.Entry e1 = (Map.Entry) o1;
			Map.Entry e2 = (Map.Entry) o2;
			Comparable c1 = (Comparable) e1.getValue();
			Comparable c2 = (Comparable) e2.getValue();
			return c1.compareTo(c2);
		}
	});
	System.out.print(entryList);
	// [five=fifth, one=first, four=fourth, two=second, three=third]
	}
}
</code></pre>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/02/20/hashmap-comparator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Цепи Маркова</title>
		<link>http://mabp.kiev.ua/2009/01/27/markovs-chains/</link>
		<comments>http://mabp.kiev.ua/2009/01/27/markovs-chains/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 22:06:26 +0000</pubDate>
		<dc:creator>CTAPbIu_MABP</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[algorithms]]></category>
		<category><![CDATA[applet]]></category>

		<guid isPermaLink="false">http://mabp.kiev.ua/?p=537</guid>
		<description><![CDATA[Я что-то не особо любил учиться в школе, потом в институте, а сейчас в институте ничему не учат, приходишь два раза в год сдаёшь сессию и не заморачиваешься - заочный в общем. Тяжелее всего мне в школе давалась вышка и физика. Все, кто мне говорил, что вышка нужна для программирования посылались на хуй не задумываясь. [...]]]></description>
			<content:encoded><![CDATA[<p>Я что-то не особо любил учиться в школе, потом в институте, а сейчас в институте ничему не учат, приходишь два раза в год сдаёшь сессию и не заморачиваешься - заочный в общем. Тяжелее всего мне в школе давалась вышка и физика. Все, кто мне говорил, что вышка нужна для программирования посылались на хуй не задумываясь. Да на хуй вышка нужна быдлокодеру на <a href="http://mabp.kiev.ua/category/programming/html/">HTML</a> и <a href="http://mabp.kiev.ua/category/programming/php/">PHP</a>?! :D. Но вот не такое уже и большое время назад я понял, что было бы неплохо знать, о чем идет речь, когда читаешь статью о программировании. Все началось наверное когда я прочел об алгоритме сортировки <a href="http://ru.wikipedia.org/wiki/Быстрая_сортировка" rel="nofollow external">quicksort</a>. Потом мне как-то на глаза попалась заметка <a href="http://andrew-vasilkov.livejournal.com/38626.html" rel="nofollow external">Пылесос Kirby не удаляет пыль Фату с ковра Серпинского</a>, естественно полез узнавать что это такое :) Где-то посреди поисков нашел фразу "Пылесос Kirby не удаляет <a href="http://ru.wikipedia.org/wiki/Пыль_Фату" rel="nofollow external">пыль Фату</a> с <a href="http://ru.wikipedia.org/wiki/Ковёр_Серпинского" rel="nofollow external">ковра Серпинского</a> просыпанную из <a href="http://ru.wikipedia.org/wiki/Бутылка_Клейна" rel="nofollow external">бутылку Клейна</a>", еще один умный термин в копилку. Кстати больше никогда не буду упоминать бутылку Клейна в разговоре, не с моим талантом объяснять людям, что это такое. И одним из последних мне на глаза попался <a href="http://blog.nihilogic.dk/2008/09/mandelbrot-in-less-than-128-bytes-of.html" rel="nofollow external">фрактал Мандельброта</a>. Так вот к чему это я так долго веду... К тому что я в рамках собственного ликбеза и наполнения блога статьями по Java написал реализацию <a href="http://ru.wikipedia.org/wiki/Цепь_Маркова" rel="nofollow external">цепей Маркова</a>, а все вышесказанное плавно подводило к тому что это граф из высшей математики.</p>
<span id="more-537"></span>
<p>Мне тут уже мягко намекали что реализации этого алгоритма есть уже на всех языках программирования, потому что он используется (использовался?) для генерации дорвеев. Я не спорю, но это была неплохая возможность потренироваться, и добавить контента на сайт. Большую часть времени написания данного чуда составило аж никак не программирование и не высшая математика, а попытки настроить <a href="http://mabp.kiev.ua/tag/applet/">applet</a> так, чтоб эта зараза могла открывать локальные файлы. предупреждение об этом вы видели когда загрузили страницу и согласились, или не согласились, тогда вам нужно нажать ctrl+r.</p>
<p>Описания того как при помощи цепей Маркова генерировать тексты в сети полно, но я рискну повториться. Берем исходный осмысленный текст и раскладываем его на последовательности, для примера я взял скороговорку:</p>
<pre>Ехал Грека через реку.
Видит Грека в реке рак.
Сунул в реку руку Грека.
Рак за руку Грека - цап. </pre>
<br />
<p>После разложения она выглядит так:</p>
<br />
<pre>{
ехал=[грека],
грека=[через, в], 
через=[реку], 
реку=[видит, руку], 
видит=[грека], 
в=[реке, реку], 
реке=[рак], 
сунул=[грека], 
руку=[греку, рак]
рак=[за],
за=[руку], 
греку=[цап], 
}</pre>
<br />
<p>У нас получился массив слов, с парами которые могут идти после этих слов. Теперь задача обратная взять любое слово и начать строить из него  цепочку в которой каждое слово имело бы себе пару из списка. Я попробую построить без программы самую длинную цепочку не проходя дважды по одним и тем же комбинациям, начнем с несчастного Греки.</p>
<br />
<pre>Грека через реку видит Грека в реке рак за руку Греку цап.</pre>
<br />
<p>Смысла конечно в предложении не много, и от оригинала не сильно отличается, просто у нас очень короткий исходный текст. Посмотрев на этот набор слов мы удостоверились что все слова по парно стыкуются по падежам, и похожи на реальный текст. Но из 4 строчек много не нагенеришь, я тут давеча взял на lib.ru Войну и Мир (500 кб) и попробовал нагенерить пару страниц оттуда, получаются весьма забавные перлы! Но как правильно заметил один человек в Войну и Мир слово "кондиционер" не впихнешь. А еще, я надеюсь, это все таки он написал <a href="http://blog.promosite.ru/comments.php?336" rel="nofollow external">статью</a>, о том как отличить текст нагенеренный из <s>4 строчек</s> 30 килобайт исходного текста до целого мегабайта.</p>
<p>Так, пока вы не разочаровались в алгоритме, я думаю пора привести его реализацию и дать с ним поиграться, а то все убегут не дочитав до конца. Вот исходный код с небольшим количеством комментариев:</p>
<br />
<pre><code class="java">
package ua.kiev.mabp;

/**
 * Created by IntelliJ IDEA.
 * User: CTAPbIu_MABP
 * Date: 26.01.2009
 * Time: 21:04:28
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.BufferedInputStream;

import java.awt.Button;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.TextArea;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.applet.Applet;


public class MarkovChainApplet extends Applet implements ActionListener {

    public void init() {
        // Порисуем :)
        setSize(300,150);
        Button btn = new Button("Select file!");
        btn.addActionListener(this);
        add(btn);
        add(new TextArea(5,30));
    }

    public void actionPerformed(ActionEvent event) {

        // Получаем файл
        FileDialog fd = new FileDialog(new Frame(), "Please choose a file:", FileDialog.LOAD);
        fd.setVisible(true);
        File file = new File(fd.getDirectory() + fd.getFile());
        System.out.println("Reading file " + fd.getDirectory() + fd.getFile());

        // Читаем файл
        String filestring = null;
        try {
            DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));

            try {
                byte[] infile = new byte[dis.available()];
                filestring = new String(infile, 0, dis.read(infile));
            } catch (IOException e) {
                System.out.println("File read error...");
                e.printStackTrace();
            }
            // Если нажали на кнопку "Отмена"
        } catch (FileNotFoundException e) {
            System.out.println("File not found...");
            e.printStackTrace();
        }

        // Файл был пустой
        if (filestring != null &#038;& filestring.length() &gt; 0) {

            // Причесываем текст
            String text = filestring.toLowerCase()
                    // Переводим все в нижний регистр, убираем цифры, спецсимволы и лишнии пробелы
                    .replaceAll("[\\d\\(\\)\\[\\]\\{\\}'\"\\*$\\\\\\/^~_,:;%@#&#038;|+=—-]", "")
                    .replaceAll("\\s+", " ");

            // Составляем карту
            Map&lt;String, Set&lt;String&gt;&gt; markovMap = new HashMap&lt;String, Set&lt;String&gt;&gt;();
            String[] sentenses = text.split("[\\.\\?!]\\s?");
            for (int i = 0, j = sentenses.length; i &lt; j; i++) {
                String[] words = sentenses[i].split(" ");
                for (int k = 0, l = words.length - 1; k &lt; l; k++) {
                    if (markovMap.containsKey(words[k])) {
                        markovMap.get(words[k]).add(words[k + 1]);
                    } else {
                        markovMap.put(words[k], new HashSet&lt;String&gt;(Arrays.asList(words[k + 1])));
                    }
                }
            }

            // Строим последовательности
            List&lt;LinkedList&lt;String&gt;&gt; prepared = new ArrayList&lt;LinkedList&lt;String&gt;&gt;();
            Random random = new Random();
            // генерируем 10 предложений
            for (int s = 0; s &lt; 10; s++) {
                ArrayList&lt;String&gt; keys = new ArrayList&lt;String&gt;(markovMap.keySet());
                String prev = keys.get(random.nextInt(keys.size()));
                LinkedList&lt;String&gt; sentense = new LinkedList&lt;String&gt;(Arrays.asList(prev));
                for (Set&lt;String&gt; next = markovMap.get(prev);
                     // по 10-20 слов в каждом
                     next != null &#038;& !next.isEmpty() &#038;& sentense.size() &lt; 10 + random.nextInt(10);
                     next = markovMap.get(prev)) {
                    List list = Arrays.asList(next.toArray());
                    prev = (String) list.get(random.nextInt(list.size()));
                    sentense.add(prev);
                }
                prepared.add(s, sentense);
            }

            // Генерируем из последовательностей текст
            StringBuilder generatedText = new StringBuilder();
            for (LinkedList&lt;String&gt; sentense : prepared) {
                if (sentense.size() &gt; 5) {
                    for (String words : sentense) {
                        generatedText.append(" ").append(words);
                    }
                    generatedText.append(".");
                }
            }

            // Выводим на экран
            ((TextArea) getComponent(1)).setText(generatedText.toString());
        }
    }
}
</code></pre>
<br />
<p>Я сегодня такой добрый, что даже покажу как это все скомпилить так чтобы не вылазила ошибка? о том что апплет не имеет доступа в файловой системе. Следующий код можно сохранить как *.bat:</p>
<br />
<pre><code>
javac path/to/your/package/ClassNameApplet.java
jar cf cna.jar path/to/your/package/ClassNameApplet.class
keytool -genkey -keystore YOU_SITE_NAME.YOUR_DOMAIN -keyalg rsa -dname "CN=YOUR_NAME, OU=, O=, L=, ST=, C=" -alias YOUR_NAME -validity 3600 -keypass YOUR_PASSWORD -storepass YOUR_PASSWORD
jarsigner -keystore YOU_SITE_NAME.YOUR_DOMAIN -storepass YOUR_PASSWORD -keypass YOUR_PASSWORD -signedjar ClassNameApplet.jar cna.jar YOUR_NAME 
</code></pre>
<br />
<p>Ну и конечно же дам поиграться результатом. Еще раз напомню если вы при загрузке страницы нажали на большом алерте с надписью "Do you want to run the application?" кнопку "нет" то сейчас нужно нажать ctrl+r и на повторно вылезшем алерте нажать "да", иначе кина не будет. Если алерт повторно не вылез, то к сожалению, скорее всего придется закрыть браузер и открыть повторно.</p>
<br />
<div style="text-align:center">
<applet codebase="/content/source/" code="ua.kiev.mabp.MarkovChainApplet" archive="MarkovChainApplet.jar" height="150" width="300" alt="Java не включена!"></applet>
</div>]]></content:encoded>
			<wfw:commentRss>http://mabp.kiev.ua/2009/01/27/markovs-chains/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

