2021/03/27

10. さんすう(三数)パズルをスクラッチで作ってみた。

さんすう(三数)パズルをスクラッチで作ってみた。

 前々回 8 回目で にすう(二数)パズルを作ってみた。
 が、パズルとしては面白くない。
 足し算には引き算、掛け算には割り算をすれば答えがすぐにわかるので。

 そこで、よんすうパズル よりは簡単だけど、
 まあまあ楽しめる さんすうパズル を作ってみた。

 スクラッチのプログラムは結構大きなものになってしまったので、
 ここでは解説をしない。

 プログラムをスクラッチのホームページに sansuu-puzzle として
 にアップしてある。これを実行してみよう。

0. 旗をクリックする。


1. 猫をクリックすると a, b, c, z に数が表示される。


2. a, b, c を使って z にする計算式を考える。
 いろいろ答えはある。1+4-1=1x4x1=4÷(1x1) などなど。
 たとえば 4÷(1x1) を計算してみよう。

3. キーボードで a, b, c のいずれかの文字を入力すると、その文字の値が e に入る。
 まず 1x1 を入力するために、a にある 1 を e に入れよう。
 キーボードの a のキーを押すと e に 1 が入る。


4. キーボードで 1 を押すと、O に +、2 を押すと -、3 には x、4 には ÷ が入る。
 1x1では掛け算なのでキーボードの 3 を押す。


5. f に入れる数を a, b, c の残っている文字をキーボードで入力。
 f には c の 1 を入れたいので、キーボードの c を押す。


 f に 1 が入り、g に 1x1 の計算結果が表示された。

6. h に入れる数を a, b, c, g の残っている文字をキーボードで入力。
 h には b の 4 を入れたいので、キーボードの b を押す。


7. O2 に入れる演算子をキーボードから入力。 1:+, 2:-, 3:x, 4:÷ 
 ここでは割り算なのでキーボードの 4 を押す。


8. i に入れる数を a, b, c, g の残っている文字をキーボードで入力
 1x1 の結果が入っている g を i に入れる。


 4÷(1x1) の結果が j に表示された。

9. 正解のときは経過時間を表示
10. 猫をクリックすると新しい問題が表示される。

このプログラムは必ず答えがあるように問題を作っている。
プログラムの「このスプライトがクリックされたとき」の部分が
解のある問題を作成している部分。

先に計算する e O f = g の e と f は、a 以外の b, c と、b 以外の a, c、
c 以外の a, b を用いる3通りの場合がある。
O と O2 の演算子はそれぞれ 4 通りの場合がある。

足し算と掛け算は交換可能(つまり a+b=b+a, axb=bxa)なので、一通りと数える。
引き算は結果が負にならない一通り、割り算は割り切れるときだけを作る。
このようにすると、計 3x4x4=48 通り以下の式ができ、
それぞれの式の計算結果を Zs というリストに蓄える。

このリストの中から乱数で z を選び、出題している。
したがって、a, b, c を使って、必ず z を作ることができる問題になっている。

プログラムは大きく複雑だが、解読してみると、
自分でプログラムを作るときのヒントが得られると思う。

2021/03/20

9. Scratch でリンゴを数えてみよう。

1. まず、よんすうパズル の問題。今回は少し難しめ。楽しんでね。
 a. 2235
 b. 2289
 c. 2334
 d. 3357
 e. 5669

