Google ClassroomGoogle Classroom
GeoGebraGeoGebra Classroom

スクリプト2(どこでもまとめ計算)

このページはマス旅の一部です。 PCがあればすぐできる「スクリプト」を使った数学を考えましょう。 今回は、PCで則プログラミングできる使い方をさぐる、「どこでもまとめ計算」。

1.どこでもまとめ計算

WindowsのコマンドプロンプトやLinuxのターミナルにも、プログラミング言語レベルの構文(繰り返し処理など)があることはあまり知られていません。 Chromebookでもメニューで選ぶだけでLinux環境が入ります。 Windows(PowerShell)を略して PS Linux(LinuxのTerminalのbash)を略して BS とかきます。 プロンプトのあとに入力データを書いています。 出力は [OUT] からの行です。 // からはコメント行です。 変数を使って反復計算 メッセージなどがうっとうしかったら clear で画面をきれいにします。 <for文が使える> //BS for i in {1..5}; do echo "回数: $i" ; done [OUT] 回数: 1 回数: 2 回数: 3 回数: 4 回数: 5 //「; do ... ; done」がブロックの区切り(他言語の { ... } の代わり)ですね。 //for item in items の構文が使えて、変数指定で出力できるので、簡単なプログラミングが組めそうです。 //PS //PSは foreach を使い、変数名に $ をつけます。こちらは普通に中カッコ { } でブロック化できます。 foreach ($i in 1..5) { Write-Output "回数: $i" } [OUT] 回数: 1 回数: 2 回数: 3 回数: 4 回数: 5 ただ連番を出力するだけでなく、計算処理を組み込めば大量の計算を一瞬でまとめて行えますね。ワクワクしてきます。 <Sum(総和)> //BS //sum=0 で初期化し、ループ内で sum+=i を実行します。 //途中は表示せず、最後に echo $sum で結果を出力します。 sum=0; for i in {1..10}; do ((sum+=i)); done; echo $sum [OUT] 55 //PS //変数には常に $ をつけます。最後に $sum とだけ書けば内容が表示されます。 $sum=0; foreach ($i in 1..10) {$sum += $i };$sum [OUT] 55 ※PSは記述ミスをしたときのエラー表示が真っ赤な文字で強烈です。タイピングには注意しましょう! <Product(総乗・階乗)> //product=1 で初期化し、加算を乗算(*=)に変更します。 //BS product=1; for i in {1..10}; do ((product*=i)); done; echo $product [OUT] 3628800 //PS $product=1; foreach ($i in 1..10) {$product *= $i };$product [OUT] 3628800 <九九の表(2重ループ)> 今度は for を入れ子にして、九九の表を出力してみましょう。 //BS for i in {1..9}; do for j in {1..9}; do echo -n "$((i*j)) "; done; echo ""; done [OUT] 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 //記号が増えてセミコロンだらけですね。 //「; do」がPythonの「:」や他言語の「{」にあたり、「; done」が「}」に相当します。 //echo -n は「改行なし出力」、最後の echo "" は「改行のみ」の処理です。 //PS //PSでは文字出力に Write-Host を使い、改行なし指定は -NoNewline にします。 foreach ($i in 1..9) { foreach ($j in 1..9) { Write-Host "$($i * $j) " -NoNewline }; Write-Host "" } [OUT] (九九表が出力される) <平方数の表> 九九表のアレンジで、$(10i + j)^2$ ($i$ は 1〜9、$j$ は 0〜9)の表を作ってみましょう。 //BS for i in {1..9}; do for j in {0..9}; do echo -n "$(((10*i+j)**2)),"; done; echo ""; done //PS foreach ($i in 1..9) { foreach ($j in 0..9) { Write-Host "$([Math]::Pow(10*$i+$j,2))," -NoNewline }; Write-Host "" } [OUT] 100,121,144,169,196,225,256,289,324,361, 400,441,484,529,576,625,676,729,784,841, ... 8100,8281,8464,8649,8836,9025,9216,9409,9604,9801, <小数の平方数表> さらにアレンジして、$\frac{(10i+j)^2}{100}$ を計算し、桁を揃えてきれいに出力してみます。 //BS //桁揃えに printf を使用します。 for i in {1..9}; do for j in {0..9}; do num=$(echo "scale=2;((10*$i+$j)*(10*$i+$j))/100" \vert{} bc); printf "\%s\t" $num; done; echo ""; done //PS //"{0,7}" -f で7文字分・右揃えの書式を指定します。 foreach ($i in 1..9) { foreach ($j in 0..9) { $num = ((10*$i+$j)*(10*$i+$j))/100; Write-Host ("{0,7}" -f $num) -NoNewline }; Write-Host "" } [OUT] 1.00 1.21 1.44 1.69 1.96 2.25 2.56 2.89 3.24 3.61 4.00 4.41 4.84 5.29 5.76 6.25 6.76 7.29 7.84 8.41 ... 81.00 82.81 84.64 86.49 88.36 90.25 92.16 94.09 96.04 98.01

geogebraならfor文の入れ子をZipとSequenceで簡単に実現できる。

2.GeoGebraでのスマートなコード化

ターミナルでは手続き型(forループ)で泥臭く回した計算ですが、 われらがGeoGebraならどうでしょうか。 GeoGebraには `for` ループがありません。 その代わりに Sequence(数列) Zip(リスト内包表記・写像)を使って、 エレガントに一括処理します。 # 計算部分 nums = Sequence(k, k, 1, 9) numT = Join(nums, {10}) SUM = Sum(numT) // 1から10の和 (55) PROD = Product(numT) // 1から10の積 (3628800) numZ = Join({0}, nums) kuku = Zip(Zip(i * j, i, nums), j, nums) sqrs = Zip(Zip((10*i + j)^2, i, nums), j, numZ) decisqrs = Zip(Zip(s / 100, s, row), row, sqrs) # 表示部分 // FormulaText(decisqrs) を使うと、生成した2次元リストを一瞬で美しいLaTeX形式の行列・表として表示できます! 【GeoGebraならfor文の入れ子もZipとSequenceで鮮やかに解決!】 手続き型プログラミング(PSやBSで書いた2重ループが、 GeoGebraでは数学的な「集合・リストの変換(内包表記)」として非常にすっきりと記述できます。 裏で動く複雑な処理を気にせず、 直感的に数学オブジェクトとして表を生成できるGeoGebraの強力さが際立ちますね。 しかし、 現代的なgeogebraには負けますが、 地味でも1行で2重ループが回せるスクリプトは何かのときに助かるでしょう。