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

<channel>
	<title>JL&#039;s blog &#187; Perl</title>
	<atom:link href="http://john.5070.info/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://john.5070.info</link>
	<description>:-)</description>
	<lastBuildDate>Sun, 06 Dec 2009 17:11:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Организация бэкапов с помощью LVM</title>
		<link>http://john.5070.info/2009/06/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b1%d1%8d%d0%ba%d0%b0%d0%bf%d0%be%d0%b2-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-lvm/</link>
		<comments>http://john.5070.info/2009/06/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b1%d1%8d%d0%ba%d0%b0%d0%bf%d0%be%d0%b2-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-lvm/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 05:58:14 +0000</pubDate>
		<dc:creator>John Lepikhin</dc:creator>
				<category><![CDATA[программирование]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[LVM]]></category>
		<category><![CDATA[lvm2]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://john.5070.info/?p=132</guid>
		<description><![CDATA[Вдруг осознал, что я тут двигаю всякие классные технологии, а сам пребываю в каменном веке. Перенёс /home в LVM. Сразу захотелось использовать моментальные инкрементальные бэкапы LVM. Как это сделать в сети написано (точнее, раскопировано и переведено) уже не один десяток раз. Но я пока не встретил ни одной статьи, где простые примеры создания снимка эволюционировали [...]]]></description>
			<content:encoded><![CDATA[<p>Вдруг осознал, что я тут двигаю всякие классные технологии, а сам пребываю в каменном веке. Перенёс /home в LVM. Сразу захотелось использовать моментальные инкрементальные бэкапы LVM. Как это сделать в сети написано (точнее, раскопировано и переведено) уже не один десяток раз. Но я пока не встретил ни одной статьи, где простые примеры создания снимка эволюционировали до полноценного скрипта. Восполню этот пробел quick programming&#8217;ом.</p>
<p><span id="more-132"></span>Но сначала немного технических деталей. В снапшотах ZFS есть неоспоримые преимущества перед снапшотами LVM:</p>
<ol>
<li>В LVM надо заранее выделять место под снапшот (по сути, создавать ещё один logical volume). Если размер изменений в основном разделе превысили это место, снапшот становится неактивным. Его нельзя ни подмонтировать, ни растянуть. Только удалить. Но место под снапшоты можно налету увеличивать, это сомнительный, но плюс.</li>
<li>В LVM в каждом снапшоте хранится разница с основным разделом, а не с предыдущим разделом. В итоге, если мы сделали снапшот backup1, затем залили в FS файлик 30MB, затем сделали снапшот backup2, затем залили ещё один файлик на 30MB, то в backup1 будет занято 60MB, а в backup2 30MB. Логично было бы делать снапшот от снапшота, тогда разница накапливалась по-человечьи. Но LVM такое извращение не поддерживается.</li>
</ol>
<p>Но есть и преимущества:</p>
<ol>
<li>Снапшот является RW. Честно говоря, так и не придумал, зачем оно может понадобиться.</li>
<li>LVM живёт в kernel space, в отличие от порта ZFS на Linux zfs-fuse.</li>
<li>ZFS предоставляет и не нужный мне слой навороченной FS.</li>
</ol>
<p>Итак, надо периодически делать снапшот раздела, хранить определённое количество часовых и суточных копий. Для этого написал shell-скриптик lvm-home-snapshot. Вот он:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #007800;">name</span>=$<span style="color: #000000;">1</span>
<span style="color: #007800;"><span style="color: #c20cb9; font-weight: bold;">size</span></span>=$<span style="color: #000000;">2</span>
<span style="color: #007800;">vgname</span>=$<span style="color: #000000;">3</span>
<span style="color: #007800;">lvname</span>=$<span style="color: #000000;">4</span>
<span style="color: #007800;">copies</span>=$<span style="color: #000000;">5</span>
&nbsp;
<span style="color: #007800;"><span style="color: #000000; font-weight: bold;">time</span></span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #ff0000;">'%Y-%m-%d--%H-%M-%S'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">sname</span>=<span style="color: #ff0000;">&quot;backup-<span style="color: #007800;">$time</span>-<span style="color: #007800;">$name</span>&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>lvcreate <span style="color: #660033;">-p</span> r -L<span style="color: #007800;">$size</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-n</span> <span style="color: #007800;">$sname</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$vgname</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$lvname</span>
&nbsp;
<span style="color: #007800;">lst</span>=<span style="color: #000000; font-weight: bold;">`/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>lvdisplay <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #ff0000;">'^ +LV Name'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #ff0000;">&quot;/dev/<span style="color: #007800;">$vgname</span>/backup-.*-<span style="color: #007800;">$name</span>&quot;</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'{print $3}'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">snapshots_cnt</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$lst</span><span style="color: #000000; font-weight: bold;">|</span><span style="color: #c20cb9; font-weight: bold;">wc</span> -w<span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$snapshots_cnt</span> <span style="color: #660033;">-gt</span> <span style="color: #007800;">$copies</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">to_delete</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$lst</span>; <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$i</span>; <span style="color: #000000; font-weight: bold;">done</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">head</span> $<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$copies</span>-<span style="color: #007800;">$snapshots_cnt</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #000000; font-weight: bold;">`</span>
	<span style="color: #000000; font-weight: bold;">for</span> i <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$to_delete</span>; <span style="color: #000000; font-weight: bold;">do</span> <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>lvremove <span style="color: #660033;">-f</span> <span style="color: #007800;">$i</span>; <span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #000000; font-weight: bold;">fi</span></pre></div></div>

<p>Как хорошо видно, принимает 5 параметров: имя снапшота, размер, имя группы разделов, имя раздела, количество хранимых копий. Пример использования:</p>
<p>lvm-home-snapshot hourly 768M home john 3</p>
<p>Создаст снапшот &#8220;/dev/home/backup-2009-06-19&#8211;14-45-01-hourly&#8221; раздела /dev/home/john размером 768MB. Если накопилось более трёх снапшотов с именем hourly — наиболее старые будут удалены. Итого, в крон написал:</p>
<p>0 14        * * *    /root/bin/lvm-home-snapshot day 2G home john 4<br />
0 0-4,15-23    * * *    /root/bin/lvm-home-snapshot hour 256M home john 8<br />
15,30,45 *    * * *    /root/bin/lvm-home-snapshot hourquot 128M home john 3</p>
<p>Итак снапшоты создаются, всё чудно. Но надо как-то минимизировать вероятность перезаполнения снапшотов. Для этого был написан ещё один скрипт, который заодно удаляет INACTIVE (переполнившиеся) снапшоты:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$vgname</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$maxpct</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$addpct</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@ARGV</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">open</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$proc</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;/sbin/lvdisplay|&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$d</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$s</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$u</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;">&lt;</span><span style="color: #0000ff;">$proc</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">chomp</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^ +LV Name +(.*)/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$d</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$1</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">elsif</span> <span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^ +COW-table size +(\d+)\S* +(.*)/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$s</span><span style="color: #339933;">=</span><span style="color: #000066;">int</span> <span style="color: #0000ff;">$1</span><span style="color: #339933;">;</span> <span style="color: #0000ff;">$u</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$2</span> <span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">elsif</span> <span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^ +Allocated to snapshot +(\d+)/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$pct</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$1</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">next</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$d</span> <span style="color: #339933;">!~</span> <span style="color: #000066;">m</span><span style="color: #339933;">|^</span><span style="color: #009966; font-style: italic;">/dev/</span><span style="color: #0000ff;">$vgname</span><span style="color: #339933;">/</span>backup<span style="color: #339933;">-.*-</span><span style="color: #0000ff;">$name</span><span style="color: #0000ff;">$|</span> <span style="color: #339933;">||</span> <span style="color: #0000ff;">$pct</span><span style="color: #339933;">&lt;</span><span style="color: #0000ff;">$maxpct</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$newsize</span> <span style="color: #339933;">=</span> <span style="color: #000066;">int</span> <span style="color: #0000ff;">$s</span><span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$addpct</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">100</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #ff0000;">`/sbin/lvextend -L$newsize$u $d`</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">elsif</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">m</span><span style="color: #339933;">|^</span> <span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/dev/</span><span style="color: #0000ff;">$vgname</span><span style="color: #339933;">/</span>backup<span style="color: #339933;">-.*-</span><span style="color: #0000ff;">$name</span><span style="color: #009900;">&#41;</span> \<span style="color: #009900;">&#91;</span>INACTIVE\<span style="color: #009900;">&#93;</span><span style="color: #339933;">|</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #ff0000;">`/sbin/lvremove -f $1`</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000066;">close</span> <span style="color: #0000ff;">$proc</span></pre></div></div>

<p>Принимает параметры: имя снапшота, имя группы разделов, максимальный процент занятости (при превышении снапшот увеличивается), на сколько процентов от текущего увеличить. Пример использования:</p>
<p>lvm-home-snapshot-extend hourly home 15 30</p>
<p>Все снапшоты с именем hourly в группе разделов home, занятые более чем на 15%, будут увеличены на 30%. В крон добавил строчки:</p>
<p>* *        * * *    /root/bin/lvm-home-snapshot-extend hourquot home 15 30<br />
* *        * * *    /root/bin/lvm-home-snapshot-extend hour home 25 30<br />
* *        * * *    /root/bin/lvm-home-snapshot-extend day home 35 20</p>
<p>Не слишком эффективно, но меня устраивает. Да и лень как-то дальше развивать.</p>
]]></content:encoded>
			<wfw:commentRss>http://john.5070.info/2009/06/%d0%be%d1%80%d0%b3%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b1%d1%8d%d0%ba%d0%b0%d0%bf%d0%be%d0%b2-%d1%81-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%d1%8e-lvm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Решение для решателя Sudoku</title>
		<link>http://john.5070.info/2009/06/%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b5%d1%88%d0%b0%d1%82%d0%b5%d0%bb%d1%8f-sudoku/</link>
		<comments>http://john.5070.info/2009/06/%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b5%d1%88%d0%b0%d1%82%d0%b5%d0%bb%d1%8f-sudoku/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 14:54:30 +0000</pubDate>
		<dc:creator>John Lepikhin</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Ocaml]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[программирование]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sudoku]]></category>

		<guid isPermaLink="false">http://john.5070.info/?p=126</guid>
		<description><![CDATA[Хотел вечерком размять мозг — набросать какой-нибудь особенно красивый решатель Sudoku на Ocaml. Но возникла мысль изучить вражеские аналоги. Итак, решатель Sudoku размером 800 с небольшим байт:

include Set.Make&#40;struct type t = &#40;int * int&#41; * int let compare = compare end&#41;
&#160;
let &#40;@&#41; g f x = g &#40;f x&#41; and id x = x and [...]]]></description>
			<content:encoded><![CDATA[<p>Хотел вечерком размять мозг — набросать какой-нибудь особенно красивый решатель Sudoku на Ocaml. Но возникла мысль изучить вражеские аналоги. Итак, решатель Sudoku размером 800 с небольшим байт:</p>

<div class="wp_syntax"><div class="code"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">include</span> <span style="color: #06c; font-weight: bold;">Set</span><span style="color: #a52a2a;">.</span><span style="color: #060;">Make</span><span style="color: #6c6;">&#40;</span><span style="color: #06c; font-weight: bold;">struct</span> <span style="color: #06c; font-weight: bold;">type</span> t <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">&#40;</span>int <span style="color: #a52a2a;">*</span> int<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">*</span> int <span style="color: #06c; font-weight: bold;">let</span> <span style="color: #06c; font-weight: bold;">compare</span> <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">compare</span> <span style="color: #06c; font-weight: bold;">end</span><span style="color: #6c6;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> <span style="color: #6c6;">&#40;</span>@<span style="color: #6c6;">&#41;</span> g f x <span style="color: #a52a2a;">=</span> g <span style="color: #6c6;">&#40;</span>f x<span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">and</span> id x <span style="color: #a52a2a;">=</span> x <span style="color: #06c; font-weight: bold;">and</span> sw f x y <span style="color: #a52a2a;">=</span> f y x <span style="color: #06c; font-weight: bold;">and</span> zip x y <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">&#40;</span>x, y<span style="color: #6c6;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> fold9 f <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">let</span> <span style="color: #06c; font-weight: bold;">rec</span> loop i <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">if</span> i<span style="color: #a52a2a;">&gt;</span><span style="color: #c6c;">8</span> <span style="color: #06c; font-weight: bold;">then</span> id <span style="color: #06c; font-weight: bold;">else</span> loop <span style="color: #6c6;">&#40;</span>i<span style="color: #a52a2a;">+</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span> @ f i <span style="color: #06c; font-weight: bold;">in</span> loop <span style="color: #c6c;">0</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> fold81 f <span style="color: #a52a2a;">=</span> fold9 <span style="color: #6c6;">&#40;</span>fold9 @ <span style="color: #6c6;">&#40;</span>@<span style="color: #6c6;">&#41;</span> f @ zip<span style="color: #6c6;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> mark <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>i,j<span style="color: #6c6;">&#41;</span>,x <span style="color: #06c; font-weight: bold;">as</span> e<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">:</span> t <span style="color: #a52a2a;">-&gt;</span> t <span style="color: #a52a2a;">=</span>
  add e @ fold9 <span style="color: #6c6;">&#40;</span><span style="color: #06c; font-weight: bold;">fun</span> k <span style="color: #a52a2a;">-&gt;</span> remove <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>i<span style="color: #a52a2a;">/</span><span style="color: #c6c;">3</span><span style="color: #a52a2a;">*</span><span style="color: #c6c;">3</span> <span style="color: #a52a2a;">+</span> k<span style="color: #a52a2a;">/</span><span style="color: #c6c;">3</span>, j<span style="color: #a52a2a;">/</span><span style="color: #c6c;">3</span><span style="color: #a52a2a;">*</span><span style="color: #c6c;">3</span> <span style="color: #a52a2a;">+</span> k <span style="color: #06c; font-weight: bold;">mod</span> <span style="color: #c6c;">3</span><span style="color: #6c6;">&#41;</span>, x<span style="color: #6c6;">&#41;</span> @
    remove <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>i,j<span style="color: #6c6;">&#41;</span>,k<span style="color: #6c6;">&#41;</span> @ remove <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>i,k<span style="color: #6c6;">&#41;</span>,x<span style="color: #6c6;">&#41;</span> @ remove <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>k,j<span style="color: #6c6;">&#41;</span>,x<span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> search <span style="color: #a52a2a;">=</span>
  <span style="color: #06c; font-weight: bold;">let</span> g p f s <span style="color: #a52a2a;">=</span> fold <span style="color: #6c6;">&#40;</span>f @ sw mark s<span style="color: #6c6;">&#41;</span> <span style="color: #6c6;">&#40;</span>filter <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span><span style="color: #a52a2a;">=</span><span style="color: #6c6;">&#41;</span> p @ <span style="color: #06c; font-weight: bold;">fst</span><span style="color: #6c6;">&#41;</span> s<span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">in</span>
  fold81 g
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> read <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span>
  <span style="color: #06c; font-weight: bold;">let</span> f p <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">Scanf</span><span style="color: #a52a2a;">.</span><span style="color: #060;">scanf</span> <span style="color: #3cb371;">&quot;%d &quot;</span> <span style="color: #6c6;">&#40;</span><span style="color: #06c; font-weight: bold;">fun</span> x <span style="color: #a52a2a;">-&gt;</span> <span style="color: #06c; font-weight: bold;">if</span> x<span style="color: #a52a2a;">&gt;</span><span style="color: #c6c;">0</span> <span style="color: #06c; font-weight: bold;">then</span> mark <span style="color: #6c6;">&#40;</span>p,x<span style="color: #a52a2a;">-</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">else</span> id<span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">in</span>
  fold81 f <span style="color: #6c6;">&#40;</span>fold81 <span style="color: #6c6;">&#40;</span>fold9 @ <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>@<span style="color: #6c6;">&#41;</span> add @ zip<span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#41;</span> empty<span style="color: #6c6;">&#41;</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> print s <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span>
  <span style="color: #06c; font-weight: bold;">let</span> pr <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>i,j<span style="color: #6c6;">&#41;</span>,x<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">Printf</span><span style="color: #a52a2a;">.</span><span style="color: #060;">printf</span> <span style="color: #3cb371;">&quot;%d%c&quot;</span> <span style="color: #6c6;">&#40;</span>x<span style="color: #a52a2a;">+</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span> <span style="color: #6c6;">&#40;</span><span style="color: #06c; font-weight: bold;">if</span> j<span style="color: #a52a2a;">=</span><span style="color: #c6c;">8</span> <span style="color: #06c; font-weight: bold;">then</span> <span style="color: #a52a2a;">'</span>\n<span style="color: #a52a2a;">'</span> <span style="color: #06c; font-weight: bold;">else</span> <span style="color: #a52a2a;">'</span> <span style="color: #a52a2a;">'</span><span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">in</span>
  iter pr s<span style="color: #a52a2a;">;</span> <span style="color: #06c; font-weight: bold;">print_newline</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span><span style="color: #a52a2a;">;;</span>
&nbsp;
search print <span style="color: #6c6;">&#40;</span>read <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#41;</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span></pre></div></div>

<p>Вы посмотрите эту красоту, это же [почти] совершенство! А если учесть, что 272 байта — это чтение задачи с STDIN и вывод результата, размер кода сокращается до менее чем 600 байт.</p>
<p><span id="more-126"></span>Впрочем, Perl традиционно отличился своей минималистической магической мешаниной:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> integer<span style="color: #339933;">;</span><span style="color: #0000ff;">@A</span><span style="color: #339933;">=</span><span style="color: #000066;">split</span><span style="color: #339933;">//,&lt;&gt;;</span>sub R<span style="color: #009900;">&#123;</span><span style="color: #b1b100;">for</span><span style="color: #0000ff;">$i</span><span style="color: #009900;">&#40;</span>0<span style="color: #339933;">..</span>80<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #b1b100;">next</span> <span style="color: #b1b100;">if</span><span style="color: #0000ff;">$A</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>my<span style="color: #0000ff;">%t</span><span style="color: #339933;">=</span><span style="color: #000066;">map</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">9</span>
<span style="color: #339933;">==</span><span style="color: #0000ff;">$i</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">9</span><span style="color: #339933;">||</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">%</span>9<span style="color: #339933;">==</span><span style="color: #0000ff;">$i</span><span style="color: #339933;">%</span>9<span style="color: #339933;">||</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">27</span><span style="color: #339933;">==</span><span style="color: #0000ff;">$i</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">27</span><span style="color: #339933;">&amp;&amp;</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">%</span>9<span style="color: #339933;">/</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">==</span><span style="color: #0000ff;">$i</span><span style="color: #339933;">%</span>9<span style="color: #339933;">/</span><span style="color: #cc66cc;">3</span><span style="color: #339933;">?</span><span style="color: #0000ff;">$A</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">=&gt;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span>0<span style="color: #339933;">..</span>80<span style="color: #339933;">;</span>R<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$A</span><span style="color: #009900;">&#91;</span>
<span style="color: #0000ff;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span><span style="color: #b1b100;">for</span> <span style="color: #000066;">grep</span><span style="color: #009900;">&#123;</span><span style="color: #339933;">!</span><span style="color: #0000ff;">$t</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span>1<span style="color: #339933;">..</span>9<span style="color: #339933;">;</span>return<span style="color: #0000ff;">$A</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#125;</span><span style="color: #000066;">die</span><span style="color: #0000ff;">@A</span><span style="color: #009900;">&#125;</span>R</pre></div></div>

<p>Ну и специалисты по PHP тоже выразились: <a href="http://www.weberdev.com/get_example-4243.html">http://www.weberdev.com/get_example-4243.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://john.5070.info/2009/06/%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b4%d0%bb%d1%8f-%d1%80%d0%b5%d1%88%d0%b0%d1%82%d0%b5%d0%bb%d1%8f-sudoku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