2. スクラッチのスプライトには「クローン」という分身の術を使える。
 リンゴを数えるパズルをクローンを使って作ってみよう。

 A. リンゴをいくつか画面上にばらまく。


  これは次のようにコードで表す。

  リンゴのコード
   旗がクリックされたとき
   大きさを (30) %にする
   [こすう] を ((6) から (15) までの乱数 ) にする
   [かず] を (0) にする
   [ばんごう] を (0) にする
   (こすう) 回繰り返す
   |(自分自身)のクローンを作る

  これにより こすう 個のクローンリンゴができる。

  ここで変数 こすう は乱数で生成したリンゴの個数を蓄えている変数。
  変数 かず はリンゴを何個まで数えたかを覚えておく変数で初期値は 0。
  変数 ばんごう はリンゴのスプラウトのそれぞれのクローンが
  何番めにクリックされたかを覚えておくための変数で、初期値は 0。
  この変数 ばんごう を作るときは「このスプライトのみ」を指定する。


  リンゴのコード
   クローンされたとき
   [ばんごう] を (0) にする
   x座標を ((-180) から (220) までの乱数)、
    y座標を ((-60) から (170) までの乱数)) にする。
   表示する

  クローンされたそれぞれのリンゴは、自分の番号をまずは 0 にし、
  画面上の乱数で指定された位置に表示される。

  猫のコード
   旗がクリックされたとき
   大きさを (50) %にする
   x座標を (-215) にする
   y座標を (-65) にする

  猫を画面左下から少し上におく。
 
 B. リンゴを一つひとつクリックして数える。
  リンゴをクリックすると、何番目にクリックされたかを表示し、
  猫の隣に移動する。

  リンゴのコード
   このスプライトがクリックされたとき
   もし <(ばんごう) = (0) > なら
   |[かず] を (1) ずつ変える
   |[ばんごう] を (かず) にする
   |(ばんごう) と (0.3) 秒言う
   |もし <(ばんごう) < (11) > なら
   ||(0.2) 秒でx座標を (((ばんごう) * (35)) - (200)) に、y座標を (-80) に変える
   |でなければ
   ||(0.2) 秒でx座標を ((((ばんごう) - (10)) * (35)) - (200)) に、y座標を (-60) に変える
   |もし <(かず) = (こすう) > なら
   ||(全部数えた) を送る
   でなければ
   |(ばんごう) と (1) 秒言う

  それぞれのクローンリンゴはクリックされていないときは、ばんごう は 0 である。
  初めてクリックされたときだけ、
  何個まで数えたかを覚えておく変数 かず を 1 増やし、
  このクリックされたリンゴの ばんごう を かず の値にする。
  数えたリンゴは猫の右側に整列するが、10個を超えたら、一段上に並べる。
  全てのリンゴをクリックすると、数えた かず がリンゴの個数 こすう と一致するので、
  メッセージ 全部数えた を猫に送る。
  すでにクリックしてあるリンゴを再度クリックしたときは、
  そのクローンリンゴの ばんごう を表示する。

  猫のコード
   [全部数えた] を受け取ったとき
   (リンゴはいくつある?) と聞いて待つ
   もし <(答え) = (こすう)> なら
   |(せいかい) と (2) 秒言う
   でなければ
   |(ちがっているよ) と (2) 秒言う
   |(こたえはぼくをクリックしてね) と (2) 秒言う

  猫はメッセージ 全部数えた を受け取ると、(リンゴはいくつある?) と言う。
  画面の下に入力欄が表示されるので、キーボードからリンゴの個数を入力する。
  猫をクリックしたときの動作は、次のコードで指定する。

  猫のコード
   このスプライトがクリックされたとき
   もし <(答え) = ()> なら
   |(リンゴをくりっくして、かぞえてみよう!) と (2) 秒言う
   でなければ
   |((こすう) と (こだね!)) と (2) 秒言う

 このスクラッチのプログラムは count として
 に置いた。

2021/03/13

8. にすうパズルを Scratch で!

A. 久しぶりに よんすうパズル の問題。
 a. 2247
 b. 2269
 c. 2288
 e. 2357
 f. 3468
 これらの問題はそれぞれ複数の解がある。2つ以上、見つけてみよう。

