小学校プログラミング授業用ミッションの問題を「新しいBing」に聞いてみた

# はじめに

K3Tunnelというサイトでは小学校プログラミング授業用のミッションが公開されています。
そのうちのひとつである「[家電買いかえ大作戦](https://k3tunnel.com/mission/101/)」というミッションについて、今はやりのチャットAI（お手軽に「新しいBing」）に聞いてやってもらうとどうなるんだろう？というエントリーです。


# 問題と期待する答え

## 「新しいBing」へのインプット
以下をBingチャットで聞いてみました。ミッションの中では満足ポイントという言葉を使っていますが、満足度のほうが一般的かなと思って置き換えています。

***
たかしくんは、おとうさん、おかあさんと一緒に暮らす3人家族です。

たかしくん家族は、掃除機、クッション、ホームベーカリーを買い替えることにしました。予算は10万円です。

それぞれの候補は以下の通りです。名前、値段とカッコ内の数字は、順番にそれを買った時のたかしくん、おとうさん、おかあさんの満足度を表しています。

掃除機の候補
１ ロボット型そうじ機 80000円 (100 100 70)
２ 高性能そうじ機 60000円 (100 80 90)
３ 軽くてかっこいいそうじ機 30000円 (50 60 90)
４ 旧型そうじ機 20000円 (30 50 50)

クッションの候補
１ マッサージ機能付クッション 50000円 (50 100 60)
２ 大きいくまさんクッション 30000円 (100 50 80)
３ マイクロビーズクッション 10000円 (70 70 80)
４ 普通のシンプルクッション 5000円 (50 70 50)

ホームベーカリーの候補
１ 本格派具材自動投入HB 40000円 (100 70 50)
２ お手軽派HB 30000円 (70 70 80)
３ ご飯でパンが焼けるHB 20000円 (60 50 70)
４ 食パン焼くだけHB 5000円 (50 100 60)

満足度の最大値が等しい場合には、たかしくんの満足度を優先します。

すべての組み合わせで、合計金額と満足度合計値を計算し、商品の名前と合計金額、満足度合計値を表示するJavaScriptのプログラムを作ってください。
***
最後の2行は微妙な日本語ですが、これについては後述します。

## 最適な組み合わせとして出てくることを期待しているもの

予算内で満足度合計最大になる組み合わせは、二つあり、そのうちたかしくんの満足度が高い組み合わせはこちらになります。

+ 高性能そうじ機
+ 大きいくまさんクッション
+ 食パン焼くだけHB
+ 満足度合計	710
+ 価格の合計	95000
+ たかしくん満足度合計 250


# Bingからの回答

## 最初の答え

<details><summary>Bingからの回答全量</summary>

こんにちは。この問題は、JavaScriptで解決できます。以下は、あなたが求めている答えを出力するJavaScriptプログラムです。

```javascript
const candidates = [
  {
    name: "ロボット型そうじ機",
    price: 80000,
    satisfaction: [100, 100, 70],
  },
  {
    name: "高性能そうじ機",
    price: 60000,
    satisfaction: [100, 80, 90],
  },
  {
    name: "軽くてかっこいいそうじ機",
    price: 30000,
    satisfaction: [50, 60, 90],
  },
  {
    name: "旧型そうじ機",
    price: 20000,
    satisfaction: [30, 50, 50],
  },
];

const cushions = [
  {
    name: "マッサージ機能付クッション",
    price: 50000,
    satisfaction: [50, 100, 60],
  },
  {
    name: "大きいくまさんクッション",
    price: 30000,
    satisfaction: [100, 50, 80],
  },
  {
    name: "マイクロビーズクッション",
    price: 10000,
    satisfaction: [70, 70, 80],
  },
  {
    name: "普通のシンプルクッション",
    price: 5000,
    satisfaction: [50, 70, 50],
  },
];

const homeBakeries = [
  {
    name: "本格派具材自動投入HB",
    price: 40000,
    satisfaction: [100, 70, 50],
  },
  {
    name: "お手軽派HB",
    price: 30000,
    satisfaction: [70, 70, 80],
  },
  {
    name: "ご飯でパンが焼けるHB",
    price: 20000,
    satisfaction: [60, 50, 70],
  },
   {
      name:"食パン焼くだけHB",
      price :5000,
      satisfaction:[50,100,60]
   }
];

let maxSatisfaction = -1;
let bestCombination = {};

for (let i =0; i < candidates.length; i++) {
   for (let j =0; j < cushions.length; j++) {
      for (let k =0; k < homeBakeries.length; k++) {
         let totalPrice = candidates[i].price + cushions[j].price + homeBakeries[k].price;
         let totalSatisfaction = Math.max(...candidates[i].satisfaction) + Math.max(...cushions[j].satisfaction) + Math.max(...homeBakeries[k].satisfaction);
         if (totalPrice <=100000 && totalSatisfaction > maxSatisfaction) {
            maxSatisfaction = totalSatisfaction;
            bestCombination = {candidates : candidates[i], cushions : cushions[j], homeBakeries : homeBakeries[k], totalPrice : totalPrice};
         }
      }
   }
}

console.log(bestCombination.candidates.name + ", " + bestCombination.cushions.name + ", " + bestCombination.homeBakeries.name + ", 合計金額：" + bestCombination.totalPrice + ", 満足度合計値：" + maxSatisfaction);
```

このプログラムを実行すると、最適な商品の名前、合計金額、満足度合計値が表示されます。どうぞお試しください。
***
</details>

それらしいJavaScriptのコードを返してくれました。

データの与え方も、これでいいかな？と思いながら書いてみましたが、ばっちり想定通りのデータ構造になっています。
↓は、掃除機。
```
const candidates = [
  {
    name: "ロボット型そうじ機",
    price: 80000,
    satisfaction: [100, 100, 70],
  },
  {
    name: "高性能そうじ機",
    price: 60000,
    satisfaction: [100, 80, 90],
  },
  {
    name: "軽くてかっこいいそうじ機",
    price: 30000,
    satisfaction: [50, 60, 90],
  },
  {
    name: "旧型そうじ機",
    price: 20000,
    satisfaction: [30, 50, 50],
  },
];
```

組み合わせを見つけていくところは、データ量が少ないからなのかfor文をぶんまわすやり方になっています。
```
for (let i =0; i < candidates.length; i++) {
   for (let j =0; j < cushions.length; j++) {
      for (let k =0; k < homeBakeries.length; k++) {
         // 中略
         }
      }
   }
}
```
ちなみにK3Tunnelのミッションでもぶんまわす方法を採用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308852/08b6b65a-7348-a635-3c6a-63ebe78711f9.png)

