わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

筆算をせずに,2桁どうしのかけ算

 いきなりですが問題です.

35×14を,筆算をせずに計算しましょう.

 さっそくですが解答です.35×14=(7×5)×(2×7)=7×(5×2)×7=7×10×7=10×7×7=490で,求めることができます.カッコの変更にあたり,結合法則を使用します.「かけ算では,じゅんじょをかえてかけても,答えは同じになります。」は,算数の3年の教科書に出現します.
 続いてですが問題です.

2桁どうしのかけ算で,工夫すれば筆算をせずに計算できる式を作りましょう.

 「35×14」については,「10をつくる」ことで,暗算で求めることができました.同じように,2つの因数の一方は5の倍数,他方は2の倍数で,ともに2桁になるものを選べばいい,と言いたいところですが,ここで制約を設けておきます(この制約は「10をつくる」以外の方法でも課します).2桁の数について,十の位にも一の位にも,「0」が出現しないものとします.例えば「25×10」を考えてみると,5×5×2×5とするまでもなく,「25を10倍したら250」で終わってしまうため,対象外とします.20,30,...も(「10をつくる」ではなく「10をわける」で計算できるので),除外します.
 そうすると,「10をつくる」場合,一つの因数は5×「3以上の奇数」,他方は2×「6以上」となります.「3以上の奇数」「6以上」のいずれにも,暗算で計算することを念頭に置き,「9以下」に制限*1すると,これで組み合わせが決まります.集合の表記では,{5a×2b|a∈{3, 5, 7, 9},b∈{6, 7, 8, 9}}となります.
 ここまでの検討で,「100を作る」やり方での2桁のかけ算の式(とその計算)を書き出すことができます.Rubyワンライナーにしました.実行コマンドは以下のとおりで,

ruby -e '$s="×";$q="=";$u="(";$v=")";def m(*a);a.map{|c|Array===c ?($u+m(*c)+$v):c}.join($s);end;1.upto(9){|i|1.upto(9){|j|next if i%2==0||i*5<10||j%5==0||j*2<10;puts [m(i*5,j*2),m([i,5],[2,j]),m(i,[5,2],j),m(i,10,j),m(10,i,j),m(10,i*j),i*j*10].join($q)}}'

出力は以下のようになりました.

15×12=(3×5)×(2×6)=3×(5×2)×6=3×10×6=10×3×6=10×18=180
15×14=(3×5)×(2×7)=3×(5×2)×7=3×10×7=10×3×7=10×21=210
15×16=(3×5)×(2×8)=3×(5×2)×8=3×10×8=10×3×8=10×24=240
15×18=(3×5)×(2×9)=3×(5×2)×9=3×10×9=10×3×9=10×27=270
25×12=(5×5)×(2×6)=5×(5×2)×6=5×10×6=10×5×6=10×30=300
25×14=(5×5)×(2×7)=5×(5×2)×7=5×10×7=10×5×7=10×35=350
25×16=(5×5)×(2×8)=5×(5×2)×8=5×10×8=10×5×8=10×40=400
25×18=(5×5)×(2×9)=5×(5×2)×9=5×10×9=10×5×9=10×45=450
35×12=(7×5)×(2×6)=7×(5×2)×6=7×10×6=10×7×6=10×42=420
35×14=(7×5)×(2×7)=7×(5×2)×7=7×10×7=10×7×7=10×49=490
35×16=(7×5)×(2×8)=7×(5×2)×8=7×10×8=10×7×8=10×56=560
35×18=(7×5)×(2×9)=7×(5×2)×9=7×10×9=10×7×9=10×63=630
45×12=(9×5)×(2×6)=9×(5×2)×6=9×10×6=10×9×6=10×54=540
45×14=(9×5)×(2×7)=9×(5×2)×7=9×10×7=10×9×7=10×63=630
45×16=(9×5)×(2×8)=9×(5×2)×8=9×10×8=10×9×8=10×72=720
45×18=(9×5)×(2×9)=9×(5×2)×9=9×10×9=10×9×9=10×81=810

 Rubyのコードについて少し解説しておきます.文字数を減らすため,変数名とメソッド名は,(グローバル変数を表す「$」は別にして)1文字にしています.またmは,数の並びを引数にとり,かけ算の式の文字列を生成する自作メソッドで,例えばm(15,12)は"15×12"を,またm(3,[5,2],6)は"3×(5×2)×6"を返します.「3以上の奇数」「6以上」は,「next if i%2==0||i*5<10||j%5==0||j*2<10」でスキップ*2しない場合となります.
 16通りの式が出て,めでたしめでたしではありません.これは「10をつくる」ことで暗算できる方法でしたが,その発展形として,「100をつくる」方法があります.一例をあげると「25×32」です.25×32=25×(4×8)=(25×4)×8=100×8=800で求められます.
 計算の途中に「100をつくる」ための,2つの2桁の数はというと,一つの因数は「25」または「75(=25×3)」,他方は「4の倍数」(で,2桁で表され1の位は0にならないもの)となります.一つの因数が,25の倍数となる理由は,100を素因数分解することで分かります.2×2×5×5ですが,ここでもし,2回出現する5を,一つずつ,2つの(2桁の数の)因数として振り分けると,次に,100の素因数になる2を振り分けたときに,2桁の数の少なくとも一方が,10の倍数となり,1の位が0になってしまうので,そういう振り分け方ができないのです.
 2桁の数を九九の範囲で分解できる必要もあるので,「4の倍数」のところは,4×{3, 4, 6, 7, 8, 9}となります.
 「100を作る」やり方での,2桁のかけ算の式(とその計算)を生成する,Rubyワンライナーは以下のとおりで,

