かけ算の順序の昔話

算数教育について気楽に書いていきます。

1行目×7=2行目


算数・数学授業のための数学的コミュニケーション論序説』p.141の図です.「1行目×7=2行目」「1行目×9=3行目」「1行目×3=4行目」というかけ算の式があります.
15桁の整数を7倍しているのではなく,1行目の15個の数それぞれに対して,7倍して10で割ったあまりが,すぐ下(2行目)の数に一致します.1行目と3行目,1行目と4行目の関係も同様です.
間に式を入れなければ,こうなっています.

なんとも,規則的です.
これは何なのかというと,フィボナッチ数列の1の位を取り出してできる数列を,15で折り返しています.1の位だけを見ていくと,周期があって,それは60です.61番目は1,62番目も1となり,1番目・2番目の数と一致します(そして,それより小さな周期はありません).
ここから本を離れます.配列に,1個の数をかけると,その配列の各要素にかけ算をすることになる…といえば,Rというプログラミング言語が思い浮かびます.
動作確認をしてみました.「$ 」と「> 」はプロンプトで,「>」だけの行はEnter空打ちです.

$ R
R version 2.15.1 (2012-06-22) -- "Roasted Marshmallows"
Copyright (C) 2012 The R Foundation for Statistical Computing
ISBN 3-900051-07-0
Platform: i686-pc-cygwin (32-bit)
(略)

> a <- c(1,1)
> for(i in seq(60)) a[i+2] <- (a[i+1]+a[i]) %% 10
>
> options(width=34)
> a
 [1] 1 1 2 3 5 8 3 1 4 5 9 4 3 7 0
[16] 7 7 4 1 5 6 1 7 8 5 3 8 1 9 0
[31] 9 9 8 7 5 2 7 9 6 5 1 6 7 3 0
[46] 3 3 6 9 5 4 9 3 2 5 7 2 9 1 0
[61] 1 1
> a1 <- a[1:15]
> a2 <- a[16:30]
> a3 <- a[31:45]
> a4 <- a[46:60]
>
> a1
 [1] 1 1 2 3 5 8 3 1 4 5 9 4 3 7 0
> a2
 [1] 7 7 4 1 5 6 1 7 8 5 3 8 1 9 0
> a3
 [1] 9 9 8 7 5 2 7 9 6 5 1 6 7 3 0
> a4
 [1] 3 3 6 9 5 4 9 3 2 5 7 2 9 1 0
>
> (a1 * 7) %% 10
 [1] 7 7 4 1 5 6 1 7 8 5 3 8 1 9 0
> (a1 * 9) %% 10
 [1] 9 9 8 7 5 2 7 9 6 5 1 6 7 3 0
> (a1 * 3) %% 10
 [1] 3 3 6 9 5 4 9 3 2 5 7 2 9 1 0
>
> unique(((a1 * 7) %% 10) == a2)
[1] TRUE
> unique(((a1 * 9) %% 10) == a3)
[1] TRUE
> unique(((a1 * 4) %% 10) == a4)
[1] FALSE  TRUE
> unique(((a1 * 3) %% 10) == a4)
[1] TRUE
> 
> c((a1 * 7) %% 10, a2)
 [1] 7 7 4 1 5 6 1 7 8 5 3 8 1 9 0
[16] 7 7 4 1 5 6 1 7 8 5 3 8 1 9 0
> c((a2 * 7) %% 10, a3)
 [1] 9 9 8 7 5 2 7 9 6 5 1 6 7 3 0
[16] 9 9 8 7 5 2 7 9 6 5 1 6 7 3 0
> c((a3 * 7) %% 10, a4)
 [1] 3 3 6 9 5 4 9 3 2 5 7 2 9 1 0
[16] 3 3 6 9 5 4 9 3 2 5 7 2 9 1 0
> c((a4 * 7) %% 10, a1)
 [1] 1 1 2 3 5 8 3 1 4 5 9 4 3 7 0
[16] 1 1 2 3 5 8 3 1 4 5 9 4 3 7 0
>
> ((a1 * a2 * a3 * a4) %% 10 )[1:14]
 [1] 9 9 4 9 5 4 9 9 4 5 9 4 9 9
>
> q()
Save workspace image? [y/n/c]: n

R言語の文法やコードの読み方は,こんな感じです:

  • 代入は「<-」を使います.
  • 「c(引数)」は,ベクトルを作ります.後ろのほうで出てきますが,2つのベクトルの連接は,「c(ベクトル1, ベクトル2)」と書けます.「seq(60)」は,1, 2, ..., 60で構成されるベクトルです.
  • 剰余の演算子は「%%」です.今回は使用していませんが,「/」は整数同士であっても商は実数になり得ます.整数の商を求めるには,「%/%」という演算子を用います.5/2,5%/%2,5%%2はそれぞれ2.5,2,1となります.
  • 「options(width=34)」は34文字で改行せよという指示です.これで,1桁の数は15個出力したら改行となるわけです(要素数が100未満なので,うまくいっています).
  • 代入では何も出力せず,式(変数名のみも)を書いてEnterとするとその内容が出力されます.「[1]」や「[16]」は,ベクトルの1番目,16番目から出力しますよという意味です.
  • 「a[1:15]」は,ベクトルaの1番目から15番目までからなるベクトルを意味します.先頭は1(1オリジン)です.
  • 7をかけるのは「ベクトル * 7」,10で割ったあまりは「ベクトル %% 10」です.
  • unique(ベクトル1 == ベクトル2)は,ベクトル1とベクトル2の各成分を比較して,真偽値(からなるベクトル)を求めてから,unique関数の適用で重複を取り除いています.これにより,ベクトル1とベクトル2の対応する成分がすべて等しいときかつそのときに限り,結果が「TRUE」になります.
  • 最後の式は,4行15列を列ごとにかけて,1の位を求めています.15番目を取り除いています.4と5と9からなる,左右対称な数列が出来上がりました.