>このプログラムを実行すると、最適な商品の名前、合計金額、満足度合計値が表示されます。どうぞお試しください。

とのことなので、実行してみた結果、以下が出力されました。
```
高性能そうじ機, 大きいくまさんクッション, 食パン焼くだけHB, 合計金額：95000, 満足度合計値：300
```
満足度合計値がおかしいですが、それよりもこの一行だけが出力されたことに驚きました。

Bingにお願いした文章はこちら。
>満足度の最大値が等しい場合には、たかしくんの満足度を優先します。
>
>すべての組み合わせで、合計金額と満足度合計値を計算し、商品の名前と合計金額、満足度合計値を表示するJavaScriptのプログラムを作ってください。

満足度合計値が最大のものだけを出力しろとは、ひとことも言っていません。
設計書にこんな記述をしたら絶対レビュー指摘が入ると思いますが、Bingには通じるようです。

## 修正を求める

コードをざっと確認したところ満足度のところでmaxが出てくるのは何かおかしい気がします。
```javascript
let totalSatisfaction = Math.max(...candidates[i].satisfaction) + Math.max(...cushions[j].satisfaction) + Math.max(...homeBakeries[k].satisfaction);
```
直してもらうことに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308852/e66b8383-a030-5075-9a57-b907b0225809.png)

