元ネタ
問題
水が5L入る容器と3L入る容器がある、この2つの容器だけを使って、
4Lの水を量るにはどうすれば良いですか?
水はいくらでも使えるものとします。
ソース
function 水を捨てる_3L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const result = {
new容器3Lの容量: 0,
new容器5Lの容量: 容器5Lの容量
}
if (need操作テキスト) {
result.操作テキスト = "3L容器を空っぽにした。 ";
}
return result;
}
function 水を捨てる_5L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const result = {
new容器3Lの容量: 容器3Lの容量,
new容器5Lの容量: 0
}
if (need操作テキスト) {
result.操作テキスト = "5L容器を空っぽにした。 ";
}
return result;
}
function 水を入れる_3L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const result = {
new容器3Lの容量: 3,
new容器5Lの容量: 容器5Lの容量
}
if (need操作テキスト) {
result.操作テキスト = "3L容器を満タンにした。 ";
}
return result;
}
function 水を入れる_5L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const result = {
new容器3Lの容量: 容器3Lの容量,
new容器5Lの容量: 5
}
if (need操作テキスト) {
result.操作テキスト = "5L容器を満タンにした。 ";
}
return result;
}
function 水を移す_3Lから5L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const 移動する容量 = Math.min(容器3Lの容量, 5 - 容器5Lの容量);
const result = {
new容器3Lの容量: 容器3Lの容量 - 移動する容量,
new容器5Lの容量: 容器5Lの容量 + 移動する容量
}
if (need操作テキスト) {
result.操作テキスト = "3L容器から5L容器へ注いだ。";
}
return result;
}
function 水を移す_5Lから3L(容器3Lの容量, 容器5Lの容量, need操作テキスト = false) {
const 移動する容量 = Math.min(3 - 容器3Lの容量, 容器5Lの容量);
const result = {
new容器3Lの容量: 容器3Lの容量 + 移動する容量,
new容器5Lの容量: 容器5Lの容量 - 移動する容量
}
if (need操作テキスト) {
result.操作テキスト = "5L容器から3L容器へ注いだ。";
}
return result;
}
const 操作一覧 = [
水を捨てる_3L, 水を捨てる_5L,
水を入れる_3L, 水を入れる_5L,
水を移す_3Lから5L, 水を移す_5Lから3L
];
const キュー = [];
キュー.push({
容器3Lの容量: 0,
容器5Lの容量: 0,
操作手順: []
});
let 答えの操作手順 = undefined;
loop:
while (true) {
const {容器3Lの容量, 容器5Lの容量, 操作手順} = キュー.shift();
for (const 操作 of 操作一覧) {
const {new容器3Lの容量, new容器5Lの容量} = 操作(容器3Lの容量, 容器5Lの容量);
if (容器3Lの容量 === new容器3Lの容量 && 容器5Lの容量 === new容器5Lの容量) {
continue;
}
const new操作手順 = [...操作手順];
new操作手順.push(操作);
if (new容器5Lの容量 === 4) {
答えの操作手順 = new操作手順;
break loop;
}
キュー.push({
容器3Lの容量: new容器3Lの容量,
容器5Lの容量: new容器5Lの容量,
操作手順: new操作手順
});
}
}
let 容器3Lの容量 = 0;
let 容器5Lの容量 = 0;
for (let i = 0; i < 答えの操作手順.length; i++) {
const 操作 = 答えの操作手順[i];
const {new容器3Lの容量, new容器5Lの容量, 操作テキスト} = 操作(容器3Lの容量, 容器5Lの容量, true);
console.log(`${i + 1}: ${操作テキスト}【3L容器: ${new容器3Lの容量}L, 5L容器: ${new容器5Lの容量}L】`);
容器3Lの容量 = new容器3Lの容量;
容器5Lの容量 = new容器5Lの容量;
}
実行結果
1: 5L容器を満タンにした。 【3L容器: 0L, 5L容器: 5L】
2: 5L容器から3L容器へ注いだ。【3L容器: 3L, 5L容器: 2L】
3: 3L容器を空っぽにした。 【3L容器: 0L, 5L容器: 2L】
4: 5L容器から3L容器へ注いだ。【3L容器: 2L, 5L容器: 0L】
5: 5L容器を満タンにした。 【3L容器: 2L, 5L容器: 5L】
6: 5L容器から3L容器へ注いだ。【3L容器: 3L, 5L容器: 4L】
別の方法