All Rights Res

リスト：仲間に分けたり，一緒にまとめたり
リストという重要な概念を学びましょう．

グループ（リスト）を作ろう
グループを作るには，中括弧（「8」と「<」）を使います．例えば，お子さんの七五三をする年齢を表す数のグループを作るには，次のように中括弧の中にカンマ（「,」）で区切って書いていきます．カンマを使うのは，どこまでが最初の数で，どこからが次の数か判るようにするためです．

ü 「食事」に関するグループを作ってみる

87, 5, 3<小学校から大学までの標準的な在学年数を表す数から構成されるグループであれ
ば，次のように同じ数が含まれることもあります．
86, 3, 3, 4<

さて，本題に戻って食事に関するものとして朝食のグループを作ってみましょう．これまでの数のグループを真似て作ると次のようになると思いがちですが，これは少しだけ書き直す必要があります．
9ごはん, 味噌汁, 焼き魚=

朝食の内容に関するグループを正しく作るには，次のように食事の内容を二重引用符（ダブルクオーテーション：「"」）で囲む必要があります．
9"ごはん", "味噌汁", "焼き魚"=

これはちょっと不思議な感じがしますが，次のように，小括弧，中括弧，大括弧を含
むような括弧のグループを作ると必要なことがわかります．まずは，引用符を付けないで作ってみましょう．
8L, H,<, 8,D, @<このように引用符を付けないと，どこまでがグループなのか判らなくなってしまいます．見方によっては，二つのグループを併記しているようにも見えますし，一つの大きなグループのようにも見えます．今度はちゃんと引用符を付けて作ってみます．非
常に判りやすくなりました．
8"L", "H", "<", "8", "D", "@"<

【数と数字】朝食の内容や括弧は二重引用符で囲む必要があるのに，数の場合には囲んでいませんでした．なぜでしょうか．実は，数と言っても数値と数字では意味が違-1-

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

います．数値は算数とか数学で言う数ですが，数字は，その数を表す「文字」です．ですから，数値として扱いたいときは二重引用符はいりません．逆に，朝食の内容のように文字や文章として数を扱いたいときは，数字と区別するために，二重引用符が必要になります．
せっかく朝食のグループを作るのですから，グループに名前を付けましょう．名前を付けるには，グループの前に，グループ名と等号（「=」）を書き加えてから，˜を押しながらÛを押してください．そうすると，次のように入力されていたものが，
朝食 = 9"ごはん", "味噌汁", "焼き魚"=

次のように変化します．
In[1]:=
Out[1]=

朝食 = 9"ごはん", "味噌汁", "焼き魚"=
9ごはん, 味噌汁, 焼き魚=

何やら入力した覚えのないものが出てきました．最初の行の左側に表示されている「In[1]」は，Mathematicaが命令（グループに名前を付けろ！）を受け取りました，その整理番号は何番です，という意味です．次の行の左側に表示されている「Out[1]」は，その整理番号の命令を実行した結果，という意味です．
【評価と計算】Mathematicaは計算のできる利口なワープロソフトだと考えると良いでしょう．普通の文章を入力することもできますし，電卓のような計算をさせることもできます．ワープロソフトと違うのは，入力した数式を計算して欲しいと思ったら，その場所で˜+Ûを押すだけ計算結果を求めてくれます．この操作のことを「評価する」と言います．最近のMathematicaでは命令をしなくても自動的に計算を行ってくれる便利な方法もありますが，この章では扱いません．
さて，朝食のグループには名前を付けたので，名前を呼べば確認できます．今度は，名前だけを入力して，˜+Ûを押してみましょう．次のように，朝食のグループを確認することができます．
In[2]:=
Out[2]=

朝食

9ごはん, 味噌汁, 焼き魚=

同じように，昼食のグループにも名前を付けましょう．次のようにグループ名と等号（「=」）を入力をしてから，˜+Ûを押してみましょう．
In[3]:=
Out[3]=

昼食 = 9"サンドイッチ", "サラダ", "コーヒー"=
9サンドイッチ, サラダ, コーヒー=-2-

All Rights Res

これで朝食と昼食の準備ができました．どんな食事の内容かを確認したい場合は，グループ名を入力してから，˜+Ûを押してください．このようにMathematicaと会話をすることが，Mathematicaを使うということです．
In[4]:=

朝食

Out[4]=

9ごはん, 味噌汁, 焼き魚=

In[5]:=

昼食

Out[5]=

9サンドイッチ, サラダ, コーヒー=

これ以外にもおやつであったり，夕食であったり，様々なグループを作ることが出来ます．このように，中括弧（「8 」 と 「< 」）で作ったグループのことを「リスト（List）」と呼びます．リストは，Mathematicaの非常に重要な概念になりますので，ぜひ名前を覚えるようにしてください．
In[6]:=

おやつ = 9"ショートケーキ", "ミルクティー"=Out[6]=

9ショートケーキ, ミルクティー=

In[7]:=

夕食 = 9"肉じゃが", "生姜焼", "味噌汁", "ごはん", "漬物"=Out[7]=

9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物=【 シンタックスカラーリング】Mathematica 6では，既に使用したグループ名を入力すると「黒色」で表示されますが，まだ使用されていないグループ名の場合は「青色」で表示されます．これは即ち，その時点でMathematicaに覚えさせているグループ
名でなければ「青色」で表示されていることを意味します．プログラミング言語の用語でいえば，未定義の変数は青色，定義済みの変数は黒色で表示されます．
ü いろいろなグループを作ってみる

先ほどの食事の内容は長坂家のものだったとします．長坂家だけでなく，いろいろな家庭の食事の内容に関するグループを作ってみます．岩見家の食事の内容のグループを作ってみましょう．あくまでも仮定の話ですが，朝食は次のようなグループになると思います．
9"食パン", "ハム", "コーヒー", "サラダ"=

このグループにも名前を付けたいので，グループ名と等号（「=」）を入力をしてから，˜+Ûを押してみましょう．

-3-

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[8]:=
Out[8]=

朝食 = 9"食パン", "ハム", "コーヒー", "サラダ"=
9食パン, ハム, コーヒー, サラダ=

岩見家の朝食のグループにも名前を付けたので，名前を呼べば確認できます．今度も，名前だけを入力して，˜+Ûを押してみましょう．次のように，朝食のグループを確認することができます．
In[9]:=
Out[9]=

朝食

9食パン, ハム, コーヒー, サラダ=

ここで疑問が一つ生まれます．長坂家の朝食のグループを知りたくなったらどうすれば良いでしょうか．長坂家の朝食のグループを教えてもらいたくて，次のように名前を呼んでも岩見家のグループしかMathematicaは教えてくれません．
In[10]:=
Out[10]=

朝食

9食パン, ハム, コーヒー, サラダ=

実は，同じ名前のグループを複数定義しても，Mathematicaは最後に覚えたものしか教
えてくれません．既に，長坂家の朝食のグループは忘れ去られていてるので，いくら聞いても岩見家のグループしか出てきません．次のように河合家の朝食を覚えてもらうと，今度は岩見家の朝食グループを忘れてしまいます．
In[11]:=

朝食 = 9"ごはん", "納豆", "味噌汁", "漬物"=Out[11]=

9ごはん, 納豆, 味噌汁, 漬物=

In[12]:=

朝食

Out[12]=

9ごはん, 納豆, 味噌汁, 漬物=【教えること＝定義＝覚えさせること】朝食グループのように，「等号（=）」を使って名前を付けてMathematicaに教えることを「定義」と言います．人が言葉を覚える
ときに，その単語の意味を教えてもらうのと同じで，その名前が意味することをMathematicaに覚えさせることになります．数学で，変数の値を「a = 1」のように表記するのと同じですね．
人間であれば，話の文脈を理解して適切なものを教えてくれるのですが，コンピュータは人間とは違って融通が利かない石頭なので仕方がないのでしょうか．安心してください．実は，Mathematicaにも「コンテキスト（文脈）」という仕組みが備わっています．そしてコンテキストごとに定義を覚えさせることが出来ます．
長坂家というコンテキスト（文脈）を「長坂家」という名前で表現するならば，長坂
家の朝食や昼食のグループを次のように定義することが出来ます．ここで，コンテキ-4-All Rights Res

スト名である「長坂家」とグループ名の間に始まりを表す単一引用符（「`」）が入っていることに注意してください．
In[13]:=

長坂家`朝食 = 9"ごはん", "味噌汁", "焼き魚"=Out[13]=

9ごはん, 味噌汁, 焼き魚=In[14]:=

長坂家`昼食 = 9"サンドイッチ", "サラダ", "コーヒー"=Out[14]=

9サンドイッチ, サラダ, コーヒー=

続いて，岩見家の朝食と昼食のグループも定義してみましょう．
In[15]:=

岩見家`朝食 = 9"食パン", "ハム", "コーヒー", "サラダ"=Out[15]=9食パン, ハム, コーヒー, サラダ=In[16]:=

岩見家`昼食 = 9"素麺", "サラダ"=Out[16]=9素麺, サラダ=

ついでにおやつや夕食に関するグループも定義しておきましょう．Mathematicaにグ
ループを覚えてもらう場合，これまでMathematicaは復唱してくれていました．覚えた
内容を次の行に表示してくれていたと思います．復唱がいらない場合は，行の最後にセミコロン（「;」）を付けてください．Mathematicaはグループの内容を記憶しますが，その内容を復唱することはありません．
In[17]:=

長坂家`おやつ = 9"ショートケーキ", "コーヒー"=;

In[18]:=

岩見家`おやつ = 9"梨", "コーヒー"=;【複合式と出力の抑制】 Mathematicaでは，セミコロン（「;」）で区切ることで同時に複数の指示を行うことが出来ます．行の最後にセミコロンだけを書くことは，次に実行すべき指示を空欄，つまりは何もしない，と指示していることに他なりません．従って，何も結果が表示されません．Version 6よりも前の版では，出力が異様に大きい場合も全てを表示しようとするので，セミコロンの利用が必須でしたが，Version 6からは巨大な出力を抑制してくれるので非常に便利になりました．
In[19]:=
Out[19]=長坂家`夕食 = 9"肉じゃが", "生姜焼", "味噌汁", "ごはん", "漬物"=9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物=-5-

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[20]:=
Out[20]=

岩見家`夕食 = 9"焼肉", "味噌汁", "サラダ", "ごはん"=
9焼肉, 味噌汁, サラダ, ごはん=

ü どんなグループだったか問い合わせてみる

実際に長坂家と岩見家のそれぞれの食事の内容を覚えているのかを確認してみましょう．確認する際には，コンテキスト名である「長坂家」や「岩見家」とグループ名の間に始まりを表す単一引用符（「`」）を忘れずに付けてください．
In[21]:=

長坂家`朝食Out[21]=

9ごはん, 味噌汁, 焼き魚=In[22]:=

岩見家`朝食Out[22]=

9食パン, ハム, コーヒー, サラダ=

コンテキスト名を付け忘れると次のように河合家の朝食グループが出てきてしまいます．これは，一番最後に定義した（コンテキスト名を指定しない）朝食グループが河合家のものだったからです．
In[23]:=
Out[23]=

朝食

9ごはん, 納豆, 味噌汁, 漬物=

実は明示的にコンテキスト名を指定しなくても「Global」というコンテキスト名が指定されているとMathematicaは解釈します．長坂家の話をしている最中に，わざわざ「長坂家の」という指定はしないのと同じで，判りきっていることは省略できるようになっています．いま使われているコンテキストは，$Contextという名前で管理されています．この出力の「Global」は特定のコンテキストでない，即ち汎用のコンテキストという意味になります．
In[24]:=$Context

Out[24]=Global`

長坂家と岩見家に関するコンテキストで管理されているグループを問い合わせてみましょう．「長坂家のコンテキストで管理されているグループ名は何ですか？」とMathematicaに聞くわけです．すると，次のように「長坂家 」のコンテキストには朝食，昼食，おやつ，夕食のグループが存在していることがわかります．
In[25]:=? 長坂家`∗

長坂家`

夕食

昼食

朝食

-6-

おやつ

All Rights Res

同様に岩見家についても問い合わせてみます．先ほど，定義したグループ名が存在していることがわかります．気になるグループ名をマウスでクリックしますと，そのグループ（リストですね）の要素を確認することが出来ます．
In[26]:=? 岩見家`∗

岩見家`

夕食

昼食

朝食

おやつ

ところで，朝食に関するグループを3つ（長坂家，岩見家，河合家）定義しました
が，どのようにしたら，コンテキスト名を入力しなくても長坂家であったり，岩見家であったりの朝食グループを確認することが出来るでしょうか．暗にどのようなコン
テキストが使われてるかは，次の変数（$ContextPath）を確認することでわかります．
In[27]:=
Out[27]=$ContextPath

8PacletManager`, WebServices`, System`, Global`<

このグループの定義を次のように変更することで，長坂家のコンテキストが優先されるようになります．この場合，ただの「朝食」でも長坂家の朝食グループを確認する
ことが出来ます．
In[28]:=$ContextPath = 9"長坂家`", "PacletManager`","WebServices`", "System`", "Global`"=Out[28]=9長坂家`, PacletManager`, WebServices`, System`, Global`=In[29]:=

朝食

Out[29]=9ごはん, 味噌汁, 焼き魚=

もちろん，このグループの定義を元に戻すことで，ただの「朝食」では河合家の朝食
グループしか参照されない状態に戻すことが出来ます．
In[30]:=$ContextPath = 8"PacletManager`", "WebServices`","System`", "Global`"<Out[30]=8PacletManager`, WebServices`, System`, Global`<

In[31]:=

朝食

Out[31]=

9ごはん, 納豆, 味噌汁, 漬物=【カスタマイズと定義済み変数】Mathematicaには「$ContextPath」のように定義済みの変数がたくさんあります．それらの変数の値を操作することで，自分好みのMathematicaにカスタマイズすることが出来ます．より簡単に変更できるよう，見た目-7-

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

や編集操作に関することも含めて，編集メニューの「環境設定...」でカスタマイズが出来るようになっています．

グループ（リスト）の性質を調べたり操作をしよう
ü 長坂家と岩見家に共通するもの

長坂家と岩見家という二つの家庭の食事に共通するものを調べることにしましょう．既に，朝食，昼食，おやつ，夕食のグループをそれぞれの家庭について定義しています．これらのグループごとに共通するものを調べましょう．

朝食（長坂家）ごはん，味噌汁，焼き魚

朝食（岩見家）食パン，ハム，コーヒー，サラダ

昼食（長坂家）サンドイッチ，サラダ，コーヒー

昼食（岩見家）素麺，サラダ

おやつ（長坂家）

ショートケーキ，コーヒー

おやつ（岩見家）

梨，コーヒー

夕食（長坂家）肉じゃが，生姜焼，味噌汁，ごはん，漬物

夕食（岩見家）焼肉，味噌汁，サラダ，ごはん

これまでに定義した長坂家と岩見家のグループの内容

Mathematicaに何か頼む場合（今回はグループに共通するものを調べさせる場合），組込み関数と呼ばれる命令を使って指示する必要があります．Mathematicaの母国語は英語なので，基本的にすべての支持は英語で出す必要もあります．下図は，基本的な指示の出し方を説明したものです．

Intersection@長坂家`夕食, 岩見家`夕食D
命令（組込み関数）

カンマ
ブラケット（大括弧）Mathematicaへの指示の出し方

ここで「Intersection」は「グループに共通するものを調べよ」という指示になります．比較すべきグループ名はカンマで区切る必要がありますし，ブラケットが使われていることにも注意してください．これらのブラケットやカンマは，Mathematicaが指示を理解するために必要なものです．実際に，長坂家と岩見家の夕食に共通する内容を調べてみましょう．
In[32]:=
Out[32]=

IntersectionA長坂家`夕食, 岩見家`夕食E
9ごはん, 味噌汁=

-8-

All Rights Res

グループ名の部分を変更するだけで，朝食，昼食，おやつについても調べることが出来ます．
In[33]:=

IntersectionA長坂家`朝食, 岩見家`朝食E

Out[33]=8<

In[34]:=

IntersectionA長坂家`昼食, 岩見家`昼食E

Out[34]=9サラダ=

In[35]:=

IntersectionA長坂家`おやつ, 岩見家`おやつE

Out[35]=8コーヒー<【中身のないグループ】Mathematicaでは「8<」のように，中括弧の間に何も含まれていないグループもあります．これはグループを集合と考えた場合の空集合にあたるものです．長坂家と岩見家の朝食の共通部分の結果が「8<」となっている意味は，双方に共通するものは存在しない，ということになります．この他，Mathematicaの使い方
や出力には，数学的なものの表現が多数あります．
ü 長坂家と岩見家に共通しないもの

一方，長坂家の食事の内容には含まれているのに，岩見家の食事には含まれていないものを調べるには，異なる命令（異なる組込み関数）を使う必要があります．そのために使う指示は「Complement」になります．これは「ある集まりから別の集まりに含まれているものを取り除きなさい」という指示になります．従って，次のようにMathematicaに命令することで，長坂家の夕食には含まれているのに，岩見家の夕食には含まれていないものを調べられます．
In[36]:=
Out[36]=

ComplementA長坂家`夕食, 岩見家`夕食E
9漬物, 生姜焼, 肉じゃが=-9-

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[37]:=

Out[37]=

IntersectionとComplementの図解

他の食事についても同様に調べてみましょう．
In[38]:=
Out[38]=ComplementA長坂家`朝食, 岩見家`朝食E
9ごはん, 味噌汁, 焼き魚=

- 10 -

All Rights Res

In[39]:=

ComplementA長坂家`昼食, 岩見家`昼食E

Out[39]=9コーヒー, サンドイッチ=

In[40]:=

ComplementA長坂家`おやつ, 岩見家`おやつE

Out[40]=

9ショートケーキ=ü グループの吸収合併（新しい食事の組合せの発見）

長坂家と岩見家が一緒に食事をしたとき，食事はどのようになるかを調べましょう．つまり，長坂家の食事に岩見家の食事の内容を加えたものをMathematicaに調べてもらいます．このような場合，「Union」という指示で「重複しないように双方の中身を併せなさい」という作業を行わせます．
In[41]:=
Out[41]=

UnionA長坂家`夕食, 岩見家`夕食E

9漬物, 焼肉, ごはん, サラダ, 味噌汁, 生姜焼, 肉じゃが=

これを応用することで，長坂家の一日の全ての食事の構成も調べられます．
In[42]:=
Out[42]=

UnionA長坂家`朝食, 長坂家`昼食, 長坂家`おやつ, 長坂家`夕食E
9漬物, ごはん, サラダ, 味噌汁, 焼き魚, 生姜焼,

コーヒー, 肉じゃが, サンドイッチ, ショートケーキ=

岩見家についても調べてみましょう．
In[43]:=
Out[43]=

UnionA岩見家`朝食, 岩見家`昼食, 岩見家`おやつ, 岩見家`夕食E

9梨, ハム, 焼肉, 素麺, ごはん, サラダ, 味噌汁, 食パン, コーヒー=

なお，Mathematicaでは共通部分「Intersection」と和集合「Union」という横文字の指示の代わりに，数学で用いられる記号を使っても同じことを調べさせることができます．
In[44]:=

長坂家`朝食 › 長坂家`夕食

Out[44]=

9ごはん, 味噌汁=

In[45]:=

岩見家`朝食 ‹ 岩見家`昼食

Out[45]=

9ハム, 素麺, サラダ, 食パン, コーヒー=- 11 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

ü グループへの新しい要素の追加

これまで長坂家と岩見家の食事の内容についてリストを作成して共通点などを調べてきました．ところが実は長坂家の朝食には「漬物」も出ていたことが判明しました．もう一度最初から操作し直さなければいけないでしょうか．大丈夫です．Mathematicaでは，既に定義したリストに新たな項目を追加する機能が備わっています．「指定したグループに新しい仲間を加えなさい」という意味の指示は「AppendTo」になります．
現在の長坂家の朝食の内容を確認し，夕食との共通点を調べてみます．
In[46]:=

長坂家`朝食Out[46]=

9ごはん, 味噌汁, 焼き魚=In[47]:=

IntersectionA長坂家`朝食, 長坂家`夕食E

Out[47]=

9ごはん, 味噌汁=

実際に「AppendTo」を使って，長坂家の朝食に漬物を加えてみましょう．夕食との共通点を調べると新たに漬物が共通していることがわかります．
In[48]:=

AppendToA長坂家`朝食, "漬物"E

Out[48]=9ごはん, 味噌汁, 焼き魚, 漬物=

In[49]:=

IntersectionA長坂家`朝食, 長坂家`夕食E

Out[49]=9漬物, ごはん, 味噌汁=

同じように，長坂家と岩見家のおやつにそれぞれ新しい食品を加えるには次のように指示を出します．
In[50]:=

AppendToA長坂家`おやつ, "チーズケーキ"E

Out[50]=

9ショートケーキ, コーヒー, チーズケーキ=

In[51]:=

AppendToA岩見家`おやつ, "ヨーグルト"EOut[51]=

9梨, コーヒー, ヨーグルト=- 12 -

All Rights Res

ü グループに含まれているかを確認する

膨大なデータを含むグループに特定の項目が含まれているかを目視で確認することは大変な作業です．例えば，長坂家の夕食に「漬物」が含まれていたかを確認するなどの 作 業 で す ． そ の よ う な 調 べ ご と はM a t h e m a t i c aに 任 せ て し ま い ま し ょう．「MemberQ」という組込み関数を使うことで，「あるグループに指定した項目が含まれているか」を調べさせることができます．実際に，長坂家の夕食に漬物が含まれているかを調べてみましょう．
In[52]:=

MemberQA長坂家`夕食, "漬物"E

Out[52]=

True「True」と表示されました．日本語に直せば「はい」です．今回の場合，食事の内容が少ないので目視でも，次のように長坂家の夕食を確認すれば，実際に漬物が含まれていることがわかります．
In[53]:=Out[53]=長坂家`夕食

9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物=

それでは，長坂家と岩見家の朝食，昼食，おやつ，夕食を通して「うどん」が含まれているかを確認するにはどうすれば良いでしょうか．漬物を確認したように8回Mathematicaに調べさせてみましょう．
In[54]:=

MemberQA長坂家`朝食, "うどん"E

Out[54]=

False

In[55]:=

MemberQA長坂家`昼食, "うどん"E

Out[55]=

False

In[56]:=

MemberQA長坂家`おやつ, "うどん"E

Out[56]=

False

In[57]:=

MemberQA長坂家`夕食, "うどん"E

Out[57]=

False

In[58]:=

MemberQA岩見家`朝食, "うどん"E

Out[58]=False- 13 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[59]:=

MemberQA岩見家`昼食, "うどん"E

Out[59]=False

In[60]:=

MemberQA岩見家`おやつ, "うどん"E

Out[60]=False

In[61]:=

MemberQA岩見家`夕食, "うどん"E

Out[61]=

False

結果は「False」，即ち日本語に直せば「いいえ」です．しかし，8回も命令するのは面倒です．このような場合はグループの吸収合併で使用した「Union」を併用します．即ち，両家併せて8回分の食事の内容を併せたものの中に「うどん」が含まれているかを確認させます．
In[62]:=

MemberQAUnionA長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食, 岩見家`朝食, 岩見家`昼食, 岩見家`おやつ,
岩見家`夕食E, "うどん"E

Out[62]=

False

このように，Mathematicaへの指示は複数個組み合わせることもできます．もしくは，両家の食事内容に新しく名前を付けてから確認させるということもできます．
In[63]:=