ruby -e '$s="×";$q="=";$u="(";$v=")";def m(*a);a.map{|c|Array===c ?($u+m(*c)+$v):c}.join($s);end;[1,3].each{|i|3.upto(9){|j|next if j%5==0;puts [m(i*25,j*4),m(*(i>1?[[i,25],[4,j]]:[25,[4,j]])),m(*[i,[25,4],j][(i>1?0:1)..3]),m(*[i,100,j][(i>1?0:1)..2]),(i>1?[m(100,i,j), m(100,i*j)]:nil),i*j*100].compact.flatten.join($q)}}'

出力は以下のようになりました.

25×12=25×(4×3)=(25×4)×3=100×3=300
25×16=25×(4×4)=(25×4)×4=100×4=400
25×24=25×(4×6)=(25×4)×6=100×6=600
25×28=25×(4×7)=(25×4)×7=100×7=700
25×32=25×(4×8)=(25×4)×8=100×8=800
25×36=25×(4×9)=(25×4)×9=100×9=900
75×12=(3×25)×(4×3)=3×(25×4)×3=3×100×3=100×3×3=100×9=900
75×16=(3×25)×(4×4)=3×(25×4)×4=3×100×4=100×3×4=100×12=1200
75×24=(3×25)×(4×6)=3×(25×4)×6=3×100×6=100×3×6=100×18=1800
75×28=(3×25)×(4×7)=3×(25×4)×7=3×100×7=100×3×7=100×21=2100
75×32=(3×25)×(4×8)=3×(25×4)×8=3×100×8=100×3×8=100×24=2400
75×36=(3×25)×(4×9)=3×(25×4)×9=3×100×9=100×3×9=100×27=2700

 Rubyのプログラムコードについて,最初の因数が25か,75かで,別々のワンライナーにする方がすっきりすると思いつつも,1つで両方を扱いました.途中の「m(*[i,[25,4],j][(i>1?0:1)..3])」は,i>1すなわち最初の2桁の数が75のとき,m(i,[25,4],j)を呼び出すのに対し,そうでないとき,言い換えると最初の2桁の数が25のときは,m([25,4],j)を呼び出します.
 「10をつくる」「100をつくる」の次に,「1000をつくる」というわけにはいきません.125×8=1000となり,2桁の数の範囲を超えてしまうからです.
 ですが別の,「つくる」方法があります.「111をつくる」という考え方です.37×3=111です(37は素数なので,これ以上分解できません).このことを使って例えば,37×24=37×(3×8)=(37×3)×8=111×8=888と求められます.
 2つの2桁の数の,一つは,37またはその2倍の74です.もう一つは,3×{4, 5, 6, 7, 8, 9}とすれば,2桁の数になります.なのですが,74×27は,111×18となって,暗算で計算できるとはいいがたいです.工夫して計算したとき,111×「1桁の数」になる場合に,限ることにします.
 Rubyワンライナーは以下のとおりで,

