地元で育む次世代のこども達!『越前がにロボコン2020』待望の「中学生部門」を新設し、業種問わず「企業実業団チーム」大募集中!!

地元で育む次世代のこども達!『越前がにロボコン2020』待望の「中学生部門」を新設し、業種問わず「企業実業団チーム」大募集中!!

今年も開催「越前がにロボコン」!

第4回となる今回は福井県のご協力もいただき「実業団チーム」大募集!!あなたの会社で地元の小中学生を応援して選手として送り出しませんか?

白熱するロボット決勝戦、こども達だけでなく おとな もいっしょになって楽しめる「越前がにロボコン」はまさに eSports。

プログラミングだけではない、物理的なの創意工夫もたくさん詰まったこども達のロボット。多くの要望に応えて今年は 中学生部門 も創設!

福井の地元で育む次世代のこども達「こどもプログラミング実業団」、銀行業、建設業、小売業、学校関係、行政関係、業種問わず参加企業募集中!!

ご一報くださいっ!










.

プログラミングすれば一目瞭然、にわかに信じがたい「モンティ・ホール問題」をシミュレーションしてみよう!

プログラミングすれば一目瞭然、にわかに信じがたい「モンティ・ホール問題」をシミュレーションしてみよう!

アメリカのTV番組で生まれたという興味深い「モンティ・ホール問題」。

「3つのうち1つが当たりのくじ引き」で、あなたが1つを選んだ後に司会者がハズレを1つ減らしてくれます。この段階でチェンジ可能な場合「あなたはチェンジしますか?しませんか?」という問題。

パッと聞くと、もはや 2つ となった目の前のくじ、変えようが変えまいが当たる確率は 1/ 2 な気がします。

ではコンピュータでシミュレーション、今回は「こどもOS IchigoLatte JS」で。

まずは、

var hit = rnd(3);

当たりをセット、このプログラムの意味は以下。

  • var
    • メモるための箱を準備
  • hit
    • そのメモ箱の名前は “hit”
  • = rnd(3)
    • そのメモ箱の中にランダムな数 0〜2 をメモる

次は、

var chosen = rnd(3);

3つのうち1つを選択。

そしてここでハズレを一つ減らします。

var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
  reduced = rnd(3);
}

これの意味は、

  • reduced
    • メモ箱の名前は “reduced”
  • while( 〇〇 ){ □□ }
    • 〇〇〇 の間 □□□ をくり返す
  • (reduced==hit) + (reduced==chosen)
    • (reducedがhitと等しい) か (reducedがchosenと等しい)

つまり、

「reduced」をランダムに1つ選ぶんだけど「hit」や「chosen」と同じだったらそれは減らしたらいけないので、違うやつになるまで rnd(3) をしまくる。

という感じ。

では今回はチェンジしないバージョンということにして、

if(chosen==hit){
log("HIT!\n");
}else{
log("blank…\n");
}

結果を表示しちゃいましょう。

  • if( 〇〇〇 ){ □□□ }
    • もし 〇〇〇 なら □□□ する
  • chosen==hit
    • chosenがhitと等しい
  • log( “HIT!\n” )
    • “HIT!\n” と画面に出す(”\n”は”改行”の意味)
  • else{ △△△ }
    • でないなら △△△ する

こんな感じ。ここまでをまとめると最終的にシミュレーションプログラムは、

var hit = rnd(3);
var chosen = rnd(3);

// reduce one
var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
  reduced = rnd(3);
}

// show result
if(chosen==hit){
  log("HIT!\n");
}else{
  log("blank…\n");
}

こんな具合、”vi” でこれを打ち込んで ESCキー でセーブ&Exitしよう。

実行は

lash> ms .

こんな具合、「HIT!」が出れば当たり、「blank…」が出ればハズレ。何度も “ms .” すれば当たったりハズレたりを確認できるね。

さて、1,000回ほどシミュレーションしてみよう。1,000回も “ms .” するのはしんどいので、これもプログラミング。

var count=1000;

while(0 < count){
  var hit = rnd(3);
  var chosen = rnd(3);

  // reduce one
  var reduced = rnd(3);
  while( (reduced==hit) + (reduced==chosen) ){
    reduced = rnd(3);
  }

  // show result
  if(chosen==hit){
    log("HIT!\n");
  }else{
    log("blank...\n");
  }

  count = count-1;
}

太字の部分を加えました。はじめ “count” を 1,000 にして置いて、”0 < count” な間くり返します。”count” は下の方で “count = count-1″ しているので1ずつ減っていき、”0” になった時点で終了します。