両家の食事 = UnionA長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食, 岩見家`朝食, 岩見家`昼食, 岩見家`おやつ,
岩見家`夕食E

Out[63]=

9梨, ハム, 漬物, 焼肉, 素麺, ごはん, サラダ,

味噌汁, 焼き魚, 生姜焼, 食パン, コーヒー, 肉じゃが,
ヨーグルト, サンドイッチ, チーズケーキ, ショートケーキ=

In[64]:=

MemberQA両家の食事, "うどん"E

Out[64]=

False【括弧の対応付け】Mathematicaでは括弧や引用符の対応付けが正しくない場合，通常とは異なる色で表示するようになっています．例えば，中括弧の左側「{」に対応す
る右側「}」がないような場合，紫色で括弧が表示されます．これにより間違った指示を出さないように気を付けることができます．色が黒色でない場合は，もう一度見直すようにしましょう．

- 14 -

All Rights Res

グループ（リスト）のグループを作ろうü グループのグループ

長坂家の朝食，昼食，おやつ，夕食と見てきましたが，これらを長坂家の食事としてグループに出来ると便利そうです．リストに含まれる項目をまとめるには，Unionという組込み関数を使いました．従って，次のように指示を出すことで長坂家の全ての食事の内容をまとめることは出来ます．
In[65]:=

長坂家の食事 = UnionA長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食E

Out[65]=9漬物, ごはん, サラダ, 味噌汁, 焼き魚, 生姜焼, コーヒー,
肉じゃが, サンドイッチ, チーズケーキ, ショートケーキ=

しかしながら，このようにまとめてしまうと，どの項目が朝食で食べられたもの
か，どの項目が重複して含まれていたのか，という情報が失われてしまいます．そこで出てくるのが「グループのグループ」ないしは「リストのリスト」です．これまでのリストを使った方法に倣い，次のようにリストのリストを作ってみました．
In[66]:=

長坂家の食事 = 9長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食=Out[66]=99ごはん, 味噌汁, 焼き魚, 漬物=, 9サンドイッチ, サラダ, コーヒー=,
9ショートケーキ, コーヒー, チーズケーキ=,
9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物==

結果として得られたものは，リストの各要素（グループの各項目）が再度リスト（グループ）になっています．Mathematicaでは繰り返して括弧を使うことで，グループのグループを表現することが出来るようになっています．
グループのグループにも共通するものがないかのチェックを「Intersection」で行うことが出来ます．例えば，河合家の食事の内容が次のようなものだったとして，長坂家の食事との共通点を探してみましょう．
In[67]:=

河合家の食事 = 99"サンドイッチ", "サラダ", "コーヒー"=,
9"素麺", "漬物", "煎茶"=,

9"焼き魚", "味噌汁", "ごはん", "漬物", "惣菜"==Out[67]=99サンドイッチ, サラダ, コーヒー=,

9素麺, 漬物, 煎茶=, 9焼き魚, 味噌汁, ごはん, 漬物, 惣菜==

- 15 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[68]:=
Out[68]=IntersectionA長坂家の食事, 河合家の食事E
99サンドイッチ, サラダ, コーヒー==

長坂家の昼食にあたるものが河合家の食事にも含まれていることが確認できました．
【リストのネスト】Mathematicaでは「リストのリスト」のように同じ構造を繰り返して使うことが良くあります．また，同じ構造を繰り返して入れ子状に使うことを「ネストする」と表現したりします．括弧の多さに嫌気がさすこともあるかもしれません
が，データ構造を表す重要なものです．注意深くネストされた情報を確認しましょう．
ü コピーとリンクの違い

長坂家の食事というグループを作ることが出来ましたが，実は長坂家の朝食には「納豆」もあったことに気がつきました．そこで，長坂家の朝食の内容に次のように納豆を追加しました．
In[69]:=
Out[69]=AppendToA長坂家`朝食, "納豆"E

9ごはん, 味噌汁, 焼き魚, 漬物, 納豆=

しかしながら，長坂家の食事を確認してみると「納豆」が追加されていません．
In[70]:=
Out[70]=

長坂家の食事99ごはん, 味噌汁, 焼き魚, 漬物=, 9サンドイッチ, サラダ, コーヒー=,
9ショートケーキ, コーヒー, チーズケーキ=,
9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物==

長坂家の食事は次のように定義したので，長坂家の朝食の内容が変化すれば，それに応じて長坂家の食事も変化するように思えます．が，その考え方は正しくありません．グループ名を定義するときに「=」を使うと，定義内容が「コピー」されてグ
ループの一員になります．既にコピーされているので，コピー前の原本を編集してもコピー済みのものは変化しないのです．
長坂家の食事 = 9長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食=このようなことを防ぐために，ショートカットやリンクという機能がファイルマ
ネージャには備わっていると思います．Mathematicaのグループ定義で同じような機能を使うためには，「=」の代わりに「:=」を使います（コロンとイコール）．例えば，長坂家の食事をコピーではなく，朝食や昼食などの内容にリンクする場合は次のようにします．

- 16 -

All Rights Res

In[71]:=

長坂家の食事 := 9長坂家`朝食, 長坂家`昼食, 長坂家`おやつ,
長坂家`夕食=実際にリンクされていることを確認しましょう．次のように，長坂家の夕食に「ビール」を追加すると，長坂家の食事の内容が変化していることがわかると思います．
In[72]:=
Out[72]=

長坂家の食事99ごはん, 味噌汁, 焼き魚, 漬物, 納豆=,
9サンドイッチ, サラダ, コーヒー=,

9ショートケーキ, コーヒー, チーズケーキ=,
9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物==
In[73]:=

AppendToA長坂家`夕食, "ビール"EOut[73]=

9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物, ビール=In[74]:=

長坂家の食事Out[74]=99ごはん, 味噌汁, 焼き魚, 漬物, 納豆=,
9サンドイッチ, サラダ, コーヒー=,

9ショートケーキ, コーヒー, チーズケーキ=,

9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物, ビール==【即時的な定義と遅延的な定義】Mathematicaでは，定義の内容を参照するタイミング
によりファイルマネージャにおける「コピー」と「リンク」のような機能を提供しています．コピーのように，操作した時点で「=」の右側にあるものの内容を確認してしまうことを「即時的な定義」と呼びます．リンクのように，操作した時点では「:=」の右側にあるものの内容を確認せずに，実際に必要になったときに改めて確認することを「遅延的な定義」と呼びます．これらは非常に重要な概念になります．
ü コピーとリンクの違いを調べる

長坂家の食事はリンク（遅延的な定義）としてMathematicaに覚えてもらったことにな
ります．一方で，河合家の食事はリストのリストとして定義しましたから，これはコピー（即時的な定義）としてMathematicaに覚えてもらったことになります．
あるグループ名（変数）の定義が即時的に行われているか，それとも遅延的に行われているかを確認するには，以前にも使用した「?」を使います．次のようにそれぞれの内容を問い合わせることで，即時的（=）なのか遅延的（:=）なのかを確認することが出来ます．

- 17 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[75]:=? 長坂家の食事

Global`長坂家の食事
長坂家の食事 :=9長坂家`朝食, 長坂家`昼食, 長坂家`おやつ, 長坂家`夕食=
In[76]:=? 河合家の食事

Global`河合家の食事

河合家の食事 = 99サンドイッチ, サラダ, コーヒー=,

9素麺, 漬物, 煎茶=, 9焼き魚, 味噌汁, ごはん, 漬物, 惣菜==

実際，遅延的な定義を行った長坂家の食事においては，朝食や昼食などへのリンクがあるだけで，その内容まではコピーされていないことがわかると思います．河合家の食事の方では即時的な定義を行っているので，既にリストのリストになっています（もちろん，河合家の食事はそのように最初から定義したのではありますが）．

グループ（リスト）をわかり易く表示しようü リスト表示の仕方を少し変える

これまでMathematicaに覚えさせたものを確認するには，次のように単純にその変数名を呼び出すだけでした．しかし，この方法では見た目がパッとしないと思う方もいるでしょう．そこで今回は，リストの内容の確認方法（画面への表示方法）について取り上げます．
In[77]:=
Out[77]=長坂家`朝食9ごはん, 味噌汁, 焼き魚, 漬物, 納豆=

最初に取り上げるのは，「列として表示しなさい」という指示になる「Column」です．この指示で長坂家の朝食の内容を確認してみましょう．次のように列として食事が表示されます．
In[78]:=

ColumnA長坂家`朝食E

ごはん
味噌汁
Out[78]= 焼き魚
漬物
納豆- 18 -

All Rights Res

一方，長坂家のすべての食事の内容をリストのリストとして表現していた変数を表示
させると次のようになります．Columnという命令は単純なリストを列として縦に表示するだけなので，リストのリストを表示させると，各項目のリストがそのまま表示されることになります．
In[79]:=

ColumnA長坂家の食事E

9ごはん, 味噌汁, 焼き魚, 漬物, 納豆=
9サンドイッチ, サラダ, コーヒー=Out[79]=9ショートケーキ, コーヒー, チーズケーキ=

9肉じゃが, 生姜焼, 味噌汁, ごはん, 漬物, ビール=

なお，列ではなく「行として表示しなさい」という指示「Row」もありますｌIn[80]:=

RowA長坂家`朝食E

Out[80]=

ごはん味噌汁焼き魚漬物納豆ü 表としてリストのリストを表示する

変数の内容にもよりますが，食事の内容をわかりやすい方法で確認したいのであれ
ば，列として表示（Column）や行として表示（Row）よりも，普通の表で表示させた
いのではないでしょうか．
リストのリストで表現されているデータを表形式で表示する命令には種類があります．まず，ColumnとRowの延長線上にある「格子状に並べて表示しなさい」という指示の「Grid」です．実際に，長坂家の食事（遅延的に定義されたリストのリスト）を表示してみましょう．
In[81]:=

Out[81]=

GridA長坂家の食事E
ごはん

味噌汁

焼き魚

サンドイッチ

サラダ

コーヒー

漬物

納豆

ショートケーキ コーヒー チーズケーキ
肉じゃが

生姜焼

味噌汁

ごはん 漬物 ビール

より汎用性が高く，関数名も判りやすいのが「TableForm」という命令で「結果が長方形の表になるようにフォーマットしなさい」という指示になります．この組込み関数は，リストであればネストの度合い（リスト形式がどれだけ入れ子になっているか）に関係なく利用することが出来ます．一方，先ほどのGridはリストのリストにしか使用することが出来ません．同じように，長坂家の食事を表示してみましょう．

- 19 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[82]:=

TableFormA長坂家の食事E

Out[82]//TableForm=

ごはん

味噌汁

焼き魚

サンドイッチサラダ

コーヒー

ショートケーキ

コーヒー

チーズケーキ

肉じゃが

生姜焼

味噌汁

漬物

納豆

ごはん

漬物

ビー

表形式でリストがネストしているデータを表示すると，比較もしやすいです．例えば，次のように河合家の食事の内容もTableFormで表示することで，長坂家の食事の内容との比較が簡単になります．
In[83]:=

TableFormA河合家の食事E

Out[83]//TableForm=

サンドイッチ
素麺
焼き魚

サラダ
漬物
味噌汁

コーヒー
煎茶
ごはん

漬物

惣菜

ü より表らしく表示するには

表計算ソフトなどを使うと，とても綺麗な表を作ることが出来ると思います．同じような装飾はMathematicaでも行うことが可能です．まずは，簡単なところからはじめましょう．次のように命令の最後に「Frame->All」という補足指示を付け加えること
で，表に枠を付けることが出来ます．なお，キーボードから入力された「->」は自動的に「→」に変換されます．
In[84]:=

Out[84]=

GridA長坂家の食事, Frame → AllE
ごはん

味噌汁

焼き魚

サンドイッチ

サラダ

コーヒー

漬物

納豆

ショートケーキ コーヒー チーズケーキ
肉じゃが

生姜焼

味噌汁

ごはん 漬物 ビール

TableFormを使った場合，次のように項目名を付け加えることが出来ます．項目名もリストで指示しているように，リストという仕組みはMathematicaの様々なところで使用されています．このような命令の最後に付け加える補足的な指示のことをオプションと呼びます．

- 20 -

All Rights Res

In[85]:=

TableFormA長坂家の食事,

TableHeadings → 99"朝食", "昼食", "おやつ", "夕食"=,
9"食事の内容"==E

Out[85]//TableForm=

朝食

食事の内容
ごはん

味噌汁

焼き魚

昼食

サンドイッチ

サラダ

コーヒー

おやつ

ショートケーキ

コーヒー

チーズケーキ

夕食

肉じゃが

生姜焼

味噌汁

漬物

納

ごはん

漬

これらのオプションは，次のような構造になっていることに注意してください．

Grid@長坂家の食事, Frame→TrueD
命令

カンマ

オプション名矢印

補足指示

Mathematicaへの補足的な指示の出し方【オプション】Mathematicaでは，右矢印を使って補足的な指示を付け加えることで様々な効果を生み出していきます．オプションという機能があることで，覚えるべき組込み関数の数を少なくすると共に，非常にバラエティに富んだ機能をMathematicaは提供しています．その関数にどのようなオプションがあるかは，ドキュメントセン
ターで確認するか，単純に「Options[関数名]」を評価することで確認します（例えば，Options[Grid]など）．
ü エラーメッセージとその対処方

Mathematicaは頭の固い計算機なので，私たちの出した指示について，非常に細かい駄目出しをしてきます．人間同士であれば融通を利かせてもらえることもあります
が，Mathematicaは人間でないので愛想がありません．
絶対の不文律「全ての命令は，Mathematicaの作法に従う必要があります」
しかしながら，Mathematicaも愛想は悪いながらもエラーメッセージという形で，我々の間違いを正そうと試みてくれます．例えば，次のように閉じる括弧（]）を付けずに評価すると，右側のほうにオレンジ色のマークが表示されます．このマークは「何かおかしいぞ」という意味です．
GridA長坂家`朝食

この時点で修正すべき間違いに気がつけなくても，オレンジ色のマークをクリックすることで「どう修正すべきか」という提案を行ってくれます．例えば今回の場合，閉じる括弧（]）が不足していることを指摘してくれます．

- 21 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

GridA長坂家`朝食
Syntax::bktmcp : 式"Grid@長坂家`朝食"には閉じる"D"がありません．
Syntax::sntxi : 式は不完全です．追加入力しなければなりません．

Mathematicaの指摘に基づいて修正を行い，再度同じセルを評価することで正しい出力を得ることが出来ます．「Mathematicaを使う」ことが「Mathematicaと対話を行う」こ
とであることを実感してもらえるのではないでしょうか．
In[86]:=

GridA長坂家`朝食E

Out[86]=

GridA9ごはん, 味噌汁, 焼き魚, 漬物, 納豆=E

また，次の例で確認できるように，適切な関数名については色が黒になりますが，そうでない場合は青色のままなので，「これはもしかして何か間違っている？」と察することが出来れば評価の前に修正することも出来ます．
TableForm, Tableform, tableform【エラーメッセージ】Mathematica 6では，スペルミス（大文字と小文字を間違えるな
ど）が文字の色分けで判断が付くようになっています．そのため，スペルミスに関す
るエラーメッセージを従来のMathematicaとは異なり，標準の状態では出力しないように設定されています．この機能を有効にしたい場合は「On[General::spell1,
General::spell]」を評価します．これにより，Mathematicaの受け取った指示にス
ペルミスの可能性がある場合，エラーメッセージが表示されます．

- 22 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

文字列：文章を扱い，自動作文をさせてみよう
文字列という基本となるデータ形式を学びましょう．

ワープロの編集機能を真似てみようü 文章に含まれる単語の数を調べてみる

リストの話を思い出してください．文字や文字列（文字が複数連なったもの）をMathematicaに指示する場合，二重引用符（ダブルクオーテーション：「"」）で囲む必
要がありました．同じように，食品の名前という単語だけでなく，文章を扱う場合にも二重引用符を使う必要があります．例えば，早口言葉をMathematicaに覚えさせる場
合も次のように二重引用符を使う必要があります．
In[1]:=

早口言葉`桃 = "スモモも桃も桃のうち桃もスモモももものうち"Out[1]=

スモモも桃も桃のうち桃もスモモももものうち

この文章の文字数をMathematicaに調べさせるには「次の文字列の文字数を調べよ」という意味を持つ「StringLength」なる命令を使います．次のように，この早口言葉の文字数は21文字であることをMathematicaは教えてくれます．
In[2]:=

StringLengthA早口言葉`桃E

Out[2]=

21

この早口言葉は「も」や「桃」がたくさん出てくるので，それぞれ何回ずつ出てくるのか知りたくなりますね．そのような場合には「StringCount」という命令を使います．これは「次の文字列の中に指定した文字列が何回出てくるか調べよ」という意味の指示になります．実際に次のようにMathematicaに問い合わせることで，「も」が6回，「桃」が3回使われていることがわかります．
In[3]:=

StringCountA早口言葉`桃, "も"E

Out[3]=

6

In[4]:=

StringCountA早口言葉`桃, "桃"EOut[4]=

3

このStringCountは，一文字だけでなく単語や文章についても出現回数を調べる命令になっています．従って，次のように「もも」が何度出てくるかも調べることが出来ます．この早口言葉には「も」が6回も出てくるのに「もも」は1回しか出てこないことがわかります．

- 23 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[5]:=

StringCountA早口言葉`桃, "もも"E

Out[5]=

1【キーボード入力の補完】Mathematicaに指示を出す組込み関数は，英単語から構成されているので覚え易いものです．しかしながら，キーボードで「StringCount」と11文字も入力するのは面倒です．そのためMathematicaには「式の補完」という機能が備わっています．この機能は，WindowsとUnix(Linux)では‚を押しながら「k」を押すことで，Macintoshでは·を押しながら「k」を押すことで利用できます．例えば，StringCountを入力するには「StringCo‚k」でも良いですし，「Str‚」で表示される一覧表の中から選択することも出来ます．
ü 文章に含まれる単語を置き換えてみる

ワープロソフトでは「置換」という機能が備わっていることは多く，文章中の特定の言葉を別の言葉に置き換えることが出来たりします．同じようなMathematicaの機能を使って，先ほどの早口言葉の漢字をひらがなに直してみましょう．置き換えに用いる組込み関数は「StringReplace」で「次の規則に従って，文字列に含まれる単語を置き換えなさい」という意味になります．「Ø」は「->」（マイナス記号と大なり記号）として入力します．
In[6]:=

StringReplaceA早口言葉`桃, "桃" → "もも"E

Out[6]=

スモモもももももものうちもももスモモももものうち【InputAutoReplacements】Mathematicaのノートブックに入力された式は，見易くなるように自動的に変換されます．これには例えば次のようなものがあります．
キーボードからの入力 Mathematica の自動変換先
−>
→
:>
<=
≤
>=
≥
!=
≠
==
非常に読みづらい文章になってしまいましたが，加えて，カタカナもひらがなに直してみましょう．カタカナは「ス」と「モ」が使われています．これらを個別にひらがなにするには「桃」の場合と同様に次のように指示を行います．
In[7]:=

StringReplaceA早口言葉`桃, "ス" → "す"EOut[7]=

すモモも桃も桃のうち桃もすモモももものうち- 24 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[8]:=

StringReplaceA早口言葉`桃, "モ" → "も"E

Out[8]=

スももも桃も桃のうち桃もスももももものうち．．．意味がないですね．「桃，ス，モ」の全てを同時にひらがなにしたいですね．このような場合，置き換えの規則（"桃"Ø"もも", "ス"Ø"す", "モ"Ø"も"）をリスト
で一括指定します．このように，Mathematicaへの指示では単一のものを複数組み合わせるときにもリストが活躍します．
In[9]:=

StringReplaceA早口言葉`桃,Out[9]=

すもももももももものうちもももすももももものうち

9"桃" → "もも", "ス" → "す", "モ" → "も"=E