<details><summary>Bingからの回答全量</summary>

すみません、私の前の回答に誤りがありました。JavaScriptプログラムを修正し、家族全員の満足度を合計した値を表示するようにしました。以下が修正後のプログラムです。

```javascript
const candidates = [
  {
    name: "ロボット型そうじ機",
    price: 80000,
    satisfaction: [100, 100, 70],
  },
  {
    name: "高性能そうじ機",
    price: 60000,
    satisfaction: [100, 80, 90],
  },
  {
    name: "軽くてかっこいいそうじ機",
    price: 30000,
    satisfaction: [50, 60, 90],
  },
  {
    name: "旧型そうじ機",
    price: 20000,
    satisfaction: [30, 50, 50],
  },
];

const cushions = [
  {
    name: "マッサージ機能付クッション",
    price: 50000,
    satisfaction: [50, 100, 60],
  },
  {
    name: "大きいくまさんクッション",
    price: 30000,
    satisfaction: [100, 50, 80],
  },
  {
    name: "マイクロビーズクッション",
    price: 10000,
    satisfaction: [70, 70, 80],
  },
  {
    name: "普通のシンプルクッション",
    price: 5000,
    satisfaction: [50, 70, 50],
  },
];

const homeBakeries = [
   {
      name:"本格派具材自動投入HB",
      price :40000,
      satisfaction:[100,70,50]
   },
   {
      name:"お手軽派HB",
      price :30000,
      satisfaction:[70,70,80]
   },
   {
      name:"ご飯でパンが焼けるHB",
      price :20000,
      satisfaction:[60,50,70]
   },
   {
      name:"食パン焼くだけHB",
      price :5000,
      satisfaction:[50,100,60]
   }
];

let maxSatisfaction = -1;
let bestCombination = {};

for (let i =0; i < candidates.length; i++) {
   for (let j =0; j < cushions.length; j++) {
      for (let k =0; k < homeBakeries.length; k++) {
         let totalPrice = candidates[i].price + cushions[j].price + homeBakeries[k].price;
         let totalSatisfaction = candidates[i].satisfaction.reduce((a,b) => a+b) + cushions[j].satisfaction.reduce((a,b) => a+b) + homeBakeries[k].satisfaction.reduce((a,b) => a+b);
         if (totalPrice <=100000 && totalSatisfaction > maxSatisfaction) {
            maxSatisfaction = totalSatisfaction;
            bestCombination = {candidates : candidates[i], cushions : cushions[j], homeBakeries : homeBakeries[k], totalPrice : totalPrice};
         }
      }
   }
}

console.log(bestCombination.candidates.name + ", " + bestCombination.cushions.name + ", " + bestCombination.homeBakeries.name + ", 合計金額：" + bestCombination.totalPrice + ", 満足度合計値：" + maxSatisfaction);
```

修正後のプログラムを実行すると、最適な商品の名前、合計金額、満足度合計値が表示されます。どうぞお試しください。
***
</details>

実行してみた結果、以下が出力されました。
```
高性能そうじ機, 大きいくまさんクッション, 食パン焼くだけHB, 合計金額：95000, 満足度合計値：710
```

すばらしい！！！

ただし、問題文の

>満足度の最大値が等しい場合には、たかしくんの満足度を優先します。

は、華麗に無視されています。

満足度合計値が最大になる組み合わせは2つあるのですが、このデータの与え方、ループの回し方だと、たまたま「最初に出てくる組み合わせ」が、たかしくんの満足度が高い方になるのです。

## 何度か実行してみた結果

全く同じことを聞いても、違うプログラムが返ってきたりしますし、最後の2行の書き方を変えると傾向が変わるような気がします。

そのうちの1回のプログラムが面白かったので紹介します。

最後の2行はこちら。

>満足度の最大値が等しい場合には、たかしくんの満足度を優先します。
>どの組み合わせで買えばよいかを求めるJavaScriptのプログラムを教えてください。

<details><summary>Bingからの回答全量</summary>