B. にすうパズル のプログラム
    2つの数の和、差、積、商の問題を出題するスクラッチのプログラムを
 前々回、前回に作った。

 今回は、a の数字と b の数字を使って z の数を作るパズル
 (これを にすうパズル と呼ぶことにする)を出題するプログラムを作ってみよう。

 0. 旗をクリックすると次の画面が表示される。(これを n=0 の画面とする。)

 1. 猫をクリックすると、a と b に数字が表示され、これらの数に対して、
  和、差、積、商のどれかの演算で計算した結果が z に表示される。 
  たとえば、次の画面になる。(これを n=1 の画面とする。)



 2. 和、差、積、商のどの演算をしたかを考える。パズルが頭の中で解けたら、
  その式を e, f に入力する。 
   キーボードの a を押すと a にある数字が e に入り、b にある数字が f に入る。
   キーボードの b を押すと b にある数字が e に入り、a にある数字が f に入る。
  上の例ではキーボードの b を押し、次の画面になる。(これを n=2 の画面とする。)


 3. 演算子を入力する。
   + のとき 1、
   − のとき 2、
   x のとき 3、
   ÷ のとき 4 
  をキーボードから入力。式の計算結果が g に表示される。 
  上の例ではキーボードの2を押すと次の画面になる。(これを n=3 の画面とする。)


 スクラッチのプログラムを順に見ていこう。 

 0. 旗を押したときに


  を表示したい。まずは、コード左側の画面の変数をクリックし、
  「変数を作る」を使って、a, b, z, e, O, f, =, g を作る。
  これらはチェックをつけ、画面に表示し、場所を上記のように移動しておく。
  変数 = を画面上で右クリックし、「大きな表示」を選択しておく。
  これらの変数の値はプログラムで設定する。

  画面上に表示されていないが、n, Oa, za も作る。
  変数 n は、どの画面が表示されているかを覚えておくための変数で、最初は 0。
  変数 Oa は、正解の演算子を覚えておく変数。
  変数 za は、割り算が割り切れるようにするための作業用の変数。
 

  スクラッチのプログラムを、このように画像で表示すると、
  わかりやすいと思うがこのように画像を表示するのは面倒だ。サボりたい。
  そこで上記のプログラムを次のように書くことにしよう。

     旗がクリックされたとき
     [n] を (0) にする
     変数 [n] を隠す
     [a] を () にする
     変数 [a] を表示する
     [b] を () にする
     変数 [b] を表示する
     [z] を () にする
     変数 [z] を表示する
     変数 [za] を隠す
     [e] を () にする
     変数 [e] を表示する
     [O] を () にする
     変数 [O] を表示する
     変数 [Oa] を隠す
     [f] を () にする
     変数 [f] を表示する
     [=] を (=) にする
     変数 [=] を表示する
     [g] を () にする
     変数 [g] を表示する
     (私をクリックするとスタート) と (2) 秒言う

 1. 猫をクリックしたときの動作を次のように書く。

     このスプライトがクリックされたとき
     もし <(n)=(0)> なら
     |[a] を ((1) から (9) までの乱数 ) にする
     |[b] を ((1) から (9) までの乱数 ) にする
     |[Oa] を ((1) から (4) までの乱数 ) にする
     |makez
     |変数 [a] を表示する
     |変数 [b] を表示する
     |変数 [z] を表示する
     |[e] を () にする
     |[O] を () にする
     |[f] を () にする
     |[g] を () にする
     |[n] を (1) にする

  つまりスクラッチで書くと次のようになる。


  ここで makez は a と b に演算子 Oa を使って z の値を決めるプログラム。
  a-b が負にならないように、a÷b が割り切れるようにする。 

     定義 makez
     もし <(Oa)=(1)> なら
     |[z] を ((a + (b)) にする
     でなければ
     |もし <(Oa) = (2)> なら
     ||もし <(a) > (b)> なら
     |||[z] を ((a) - (b)) にする
     ||でなければ
     |||[z] を ((b) - (a)) にする
     |でなければ
     ||もし <(Oa) = (3)> なら
     |||[z] を ((a) x (b)) にする
     ||でなければ
     |||[za] を ((a) x (b)) にする
     |||[z] を (a) にする
     |||[a] を (b) にする

  念の為、スクラッチで表すと。

  この処理が終わると n=1となり、e, f を入力するときの画面が表示されている。

 2. 和、差、積、商のどの演算をしたかを考え、その式を e, f に入力する。 
   キーボードの a を押すと a にある数字が e に入り、b にある数字が f に入る。
   キーボードの b を押すと b にある数字が e に入り、a にある数字が f に入る。

  これを処理するために、キーボードの a が押されたときの処理と、
  キーボードの b が押されたときの処理を次のように書く。

     [a] キーが押されたとき
     もし <(n) = (1)> なら
     |[e] を (a) にする
     |[f] を (b) にする
     |[n] を (2) にする

     [b] キーが押されたとき
     もし <(n) = (1)> なら
     |[e] を (b) にする
     |[f] を (a) にする
     |[n] を (2) にする

  この処理が終わると n=2 の画面となり、演算子を入力するときの画面となる。

 3. 入力したい演算子が + のとき 1、− のとき 2、x のとき 3、÷ のとき 4 を入力する。
  プログラムは次のように書く。

     [1] キーが押されたとき
     もし <(n) = (2)> なら
     |[O] を (+) にする
     |[g] を ((e) + (f)) にする
     |[n] を (3) にする
     |(n=3) を送る

     [2] キーが押されたとき
     もし <(n) = (2)> なら
     |[O] を (-) にする
     |[g] を ((e) - (f)) にする
     |[n] を (3) にする
     |(n=3) を送る

     [3] キーが押されたとき
     もし <(n) = (2)> なら
     |[O] を (x) にする
     |[g] を ((e) x (f)) にする
     |[n] を (3) にする
     |(n=3) を送る

     [4] キーが押されたとき
     もし <(n) = (2)> なら
     |[O] を (➗) にする
     |[g] を ((e) ➗ (f)) にする
     |[n] を (3) にする
     |(n=3) を送る

  この処理が終わると n=3 の画面となり、メッセージ n=3 を送る。

 4. 猫は、メッセージ n=3 を受け取ると、計算結果を g に表示し、
  z と一致しているか調べ、合っていれば「正解です!!!」と表示し、
  違っているときは「うーん...」と表示する。
  次の問題をするときのために「私をクリックするとスタート」と表示し、
  n=0  とする。
  プログラムは次のように書く。

     [n=3] を受け取ったとき
     もし <(g) = (z)> なら
     |(正解です!!!) と (2) 秒言う
     でなければ
     |(うーん...) と (2) 秒言う
     (私をクリックするとスタート) と (1) 秒言う
     [n] を (0) にする。

 このプログラムは nisuu-puzzle-simple2 として

 また、このプログラムと動作は同じだが、操作方法を表示するプログラム
 nisuu-puzzle-simple と、入力のやり直しができる nisuu-puzzle も
 Math Quiz Generator https://scratch.mit.edu/studios/28927140 に置いてある。

2021/03/06

7. スクラッチで算数ドリルを作問

1. スクラッチで算数ドリル

 前回の後半で、足し算練習問題出題プログラムを作った。

 掛け算の練習問題を出題するプログラムは、
 足し算のプログラムを次のように 3 箇所変更する。
 + のスプライトを x のスプライトに、
 「a と + と b と は? と聞いて待つ」を「a と x と b と は? と聞いて待つ」に、
 「もし a + b = c なら」を「もし a x b = c なら」に変える。

 引き算の練習問題は答え c が負にならないように出題する必要がある。
 「a と + と b と は? と聞いて待つ」を「a と - と b と は? と聞いて待つ」に、
 「もし a + b = c なら」という部分を「もし a - b = c なら」に変えるだけだと
 c が負になることがある。そこで a < b のとき、a と b を入れ替える。


 このようにすると引き算の練習問題を出題するプログラムは以下のようになる。



 割り算の練習問題は答え c が分数にならないように出題する必要がある。
  b と d に 1 から 9 までの乱数を入れ、a には b x d を入れる。
 すると、a ÷ b = (b x d) ÷ b = d なので、a ÷ b は分数になることはない。
 そこで答え c に対して、それが正しいかは「もし d = c なら」で判定する。

 このようにすると割り算の練習問題を出題するプログラムは、
 足し算のプログラムの a と b を乱数で設定する部分を、
 + のスプライトを ÷ のスプライトにし、
 b と d に 1 から 9 までの乱数を入れ、a には b x d を入れるようにし、
 「a と + と b と は? と聞いて待つ」を「a と ÷ と b と は? と聞いて待つ」に、
 「もし a + b = c なら」を「もし d = a なら」に置き換えればよい。


 足し算、引き算、掛け算、割り算の練習問題(ドリル)を出題するプログラムを、
 スクラッチのホームページ上に共有で公開している。

2. 前回の解説「数字を小さい順に並べてできる 4 桁の数の個数」の続き

 前回は 4 桁の数で右となりの数字が同じか大きくなっている数の個数を、
 スクラッチのプログラムで数えてみた。

 そのプログラムではに対応した方法で 1 を一つひとつ数える。
 前々回、5回目の記事で示したように、この右端の
   d が c から d が 9 になるまで 1 を 10-c 個足し合わせる
 つまり ( ... ((1+1)+1) ... +1) のような足し算をせよという意味の式だ。
 1 を 10-c 個足し合わせれば、その計算結果は足し算をしなくても 10-c である。
 さらにこの結果を使うと、前々回示したように
 1 を足し合わせることをせずに、
 のように c が 0 のとき 10、1 のとき 9、... 、9 のとき 1 を足し合わせればよい。
 この足し算はたす順序を変えて、 1+2+ ... +9+10 と表すことができ、
 上に示したようにと書くことができる。
 
 この式は、足し算の順序を反転した2つの式を加え合わせることによって
 のように計算できることを前々回示した。
 一般にとなることも前々回に示した。

 この公式を用いると
 のように 10-b 個の数の足し算をせずに、
 引き算2回、掛け算1回、割り算1回で計算することができる。

 この式を用いると 3 桁の数で右となりの数字が同じか大きくなっている数の個数は
 のように表すことができる。ここで i=10-b とおくと、
 b=0 のとき i=10、b=1 のとき i=9、... 、b=9 のとき i=1 となることから、上式右辺は
 と変形できる。証明は後日示すが、
 が成り立つ。これを使うと
 となり、 3 桁の数で右となりの数字が同じか大きくなっている数の個数が
 220 個であることがわかる。

 4 桁の数で右となりの数字が同じか大きくなっている数の個数を数式で計算してみよう。
 公式 を用いる。この証明も後日示す。



 数式での計算はちょっと大変だったが、プログラムで数えた個数と同じ結果が得られた。

 プログラムを作るのと、この計算ではプログラムを作る方が楽のようだ。

 問題によってはプログラムの実行時間が非常にかかり、計算機では手に負えなくなる。
 そのようなときは、計算機が無駄な計算をしなくてもよいように、
 数学でわかることを使ってプログラムを作る。数学は強力だ。

20. 円錐の半分?

17-19 で三角形、四角形の面積を半分にする問題を解いた。 今回は円錐を半分にする実験をしてみよう。 まず、円錐を作るための図形をスクラッチで描いてみた。 プログラムはここ。 https://scratch.mit.edu/projects/561804896 これを実行すると...