125 lines
11 KiB
Markdown
125 lines
11 KiB
Markdown
---
|
|
title: isbn13→isbn10を求めるlispスクリプト
|
|
author: kazu634
|
|
date: 2008-11-08
|
|
url: /2008/11/08/_1141/
|
|
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スクリプト – 武蔵の日記');" target="_blank"> isbn13からisbn10を求めるlispスクリプト – 武蔵の日記</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を求めるスクリプトを作る(途中) – 武蔵の日記');" target="_blank"> isbn13からisbn10を求めるスクリプトを作る(途中) – 武蔵の日記</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 –&gt; isbn10 – 武蔵の日記');" target="_blank"> isbn13 –> isbn10 – 武蔵の日記</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->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->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">"Not match"</span><span class="synSpecial">)))</span>
|
|
<span class="synComment">;; 数字からリストにする。後ろにShiroさんの別解あり</span>
|
|
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number->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->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->list <span class="synSpecial">(</span>number->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->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->list別解 - (1)</span>
|
|
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number->list n<span class="synSpecial">)</span>
|
|
<span class="synSpecial">(</span><span class="synStatement">map</span> digit->integer
|
|
<span class="synSpecial">(</span>string->list <span class="synSpecial">(</span>number->string n<span class="synSpecial">))))</span>
|
|
<span class="synComment">;; number->list別解 - (2)</span>
|
|
<span class="synSpecial">(</span>define <span class="synSpecial">(</span>number->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"><</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 – 武蔵の日記');" target="_blank">2008-07-02 – 武蔵の日記</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> <span class="synSpecial">(</span>isbn <span class="synConstant">9784873113487</span><span class="synSpecial">)</span>
|
|
<span class="synConstant">4873113482</span>#<undef>
|
|
</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> |