lash> ms .
HIT!
HIT!
blank…
blank…
HIT!
blank…
blank…
:
:
:

実行するとこんな具合、1,000回シミュレーションされ、結果が大量に表示されます。あとはこれを集計すれば、、、でも手ではたいへん。なので集計もプログラミング。

var count=1000;
var hits=0;

while(0 < count){
  var hit = rnd(3);
  var chosen = rnd(3);

  // reduce one
  var reduced = rnd(3);
  while( (reduced==hit) + (reduced==chosen) ){
    reduced = rnd(3);
  }

  // show result
  if(chosen==hit){
    hits = hits+1;
  }else{
    // none
  }

  count = count-1;
}

log(hits, "\n");

はじめ “hits” を0にして置いて、当たったら “hits = hits+1” で1増やす。1,000回終わったら hits を表示、”\n”は改行の意味。

lash> ms .
319

319回当たりました。

lash> ms .
326

2回目は326。

lash> ms .
350

3回目は350、3回を平均すると331.7回。モンティ・ホール問題で当たる確率は、チェンジしないと33%ほどのようです。つまり、66%ほどはハズレる、言い換えると「チェンジしていれば66%ほどで当たる」という事になります。不思議ですね。

ここで、よくよくソースコードを見ると、

var reduced = rnd(3);
while( (reduced==hit) + (reduced==chosen) ){
  reduced = rnd(3);
}

この部分、せっかく while まで使って reduced(減らすやつ) を選んでいるのに、

if(chosen==hit){
  hits = hits+1;
}else{
  // none
}

結果に reduced は利用されていません。つまりこのプログラムで “reduced” は無くても結果に影響しない、あるだけでCPUやメモリを消費する無駄なモノです。

var count=1000;
var hits=0;

while(0 < count){
  var hit = rnd(3);
  var chosen = rnd(3);

  // show result
  if(chosen==hit){
    hits = hits+1;
  }else{
    // none
  }

  count = count-1;
}

log(hits, "\n");

つまりこうですね。このように無駄なモノを取り除くことを「最適化」と呼んだりします。C/C++などの言語ではコンパイラがこれを自動でやってくれますが、今回の IchigoLatte JS はやってくれないのでこのように手動で最適化しました。

lash> ms .
313

実行しても結果は最適化前と同じです。

つまりこの「モンティ・ホール問題」、チェンジしないのであれば「司会者が1つ減らす」という行為は必要ありません。単に3つの中から1つ選ぶので、確率は1/3。

「チェンジしていれば2/3で当たり」をあえてプログラミングしてみましょう。

if(reduced==0){
  if(chosen==1) chosen=2;
  else          chosen=1;
}else{
if(reduced==1){
  if(chosen==0) chosen=2;
  else          chosen=0;
}else{
  if(chosen==0) chosen=1;
  else          chosen=0;
}}

チェンジするプログラムはこんな感じ。

var count=1000;
var hits=0;

while(0 < count){
  var hit = rnd(3);
  var chosen = rnd(3);

  // reduce one
  var reduced = rnd(3);
  while( (reduced==hit) + (reduced==chosen) ){
    reduced = rnd(3);
  }

  // change chosen
  if(reduced==0){
    if(chosen==1) chosen=2;
    else chosen=1;
  }else{
  if(reduced==1){
    if(chosen==0) chosen=2;
    else chosen=0;
  }else{
    if(chosen==0) chosen=1;
    else chosen=0;
  }}

  // show result
  if(chosen==hit){
    hits = hits+1;
  }else{
    // none
  }

  count = count-1;
}

log(hits, "\n");

これを結果表示の前に入れ込んで、全体はこんな具合。前回と違って reduced が役に立っているので消すことはできませんね。

lash> ms .
693

実行してみるとだいたい 2/3 になっています。ただし、さっきの最適化したプログラムで 2.5秒 だったシミュレーションが、今回は 7.5秒 になりました。元のシミュレーションの方が良いですね。

ひとまず「モンティ・ホール問題」において、「当てたいのであればチェンジはすべき」というのが結論になりそうです。


この問題を知った時、「だったら最初から2つにして選ばせればいいじゃん」って思ってたわけですが、それだと当たる確率は1/2。あえて「3つの時に1つ選ばせて、減らしたあとでチェンジする」という手段を取ることで当たる確率が2/3に上昇するという、にわかに信じ難い くじ引きゲーム。

米村でんじろうサイエンスプロダクションチャンネル でも詳しく説明されています。(でんじろうさん、福井に引っ越してもっと広い実験場で楽しい動画を撮られてはいかがでしょう?)