ruby -e '$s="×";$q="=";$u="(";$v=")";def m(*a);a.map{|c|Array===c ?($u+m(*c)+$v):c}.join($s);end;1.upto(2){|i|1.upto(9){|j|next if i*j>=10||j*3<10;puts [m(37*i,3*j),m(*(i>1?[[i,37],[3,j]]:[37,[3,j]])),m(*[i,[37,3],j][(i>1?0:1)..2]),m(*[i,111,j][(i>1?0:1)..2]),(i>1?[m(111,i,j),m(111,i*j)]:nil),111*i*j].compact.flatten.join($q)}}' | lv

出力は以下のとおりとなりました.

37×12=37×(3×4)=(37×3)×4=111×4=444
37×15=37×(3×5)=(37×3)×5=111×5=555
37×18=37×(3×6)=(37×3)×6=111×6=666
37×21=37×(3×7)=(37×3)×7=111×7=777
37×24=37×(3×8)=(37×3)×8=111×8=888
37×27=37×(3×9)=(37×3)×9=111×9=999
74×12=(2×37)×(3×4)=2×(37×3)×4=2×111×4=111×2×4=111×8=888

 件数としては,「10をつくる」という工夫ができるかけ算は,16通り,「100をつくる」は12通り,「111をつくる」は7通りの,合計35通りとなりました.2つの数を積の形で分解し,かける順番を変えて「10」「100」「111」のいずれかをつくり,残りの因数をかけることで,答えを求めています.
 他の工夫の仕方として,99×53=(100-1)×53=100×53-1×53=5300-53=5247とするものや,https://twitter.com/takehikom/status/1168157548320448512のリンク先にある74×76=5624,35×35=1225のような速算法(簡便算)があります.いずれも,計算の途中に加減算を用いています.


 本日の元ネタです.

そのひと言で授業・子供が変わる!  算数7つの決めゼリフ

そのひと言で授業・子供が変わる! 算数7つの決めゼリフ

 一方で,例えば4年生の単元「工夫して計算しよう」です。

25×12を工夫して計算しよう。

 という問題があったとします。

①25×12=5×5×3×4=(5×5×3)×4=75×4
②25×12=5×5×3×4=(5×3)×(5×4)=15×20
③25×12=25×4×3=(25×4)×3=100×3

 の3つの考え方が出てきました。3つとも工夫して計算の方法を考えているようですが,①はもっと工夫ができますし,②は順番を入れ替えており,3つの考え方では一番時間がかかります。100のまとまりを見つけて計算するという③が一番早く・簡単にできる考え方です。「12×25」といった似たような問題では③の考えを使ってもらいたいものです。このときには,「は・か・せ」と問うことは有効です。
(p.13)

 この本は,台形面積・はかせどん2018年・2019年の出版物に見る「1あたり」 - かけ算の順序の昔話で取り上げています.
 積の形で分解するというのは,全国学力・学習状況調査の算数Bでも出題されています.全国学力テストの,乗法の結合法則の出題 - かけ算の順序の昔話で整理しており,例題または出題における「25×12」「25×32」「37×24」の式は,今回,作成したワンライナーの出力に含まれています.

*1:「15×22=3×5×2×11=330」は,除外されます.

*2:RubyのnextはC言語のcontinueに対応します.「next if...」を,C言語で書き換えるなら,「if (i%2==0||i*5<10||j%5==0||j*2<10) continue;」となります.