<?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>Serendip &#187; ruby</title>
	<atom:link href="http://www.serendip.ws/archives/tag/ruby/feed" rel="self" type="application/rss+xml" />
	<link>http://www.serendip.ws</link>
	<description>Webデザイン・プログラミング</description>
	<lastBuildDate>Fri, 10 Feb 2012 05:33:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>コーディングスキル判定の麻雀問題を解いてみた</title>
		<link>http://www.serendip.ws/archives/4673</link>
		<comments>http://www.serendip.ws/archives/4673#comments</comments>
		<pubDate>Tue, 06 Apr 2010 09:26:30 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4673</guid>
		<description><![CDATA[こちら（makeplex salon：あなたのスキルで飯は食えるか？　史上最大のコーディングスキル判定 (1/2) &#8211; ITmedia エンタープライズ）の麻雀問題を Ruby で解いてみた。 以前やった迷路 [...]]]></description>
			<content:encoded><![CDATA[<p>こちら（<a href="http://www.itmedia.co.jp/enterprise/articles/1004/03/news002.html" class="out" rel="external">makeplex salon：あなたのスキルで飯は食えるか？　史上最大のコーディングスキル判定 (1/2) &#8211; ITmedia エンタープライズ</a>）の麻雀問題を Ruby で解いてみた。</p>
<p>以前やった迷路探索問題（<a href="http://okajima.air-nifty.com/b/2010/01/post-abc6.html" class="out" rel="external">人生を書き換える者すらいた。: 人材獲得作戦・４　試験問題ほか</a>）の作者の問題らしい。<br />
<a href="/archives/4186">Gauche 穴掘り法で迷路作成</a><br />
<a href="/archives/4133">最短経路探索プログラムの試験問題を解いてみた</a></p>
<p>麻雀に詳しくないのでクラス名・変数名がおかしいかも。</p>
<p>結果の牌の組み合わせを <code>Machi</code> クラスとして <code>MachiList</code> クラスに保存していく。</p>
<p><code>Machi</code> クラスには刻子・順子・アタマ・待ちをそれぞれインスタンス変数として別々に保持する。</p>
<p><code>check</code> メソッドで残り牌の数を調べながら処理を振り分けている。</p>
<pre><span class="Comment">### 待ち</span>
<span class="PreProc">class</span> <span class="Type">Machi</span>
  <span class="Statement">attr_accessor</span> <span class="Constant">:kantsu</span>, <span class="Constant">:juntsu</span>, <span class="Constant">:atama</span>, <span class="Constant">:machi</span>
  <span class="PreProc">def</span> <span class="Identifier">initialize</span>(machi = <span class="Constant">nil</span>)
    <span class="Statement">if</span> machi.nil?
      <span class="Identifier">@kantsu</span> = []
      <span class="Identifier">@juntsu</span> = []
      <span class="Identifier">@atama</span> = <span class="Special">&quot;&quot;</span>
      <span class="Identifier">@machi</span> = <span class="Special">&quot;&quot;</span>
    <span class="Statement">else</span>
      <span class="Identifier">@kantsu</span> = <span class="Type">Array</span>.new(machi.kantsu)
      <span class="Identifier">@juntsu</span> = <span class="Type">Array</span>.new(machi.juntsu)
      <span class="Identifier">@atama</span> = machi.atama
      <span class="Identifier">@machi</span> = machi.machi
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 自身と machi との同一性チェック</span>
  <span class="PreProc">def</span> <span class="Identifier">has_same?</span>(machi)
    <span class="Statement">if</span> (<span class="Identifier">@kantsu</span>.sort &lt;=&gt; machi.kantsu.sort) == <span class="Constant">0</span> <span class="Statement">and</span>
       (<span class="Identifier">@juntsu</span>.sort &lt;=&gt; machi.juntsu.sort) == <span class="Constant">0</span> <span class="Statement">and</span>
       <span class="Identifier">@atama</span> == machi.atama <span class="Statement">and</span>
       <span class="Identifier">@machi</span> == machi.machi
      <span class="Statement">return</span> <span class="Constant">true</span>
    <span class="Statement">else</span>
      <span class="Statement">return</span> <span class="Constant">false</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># データを配列にする</span>
  <span class="Comment"># 待ち牌は [] で囲む</span>
  <span class="PreProc">def</span> <span class="Identifier">to_a</span>
    <span class="Statement">return</span> <span class="Identifier">@kantsu</span>.sort.concat(<span class="Identifier">@juntsu</span>.sort) &lt;&lt; (<span class="Identifier">@atama</span>) &lt;&lt; <span class="Special">&quot;</span><span class="Constant">[</span><span class="Special">#{</span><span class="Identifier">@machi</span><span class="Special">}</span><span class="Constant">]</span><span class="Special">&quot;</span>
  <span class="PreProc">end</span>
<span class="PreProc">end</span>

<span class="Comment">### 待ちリスト</span>
<span class="PreProc">class</span> <span class="Type">MachiList</span>
  <span class="Statement">attr_accessor</span> <span class="Constant">:list</span>
  <span class="PreProc">def</span> <span class="Identifier">initialize</span>
    <span class="Identifier">@list</span> = []
  <span class="PreProc">end</span>

  <span class="Comment"># リストに待ちを追加する</span>
  <span class="Comment"># 追加時に同一性チェックをする</span>
  <span class="PreProc">def</span> <span class="Identifier">add</span>(machi)
    <span class="Statement">if</span> is_unique?(machi)
      <span class="Identifier">@list</span> &lt;&lt; machi
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># リストを印字する</span>
  <span class="PreProc">def</span> <span class="Identifier">print_list</span>
    <span class="Identifier">@list</span>.each <span class="Statement">do</span> |<span class="Identifier">m</span>|
      m.to_a.each <span class="Statement">do</span> |<span class="Identifier">s</span>|
        <span class="Statement">if</span> s.match(<span class="Special">/</span><span class="Special">^</span><span class="Special">\d</span><span class="Special">+</span><span class="Special">$</span><span class="Special">/</span>)
          print <span class="Special">&quot;</span><span class="Constant">(</span><span class="Special">#{</span>s<span class="Special">}</span><span class="Constant">)</span><span class="Special">&quot;</span>
        <span class="Statement">else</span>
          print <span class="Special">&quot;</span><span class="Special">#{</span>s<span class="Special">}</span><span class="Special">&quot;</span>
        <span class="Statement">end</span>
      <span class="Statement">end</span>
      print <span class="Special">&quot;</span><span class="Special">\n</span><span class="Special">&quot;</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 待ちを探す</span>
  <span class="PreProc">def</span> <span class="Identifier">check</span>(data, machi)
    c = count_rest(data)
    <span class="Statement">case</span> c
    <span class="Statement">when</span> <span class="Constant">0</span>
      <span class="Constant">self</span>.add(machi)
    <span class="Statement">when</span> <span class="Constant">1</span>
      <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
        <span class="Statement">if</span> data[i] &gt; <span class="Constant">0</span>
          tmp_mdata = <span class="Type">Array</span>.new(data)
          tmp_mmachi = <span class="Type">Machi</span>.new(machi)
          tmp_mdata[i] -= <span class="Constant">1</span>
          tmp_mmachi.machi = <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}</span><span class="Special">&quot;</span>
          check(tmp_mdata, tmp_mmachi)
        <span class="Statement">end</span>
      <span class="Statement">end</span>
    <span class="Statement">when</span> <span class="Constant">2</span>
      check_machi(data, machi)
    <span class="Statement">when</span> <span class="Constant">4</span>
      check_kantsu(data, machi)
      check_juntsu(data, machi)
      check_atama(data, machi)
    <span class="Statement">else</span>
      check_kantsu(data, machi)
      check_juntsu(data, machi)
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Statement">private</span>

  <span class="Comment"># 刻子</span>
  <span class="PreProc">def</span> <span class="Identifier">check_kantsu</span>(data, machi)
    <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
      <span class="Statement">if</span> has_kantsu?(i, data)
        tmp_kdata = <span class="Type">Array</span>.new(data)
        tmp_kdata[i] -= <span class="Constant">3</span>
        tmp_kmachi = <span class="Type">Machi</span>.new(machi)
        tmp_kmachi.kantsu &lt;&lt; <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i<span class="Special">}#{</span>i<span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_kdata, tmp_kmachi)
      <span class="Statement">end</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 順子</span>
  <span class="PreProc">def</span> <span class="Identifier">check_juntsu</span>(data, machi)
    <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
      <span class="Statement">if</span> has_juntsu?(i, data)
        tmp_jdata = <span class="Type">Array</span>.new(data)
        tmp_jdata[i] -= <span class="Constant">1</span>
        tmp_jdata[i+<span class="Constant">1</span>] -= <span class="Constant">1</span>
        tmp_jdata[i+<span class="Constant">2</span>] -= <span class="Constant">1</span>
        tmp_jmachi = <span class="Type">Machi</span>.new(machi)
        tmp_jmachi.juntsu &lt;&lt; <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i+<span class="Constant">1</span><span class="Special">}#{</span>i+<span class="Constant">2</span><span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_jdata, tmp_jmachi)
      <span class="Statement">end</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># アタマ</span>
  <span class="PreProc">def</span> <span class="Identifier">check_atama</span>(data, machi)
    <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
      <span class="Statement">if</span> has_atama?(i, data)
        tmp_adata = <span class="Type">Array</span>.new(data)
        tmp_adata[i] -= <span class="Constant">2</span>
        tmp_amachi = <span class="Type">Machi</span>.new(machi)
        tmp_amachi.atama = <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i<span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_adata, tmp_amachi)
      <span class="Statement">end</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 待ち</span>
  <span class="PreProc">def</span> <span class="Identifier">check_machi</span>(data, machi)
    <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
      tmp_mdata = <span class="Type">Array</span>.new(data)
      tmp_mmachi = <span class="Type">Machi</span>.new(machi)
      <span class="Statement">if</span> data[i] &gt; <span class="Constant">1</span>
        tmp_mdata[i] -= <span class="Constant">2</span>
        tmp_mmachi.machi = <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i<span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_mdata, tmp_mmachi)
      <span class="Statement">elsif</span> data[i+<span class="Constant">1</span>] <span class="Statement">and</span> data[i] &gt; <span class="Constant">0</span> <span class="Statement">and</span> data[i+<span class="Constant">1</span>] &gt; <span class="Constant">0</span>
        tmp_mdata[i] -= <span class="Constant">1</span>
        tmp_mdata[i+<span class="Constant">1</span>] -= <span class="Constant">1</span>
        tmp_mmachi.machi = <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i+<span class="Constant">1</span><span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_mdata, tmp_mmachi)
      <span class="Statement">elsif</span> data[i+<span class="Constant">2</span>] <span class="Statement">and</span> data[i] &gt; <span class="Constant">0</span> <span class="Statement">and</span> data[i+<span class="Constant">2</span>] &gt; <span class="Constant">0</span>
        tmp_mdata[i] -= <span class="Constant">1</span>
        tmp_mdata[i+<span class="Constant">2</span>] -= <span class="Constant">1</span>
        tmp_mmachi.machi = <span class="Special">&quot;</span><span class="Special">#{</span>i<span class="Special">}#{</span>i+<span class="Constant">2</span><span class="Special">}</span><span class="Special">&quot;</span>
        check(tmp_mdata, tmp_mmachi)
      <span class="Statement">end</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 刻子の候補を持っているかどうか</span>
  <span class="PreProc">def</span> <span class="Identifier">has_kantsu?</span>(i, ary)
    ary[i] &gt; <span class="Constant">2</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 順子の候補を持っているかどうか</span>
  <span class="PreProc">def</span> <span class="Identifier">has_juntsu?</span>(i, ary)
    <span class="Statement">if</span> i &lt; <span class="Constant">8</span>
      ary[i] &gt; <span class="Constant">0</span> <span class="Statement">and</span> ary[i+<span class="Constant">1</span>] &gt; <span class="Constant">0</span> <span class="Statement">and</span> ary[i+<span class="Constant">2</span>] &gt; <span class="Constant">0</span>
    <span class="Statement">else</span>
      <span class="Constant">false</span>
    <span class="Statement">end</span>
  <span class="PreProc">end</span>

  <span class="Comment"># アタマの候補を持っているかどうか</span>
  <span class="PreProc">def</span> <span class="Identifier">has_atama?</span>(i, ary)
    ary[i] &gt; <span class="Constant">1</span>
  <span class="PreProc">end</span>

  <span class="Comment"># 残り牌の数を調べる</span>
  <span class="PreProc">def</span> <span class="Identifier">count_rest</span>(ary)
    count = <span class="Constant">0</span>
    <span class="Constant">1</span>.upto(<span class="Constant">9</span>).each <span class="Statement">do</span> |<span class="Identifier">i</span>|
      <span class="Statement">if</span> ary[i] &gt; <span class="Constant">0</span>
        count += ary[i]
      <span class="Statement">end</span>
    <span class="Statement">end</span>
    count
  <span class="PreProc">end</span>

  <span class="Comment"># 重複する待ちがないかどうかをチェック</span>
  <span class="PreProc">def</span> <span class="Identifier">is_unique?</span>(machi)
    <span class="Identifier">@list</span>.each <span class="Statement">do</span> |<span class="Identifier">m</span>|
      <span class="Statement">if</span> m.has_same?(machi)
        <span class="Statement">return</span> <span class="Constant">false</span>
      <span class="Statement">end</span>
    <span class="Statement">end</span>
    <span class="Statement">return</span> <span class="Constant">true</span>
  <span class="PreProc">end</span>