それでも「えー、ほうとうに?」「いやー、ちがうでしょー」と思う人がいるかも。今回のシミュレーションとは違う意見がある方はご意見聞かせてください。

最初の くじの数 が 1億個 だったら?










.

教室で立てようチャットサーバ、ラズパイ3ならコンセントに挿すだけ!

教室で立てようチャットサーバ、ラズパイ3ならコンセントに挿すだけ!

極小手作りネットワーク」では1対1の通信、「ちょっと物足りない」という場合は多対多、インターネットでも標準的なネットワーク方式「TCP/IP」を味わってみましょう。

取り出しましたはRaspberryPi3、WiFi搭載ということでこれをアクセスポイント(AP)にしてIchigoJam達をwifi接続します。消費電流は0.46A、ICの温度は43℃。

今回も IchigoDake / IchigoDyhookMixJuiceを接続すればWiFiに接続できます。

ラズパイで作ったAPに接続したら、

MJ TCP 192.168.4.1 3333

にアクセス。ここにはチャットサーバーを立てておきました。

var net = require('net');
var member = new Array();

var server = net.createServer(function(socket) {
        member.push(socket);

        socket.write(`'chat server(member:${member.length})\r\n`);
        socket.on('data', function(data){
                console.log(data);
                var text = data.toString('utf8');
                console.log(text);

                for(var n in member){
                        member[n].write('\''+text);
                }
        });
        socket.on('close', function(){
                member = member.filter(item => item !== socket);

                console.log('closed.\r\n');
        });
});

server.listen(3333, '0.0.0.0');

これがラズパイの中に作ったチャットサービスのプログラム「chat.js」。

前回と同じ、チャットを送るには「PRINT」or「?」を使います。

残りの5台に「Hello!!!」が一斉に届きました。

「KONNICHIWA」を返してみると、

みんなに「KONNICHIWA」が届きます。

前回と違ってwifiなので結構離れても、しかも何人でも同時にチャット可能、これは楽しいっ!

ちなみに、前回の3本線とハード構成が同じなので、IchigoLatte JS

while(1){
  var k=inkey();
  if(0<k) uart(k);
  var u=uart();
  if(0<u) log(chr(u));
}

このチャットプログラム、そのまま動くはず。君が作ったBASICのチャットプログラムもそのままうごくよ!

iodataのラズパイなら、設定してコンセントに挿すだけで辺りにチャットのwifiが飛ぶ。こっそり教室で動かしてみてはいかが?

(設定済みのSDをご入用の方はご連絡ください)










.

極小手作りネットワークで双方向通信、IchigoJamで作るチャットマシン!

極小手作りネットワークで双方向通信、IchigoJamで作るチャットマシン!

IchigoJamについている TX,RX ポートは他デバイスと通信するため。TXは送信、RXは受信。

IchigoJam A      IchigoJam B
-----------------------------
         TX   -   RX
         RX   -   TX
        GND   -   GND

のように結線、今回は IchigoDake / IchigoDyhook

電源を入れると

Syntax error

の嵐に。

慌てず GND を抜き、そしてまたさします。

では、IchigoJam Aで

LED1

と入力してみます。

IchigoJam A の LED がつきますね。

では IchigoJam A から IchigoJam B の LED をつけてみましょう。

PRINT "LED1"

と入力。

相手(IchigoJam B)のLEDがつきました。

IchigoJam B の画面には、勝手に「LED1」の文字が。

相手のLEDを消すには、

PRINT "LED0"

ですね。IchigoJam BASIC の PRINT 命令は 画面に表示 しますが、TXから送信 も同時に行なっています。相手に何か送りたいときは PRINT です。

にしても勝手に相手のコンピュータを操作できるのはセキュリティ甘甘、楽しいいたずらいろいろできちゃう。

では、相手の画面にメッセージを送ってみます。「?」は PRINT と同義。

相手に

HELLO!

が伝わりました、が「Syntax error」嵐 再び。

送り手側も同様の嵐。GNDを抜いてさしましょう。

嵐を避けるには BASIC のコメント

?"'HELLO!"

として送ります。

出ました。

返事もコメントとして。

返事到着。

線を長くすれば離れたところと会話可能。

ちょっとミスると「Syntax error」の嵐になっちゃうし、勝手にLEDとか操作できてしまってセキュリティ的に甘いので、BASICで本格的なチャットプログラムを作ってみるのも楽しいかも。

while(1){
var k=inkey();
if(0<k) uart(k);
var u=uart();
if(0<u) log(chr(u));
}

[ヒント] IchigoLatte JS なら、チャットプログラムはこんな感じ。

みがけ君の技術力。










.