blog/content/post/2008/11/08/2008-11-08-00001063.md

125 lines
11 KiB
Markdown

---
title: isbn13→isbn10を求めるlispスクリプト
author: kazu634
date: 2008-11-08
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4367;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- gauche
- Lisp
---
<div class="section">
<p>
これで完結編だよ。
</p>
<blockquote>
<ul>
<li>
「isbn」に関連する最近のエントリ <ul>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20081107/1226068936" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20081107/1226068936', ' isbn13からisbn10を求めるlispスクリプト &#8211; 武蔵の日記');" target="_blank"> isbn13からisbn10を求めるlispスクリプト &#8211; 武蔵の日記</a>
</li>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20081026/1224993758" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20081026/1224993758', ' isbn13からisbn10を求めるスクリプトを作る(途中) &#8211; 武蔵の日記');" target="_blank"> isbn13からisbn10を求めるスクリプトを作る(途中) &#8211; 武蔵の日記</a>
</li>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20080702/1215008700" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080702/1215008700', ' isbn13 &#8211;&#038;gt; isbn10 &#8211; 武蔵の日記');" target="_blank"> isbn13 &#8211;> isbn10 &#8211; 武蔵の日記</a>
</li>
<li>
<a href="http://d.hatena.ne.jp/sirocco634/20080209/4797336803" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080209/4797336803', '武蔵の日記');" target="_blank">武蔵の日記</a>
</li>
</ul>
</li>
</ul>
</blockquote>
<p>
<a name="seemore"></a>
</p>
<h4>
ソース
</h4>
<pre class="syntax-highlight">
<span class="synComment">;; 引数が13桁の数字かどうかを判断する。</span>
<span class="synComment">;; 13桁の場合はisbn10を求める</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>isbn arg<span class="synSpecial">)</span>
<span class="synComment">;; もし13桁の数字であれば</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span>rxmatch #/\d\d\d\d\d\d\d\d\d\d\d\d\d/ <span class="synSpecial">(</span>number-&#62;string arg<span class="synSpecial">))</span>
<span class="synSpecial">(</span>begin
<span class="synComment">;; split-listの返り値のリストを表示する。</span>
<span class="synComment">;; そのリストから最後の1桁を求め、最後に表示する。</span>
<span class="synSpecial">(</span>for-each <span class="synSpecial">(</span><span class="synStatement">lambda</span> <span class="synSpecial">(</span>x<span class="synSpecial">)</span> <span class="synSpecial">(</span>display x<span class="synSpecial">))</span> <span class="synSpecial">(</span>split-list <span class="synSpecial">(</span>number-&#62;list arg<span class="synSpecial">)))</span>
<span class="synSpecial">(</span>display <span class="synSpecial">(</span>chkdigit arg<span class="synSpecial">)))</span>
<span class="synComment">;; 13桁の数字でなければ</span>
<span class="synSpecial">(</span><span class="synStatement">print</span> <span class="synConstant">&#34;Not match&#34;</span><span class="synSpecial">)))</span>
<span class="synComment">;; 数字からリストにする。後ろにShiroさんの別解あり</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number-&#62;list <span class="synStatement">number</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span><span class="synStatement">loop</span> lis<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">cond</span> [<span class="synSpecial">(</span><span class="synStatement">null</span>? lis<span class="synSpecial">)</span> <span class="synSpecial">'()</span>]
[else <span class="synSpecial">(</span><span class="synStatement">cons</span> <span class="synSpecial">(</span>digit-&#62;integer <span class="synSpecial">(</span><span class="synStatement">car</span> lis<span class="synSpecial">))</span> <span class="synSpecial">(</span><span class="synStatement">loop</span> <span class="synSpecial">(</span><span class="synStatement">cdr</span> lis<span class="synSpecial">)))</span>]<span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>num_list <span class="synSpecial">(</span>string-&#62;list <span class="synSpecial">(</span>number-&#62;string <span class="synStatement">number</span><span class="synSpecial">))))</span>
<span class="synSpecial">(</span><span class="synStatement">loop</span> num_list<span class="synSpecial">)))</span>
<span class="synComment">;; isbn13から必要な部分だけを抜き出してリストにする。</span>
<span class="synComment">;; これで10桁のうち9桁の数字が決まる。</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>split-list <span class="synStatement">list</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span>drop-right <span class="synSpecial">(</span>take-right <span class="synStatement">list</span> <span class="synConstant">10</span><span class="synSpecial">)</span> <span class="synConstant">1</span><span class="synSpecial">))</span>
<span class="synComment">;; チェックディジットを求める関数。残りの1桁がこれで判明する。</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>chkdigit num<span class="synSpecial">)</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>proc <span class="synStatement">list</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">cond</span> [<span class="synSpecial">(</span><span class="synStatement">null</span>? <span class="synStatement">list</span><span class="synSpecial">)</span> <span class="synConstant"></span>]
[else <span class="synSpecial">(</span><span class="synStatement">+</span> <span class="synSpecial">(</span><span class="synStatement">*</span> <span class="synSpecial">(</span><span class="synStatement">car</span> <span class="synStatement">list</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">+</span> <span class="synConstant">1</span> <span class="synSpecial">(</span><span class="synStatement">length</span> <span class="synStatement">list</span><span class="synSpecial">)))</span> <span class="synSpecial">(</span>proc <span class="synSpecial">(</span><span class="synStatement">cdr</span> <span class="synStatement">list</span><span class="synSpecial">)))</span>]<span class="synSpecial">))</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synSpecial">((</span>result <span class="synSpecial">(</span><span class="synStatement">-</span> <span class="synConstant">11</span> <span class="synSpecial">(</span>modulo <span class="synSpecial">(</span>proc <span class="synSpecial">(</span>split-list <span class="synSpecial">(</span>number-&#62;list num<span class="synSpecial">)))</span> <span class="synConstant">11</span><span class="synSpecial">))))</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">=</span> result <span class="synConstant">10</span><span class="synSpecial">)</span>
<span class="synSpecial">'</span><span class="synIdentifier">X</span>
result<span class="synSpecial">)))</span>
<span class="synComment">;; number-&#62;list別解 - (1)</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number-&#62;list n<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">map</span> digit-&#62;integer
<span class="synSpecial">(</span>string-&#62;list <span class="synSpecial">(</span>number-&#62;string n<span class="synSpecial">))))</span>
<span class="synComment">;; number-&#62;list別解 - (2)</span>
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number-&#62;list n<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">let</span> <span class="synStatement">loop</span> <span class="synSpecial">((</span>n n<span class="synSpecial">)</span> <span class="synSpecial">(</span>r <span class="synSpecial">'()))</span>
<span class="synSpecial">(</span><span class="synStatement">if</span> <span class="synSpecial">(</span><span class="synStatement">&#60;</span> n <span class="synConstant">10</span><span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">cons</span> n r<span class="synSpecial">)</span>
<span class="synSpecial">(</span><span class="synStatement">loop</span> <span class="synSpecial">(</span>quotient n <span class="synConstant">10</span><span class="synSpecial">)</span> <span class="synSpecial">(</span><span class="synStatement">cons</span> <span class="synSpecial">(</span>modulo n <span class="synConstant">10</span><span class="synSpecial">)</span> r<span class="synSpecial">)))))</span>
</pre>
<p>
これだけだとなにをやっているかわからないと思うので、Perl版が「<a href="http://d.hatena.ne.jp/sirocco634/20080702#1215008700" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/sirocco634/20080702#1215008700', '2008-07-02 &#8211; 武蔵の日記');" target="_blank">2008-07-02 &#8211; 武蔵の日記</a>」にあります。アルゴリズムはそっちをごらんください。
</p>
<h4>
実行結果
</h4>
<p>
<a href="http://d.hatena.ne.jp/asin/4873113482" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/asin/4873113482', 'プログラミングGauche');">プログラミングGauche</a>』で試してみます。isbn13は9784873113487なので
</p>
<pre class="syntax-highlight">
gosh&#62; <span class="synSpecial">(</span>isbn <span class="synConstant">9784873113487</span><span class="synSpecial">)</span>
<span class="synConstant">4873113482</span>#&#60;undef&#62;
</pre>
<p>
という結果でした。確かめてみましょう。
</p>
<p>
<center>
</center>
</p>
<p>
<a href="http://f.hatena.ne.jp/sirocco634/20081108214239" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://f.hatena.ne.jp/sirocco634/20081108214239', '');"><img alt="20081108214239" src="http://img.f.hatena.ne.jp/images/fotolife/s/sirocco634/20081108/20081108214239.png" /></a>
</p></p>
<p>
asinはisbn10のことなので、asin記法のところを見ます。あってますね。というわけで、できました。
</p>
</div>