<span class="PreProc">end</span>

<span class="Comment">### ここからテスト</span>

<span class="PreProc">def</span> <span class="Identifier">str2num_array</span>(str)
  ret_array = <span class="Type">Array</span>.new(<span class="Constant">10</span>, <span class="Constant">0</span>)
  str.each_char <span class="Statement">do</span> |<span class="Identifier">c</span>|
    ret_array[c.to_i] += <span class="Constant">1</span>
  <span class="Statement">end</span>
  ret_array
<span class="PreProc">end</span>

<span class="PreProc">def</span> <span class="Identifier">test</span>(str)
  machilist = <span class="Type">MachiList</span>.new
  machi = <span class="Type">Machi</span>.new
  machilist.check(str2num_array(str), machi)
  machilist.print_list
<span class="PreProc">end</span>

haipai_list = [ <span class="Special">&quot;</span><span class="Constant">1112224588899</span><span class="Special">&quot;</span>,
                <span class="Special">&quot;</span><span class="Constant">1122335556799</span><span class="Special">&quot;</span>,
                <span class="Special">&quot;</span><span class="Constant">1112223335559</span><span class="Special">&quot;</span>,
                <span class="Special">&quot;</span><span class="Constant">1223344888999</span><span class="Special">&quot;</span>,
                <span class="Special">&quot;</span><span class="Constant">1112345678999</span><span class="Special">&quot;</span> ]

