จากการเขียนโปรแกรมทดสอบพบว่า หากแต่ละคนเลือกแบบสุ่ม วิธีใดวิธีหนึ่งจาก
- เลือกหยิบเพชรที่วางทิ้งไว้เท่านั้น
- วางเพชรปลอมทิ้งไว้
- ไม่ยุ่งกับเพชรที่วางทิ้งไว้ และก็ไม่ทิ้งเพชรปลอมเอาไว้
- เลือกหยิบเพชรที่วางทิ้งไว้ และวางเพชรปลอมทิ้งไว้ด้วย
พบว่ามีรูปแบบวิธีที่เป็นไปได้ทั้งหมด 96 วิธี โดยสุดท้ายแล้วเพชรแท้จะอยู่ที่
- ห้องแสดงเพชร ได้ทั้งสิ้น 24 วิธี
- ผู้เล่นคนที่ 1 ได้ทั้งสิ้น 24 วิธี
- ผู้เล่นคนที่ 2 ได้ทั้งสิ้น 24 วิธี
- ผู้เล่นคนที่ 3 ได้ทั้งสิ้น 24 วิธี
แสดงว่า ความน่าจะเป็นที่เพชรแท้จะอยู่ที่ตนเองคือ 1/4 และความน่าจะเป็นที่เพชรแท้จะอยู่ที่สองคนอื่นคือ 1/2
และเมื่อแต่ละคนมีสิทธิ์ทายได้ว่า ใครเป็นคนเก็บเพชรแท้ไว้กับตัว ก็ทำได้เช่นเดียวกัน ดังนั้นผู้เข้าเล่นเกมทั้งสามคน จึงมีโอกาสชนะเท่ากันหมด
พิจารณาแผนการเล่น เมื่อสมมติว่าเกมนี้ต้องมีผู้ชนะ
หากเรารู้ว่าเพชรเม็ดไหนในห้องเป็นเพชรแท้แล้ว
- เก็บเพชรแท้นั้นไว้กับตัว ความน่าจะเป็นที่จะชนะคือ (3*2*2)/(3*3*3) = 4/9
- หากปล่อยเพชรแท้นั้นให้คนอื่นเก็บไป แต่ไม่รู้ว่าใครเป็นคนเก็บ ความน่าจะเป็นที่จะชนะคือ 1/2
- หากปล่อยเพชรแท้นั้นให้คนอื่นเก็บไป และรู้ด้วยว่าใครเป็นคนเก็บ ความน่าจะเป็นที่จะชนะคือ 1
ดังนั้นเราจึงควรทิ้งเพชรแท้ไว้ดังเดิม แม้ไม่รู้ว่าใครจะเป็นคนเก็บไป เพราะมีความน่าจะเป็นที่จะชนะมากกว่า ยกเว้นกรณีที่เราเป็นผู้เล่นคนที่ 3 ที่จะต้องเก็บเพชรทุกเม็ด ไม่เช่นนั้นจะมีโอกาสแพ้ทุกคน
ในทำนองเดียวกัน หากเราไม่รู้ว่าเพชรเม็ดไหนในห้องเป็นเพชรแท้แล้ว เราควรทิ้งเพชรเหล่านั้นไว้ดังเดิม เพราะมีความน่าจะเป็นที่จะชนะมากกว่า ยกเว้นกรณีที่เราเป็นผู้เล่นคนที่ 3 ที่จะต้องเก็บเพชรทุกเม็ด ไม่เช่นนั้นจะมีโอกาสแพ้ทุกคน
ถ้าผู้เล่นทุกคนใช้แผนการเล่นแบบนี้หมด เพชรแท้จะต้องถูกเก็บโดยผู้เล่นคนที่ 3 แน่นอน ทำให้เกมนี้ผู้เล่นคนที่ 1 และ 2 เป็นผู้ชนะ
ส่วนนี่เป็นรูปจากการ์ตูนส่วนที่เหลือครับ
C Code:
#include <stdio.h>
#include <string.h>
void doSomething(int iPerson, int *piDiamondRoom, int iRealDiamondPos, int iDiamondIdx);
int main(int argc, char* argv[])
{
int arDiamondRoom[4]; /* บอกว่ามีเพชรของใครวางทิ้งไว้ในห้อง */
int iRealDiamondPos = 0; /* บอกว่าตอนนี้เพชรแท้เก็บไว้ที่ใคร, ค่า 0 หมายถึงเพชรจริงยังเก็บไว้ในห้อง */
memset(arDiamondRoom
, 0x00, sizeof(arDiamondRoom
));
arDiamondRoom[0] = 1; /* วางเพชรแท้ 1 เม็ด ในห้อง, arDiamondRoom[0] หมายถึงตำแหน่งที่เก็บเพชรแท้ */
doSomething(1, arDiamondRoom, 0, -1);
return 0;
}
void doSomething(int iPerson, int *piDiamondRoom, int iRealDiamondPos, int iDiamondIdx)
{
int arDiamondRoom[4];
int iKeepDiamondFlg;
int iDropDiamondFlg;
memset(arDiamondRoom
, 0x00, sizeof(arDiamondRoom
)); memcpy(arDiamondRoom
, piDiamondRoom
, sizeof(arDiamondRoom
));
if(iDiamondIdx == -1) /* ขั้นตอนเริ่มต้นของแต่ละคน */
{
/* วางเพชรปลอมของตนเองทิ้งไว้หรือไม่ */
for(iDropDiamondFlg = 0; iDropDiamondFlg < 2; iDropDiamondFlg++)
{
arDiamondRoom[iPerson] = iDropDiamondFlg;
doSomething(iPerson, arDiamondRoom, iRealDiamondPos, 0); /* พิจารณาเพชรที่วางทิ้งไว้ในห้อง */
}
}
else if(iDiamondIdx < iPerson) /* พิจารณาว่าจะเก็บเพชรเม็ดไหนไว้หรือไม่ */
{
/* พบเพชรอันหนึ่ง */
if(arDiamondRoom[iDiamondIdx] > 0)
{
/* เก็บเพชรนั้นไว้กับตนเองหรือไม่ */
for(iKeepDiamondFlg = 0; iKeepDiamondFlg < 2; iKeepDiamondFlg++)
{
arDiamondRoom[iDiamondIdx] = iKeepDiamondFlg;
if(iDiamondIdx == 0 && iKeepDiamondFlg == 0)
doSomething(iPerson, arDiamondRoom, iPerson, iDiamondIdx+1); /* พิจารณาเพชรที่วางทิ้งไว้อันถัดไป */
else
doSomething(iPerson, arDiamondRoom, iRealDiamondPos, iDiamondIdx+1); /* พิจารณาเพชรที่วางทิ้งไว้อันถัดไป */
}
}
else
doSomething(iPerson, arDiamondRoom, iRealDiamondPos, iDiamondIdx+1); /* พิจารณาเพชรที่วางทิ้งไว้อันถัดไป */
}
else if(iPerson < 3) /* ให้คนถัดไปเข้าห้อง */
doSomething(iPerson+1, arDiamondRoom, iRealDiamondPos, -1);
else /* เข้าห้องครบทั้ง 3 คนแล้ว */
{
/* แสดงผลลัพธ์สุดท้าย */
/* เพชรแท้เก็บไว้ที่ใคร, [เพชรแท้วางทิ้งไว้ในห้องหรือไม่, เพชรปลอมของคนที่ 1 วางทิ้งไว้หรือไม่, เพชรปลอมของคนที่ 2 วางทิ้งไว้หรือไม่, เพชรปลอมของคนที่ 3 วางทิ้งไว้หรือไม่] */
printf("%d, [%d : %d : %d : %d]\n", iRealDiamondPos
, arDiamondRoom
[0], arDiamondRoom
[1],arDiamondRoom
[2],arDiamondRoom
[3]); }
}