<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>typedef</title>
	
	<link>http://typedef.ru</link>
	<description>Сан Саныч о программировании, технологиях, Computer Science и вообще.</description>
	<lastBuildDate>Wed, 04 Apr 2012 08:53:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Typedef" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="typedef" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Самопроверка при решении задач</title>
		<link>http://typedef.ru/2012/04/self-verification-in-problem-solving/</link>
		<comments>http://typedef.ru/2012/04/self-verification-in-problem-solving/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 08:52:44 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[математика]]></category>
		<category><![CDATA[методология]]></category>
		<category><![CDATA[советы]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=851</guid>
		<description><![CDATA[Кросспост с личного блога. У меня ни школьные, ни институтские курсы математики никогда не вызывали особых проблем. Я даже участвовал в каких-то математических олимпиадах и даже, не поверите, занимал призовые места. Это сейчас я обленился &#160;и все забыл, но когда-то решение задачек и головоломок меня весьма увлекало. Однако у меня была и остается одна черта, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://polycode.livejournal.com/7730.html" target="_blank">Кросспост с личного блога</a>.</p>
<p>У меня ни школьные, ни институтские курсы математики никогда не вызывали особых проблем. Я даже участвовал в каких-то математических олимпиадах и даже, не поверите, занимал призовые места. Это сейчас я обленился &nbsp;и все забыл, но когда-то решение задачек и головоломок меня весьма увлекало. Однако у меня была и остается одна черта, раз за разом основательно портящая всю малину,&nbsp;&mdash; невнимательность.</p>
<p>Помню, как дважды досрочно (каково, а?) сдавал экзамен по дифурам. Оба раза я был идеально готов, и преподаватель об этом знал. И оба раза я сделал глупейшие, хотя и разные, ошибки и пришел к неправильным результатам. Если бы я сам у себя принимал экзамен, то ошибки эти заметил бы непременно, настолько они бросались в глаза! В результате получил &laquo;хорошо&raquo;, и это было очень обидно, но правильно и справедливо.</p>
<p>Наверное, с того момента я и начал бороться сам с собой. В любой задаче я стал искать обходной путь, который позволил бы проверить правильность решения. Иногда обходной путь давал само искомое решение, иногда лишь какую-нибудь верхнюю границу или качественную характеристику, но даже это уже было большим подспорьем и помогало отсечь &laquo;совсем неправильные&raquo; ответы.</p>
<p>Приведу на тему самопроверки несколько поучительных примеров.</p>
<p><b>1. True story.</b> Наверняка все уже слышали эту историю.</p>
<blockquote><p>Был он [преподаватель математики] человеком крупным и покушать любил. В столовой однажды взял он два супа, два вторых&#8230; словом, обед в двух экземплярах. Подходит к кассе. Молоденькая кассирша щелк-щелк-щелк на счетах:&laquo;С вас 2-17&raquo;, он в ответ &laquo;Неправильно&raquo;. Кассирша снова за счеты: &laquo;2-05&raquo;, он в ответ &laquo;Неправильно&raquo;. Кассирша, окончательно смущенная и напуганная,&nbsp;&mdash; щелк-щелк-щелк&nbsp;&mdash; &laquo;1-97&raquo;, а сей ученый муж ей в ответ: &laquo;Снова неправильно!&raquo; Отчаявшаяся кассирша: &laquo;А сколько должно быть?!&raquo; Он в ответ: &laquo;Не знаю. Но два одинаковых обеда&nbsp;&mdash; <i>четное число!</i>&raquo;</p></blockquote>
<p><b>2. Взвешивание монет.</b></p>
<blockquote><p>У нас есть 9 монет, 8 из которых имеют одинаковый вес, а вес одной (фальшивой) больше весов остальных. Также у нас есть равноплечные весы с чашами. Необходимо найти фальшивую монету за минимальное число взвешиваний.</p></blockquote>
<p>При таком малом количестве монет найти правильное решение можно просто перебором, это вряд ли займет больше минуты. Взвешивая по 3 монеты на каждой чаше, мы найдем группу из 3 монет, вес которой больше веса каждой из двух других групп. Затем, взвешивая 2 из этих 3 монет, находим фальшивую. Итого 2 взвешивания.</p>
<p>Попробуем подойти с другого бока. Представим номер фальшивой монеты в двоичном виде. Очевидно, 3 бит недостаточно, в них можно закодировать только 8 номеров, а 4&nbsp;&mdash; уже слишком много, в них можно закодировать целых 16. Точное значение количества требуемых битов выражается двоичным логарифмом: <i>log</i><sub>2</sub>9. Теперь заметим, что каждое взвешивание может иметь 3 возможных исхода: левая чаша тяжелее, правая чаша тяжелее, чаши в равновесии. Таким образом, результат взвешивания можно представить <i>log</i><sub>2</sub>3 битами. Теперь чтобы найти минимальное необходимое количество взвешиваний, нужно найти отношение количества неизвестных нам битов к количеству битов, получаемых за одно взвешивание, и округлить вверх: <i>ceil</i>(<i>log</i><sub>2</sub>9 / <i>log</i><sub>2</sub>3) = <i>ceil</i>(<i>log</i><sub>2</sub>(9/3)) = <i>ceil</i>(<i>log</i><sub>2</sub>3) = 2.</p>
<p>Понятно, что для 9 монет все это имеет мало смыла в силу очевидности ответа, но что если монет не 9, а 999? Слабо найти минимальное число взвешиваний? Да легко: <i>ceil</i>(<i>log</i><sub>2</sub>999 / <i>log</i><sub>2</sub>3) = <i>ceil</i>(<i>log</i><sub>2</sub>333) = 9. И теперь, зная ответ, гораздо проще подобрать искомую последовательность взвешиваний.</p>
<p><b>3. Самые быстрые лошади.</b></p>
<blockquote><p>В скачках участвует 25 лошадей. В каждом заезде может участвовать не более 5 лошадей. Результатом заезда является последовательность прохождения участниками финишной черты, времена не фиксируются. Две лошади не могут финишировать одновременно. Скорости лошадей постоянны: в каждом заезде лошадь скачет с одной и той же скоростью. Требуется за минимальное количество заездов определить первую, вторую и третью быстрейшую лошадь.</p></blockquote>
<p>Эта задача немного сложнее предыдущей, и, соответственно, при нахождении искомой последовательности заездов проще ошибиться. Но если заранее знать, <i>сколько</i> должно быть заездов, то это мало того что позволяет проверить результат, это может еще и направлять ход мысли при поиске решения!</p>
<p>Что ж, попробуем подумать. Из условия следует, что если взять любые две лошади, то или первая будет быстрее второй, или вторая быстрее первой. Сформулируем, что именно нужно найти:
<ul>
<li>лошадь, которая быстрее каждой из&nbsp;24 остальных лошадей;</li>
<li>лошадь, которая быстрее каждой из&nbsp;оставшихся 23;</li>
<li>лошадь, которая быстрее каждой из оставшихся 22.</li>
</ul>
<p>Таким образом, для получения ответа нужно знать по меньшей мере 24 + 23 + 22 = 69 отношений &laquo;быстрее&raquo;.</p>
<p>Теперь заметим, что каждый заезд из 5 лошадей дает нам 4 + 3 + 2 + 1 = 10 отношений. После этого легко найти минимальное количество заездов: просто поделим 69 на 10 и округлим вверх. Выходит, что нужно как минимум 7 заездов. Конкретную расстановку лошадей не буду приводить, можете сами определить, если хотите.</p>
<p>При построении проверки, разумеется, тоже можно провраться. Но здесь уже решение может выступить в роли проверки для проверки. Все-таки случаи взаимной совместимости неправильного решения и неправильной проверки маловероятны.</p>
<p>В заключение хочу сказать, что все вышесказанное вполне применимо не только к математическим задачкам, но и к разнообразным жизненным ситуациям, в чем я не раз убеждался.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2012/04/self-verification-in-problem-solving/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debian: ищем пакет по имени файла</title>
		<link>http://typedef.ru/2012/02/debian-seach-package-by-filename/</link>
		<comments>http://typedef.ru/2012/02/debian-seach-package-by-filename/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 14:29:18 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=847</guid>
		<description><![CDATA[Иногда встает такая задача: зная имя файла или его фрагмент, найти пакет(ы), которому(ым) этот файл принадлежит. Если область поиска ограничивается установленными пакетами, то подойдет любой из вариантов: dpkg -S pattern dpkg --search pattern dpkg-query -S pattern dpkg-query --search pattern Понятно, что dpkg здесь &#8212; просто фронтенд к dpkg-query. Шаблон имени файла pattern может включать shell-style [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда встает такая задача: зная имя файла или его фрагмент, найти пакет(ы), которому(ым) этот файл принадлежит.</p>
<p>Если область поиска ограничивается установленными пакетами, то подойдет любой из вариантов:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">-S</span> pattern
<span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">--search</span> pattern
dpkg-query <span style="color: #660033;">-S</span> pattern
dpkg-query <span style="color: #660033;">--search</span> pattern</pre></div></div>

<p>Понятно, что <code>dpkg</code> здесь &#8212; просто фронтенд к <code>dpkg-query</code>.</p>
<p>Шаблон имени файла <code>pattern</code> может включать shell-style wildcards (можно я не буду переводить?).</p>
<p>Если же хотим искать во всех пакетах вообще, даже неустановленных, то:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-file</span> search pattern</pre></div></div>

<p>Если задать опцию <code>--regexp|-x</code>, то <code>pattern</code> становится перловой регуляркой.</p>
<p>Кстати, <code>apt-file</code> использует собственную БД, поэтому перед первым использованием нужно выполнить</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-file</span> update</pre></div></div>

<p>чтобы синхронизироваться с репозиториями из <code>/etc/apt/sources.list</code>.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2012/02/debian-seach-package-by-filename/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stanford ML and AI Classes</title>
		<link>http://typedef.ru/2011/12/stanford-ml-and-ai-classes/</link>
		<comments>http://typedef.ru/2011/12/stanford-ml-and-ai-classes/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 19:56:56 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[наука]]></category>
		<category><![CDATA[обучение]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=841</guid>
		<description><![CDATA[А я ведь тоже их осилил, и даже получил 98.1% за AI, завидуйте! Коллеги-блоггеры, к счастью, все уже написали за меня, так что кто интересуется темой, наверняка уже в курсе. Я добавлю только немного личных ощущений. ML Class близок к идеалу. Именно таким должен быть настоящий учебный курс — невероятно простым, невыносимо нудным, но при этом дающим [...]]]></description>
			<content:encoded><![CDATA[<p>А я ведь тоже их осилил, и даже получил 98.1% за AI, завидуйте! Коллеги-блоггеры, к счастью, все уже написали за меня, так что кто интересуется темой, наверняка уже в курсе. Я добавлю только немного личных ощущений.</p>
<p>ML Class близок к идеалу. Именно таким должен быть настоящий учебный курс — невероятно простым, невыносимо нудным, но при этом дающим твердое понимание того, что происходит и как это работает. Рижским бальзамом на душу льются слова Andrew Ng: &laquo;<em>Если вы это не понимаете, не переживайте, сейчас я расскажу, поймете</em>&raquo; или &laquo;<em>Если вы это не понимаете, не переживайте, я тоже не понимаю, это вам не нужно</em>&laquo;. Ну и прочие подобные высказывания и шутки вроде &laquo;<em>Если вы эксперт в линейной алгебре и знаете, что такое собственные вектора, то &#8230;</em>&raquo; доставляют. Столько студентов сразу почувствовали себя экспертами в линейной алгебре! Отдельная благодарность за возможность ускорить лекции в 1.2 и 1.5 раза.</p>
<p>AI Class имеет гораздо больший охват материала, но при этом он менее проработанный. Куча несогласованной терминологии, много недосказанного, вопросы иногда расплывчаты и имеют слабое отношение к тексту. Постоянно происходят какие-то технические накладки, то сроки отодвигаются, то публикуются уточнения к вопросам, то еще какая напасть. Это не говоря уже об очаровательном немецком акценте Prof. Sebastian Thrun, которого я, в отличие от ускоренного Andrew Ng, понимал только процентов на 95 — некоторые фразы не могли понять даже native speakers. Но, несмотря на все недостатки, получился очень неплохой <em>обзорный </em>курс.</p>
<p>Оба курса я изучал в обстановке, приближенной к боевой. У меня было на них действительно очень мало времени, и я искал любую возможность его экономить. Это, конечно, сказалось на глубине обучения.</p>
<p>В целом нисколько не жалею, но курсы будущего семестра — разве что в пассивном режиме посмотрю.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/12/stanford-ml-and-ai-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>John McCarthy</title>
		<link>http://typedef.ru/2011/10/john-mccarthy/</link>
		<comments>http://typedef.ru/2011/10/john-mccarthy/#comments</comments>
		<pubDate>Tue, 25 Oct 2011 05:35:28 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[новости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=837</guid>
		<description><![CDATA[Thanks for LISP and AI. RIP. Черт, да что же это за месяц такой&#8230;]]></description>
			<content:encoded><![CDATA[<p>Thanks for LISP and AI.<br />
RIP.</p>
<p>Черт, да что же это за месяц такой&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/10/john-mccarthy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Dennis Ritchie</title>
		<link>http://typedef.ru/2011/10/dennis-ritchie/</link>
		<comments>http://typedef.ru/2011/10/dennis-ritchie/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 07:49:36 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[новости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=833</guid>
		<description><![CDATA[Thanks for C and UNIX. RIP.]]></description>
			<content:encoded><![CDATA[<p>Thanks for C and UNIX.<br />
RIP.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/10/dennis-ritchie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Альтернативное мнение об аспирантском курсе философии науки</title>
		<link>http://typedef.ru/2011/08/alternative-opinion-on-postgrad-philosophy-of-science-course/</link>
		<comments>http://typedef.ru/2011/08/alternative-opinion-on-postgrad-philosophy-of-science-course/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 08:02:06 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[наука]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=819</guid>
		<description><![CDATA[В комментариях один из моих читателей обоснованно возразил мне по поводу необходимости курса философии науки для аспирантов. У меня в блоге гласность и демократия, а свое мнение я не считаю единственно верным, тем более что в обсуждаемой теме оно вообще едва ли может быть. Поэтому я решил опубликовать некоторые из комментариев читателя в виде отдельного [...]]]></description>
			<content:encoded><![CDATA[<p><em>В <a href="http://typedef.ru/2009/04/science-what-science/#comments" target="_blank">комментариях</a> один из моих читателей обоснованно возразил мне по поводу <a href="http://typedef.ru/2010/11/philosophy-considered-harmful/" target="_blank">необходимости курса философии науки</a> для аспирантов. У меня в блоге гласность и демократия, а свое мнение я не считаю единственно верным, тем более что в обсуждаемой теме оно вообще едва ли может быть. Поэтому я решил опубликовать некоторые из комментариев читателя в виде отдельного поста. В комментариях оставлено цитирование моих комментариев для сохранения контекста.</em></p>
<hr/>
<p>Категорически не соглашусь. Лично для меня курс философии науки стал, не побоюсь этого слова, откровением. Можно сказать, поворотным пунктом. Когда в школе и в вузе проходят различные науки, совершенно не затрагивают тему того, насколько мы можем быть уверены в предлагаемом знании. И у каждого слушателя формируется своё весьма наивное представление о сущности истины и человеческого знания. Кто-то, например, освоил какой-то метод в какой-то области, сидит и только его применяет, а всё остальное считает ересью. А кто-то, скажем, любое порождение своего мозга принимает за великое открытие. Кто-то считает математику непогрешимой, а кто-то – что математика вообще ни на что не способна. Немалая доля людей вовсе науку не признаёт, а верит в различное НЛО и т. п.</p>
<p>Курс же философии науки знакомит нас с тем, как различные (не самые глупые) люди подходили к решению означенной проблемы. А проблема очень серьёзная – можем ли мы доверять научному или какому-либо ещё знанию? Как нынче принято говорить, краткий ответ – нет. Но если мы углубимся ещё немного, то оказывается, что лучше всё же доверять научному знанию, чем не доверять. В общем, там очень много весёлого, так в двух словах не перескажешь. Скажу лишь, что современной науке по моему представлению наиболее соответствует эволюционная эпистемология, а современному общественному сознанию – постмодернизм. Разумеется, сей курс не даёт правильного ответа – именно в силу невозможности абсолютного познания истины. Но он заставляет задуматься над тем, правильно ли то, что ты делаешь. Я категорически утверждаю, что философия науки необходима любому человеку, претендующему на то, что он занимается наукой, а не просто наливает раствор А в раствор Б.</p>
<p>Возможно, автору просто не повезло с преподавателями оного курса.</p>
<hr/>
<p>Я вам тоже могу открыто признаться, что не мог терпеть философию до тех пор, пока не прослушал курс философии науки в аспирантуре. В том числе когда проходил «философию» на четвёртом курсе.</p>
<p>Я совершенно с вами согласен в том, что философия как таковая не может быть единственной профессией – это всё равно, что заниматься архитектурой, не зная, как кладут кирпичи и куда попадают отходы из унитаза. Можно заметить, что ни один признанный философ не занимался исключительно рассуждениями о вещах в себе.</p>
<p>> В этой области множество людей столетиями придумывали термины, «законы» и «принципы».</p>
<p>Термины, законы и принципы как таковые (то бишь как руководство к действию) не нужны. История философии – это суть собрание заблуждений. И именно этим она ценна. Ибо с очень большой вероятностью человек может встретить среди них и свои заблуждения. И увидеть не только преимущества, но и недостатки по сравнению с другими заблуждениями, и на основании этого, возможно, изменить свои взгляды. Грубо говоря, философия учит задавать себе неудобные вопросы и излечивает от излишней уверенности в себе.</p>
<p>> до какого-нибудь Витгенштейна</p>
<p>Витгенштейн, равно как и вся философия науки двадцатого века, совершенно напрямую связан с математикой и проблемами построения искусственного интеллекта. Ещё раз повторю, что ни его, ни любого другого философа не следует принимать на веру. Просто полезно на минуту представить себя в его шкуре.</p>
<p>> И думается мне, что те принципы, которые, по идее, должна прививать ученому философия, нормальный ученый прививает себе сам.</p>
<p>А вот для чего, скажем, программисты алгоритмы проходят? Достаточно было бы обучить кодить и компилять, а коли человек достаточно умный, то до всех необходимых алгоритмов сам додумается. Конечно, это грубая аналогия, но смысл именно такой. Мировоззрение, конечно, за самого человека никто не сформирует. Но если он будет выбирать подходящее мировоззрение не только из собственных домыслов, но и на основании предыдущего опыта человечества – то он сможет сделать это более адекватно. Конечно, научное мировоззрение неявно сквозит в большинстве специальных курсов. Но, как известно, явное лучше неявного.</p>
<p>> Нет, я согласен, что при наличии хорошего преподавателя это может быть даже интересно, но нужно ли?</p>
<p>А зачем вообще общеобразовательные предметы проходят? Для того, чтобы человек видел перспективу, а не становился специалистом по правой ноздре. Другое дело, что т. н. гуманитарные предметы действительно в массе своей преподаются совершенно паскудным образом. Видимо, потому, что в гуманитарии идут в основном люди, у которых не сложились отношения с математикой и которые посвящают всю оставшуются жизнь убеждению окружающих, что плохи не они, а математика.</p>
<p>Ежели спрашивать лично меня – то я бы исключил литературу и русский язык из школьной программы за полной бесполезностью. Оставил бы только чтение-запись в начальной школе.</p>
<hr/>
<p>Кстати, вот ещё вспомнил. Одна из основных задач философии науки – это отличать науку от ненауки. В связи с нынешним засильем мракобесия и «альтернативной» науки это становится как никогда актуально. Грубо говоря, учёный, занимавшийся только наукой и не занимавшийся философией, скорее всего, правильно определит, кто есть кто, по крайней мере в своей области. Но вот убедить другого человека, что это так – это уже задача посложнее. Скорее всего, его аргументы сведутся к «это же очевидно любому здравомыслящему человеку» и «пойди ещё раз поучись в школе». Тогда как знакомство с философией и методологией науки даёт некоторые критерии (прежде всего фальсифицируемость) и приёмы убеждения. Хотя, к сожалению, переубедить «адепта» всё равно почти никогда не получается, но по крайней мере ты сам от такого спора не будешь погружаться в состояние отчаяния от осознания своего бессилия оправдать научную точку зрения.</p>
<hr/>
<p>Из конкретных философских трактатов могу порекомендовать разве что статью Карла Поппера об эволюционной эпистемологии http://www.keldysh.ru/pages/mrbur-web/philosophy/popper.html . Также не совсем по теме, но всё же – Ричард Докинз «Эгоистичный ген».</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/08/alternative-opinion-on-postgrad-philosophy-of-science-course/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Случайно придумал quine на C</title>
		<link>http://typedef.ru/2011/08/accidentally-invented-c-quine/</link>
		<comments>http://typedef.ru/2011/08/accidentally-invented-c-quine/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 09:05:33 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[идеи]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=809</guid>
		<description><![CDATA[Для тех, кто не знает: quine (квайн) &#8212; это программа, которая при запуске выводит свой исходный текст. Что интересно, мой вариант более чем вдвое короче, чем представленный в Википедии. main&#40;&#41;&#123;char*p=&#34;main(){char*p=%c%s%c,c='%c',s[256];sprintf(s,p,c,p,c,c);puts(s);}&#34;,c='&#34;',s&#91;256&#93;;sprintf&#40;s,p,c,p,c,c&#41;;puts&#40;s&#41;;&#125; Изобрел я его совершенно случайно как побочный эффект своих рабочих дел. Опечатавшись, указал в printf() форматную строку как один из подставляемых аргументов, подставив тем самым [...]]]></description>
			<content:encoded><![CDATA[<p>Для тех, кто не знает: quine (квайн) &mdash; это программа, которая при запуске выводит свой исходный текст.</p>
<p>Что интересно, мой вариант более чем вдвое короче, чем <a href="http://ru.wikipedia.org/wiki/%D0%9A%D1%83%D0%B0%D0%B9%D0%BD_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)#.D0.A1.D0.B8.2F.D0.A1.D0.B8.2B.2B" target="_blank">представленный в Википедии</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span>p<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;main(){char*p=%c%s%c,c='%c',s[256];sprintf(s,p,c,p,c,c);puts(s);}&quot;</span><span style="color: #339933;">,</span>c<span style="color: #339933;">=</span><span style="color: #ff0000;">'&quot;'</span><span style="color: #339933;">,</span>s<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>sprintf<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span>p<span style="color: #339933;">,</span>c<span style="color: #339933;">,</span>p<span style="color: #339933;">,</span>c<span style="color: #339933;">,</span>c<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>puts<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Изобрел я его совершенно случайно как побочный эффект своих рабочих дел. Опечатавшись, указал в <code>printf()</code> форматную строку как один из подставляемых аргументов, подставив тем самым форматную строку саму в себя. Сразу появились ассоциации с квайнами, повозился минут 15 &mdash; и готово. Заодно запостил в соответствующий раздел <a href="http://codegolf.stackexchange.com/questions/69/golf-you-a-quine-for-great-good" target="_blank">Codegolf@Stackexchange</a>.</p>
<p><strong>Добавлено</strong></p>
<p>Оказывается, этот подход уже сто лет назад как <a href="http://www.nyx.net/~gthompso/quine.htm" target="_blank">придумали</a>, и программа намного короче:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">char</span><span style="color: #339933;">*</span>f<span style="color: #339933;">=</span><span style="color: #ff0000;">&quot;char*f=%c%s%c;main(){printf(f,34,f,34,10);}%c&quot;</span><span style="color: #339933;">;</span>main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span>f<span style="color: #339933;">,</span><span style="color: #0000dd;">34</span><span style="color: #339933;">,</span>f<span style="color: #339933;">,</span><span style="color: #0000dd;">34</span><span style="color: #339933;">,</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>В общем, я изобрел велосипед, ура.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/08/accidentally-invented-c-quine/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Как отбросить непрочитанные символы из cin?</title>
		<link>http://typedef.ru/2011/08/how-to-discard-unread-chars-from-cin/</link>
		<comments>http://typedef.ru/2011/08/how-to-discard-unread-chars-from-cin/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 10:26:42 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[CPP]]></category>
		<category><![CDATA[грабли]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=780</guid>
		<description><![CDATA[Зачем отбрасывать символы? Попробуем решить такую задачу: нужно прочитать из cin целое число, причем если вместо целого числа нам подсунут какую-нибудь гадость, нужно сообщить об этом и попытаться прочитать число снова. Попытка номер один: 1 2 3 4 5 6 7 using namespace std; int value = 0; while &#40;not &#40;cin &#62;&#62; value&#41;&#41; &#123; cout [...]]]></description>
			<content:encoded><![CDATA[<p>Зачем отбрасывать символы? Попробуем решить такую задачу: нужно прочитать из <code>cin</code> целое число, причем если вместо целого числа нам подсунут какую-нибудь гадость, нужно сообщить об этом и попытаться прочитать число снова. Попытка номер один:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> value <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>not <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> value<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Invalid format&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Your input: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> value <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Попытавшись ввести нечто, непохожее на целое число, получим бесконечный цикл. Попытка прочитать число в строке 3 заканчивается неудачей, но введенные символы из буфера ввода никуда не исчезают. Повторное чтение, натыкаясь на те же самые символы, заканчивается с тем же результатом.</p>
<p>Беглый гуглеж приводит меня к функции <code>istream::sync()</code>, которая, как говорит <a href="http://www.cplusplus.com/reference/iostream/istream/sync/" target="_blank">один источник</a>, делает именно то, что нам нужно:</p>
<blockquote><p>Synchronizes the buffer associated with the stream to its controlled input sequence. This effectively means that the unread characters in the buffer are discarded.</p></blockquote>
<p>Что ж, попробуем:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> value <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>not <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> value<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Invalid format&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">sync</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Your input: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> value <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Хм. В моей системе результат не изменился, код работает точно так же, как и первый. Беда в том, что функция <code>istream::sync()</code> в некоторых реализациях стандартной библиотеки <a href="http://www.daniweb.com/software-development/cpp/threads/132714" target="_blank">таки отбрасывает</a> непрочитанные символы. Но не в моем случае.</p>
<p>А я человек простой — лезу в код своей стандартной библиотеки и смотрю что да как. Выходит, что <code>istream::sync()</code> вызывает <code>stdio_sync_filebuf::pubsync()</code>, которая вызывает <code>stdio_sync_filebuf::sync()</code>, которая, наконец, вызывает <code>fflush(stdin)</code>. Понятно, что <code>fflush(stdin)</code> не может оказать никакого влияния на входной буфер <code>cin</code>.</p>
<p>Так что упомянутый выше &laquo;один источник&raquo; не стоит считать истиной в последней инстанции. Но надо сказать, что попытки найти истину в стандарте — еще более неблагодарное занятие.</p>
<p>В общем, правильное решение заключается в использовании функции <code>istream::ignore()</code> таким вот образом:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> value <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>not <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> value<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Invalid format&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">ignore</span><span style="color: #008000;">&#40;</span>numeric_limits<span style="color: #000080;">&lt;</span>streamsize<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">max</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Your input: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> value <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Надо отметить, что вызов <code>ignore()</code> неплохо бы вставлять даже после успешного ввода, так как при вводе строки &laquo;123qwe&raquo; первые три символа будут прочитаны и распознаны как число, а &laquo;qwe&raquo; останутся во входном буфере и будут портить жизнь при следующем чтении. Еще одна тонкость — обработка конца файла. Если пользователь в ответ на приглашение к вводу нажмет Ctrl+D или что там в вашей системе для этого предназначено, то программа вместо того, чтобы завершиться, сообщит о неверном формате и предложит ввести число еще раз. Поэтому по-хорошему код должен быть вроде этого (вся программа):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;limits&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> Type<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">bool</span> read_value<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> <span style="color: #000040;">&amp;</span>prompt, Type <span style="color: #000040;">&amp;</span>value<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> repeat <span style="color: #000080;">=</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">bool</span> eof <span style="color: #000080;">=</span> <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">eof</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>repeat and not eof<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> prompt <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;: &quot;</span><span style="color: #008080;">;</span>
        <span style="color: #0000dd;">cin</span> <span style="color: #000080;">&gt;&gt;</span> value<span style="color: #008080;">;</span>
        eof <span style="color: #000080;">=</span> <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">eof</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        repeat <span style="color: #000080;">=</span> <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">fail</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> and not eof<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>repeat<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;***Invalid data format!&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
            <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>eof<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;(EOF)&quot;</span> <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
        <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">ignore</span><span style="color: #008000;">&#40;</span>numeric_limits<span style="color: #000080;">&lt;</span>streamsize<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">max</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #FF0000;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> not eof<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> value <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>read_value<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Input integer&quot;</span>, value<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;Your input: &quot;</span> <span style="color: #000080;">&lt;&lt;</span> value <span style="color: #000080;">&lt;&lt;</span> endl<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Но и в этом, казалось бы, безошибочном, коде затаилась пара граблей. Например, что если функцию <code>read_value()</code> использовать для ввода символов или строк? Сумеем мы ввести символ пробела? Сумеем ли ввести строку из нескольких слов, разделенных пробелами? Хрен! С вводом символа пробела еще несложно — надо только использовать манипулятор <code>noskipws</code>, а вот ввод строк с пробелами потребует перегрузки <code>read_value()</code> и использования <code>getline()</code> вместо оператора <code>>></code>.</p>
<p>В общем, писать на C++ — сплошное счастье.<br />
Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/08/how-to-discard-unread-chars-from-cin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bash как mainstream-язык</title>
		<link>http://typedef.ru/2011/08/bash-as-a-mainstream-language/</link>
		<comments>http://typedef.ru/2011/08/bash-as-a-mainstream-language/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 11:53:33 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[юмор]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=782</guid>
		<description><![CDATA[Нет, я не буду здесь расползаться пространными рассуждениями, как я обычно это делаю. Просто две ссылки: Объектно-ориентированный bash. Bash on Balls — web-framework на bash.]]></description>
			<content:encoded><![CDATA[<p>Нет, я не буду здесь расползаться пространными рассуждениями, как я обычно это делаю. Просто две ссылки:</p>
<ul>
<li><a href="http://lab.madscience.nl/oo.sh.txt" target="_blank">Объектно-ориентированный bash</a>.</li>
<li><a href="https://github.com/jayferd/balls" target="_blank">Bash on Balls</a> — web-framework на bash.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/08/bash-as-a-mainstream-language/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Теория крючков</title>
		<link>http://typedef.ru/2011/07/hooks-theory/</link>
		<comments>http://typedef.ru/2011/07/hooks-theory/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 08:35:30 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[идеи]]></category>
		<category><![CDATA[обучение]]></category>
		<category><![CDATA[философия]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=777</guid>
		<description><![CDATA[В студенческие годы мне пришлось столкнуться с одной интересной образовательной проблемой. Она имеет две стороны, кажду из которых проще всего проиллюстрировать на примерах: На младших курсах все студенты изучают математический анализ. Это очень непростой для неокрепших умов предмет, и самое непростое в нем то, что когда его изучаешь, ты абсолютно не понимаешь, зачем все это [...]]]></description>
			<content:encoded><![CDATA[<p>В студенческие годы мне пришлось столкнуться с одной интересной образовательной проблемой. Она имеет две стороны, кажду из которых проще всего проиллюстрировать на примерах:</p>
<ol>
<li>На младших курсах все студенты изучают математический анализ. Это очень непростой для неокрепших умов предмет, и самое непростое в нем то, что когда его изучаешь, ты абсолютно не понимаешь, <em>зачем все это нужно</em>. Понять доказательство теоремы Вейерштрасса или разложение в ряд Тейлора в принципе можно, но должно пройти немало времени, прежде чем <em>может быть</em> у кого-то возникнет дежа вю — «Кажется, что-то такое я учил на первом курсе&#8230; Но уже нифига не помню». Хуже всего, если эти знания действительно нужны, и приходится открывать учебники и учиться заново. Во второй раз изучать получается быстрее, но все равно время жалко.</li>
<li>На младших курсах многие студенты изучают еще и разнообразную физику. Это вообще труба, потому что используемый в лекциях матаппарат студенты <em>еще не проходили</em>. В результате физику никто не знает, а когда приходит время изучать тот матаппарат, то параллели провести тоже не получается — едва ли кто-то воскликнет «Так вот что, оказывается, имел в виду наш физик год назад, когда говорил о линейных операторах!».</li>
</ol>
<p>Интересно то, что многие считают второй случай вопиющей халатностью при составлении учебного плана, а первый — неизбежным злом. Некоторые даже добавят что-то в духе «учиться надо было лучше». Так вот, я учился хорошо. Местами даже отлично. И получил красный диплом. Но сейчас, в аспирантуре, мне приходится <em>изучать математику заново</em>, иногда даже по тем же самым учебникам.</p>
<p>Мне придумалась образное объяснение, почему так происходит — <strong>теория крючков</strong>. Она состоит из следующих постулатов:</p>
<ol>
<li>Поглощаемые человеком знания ищут в мозгу крючки, за которые могут зацепиться. Чем больше таких крючков, за которые зацепилось некоторое знание, тем дольше оно останется в мозгу.</li>
<li>Крючки типизированные: определенным знаниям нужны определенные крючки. Нельзя зацепить знания о языке Фортран за крючки, относящиеся к плаванию кролем.</li>
<li>Хотя некоторые уникумы умудряются нарушать типизацию крючков, проводя смелые аналогии в различных областях знаний.</li>
<li>Закрепленные в мозгу новые знания сами начинают создавать крючки. Больше знаний — больше крючков — проще усваиваются новые знания.</li>
</ol>
<p>Попробую продемонстрировать эту теорию на ней же самой. Эти постулаты сами по себе не очень ценны — какие-то утверждения, сделанные неизвестно кем непонятно с какой целью. Если трактовать их именно так, то на следующий день после прочтения они из головы сотрутся. Но можно прицепить их крючками к уже известным фактам, наведя между ними «знания-мосты». Такими мостами могут быть, например, следующие факты:</p>
<ul>
<li>Когда знаешь много языков программирования (или иностранных языков), изучить еще один — гораздо более простая задача, чем изучить первый. Новый язык цепляется за множество крючков, выращенных уже изученными языками.</li>
<li>Система крючков гуманитария кардинально отличается от оной у технаря. Поэтому технические понятия гуманитарии воспринимают с трудом — крючки не подходят!</li>
<li>Проводить аналогии между программированием и постройкой домов, литературой, живописью, вышиванием крестиком или выращиванием цветов — нарушение типизации крючков. Но кто сказал, что это плохо?</li>
<li>Теория, пересыпанная примерами, изучается куда проще, чем сначала куча теории, а потом куча примеров. Поглощая знания маленькими кусочками, мы цепляем их друг к другу, не давая им успеть забыться. С большими кусками сложнее. Это все равно как есть очень длинную колбасу — пока доедаешь ее конец, начало уже давно переварилось и путешествует по канализации.</li>
<li>В этом посте неимоверное, зашкаливающее количество употреблений слова «крючок».</li>
</ul>
<p>В общем, берегите свои крючки и не цепляйте на них всякую гадость.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/07/hooks-theory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Определить, поддерживает ли компилятор C вложенные комментарии</title>
		<link>http://typedef.ru/2011/07/check-c-compiler-nested-comments-support/</link>
		<comments>http://typedef.ru/2011/07/check-c-compiler-nested-comments-support/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 14:58:44 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[хитрости]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=762</guid>
		<description><![CDATA[Такая вот классическая задача, которая которую я когда-то увидел в книжке &#171;C Traps and Pitfalls&#187;. Для современных компиляторов ответ однозначен: вложенные комментарии вида /*&#8230;/*&#8230;*/&#8230;*/ не поддерживаются, см. п. 6.4.9-1 стандарта C99. Но во времена динозавров, говорят, некоторые компиляторы все-таки поддерживали. Собственно, задача формулируется так: Написать программу на C, компилирующуюся без ошибок (warning-и не в счет), [...]]]></description>
			<content:encoded><![CDATA[<p>Такая вот классическая задача, которая которую я когда-то увидел в книжке &laquo;C Traps and Pitfalls&raquo;. Для современных компиляторов ответ однозначен: вложенные комментарии вида /*&#8230;/*&#8230;*/&#8230;*/ не поддерживаются, см. п. 6.4.9-1 стандарта C99. Но во времена динозавров, говорят, некоторые компиляторы все-таки поддерживали. Собственно, задача формулируется так:</p>
<blockquote><p>Написать программу на C, компилирующуюся без ошибок (warning-и не в счет), которая при запуске выводит &laquo;YES&raquo;, если вложенные комментарии поддерживаются, и &laquo;NO&raquo;, если это не так.</p></blockquote>
<p>Механизм, вокруг которого должна строиться такая программа, очевиден &#8212; вложенные комментарии:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* всегда в комментарии /* всегда в комментарии */</span> какой<span style="color: #339933;">-</span>то<span style="color: #339933;">-</span>код <span style="color: #339933;">*/</span></pre></div></div>

<p>Если вложенность поддерживается, <em>какой-то-код</em> &#8212; всего лишь часть комментария. Но если вложенности нет, то комментарий кончается на первом же &laquo;*/&raquo;, а <em>какой-то-код</em> будет выполнен. Проблема только в одном: что делать с остающимися в хвосте &laquo;*/&raquo;? Наверное, нужно где-то раньше поместить парные &laquo;/*&raquo;, но тогда код станет некорректным в случае, если вложенность поддерживается. Нетрудно видеть, что написание комментариев с еще большей глубиной вложенности лишь усугубляет проблему.</p>
<p>(Здесь самое время прекратить читать и попытаться придумать решение самостоятельно.)</p>
<p>Ключ к решению &#8212; различная лексическая трактовка символов в зависимости от контекста. Я придумал три способа:</p>
<ol>
<li>Использовать двойные кавычки. Символы между парными кавычками становятся частью строкового литерала. Конечно, придется использовать два набора вложенных комментариев.</li>
<li>Использовать символ &laquo;*&raquo;, в зависимости от ситуации, как оператор разыменования или оператор умножения. Опять нужно два набора комментариев.</li>
<li>Поглотить &laquo;*/&raquo;, сделав эту строку содержимым символа препроцессора. Здесь нужно также вспомнить, что комментарии обрабатываются препроцессором до обработки макродиректив.</li>
</ol>
<p>Код выглядит немного странно, но разобраться несложно:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// file: nestcomm.c?</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #993333;">void</span> method1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Method 1: &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #808080; font-style: italic;">/*/**/</span><span style="color: #ff0000;">&quot;  NO<span style="color: #006699; font-weight: bold;">\0</span>*/&quot;</span><span style="color: #808080; font-style: italic;">/*YES\0&quot;/**/</span><span style="color: #ff0000;">&quot;*/&quot;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">void</span> method2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> a <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Method 2: &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #808080; font-style: italic;">/*/**/</span><span style="color: #0000dd;">2</span><span style="color: #339933;">*</span><span style="color: #808080; font-style: italic;">/*(&amp;a)+/**/</span><span style="color: #0000dd;">2</span><span style="color: #339933;">==</span><span style="color: #0000dd;">4</span><span style="color: #339933;">?</span><span style="color: #ff0000;">&quot;NO&quot;</span><span style="color: #339933;">:</span><span style="color: #ff0000;">&quot;YES&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">void</span> method3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Method 3: &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #808080; font-style: italic;">/*/**/</span><span style="color: #339933;">#define A */</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span>
           <span style="color: #339933;">#ifdef A</span>
               <span style="color: #ff0000;">&quot;NO&quot;</span>
           <span style="color: #339933;">#else</span>
               <span style="color: #ff0000;">&quot;YES&quot;</span>
           <span style="color: #339933;">#endif</span>
            <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    method1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    method2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    method3<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Компилятор с поддержкой вложенных комментариев уже не найдешь, но можно его сымитировать, написав на flex небольшой препроцессор:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="lex" style="font-family:monospace;">  // file: snc.lex
%option noyywrap
%{
int comm = 0;
%}
%x STRING COMMENT
%%
&lt;INITIAL&gt;{
    \&quot;         { BEGIN(STRING); ECHO; }
    &quot;/*&quot;       { comm++; BEGIN(COMMENT); }
    .          { ECHO; }
}
&lt;COMMENT&gt;{
    &quot;/*&quot;   { comm++; }
    .      { }
    &quot;*/&quot;   { comm--; if (!comm) BEGIN(INITIAL); }
}
&lt;STRING&gt;{
    \&quot;     { BEGIN(INITIAL); ECHO; }
    .      { ECHO; }
}
%%
int main()
{
    yylex();
    return 0;
}</pre></td></tr></table></div>

<p>Ну, и чтобы два раза не вставать, Makefile для автоматического прогона:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="make" style="font-family:monospace;"><span style="color: #990000;">.PHONY</span><span style="color: #004400;">:</span> all
all<span style="color: #004400;">:</span> nest_yes nest_no
	<span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;With nested comments support:&quot;</span>
	<span style="color: #004400;">./</span>nest_yes
	<span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;Without nested comments support:&quot;</span>
	<span style="color: #004400;">./</span>nest_no
&nbsp;
nest_yes<span style="color: #004400;">:</span> nestcomm<span style="color: #004400;">.</span>c snc
	<span style="color: #004400;">./</span>snc <span style="color: #004400;">&lt;</span> <span style="color: #000088; font-weight: bold;">$&lt;</span> <span style="color: #004400;">&gt;</span> tmp<span style="color: #004400;">.</span>c
	cc <span style="color: #004400;">-</span>o <span style="color: #000088; font-weight: bold;">$@</span> tmp<span style="color: #004400;">.</span>c
	rm <span style="color: #004400;">-</span>f tmp<span style="color: #004400;">.</span>c
&nbsp;
snc<span style="color: #004400;">:</span> snc<span style="color: #004400;">.</span>lex	
	flex <span style="color: #004400;">-</span>o <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">subst</span> <span style="color: #004400;">.</span>lex<span style="color: #004400;">,.</span>c<span style="color: #004400;">,</span><span style="color: #000088; font-weight: bold;">$&lt;</span><span style="color: #004400;">&#41;</span> <span style="color: #000088; font-weight: bold;">$&lt;</span>
	cc <span style="color: #004400;">-</span>o <span style="color: #000088; font-weight: bold;">$@</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">subst</span> <span style="color: #004400;">.</span>lex<span style="color: #004400;">,.</span>c<span style="color: #004400;">,</span><span style="color: #000088; font-weight: bold;">$&lt;</span><span style="color: #004400;">&#41;</span>
&nbsp;
nest_no<span style="color: #004400;">:</span> nestcomm<span style="color: #004400;">.</span>c
	cc <span style="color: #004400;">-</span>o <span style="color: #000088; font-weight: bold;">$@</span> <span style="color: #000088; font-weight: bold;">$&lt;</span>
&nbsp;
<span style="color: #990000;">.PHONY</span><span style="color: #004400;">:</span> clean
clean<span style="color: #004400;">:</span>
	rm <span style="color: #004400;">-</span>f snc<span style="color: #004400;">.</span>c snc nest_yes nest_no</pre></td></tr></table></div>

<p>Многие считают подобные упражнения напрасной тратой времени, но на самом деле таким образом можно узнать удивительно много нового о тонкостях языка.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/07/check-c-compiler-nested-comments-support/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Удивительное рядом</title>
		<link>http://typedef.ru/2011/05/amazing-nearby/</link>
		<comments>http://typedef.ru/2011/05/amazing-nearby/#comments</comments>
		<pubDate>Fri, 20 May 2011 13:02:27 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=757</guid>
		<description><![CDATA[Уличил сам себя в бессовестном разбазаривании вычислительных ресурсов. У меня запущен urxvt, в котором запущен tmux, в котором через ssh запущен screen, в котором запущен minicom, в котором видна консоль суровой отечественной железки. Остается только запустить это все в виртуальной машине.]]></description>
			<content:encoded><![CDATA[<p>Уличил сам себя в бессовестном разбазаривании вычислительных ресурсов. У меня запущен urxvt, в котором запущен tmux, в котором через ssh запущен screen, в котором запущен minicom, в котором видна консоль суровой отечественной железки. Остается только запустить это все в виртуальной машине.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/05/amazing-nearby/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SRM 504: epic, just epic</title>
		<link>http://typedef.ru/2011/04/srm-504-epic-just-epic/</link>
		<comments>http://typedef.ru/2011/04/srm-504-epic-just-epic/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 19:40:47 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[алгоритмы]]></category>
		<category><![CDATA[печаль]]></category>
		<category><![CDATA[радость]]></category>
		<category><![CDATA[спорт]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=755</guid>
		<description><![CDATA[Стоило мне впервые успешно решить 1000-бальную задачу из SRM 504 Div 2, как результаты матча аннулировали из-за технических неполадок на сервере. Я, конечно, горжусь собой, но моя радость была бы более полной, если бы мои успехи отразились в рейтинге. А первые две задачи во втором дивизионе вот уже второй матч подряд совсем простые. Или дело [...]]]></description>
			<content:encoded><![CDATA[<p>Стоило мне впервые успешно решить 1000-бальную задачу из <a href="http://www.topcoder.com/tc?module=MatchDetails&amp;rd=14433" target="_blank">SRM 504</a> Div 2, как результаты матча аннулировали из-за технических неполадок на сервере. Я, конечно, горжусь собой, но моя радость была бы более полной, если бы мои успехи отразились в рейтинге.</p>
<p>А первые две задачи во втором дивизионе вот уже второй матч подряд совсем простые. Или дело во мне?..</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/04/srm-504-epic-just-epic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Наука и жизнь</title>
		<link>http://typedef.ru/2011/04/science-and-life/</link>
		<comments>http://typedef.ru/2011/04/science-and-life/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 10:12:43 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[жизнь]]></category>
		<category><![CDATA[наука]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=753</guid>
		<description><![CDATA[Еду, стало быть, в метро. Изучаю налепленные на стены вагонов творения неизвестных рекламщиков. Оказывается, средство от аллергии N не вызывает сонливости! Волшебно! Но впечатление смазывается циферками-сносками. Что обычно пишут в сносках к рекламному тексту? Например, что N не вызывает сонливости, если его не принимать. Или что сонливостью считается только мгновенное погружение в сон не менее [...]]]></description>
			<content:encoded><![CDATA[<p>Еду, стало быть, в метро. Изучаю налепленные на стены вагонов творения неизвестных рекламщиков. Оказывается, средство от аллергии N не вызывает сонливости! Волшебно! Но впечатление смазывается циферками-сносками. Что обычно пишут в сносках к рекламному тексту? Например, что N не вызывает сонливости, если его не принимать. Или что сонливостью считается только мгновенное погружение в сон не менее чем на 10 часов. Но нет!</p>
<p>В сносках были ссылки на научные статьи. Такие дела.</p>
<p>Я аж всплакнул от счастья.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/04/science-and-life/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unix: тени прошлого</title>
		<link>http://typedef.ru/2011/04/unix-shadows-of-the-past/</link>
		<comments>http://typedef.ru/2011/04/unix-shadows-of-the-past/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 13:40:20 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[UNIX]]></category>
		<category><![CDATA[грабли]]></category>
		<category><![CDATA[история]]></category>
		<category><![CDATA[устройство ОС]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=751</guid>
		<description><![CDATA[Друзья, не обижайтесь, но у меня сейчас совершенно нет времени писать что-то вдумчивое и основательное. Поэтому решил разбавить тишину ссылками на статьи с LWN: Ghosts of Unix Past, part 1 Ghosts of Unix Past, part 2 Ghosts of Unix Past, part 3 Ghosts of Unix Past, part 4 Вкратце о содержимом. В ранние годы Unix [...]]]></description>
			<content:encoded><![CDATA[<p>Друзья, не обижайтесь, но у меня сейчас совершенно нет времени писать что-то вдумчивое и основательное. Поэтому решил разбавить тишину ссылками на статьи с LWN:</p>
<ul>
<li><a href="http://lwn.net/Articles/411845/" target="_blank">Ghosts of Unix Past, part 1</a></li>
<li><a href="http://lwn.net/Articles/412131/" target="_blank">Ghosts of Unix Past, part 2</a></li>
<li><a href="http://lwn.net/Articles/414618/" target="_blank">Ghosts of Unix Past, part 3</a></li>
<li><a href="http://lwn.net/Articles/416494/" target="_blank">Ghosts of Unix Past, part 4</a></li>
</ul>
<p>Вкратце о содержимом. В ранние годы Unix были приняты некоторые архитектурные решения, которые определили то, что сейчас принято называть &laquo;Unix Way&raquo;. Над этими решениями думали не самые глупые люди, но предусмотреть, что будет через 40 лет, никто не в силах. Поэтому в свете современных требований некоторые ключевые решения и паттерны до сих пор остались красивыми и согласованными, а некоторые породили проблемы разной величины. В статьях как раз про второй тип: какие выявились проблемы, как их можно решать и как они решаются сейчас.</p>
<p>Лично меня статьи зацепили тем, что многие из описанных проблем я заметил и сам, хотя и не подвергал их такому глубокому анализу.</p>
<p>Как часто бывает на LWN, комменты не менее ценны, чем сами статьи.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/04/unix-shadows-of-the-past/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Предупреждение</title>
		<link>http://typedef.ru/2011/03/warning/</link>
		<comments>http://typedef.ru/2011/03/warning/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 12:46:41 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=749</guid>
		<description><![CDATA[Кривизна моих рук достигла неимоверных высот. Поэтому не удивляйтесь, что в RSS-фиде внезапно появилось несколько старых постов.]]></description>
			<content:encoded><![CDATA[<p>Кривизна моих рук достигла неимоверных высот. Поэтому не удивляйтесь, что в RSS-фиде внезапно появилось несколько старых постов.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/03/warning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Разбор программы, играющей «в города»</title>
		<link>http://typedef.ru/2011/03/cities-uncovered/</link>
		<comments>http://typedef.ru/2011/03/cities-uncovered/#comments</comments>
		<pubDate>Sat, 05 Mar 2011 20:24:55 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[алгоритмы]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=724</guid>
		<description><![CDATA[Напомню требования к программе. Входные данные — последовательность строк; каждая строка начинается с прописной буквы, остальные буквы строчные. Входную последовательность всегда можно переупорядочить в допустимую последовательность, в которой у каждой пары смежных строк первая буква второй строки, переведенная в нижний регистр, совпадает с последней допустимой буквой первой строки. Допустимая буква — это буква, с которой начинается [...]]]></description>
			<content:encoded><![CDATA[<p>Напомню требования к <a href="http://typedef.ru/2011/02/code-golf-cities-in-c/" target="_blank">программе</a>.</p>
<ol>
<li>Входные данные — последовательность строк; каждая строка начинается с прописной буквы, остальные буквы строчные.</li>
<li>Входную последовательность всегда можно переупорядочить в <em>допустимую последовательность</em>, в которой у каждой пары смежных строк первая буква второй строки, переведенная в нижний регистр, совпадает с последней допустимой буквой первой строки. <em>Допустимая буква</em> — это буква, с которой начинается хотя бы одно слово последовательности.</li>
<li>Требуется написать кратчайшую программу, находящую любую допустимую перестановку входной последовательности.</li>
</ol>
<p>Как это часто бывает, есть два очевидных способа решения этой задачи: один быстрый, другой простой.</p>
<p>Суть <strong>быстрого алгоритма</strong>: возьмем все первые и последние допустимые буквы всех слов и сделаем их вершинами в графе. Сами слова будут представлены дугами. Теперь достаточно в этом графе <em>найти эйлерову цепь или эйлеров цикл</em>. Если кто не помнит, эйлерова цепь/цикл проходит через каждую дугу графа ровно один раз. В честь Эйлера, который желал странного, бродя по кенигсбергским мостам.</p>
<p>Быстрый алгоритм хорош тем, что он быстрый. И плох тем, что трудно его реализовать компактно. Такое случается с быстрыми алгоритмами, ничего не поделаешь&#8230; Из-за этого многие им предпочитают медленные и простые, но ради справедливости код все равно пишут длинный и сложный.  И комментарии к нему не пишут. А потом увольняются, а новый разработчик все переписывает заново. Используя тот же алгоритм. Да&#8230; О чем я говорил?</p>
<p>К счастью, в требованиях к программе ничего не сказано про время работы, что совершенно развязывает нам руки и позволяет использовать Его Величество Полный Перебор. К слову, полный перебор часто недооценивают, и он играет роль этакого <em>алгоритмического goto</em> — подходит не везде, но во многих случаях сильно упрощает жизнь, хотя и сильно нелюбим большинством.</p>
<p>Идея <strong>простого алгоритма</strong> в том, чтобы рассмотреть все перестановки входной последовательности и проверить каждую на допустимость. Одна из них, согласно условию, обязательно подойдет.</p>
<p>От алгоритма перебора всех перестановок требуется только одно: как можно более короткая реализация. Концептуально наиболее просто способ — перемешивать последовательность случайным образом, как карты в колоде. При идеальном генераторе случайных чисел случайный перебор потребует столько же времени, сколько и &laquo;честный&raquo;. К сожалению, в стандартной библиотеке C нет функций вроде shuffle, поэтому напишем честный перебор руками. Я взял кнутовское &laquo;Искусство программирования&raquo;, том 4, выпуск 2, главу 7.2.1.2 и нашел там на странице 71 (в русскоязычном издании) алгоритм <em>генерации перестановок с помощью циклических сдвигов</em>. Автор уверял, что алгоритм отличается чертовски простой реализацией. Итак, имея исходную последовательность $x_1\ldots x_n$:</p>
<ol>
<li>Установить $a_i = x_i$, $1 \leq i \leq n$.</li>
<li>Посетить перестановку $a_1 \ldots a_n$ и установить $k = n$.</li>
<li>Заменить $a_1a_2\ldots a_k$ на $a_2\ldots a_ka_1$ (циклический сдвиг). Если $a_k \neq x_k$, перейти к п. 2.</li>
<li>Уменьшить $k$ на 1. Если $k &gt; 1$, вернуться к п. 3 (мы будем возвращаться на п.3 без выполнения этой проверки, т.к. знаем, что одна из перестановок нам точно подойдет).</li>
</ol>
<p>Проверка перестановки на допустимость выполняется элементарно. Построим множество первых букв всех слов. Для каждой пары соседних слов в перестановке:</p>
<ol>
<li>Отбрасываем с конца первого слова буквы до тех пор, пока последняя буква не будет присутствовать в множестве первых букв. Такая буква всегда существует: в худшем случае это будет первая буква слова.</li>
<li>Сравниваем последнюю оставшуюся букву первого слова с первой буквой второго слова.</li>
</ol>
<p>Поскольку первые буквы — прописные, их надо преобразовать в строчные. Проще всего это делается для букв в кодировке ASCII или CP1251: нужно просто прибавить к коду буквы 32.</p>
<p>Итак, первый вариант программы:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;string.h&gt;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">**</span> argv<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> k<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> match<span style="color: #339933;">,</span> first<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>r<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>permut<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> maxidx<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// обнуляем множество первых букв</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">256</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        first<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// входная последовательность задана в командной строке, поэтому</span>
    <span style="color: #666666; font-style: italic;">// пропускаем находящееся в начале массива argv имя программы</span>
    argv<span style="color: #339933;">++;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// проходим по входным словам (argv завершается нулевым указателем)</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> argv<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        permut<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> argv<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// начальная перестановка равна исходной</span>
        first<span style="color: #009900;">&#91;</span>permut<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// добавляем первую букву слова в множество</span>
    <span style="color: #009900;">&#125;</span>
    maxidx <span style="color: #339933;">=</span> i <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// максимальный индекс слова в последовательности</span>
    k <span style="color: #339933;">=</span> maxidx<span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">// когда match станет 1, допустимая последовательность найдена</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>match <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> <span style="color: #339933;">!</span>match<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// циклический сдвиг элементов массива permut с 0 по k-1</span>
        r <span style="color: #339933;">=</span> permut<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        memmove<span style="color: #009900;">&#40;</span>permut <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> permut<span style="color: #339933;">,</span> k<span style="color: #339933;">*</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        permut<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> r<span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// см. алгоритм сдвига</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>permut<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> argv<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
            k<span style="color: #339933;">--;</span>
        <span style="color: #b1b100;">else</span>
            k <span style="color: #339933;">=</span> maxidx<span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// проверка перестановки на допустимость</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> match <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> maxidx <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">&amp;&amp;</span> match<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// получим указатель на последнюю букву первого слова</span>
            r <span style="color: #339933;">=</span> permut<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> strlen<span style="color: #009900;">&#40;</span>permut<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">// сдвигаем указатель, пока не найдем букву из множества первых букв</span>
            <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>first<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>r<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
                r<span style="color: #339933;">--;</span>
            <span style="color: #666666; font-style: italic;">// проверяем совпадение</span>
            match <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>r <span style="color: #339933;">==</span> <span style="color: #339933;">*</span>permut<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> maxidx<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> permut<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>А дальше дело техники — надо сжимать программу:</p>
<ol>
<li>Всем переменным — кратчайшие имена.</li>
<li>Убираем включения заголовочных файлов, оператор return (компилятор сам вставит), все упоминания типа int (это тип по умолчанию, его можно не указывать).</li>
<li>Вспоминаем, что глобальные переменные инициализируются нулями.</li>
<li>Заменим sizeof(char*) на 4 или 8, если компилируем, соответственно, на 32- или 64-разрядной системе.</li>
<li>Используем argc в качестве одной из нужных нам переменных, например, maxidx.</li>
</ol>
<p>Получим:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">k<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> f<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>r<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> l<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">**</span> x<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    x<span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> x<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> x<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    l <span style="color: #339933;">=</span> i <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    k <span style="color: #339933;">=</span> l<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> <span style="color: #339933;">!</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        r <span style="color: #339933;">=</span> q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        memmove<span style="color: #009900;">&#40;</span>q <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> q<span style="color: #339933;">,</span> k<span style="color: #339933;">*</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> r<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> x<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
            k<span style="color: #339933;">--;</span>
        <span style="color: #b1b100;">else</span>
            k <span style="color: #339933;">=</span> l<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> b <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> l <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">&amp;&amp;</span> b<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            r <span style="color: #339933;">=</span> q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> strlen<span style="color: #009900;">&#40;</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>r<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
                r<span style="color: #339933;">--;</span>
            b <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>r <span style="color: #339933;">==</span> <span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span>i <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> l<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Ну, и остается только</p>
<ol>
<li>Избавиться от strlen — указатель на последнюю букву можно найти и короче.</li>
<li>Выполнить кое-какие перестановки присваиваний и инкрементов, использовать разыменование вместо индексации.</li>
<li>Убрать пробелы и переводы строк.</li>
</ol>
<p>Получим итоговый вариант (разбиение на строки оставлено для читабельности):</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">k<span style="color: #339933;">,</span>i<span style="color: #339933;">,</span>b<span style="color: #339933;">,</span>f<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span><span style="color: #339933;">*</span>r<span style="color: #339933;">,*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> l<span style="color: #339933;">,</span><span style="color: #993333;">char</span><span style="color: #339933;">**</span>x<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>x<span style="color: #339933;">++;</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>x<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>l<span style="color: #339933;">=--</span>k<span style="color: #339933;">;!</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        memmove<span style="color: #009900;">&#40;</span>q<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>q<span style="color: #339933;">,</span>k<span style="color: #339933;">*</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #339933;">*</span>q<span style="color: #339933;">=</span>r<span style="color: #339933;">;</span>
        k<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>x<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">?</span>k<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>l<span style="color: #339933;">;</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span>l<span style="color: #339933;">&amp;&amp;</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;*</span>r<span style="color: #339933;">++;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*--</span>r<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            b<span style="color: #339933;">=*</span>r<span style="color: #339933;">==*</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> l<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Вот и все. Должен только заметить, что даже если все допустимые буквы — последние, все равно время работы алгоритма будет что-то вроде $O(n\cdot n!)$, где $n$ — количество строк во входной последовательности. Время работы сильно зависит от порядка слов во входной последовательности и от порядка перебора. На моем компьютере на 14 словах алгоритм работал более 10 минут! Добавить 15-е слово я не решился. Так что с общечеловеческой точки зрения это очень плохой алгоритм.</p>
<p>Кстати, в предыдущем посте у меня в код закралась неиспользуемая переменная, что позволяет сократить решение еще на 2 символа.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/03/cities-uncovered/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Code Golf: игра «в города» на C</title>
		<link>http://typedef.ru/2011/02/code-golf-cities-in-c/</link>
		<comments>http://typedef.ru/2011/02/code-golf-cities-in-c/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 12:58:04 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[алгоритмы]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=706</guid>
		<description><![CDATA[Вчера наткнулся на давно закончившийся конкурс на написание самой короткой программы для игры &#171;в города&#187;. Вкратце: программе подается на вход набор строк, а она их должна выстроить так, чтобы последняя буква i-ой строки совпадала с первой буквой i+1-ой строки. Если строка оканчивается на букву, с которой не начинается ни одна другая строка, разрешается &#171;удалять&#187; последнюю [...]]]></description>
			<content:encoded><![CDATA[<p>Вчера наткнулся на давно закончившийся <a href="http://www.askdev.ru/question/1969/Code-Golf-%D0%B8%D0%B3%D1%80%D0%B0-%D0%B2-%D0%B3%D0%BE%D1%80%D0%BE%D0%B4%D0%B0/" target="_blank">конкурс</a> на написание самой короткой программы для игры &laquo;в города&raquo;. Вкратце: программе подается на вход набор строк, а она их должна выстроить так, чтобы последняя буква i-ой строки совпадала с первой буквой i+1-ой строки. Если строка оканчивается на букву, с которой не начинается ни одна другая строка, разрешается &laquo;удалять&raquo; последнюю букву до тех пор, пока это условие не нарушится. Решение всегда есть. Самое главное: основная часть программы должна состоять из минимально возможного количества символов, ввод-вывод-подготовка не считаются.</p>
<p>Победило в конкурсе решение, кто бы сомневался, <a href="http://www.askdev.ru/a/4147" target="_blank">на Перле</a> в 62 символа (и фиг с ним). Меня поразило <a href="http://www.askdev.ru/a/4002" target="_blank">решение на C</a>, в котором вся программа состоит из 229 символов. На такое я спокойно смотреть не мог. Несколько часов работы — и получилось то же самое выразить в 225 символах! Давненько я не получал такого удовольствия от возни с кодом!</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">k<span style="color: #339933;">,</span>i<span style="color: #339933;">,</span>t<span style="color: #339933;">,</span>b<span style="color: #339933;">,</span>f<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>char<span style="color: #339933;">*</span>r<span style="color: #339933;">,*</span>q<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">256</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> l<span style="color: #339933;">,</span><span style="color: #993333;">char</span><span style="color: #339933;">**</span>s<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">++;</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>s<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span>l<span style="color: #339933;">=--</span>k<span style="color: #339933;">;!</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>memmove<span style="color: #009900;">&#40;</span>q<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>q<span style="color: #339933;">,</span>k<span style="color: #339933;">*</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;*</span>q<span style="color: #339933;">=</span>r<span style="color: #339933;">;</span>k<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>s<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">?</span>k<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>l<span style="color: #339933;">;</span>
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span>l<span style="color: #339933;">&amp;&amp;</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;*</span>r<span style="color: #339933;">++;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>while<span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*--</span>r<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>b<span style="color: #339933;">=*</span>r<span style="color: #339933;">==*</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>А если оставить только код, решающий задачу, то получится 174 символа:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">++;</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span>s<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span>l<span style="color: #339933;">=--</span>k<span style="color: #339933;">;!</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>memmove<span style="color: #009900;">&#40;</span>q<span style="color: #339933;">+</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span>q<span style="color: #339933;">,</span>k<span style="color: #339933;">*</span><span style="color: #0000dd;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;*</span>q<span style="color: #339933;">=</span>r<span style="color: #339933;">;</span>k<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">==</span>s<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">?</span>k<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">:</span>l<span style="color: #339933;">;</span>for<span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span>b<span style="color: #339933;">=</span><span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>i<span style="color: #339933;">&lt;</span>l<span style="color: #339933;">&amp;&amp;</span>b<span style="color: #339933;">;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span>r<span style="color: #339933;">=</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">++</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;*</span>r<span style="color: #339933;">++;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>while<span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>f<span style="color: #009900;">&#91;</span><span style="color: #339933;">*--</span>r<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>b<span style="color: #339933;">=*</span>r<span style="color: #339933;">==*</span>q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">+</span><span style="color: #0000dd;">32</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Переводы строк, как наверное многие догадались, перед подсчетом надо убрать.</p>
<p>Имена городов передаются в командной строке через пробел. Первая буква каждого имени должна быть прописная. Кодировка cp1251 (если русскими буквами) или ASCII. Компилировать gcc на 64-битной системе. Например:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>cities Kaliningrad Vologda Dalmatovo Dmitrov Arkhangelsk Vladivistok Krakov
Dalmatovo
Vladivostok
Kaliningrad
Dmitrov
Vologda
Arkhangelsk
Krakov</pre></div></div>

<p>Чтобы программа выводила результат, нужно вставить в main код вывода:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;=</span> l<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> q<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Если интересно, как это работает, напишу отдельным постом.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/02/code-golf-cities-in-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Нахождение всех путей между двумя вершинами, матричный подход</title>
		<link>http://typedef.ru/2011/01/calculating-all-routes-between-two-vertices-with-matrix/</link>
		<comments>http://typedef.ru/2011/01/calculating-all-routes-between-two-vertices-with-matrix/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 18:18:10 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[математика]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=692</guid>
		<description><![CDATA[В теории графов я не силен, как, впрочем, и во всем остальном тоже. Но наткнувшись на этот метод поиска всех простых путей между двумя вершинами в графе, я немало удивился. А когда убедился, что метод работает, удивился еще больше. Приведу здесь наглядное описание метода. Составляем структурную матрицу $A$ графа $G$. Элемент $a_{ij}$ матрицы содержит: $0$, [...]]]></description>
			<content:encoded><![CDATA[<p>В теории графов я не силен, как, впрочем, и во всем остальном тоже. Но наткнувшись на этот <a href="http://dvo.sut.ru/libr/himath/w163rabk/11.htm" target="_blank">метод поиска всех простых путей между двумя вершинами в графе</a>, я немало удивился. А когда убедился, что метод работает, удивился еще больше. Приведу здесь наглядное описание метода.</p>
<ol>
<li>Составляем <strong>структурную матрицу</strong> $A$ графа $G$. Элемент $a_{ij}$ матрицы содержит:
<ul>
<li>$0$, если в графе нет ребра $(i, j)$.</li>
<li>$1$, если $i = j$.</li>
<li>Имя булевской переменной, идентифицирующей ребро $(i, j)$. Если $i &lt; j$, указывается сама переменная, а если $i &gt; j$, то ее отрицание, например, $a_{ij}=x$ и $a_{ji}=\bar x$. Если между вершинами $i$ и $j$ несколько ребер, указывается их конъюнкция, например, $a_{ij}=x \wedge y$ и $a_{ji}=\bar x \vee \bar y$.</li>
</ul>
</li>
<li>Для нахождения всех простых путей между вершинами $i$ и $j$ необходимо найти дополнительный минор $\bar{M}^j_i$ (вычеркнуть $j$-ую строку и $i$-ый столбец и найти определитель оставшейся матрицы) по следующим правилам:
<ul>
<li>вместо сложения/вычитания используется дизъюнкция;</li>
<li>вместо умножения используется конъюнкция;</li>
<li>$1$ выступает в роли истинного значения, а $0$ — ложного;</li>
<li>$x \wedge \bar x$ уничтожаются, ну и вообще, можно выполнять обычные булевские преобразования.</li>
</ul>
</li>
<li>Получили булевское выражение в дизъюнктивной форме. Каждая конъюнктивная группа в нем соответствует маршруту между выбранными вершинами, а каждая переменная, входящая в группу, обозначает соответствующее ребро. Отрицания можно убрать, они показывают направление прохождения ребер.</li>
</ol>
<p>Немного запутанно выглядит, да? Рассмотрим на конкретном примере. Возьмем полный граф с тремя вершинами. Ребрам сопоставим следующие переменные:</p>
<ul>
<li>$(1, 2)$ — $x$;</li>
<li>$(1, 3)$ — $y$;</li>
<li>$(2, 3)$ — $z$.</li>
</ul>
<p>Структурная матрица тогда получится такой:</p>
<p>$$<br />
A=\left( \begin{array}{ccc}<br />
1 &amp;&amp; x &amp;&amp; y\\<br />
\bar x &amp;&amp; 1 &amp;&amp; z \\<br />
\bar y &amp;&amp; \bar z &amp;&amp; 1<br />
\end{array} \right)<br />
$$</p>
<p>Найдем все маршруты между вершинами 1 и 3. Вычеркнув третью строку и первый столбец, найдем значение минора:</p>
<p>$$<br />
\bar M^3_1 = \left| \begin{array}{cc}<br />
x &amp;&amp; y \\<br />
1 &amp;&amp; z<br />
\end{array} \right| = (x \wedge z) \vee y<br />
$$</p>
<p>Вот и получилось, что есть два маршрута, один через ребра $x$ и $z$, а второй — через ребро $y$.</p>
<p>Красивый хак, а?  Что интересно, как я ни старался, не смог найти описание этого метода в англоязычных источниках. Может, кто-то видел подобное?</p>
<p>P.S. Включите JavaScript для отображения формул. Если не работает, пишите в комменты вместе с версией браузера.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2011/01/calculating-all-routes-between-two-vertices-with-matrix/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Обновление движка</title>
		<link>http://typedef.ru/2010/12/blog-cms-update/</link>
		<comments>http://typedef.ru/2010/12/blog-cms-update/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 14:25:46 +0000</pubDate>
		<dc:creator>Сан Саныч</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[блог]]></category>

		<guid isPermaLink="false">http://typedef.ru/?p=680</guid>
		<description><![CDATA[Обновил движок блога, некоторое время могут быть глюки. Не обращайте внимания.]]></description>
			<content:encoded><![CDATA[<p>Обновил движок блога, некоторое время могут быть глюки. Не обращайте внимания.</p>
]]></content:encoded>
			<wfw:commentRss>http://typedef.ru/2010/12/blog-cms-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