haipai_list.each <span class="Statement">do</span> |<span class="Identifier">str</span>|
  p str
  test(str)
  puts <span class="Special">&quot;</span><span class="Constant">------------------------------</span><span class="Special">&quot;</span>
<span class="Statement">end</span>
</pre>
<p>実行結果</p>
<pre>&quot;1112224588899&quot;
(111)(222)(888)(99)[45]
------------------------------
&quot;1122335556799&quot;
(555)(123)(123)(99)[67]
(123)(123)(567)(55)[99]
(123)(123)(567)(99)[55]
------------------------------
&quot;1112223335559&quot;
(111)(222)(333)(555)[9]
(555)(123)(123)(123)[9]
------------------------------
&quot;1223344888999&quot;
(888)(999)(123)(234)[4]
(888)(999)(123)(44)[23]
(888)(999)(234)(234)[1]
------------------------------
&quot;1112345678999&quot;
(111)(999)(234)(567)[8]
(111)(999)(234)(678)[5]
(111)(999)(345)(678)[2]
(111)(234)(567)(99)[89]
(111)(234)(789)(99)[56]
(111)(456)(789)(99)[23]
(999)(123)(456)(11)[78]
(999)(123)(678)(11)[45]
(999)(345)(678)(11)[12]
(123)(456)(789)(11)[99]
(123)(456)(789)(99)[11]
------------------------------
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41CGDEMgyoL._SL160_.jpg" alt="プログラミング言語 Ruby" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語 Ruby</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4873113946/serendip7822-22/ref=nosim/" title="プログラミング言語 Ruby" target="_blank">amazlet</a> at 10.04.06</div>
</div>
<div class="amazlet-detail">まつもと ゆきひろ David Flanagan <br />オライリージャパン <br />売り上げランキング: 91254</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4673/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python の if __name__ == &#8216;__main__&#8217;: を Perl, Ruby, PHP で行う</title>
		<link>http://www.serendip.ws/archives/4360</link>
		<comments>http://www.serendip.ws/archives/4360#comments</comments>
		<pubDate>Fri, 19 Feb 2010 13:37:02 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4360</guid>
		<description><![CDATA[以下の Python コードの if 文の本体は、直接スクリプトとして呼び出された場合のみ実行され、ライブラリとして読み込まれた場合は実行されない。 if __name__ == '__main__': # do som [...]]]></description>
			<content:encoded><![CDATA[<p>以下の Python コードの <code>if</code> 文の本体は、直接スクリプトとして呼び出された場合のみ実行され、ライブラリとして読み込まれた場合は実行されない。</p>
<pre><span class="Statement">if</span> __name__ == '<span class="Constant">__main__</span>':
    <span class="Comment"># do something</span>
</pre>
<p>同様のコードを Perl, Ruby, PHP で書く方法を調べてみた。</p>
<h3>Perl の場合</h3>
<pre><span class="Statement">if</span> (<span class="Special">$0</span> <span class="Statement">eq</span> __FILE__) {
    <span class="Comment"># do something</span>
}
</pre>
<h3>Ruby の場合</h3>
<pre><span class="Statement">if</span> <span class="Special">$0</span> == <span class="Constant">__FILE__</span>
  <span class="Comment"># do something</span>
<span class="Statement">end</span>
</pre>
<h3>PHP の場合</h3>
<pre><span class="Statement">if</span> <span class="Special">(</span><span class="Identifier">basename</span><span class="Special">(</span><span class="Constant">__FILE__</span><span class="Special">)</span> <span class="Statement">==</span> <span class="Identifier">basename</span><span class="Special">(</span><span class="Statement">$</span><span class="Identifier">_SERVER</span><span class="Special">[</span>'<span class="Constant">PHP_SELF</span>'<span class="Special">]))</span> <span class="Special">{</span>
    <span class="Comment">// do something</span>
<span class="Special">}</span>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4360/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>最短経路探索プログラムの試験問題を解いてみた</title>
		<link>http://www.serendip.ws/archives/4133</link>
		<comments>http://www.serendip.ws/archives/4133#comments</comments>
		<pubDate>Thu, 14 Jan 2010 06:22:36 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=4133</guid>
		<description><![CDATA[以前読んだブログに、とある求人の際のプログラミングの実技試験についての記事（人生を書き換える者すらいた。: 人材獲得作戦・３）があった。 その時は問題内容については、『ちょっとしたパズル』としか書かれていなか]]></description>
			<content:encoded><![CDATA[<p>以前読んだブログに、とある求人の際のプログラミングの実技試験についての記事（<a href="http://okajima.air-nifty.com/b/2009/12/post-f94c.html" class="out">人生を書き換える者すらいた。: 人材獲得作戦・３</a>）があった。<br />
その時は問題内容については、『ちょっとしたパズル』としか書かれていなかったが、記事の続編が投稿されたようで、試験問題の内容が公開されていた。</p>
<p><a href="http://okajima.air-nifty.com/b/2010/01/post-abc6.html" class="out">人生を書き換える者すらいた。: 人材獲得作戦・４　試験問題ほか</a></p>
<p>試験問題は迷路の最短経路探索プログラム。<br />
最初、アルゴリズムとかがわからないので力技で解いてみたが、迷路内の空白が大きくなると処理が終らないのでアルゴリズムを調べてから再度実装してみた。<br />
使ったアルゴリズムはダイクストラ法、こちらのサイト &quot;<a href="http://www.deqnotes.net/acmicpc/dijkstra/" class="out">ダイクストラ法（最短経路問題）</a>&quot; を参考にした。</p>
<p>あと、Gauche で解こうとしてみたが、行き詰まってしまったので Ruby で解いた。</p>
<p>追記：<ins date="2010-01-16T22:03:52+0900"><a href="/archives/4143">Gauche 版</a>も解けた。</ins></p>
<pre><span class="Comment">### ノードクラス</span>
<span class="PreProc">class</span> <span class="Type">Node</span>
  <span class="PreProc">def</span> <span class="Identifier">initialize</span>(val, edges_to)
    <span class="Identifier">@val</span> = val        <span class="Comment"># マップ上での文字</span>
    <span class="Identifier">@edges_to</span> = edges_to    <span class="Comment"># 各エッジの接続先のノード番号</span>
    <span class="Identifier">@edges_cost</span> = []  <span class="Comment"># 各エッジのコスト</span>
    <span class="Identifier">@done</span> = <span class="Constant">false</span>     <span class="Comment"># 確定ノードか否か</span>
    <span class="Identifier">@cost</span> = -<span class="Constant">1</span>        <span class="Comment"># このノードへの現時点で判明している最小コスト</span>
  <span class="PreProc">end</span>
  <span class="Statement">attr_accessor</span> <span class="Constant">:val</span>, <span class="Constant">:edges_to</span>, <span class="Constant">:edges_cost</span>, <span class="Constant">:done</span>, <span class="Constant">:cost</span>
<span class="PreProc">end</span>

<span class="Comment">### マップ文字列を2次元配列に変換する</span>
<span class="PreProc">def</span> <span class="Identifier">map2array</span>(s_map)
  rt = []
  s_map.each{|<span class="Identifier">line</span>|
    rt.push(line.chomp.split(<span class="Special">//</span>))
  }
  <span class="Statement">return</span> rt
<span class="PreProc">end</span>

<span class="Comment">### 接続先を探す</span>
<span class="PreProc">def</span> <span class="Identifier">find_movable</span>(x, y, a_map)
  rt = []
  [[x,y-<span class="Constant">1</span>], [x,y+<span class="Constant">1</span>], [x-<span class="Constant">1</span>,y], [x+<span class="Constant">1</span>,y]].each{|<span class="Identifier">v</span>|
    <span class="Statement">if</span> a_map[v[<span class="Constant">1</span>]][v[<span class="Constant">0</span>]].match(<span class="Special">/</span><span class="Special">(?:</span><span class="Special">\s</span><span class="Special">|</span><span class="Constant">S</span><span class="Special">|</span><span class="Constant">G</span><span class="Special">)</span><span class="Special">/</span>) <span class="Statement">then</span>
      rt.push(v)
    <span class="Statement">end</span>
  }
  <span class="Statement">return</span> rt
<span class="PreProc">end</span>

<span class="Comment">### マップ配列(2次元)からノードリスト(配列)を作る</span>
<span class="PreProc">def</span> <span class="Identifier">array2nodelist</span>(a_map)
  rt = []
  a_map.each_with_index{|<span class="Identifier">y</span>, <span class="Identifier">i</span>|
    _y = []
    y.each_with_index{|<span class="Identifier">x</span>, <span class="Identifier">j</span>|
      <span class="Statement">if</span> x == <span class="Special">'</span><span class="Constant"> </span><span class="Special">'</span> || x == <span class="Special">'</span><span class="Constant">S</span><span class="Special">'</span> || x == <span class="Special">'</span><span class="Constant">G</span><span class="Special">'</span> <span class="Statement">then</span>
        node = <span class="Type">Node</span>.new(x, find_movable(j,i,a_map))
        <span class="Statement">if</span> x == <span class="Special">'</span><span class="Constant">S</span><span class="Special">'</span> <span class="Statement">then</span> <span class="Comment"># スタートノードのコストを 0 にする</span>
          node.cost = <span class="Constant">0</span>
        <span class="Statement">end</span>
        _y.push(node)
      <span class="Statement">else</span>
        _y.push(<span class="Constant">nil</span>)
      <span class="Statement">end</span>
    }
    rt.push(_y)
  }
  <span class="Statement">return</span> rt
<span class="PreProc">end</span>

<span class="Comment">### ノードの座標を得る</span>
<span class="PreProc">def</span> <span class="Identifier">get_pos</span>(nodes, str)
  nodes.each_with_index{|<span class="Identifier">y</span>,<span class="Identifier">i</span>|
    y.each_with_index{|<span class="Identifier">x</span>,<span class="Identifier">j</span>|
      <span class="Statement">if</span> x &amp;&amp; x.val == str <span class="Statement">then</span>
        <span class="Statement">return</span> [j,i]
      <span class="Statement">end</span>
    }
  }
  <span class="Statement">return</span> <span class="Constant">nil</span>
<span class="PreProc">end</span>

<span class="Comment">### アルゴリズム実行</span>
<span class="PreProc">def</span> <span class="Identifier">search</span>(nodes)

  <span class="Comment"># 確定ノードを探す</span>
  <span class="Statement">while</span> <span class="Constant">true</span>
    done_node = <span class="Constant">nil</span>
    nodes.each_with_index{|<span class="Identifier">y</span>,<span class="Identifier">i</span>|
      y.each_with_index{|<span class="Identifier">x</span>,<span class="Identifier">j</span>|
        <span class="Statement">if</span> x <span class="Statement">then</span>
          <span class="Statement">if</span> x.done || x.cost &lt; <span class="Constant">0</span> <span class="Statement">then</span>
            <span class="Statement">next</span>
          <span class="Statement">end</span>
          <span class="Statement">if</span> done_node == <span class="Constant">nil</span> || x.cost &lt; done_node.cost <span class="Statement">then</span>
            done_node = x
            <span class="Statement">break</span>
          <span class="Statement">end</span>
        <span class="Statement">end</span>
      }
      <span class="Statement">if</span> done_node <span class="Statement">then</span>
        <span class="Statement">break</span>
      <span class="Statement">end</span>
    }
    <span class="Comment"># 確定ノードがなくなれば終了</span>
    <span class="Statement">if</span> done_node == <span class="Constant">nil</span>
      <span class="Statement">break</span>
    <span class="Statement">end</span>

    <span class="Comment"># 確定フラグを立てる</span>
    done_node.done = <span class="Constant">true</span>
    <span class="Comment"># 接続先のノードの情報を更新する</span>
    done_node.edges_to.each_with_index{|<span class="Identifier">v</span>, <span class="Identifier">i</span>|
      cost = done_node.cost + <span class="Constant">1</span> <span class="Comment"># 各エッジのコストは 1</span>
      nodes_to = nodes[v[<span class="Constant">1</span>]][v[<span class="Constant">0</span>]]
      <span class="Statement">if</span> nodes_to.cost &lt; <span class="Constant">0</span> || cost &lt; nodes_to.cost <span class="Statement">then</span>
        nodes[v[<span class="Constant">1</span>]][v[<span class="Constant">0</span>]].cost = cost
      <span class="Statement">end</span>
    }
  <span class="Statement">end</span>

  <span class="Statement">return</span> nodes
<span class="PreProc">end</span>

<span class="Comment">### 再帰的に最小コストの接続元ノードをたどり、valに'$'を代入していく</span>
<span class="PreProc">def</span> <span class="Identifier">get_from_node</span>(node, nodes)
  <span class="Statement">if</span> node <span class="Statement">then</span>
    node.edges_to.each{|<span class="Identifier">e</span>|
      n = nodes[e[<span class="Constant">1</span>]][e[<span class="Constant">0</span>]]
      <span class="Statement">if</span> n.cost == node.cost - <span class="Constant">1</span> &amp;&amp; n.val != <span class="Special">'</span><span class="Constant">S</span><span class="Special">'</span> <span class="Statement">then</span>
        n.val = <span class="Special">'</span><span class="Constant">$</span><span class="Special">'</span>
        <span class="Statement">return</span> get_from_node(n, nodes)
      <span class="Statement">end</span>
    }
  <span class="Statement">end</span>
  <span class="Statement">return</span> <span class="Constant">nil</span>
<span class="PreProc">end</span>

<span class="Comment">### マップ文字列を受け取り、最短経路を探索して、結果のマップを印字する</span>
<span class="PreProc">def</span> <span class="Identifier">maiz</span>(map_str)
  a_map = map2array(map_str)
  nodes = array2nodelist(a_map)
  result_nodes = search(nodes)
  goal_pos = get_pos(result_nodes, <span class="Special">'</span><span class="Constant">G</span><span class="Special">'</span>)
  goal = result_nodes[goal_pos[<span class="Constant">1</span>]][goal_pos[<span class="Constant">0</span>]]
  get_from_node(goal, result_nodes)
  <span class="Comment"># 結果のマップを印字する</span>
  result_nodes.each_with_index{|<span class="Identifier">y</span>,<span class="Identifier">i</span>|
    y.each_with_index{|<span class="Identifier">x</span>,<span class="Identifier">j</span>|
      <span class="Statement">if</span> x <span class="Statement">then</span>
        print x.val
      <span class="Statement">else</span>
        print <span class="Special">'</span><span class="Constant">*</span><span class="Special">'</span>
      <span class="Statement">end</span>
    }
    print <span class="Special">&quot;</span><span class="Special">\n</span><span class="Special">&quot;</span>
  }
<span class="PreProc">end</span>

<span class="Comment">### 実行結果</span>

<span class="Comment"># マップ文字列</span>
<span class="Identifier">$MAP1</span> =&lt;&lt;<span class="Special">EOD</span>
<span class="Constant">**********</span>
<span class="Constant">*S*      *</span>
<span class="Constant">* * ** * *</span>
<span class="Constant">*   ** * *</span>
<span class="Constant">***  *  G*</span>
<span class="Constant">**********</span>
<span class="Special">EOD</span>
<span class="Identifier">$MAP2</span> =&lt;&lt;<span class="Special">EOD</span>
<span class="Constant">**************************</span>
<span class="Constant">*S* *                    *</span>
<span class="Constant">* * *  *  *************  *</span>
<span class="Constant">* *   *    ************  *</span>
<span class="Constant">*    *                   *</span>
<span class="Constant">************** ***********</span>
<span class="Constant">*                        *</span>
<span class="Constant">** ***********************</span>
<span class="Constant">*      *              G  *</span>
<span class="Constant">*  *      *********** *  *</span>
<span class="Constant">*    *        ******* *  *</span>
<span class="Constant">*       *                *</span>
<span class="Constant">**************************</span>
<span class="Special">EOD</span>
<span class="Identifier">$MAP3</span> =&lt;&lt;<span class="Special">EOD</span>
<span class="Constant">**************************</span>
<span class="Constant">*S                       *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                     G  *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">*                        *</span>
<span class="Constant">**************************</span>
<span class="Special">EOD</span>

maiz(<span class="Identifier">$MAP1</span>)
puts <span class="Special">&quot;&quot;</span>
maiz(<span class="Identifier">$MAP2</span>)
puts <span class="Special">&quot;&quot;</span>
maiz(<span class="Identifier">$MAP3</span>)
</pre>
<p>実行結果</p>
<pre>$ ./maze.rb
**********
*S*$$$$$$*
*$*$** *$*
*$$$** *$*
***  *  G*
**********

**************************
*S* * $$$$               *
*$* *$$* $*************  *
*$* $$*  $$************  *
*$$$$*    $$$$$          *
**************$***********
* $$$$$$$$$$$$$          *
**$***********************
* $$$$$* $$$$$$$$$$$$$G  *
*  *  $$$$*********** *  *
*    *        ******* *  *
*       *                *
**************************

**************************
*S$$$$$$$$$$$$$$$$$$$$$  *
*                     $  *
*                     $  *
*                     $  *
*                     $  *
*                     $  *
*                     $  *
*                     G  *
*                        *
*                        *
*                        *
**************************
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:9pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41CGDEMgyoL._SL160_.jpg" alt="プログラミング言語 Ruby" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語 Ruby</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4873113946/serendip7822-22/ref=nosim/" title="プログラミング言語 Ruby" target="_blank">amazlet</a> at 10.01.14</div>
</div>
<div class="amazlet-detail">まつもと ゆきひろ David Flanagan <br />オライリージャパン <br />売り上げランキング: 24906</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/4133/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>シュワルツ（シュウォーツ）変換 (Schwartzian Transform)</title>
		<link>http://www.serendip.ws/archives/2815</link>
		<comments>http://www.serendip.ws/archives/2815#comments</comments>
		<pubDate>Sun, 09 Aug 2009 07:02:39 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=2815</guid>
		<description><![CDATA[コレクションを操作する際に、各要素に変換を行った要素に基づいて操作を行うが、欲しい結果は変換を行った要素のコレクションではなく元の要素のコレクションである場合に利用する。 文字列の配列を大文字・小文字を無]]></description>
			<content:encoded><![CDATA[<p>コレクションを操作する際に、各要素に変換を行った要素に基づいて操作を行うが、欲しい結果は変換を行った要素のコレクションではなく元の要素のコレクションである場合に利用する。</p>
<p>文字列の配列を大文字・小文字を無視してソートする場合を考える。</p>
<pre><span class="Comment"># 文字列の配列</span>
ary = [<span class="Special">&quot;</span><span class="Constant">foo</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">Bar</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">baz</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">HOGE</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">FUGA</span><span class="Special">&quot;</span>]

<span class="Comment"># そのままソートすると</span>
p ary.sort <span class="Comment">#=&gt; [&quot;Bar&quot;, &quot;FUGA&quot;, &quot;HOGE&quot;, &quot;baz&quot;, &quot;foo&quot;]</span>

<span class="Comment"># 大文字・小文字を無視してソートする（ブロックが繰り返される度に upcase が実行される）</span>
p ary.sort {|<span class="Identifier">x</span>,<span class="Identifier">y</span>| x.upcase &lt;=&gt; y.upcase } <span class="Comment">#=&gt; [&quot;Bar&quot;, &quot;baz&quot;, &quot;foo&quot;, &quot;FUGA&quot;, &quot;HOGE&quot;]</span>

<span class="Comment"># 大文字・小文字を無視してソートする（upcase した要素と元の要素を含む配列を作り sort した後、元の要素のみを取り出す )</span>
p ary.collect {|<span class="Identifier">x</span>| [x.upcase, x] }.sort.collect {|<span class="Identifier">y</span>| y[-<span class="Constant">1</span>] } <span class="Comment">#=&gt; [&quot;Bar&quot;, &quot;baz&quot;, &quot;foo&quot;, &quot;FUGA&quot;, &quot;HOGE&quot;]</span>

<span class="Comment"># ruby に備わっている sort_by メソッドでシュワルツ変換を利用する。</span>
p ary.sort_by {|<span class="Identifier">x</span>| x.upcase } <span class="Comment">#=&gt; [&quot;Bar&quot;, &quot;baz&quot;, &quot;foo&quot;, &quot;FUGA&quot;, &quot;HOGE&quot;]</span>
</pre>
<p><code>collect</code> を使って一時配列を作ってソートする場合の一時配列を見てみる。</p>
<pre>p ary.collect {|<span class="Identifier">x</span>| [x.upcase, x] }
<span class="Comment">#=&gt; [[&quot;FOO&quot;, &quot;foo&quot;], [&quot;BAR&quot;, &quot;Bar&quot;], [&quot;BAZ&quot;, &quot;baz&quot;], [&quot;HOGE&quot;, &quot;HOGE&quot;], [&quot;FUGA&quot;, &quot;FUGA&quot;]]</span>
p ary.collect {|<span class="Identifier">x</span>| [x.upcase, x] }.sort
<span class="Comment">#=&gt; [[&quot;BAR&quot;, &quot;Bar&quot;], [&quot;BAZ&quot;, &quot;baz&quot;], [&quot;FOO&quot;, &quot;foo&quot;], [&quot;FUGA&quot;, &quot;FUGA&quot;], [&quot;HOGE&quot;, &quot;HOGE&quot;]]</span>
p ary.collect {|<span class="Identifier">x</span>| [x.upcase, x] }.sort.collect {|<span class="Identifier">y</span>| y[-<span class="Constant">1</span>] }
<span class="Comment">#=&gt; [&quot;Bar&quot;, &quot;baz&quot;, &quot;foo&quot;, &quot;FUGA&quot;, &quot;HOGE&quot;]</span>
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:7pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4822234312/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41y65zf27LL._SL160_.jpg" alt="まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-top:10px;margin-left:15px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4822234312/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4822234312/serendip7822-22/ref=nosim/" title="まつもとゆきひろ コードの世界‾スーパー・プログラマになる14の思考法" target="_blank">amazlet</a> at 09.08.09</div>
</div>
<div class="amazlet-detail">まつもとゆきひろ <br />日経BP出版センター <br />売り上げランキング: 6604</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4822234312/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/2815/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby ひらがな・カタカナ変換をする</title>
		<link>http://www.serendip.ws/archives/2312</link>
		<comments>http://www.serendip.ws/archives/2312#comments</comments>
		<pubDate>Fri, 19 Jun 2009 11:04:38 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=2312</guid>
		<description><![CDATA[最初、tr で変換すると文字化けしてしまった。tr で日本語を使うには require &#34;jcode&#34; する必要があるらしい。 #!/usr/bin/env ruby -w # -*- coding: [...]]]></description>
			<content:encoded><![CDATA[<p>最初、<code>tr</code> で変換すると文字化けしてしまった。<code>tr</code> で日本語を使うには <code>require &quot;jcode&quot;</code> する必要があるらしい。</p>
<pre><span class="PreProc">#!/usr/bin/env ruby -w</span>
<span class="Comment"># -*- coding: utf-8 -*-</span>

<span class="Identifier">$KCODE</span> = <span class="Special">&quot;</span><span class="Constant">u</span><span class="Special">&quot;</span>
<span class="PreProc">require</span> <span class="Special">&quot;</span><span class="Constant">jcode</span><span class="Special">&quot;</span> <span class="Comment"># String クラスの tr メソッドで日本語を使用可能にする。</span>

<span class="Comment">### ひらがな・カタカナ変換</span>
<span class="PreProc">def</span> <span class="Identifier">translator</span>(from, to)
    <span class="Statement">lambda</span> {|<span class="Identifier">str</span>| str.tr(from, to) }
<span class="PreProc">end</span>

upto = translator(<span class="Special">&quot;</span><span class="Constant">a-z</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">A-Z</span><span class="Special">&quot;</span>)
downto = translator(<span class="Special">&quot;</span><span class="Constant">A-Z</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">a-z</span><span class="Special">&quot;</span>)
hira2kata = translator(<span class="Special">&quot;</span><span class="Constant">ぁ-ん</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">ァ-ン</span><span class="Special">&quot;</span>)
kata2hira = translator(<span class="Special">&quot;</span><span class="Constant">ァ-ン</span><span class="Special">&quot;</span>, <span class="Special">&quot;</span><span class="Constant">ぁ-ん</span><span class="Special">&quot;</span>)

puts upto.call(<span class="Special">&quot;</span><span class="Constant">hello WORLD</span><span class="Special">&quot;</span>)   <span class="Comment"># =&gt; HELLO WORLD</span>
puts downto.call(<span class="Special">&quot;</span><span class="Constant">hello WROLD</span><span class="Special">&quot;</span>) <span class="Comment"># =&gt; hello wrold</span>
puts hira2kata.call(<span class="Special">&quot;</span><span class="Constant">こんにちはワールド</span><span class="Special">&quot;</span>) <span class="Comment"># =&gt; コンニチハワールド</span>
puts kata2hira.call(<span class="Special">&quot;</span><span class="Constant">こんにちはワールド</span><span class="Special">&quot;</span>) <span class="Comment"># =&gt; こんにちはわーるど</span>
</pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:7pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41CGDEMgyoL._SL160_.jpg" alt="プログラミング言語 Ruby" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:10px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">プログラミング言語 Ruby</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4873113946/serendip7822-22/ref=nosim/" title="プログラミング言語 Ruby" target="_blank">amazlet</a> at 09.06.19</div>
</div>
<div class="amazlet-detail">まつもと ゆきひろ David Flanagan <br />オライリージャパン <br />売り上げランキング: 66949</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4873113946/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/2312/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>csvファイルのカラムの要素による集計をするRubyスクリプト</title>
		<link>http://www.serendip.ws/archives/485</link>
		<comments>http://www.serendip.ws/archives/485#comments</comments>
		<pubDate>Tue, 25 Nov 2008 06:11:52 +0000</pubDate>
		<dc:creator>iNo</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.serendip.ws/?p=485</guid>
		<description><![CDATA[住所録から市（区）毎の合計数を集計するRubyスクリプトのメモ。 csvファイルは、文字コードが utf-8 、改行コードが lf を想定している。 $KCODE = &#34;UTF8&#34; require &#038; [...]]]></description>
			<content:encoded><![CDATA[<p>住所録から市（区）毎の合計数を集計するRubyスクリプトのメモ。<br />
csvファイルは、文字コードが utf-8 、改行コードが lf を想定している。</p>
<pre><span class="Identifier">$KCODE</span> = <span class="Special">&quot;</span><span class="Constant">UTF8</span><span class="Special">&quot;</span>
<span class="PreProc">require</span> <span class="Special">&quot;</span><span class="Constant">csv</span><span class="Special">&quot;</span>

areas = <span class="Type">Hash</span>.new
total = <span class="Constant">0</span>
colnum = <span class="Constant">4</span>

<span class="Type">CSV</span>.open(<span class="Identifier">ARGV</span>[<span class="Constant">0</span>], <span class="Special">&quot;</span><span class="Constant">r</span><span class="Special">&quot;</span>) {|<span class="Identifier">row</span>|
    address = row[colnum]
    city_name = address.slice(<span class="Special">/</span><span class="Special">[^</span><span class="Constant">市区</span><span class="Special">]</span><span class="Special">*</span><span class="Special">(</span><span class="Constant">市</span><span class="Special">|</span><span class="Constant">区</span><span class="Special">)</span><span class="Special">/</span>)
    <span class="Statement">unless</span> city_name <span class="Statement">then</span>
        <span class="Statement">next</span>
    <span class="Statement">end</span>

    <span class="Statement">if</span> areas.key?(city_name) <span class="Statement">then</span>
        new_count = areas[city_name].to_i + <span class="Constant">1</span>
        areas.store(city_name, new_count)
    <span class="Statement">else</span>
        areas.store(city_name, <span class="Constant">1</span>)
    <span class="Statement">end</span>
    total = total + <span class="Constant">1</span>
}

areas.each {|<span class="Identifier">key</span>,<span class="Identifier">val</span>|
    puts <span class="Special">&quot;</span><span class="Special">#{</span>key<span class="Special">}</span><span class="Constant">, </span><span class="Special">#{</span>val<span class="Special">}</span><span class="Special">&quot;</span>
}
puts <span class="Special">&quot;</span><span class="Constant">合計 </span><span class="Special">#{</span>total<span class="Special">}</span><span class="Special">&quot;</span>
</pre>
<p>csvデータの中身は以下のようになっている。<br />
市（または区）別に集計をしていく。</p>
<pre><code>&quot;連番&quot;,&quot;法人名&quot;,&quot;法人電話番号&quot;,&quot;法人郵便番号&quot;,&quot;法人住所&quot;
&quot;1&quot;,&quot;安威小学校&quot;,&quot;072-xxx-xxxx&quot;,&quot;567-xxxx&quot;,&quot;大阪府茨木市安威x-xx-xx&quot;
&quot;5&quot;,&quot;茨木市立小学校東小学校&quot;,&quot;072-xxx-xxxx&quot;,&quot;567-xxxx&quot;,&quot;大阪府茨木市鮎川x-x-xx&quot;
&quot;9&quot;,&quot;茨木市立小学校清溪小学校&quot;,&quot;072-xxx-xxxx&quot;,&quot;568-xxxx&quot;,&quot;大阪府茨木市泉原xxx&quot;
&quot;16&quot;,&quot;茨木市立小学校茨木小学校&quot;,&quot;072-xxx-xxxx&quot;,&quot;567-xxxx&quot;,&quot;大阪府茨木市片桐町x-xx&quot;
...
...
...
&quot;116&quot;,&quot;金蘭千里中学校&quot;,&quot;06-xxxx-xxxx&quot;,&quot;565-xxxx&quot;,&quot;大阪府吹田市藤白台x-xx-x&quot;
&quot;117&quot;,&quot;弘済中学校&quot;,&quot;06-xxxx-xxxx&quot;,&quot;565-xxxx&quot;,&quot;大阪府吹田市古江台x-x-x&quot;
&quot;118&quot;,&quot;吹田市立中学校豊津西中学校&quot;,&quot;06-xxxx-xxxx&quot;,&quot;564-xxxx&quot;,&quot;大阪府吹田市豊津町x-x&quot;
</code></pre>
<p>必要に応じてcsvファイルの文字コード・改行コードを変更する。<br />
実行結果。</p>
<pre><code>$ cat school_data_osaka.csv | nkf -dw &gt;hoge
$ ./count.rb hoge
大阪府吹田市, 57
大阪府茨木市, 47
大阪府大阪市, 456
合計 560
</code></pre>
<div class="amazlet-box" style="margin-bottom:0px;font-size:7pt;">
<div class="amazlet-image" style="float:left;"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797340045/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank"><img src="http://ecx.images-amazon.com/images/I/41w6qA2x-zL._SL160_.jpg" alt="Rubyレシピブック 第2版 268の技" style="border: none;" /></a></div>
<div class="amazlet-info" style="float:left;margin-left:15px;margin-top:15px;line-height:120%">
<div class="amazlet-name" style="margin-bottom:10px;line-height:120%"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797340045/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Rubyレシピブック 第2版 268の技</a>
<div class="amazlet-powered-date" style="font-size:7pt;margin-top:5px;font-family:verdana;line-height:120%">posted with <a href="http://www.amazlet.com/browse/ASIN/4797340045/serendip7822-22/ref=nosim/" title="Rubyレシピブック 第2版 268の技" target="_blank">amazlet</a> at 08.11.25</div>
</div>
<div class="amazlet-detail">青木 峰郎 後藤 裕蔵 高橋 征義 <br />ソフトバンク クリエイティブ <br />売り上げランキング: 63136</div>
<div class="amazlet-link" style="margin-top: 5px"><a href="http://www.amazon.co.jp/exec/obidos/ASIN/4797340045/serendip7822-22/ref=nosim/" name="amazletlink" target="_blank">Amazon.co.jp で詳細を見る</a></div>
</div>
<div class="amazlet-footer" style="clear: left"></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.serendip.ws/archives/485/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