たかしくん家族の予算内で掃除機、クッション、ホームベーカリーを買い替えるためのJavaScriptプログラムを求めているとのことですね。以下のようなプログラムを作成することができます。

```javascript
const candidates = [
  {
    name: "ロボット型そうじ機",
    price: 80000,
    satisfaction: [100, 100, 70],
    type: "vacuum",
  },
  {
    name: "高性能そうじ機",
    price: 60000,
    satisfaction: [100, 80, 90],
    type: "vacuum",
  },
  {
    name: "軽くてかっこいいそうじ機",
    price: 30000,
    satisfaction: [50, 60, 90],
    type: "vacuum",
  },
  {
    name: "旧型そうじ機",
    price: 20000,
    satisfaction: [30, 50, 50],
    type: "vacuum",
  },
  {
    name: "マッサージ機能付クッション",
    price: 50000,
    satisfaction: [50, 100, 60],
    type: "cushion",
  },
  {
    name: "大きいくまさんクッション",
    price: 30000,
    satisfaction: [100, 50, 80],
    type: "cushion",
  },
  {
    name: "マイクロビーズクッション",
    price: 10000,
    satisfaction: [70, 70, 80],
    type: "cushion",
  },
  {
    name: "普通のシンプルクッション",
    price: 5000,
    satisfaction: [50, 70, 50],
    type: "cushion",
  },
  {
    name: "本格派具材自動投入HB",
    price: 40000,
    satisfaction: [100, 70, 50],
    type: "breadmaker",
  },
  {
    name: "お手軽派HB",
    price: 30000,
    satisfaction: [70, 70, 80],
    type: "breadmaker",
  },
  {
    name: "ご飯でパンが焼けるHB",
    price: 20000,
    satisfaction: [60,50 ,70],
    type:"breadmaker"
},
{
name:"食パン焼くだけHB",
price :5000,
satisfaction:[50 ,100 ,60],
type:"breadmaker"
}
];

const budget = { vacuum :100000 , cushion :100000 , breadmaker :100000 };

const result = candidates.reduce((acc,current)=>{
if(current.price<=budget[current.type]){
acc.push(current);
}
return acc;
},[]);

console.log(result);
```
このプログラムは、candidates配列に候補の情報を格納し、budgetオブジェクトに予算を格納しています。reduceメソッドを使って、予算内で購入可能な商品を抽出しています。このプログラムを実行すると、以下のような結果が得られます。

```javascript
[
   { name:'高性能そうじ機', price :60000,satisfaction:[100 ,80 ,90],type:'vacuum' },
   { name:'軽くてかっこいいそうじ機',price :30000,satisfaction:[50 ,60 ,90],type:'vacuum' },
   { name:'大きいくまさんクッション',price :30000,satisfaction:[100 ,50 ,80],type:'cushion' },
   { name:'マイクロビーズクッション',price :10000,satisfaction:[70 ,70 ,80],type:'cushion' },
   { name:'普通のシンプルクッション',price :5000,satisfaction:[50 ,70 ,50],type:'cushion' },
   { name:'ご飯でパンが焼けるHB',price :20000,satisfaction:[60 ,50 ,70],type:'breadmaker' },
   { name:'食パン焼くだけHB',price :5000,satisfaction:[50 ,100 ,60],type:'breadmaker' }
]
```

この結果から、予算内で購入可能な商品は上記の7つです。それぞれの商品の満足度を比較して、最も満足度が高い組み合わせを選ぶことができます。
***
</details>


# まとめ

少し触ってみただけですが、現時点では、この程度の問題でも、チャットでの聞き方、結果の活用の仕方に、ある程度の専門性が必要だというのが個人的な感触です。ただ、これがより高性能になった先の世界で生きる子どもたちに、プログラミング体験として、今、何を提供していくのがいいのかは改めて考えたほうがよさそうだなあと感じています。

なお、今回使ってみた「家電買いかえ大作戦」ですが、授業で利用するには、やや難易度が高くなってしまっており、近いうちにブラッシュアップすることを計画しているそうです。