この状態で先ほど使った組込み関数で文字の数を調べると，音としての「も」の回数がわかります．Mathematicaが調べた結果を次の指示で使うためには，「Mathematicaが直前に報告した結果」を意味する「%」を使うと非常に便利です．もちろん，「%」の代わりに直接「StringReplace[早口言葉`桃,{"桃"→"もも", "ス"→"す", "モ"→"も"}]」を使うことも出来ます．
In[10]:=

StringCountA% , "も"E

Out[10]=16

In[11]:=

StringLengthA早口言葉`桃E

Out[11]=21

このようにして調べると，この早口言葉は21文字中16文字も同じ「も」が出てくることがわかります．面白いですね．
【前の結果の引用】Mathematicaを使うことは「Mathematicaとの会話」です．人間同士の会話から代名詞がなくなったら非常に不便なのと同様に，Mathematicaを使う上でも代名詞は非常に重要です．今回登場した「%」は「直前の結果」を表すものですが，これ以外にも「%%」で「二つ前の結果」，「%%%」で「三つ前の結果」を表しま
す．即ち，パーセント記号を並べただけ前の結果を遡って引用することが出来ます．
ü 文章に含まれる似通った単語の数を調べてみる

ワープロの置換機能に似た方法で音として「も」がたくさん入っていることがわかりました．しかし，私たちがいま使っているのはハイテクの塊とも言えるMathematicaなのに，少しローテク（地味で時代後れ）な方法のように思えませんか．実は，もっとスマートな方法があります．

- 25 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

早口言葉`桃 = "スモモも桃も桃のうち桃もスモモももものうち"
いま取り上げている早口言葉の定義

Mathematicaの組込み関数「StringCases」は「次の文字列の中から，指定したパターンにマッチする単語（部分文字列）を取り出せ」という意味の指示になります．パターンとは例えば，「の」で始まって「桃」で終わる文字列，のような条件のことを指します．この場合，Mathematicaへの命令は次のようになります．
In[12]:=
Out[12]=StringCasesA早口言葉`桃, "の" ∼∼ ___ ∼∼ "桃"E
9のうち桃=

最初は「の」"の"∼∼___∼∼"桃"

チルダ2つ「∼∼」は「次に続く」の意味

最後は「桃」

下線3つ「___」は「何でもOK」の意味

文字列パターン：「の」で始まって「桃」で終わる文字列

他のパターンでも調べてみましょう．次の命令では，「桃」または「もも」または「モモ」にマッチする文字列，を調べさせています．この早口言葉には音として「もも」を6個も含んでいることがわかります．縦線（「|」）を「または」と読むこと
で，文字列パターンは日本語での意味と同じになることがわかると思います．
In[13]:=
Out[13]=StringCasesA早口言葉`桃, "桃" … "もも" … "モモ"E
9モモ, 桃, 桃, 桃, モモ, もも=

Mathematicaの調査結果と早口言葉を比較することで，「ももも」の部分が1つ分の「もも」としか数えられていないことがわかると思います．Mathematicaに重複している部分も数えるように補足指示（オプション）を出すことも出来ます．命令の最後にIn[14]:=

StringCasesA早口言葉`桃, "桃" … "もも" … "モモ",Overlaps → TrueE

Out[14]=

9モモ, 桃, 桃, 桃, モモ, もも, もも=

音として「もも」になるようなカタカナとひらがなの組合せも重複して調べさせることも可能です．この場合，次のように文字列パターンは長くなってしまいます．
In[15]:=

StringCasesA早口言葉`桃, "桃" … "もも" … "モモ" … "もモ" … "モも",Overlaps → TrueE

Out[15]=

9モモ, モも, 桃, 桃, 桃, モモ, モも, もも, もも=- 26 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

カタカナとひらがなの組合せの「もも」を効率良くMathematicaに指示するには，または（「|」）と次に続く「（~~）」を組み合わせて指示を出します．丸括弧（「(」と「)」）は「または」の対象を明確に示すために必要です．この丸括弧がないと，1文
字目が「桃」か「も」か「モ」で，2文字目が「も」か「モ」の単語，という意味になってしまいます．Mathematicaでの丸括弧は，このように物事の優先順位を定めるために使われます．
In[16]:=

StringCasesA早口言葉`桃, "桃" … I"も" … "モ" ∼∼ "も" … "モ"M,Overlaps → TrueE

Out[16]=

9モモ, モも, 桃, 桃, 桃, モモ, モも, もも, もも=

より正確に「もも」という音が何回出てくるかを調べるには，次のように複雑な文字列パターンを使わなければいけませんが，このパターンの意味は自分で考えてみてください．「リストの要素数を調べよ」という意味の命令「Length」を使って，13個のIn[17]:=

StringCasesA早口言葉`桃,"桃" … I9"も", "モ"= ∼∼ 9"も", "モ"=M …

I9"も", "モ"= ∼∼ 9"桃"=M … I9"桃"= ∼∼ 9"も", "モ"=M,

Overlaps → AllE

Out[17]=

9モモ, モも, も桃, 桃, 桃も,も桃, 桃, 桃, 桃も, モモ, モも, もも, もも=

In[18]:=

Length@%DOut[18]=13

なお，オプションの「Overlaps→All」は「桃」と「桃も」のようにマッチする文字
列が他のマッチする文字列に含まれる場合も別のものとして扱うという追加指示にな
ります．これがないと13個ではなく11個しか検出されません．
【文字列パターン】Mathematicaでは，様々な種類のパターンを利用することが出来ます．早口言葉の件で扱っている文字列パターンはそのひとつです．文字列パターンについての詳しい情報はドキュメントセンターで「StringExpression」を調べると書いてあります．なお，文字列パターンは「StringCount」とも組み合わせることが出来ます．「StringCases」の代わりに「StringCount」を使うと，同時に「Length」も使ったのと同じように，パターンにマッチする単語の個数を調べてくれます．ぜひ試してみてください．

- 27 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

お猿さんはシェークスピアの話を書けるか？
ü 言葉（ひらなが，カタカナ，記号）のグループを作ろう

Mathematicaで言葉のリストを作るのには「CharacterRange」という命令を使います．この命令の意味は「次の2つの文字の間にある全ての文字を調べよ」になります．例えば，「な」と「の」の間にある全ての文字を調べさせるには次のように命令します．結果はリストで報告されますが，当然「なにぬねの」です．
In[19]:=
Out[19]=CharacterRangeA"な", "の"E
9な, に, ぬ, ね, の=

この機能を使うと，ひらがなのリストを作ることが出来ます．「ひらがな」という名前でひらがなのリストを覚えさせておきましょう．なお，下記の「ぁ」は小さい「あ」であって，大きな「あ」ではないので注意してください．
In[20]:=
Out[20]=

ひらがな = CharacterRangeA"ぁ", "ん"E

9ぁ, あ, ぃ, い, ぅ, う, ぇ, え, ぉ, お, か, が, き, ぎ, く, ぐ, け,げ, こ, ご, さ, ざ, し, じ, す, ず, せ, ぜ, そ, ぞ, た, だ, ち, ぢ,
っ, つ, づ, て, で, と, ど, な, に, ぬ, ね, の, は, ば, ぱ, ひ, び,ぴ, ふ, ぶ, ぷ, へ, べ, ぺ, ほ, ぼ, ぽ, ま, み, む, め, も, ゃ,や, ゅ, ゆ, ょ, よ, ら, り, る, れ, ろ, ゎ, わ, ゐ, ゑ, を, ん=

同様に，カタカナのリストも「カタカナ」という名前で覚えさせておきましょう．「ヴ」が最後に来ていますが，これは「ン」でも良いと思います．なお，ひらがなのときと同じで，下記の「ァ」は小さい「ア」であって，大きな「ア」ではないので注意してください．
In[21]:=
Out[21]=

カタカナ = CharacterRangeA"ァ", "ヴ"E9ァ, ア, ィ, イ, ゥ, ウ, ェ, エ, ォ, オ, カ, ガ, キ, ギ,
ク, グ, ケ, ゲ, コ, ゴ, サ, ザ, シ, ジ, ス, ズ, セ, ゼ,ソ, ゾ, タ, ダ, チ, ヂ, ッ, ツ, ヅ, テ, デ, ト, ド, ナ,
ニ, ヌ, ネ, ノ, ハ, バ, パ, ヒ, ビ, ピ, フ, ブ, プ, ヘ,ベ, ペ, ホ, ボ, ポ, マ, ミ, ム, メ, モ, ャ, ヤ, ュ, ユ,
ョ, ヨ, ラ, リ, ル, レ, ロ, ヮ, ワ, ヰ, ヱ, ヲ, ン, ヴ=

記号については，順序が複雑で一括して作り出すことが難しいので，リスト（グループ）として必要な記号を「記号」という名前で覚えさせておきます．

- 28 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[22]:=
Out[22]=

記号 = 9"，", "．", "「", "」", "（", "）"=
9，, ．, 「, 」, （, ）=ちなみに半角のアルファベットも次のように生成することが出来ます．
CharacterRange@"a", "z"DOut[23]=8a, b, c, d, e, f, g, h, i, j, k, l,
m, n, o, p, q, r, s, t, u, v, w, x, y, z<

In[24]:=

CharacterRange@"A", "Z"DIn[23]:=

Out[24]=

8A, B, C, D, E, F, G, H, I, J, K, L,
M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z<ü 言葉のグループからランダムな単語を作ってみよう

この章では，お猿さんがキーボードを使ってシェークスピアの文章を入力する可能性は皆無ではない，という有名な話を実際に確かめてみようとしています．言い替えれば，ランダムに選ばれた語から構成される文章が意味を持つことがあるか，ということですね．もっとも，我々人間に確認可能な短い時間で，お猿さんがシェークスピア
を入力することは非常に難しいと思いますが．．．
この実験にちょうど良い命令として「RandomChoice」があります．意味は「次のグループの中から無作為に要素を取り出し，取り出した要素を元に戻す．これを指示された回数実験せよ」です．ひらがなのリストからランダム（無作為）に3個のひらがなを取り出すには，次のように命令することになります．3個のひらがなはランダムに選ばれるため，Mathematicaに命令を出すたび（評価を行うごと）に結果は変化します．
In[25]:=
Out[25]=

RandomChoiceAひらがな, 3E
9じ, ぉ, じ=

このままでは「語のリスト」であって「単語」になっていません．そこで ，Mathematicaに対して「次の語のリストを単語にまとめなさい」という意味の「StringJoin」なる命令も併せて実行させることにします．次の例のように，ひらがな5つから構成される単語が評価毎に作られていきます．
In[26]:=

StringJoinARandomChoiceAひらがな, 5EEOut[26]=いほぞぅだ

同様に，カタカナの単語，記号のみからなる文字列なども作り出すことが出来ます．

- 29 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[27]:=

StringJoinARandomChoiceAカタカナ, 5EEOut[27]=

メシオナケ

In[28]:=

StringJoinARandomChoiceA記号, 5EEOut[28]=））（（，

ちなみに，似たような命令に「RandomSample」があります．この意味は「次のグループの中から無作為に要素を取り出す（元には戻さない）．これを指示された回数実験せよ」です．従って，結果は非常に良く似ていますが，いくら繰り返しても「きつつき」，「とまと」，「とうきょう」などは出てきません．
In[29]:=

StringJoinARandomSampleAひらがな, 3EEOut[29]=ぴとど【ランダムな選択】Mathematicaには最初のバージョンから疑似乱数を作り出す命令「Random」が組み込まれていました．最新のMathematica 6では，より使い易く目的に応じた6つの命令「RandomChoice, RandomComplex, RandomInteger,
RandomPrime, RandomReal, RandomSample」に進化しています．今回使用した
ものは，以前のバージョンになかった組込み関数になります．
ü 言葉のグループからランダムな文章を作ってみよう

漢字はありませんが，ひらがな，カタカナ，記号だけでも文章を作るには十分です．例えば，冒頭で出てきた早口言葉で漢字を使わない場合，次のようになりますが十分理解できます（分かり易いかは別問題とすれば）．
In[30]:=

StringReplaceA早口言葉`桃, "桃" → "もも"E

Out[30]=

スモモもももももものうちもももスモモももものうち以前に使った組込み関数Unionで，文章の構成要素となるリスト「言葉のもと」を作っておけば，単語を作るようにRandomChoiceとStringJoinにより任意の長さの文章を作り出すことが出来ます．
In[31]:=

言葉のもと = UnionAひらがな, カタカナ, 記号E;In[32]:=

StringJoinARandomChoiceA言葉のもと, 30EE

Out[32]=ゅボゆプぽわャづペクゲュご．ぅナむュぷヘザデヂゎのゆウほチク

しかし，これでは文章には程遠いですね．そこで，文章はひらがなの塊とカタカナの塊と記号から構成されていると仮定しましょう．塊の長さ（1文字から5文字程度）もランダムに決める必要があります．文字数は整数（…, -2, -1, 0, 1, 2, …）なので，単- 30 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

語作りに使った組込み関数に似た命令の「RandomInteger」により「次の範囲から
整数を無作為に取り出せ」という指示をMathematicaに出すことが出来ます．次の例
は，-5 から5の整数（-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 ）から無作為にひとつ選ばれます．
In[33]:=

RandomInteger@8−5, 5<DOut[33]=

1

この組込み関数を使って「塊の長さ」を覚えさせておきましょう．まず，長さとしては1文字から5文字とし，RandomIntegerへの指示は{1,5}となります．塊の長さは評価するたびに変化する可能性（無作為に整数が選ばれるため）があるので，ショートカットやリンクに準ずる遅延的な定義（コロンとイコール）を使って定義します．
In[34]:=

塊の長さ := RandomInteger@81, 5<D

In[35]:=

塊の長さ

Out[35]=

3

In[36]:=

塊の長さ

Out[36]=2

定義した塊の長さを使って，ひらがなの塊も定義しましょう．基本的にはひらがなの単語を作ったときと同じですが，無作為に取り出す回数を「塊の長さ」とすることと，遅延的な定義（コロンとイコール）を使うこと点で異なります．同じようにカタカナの塊も定義しておきますが，記号については常に1文字になるように定義しておきます．実際に，ひらながの塊やカタカナの塊を評価すると，無作為な言葉の塊が出てくることを確認できます．
In[37]:=

ひらがなの塊 := StringJoinARandomChoiceAひらがな, 塊の長さEE

In[38]:=

カタカナの塊 := StringJoinARandomChoiceAカタカナ, 塊の長さEE

In[39]:=

記号の欠片 := StringJoinARandomChoiceA記号, 1EE

In[40]:=

ひらがなの塊Out[40]=ふきIn[41]:=

カタカナの塊Out[41]=ル- 31 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

さて，これらの塊を使って文章を作るのですが，ひらがな，カタカナ，記号をどのよ
うな割合いでどのような順番で組み合わせるかという問題が残っています．特に，普通の文章に含まれる記号の割合いは著しく低いですし，カタカナもひらがなよりは低いでしょう．これを反映させなければいけません．何度も使っているMathematicaの組込み関数「RandomChoice」では，選ばれる確率を指定することも出来ます．例えば，次の例では「言葉のもとからひとつ」を遅延的に定義していますが，ひらがなの塊が70%程度，カタカナの塊が20%程度，記号の欠片が10%程度の割合いで選択されるように指示しています．
In[42]:=

言葉のもとからひとつ :=RandomChoiceA

80.7, 0.2, 0.1< → 9ひらがなの塊, カタカナの塊, 記号の欠片=EIn[43]:=

言葉のもとからひとつ

Out[43]=

ゑ

文章にするには，この「言葉のもとからひとつ」をいくつも組み合わせることになります．そのためには「次の指示を指定された回数だけ繰り返せ」という意味の「Table」を使うことになります．この組込み関数は非常に便利なので，今後何度も使うことになります．例えば，言葉のもとからひとつを10回繰り返したい場合，次のように「{10}」という指示を出します．この数字を変えれば繰り返す回数を変化させることが可能です．
In[44]:=
Out[44]=

TableA言葉のもとからひとつ, 810<E

9」, てたりたみ, よるよ, にゅが, は, ）, ぢぃき, ，, で, オ=

文章にするには，全体をStringJoinで囲めば良いので，最終的に次のような命令でランダムな文章を作ることが出来るようになります．何度も評価を繰り返すと，普段の会話のような文章が表れるかも，しれません．．．
In[45]:=

StringJoinATableA言葉のもとからひとつ, 810<EE

Out[45]=

ルネポヅデフアャラコオんいとわぃヒスチぶおオクもつじぽなろひび【遅延的な定義の本質】Mathematicaでの「即時的な定義」と「遅延的な定義」の違い
は，ファイルマネージャにおける「コピー」と「ショートカット」の違いに近い，という話をしました．より正確に表現すると，イコール（=）だけを使った即時的な定義では，右辺の評価結果を覚えますが，コロンとイコール（:=）を使った遅延的な定義では，右辺の評価はせずに右辺をそのまま覚えます．従って，無作為に何を選択する組込み関数と即時的な定義を組み合わせても，毎回同じ結果しか表示されません
が，遅延的な定義を組み合わせれば，毎回違うランダムな結果が表示されることにな
ります．

- 32 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

小学校で習う漢字も追加しよう

やはり漢字がないと寂しいので，小学校の最初に習う漢字を追加しましょう．文部科学省のウェブサイトでは，各種の指導要領が公開されています．その中から小学校学
習指導要領の国語に関するところに掲載されている「学年別漢字配当表」から，第一学年のものを写したのが次の文字列です．
In[46]:=

小学校学習指導要領一学年漢字 ="一右雨円王音下火花貝学気九休玉金空月犬見五口校左三山子四糸字耳
七車手十出女小上森人水正生青夕石赤千川先早草足村大男竹中虫
町天田土二日入年白八百文木本名目立力林六";

ひらがなやカタカナなどは一語ずつのリストになっていましたので，この漢字についても一語ずつのリストに直す必要があります．手作業で行うことも可能です
が，Mathematicaの「Characters」という命令を使うことで，次のように簡単に1文字ずつに分割できます．この命令は「次の文字列を一語ずつの文字のリストに分解せよ」という意味なのは明らかでしょう．
In[47]:=
Out[47]=

小学校一学年 = CharactersA小学校学習指導要領一学年漢字E

9一, 右, 雨, 円, 王, 音, 下, 火, 花, 貝, 学, 気, 九, 休, 玉, 金,空, 月, 犬, 見, 五, 口, 校, 左, 三, 山, 子, 四, 糸, 字, 耳, 七,車, 手, 十, 出, 女, 小, 上, 森, 人, 水, 正, 生, 青, 夕, 石, 赤,
千, 川, 先, 早, 草, 足, 村, 大, 男, 竹, 中, 虫, 町, 天, 田, 土,
二, 日, 入, 年, 白, 八, 百, 文, 木, 本, 名, 目, 立, 力, 林, 六=

あとは先ほどと同様に「小学校一学年の塊」を遅延的な方法で定義しておきます．
In[48]:=

小学校一学年の塊 :=StringJoinARandomChoiceA小学校一学年, 塊の長さEE「言葉のもとからひとつ」の定義にも漢字を入れて定義し直しましょう．割合いは，ひらがなが40%，漢字が30%，カタカナが20%，記号が10%にしてみました．結果
を見ると，多少は文章らしくなってきたのではないでしょうか．
In[49]:=

言葉のもとからひとつ :=RandomChoiceA80.4, 0.3, 0.2, 0.1< →9ひらがなの塊, 小学校一学年の塊, カタカナの塊, 記号の欠片=E

In[50]:=

StringJoinATableA言葉のもとからひとつ, 810<EE

Out[50]=女空川正ほぇ名三小足ネ上夕タパぎゆよざわぃけいじっれ青水学川文章として意味のあるものになることは非常に稀ですが，漢字の塊だけを次のように20組程度作ると，中には意味のあるものが作られたり，意味がありそうな不思議な熟- 33 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

語になっていたりします．もしかすると，本当に猿もシェークスピアが書けてしまう
かもしれませんね．
In[51]:=Out[51]=

TableA小学校一学年の塊, 820<E

9学男, 口入学, 車生日, 木田早, 八, 先貝火,
気白, 見貝大, 草, 左校先川土, 村, 木白男九, 雨八空,
目, 十女目, 見正, 名水, 立見九王, 赤大見手, 校=

ランダム作文で洒落た短文を書いてもらおうü いつ，誰が，どうした？

キーボードを無作為に押していくことでシェークスピアを書くのは無謀だということがわかりました．ランダムな熟語を作るという試みとしては面白かったと思いますが，現実的な作文にはなっていませんでした．そこで，よりシンプルに短い文を作ることにしましょう．「いつ，誰が，どうした」というシンプルな作文です．まずは，それぞれの候補をリストで定義しておきます．
In[52]:=

いつ = 9"昨日の朝，", "昨日の昼間，", "昨日の夕方，","昨日の夜，", "今日の朝，", "今しがた，"=;In[53]:=

誰が = 9"私は", "あなたは", "先輩は", "後輩は", "知合いは"=;In[54]:=

どうした = 9"寝坊した．", "遅刻した．", "宝くじに当たった．","宝くじに外れた．", "ベッドから落ちた．", "ごはんを食べた．"=;

それぞれの候補の中から無作為に選択する命令は既に使ったRandomChoiceで行えます．前回使用したときとは異なり，取り出す要素の個数は1個なので，わざわざ「RandomChoice[いつ,1]」とMathematicaに指示を出す必要はありません．
In[55]:=

RandomChoice@いつD

Out[55]=

昨日の夜，文章を構成するには，残りも併せて3つの要素をそれぞれ無作為に選択すれば良いことがわかります．これを遅延的な定義で次のように覚えさせておきましょう．扱う部品が3つあるのでリストでまとめてあることに注意してください．遅延的な定義なので，評価するたびにランダムな文章が作られるようになります．
In[56]:=

いつ誰がどうしたリスト :=9RandomChoice@いつD, RandomChoiceA誰がE,
RandomChoiceAどうしたE=- 34 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[57]:=

いつ誰がどうしたリスト

Out[57]=9今日の朝，, あなたは, ごはんを食べた．=

In[58]:=

いつ誰がどうしたリスト

Out[58]=

9昨日の夜，, 知合いは, 宝くじに外れた．=

このままでは1つの文章（文字列）になっていないので，前回も使用した
StringJoinを使って結合することにしましょう．これも遅延的な定義を使って覚えさせておくことで，評価するたびにランダムに文章が作られるようになります．
In[59]:=

いつ誰がどうした := StringJoinAいつ誰がどうしたリストEIn[60]:=

いつ誰がどうしたOut[60]=

昨日の昼間，あなたはごはんを食べた．

In[61]:=

いつ誰がどうしたOut[61]=

今しがた，先輩は宝くじに外れた．

Mathematicaには様々な省略表記があり，StringJoinという指示は「<>」（小なり記
号，大なり記号）を使っても同じ意味になります．従って，先ほど定義した「いつ誰がどうした」という名前のショートカット（後述しますが，本来は変数ないしは関数と呼ぶ）は次のように定義することも可能です．
In[62]:=

いつ誰がどうした := RandomChoice@いつD <> RandomChoiceA誰がE <>RandomChoiceAどうしたE

In[63]:=

いつ誰がどうしたOut[63]=

今しがた，私はベッドから落ちた．

【マルチパラダイム】このように，Mathematicaでは同じ意味の指示を出すのに複数の具体的な命令が存在します．書き方によって，Mathematicaが指示を実行するために必要な時間が大きく変化するため，科学技術計算などの速度が求められる場合には注意
深く記述する必要があります．一方，これまでに取り組んできた内容のように高速に計算される必要がない場合は，ユーザが理解しやすい方法で柔軟に書くことが出来るという大きなメリットになります．

- 35 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

ü いつ，誰が，何を，どうして，どうなった？

いつ，誰が，どうした，では短すぎて面白みが少ないかもしれません．もっと長い文章が生成されるように，いつ，誰が，何を，どうして，どうなった，という構成要素に拡張しましょう．まずは，先ほどと同じように各グループ毎に名前をつけて定義しておきます．各グループの要素が変化することはありませんので，即時的なもの（コピー）で大丈夫です．
In[64]:=

いつ = 9"昨日の朝，", "昨日の昼間，", "昨日の夕方，","昨日の夜，", "今日の朝，", "今しがた，"=;In[65]:=

誰が = 9"私は", "あなたは", "先輩は", "後輩は", "知合いは"=;In[66]:=

何を = 9"パソコンを", "財布を", "ケーキを", "コーヒーを","歯磨き粉を", "かばんを"=;In[67]:=

どうして = 9"壊して", "失くして", "食べて", "こぼして","搾って", "背負って"=;In[68]:=

どうなった = 9"非常に困った．", "交番に届け出た．","幸せだった．", "火傷した．", "歯磨きをした．","買い物に行った．"=;

簡単のため，冗長な方法で「いつ誰が何をどうしてどうなった」を遅延的に定義しま
しょう．前回と同じくRandomChoiceとStringJoinを使っています．繰り返しにな
りますが，毎回，異なる言葉が無作為に選択されないといけませんから，遅延的な定義にする必要があることに注意してください．
In[69]:=

いつ誰が何をどうしてどうなったリスト :=9RandomChoice@いつD, RandomChoiceA誰がE,
RandomChoiceA何をE, RandomChoiceAどうしてE,
RandomChoiceAどうなったE=

In[70]:=

いつ誰が何をどうしてどうなった :=StringJoinAいつ誰が何をどうしてどうなったリストE

実際に「いつ誰が何をどうしてどうなった」を評価すると，次のように面白い文章が毎回ランダムに生成されることがわかります．
In[71]:=

いつ誰が何をどうしてどうなったOut[71]=

昨日の昼間，あなたはパソコンを背負って交番に届け出た．

- 36 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[72]:=

いつ誰が何をどうしてどうなったOut[72]=

昨日の夜，あなたはかばんを壊して火傷した．

言葉を選んでくるグループが5個なのでRandomChoiceを5 回記述して，それをStringJoinでまとめるという定義を行っていますが，これが10個になれば10回記述する必要が出てきます．Mathematicaは計算機なので面倒とは思わないかもしれません
が，私たちは人間ですから同じことを何度もするのは面倒です．そのため，このような同じ操作を繰り返すことを簡単に指示できる仕組みが準備されています．まずは「いつ誰が何をどうしてどうなったリスト」の定義を確認して，共通部分がどこにあるのか，何を冗長に何度も繰り返しているかを確認しましょう．
? いつ誰が何をどうしてどうなったリスト

Global`いつ誰が何をどうしてどうなったリスト
いつ誰が何をどうしてどうなったリスト :=9RandomChoice@いつD, RandomChoiceA誰がE, RandomChoiceA何をE,
RandomChoiceAどうしてE, RandomChoiceAどうなったE=

赤字で強調表示している部分が共通している部分です．いつ，誰が，何を，どうして，どうなった，のそれぞれに対してRandomChoiceの指示を出しています．これと同じ指示を組込み関数「Map」を使うと簡単に書くことが出来ます．この命令の意味
は「次のリストのそれぞれに対して同じ命令を実行せよ」です．この関数を使うと「いつ誰が何をどうしてどうなったリスト」は次のように書き直すことが出来ます．
In[73]:=
Out[73]=MapARandomChoice, 9いつ, 誰が, 何を, どうして, どうなった=E

9昨日の朝，, 先輩は, ケーキを, 搾って, 交番に届け出た．=

Map@RandomChoice, 8いつ,誰が,何を<D

どんな操作を実行させたいか

指示の対象を記したリスト

リストの一括処理：いくつものリストに同じ操作を実行

この命令を使って「いつ誰が何をどうしてどうなった」を再度定義しなおすと次のように短い表現になります．わかりやすくなったはずですが，新しい命令であるMapを理解できていないと難しく感じるかもしれません．この命令は非常に重要で，今後も何度も出てきます．何度も読み返して便利さを確認してください．

- 37 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[74]:=

いつ誰が何をどうしてどうなった :=StringJoinAMapARandomChoice,

9いつ, 誰が, 何を, どうして, どうなった=EE

In[75]:=

いつ誰が何をどうしてどうなったOut[75]=

昨日の夕方，あなたはコーヒーを搾って幸せだった．

【Mapによるリスト処理】MathematicaはLispの流れを汲む言語と考えるのが自然で，リストで表現されたデータに対する一括処理に秀でています．ここでは単純に命令を短くする目的だけにMapを使用していますが，後の章では計算速度を速くするためにも用います．前の方の章で何度も断っていますが，Mathematicaを使う上でリストは非常に重要な概念ですので，この一括操作も非常に重要な概念になります．始めにリストありき，という考え方を身につけることはMathematicaを覚える近道です．
ü 「いつ誰がどうした？」で時制もランダムにしたい

前項まで取り上げた作文では，時制や助詞も含めてある言葉から無作為に選択していました．これでは，時制や助詞の分だけ全てを想定した言葉を事前にリストで定義しておかなければいけません．もっと手軽に時制を扱える方法がないかを考えてみたいと思います．まずは，時制に関係のない部分だけをMathematicaに覚えておいてもらいましょう．
In[76]:=

誰が = 9"私", "彼", "彼女", "友達"=;

In[77]:=

助詞 = 9"が", "は", "も"=;In[78]:=

どうした = 9"勉強", "食事", "カラオケ", "寝坊"=;

次に，時制の部分が除かれた無作為な文章を生成する「誰がどうした」を定義しましょう．毎回異なる文章を生成させるには，遅延的な定義になることに注意してください．
In[79]:=

誰がどうした :=StringJoinAMapARandomChoice, 9誰が, 助詞, どうした=EE

実際に「誰がどうした」をMathematicaに問い合わせることで，時制と述語が不足している文章がランダムに返ってきます．あとは，この文章にランダムに時制と述語を付けられれば何も問題ありませんが，時制と述語は「昨日，した」と「明日，する」とペアになるので，各々を勝手に述語を決める訳にもいきません．どうすれば良いでしょうか．
誰がどうした
彼は食事- 38 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

誰がどうした
私が寝坊

まずは，その出来事が昨日のことであるかを判定する命令「昨日のこと？」を作りましょう（はてなマークは全角にしてください）．Mathematicaでは「True」という言葉で「その通り！」を意味する「真」を，「False」で「そうじゃない！」を意味する「偽」を表します．従って，真偽を無作為に選択する「昨日のこと？」は次のような遅延的な定義になります．何度も出てきているRandomChoiceを使っていることに注意してください．
In[80]:=

昨日のこと？ := RandomChoice@8True, False<D

実際にMathematicaへ問い合わせてみると，評価するたびに真と偽が無作為に報告されるのがわかると思います．
昨日のこと？
False
昨日のこと？
True

不足している時制と述語のペアを文章に追加するには，「昨日のこと？」が真である
か偽であるかという状況に応じてMathematicaがすべきことを変化させる必要があります．これには，「次の条件が満たされたら，指定の命令を実行せよ」という意味の「If」を使います．昨日のことであれば「昨日，」と「した．」を追加し，そうでなければ「明日，」と「する．」を追加しています．
In[81]:=

IfA昨日のこと？, StringJoinA"昨日，", 誰がどうした, "した．"E,
StringJoinA"明日，", 誰がどうした, "する．"EEOut[81]=

昨日，私も食事した．

If@条件, 成立の場合, 不成立の場合D
例：昨日のことかを確認

例：昨日の時制

例：明日の時制

条件分岐：内容によって命令を変える

最終的に，時制も無作為に選択される「いつ誰がどうした」は次のように遅延的な定義で表現されることになります．実際に評価してみると，いくつか面白い文章が作られることがわかると思います．

- 39 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[82]:=

いつ誰がどうした :=IfA昨日のこと？, StringJoinA"昨日，", 誰がどうした, "した．"E,
StringJoinA"明日，", 誰がどうした, "する．"EE
いつ誰がどうした
明日，彼が寝坊する．
いつ誰がどうした
昨日，友達が寝坊した．

【TrueとFalse】Mathematicaでは条件が満たされていることを「True」で表し，条件が満たされていないことを「False」で表します．いわゆる真偽値と呼ばれるもの
で，今回のような条件分岐の他，以前にも出てきたような判定問題（リストに指定した要素が含まれているか）などでのMathematicaからの報告にも使われます．今後も頻繁に出てきますので，良く覚えておいてください．
ü 「いつ誰が何をどうしてどうなった？」で時制もランダムにしたい

前項よりもバリエーションを増やして文章も長くすることを考えましょう．まずは，前項と同じように時制を除いた「誰が何をどうしてどうなった」をこれまでと同じように定義しましょう．
In[83]:=

誰が = 9"私", "彼", "彼女", "友達"=;In[84]:=

助詞 = 9"が", "は", "も"=;In[85]:=

何を = 9"数学を", "運動会を", "十八番を", "携帯電話を", "卵を"=;In[86]:=

どうして = 9"勉強して", "食べて", "歌って", "寝過ごして","壊して", "落として"=;In[87]:=

何が = 9"成績を", "調子を", "懐を", "雰囲気を", "気分を"=;In[88]:=

どうなった = 9"良く", "悪く", "寂しく", "悲しく"=;In[89]:=

誰が何をどうしてどうなった :=StringJoinAMapARandomChoice,

9誰が, 助詞, 何を, どうして, 何が, どうなった=EE

この時点で「誰が何をどうしてどうなった」をMathematicaに評価させると，これまでと同じように，時制の部分を除いた文章がランダムに返ってきます．

- 40 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[90]:=

誰が何をどうしてどうなったOut[90]=

彼女も携帯電話を寝過ごして調子を悪く

時制と述語を加えて，私達としては「明日，（本文）する．」とか「昨日，（本文）した．」という文章にしたいですね．そこで，このような時制と述語のペアをリストで定義しておきましょう．リストには「時制」という名前を付けてMathematicaに覚えておいてもらいます．
In[91]:=

時制 = 9"昔，（本文）したものだ．", "昨日，（本文）した．","今日，（本文）したところだ．", "明日，（本文）する．","将来，（本文）したい．"=;

いつの文章であるかをランダムにしたいので，時制をランダムに選択するように「時制の選択」も定義しておきます．そうすると，次のように時制と述語のペアが無作為に返ってくることがわかると思います．遅延的な定義を使うのにも慣れてきたでしょうか．
In[92]:=

時制の選択 := RandomChoiceA時制E

In[93]:=

時制の選択

Out[93]=

今日，（本文）したところだ．

In[94]:=

時制の選択

Out[94]=

明日，（本文）する．

「（本文）」の部分が例えば「私は数学を勉強して成績を良く」になれば，作りたかった文章に近づきます．そこで，時制がランダムに選択されるようにしたままで，（本文）を置き換えるようMathematicaに指示を出してみます．次のように，以前に利用した命令StringReplaceを使うことで，簡単に置き換えは行えます．
In[95]:=

StringReplaceA時制の選択,"（本文）" → "私は数学を勉強して成績を良く"E

Out[95]=

将来，私は数学を勉強して成績を良くしたい．

このままでは，本文のところがランダムに選択されないので，置き換え先をランダムに本文を生成する「誰が何をどうしてどうなった」に置き換えてみます．すると，次のように時制と本文が無作為に選択された文章が作られるようになります．

- 41 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[96]:=

StringReplaceA時制の選択,"（本文）" → 誰が何をどうしてどうなったE

Out[96]=

明日，友達は携帯電話を落として気分を悪くする．

あとは遅延的な定義で「いつ誰が何をどうしてどうなった」を次のように定義することで，時制も本文も無作為に選択された文章をつくり出すことが出来ます．
In[97]:=

いつ誰が何をどうしてどうなった :=StringReplaceA時制の選択,"（本文）" → 誰が何をどうしてどうなったE

In[98]:=

いつ誰が何をどうしてどうなったOut[98]=

今日，友達は運動会を寝過ごして成績を悪くしたところだ．

文豪の作品を小学生になって読んでみようü 作品に使われている文字を調べてみよう

今回の目的は文豪の作品を調べることです．例題として夏目漱石の「吾輩は猫である」から最初の段落を取り上げたいと思います．自分で試してみる際には，青空文庫（http://www.aozora.gr.jp）などからお気に入りの作品を探してみることをお薦めします．まずは，文章を分かり易い名前でMathematicaに覚えさせましょう．このような文章の定義の際などは，最後にセミコロン（;）を付けておくと復唱（結果出力）がない
のでスッキリするので，忘れずに付けておきましょう．

- 42 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[99]:=

吾輩は猫である ="吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だ
けは記憶している。吾輩はここで始めて人間というものを見た。
しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段
恐しいとも思わなかった。ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後猫にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せ
ぽくて実に弱った。これが人間の飲む煙草というものである事はようやくこの頃知った。";

この文章で使われている文字一覧は，既に使ったことのあるCharactersとUnionを使うことで，次のようにMathematicaに調べさせることが出来ます．直前の出力を表す
パーセント記号（%）も使って，使われている文字の種類（今回の場合，文字一覧のリストに含まれる要素の個数）がいくつあるかも調べさせています．
In[100]:=Out[100]=

使用文字の一覧 = UnionACharactersA吾輩は猫であるEE9。, 々, あ, い, う, え, か, が, き, く, け, げ, こ, さ, し, じ,ず, せ, そ, た, だ, ち, っ, つ, て, で, と, ど, な, に, ぬ, の,は, ば, ぶ, ぷ, べ, ぽ, ま, み, む, め, も, や, ゆ, よ, ら, り,る, れ, ろ, わ, を, ん, ス, ニ, フ, ャ, ワ, ー, 一, 上, 中,
事, 人, 今, 会, 何, 出, 別, 前, 名, 吹, 吾, 咽, 妙, 始, 実,
少, 度, 弱, 当, 彼, 後, 思, 恐, 悪, 感, 憶, 我, 所, 持, 捕,掌, 族, 時, 暗, 書, 残, 段, 毛, 泣, 無, 煙, 煮, 片, 猫, 獰,生, 番, 真, 知, 種, 穴, 突, 第, 缶, 考, 聞, 草, 落, 薄, 薬,
装, 見, 記, 話, 起, 載, 輩, 輪, 逢, 間, 頃, 顔, 食, 飲, 飾=

In[101]:=

Length@%DOut[101]=

138

文章の文字数は，次のように448文字ですから，かなり同じ文字（そのほとんどは平仮
名 と 思 い ま す ） が 繰 り 返 し て 使 わ れ て い る こ と が わ か り ま す ．L e n g t hと- 43 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

StringLengthの使い分けをきちんと出来るか大丈夫でしょうか．Lengthはリストに含まれる要素の個数で，StringLengthは文字列の文字の長さです．
In[102]:=StringLengthA吾輩は猫であるE

Out[102]=448【青空文庫】本文中の「吾輩は猫である」は，夏目漱石全集を底本とする青空文庫の
XHTMLファイルから引用しています．引用にあたり，括弧書きのルビは削除してあります．この場をかりて，青空文庫のような素晴らしい取り組みをされている方々に感謝します．貴重な電子データをありがとうございます！
ü 作品に使われている文字の種類を調べてみよう

もっと詳しく調べていくことにしましょう．まずは文字を種類ごとにリストとして定義しましょう．ひらがなとカタカナは以前の通り，次のように定義します（結果を確認する必要がない場合はセミコロンを付けましょう）．
In[103]:=

ひらがな = CharacterRangeA"ぁ", "ん"E;

In[104]:=

カタカナ = CharacterRangeA"ァ", "ヴ"E;

記号は非常に多くの種類があるので，いくつか主要なものだけを含めて「漢字以外」というグループも定義しておきます．ここでは全角スペース（ ）からカタカナの伸ばす記号（ー）までとして定義しています．どのような内容が含まれるかを確認したい場合は，次のようにセミコロンを付けずに実行しましょう．文字が表示されていないところは，機種依存文字であったり，もともと文字が未定義になっている区画になります．

- 44 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[105]:=Out[105]=

漢字以外 = CharacterRange@"
9", "ー"D】, 〒, 〓, 〔, 〕, 〖, 〗, 〘, 〙, P, T, ～, 〝, 〞, 〟, 〠,〡, 〢, 〣, 〤, 〥, 〦, 〧, 〨, 〩, , , , , , , 〰, 〱,〲, 〳, 〴, 〵, 〶, 〷, , , , , , , , , , ぁ, あ, ぃ,い, ぅ, う, ぇ, え, ぉ, お, か, が, き, ぎ, く, ぐ, け, げ,
こ, ご, さ, ざ, し, じ, す, ず, せ, ぜ, そ, ぞ, た, だ, ち,
ぢ, っ, つ, づ, て, で, と, ど, な, に, ぬ, ね, の, は, ば,ぱ, ひ, び, ぴ, ふ, ぶ, ぷ, へ, べ, ぺ, ほ, ぼ, ぽ, ま, み,む, め, も, ゃ, や, ゅ, ゆ, ょ, よ, ら, り, る, れ, ろ, ゎ,
わ, ゐ, ゑ, を, ん, ゔ, , , , , , , ゛, ゜, ゝ, ゞ, ,, ァ, ア, ィ, イ, ゥ, ウ, ェ, エ, ォ, オ, カ, ガ, キ, ギ, ク,
グ, ケ, ゲ, コ, ゴ, サ, ザ, シ, ジ, ス, ズ, セ, ゼ, ソ, ゾ, タ,ダ, チ, ヂ, ッ, ツ, ヅ, テ, デ, ト, ド, ナ, ニ, ヌ, ネ, ノ,
ハ, バ, パ, ヒ, ビ, ピ, フ, ブ, プ, ヘ, ベ, ペ, ホ, ボ, ポ,
マ, ミ, ム, メ, モ, ャ, ヤ, ュ, ユ, ョ, ヨ, ラ, リ, ル, レ,, 、, 。, 〃, 〄, 々, 〆, 〇, 〈, 〉, 《, 》, 「, 」, 『, 』, 【,ロ, ヮ, ワ, ヰ, ヱ, ヲ, ン, ヴ, ヵ, ヶ, ヷ, ヸ, ヹ, ヺ, ・, ー=グループについての章で使った，Intersection，Complement，Unionなどの組込み関数を使うことで，文章で使われている文字を種類ごとに分類することが出来ます．復讐しておくと，共通部分がIntersectionで，補集合（指定したもの以外の集合）がComplementで，和集合がUnionです．
従って，吾輩は猫であるの冒頭の一段落に含まれるひらがなの種類は次のように命令
します．Lengthと%を使うことで，使われているひらがなの種類が52個であることもわかります．
In[106]:=Out[106]=

IntersectionA使用文字の一覧, ひらがなE

9あ, い, う, え, か, が, き, く, け, げ, こ, さ,し, じ, ず, せ, そ, た, だ, ち, っ, つ, て, で, と,ど, な, に, ぬ, の, は, ば, ぶ, ぷ, べ, ぽ, ま, み,む, め, も, や, ゆ, よ, ら, り, る, れ, ろ, わ, を, ん=In[107]:=

Length@%DOut[107]=52

カタカナについても同様です．

- 45 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[108]:=Out[108]=

IntersectionA使用文字の一覧, カタカナE
8ス, ニ, フ, ャ, ワ<

使われている漢字を調べるには，先ほど準備した漢字以外の補集合（漢字以外に含まれていない要素の集合）をMathematicaに調べてもらいます．漢字以外には，ひらがなとカタカナ，いくつかの記号が含まれているので，次のように文章に使われている漢字だけを含むリストが得られます．冒頭の段落だけなのに，78種類もの漢字が使われているとは驚きですね．
In[109]:=Out[109]=

ComplementA使用文字の一覧, 漢字以外E

9一, 上, 中, 事, 人, 今, 会, 何, 出, 別, 前, 名, 吹, 吾, 咽, 妙,
始, 実, 少, 度, 弱, 当, 彼, 後, 思, 恐, 悪, 感, 憶, 我, 所, 持,捕, 掌, 族, 時, 暗, 書, 残, 段, 毛, 泣, 無, 煙, 煮, 片, 猫, 獰,生, 番, 真, 知, 種, 穴, 突, 第, 缶, 考, 聞, 草, 落, 薄, 薬,
装, 見, 記, 話, 起, 載, 輩, 輪, 逢, 間, 頃, 顔, 食, 飲, 飾=

In[110]:=Length@%DOut[110]=78

記号を調べさせるときの命令は少し複雑になります．まず，ひらがなとカタカナと記号だけを使われている文字一覧から抜き出してから，ひらがなとカタカナを取り除きます．IntersectionとComplementを組み合わしているので少し難しいかもしれま
せん．
In[111]:=

ComplementAIntersectionA使用文字の一覧, 漢字以外E,
ひらがな, カタカナE

Out[111]=8。, 々, ー<「Complement」という命令は正確には「最初のリストから，二番目以降のリストに含まれている要素を全て取り除け」という意味になるので，共通部分を抜き出しているところを分解してみれば難しくないことがわかると思います．
In[112]:=

In[113]:=

使用文字の一覧のうち記号とひらがなとカタカナ =IntersectionA使用文字の一覧, 漢字以外E;
ComplementA使用文字の一覧のうち記号とひらがなとカタカナ,
ひらがな, カタカナE

Out[113]=8。, 々, ー<- 46 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

ü 作品を小学生のつもりになって読んでみよう

以前に小学校第一学年の漢字リストを作ったように，文部科学省のウェブサイトの小学校学習指導要領の国語に関するところに掲載されている「学年別漢字配当表」から，各学年に配当されている漢字のリストを作っておきます．
In[114]:=

小学校1学年 =CharactersA"一右雨円王音下火花貝学気九休玉金空月犬見五口校左三山子四糸字耳七車手十出女小上森人水正生青夕石赤千川先早草足村大男
竹中虫町天田土二日入年白八百文木本名目立力林六"E;In[115]:=

小学校2学年 =CharactersA"引羽雲園遠何科夏家歌画回会海絵外角楽活間丸岩顔汽記帰弓牛魚京
強教近兄形計元言原戸古午後語工公広交光考行高黄合谷国黒今才細作算止市矢姉思紙寺自時室社弱首秋週春書少場色食心
新親図数西声星晴切雪船線前組走多太体台地池知茶昼長鳥朝
直通弟店点電刀冬当東答頭同道読内南肉馬売買麦半番父風分
聞米歩母方北毎妹万明鳴毛門夜野友用曜来里理話"E;In[116]:=

小学校3学年 =CharactersA"悪安暗医委意育員院飲運泳駅央横屋温化荷界開階寒感漢館岸起期客究急級宮球去橋業曲局銀区苦具君係軽血決研県庫湖向幸港号
根祭皿仕死使始指歯詩次事持式実写者主守取酒受州拾終習集
住重宿所暑助昭消商章勝乗植申身神真深進世整昔全相送想息
速族他打対待代第題炭短談着注柱丁帳調追定庭笛鉄転都度投
豆島湯登等動童農波配倍箱畑発反坂板皮悲美鼻筆氷表秒病品
負部服福物平返勉放味命面問役薬由油有遊予羊洋葉陽様落流
旅両緑礼列練路和"E;- 47 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[117]:=

小学校4学年 =CharactersA"愛案以衣位囲胃印英栄塩億加果貨課芽改械害街各覚完官管関観願希
季紀喜旗器機議求泣救給挙漁共協鏡競極訓軍郡径型景芸欠結建健験固功好候航康告差菜最材昨札刷殺察参産散残士氏史司
試児治辞失借種周祝順初松笑唱焼象照賞臣信成省清静席積折
節説浅戦選然争倉巣束側続卒孫帯隊達単置仲貯兆腸低底停的
典伝徒努灯堂働特得毒熱念敗梅博飯飛費必票標不夫付府副粉
兵別辺変便包法望牧末満未脈民無約勇要養浴利陸良料量輪類
令冷例歴連老労録"E;In[118]:=

小学校5学年 =CharactersA"圧移因永営衛易益液演応往桜恩可仮価河過賀快解格確額刊幹慣眼基
寄規技義逆久旧居許境均禁句群経潔件券険検限現減故個護効
厚耕鉱構興講混査再災妻採際在財罪雑酸賛支志枝師資飼示似
識質舎謝授修述術準序招承証条状常情織職制性政勢精製税責績接設舌絶銭祖素総造像増則測属率損退貸態団断築張提程適
敵統銅導徳独任燃能破犯判版比肥非備俵評貧布婦富武復複仏編弁保墓報豊防貿暴務夢迷綿輸余預容略留領"E;In[119]:=

小学校6学年 =CharactersA"異遺域宇映延沿我灰拡革閣割株干巻看簡危机揮貴疑吸供胸郷勤筋系
敬警劇激穴絹権憲源厳己呼誤后孝皇紅降鋼刻穀骨困砂座済裁
策冊蚕至私姿視詞誌磁射捨尺若樹収宗就衆従縦縮熟純処署諸除将傷障城蒸針仁垂推寸盛聖誠宣専泉洗染善奏窓創装層操蔵
臓存尊宅担探誕段暖値宙忠著庁頂潮賃痛展討党糖届難乳認納
脳派拝背肺俳班晩否批秘腹奮並陛閉片補暮宝訪亡忘棒枚幕密盟模訳郵優幼欲翌乱卵覧裏律臨朗論"E;

面倒なので，小学校の各学年に配当された全ての漢字を含むリスト「小学校配当漢字」も定義しておきます．ここでは「複数のリストをひとつのリストにまとめなさい」という意味を持つ「Join」という命令を使っていますが，Unionでも同じ結果に
In[120]:=

小学校配当漢字 = JoinA小学校1学年, 小学校2学年, 小学校3学年,
小学校4学年, 小学校5学年, 小学校6学年E;

前回に使った「使用文字の一覧」と「漢字以外」を組み合わせることで，次のように
小学校配当漢字に含まれない漢字のみを抜き出すことが出来ます（これを未配当漢字として定義しておきましょう）．そんなに難しそうな漢字を含んでいるようには見え- 48 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

ませんし，わずか一段落ですが，21種類もの小学校に配当されていない漢字を含んでいることがわかります．
In[121]:=Out[121]=

未配当漢字 = ComplementA使用文字の一覧, 漢字以外, 小学校配当漢字E
9吹, 吾, 咽, 妙, 彼, 恐, 憶, 捕, 掌,

煙, 煮, 猫, 獰, 突, 缶, 薄, 載, 輩, 逢, 頃, 飾=In[122]:=

Length@%DOut[122]=

21

早口言葉のところで何度も使ったStringReplaceを使うと，未配当漢字を マークなどに置き換えることで，小学生になった気分で作品を読むことが出来ます．次の例は実際に「猫」という文字を「 」に置き換えてみたものです．出力された作品中で「猫」が「 」に変わっているのがわかると思います．
In[123]:=
Out[123]=

StringReplaceA吾輩は猫である, "猫" → " "E
吾輩は である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。
何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番獰悪な種族であったそうだ。この書生というのは時々我々を捕えて煮て食うという話である。しかしその当時は何という考もなかったから別段恐しいとも思わなかった。
ただ彼の掌に載せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。掌の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時妙なものだと思った感じが今でも残っている。第一毛をもって装飾されべきはずの顔がつるつるしてまるで薬缶だ。その後 にもだいぶ逢ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに突起している。そうしてその穴の中から時々ぷうぷうと煙を吹く。どうも咽せぽくて実に弱った。これが人間の飲む煙草というものである事
はようやくこの頃知った。

この作業を全ての未配当漢字に対して繰り返せば，確かに小学生の気持ちになって作品を読むことは出来ます．しかしながら，余りにも冗長で計算機のパワーを，即ちMathematicaのパワーを使っていません．冗長な作業はMathematicaに任せることが重要です．
Mathematicaにおける文字の置き換え規則には，「リストの中のどれか」という意味を持つ「Alternatives」という命令が使えます．従って，次のような置き換え規則を使うことで，未配当漢字の全てを「 」に置き換えることが出来ます．当り前のこと- 49 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

かもしれませんが，小学生に「吾輩は猫である」は少し難しいかもしれないことがわ
かります．
In[124]:=Out[124]=

StringReplaceA吾輩は猫である, AlternativesA未配当漢字E → " "Eは である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも 暗いじめじめした所でニャーニャー泣いていた事だけは記 している。 はここで始めて人間というものを見た。しかもあとで聞くとそれは書生という人間中で一番 悪な種族であったそうだ。この書生というのは時々我々を えて て食うという話である。しかしその当時は何という考もなかったから別段 しいとも思わなかった。ただ のに せられてスーと持ち上げられた時何だかフワフワした感じがあったばかりである。 の上で少し落ちついて書生の顔を見たのがいわゆる人間というものの見始であろう。この時 なものだと思った感じが今でも残っている。第一毛をもって装 されべきはずの顔がつるつるしてまるで薬 だ。その後 にもだいぶ ったがこんな片輪には一度も出会わした事がない。のみならず顔の真中があまりに 起している。
そうしてその穴の中から時々ぷうぷうと を く。どうも せぽくて実に弱った。これが人間の飲む 草というものである事はようやくこの知った。

ü 学年別配当漢字を使って細かく調べてみよう

この作品をもう少し詳しく調べてみることにしましょう．Mathematicaに調べさせるのに必要な組込み関数は既に使ったものばかりです．文字列の長さを調べさせる
StringLength，該当する文字の個数を調べさせるStringCount，リストの要素のどれかに該当という意味を持つAlternativesです．まずは，対象の文章の長さを確認しておきましょう．
In[125]:=

文章の長さ = StringLengthA吾輩は猫であるE

Out[125]=448

小学校の各学年に配当されている漢字の個数を確認していきましょう．StringCountとAlternativesで使われている漢字の個数を求められます．各
学年ごとに6回繰り返すことで，それぞれの配当漢字の個数がわかります．
In[126]:=

StringCountA吾輩は猫である, AlternativesA小学校1学年EE

Out[126]=

23

In[127]:=

StringCountA吾輩は猫である, AlternativesA小学校2学年EE

Out[127]=36- 50 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[128]:=StringCountA吾輩は猫である, AlternativesA小学校3学年EE

Out[128]=

20

In[129]:=StringCountA吾輩は猫である, AlternativesA小学校4学年EE

Out[129]=

6

In[130]:=StringCountA吾輩は猫である, AlternativesA小学校5学年EE

Out[130]=0In[131]:=

StringCountA吾輩は猫である, AlternativesA小学校6学年EE

Out[131]=5

文字が赤くなっていますが，この赤字で強調表示している部分は，それぞれの命令に共通している部分です．変化しているのは学年別の配当漢字を覚えさせたリストの名前だけです．このように共通する部分が多い場合，以前にも出てきましたが．これと同じ指示を組込み関数「Map」を使うと簡単に書くことが出来ます．この命令の意味
は「次のリストのそれぞれに対して同じ命令を実行せよ」です．
今回の場合，以前に比べて共通する部分が多いので，次のように少し複雑になります．赤い文字の部分は，個別に命令した場合に共通していた部分を表しています．共通しなかった部分が「シャープ（#）」になり，最後に「アンパサンド（&）」が付け加わっているのが変更部分です．以前のMapの例では，#と&が省略されていたのですが，Mapを使うときは基本的に，共通しない部分を#に，共通する部分の最後に&を付
け加えなければいけません．
In[132]:=

MapAStringCountA吾輩は猫である, Alternatives@ DE &,9小学校1学年, 小学校2学年, 小学校3学年, 小学校4学年,
小学校5学年, 小学校6学年=E

Out[132]=

823, 36, 20, 6, 0, 5<

Map@StringCount@文章,Alternatives@ DD&, 8学年1,学年2<D

どんな操作か

共通部分は ，最後に&指示の対象を記したリスト

リストの一括処理：いくつものリストに同じ操作を実行

ひらがなとカタカナの個数も同時に調べるには，次のように，ひらがなとカタカナも追加するだけで，300個と9個ということがわかります．

- 51 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[133]:=

MapAStringCountA吾輩は猫である, Alternatives@ DE &,9小学校1学年, 小学校2学年, 小学校3学年, 小学校4学年,
小学校5学年, 小学校6学年, ひらがな, カタカナ=E

Out[133]=

823, 36, 20, 6, 0, 5, 300, 9<

In[134]:=% ë 文章の長さ ∗ 100.0Out[134]=85.13393, 8.03571, 4.46429,
1.33929, 0, 1.11607, 66.9643, 2.00893<

次章で扱いますが，求めた文字の個数を「文章の長さ」で割って100倍すれば使用率がパーセントで求められます．わり算は「スラッシュ（/）」で，かけ算は「アスタリス
ク （*）」で命令します．これによれば，小学校1学年の配当漢字は5%，2学年が8%，3学年が4%，4学年が1%，5学年が0%，6学年が1%，ひらがなが67%，カタカナが2%使われていることがわかります．

- 52 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

数と式：数に隠された秘密を少し覗いてみよう
数と式，計算をする上で基本となる仕組みを学びましょう．

四則演算で面白い数を見付けてみよう
これまでMathematicaにリストや文字列などの数学とはかけ離れた内容を扱わせてきま
したが，Mathematicaには難しい計算をさせることも出来ます．ここでは，基本的な四則演算（足す，引く，掛ける，割る）について取り上げていきたいと思います．
ü 足し算（+）で足して10になる数を探そう

Mathematicaに足し算を行わせるには，算数や数学でも使われるプラス記号「+」を使います．教科書などにあるように，そのまま命令として入力すれば，Mathematicaは計算結果を教えてくれます．例えば，単純な「1+2+3+4」もそのまま入力するだけで十分です．答えが「10」であると教えてくれます．
In[1]:=

1+2+3+4Out[1]=

10

これまで組込み関数と呼ばれるMathematicaへ指示するための命令をいくつも習ってきました．実は，足し算にもプラス記号とは別に，「次の数を足し合わせよ」という意味を持つ「Plus」という命令も用意されています．例えば，この命令を使って先ほどの単純な「1+2+3+4」を計算するには次のようにします．もちろん，答えは「10」になります．
In[2]:=

Plus@1, 2, 3, 4DOut[2]=

10

では，日本で余り見ないタイプの問題「3+Ó=10」を考えましょう．日常的には良くある状況を表していて，例えば，パーティの参加者は10人なのにコップが3人分しかな
い，あといくつコップを用意すれば良いでしょうか，という問題になります．
普通の考え方とは違いますが，用意しなければならないコップの数を直接求めるのではなく，新たにいくつコップを追加すると10人分になるのかを考えましょう．そこで，追加するコップの個数として，5個，6個，7個，8個，9個，10個の場合を考えます．分かりやくするために，追加する可能性のあるコップの個数をMathematicaに覚えさせておきます．
In[3]:=
Out[3]=

追加するコップの個数 = 85, 6, 7, 8, 9, 10<85, 6, 7, 8, 9, 10<- 53 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

問題は，既にある3個のコップに加えると10個になるコップの個数ですから，この数のそれぞれに3を加えて10になるかを確認すれば良いですね．プラス記号「+」を使って確認しようとすると，6回も足し算を命令する必要があります．非常に面倒ですね．Mathematicaでは面倒なことをしなくても良いように，もっと便利な方法を用意しています．それは．．．
『リストに足し算を行ってしまう』
です．Mathematicaでは「数とリストの足し算」を，「リストの各要素ごとに同じ足し算をしたいのだろう」と解釈してくれます．従って，次のように単純に3をリストに加えることで一度に全ての足し算を指示することが出来ます．
In[4]:=
Out[4]=

3 + 追加するコップの個数

88, 9, 10, 11, 12, 13<

3+81,2,3,4,5< ⇒ 83+1,3+2,3+3,3+4,3+5<
各要素との四則演算に展開される

リストと四則演算

リストと四則演算：各要素に対しての同じ四則演算が行われる

実 際 に は 次 の よ う に ， 以 前 に 出 て き たT a b l e F o r mを オ プ シ ョ ン （ 追 加 指示）TableHeadingsと組み合わせて使うことで，よりわかりやすい見た目となります．
In[5]:=

TableFormA9追加するコップの個数, 3 + 追加するコップの個数=,

TableHeadings → 99"追加するコップの個数", "合計"=, None=E

Out[5]//TableForm=

追加するコップの個数 5 6 7 8 9 10
合計
8 9 10 11 12 13

もちろん，同じ操作を何度も繰り返す，という視点からは文字列操作で出てきたMapを使うことも出来ますね．足し算の2種類の書き方のそれぞれに対して，実際にMapを使ってみたものが次になります．直接リストと足し算した方が簡単で便利だということがわかると思います．
In[6]:=

MapAPlus@3,

D &, 追加するコップの個数E

Out[6]=

88, 9, 10, 11, 12, 13<

In[7]:=

MapAH3 + L &, 追加するコップの個数E

Out[7]=

88, 9, 10, 11, 12, 13<- 54 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

引き算（-）で足して10になることを確認しよう

Mathematicaに引き算を行わせるには，算数や数学でも使われるマイナス記号「-」を使います．教科書などにあるように，そのまま命令として入力すれば，Mathematicaは計算結果を教えてくれます．例えば，単純な「20-4-3-2-1」もそのまま入力するだ
けで十分です．答えが「10」であると教えてくれます．
In[8]:=

20 − 4 − 3 − 2 − 1

Out[8]=

10

引き算にも，足し算と同じように，「次の2数の引き算をせよ」という意味を持つ「Subtract」という命令も用意されています．ただし，足し算と異なり2数に対してしか使えません．例えば，この命令を使って単純な「20-10」を計算するには次のようにします．もちろん，答えは「10」になります．
In[9]:=

Subtract@20, 10D

Out[9]=

10

では，先ほどと同じ問題「3+Ó=10」を考えましょう．これを「10-Ó=3」と変形して解きましょう．即ち，10から何を引いたら3になるのか，を考えましょう．そこで，引くコップの個数として，5個，6個，7個，8個，9個，10個の場合を考えます．先ほど同じように，引き算するコップの個数をMathematicaに覚えさせておきます．
In[10]:=
Out[10]=引くコップの個数 = 85, 6, 7, 8, 9, 10<85, 6, 7, 8, 9, 10<

引き算についてもMathematicaでは「数とリストの引き算」を，「リストの各要素ごとに同じ引き算をしたいのだろう」と解釈してくれます．従って，次のように単純に10からリストを引くことで一度に全ての引き算を指示することが出来ます．
In[11]:=
Out[11]=10 − 引くコップの個数
85, 4, 3, 2, 1, 0<

実 際 に は 次 の よ う に ， 以 前 に 出 て き たT a b l e F o r mを オ プ シ ョ ン （ 追 加 指示）TableHeadingsと組み合わせて使うことで，よりわかりやすい見た目となります．
In[12]:=

TableFormA9引くコップの個数, 10 − 引くコップの個数=,

TableHeadings → 99"引くコップの個数", "残り"=, None=E

Out[12]//TableForm=

引くコップの個数 5 6 7 8 9 10
残り
5 4 3 2 1 0- 55 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

もちろん，同じくMapを使うことも出来ます．
In[13]:=

MapASubtract@10,

D &, 引くコップの個数E

Out[13]=85, 4, 3, 2, 1, 0<

In[14]:=

MapAH10 − L &, 引くコップの個数E

Out[14]=85, 4, 3, 2, 1, 0<【数学的表記と四則演算】Mathematicaでの計算に関する指示は，なるべく算数や数学の慣用的な表現方法を踏襲するようになっています．従って，教科書等にある計算問
題はそのまま入力すれば，結果をMathematicaが求めて教えてくれます．実際に，この項では足し算と引き算を習っていますが，他の演算や括弧なども含め，慣用的な表現がそのまま利用できるようになっています．
ü 掛け算（×）して規則正しい数を探してみよう

Mathematicaに掛け算を行わせるには，算数や数学でも使われる記号「×」を使います．教科書などにあるように，そのまま命令として入力すれば，Mathematicaは計算結果を教えてくれます．例えば，単純な「1×2×3×4」もそのまま入力するだけで十分です．答えが「24」であると教えてくれます．なお，記号「×」は「Â*Â」で入力できます．
In[15]:=

1×2×3×4

Out[15]=24

かけ算の記号には，「×」の他，アスタリスク「*」やスペース「」も使えます．このうちスペースについては，Mathematicaが自動的に「×」を補って表示してくれます
ので，入力簡単で表示もわかりやすいのでお薦めです．
In[16]:=

1∗2∗3∗4

Out[16]=24

In[17]:=

1×2×3×4

Out[17]=24

更に掛け算にも，足し算や引き算と同じように，「次の数を掛け合わせよ」という意味を持つ「Times」という命令も用意されています．例えば，この命令を使って先ほど の 単 純 な 「1 × 2 × 3 × 4」を計算するには次のようにします．もちろん，答えは「24」になります．

- 56 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[18]:=

Times@1, 2, 3, 4DOut[18]=24

次の2つの掛け算を見てください．
In[19]:=

110 011 ∗ 101

Out[19]=11 111 111

In[20]:=

110 011 ∗ 202

Out[20]=22 222 222

Mathematicaでは算数や数学で習う計算順序（掛け算を足し算や引き算よりも先に行う）に従って計算をします．従って，何も考えずに教科書にあるような計算式をそのまま指示するだけで答えが得られます．
In[21]:=

110 011 ∗ 202 − 110 011 ∗ 101

Out[21]=11 111 111

また，括弧による計算順序の指定も可能です．このとき使う括弧は必ず丸括弧（ 「(」 と 「)」）にしてください．算数や数学で使用することもある「{ }」 や「[]」は，Mathematicaでは別のに意味で使われますので，何重になっても計算順序の指定には丸括弧だけを使います．
In[22]:=

H10 000 + 100 + 1L ∗ 11

Out[22]=

111 111

In[23]:=

10 101 ∗ 11

Out[23]=111 111

足し算や引き算と同じく，Mathematicaでは「数とリストの掛け算」を，「リストの各要素ごとに同じ掛け算をしたいのだろう」と解釈してくれます．この機能をうまく使って，「12345679」に何を掛けたら「111111」のような規則正しい数になるかを考えましょう．試しに，1から5のリストと積をとってみます．規則正しそうな数は表れません．
In[24]:=
Out[24]=12 345 679 ∗ 81, 2, 3, 4, 5<

812 345 679, 24 691 358, 37 037 037, 49 382 716, 61 728 395<

もっと大きな数，もっとたくさんの数との積を計算させないと見付かりそうにありません．でも，そんなに長いリストを手で入力するのは面倒です．Mathematicaには「次- 57 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007の数までの整数のリストを作成せよ」という意味の「Range」なる命令があります．これを使うことで，次のように簡単にリストを作ることが出来ます．
In[25]:=
Out[25]=

Range@20D

81, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20<

従って，次のように使うことで，9のときと18のときに「111111」のような規則正しい数になることがわかります．
In[26]:=
Out[26]=

12 345 679 ∗ Range@20D

812 345 679, 24 691 358, 37 037 037, 49 382 716, 61 728 395,
74 074 074, 86 419 753, 98 765 432, 111 111 111, 123 456 790,
135 802 469, 148 148 148, 160 493 827, 172 839 506, 185 185 185,
197 530 864, 209 876 543, 222 222 222, 234 567 901, 246 913 580<

T a b l e F o r mに 「 行 方 向 に 表 形 式 で 表 示 せ よ 」 と い う オ プ シ ョ ン「TableDirections → Row」を付けて指示を出すことで，次のようにわかりやすい
結果も得られます．
In[27]:=

TableForm@8Range@20D, 12 345 679 ∗ Range@20D<,
TableDirections → RowD

Out[27]//TableForm=

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

12 345 679
24 691 358
37 037 037
49 382 716
61 728 395
74 074 074
86 419 753
98 765 432
111 111 111
123 456 790
135 802 469
148 148 148
160 493 827
172 839 506
185 185 185
197 530 864
209 876 543
222 222 222
234 567 901
246 913 580- 58 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

【数のブロック表示】Mathematicaでは次のように比較的大きな数を入力すると，3桁ずつまとめて表示を行います．日本式では4桁ずつの方がわかりやすいかもしれません．4桁ずつに変更したい場合は， 編集メニューの「環境設定...」で表示されるダイアログにて，「外観」のタブの中の「数」のタブの中の「桁ブロックのサイズ」を変更してください．このダイアログでは様々な設定を変更できるようになっていま
す．いろいろと変更してみるのも面白いかもしれません．「デフォルト値に戻す」ボ
タンで元に戻せるので安心して変更してみてください．
ü 割り算（/）も使って分数の計算をしてみよう

Mathematicaに割り算を行わせるには，算数や数学でも使われる記号「÷」を使います．教科書などにあるように，そのまま命令として入力すれば，Mathematicaは計算結果を教えてくれます．例えば，単純な「20÷2」もそのまま入力するだけで十分です．答えが「10」であると教えてくれます．なお，記号「÷」は「ÂdivÂ」で入力できます．
In[28]:=

20 ÷ 2Out[28]=10

割り算の記号には，「÷」の他，スラッシュ「/」も使えます．
In[29]:=

20 ê 2Out[29]=10

更に割り算にも，他の四則演算と同じように，「次の2数の割り算を求めよ」という意味を持つ「Divide」という命令も用意されています．例えば，この命令を使って先ほどの単純な「20÷2」を計算するには次のようにします．もちろん，答えは「10」になります．
In[30]:=

Divide@20, 2DOut[30]=10

割り切れない場合，Mathematicaは結果を分数で教えてくれます．
In[31]:=1ê2
1

Out[31]=

2

他の四則演算と同じく，Mathematicaでは「数とリストの割り算」を，「リストの各要
素ごとに同じ割り算をしたいのだろう」と解釈してくれます．この機能をうまく使って，「3」で割り切れる数字を1から20までの整数から探してみましょう．

- 59 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[32]:=

Out[32]=

In[33]:=

Range@20D ê 3

1 2
4 5
7 8
10
: , , 1, , , 2, , , 3,
,
3 3
3 3
3 3
3
11
13 14
16 17
19 20
,
,
, 6,
,
>
, 4,
, 5,
3
3
3
3
3
3
3
TableForm@8Range@20D, Range@20D ê 3<D

Out[33]//TableForm=

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1
3

2
3

4
3

1

5
3

2

7
3

8
3

10
3

3

11
3

4

13
3

14
3

5

16
3

17
3

6

19
3

20
3

割り算の順番を変えることで，「30」を割り切る数を1から20までの整数から探すこ
とも出来ます．
In[34]:=

TableForm@8Range@20D, 30 ê Range@20D<DOut[34]//TableForm=

1

2

3

30 15 10

4

5 6 7

8

9

10 11 12 13 14 15 16 17 18 1

15
2

30
7

15
4

10
3

3

6 5

30
11

5
2

30
13

15
7

2

15
8

30
17

5
3

3
1

分数同士の四則演算もそのまま行えます．
In[35]:=

1ê2 +1ê3
5

Out[35]=6より分数らしく入力したい場合は，‚を押しながら「/」を入力します．例えば，次のような分数の計算式を入力するには，「1」を入力，‚を押しながら「/」を入力，「2」を入力，カーソルキーの右，「+」を入力，「1」を入力，‚を押しながら「/」を入力，「3」を入力します．カーソルキーの右は，‚を押しながらスペースを入力でも代用できます．
1
In[36]:=

2

+

1
3

5
Out[36]=6【帯分数と仮分数】Mathematicaは分数を仮分数で表現します．帯分数では掛け算との区別が難しいためです．区別が難しいため利用はお薦めしませんが，どうしても帯分数で入力を行いたい場合は，暗黙の加算である「Â+Â」を使ってください．「1Â+Â 1 」で「1 1 」と入力でき，「 4 」を表します．
3

3

3- 60 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

累乗（^）を使って複利計算をしてみよう

Mathematicaに累乗（冪乗，指数計算）を行わせるには，算数や数学での表現とは異なる記号「^」を使います．教科書などにあるような表現（数の右肩に小さく指数を書く
方法）にしたい場合は，パレット（ÑÑ ）を使うか後述するキーボードショートカット
を利用してください．例えば，記号「^」を使う場合，単純な「210 」を入力するには「2^10」と入力します．答えが「1024」であると教えてくれます．
In[37]:=

2 ^ 10Out[37]=1024

累乗にも四則演算（加減乗除）と同じように，「次の累乗を求めよ」という意味の「Power」という命令も用意されています．例えば，この命令を使って先ほどの単純な「2^10」を計算するには次のようにします．もちろん，答えは「1024」になります．
In[38]:=

Power@2, 10D

Out[38]=1024

四則演算と同じく，Mathematicaでは「数とリストの累乗」を，「リストの各要素ごとに同じ累乗をしたいのだろう」と解釈してくれます．この機能をうまく使って，「3」を何度掛けたら1000に近くなるか，1から10までの整数から探してみましょう．結果をTableFormで表示すると，3を6回掛けると1000に近いことがわかります．
3 ^ Range@10D

Out[39]=83, 9, 27, 81, 243, 729, 2187, 6561, 19 683, 59 049<

In[40]:=

TableForm@8Range@10D, 3 ^ Range@10D<DIn[39]:=

Out[40]//TableForm=

1 2 3 4 5
6
7
8
9
10
3 9 27 81 243 729 2187 6561 19 683 59 049

より指数らしく入力したい場合は，‚を押しながら「^」を入力します．例えば，次のような累乗の計算式を入力するには，「2」を入力，‚を押しながら「^」を入力，「10」を入力，カーソルキーの右，「+」を入力，「3」を入力，‚を押しながら 「^」を入力，「1 0」を入力します．カーソルキーの右は，‚を押しながらス
ペースを入力でも代用できます．
In[41]:=

210 + 310

Out[41]=60 073- 61 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

累乗の計算が出来ると複利計算が簡単に出来ます．複利計算は，年利を小数表示に直したものに1を加えた数を，年数分だけ累乗するだけです．例えば，0.5%の年利の場
合は1.005を年数分だけ累乗すれば良いことになります．10年の場合の計算をしてみます．1.05114ということは，10年間での利率は約5.1%ということになります．
In[42]:=

1.005 ^ 10

Out[42]=

1.051140.1%から1%まで0.2%刻みの年利で，10年後にどの程度違うかを計算してみましょう．まずは，Rangeを使って年利のリストを作りましょう．Rangeでは次のように使うことで，0.1から1まで0.2刻みの数を作ることが出来ます．
In[43]:=
Out[43]=

年利 = Range@0.1, 1, 0.2D

80.1, 0.3, 0.5, 0.7, 0.9<

Range@0.1, 1, 0.2D
刻幅の指定

最初の数

最後の数

リストの作成：刻幅を指定して数のリストを作る

年利をパーセントから小数に直します．
In[44]:=
Out[44]=

年利の割合 = 年利 ë 100

80.001, 0.003, 0.005, 0.007, 0.009<

年利の割合に1を加えます．1は元本に対応しています．
In[45]:=
Out[45]=

元本込の割合 = 年利の割合 + 1

81.001, 1.003, 1.005, 1.007, 1.009<

複利計算で10年後の元本比を計算し，計算結果から1を引き，100を掛けて小数からパーセントに直すことで10年間での利率を計算します．結果を見ると，かなり違うことがわかりますね．なお，何ら計算結果を保証するものではありませんので，あしからず．
In[46]:=

TableFormA9年利, II元本込の割合 ^ 10M − 1M ∗ 100=,

TableHeadings → 99"年利", "10年間での利率"=, None=E

Out[46]//TableForm=

年利
0.1
0.3
0.5
0.7
0.9
10年間での利率 1.00451 3.04083 5.11401 7.22467 9.37339- 62 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

数のリストから目当てのものを捜し出そうü 素数を探そう

素数とは「1とその数自身以外に正の約数を持たない （つまり1とその数以外のどんな自然数によっても割り切れない），1より大きな自然数」のことです．具体的に素数を探してみましょう．Mathematicaでは「n番目の素数を教えなさい」という意味の命令「Prime」を使うことで，簡単に素数を知ることが出来ます．例えば，小さい順に10番目の素数は次のように求められます．
In[47]:=

Prime@10D

Out[47]=29

作文のときに使った組込み関数のTableを使うことで，より簡単に素数を調べることが出来ます．以前とは異なり，Primeには何番目の素数を知りたいのかを指定する必要があるので，Tableの使い方も以前とは変わってきます．例えば，1番目から10番目までの素数を知りたい場合は，次のように，何番目という変数を1から10まで変化させつつ「Prime[何番目]」を評価することが必要になります．
In[48]:=
Out[48]=

TableAPrimeA何番目E, 9何番目, 1, 10=E
82, 3, 5, 7, 11, 13, 17, 19, 23, 29<

Table@Prime@何番目D, 8何番目, 1, 10<D

何を作るのか最大の数変化させたい変数名

最小の数

リストの作成：同じ仕組みでたくさん作るには

もちろん，いままでに登場した他の組込み関数を使っても同じことは可能です．例えば，次の例はMapとRangeを組み合わせた方法です．
Map@Prime, Range@10DD

Out[49]=82, 3, 5, 7, 11, 13, 17, 19, 23, 29<

In[50]:=

Map@Prime@ D &, Range@10DD

In[49]:=Out[50]=82, 3, 5, 7, 11, 13, 17, 19, 23, 29<

Mathematicaにはもっと便利な方法も用意されています．まずは，Primeという命令の属性を「関数の属性を調べよ」という意味の「Attributes」なる命令で調べましょう．すると，「リストを自動展開して，個々の要素に対して関数を適用する」という属性である「Litable」をPrimeが持っていることがわかります．

- 63 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[51]:=Out[51]=Attributes@PrimeD

8Listable, Protected<

即ち，次のように命令しても，1番目から10番目までの素数を知ることが出来ます．
In[52]:=Out[52]=

Prime@Range@10DD

82, 3, 5, 7, 11, 13, 17, 19, 23, 29<

ところで本当に「29」は素数でしょうか．素数であれば「1とその数以外のどんな自然数によっても割り切れない」はずですから，本当に割り切れないか調べましょう．29よりも大きな数で割り切れないことは明らかですから，1から29までの整数で割ってみましょう．確かに，1と29以外の数では割り切れていません．
In[53]:=Out[53]=29 ê Range@29D
:29,

29

,

29

29

3
29

,

29

4
29

,

29

5
29

,

29

6
29

,

29

7
29

,

29

,
9
29
29 29
,
,
,
,
,
,
,
,
,
,
10 11 12 13 14 15 16 17 18 19
29 29 29 29 29 29 29 29 29
,
,
,
,
, 1>
,
,
,
,
20 21 22 23 24 25 26 27 28
2
29

,

8
29

では「14351」はどうでしょうか．全部で14351個も数が表示されることになるので，Mathematicaが気を利かせて，一部分だけの出力をしてくれています．表示を増やしながら割り切れているかを確認しても良いのですが，非常に面倒です．
In[54]:=

14 351 ê Range@14 351D

非常に大きな出力が生成されました．以下はそのサンプルです．
:14 351, 14 351 , 14 351 , 14 351 , 14 351 , 14 351 , 14 351 , 14 351 ,Out[54]=2
3
14 35114 35114 351
,
,
,
9
10
11

4

5

14 329,67
8
14 35114 35114 351,,,14 34114 34214 34314 351, 14 351 , 14 351 , 14 351 , 14 351 , 14 351 , 14 351 , 1>
14 34414 34514 34614 347
14 34814 34914 350

表示を少なく もっと表示 全出力を表示 大きさ制限の設定...
このような場合は，「14351/Range[14351]」の結果であるリストから知りたい情報だけを抜き出して表示させた方が便利です．割り切れていれば整数で，割り切れていなければ分数ですから，整数だけを抜き出すことにしましょう．
整数だけの抜き出しには，「次の条件を満たすものだけをリストから抜き出しなさい」という意味の「Select」なる関数と，「整数かどうか調べなさい」という意味の- 64 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

「IntegerQ」を組み合わせます．結果を見ると，1と14351以外に127と113でも割り切れていますから，14351は素数でないことがわかります．
In[55]:=Out[55]=

Select@14 351 ê Range@14 351D, IntegerQD
814 351, 127, 113, 1<

Select@調べたいリスト, 抽出したい条件D
リストの名称やリストそのもの

NumberQ
主な例としては NumericQ

リストからの選出：条件を満たす要素だけを取り出す

条件として使える関数には様々なものがあります．必ずしも使えるとは限りません
が，命令の最後に「Q」が付いているものは，Mathematicaに何かを問い合わせる命令なので，条件として使えるも野が多くあります．

- 65 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[56]:=? System`∗Q

System`AlgebraicIntegerQ

MatrixQ

AlgebraicUnitQ

MemberQ

ArgumentCountQ

NameQ

ArrayQ

NumberQ

AtomQ

NumericQ

CoprimeQ

OddQ

DigitQ

OptionQ

DistributionDomainQ

OrderedQ

DistributionParameterQ

PartitionsQ

EllipticNomeQ

PolynomialQ

EvenQ

PositiveDefiniteMatrixQ

ExactNumberQ

PossibleZeroQ

FreeQ

PrimePowerQ

HermitianMatrixQ

PrimeQ

HypergeometricPFQ

QuadraticIrrationalQ

InexactNumberQ

RootOfUnityQ

IntegerQ

SameQ

IntervalMemberQ

SquareFreeQ

InverseEllipticNomeQ

StringFreeQ

LegendreQ

StringMatchQ

LetterQ

StringQ

LinkConnectedQ

SyntaxQ

LinkReadyQ

TensorQ

ListQ

TrueQ

LowerCaseQ

UnsameQ

MachineNumberQ

UpperCaseQ

MatchLocalNameQ

ValueQ

MatchQ

VectorQ- 66 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

双子素数，三つ子素数，四つ子素数を探そう

素数についてもっと調べていきましょう．素数の中には中の良い双子のような数もあり，「差が2の二つの素数の組」のことを双子素数といいます．双子素数の例として
は，「3と5」や「11と13」などがあります．
Mathematicaを使って双子素数を捜し出す方法はいろいろとありますが，ここでは比較的単純で簡単な方法を使ってみます（もっと良い方法もありますが，もっと詳しくなってからにしましょう）．まずは，双子素数の候補となる隣り合った素数のペアを作らなければいけませんが，次のように「素数同士の差」も含めたグループにしておきます．
In[57]:=Out[57]=差と素数のペア =Table@8Prime@n + 1D − Prime@nD, Prime@nD, Prime@n + 1D<,
8n, 1, 20<D881, 2, 3<, 82, 3, 5<, 82, 5, 7<, 84, 7, 11<,82, 11, 13<, 84, 13, 17<, 82, 17, 19<, 84, 19, 23<,86, 23, 29<, 82, 29, 31<, 86, 31, 37<, 84, 37, 41<,82, 41, 43<, 84, 43, 47<, 86, 47, 53<, 86, 53, 59<,
82, 59, 61<, 86, 61, 67<, 84, 67, 71<, 82, 71, 73<<

双子素数であれば，赤字の部分で求めさせた「素数同士の差」は2になっているはずです．そこで，「パターンにマッチする要素を取り出しなさい」という意味の「Cases」なる命令で，双子素数を含むグループのみを取り出します．Casesは以前に出てきた文字列用の同じような関数StringCasesの拡張バージョンと思ってください．
In[58]:=Out[58]=差と双子素数のグループ = CasesA差と素数のペア, 82, ___<E
882, 3, 5<, 82, 5, 7<, 82, 11, 13<, 82, 17, 19<,82, 29, 31<, 82, 41, 43<, 82, 59, 61<, 82, 71, 73<<「8」でリストの開始
最初の要素は「2」82, ___<「<」でリストの終了

下線3つ「___」は「何でもOK」の意味

リストのパターン：最初の要素が「2」のリスト

この段階で，Casesにより双子素数を含むグループだけを選別できましたが，いまとなっては余計な「素数同士の差」も含まれてしまっています．これを取り除かないと双子素数のペアにはなりません．要素の削除には「Drop」という命令を使います．この意味は「リストの最初の要素から指定した個数分だけ削除しなさい」です．例えば，「{2,3,5}」から最初の1つを削除し「{3,5}」にするには次のようにします．

- 67 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[59]:=Out[59]=Drop@82, 3, 5<, 1D
83, 5<

Drop@リスト, nD
要素の一部を削除する対象のリスト

最初のいくつを削除するか

1なら最初のひとつ
2なら最初のふたつリストから要素を削除：最初のいくつかを削除

従って，DropをMapと組み合わせて使うことで，個々のグループから余計な部分を削ぎ落とした，次のような双子素数のペアのリストを捜し出すことが出来ます．この結果を見る限りでは，双子素数はたくさんありますね．
In[60]:=
Out[60]=MapADrop@ , 1D &, 差と双子素数のグループE

883, 5<, 85, 7<, 811, 13<, 817, 19<,
829, 31<, 841, 43<, 859, 61<, 871, 73<<

双子素数を探した方法を少し変えることで，三つ子素数と呼ばれる「差が2である3つの素数の組」も見付けることが出来ます．三つ子素数の例としては「3と5と7」です．双子素数の場合と異なるのは，赤字の部分の差を隣り合ったふたつのペアそれぞれで計算していること，三つ子なので素数のトリオになっていることです．
In[61]:=

Out[61]=

差と素数のトリオ =Table@8Prime@n + 2D − Prime@n + 1D, Prime@n + 1D − Prime@nD,
Prime@nD, Prime@n + 1D, Prime@n + 2D<, 8n, 1, 20<D882, 1, 2, 3, 5<, 82, 2, 3, 5, 7<, 84, 2, 5, 7, 11<,82, 4, 7, 11, 13<, 84, 2, 11, 13, 17<, 82, 4, 13, 17, 19<,84, 2, 17, 19, 23<, 86, 4, 19, 23, 29<,82, 6, 23, 29, 31<, 86, 2, 29, 31, 37<, 84, 6, 31, 37, 41<,82, 4, 37, 41, 43<, 84, 2, 41, 43, 47<, 86, 4, 43, 47, 53<,86, 6, 47, 53, 59<, 82, 6, 53, 59, 61<, 86, 2, 59, 61, 67<,
84, 6, 61, 67, 71<, 82, 4, 67, 71, 73<, 86, 2, 71, 73, 79<<

この個々のリストの中から，最初の2つの差がどちらも2になっているグループを捜し出せば良いので，Casesで指定するパターンは2がひとつ増え，DropとMapで削ぎ落とす余計な部分は最初の2つに変わります．結果は，「3と5と7」の組しか見付かりませんでしたが，Tableの20を増やしてもこれしか見付かりません．実は，三つ子素数
はこの一組しか存在しないのです．不思議ですね．

- 68 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[62]:=
Out[62]=

MapADrop@ , 2D &, CasesA差と素数のトリオ, 82, 2, ___<EE

883, 5, 7<<

同じように，四つ子素数と呼ばれる「n, n+2, n+6, n+8がすべて素数であるような数の組」も見付けることが出来ます．これまでと異なるのは，赤字の部分の差を隣り合った三つのペアそれぞれで計算していること，四つ子なので素数のカルテットになっていることです．
In[63]:=

Out[63]=差と素数のカルテット =Table@8Prime@n + 3D − Prime@n + 2D,
Prime@n + 2D − Prime@n + 1D, Prime@n + 1D − Prime@nD,
Prime@nD, Prime@n + 1D, Prime@n + 2D, Prime@n + 3D<,
8n, 1, 20<D882, 2, 1, 2, 3, 5, 7<, 84, 2, 2, 3, 5, 7, 11<,82, 4, 2, 5, 7, 11, 13<, 84, 2, 4, 7, 11, 13, 17<,82, 4, 2, 11, 13, 17, 19<, 84, 2, 4, 13, 17, 19, 23<,
86, 4, 2, 17, 19, 23, 29<, 82, 6, 4, 19, 23, 29, 31<,86, 2, 6, 23, 29, 31, 37<, 84, 6, 2, 29, 31, 37, 41<,82, 4, 6, 31, 37, 41, 43<, 84, 2, 4, 37, 41, 43, 47<,
86, 4, 2, 41, 43, 47, 53<, 86, 6, 4, 43, 47, 53, 59<,
82, 6, 6, 47, 53, 59, 61<, 86, 2, 6, 53, 59, 61, 67<,
84, 6, 2, 59, 61, 67, 71<, 82, 4, 6, 61, 67, 71, 73<,86, 2, 4, 67, 71, 73, 79<, 84, 6, 2, 71, 73, 79, 83<<

この個々のリストの中から，最初の3つの差が2,4,2になっているグループを捜し出せば良いので，Casesで指定するパターンは「{2,4,2,___}」となり，DropとMapで削ぎ落とす余計な部分は最初の3つに変わります．
In[64]:=
Out[64]=MapADrop@ , 3D &, CasesA差と素数のカルテット, 82, 4, 2, ___<EE

885, 7, 11, 13<, 811, 13, 17, 19<<

【BlankNullSequence（___）】Mathematicaではパターンマッチが非常に重要な役割を担っています．今回のように特定の形にマッチするものを抜き出したり，以前の例のように特定のパターンの文字列だけを検出することは，多くの実際的な作業において頻出します．その中でもアンダースコアを複数組み合わせたパターンは重要で，いわゆるワイルドカード，何にでもマッチするジョーカーです．詳細はまだ説明しませんが，アンダースコアの数は重要な意味を持つので，入力間違いには注意してください．

- 69 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

ü 完全数や友愛数を探そう

素数に限らず整数には関係の深いペアが存在します．ここでは非常に有名な「完全数」と「友愛数」について取り上げたいと思います．完全数とは「その数自身を除く約数の和が，その数自身と等しい自然数」のことを指します．例えば，6の約数は1と2と3と6で，それ自身である6を除いて足すと1+2+3=6となるので，6は完全数です．
Mathematicaに約数を求めさせるには「Divisors」という命令を使います．この意味
は「指示した数の約数を全て求めなさい」です．実際に，6の約数を求めてみましょう．きちんと，1と2と3と6をリストで報告してくれます．
In[65]:=
Out[65]=

Divisors@6D
81, 2, 3, 6<

この約数のリストからその数自身を除いて和を計算しなければ，完全数であるかの確認が出来ません．その数自身は常にリストの最後尾に出てくる（大きさの順に並んでいるので，最後になる）ので，双子素数のところで使った「Drop」を応用して，最後の要素だけを削除します．Dropに指示する整数が負の数の場合，リストの最後尾から指示した個数だけ要素を削除できます．最後尾だけを削除する場合は「-1」を指定します．
In[66]:=
Out[66]=

Drop@Divisors@6D, −1D
81, 2, 3<

Drop@リスト, -nD
要素の一部を削除する対象のリスト

最後のいくつを削除するか-1なら最後のひとつ-2なら最後のふたつリストから要素を削除：最後尾のいくつかを削除

その数自身をリストから削除できたので，あとはこのリストに含まれる数の総和が元の数になっていれば，完全数ということになります．これには「リストに含まれる要素の合計を計算しなさい」という意味をもつ「Total」なる関数を使います．すると，次のように元の数である6になるので，6は完全数であることを確認出来ます．
In[67]:=

Total@Drop@Divisors@6D, −1DD

Out[67]=

6

それでは完全数を探してみましょう．まずは，次のように整数とその約数の和をペアにして，完全数の候補のリストを作ります．1が完全数でないことは明らかですか
ら，1は外して2から30までを候補として作っています．もちろん，30よりも大きな数まで作っても良いでしょう．

- 70 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[68]:=

Out[68]=

整数と約数の和 = Table@8n, Total@Drop@Divisors@nD, −1DD<,
8n, 2, 30<D
882, 1<, 83, 1<, 84, 3<, 85, 1<, 86, 6<, 87, 1<, 88, 7<,
89, 4<, 810, 8<, 811, 1<, 812, 16<, 813, 1<, 814, 10<,815, 9<, 816, 15<, 817, 1<, 818, 21<, 819, 1<, 820, 22<,821, 11<, 822, 14<, 823, 1<, 824, 36<, 825, 6<,826, 16<, 827, 13<, 828, 28<, 829, 1<, 830, 42<<

もちろん，この操作はMapを使っても同じです．Tableとの違いを見比べると理解がより深まります．
In[69]:=

整数と約数の和 = Map@8 , Total@Drop@Divisors@ D, −1DD< &,Range@2, 30DD;

さて，完全数であるならば，整数とその約数の和は同じになっているはずです．そこで，ペアを構成する数が同じものをCasesで取り出したいのですが，これまでとは異なるパターンが必要になります．まず，アンダースコア1つ「_」で「何でもOKだが，ひとつだけ」という意味を持ちます．アンダースコア3つ「___」の場合と異なり，ひとつにしかマッチしないことに注意してください．
さらに，今回の場合，ペアの数が同じになっていなければいけません．パターンを「{_,_}」としてしまうと，同じ数でなくてもマッチしてしまうことになります．そこで，Mathematicaに追加指示として，各アンダースコアに名前を付けることにします．すると，同じ名前のアンダースコアは同じものを表すことになるので，「{m_,m_}」は「何だかわからないけど，同じものふたつからなるリスト」を表します．従って，次のようにすることで完全数のペアを取り出すことが出来ます．
In[70]:=
Out[70]=CasesA整数と約数の和, 8m_, m_<E
886, 6<, 828, 28<<

「8」でリストの開始
同じ名前は同じもの

8m_, m_<「<」でリストの終了

下線1つ「_」は「何でもOKだけど，1つだけ」

リストのパターン：最初の要素が「2」のリスト

より洗練された結果が欲しい場合は，「リストの最初の要素だけを取り出しなさい」という意味の「First」を使うことで，重複のない完全数のみのリストに出来ます．

- 71 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[71]:=
Out[71]=

MapAFirst, CasesA整数と約数の和, 8m_, m_<EE

86, 28<完全数を探す方法を少しだけ工夫することで，友愛数も見付けることが出来ます．友愛数は親和数とも呼ばれ，「異なる2つの自然数の自分自身を除いた約数の和が，互いに他方と等しくなるような数」のことを指します．例えば，220と284は友愛数です．まずは，これを確認してみましょう．
2 2 0の約数の和を求めさせるには，完全数のときと同じくD i v i s o r s，D r o p，Totalを使えば良いので，次のようになります．そして結果の「約数の和」に対して同じ操作をして220に戻れば良いので，引き続いてその操作を行っています．結果は220となっており，220と284は友愛数であることを確認できました．
In[72]:=

約数の和 = Total@Drop@Divisors@220D, −1DD

Out[72]=284

In[73]:=

TotalADropADivisorsA約数の和E, −1EE

Out[73]=220

なお，この操作を一度で済まそうとすると，次のようになりますね．
In[74]:=

Total@Drop@Divisors@
Total@Drop@Divisors@220D, −1DD
D, −1DDOut[74]=220では実際に友愛数を見付けてみましょう．完全数のときは，整数と約数の和のペアのリストを作って，そこから整数と約数の和が同じものを選んできました．今回も同じ方法でアプローチしてみます．整数，その約数の和，さらに和の約数の和という3つの数から構成されるリストを作ります．友愛数であれば，最初の整数と最後の和が同じになっているはずです．友愛数はそう頻出しないので，2から30000までの整数を対象にします．セミコロンを付けて出力を抑制した方が良いかもしれませんね．
In[75]:=

整数と約数の和とその約数の和 =Table@8n, Total@Drop@Divisors@nD, −1DD,
Total@Drop@Divisors@Total@Drop@Divisors@nD, −1DDD,−1DD<, 8n, 2, 30 000<D;

完全数のときと同じように，友愛数の候補を「{m_, _, m_}」というパターンで取り出します．完全数のときとは異なり，リストが長くなっている分，パターンの間にアンダースコアがひとつ挿入しています．

- 72 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[76]:=
Out[76]=

友愛数候補 = CasesA整数と約数の和とその約数の和, 8m_, _, m_<E
886, 6, 6<, 828, 28, 28<, 8220, 284, 220<,
8284, 220, 284<, 8496, 496, 496<, 81184, 1210, 1184<,
81210, 1184, 1210<, 82620, 2924, 2620<,
82924, 2620, 2924<, 85020, 5564, 5020<,
85564, 5020, 5564<, 86232, 6368, 6232<,
86368, 6232, 6368<, 88128, 8128, 8128<,
810 744, 10 856, 10 744<, 810 856, 10 744, 10 856<,
812 285, 14 595, 12 285<, 814 595, 12 285, 14 595<,
817 296, 18 416, 17 296<, 818 416, 17 296, 18 416<<と，良く見ると完全数が混ざってしまっています．完全数の場合，その約数の和も，その和の約数の和も，元の数になりますから友愛数候補として検出されてしまっているのです．そこで，Casesの逆操作を行う命令「DeleteCases」を使い余計な完全数を排除してしまいましょう．この命令の意味は「パターンにマッチする要素をリ
ストから削除しなさい」です．指定するパターンは「全て同じ要素」を意味する「{m_, m_, m_}」です．
In[77]:=
Out[77]=

友愛数の真の候補 = DeleteCasesA友愛数候補, 8m_, m_, m_<E
88220, 284, 220<, 8284, 220, 284<,
81184, 1210, 1184<, 81210, 1184, 1210<,
82620, 2924, 2620<, 82924, 2620, 2924<,
85020, 5564, 5020<, 85564, 5020, 5564<,
86232, 6368, 6232<, 86368, 6232, 6368<,
810 744, 10 856, 10 744<, 810 856, 10 744, 10 856<,
812 285, 14 595, 12 285<, 814 595, 12 285, 14 595<,
817 296, 18 416, 17 296<, 818 416, 17 296, 18 416<<

このままでは少し見づらいので，個々の要素数が3のリストをUnionを使って重複をなくして，友愛数のペアにしましょう（赤字の部分の命令に相応）．さらに，友愛数のペアのそれぞれに対して友愛数のペアが作られてしまっているので，この重複もUnionを使ってなくすと，次のように友愛数のペアが8個できあがります．
In[78]:=
Out[78]=

UnionAMapAUnion, 友愛数の真の候補EE88220, 284<, 81184, 1210<, 82620, 2924<,
85020, 5564<, 86232, 6368<, 810 744, 10 856<,
812 285, 14 595<, 817 296, 18 416<<【TableとRangeとMap】Mathematicaでは，ある特定の性質を満たすリスト（今回はたくさんのそういうリストを作りました）を準備する場合，いろいろな方法が選べます．大抵の場合，TableとRangeとMapのどの方法でも同じものを作れますので，自- 73 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

分の分かり易い方法を選ぶようにしましょう．ただ，今後はどれかでしか出来ない操作も出てきますので，なるべく比較検討しておく方が勉強にはなります．
ü 円周率の中に誕生日を捜し出そう

素数の他にも不思議な数はたくさんあります．ここでは，円周率pと自然対数の底‰を扱いたいと思います．突然ですが，円周率を何桁まで覚えているでしょうか．もしくは何桁まで覚えたいでしょうか．Mathematicaに「指定した桁数まで小数に直しなさい」という意味を持つ命令「N」を使うことで，円周率を何桁まででも知ることが出来ます．例えば，100桁まで円周率を知りたい場合は次のように命令します．円周率は「Pi」または「ÂpiÂ」と入力するか，パレットから選択して入力します．
In[79]:=

N@Pi, 100DOut[79]=3.14159265358979323846264338327950288419716939937510582
0974944592307816406286208998628034825342117068

同じように，自然対数の底についてもNを使うことで，何桁まででも知ることが出来ます．同様に，100桁まで自然対数の底を知りたい場合は次のように命令します．自然対数の底は「E」または「ÂeeÂ」と入力するか，パレットから選択して入力します．
In[80]:=

N@E, 100DOut[80]=2.71828182845904523536028747135266249775724709369995957
4966967627724076630353547594571382178525166427

この組込み関数「N」は非常に便利な命令で，次のように様々な厳密な数を，より直感的に大きさを把握することのできる小数に変換してくれます．
In[81]:=

Out[81]=

NB:

12

,

12

,

40

83

,

,

5

,

18

,

7

,

17

,

12

,

16

>F

80.413793, 0.184615, 0.97561, 0.399038, 0.147059,
0.439024, 0.0457516, 0.293103, 0.342857, 0.592593<
29

65

41

208

34

41

153

58

35

27

「N」の逆変換（小数を分数に変換）させるための命令も用意されており，英語で有理化を意味する「Rationalize」という命令になります．
In[82]:=

Rationalize@0.5D
1

Out[82]=2

少し横道にそれましたが，円周率も自然対数の底も無限小数（小数点以下，延々と無限に桁が続く小数）です．実に様々な数字が小数点以下に表れてきます．もしかすると誕生日と同じ数字の並びがあるかもしれません．それを探してみましょう．
数字の並びを探すには，文字列として捜し出す方が簡単です．まずは「次の数を文字列に変換しなさい」という意味をもつ「ToString」で，1万桁程度の円周率を文字列- 74 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007にしておきましょう．1万桁分の円周率を表示するには何ページか必要なので，ここではセミコロンを付けて出力を抑制しています．
In[83]:=

円周率の文字列 = ToString@N@Pi, 10 000DD;

文字列の中から特定の文字列を探し出すには，早口言葉のところで使った，StringCount，StringCasesと似ている命令「StringPosition」を使います．この命令の意味は「次の文字列は何文字目から何文字目までに表れるか調べなさい」です．従って，2月29日生まれの人の場合，次のようにすることで円周率の中に誕
生日と同じ数字「0229」が表れるかを調べることが出来ます．
In[84]:=
Out[84]=

StringPositionA円周率の文字列, "0229"E
886708, 6711<, 89227, 9230<<

結果は「{6708, 6711}」と「{9227, 9230}」になっています．円周率の文字列の最初には「3.14」と小数点以下でない文字が2文字含まれているので，2月29日生まれの誕生日は，円周率の小数点以下6706桁目から6709桁目と，小数点以下9225桁目から9228桁目に表れることがわかります．
同じように自然対数の底についても調べてみると，1万桁分の中には存在しないので，3万桁分まで調べたところ，小数点以下22438桁目から22441桁目に表れることがわかります．他にもいろいろな数字が隠れているかもしれません．面白いですね．
StringPosition@ToString@N@E, 10 000DD, "0229"DOut[85]=8<

In[86]:=

StringPosition@ToString@N@E, 30 000DD, "0229"DIn[85]:=

Out[86]=8822 440, 22 443<<【厳密数と近似数】Mathematicaでは，小数の形で表される数のことを「近似数」，整数や分数のように小数の形でないものを「厳密数」と分類しています．円周率は組込み関数Nで小数に変換しなければ厳密数ですが，有限な小数で表現してしまうと正確には円周率とは言えない近似数になります．Mathematicaは，厳密数同士の計算結果は
厳密数で，近似数との計算結果は近似数で報告してきます．正確さか，分かり易さ
か，必要に応じて選んで計算するようにしてください．

切符の番号で10を作る遊びを再現してみようü 切符の番号で10を作る答えを探そう

鉄道の切符には大抵4桁の番号が振ってあり，その数の四則演算で10を作るという遊びがあります．例えば，「3142」であれば「3-1+4×2」と演算子を補うことで10に出来ます．この遊びには様々なローカルルールがあるようなので，本書では次のようなルールを定めておきます．

- 75 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

2.
3.
4.
5.

数の順番を入れ換えてはいけない
使ってよい演算は，加減乗除の4種類（累乗は禁止）
同じ演算を何度使っても良い
括弧は使用禁止
使える演算子の数は3個（最初の文字の前には付けられない）

このようなルールの元，Mathematicaに次の問題を解いてもらいましょう．
In[87]:=
Out[87]=

問題 = 84, 3, 6, 2<
84, 3, 6, 2<

Mathematicaは計算機なので，全ての演算子の組合せに対して10になるかを確認してもらうという力業が出来ます．そこで，ルールに基づいて4種類から重複を許した3個の演算の組合せを全て求めます．「Tuples」という命令を使うと非常に簡単に作れます．この命令の意味は「リストの要素から重複を許して指定した個数になるような組合せを全て求めなさい」です．
従って，次のようにTuplesを使うことで演算の全ての組合せを求められます．な
お，演算子を文字列として入力しないと，足し算やら引き算やらを実行しようとしてしまいエラーになってしまうので注意してください．
In[88]:=
Out[88]=演算の組合せ = Tuples@8"+", "−", "∗", "ê"<, 3D

88+, +, +<, 8+, +, −<, 8+, +, ∗<, 8+, +, ê<,8+, −, +<, 8+, −, −<, 8+, −, ∗<, 8+, −, ê<, 8+, ∗, +<,8+, ∗, −<, 8+, ∗, ∗<, 8+, ∗, ê<, 8+, ê, +<, 8+, ê, −<,8+, ê, ∗<, 8+, ê, ê<, 8−, +, +<, 8−, +, −<, 8−, +, ∗<,8−, +, ê<, 8−, −, +<, 8−, −, −<, 8−, −, ∗<, 8−, −, ê<,8−, ∗, +<, 8−, ∗, −<, 8−, ∗, ∗<, 8−, ∗, ê<, 8−, ê, +<,8−, ê, −<, 8−, ê, ∗<, 8−, ê, ê<, 8∗, +, +<, 8∗, +, −<,8∗, +, ∗<, 8∗, +, ê<, 8∗, −, +<, 8∗, −, −<, 8∗, −, ∗<,8∗, −, ê<, 8∗, ∗, +<, 8∗, ∗, −<, 8∗, ∗, ∗<, 8∗, ∗, ê<,
8∗, ê, +<, 8∗, ê, −<, 8∗, ê, ∗<, 8∗, ê, ê<, 8ê, +, +<,8ê, +, −<, 8ê, +, ∗<, 8ê, +, ê<, 8ê, −, +<, 8ê, −, −<,8ê, −, ∗<, 8ê, −, ê<, 8ê, ∗, +<, 8ê, ∗, −<, 8ê, ∗, ∗<,8ê, ∗, ê<, 8ê, ê, +<, 8ê, ê, −<, 8ê, ê, ∗<, 8ê, ê, ê<<

演算子を文字列で表現しているので，問題に含まれる数も文字列に変換しておきます．文字列は文字列同士，数は数同士，揃えて扱わないとMathematicaも混乱してしまいます．
In[89]:=
Out[89]=

問題文字列 = MapAToString, 問題E
84, 3, 6, 2<- 76 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

問題文字列と演算の組合せから，計算式を構成します．これには「要素を交互に組み合わせて1つのリストにしなさい」という意味をもつ「Riffle」なる命令が非常に便利です．例えば，演算の組合せ「{"+", "-", "*"}」に対しては次のようなリストが得られるので，StringJoinで1つの文字列にまとめると，1つの計算式が出来ることになります．
Riffle@8"4", "3", "6", "2"<, 8"+", "−", "∗"<D

Out[90]=84, +, 3, −, 6, ∗, 2<

In[91]:=

StringJoin@Riffle@8"4", "3", "6", "2"<, 8"+", "−", "∗"<DD

Out[91]=

4+3−6∗2

In[90]:=

このような変換を全ての演算の組合せに対してMathematicaにさせるには，何度も出てきているMapを次のように使えば良いことはすぐにわかると思います．
In[92]:=
Out[92]=

計算式 = MapAStringJoinARiffleA問題文字列,

EE &, 演算の組合せE

84+3+6+2, 4+3+6−2, 4+3+6∗2, 4+3+6ê2, 4+3−6+2,
4+3−6−2, 4+3−6∗2, 4+3−6ê2, 4+3∗6+2, 4+3∗6−2,
4+3∗6∗2, 4+3∗6ê2, 4+3ê6+2, 4+3ê6−2, 4+3ê6∗2, 4+3ê6ê2,
4−3+6+2, 4−3+6−2, 4−3+6∗2, 4−3+6ê2, 4−3−6+2, 4−3−6−2,
4−3−6∗2, 4−3−6ê2, 4−3∗6+2, 4−3∗6−2, 4−3∗6∗2, 4−3∗6ê2,
4−3ê6+2, 4−3ê6−2, 4−3ê6∗2, 4−3ê6ê2, 4∗3+6+2, 4∗3+6−2,
4∗3+6∗2, 4∗3+6ê2, 4∗3−6+2, 4∗3−6−2, 4∗3−6∗2, 4∗3−6ê2,4∗3∗6+2, 4∗3∗6−2, 4∗3∗6∗2, 4∗3∗6ê2, 4∗3ê6+2, 4∗3ê6−2,
4∗3ê6∗2, 4∗3ê6ê2, 4ê3+6+2, 4ê3+6−2, 4ê3+6∗2, 4ê3+6ê2,
4ê3−6+2, 4ê3−6−2, 4ê3−6∗2, 4ê3−6ê2, 4ê3∗6+2, 4ê3∗6−2,
4ê3∗6∗2, 4ê3∗6ê2, 4ê3ê6+2, 4ê3ê6−2, 4ê3ê6∗2, 4ê3ê6ê2<

このままでは10になるか分からないので，Mathematicaに計算させましょう．文字列になっている計算式を計算させるには，「文字列を数式と解釈して，計算を行いなさい」という意味の「ToExpression」を使います．計算式はリストで与えられている
ので，この場合もMapを次のように使います．

- 77 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[93]:=

計算結果 = MapAToExpression, 計算式EOut[93]=:15, 11, 19, 10, 3, −1, −5, 4, 24, 20, 40, 13,
5
2

, 5,

17
4

−32, −5,

13,

2, 9, 5, 13, 4, −3, −7, −11, −2, −12, −16,
11
2

,

3

, 3,

2

15

, 20, 16, 24, 15, 8, 4, 0,

4
28

,

16

,

40

,

13

,
3
3
3
8
20
32
5
20
16 4 1
,−
, , >
− ,−
,−
, − , 10, 6, 16, 4,
9
9
3
3
3
3
9 9
9, 74, 70, 144, 36, 4, 0, 4, 1,

3

この中に10があれば問題を解く演算の組合せがあることになります．リストの中から
1 0を 探 す に は ，S t r i n g P o si t io nの リ ス ト 版 で あ る 「P o s i t i o n」 を 使 い ます．Positionの結果を「Extract」に指定することで，計算結果が10になった計算
式を取り出すことが出来ます．「Extract」は「リストから指定した部分を取り出しなさい」という意味を持つ命令です．「{{4},{57}}」は「リストの4番目と57番目」という部分指定になります．
In[94]:=

PositionA計算結果, 10E

Out[94]=884<, 857<<

In[95]:=

ExtractA計算式, PositionA計算結果, 10EE

Out[95]=84+3+6ê2, 4ê3∗6+2<

まとめると，4362という問題は「4+3+6/2」ないしは「4/3*6+2」で10に出来ることがわかります．
【文字列と数式】Mathematicaは，入力された数式を自動的に計算して見易く報告してくれます．従って，数式を計算せずにそのままの状態で扱うには，文字列として扱ったり，明示的に「評価を行うな」という補足指示を出す必要があります．この補足指示に興味のある方は，ドキュメントセンターで「Hold」を調べてみてください．
ü 切符の番号で10を作る問題を作ってみよう

今度は逆に「10に出来る4桁の数字」を作ってみましょう．切符の番号の中には，どんなに頑張っても10に出来ない数（例えば，1000や2345）が存在しますが，事前にMathematicaで確認すれば，解の存在する問題を簡単に作ることが出来ます．
まず，演算の組合せは必要なので，前項に引き続いて定義しておきましょう．
In[96]:=

演算の組合せ = Tuples@8"+", "−", "∗", "ê"<, 3D;- 78 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

問題の解き方を調べさせるときに準備した各種のリスト（問題候補，問題候補文字列，問題文，計算結果）を一括して作成できるように，遅延的に定義しておきます．問題候補自体は，何度も使っているRandomIntegerを使うことで簡単に作れます．ここでは，演算として割り算を使えるルールになっているので，意図的に問題候補から0を除外しています（0では割り算できないため）．
In[97]:=

下準備 := I問題候補 = RandomInteger@81, 9<, 4D;
問題候補文字列 = MapAToString, 問題候補E;

問題文 = MapAStringJoinARiffleA問題候補文字列,

EE &,演算の組合せE;
計算結果 = MapAToExpression, 問題文EM

この命令のように，Mathematicaに出す指示はセミコロンで区切れば，複数の指示を組み合わせることが出来ます．全体を丸括弧で囲んでいるのは，この4つの命令を1つのまとまりとして「下準備」と名付けなさい，とMathematicaに指示するためです．括弧がないと，最初の命令のみが下準備になってしまいます．
次に，問題候補が解くことの出来る問題であるかをチェックする遅延的な定義を行いましょう．計算結果の中に10があるかをMemberQで問い合わせるだけでチェックが出来ます．結果は，真偽値であるTrue（解ける）かFalse（解けない）になります．
In[98]:=

問題候補は解ける？ := MemberQA計算結果, 10E

問題候補が解ける場合に，問題文を抽出する遅延的な定義も行っておきましょう．
In[99]:=

問題の解き方 := ExtractA問題文, PositionA計算結果, 10EE

これらをまとめると，次のように問題作成を行ってくれる遅延的な定義を作れます．問題作成を呼び出すたびに，10にすることの出来る問題が解き方と共に報告されます．「If」という命令は以前にも出てきましたが，今回の場合，条件が満たされていれば「{問題候補,
問題の解き方}」を，満たされていなければ「問題作成」をMathematicaは実行します．即ち，問題候補が解ける状態になるまで，延々と「遅延的な定義の問題作成」が何度も呼び出されることになります．
In[100]:=

問題作成 := I下準備;

In[101]:=

問題作成

IfA問題候補は解ける？, 9問題候補, 問題の解き方=, 問題作成EM

Out[101]=

882, 8, 7, 7<, 82+8+7−7, 2+8−7+7, 2+8∗7ê7, 2+8ê7∗7<<

In[102]:=

問題作成

Out[102]=884, 4, 2, 2<, 84+4∗2−2, 4∗4ê2+2<<- 79 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

変数と式を使って数学の問題を解いてみようü 未知の何かを見つけ出す中等教育で未知数について習うときに頻出する問題があります．それは「地球の半径が1m長くなったら，地球の周の長さは何m長くなるか」という問です．周の長さは「直径×円周率」ですから，地球の半径を「地球の半径」という言葉で表現することにすると，地球の周の長さは次のように書くことが出来ます．Piは既に出てきていますが，円周率を表しています．もちろん，「ÂpiÂ」により「π」と入力されても構いません．
In[103]:=

地球の周の長さ = 地球の半径 ∗ 2 ∗ Pi

Out[103]=

2 地球の半径 π

続いて，地球の半径が1m長くなった場合の周の長さも同様に計算してみましょう．丸括弧を使うことで次のように書くことが出来ますね．ここでも地球の半径は未知のままで，「地球の半径」という言葉で表現しているだけです．
In[104]:=Out[104]=

地球の半径が1m長くなった場合の周の長さ = I地球の半径 + 1M ∗ 2 ∗ Pi
2 I1 + 地球の半径M π

どれだけ長くなるかを知るためには，「地球の半径が1m長くなった場合の周の長さ」から「地球の周の長さ」を引いて差を求める必要があります．実際に差を計算してみましょう．
In[105]:=Out[105]=

差 = 地球の半径が1m長くなった場合の周の長さ − 地球の周の長さ−2 地球の半径 π + 2 I1 + 地球の半径M π

何やら複雑な式が出てきました．やはり，地球の半径がわからないと何m長くなるかを知ることは出来ないのでしょうか．そうではありません．Mathematicaは人間から与えられた命令を忠実に実行する機械なので，数式を勝手に展開しないだけです．場合によっては展開してしまうと見づらくなることもあるからです．展開させたい場合には，「Expand」という命令を使います．この意味は「次の数式を出来るだけ展開しな
さい」です．
In[106]:=

ExpandA差E

Out[106]=2π

結 局 ， 半 径 が 1 m 長 く な る と 周 の 長 さ は 「2 π」 m 長 く な る こ と が わ か り ま した．「2π」では具体的にどれくらいの長さなのか把握しづらい場合は，以前に出てきた組込み関数Nを使うことで，次のように約6.28mであることを知ることも出来ます．

- 80 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[107]:=

NAExpandA差EE

Out[107]=6.28319

この計算例に出てくる「地球の半径」のように，未知の何かを表すもの，等号を使って M a t h e m a t i c aに 値 を 覚 え さ せ る も の ， を 一 般 に 「 変 数 」 と 呼 ん で い ま す ． 一
方 ，E x p a n dや N の よ う にM a t h e m a t i c aへ の 命 令 の こ と を 「 関 数 」 と 呼 び ます．Mathematicaでは変数と関数に大きな違いはなく，どちらも「シンボル」と呼ぶこともあります．これらのシンボルの名前には，どのような名前も（英語でも，日本語でも，何文字でも）付けられますが，次のような制限があります．
シンボル名は半角の数字から始めてはいけない（シンボルの前にある数字はスカラー倍として認識されるため．例えば，「2 x」など）
シンボル名に演算子やスペースなど，他に意味のある記号を使ってはいけない（それぞれの記号は別に用途があり名前とは認識されないため）
シンボル名を半角英数字にするときは，大文字から始めないことが望ましい（Mathematicaの組込み関数は大文字から始まっており混乱を避けるため）

1.
2.
3.

これらを踏まえて，似た問題を解いてみましょう．それは「太陽の周を1m長くするには，太陽の半径を何m長くすれば良いか」という問です．太陽の半径の長さは「太陽の周の長さ÷円周率÷2」ですから，太陽の周の長さを「太陽の周の長さ」という言葉で表現することにすると，太陽の半径は次のように書くことが出来ますIn[108]:=太陽の半径 = 太陽の周の長さ ë Pi ë 2
太陽の周の長さ

Out[108]=2π

太陽の周を1m長くした場合の太陽の半径も同様に計算してみましょう．
In[109]:=太陽の周を1m長くした太陽の半径 = I太陽の周の長さ + 1M ë Pi ë 2
1 + 太陽の周の長さ

Out[109]=2π

どれだけ長くする必要があるかを知るためには，「太陽の周を1m長くした太陽の半径」から「太陽の半径」を引いて差を求める必要があります．実際に差を計算してみましょう．
In[110]:=差 = 太陽の周を1m長くした太陽の半径 − 太陽の半径Out[110]=−太陽の周の長さ
2π+

1 + 太陽の周の長さ2π

今回も同様にExpandで展開させると，太陽の周を1m長くするには，太陽の半径を「 1 」m長くする必要があることがわかります．
2π- 81 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[111]:=

ExpandA差E
1

Out[111]=2π

具体的な数でないと大きさが把握できないので，今回もNで小数に直しましょう．すると，約16cm半径を長くすると周の長さが1m長くなることがわかりました．
In[112]:=NAExpandA差EE

Out[112]=0.159155

ü 結局のところそれは何？，方程式を解いてみよう

今度は次のような問題を考えてみよう．それは「1000円だけ財布に入れ，阪急六甲駅
から神戸大学までバスで2往復しました．途中，缶珈琲が100円だったので2本買ったと
ころ，ちょうど1000円を使いきりました．バスの片道運賃はいくらでしょうか」です．
バスの片道運賃を表すシンボル「バスの片道運賃」を未知数として方程式を立ててみましょう．使ったお金の合計を計算すると次のようになります．
バスの片道運賃 × 2 × 2 + 100 × 2

この金額が1000円に等しいので，方程式は次のようになります．
バスの片道運賃 × 2 × 2 + 100 × 2 = 1000

しかし，Mathematicaにとって「=」は，リストや数に名前を付けて覚えておく「シンボルへの値の割り当て」の意味を持つため，左辺と右辺が等しい「方程式」として認識してくれません．Mathematicaに方程式だと認識させる場合には，左辺と右辺が数学的に等しいことを表す「==」を使います（等号を2つ並べます）．従って，この問題の未知数が満たす関係式は次のように表すことになります．
バスの片道運賃 × 2 × 2 + 100 × 2

1000

では，バスの片道運賃はいくらでしょうか．せっかくですから，Mathematicaに解いてもらいましょう．「次の方程式を解いて未知数を求めよ」という意味の命令は「Solve」になります．次のように指示することで，バスの片道運賃が200円であることがわかります．

- 82 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[113]:=
Out[113]=

SolveAバスの片道運賃 × 2 × 2 + 100 × 2
99バスの片道運賃 → 200==

1000, バスの片道運賃E

Solve@左辺==右辺, 未知数D
解きたい方程式

答えを知りたい未知数

方程式を解く：未知数の値を求めるには

Solveは係数にパラメータを持つ場合も答えを求めてくれますので，次のように解の公式なども調べることが出来ます．3次や4次の場合の解の公式も同様に求めることが出来ます（スペースの関係でここでは取り扱いませんが）．
In[114]:=

SolveAa x2 + b x + c

Out[114]= ::x →

−b −

0, xE

b2 − 4 a c
2a>, :x →−b +b2 − 4 a c
2a>>では，もっと有名な鶴亀算もMathematicaに解いてもらいましょう．問題は「鶴と亀があわせて10匹，足の数があわせて28本であるとき，鶴と亀は何匹いるか．ただし，鶴の足は2本，亀の足は4本とする」です．
「鶴」と「亀」を未知数として次の連立方程式を作ることになりますね．
鶴 + 亀 = 10
鶴 × 2 + 亀 × 4 = 28

まず，Mathematicaに方程式だと認識させる場合には，左辺と右辺が数学的に等しいことを表す「==」を使わなければいけません．そして，連立方程式であることを示すには，方程式をリストで与える必要があります．従って，この鶴亀算の連立方程式は次のように指示をしなければいけません．
9鶴 + 亀10, 鶴 × 2 + 亀 × 4

28=

あとは先ほどと同じく組込み関数のSolveで解いてもらえば良いのですが，今回は未知数が「鶴」と「亀」の2つあるので，未知数もリストで指定する必要があります．従って，次のように指示することで，鶴が6匹，亀が4匹であることがわかります．

- 83 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[115]:=Out[115]=

SolveA9鶴 + 亀

10, 鶴 × 2 + 亀 × 4

99鶴 → 6, 亀 → 4==

28=, 9鶴, 亀=E

Solve@8左辺==右辺, ...<, 8未知数, ...<D

In[116]:=

解きたい連立方程式をリストで答えを知りたい未知数もリストでSolve@8左辺==右辺, ...<, 8未知数, ...<DOut[116]=

解きたい連立方程式をリストで答えを知りたい未知数もリ方程式を解く：複数の未知数の値を求めるには【=と==と===】Mathematicaでは，等号を複数組み合わせて3つの異なる意味を持たせています．等号1つ「=」で「シンボルの定義」，等号2つ「==」で「数学的に等しい
関係」，そして等号3つ「===」で「見た目に等しい関係」です．
ü 結局のところそれは何？，もっと難しい方程式を解いてみよう

今度は少し恣意的ですが，半径が2の円と3次曲線 y = x3 - 1 の交点を求めてみましょう．即ち，次のような連立方程式を解かなければいけません．
x2 + y2 = 2
y = x3 − 1
2

1

-2

-1

1

-1

-2

- 84 -

2

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

そこで，前項で習ったSolveを使い，次のようにMathematicaに解かせると，何やら見たことのない結果が表示されました．これらは何を意味するものでしょうか．
In[117]:=Out[117]=

Solve@8x ^ 2 + y ^ 22, y == x ^ 3 − 1<, 8x, y<D

99y → −1 + RootA−1 + 12 − 2 13 + 16 &, 1E ,3

x → RootA−1 + 12 − 2 13 + 16 &, 1E=,

9y → −1 + RootA−1 + 12 − 2 13 + 16 &, 2E ,3x → RootA−1 + 12 − 2 13 + 16 &, 2E=,

9y → −1 + RootA−1 + 12 − 2 13 + 16 &, 3E ,3x → RootA−1 + 12 − 2 13 + 16 &, 3E=,

9y → −1 + RootA−1 + 12 − 2 13 + 16 &, 4E ,3

x → RootA−1 + 12 − 2 13 + 16 &, 4E=,

9y → −1 + RootA−1 + 12 − 2 13 + 16 &, 5E ,3

x → RootA−1 + 12 − 2 13 + 16 &, 5E=,

9y → −1 + RootA−1 + 12 − 2 13 + 16 &, 6E ,3

x → RootA−1 + 12 − 2 13 + 16 &, 6E==

実は，ある程度次数の大きな方程式の解を，数学的な厳密さを失わずに表示するためには，代数的数と呼ばれる難しい概念を導入する必要があります．解の中に含まれる「Root」というのは，それを表現しているものです．厳密さを失っても良いのでわかりやすい形で解を知りたい場合は，Nで数値化させます．
In[118]:=Out[118]=

N@%D88y → −1.26141, x → −0.639404<, 8y → 0.742818, x → 1.20342<,
8y → 1.74449 − 0.524192 , x → −0.779525 − 1.17308 <,8y → 1.74449 + 0.524192 , x → −0.779525 + 1.17308 <,8y → −1.48519 − 0.213862 , x → 0.497517 − 0.638423 <,8y → −1.48519 + 0.213862 , x → 0.497517 + 0.638423 <<Solveで解を求めてからNで数値化（小数化）するのは面倒ですね．でも安心してください．Mathematicaへの命令には「NSolve」というのもあり，これは「数学的な厳密さは多少失っても良いから，わかりやすい小数の形で解を求めなさい」という意味なので，次のように非常にわかりやすい解を直接求めてくれます．なお，結果を「解」という名前で覚えさせておきましょう．

- 85 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[119]:=Out[119]=

解 = NSolve@8x ^ 2 + y ^ 22, y == x ^ 3 − 1<, 8x, y<D

88x → −0.779525 + 1.17308 , y → 1.74449 + 0.524192 <,8x → −0.779525 − 1.17308 , y → 1.74449 − 0.524192 <,8x → 0.497517 + 0.638423 , y → −1.48519 + 0.213862 <,
8x → 0.497517 − 0.638423 , y → −1.48519 − 0.213862 <,
8x → −0.639404, y → −1.26141<, 8x → 1.20342, y → 0.742818<<

この解を改めて良く見ると，右矢印（Ø）が多用されています．この右矢印はオプシ
ョン（捕捉指示）のときにも利用しましたが，Mathematicaは「左側のものを右側に対応させる」という意味を持つ「置換規則（変換規則）」として認識します．
なぜ，Mathematicaは方程式の解を置換規則で報告してくるのでしょうか．このことを理解するためには，「/.」という記号で行える操作「左の式に含まれる変数を，右側の置換規則で置き換えなさい」を理解する必要があります．
「 x + y」という式の「x」を「3」に置き換えたい（ xに3を代入したい）場合，次のよ
うに「ê.」の左に式を，右側に置換規則「 x Ø 3」を書きます．Mathematicaは右側の置換規則に基づいて，左側に含まれている変数を全て置き換えます．
In[120]:=x + y ê. x → 3

Out[120]=

3+y

同時に「 y」も「z」に置き換えたい場合は，置換規則をリストで指定します．
In[121]:=x + y ê. 8x → 3, y → z<

Out[121]=3+z

置換規則をリストのリストで与えると，次のように最初の置換規則の組の代入結果と，次の置換規則の組の代入結果をリストで返してきます．
In[122]:=
Out[122]=x + y ê. 88x → 3, y → z<, 8x → 4, y → w<<
83 + z, 4 + w<

このような置換規則の仕組みを理解した上で，方程式の解を確認してみると，置換規則のリストのリストになっていることがわかると思います．すなわち，解の組ごとにリストになっているので，次のように「/ .」を使って変数の置き換えをすること
で，解の数のみからなるリストを得ることが出来ます．

- 86 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[123]:=
Out[123]=解のリスト = 8x, y< ê. 解

88−0.779525 + 1.17308 , 1.74449 + 0.524192 <,8−0.779525 − 1.17308 , 1.74449 − 0.524192 <,80.497517 + 0.638423 , −1.48519 + 0.213862 <,80.497517 − 0.638423 , −1.48519 − 0.213862 <,8−0.639404, −1.26141<, 81.20342, 0.742818<<

元の問題ですが，グラフの交点は実数でなければいけないので，解のうち虚部が0でない複素数は関係ありません．従って，解のリストの中から実数だけを取り出す必要があります．このような場合，双子素数などの検出に使った組込み関数Casesを使って，実数のペアになっているリストだけを取り出します．
In[124]:=Out[124]=CasesA解のリスト, 8_Real, _Real<E

88−0.639404, −1.26141<, 81.20342, 0.742818<<

このパターン「{_Real, _Real}」の意味はなんでしょうか．アンダースコアの後ろにはヘッド（頭部）を指定することができ，「Real」とは「実数」を意味します．これ 以 外 に も 次 の よ う に 頭 部 を 調 べ る こ と で ， 「I n t e g e r」 で 「 整数」を，「Rational」で「分数」を，「Complex」で「複素数」（虚数単位は「I」で表す）を，「Symbol」で「シンボル（変数）」を表すことがわかります．
In[125]:=Out[125]=

Map@Head, 81, 1.5, 2 ê 3, 1 + I, Pi<D

8Integer, Real, Rational, Complex, Symbol<【SolveとNSolve】Mathematicaの組込み関数は，英語の単語になっている他，いく
つかの機能の組合せになっている場合（今回のSolveとNSolveのように），単純に組み合わせたものが新たな機能の名称になっていることが多いです．ドキュメントセ
ンターを確認したりしなくても，ある程度機能の内容や，必要な関数の名称がわかったりします．
ü 使えるお金はいくら？，不等式を解いてみよう

今度はもっと現実的な鶴亀算を解いてみましょう．例えば「鶴と亀があわせて9匹か10匹，足の数があわせて28本から32本くらいであるとき，鶴と亀は何匹いるか．ただし，鶴の足は2本，亀の足は4本とする」です．曖昧なので不等式になります．
「鶴」と「亀」を未知数として次の連立不等式を作ることになりますね．
9 ≤ 鶴 + 亀 ≤ 10
28 ≤ 鶴 × 2 + 亀 × 4 ≤ 32

Mathematicaに連立不等式であることを示すには，連立方程式と同じくリストで与える
必要があります．従って，この鶴亀算の連立不等式は次のように指示をしなければい
けません．

- 87 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

In[126]:=Out[126]=

99 ≤ 鶴 + 亀 ≤ 10, 28 ≤ 鶴 × 2 + 亀 × 4 ≤ 32=
99 ≤ 亀 + 鶴 ≤ 10, 28 ≤ 4 亀 + 2 鶴 ≤ 32=

不等式はSolveやNSolveを使って指示を出しても方程式でないのでMathematicaは解
いてくれません．不等式を解かせるには，「Reduce」という命令を使います．この命令の意味は「方程式や不等式を解き，変数に関する条件を簡約しなさい」です．使い方は基本的にSolveと同じです．
In[127]:=

ReduceA99 ≤ 鶴 + 亀 ≤ 10, 28 ≤ 鶴 × 2 + 亀 × 4 ≤ 32=, 9鶴, 亀=E

Out[127]=

I鶴

2 && 亀4 < 鶴 < 6 &&7M »» 2 < 鶴 ≤ 4 && 9 − 鶴 ≤ 亀 ≤14 − 鶴2≤ 亀 ≤ 10 − 鶴 »» I鶴»»

16 − 鶴2

6 && 亀4M

この報告を見ると，鶴が2匹で亀が7匹，鶴が6匹で亀が4匹という答えは分かります
が，他にも何やら複雑な式が出ていて良く分かりません．このような場合
は，Reduceの最後に「鶴」と「亀」は整数だと思って解きなさい，という付加的な命
令「Integers」を付け加えます．そうすると，次のように全ての可能性のある解を得ることが出来ます．
In[128]:=ReduceA99 ≤ 鶴 + 亀 ≤ 10, 28 ≤ 鶴 × 2 + 亀 × 4 ≤ 32=, 9鶴, 亀=,IntegersE

Out[128]=

I鶴

I鶴

2 && 亀4 && 亀7M »» I鶴

6M »» I鶴

3 && 亀5 && 亀6M »» I鶴

5M »» I鶴

4 && 亀5M »»6 && 亀4M

S o l v eや N S o l v eと は 異 な り 結 果 が 置 換 規 則 で な い こ と に 注 意 し て く だ さい．Reduceは指定されたシンボルの満たす条件を簡約するための命令であり，結果が規則でなく条件になっています．
【論理演算】Mathematicaでも他のプログラミング言語と同じく，アンパサンド2つ（&&）で論理積（かつ）を，縦線2つ（||）で論理和（または）を表します．これらの論理演算は，通常の演算記号（+, -, *, /, ^）と同じくMathematicaの至る所で使うことが出来ます．特に，条件判定などで役に立つと思います．
ü 最大値と最小値，もっとも得な値を探し出す

今度はもっと現実的な問題を解いてみましょう．例えば「私の貯金は10万円あります．この中から光熱費と食費，そして旅行費用を出すとした場合，旅行には最大いく
ら使えるでしょうか．なお，先月の金額から推定すると，光熱費は5,000円から
6,500円，食費は25,000円から32,500円必要になります」のようなものです．

- 88 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

最大いくら？という問題をMathematicaに解かせるためには，「Maximize」という命令を使います．これは「制約条件下で指定したものを最大化するにはどうすれば良いか調べよ」という意味です．今回の問題の場合，次のような制約条件下で「旅行費用」を最大化したいわけです．
光熱費 + 食費 + 旅行費用 = 100 000
5000 ≤ 光熱費 ≤ 6500
25 000 ≤ 食費 ≤ 32 500

Maximizeを使った指示の出し方は，SolveやReduceと同じです．最初にリストで制
約条件などを書き，最後に変数のリストを書きます．ただし，制約条件のリストの最初の要素は，それらの制約下で最大にしたい式を書きます（今回の場合は旅行費用です）．従って，次のようにMathematicaに指示を出すことになります．
In[129]:=MaximizeA9旅行費用, 光熱費 + 食費 + 旅行費用

100 000,

5000 ≤ 光熱費 ≤ 6500, 25 000 ≤ 食費 ≤ 32 500=,

9旅行費用, 光熱費, 食費=E

Out[129]=970 000, 9旅行費用 → 70 000, 光熱費 → 5000, 食費 → 25 000==

結果を見ると，光熱費を5000円に，食費を25000円に抑えれば，旅行費用として70000円を出せることがわかりました．簡単な関係なので，わざわざMathematicaに計算してもらわなくても暗算できるかもしれませんが，難しい問題では役に立つでしょう．

Maximize@8最大化したい式, 制約条件, ...<, 8変数,...<D

方程式や不等式での制約条件
最大値を求めたい式なので等号や不等号は含まない
最大値を求める：式を最大化する変数の値は？

一方，逆に旅行費用を最小化したい場合は，「Minimize」という命令を使います．この命令はMaximizeの逆で，リストの最初の要素を最小化する変数の値を求めてくれます．
In[130]:=

MinimizeA9旅行費用, 光熱費 + 食費 + 旅行費用

100 000,

5000 ≤ 光熱費 ≤ 6500, 25 000 ≤ 食費 ≤ 32 500,
68 000 ≤ 旅行費用 ≤ 85 000=, 9旅行費用, 光熱費, 食費=E

Out[130]=

968 000, 9旅行費用 → 68 000, 光熱費 → 6500, 食費 → 25 500==

この他，Solveに対するNSolveなどのように，NMaximizeやNMinimizeなどもあります．

- 89 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

この章のまとめ
この章で学んだことを箇条書きでまとめておきます．
リストには，中括弧（「8」と「<」）を使います．
リストの要素ごとの区切りには，カンマ（「,」）を使います．
文字列は，二重引用符（ダブルクオーテーション：「"」）で囲みます．
˜を押しながらÛで指示をMathematicaに実行（評価）させます．
等号（「=」）を使ってMathematicaにシンボルの値を覚えさせます．
コンテキスト（文脈）を表すには，単一引用符（「`」）を使います．
行の最後にセミコロン（「;」）を付けると結果が表示されません．
疑問符（「?」）をシンボルに付けると知っていることを返します．
「Intersection」は「グループに共通するものを調べよ」「Complement」は「リストから次のリストの要素を取り除きなさい」「Union」は「重複しないように双方の中身を併せなさい」
共通部分「Intersection」と和集合「Union」は「›」と「‹」でも可「AppendTo」は「指定したグループに新しい仲間を加えなさい」「MemberQ」は「あるグループに指定した項目が含まれているか」「はい」が「True」で，「いいえ」が「False」
リストはネストさせて，リストのリストなどを作ることが出来ます．
「遅延的な定義」は「ファイルマネージャでのショートカットやリンク」「:=」が「遅延的な定義」で，「=」が「即時的な定義」「Column」は「リストを列として表示しなさい」「Row」は「リストを行として表示しなさい」「Grid」は「リストを格子状に並べて表示しなさい」「TableForm」は「結果が長方形の表になるようにフォーマットしなさい」
命令の最後に付け加える補足的な指示のことを「オプション」と呼びます．
オプションで使う「→」は「->」をキーボード入力すれば自動変換されます．

リスト：仲間に分けたり，一緒にまとめたり
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

文字列：文章を扱い，自動作文をさせてみよう
1.
2.
3.
4.
5.
6.
7.

「StringLength」は「次の文字列の文字数を調べよ」「StringCount」は「次の文字列の中に指定した文字列が何回出てくるか」
WindowsとUnix(Linux)では‚を押しながら「k」で「式の補完」
Macintoshでは·を押しながら「k」で「式の補完」「StringReplace」は「規則に従って，文字列の単語を置き換えなさい」「%」は「Mathematicaが直前に報告した結果」「%%」で「二つ前の結果」，「%%%」で「三つ前の結果」を表します．

- 90 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.

「StringCases」は「次の文字列の中から，指定した文字列パターン（StringExpression）にマッチする単語（部分文字列）を取り出せ」
文字列パターンの「~~」は「次に続く」の意味です．
文字列パターンの「___」（下線3つ）は「何でもOK」の意味です．
「Length」は「リストの要素数を調べよ」「CharacterRange」は「次の2つの文字の間にある全ての文字を調べよ」「RandomChoice」は「次のグループの中から無作為に要素を取り出し，取り出した要素を元に戻す．これを指示された回数実験せよ」「StringJoin」は「次の語のリストを単語にまとめなさい」「RandomSample」は「次のグループの中から無作為に要素を取り出す（元には戻さない）．これを指示された回数実験せよ」「RandomInteger」は「次の範囲から整数を無作為に取り出せ」「Table」は「次の指示を指定された回数だけ繰り返せ」「Characters」は「次の文字列を一語ずつの文字のリストに分解せよ」「StringJoin」は「<>」（小なり記号，大なり記号）を使っても同じ．
「Map」は「次のリストのそれぞれに対して同じ命令を実行せよ」「If」は「次の条件が満たされたら，指定の命令を実行せよ」「Join」は「複数のリストをひとつのリストにまとめなさい」「Alternatives」は「リストの中のどれか」という意味です．
「Map」を使うときは基本的に，共通しない部分を「シャープ（#）」に，共通する部分の最後に「アンパサンド（&）」を付け加えなければいけません．

数と式：数に隠された秘密を少し覗いてみよう
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.

足し算を行わせるには，プラス記号「+」を使います．
「Plus」は「次の数を足し合わせよ」
Mathematicaでは「数とリストの足し算」を，「リストの各要素ごとに同じ足し算をしたいのだろう」と解釈してくれます．
引き算を行わせるには，マイナス記号「-」を使います．
「Subtract」は「次の2数の引き算をせよ」
Mathematicaでは「数とリストの引き算」を，「リストの各要素ごとに同じ引き算をしたいのだろう」と解釈してくれます．
掛け算には，記号「×」，アスタリスク「*」やスペース「 」を使います．
記号「×」は「Â*Â」で入力できます．
「Times」は「次の数を掛け合わせよ」
Mathematicaでは「数とリストの掛け算」を，「リストの各要素ごとに同じ掛け算をしたいのだろう」と解釈してくれます．
何重になっても計算順序の指定には丸括弧（「(」と「)」）だけを使います．
数のブロック表示の変更は，編集メニューの「環境設定...」で表示されるダイア
ログにて，「外観/数/桁ブロックのサイズ」を変更してください．
割り算を行わせるには，記号「÷」やスラッシュ「/」を使います．
記号「÷」は「ÂdivÂ」で入力できます．
「Divide」は「次の2数の割り算を求めよ」- 91 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.

Mathematicaでは「数とリストの割り算」を，「リストの各要素ごとに同じ割り算をしたいのだろう」と解釈してくれます．
分数らしく入力したい場合は，‚を押しながら「/」を入力します．
累乗（冪乗，指数計算）を行わせるには，記号「^」を使います．
「Power」は「次の累乗を求めよ」
Mathematicaでは「数とリストの累乗」を，「リストの各要素ごとに同じ累乗をしたいのだろう」と解釈してくれます．
指数らしく入力したい場合は，‚を押しながら「^」を入力します．
「Prime」は「n番目の素数を教えなさい」「Attributes」は「次の関数の属性を調べよ」「Litable」は「リストを自動展開して，各要素に関数を適用する」属性「Select」は「次の条件を満たすものだけをリストから抜き出しなさい」「IntegerQ」は「整数かどうか調べなさい」「Cases」は「パターンにマッチする要素をリストから取り出しなさい」「Drop」は「リストの最初の要素から指定した個数分だけ削除しなさい」「Divisors」は「指示した数の約数を全て求めなさい」「Drop」に指示する整数が負の数の場合，リストの最後尾から指示した個数だ
け要素を削除できます．
「Total」は「リストに含まれる要素の合計を計算しなさい」
下線1つ「_」で「何でもOKだが，ひとつだけ」という意味のパターンです．
同じ名前の付いた下線（アンダースコア）は同じものを表すパターンです．
「First」は「リストの最初の要素だけを取り出しなさい」「DeleteCases」は「パターンにマッチする要素を削除しなさい」「N」は「指定した桁数まで小数に直しなさい」
円周率は「Pi」または「ÂpiÂ」と入力します．
自然対数の底は「E」または「ÂeeÂ」と入力します．
「Rationalize」は「小数を分数に変換しなさい」「ToString」は「次の数を文字列に変換しなさい」「StringPosition」は「次の文字列が表れる場所を調べなさい」「Tuples」は「リストの要素から重複を許して指定した個数になるような組合
せを全て求めなさい」「Riffle」は「要素を交互に組み合わせて1つのリストにしなさい」「ToExpression」は「文字列を数式と解釈して，計算を行いなさい」「Position」は「リストの中で次のものが表れる場所を調べなさい」「Extract」は「リストから指定した部分を取り出しなさい」「Expand」は「次の数式を出来るだけ展開しなさい」
Mathematicaでは変数と関数に違いはなく，どちらも「シンボル」です．
「=」は，リストや数に名前を付けて覚えておく「シンボルへの値の割り当て」の意味を持ちます．
「==」（等号を2つ並べます）は，左辺と右辺が数学的に等しいことを表し，Mathematicaに方程式だと認識させます．

- 92 -

All Rights Reserved, Copyright (C) Kosaku Nagasaka 2007

52.
53.
54.
55.
56.
57.
58.
59.
60.

「Solve」は「次の方程式を解いて未知数を求めよ」
連立方程式であることを示すには，方程式をリストで与えます．
等号1つ「=」で「シンボルの定義」，等号2つ「==」で「数学的に等しい関係」，そして等号3つ「===」で「見た目に等しい関係」です．
「NSolve」は「数学的な厳密さは多少失っても良いから，わかりやすい小数の形で解を求めなさい」「/.」は「左の式に含まれる変数を，右側の置換規則で置き換えなさい」
右矢印（Ø）は「左側のものを右側に対応させる置換規則（変換規則）」
パターンにおいて，「Real」で「実数」を，「Integer」で「整数」を，「Ratio
数単位は「I」で表す）を，「Symbol」で「シンボル（変数）」を表します．
「Reduce」は「方程式や不等式を解き，変数に関する条件を簡約しなさい」
Mathematicaでも，アンパサンド2つ（&&）で論理積（かつ）を，縦線2つ（||）で論理和（または）を表します．
「Maximize」は「制約条件下で指定した式を最大化する変数の値を求めよ」- 93 -