כנראה שנגמרו הבעיות אם יש לנו זמן לשחק ב-"בול פגיעה".
החוקים למי שבמקרה אינו מכיר: שחקן א’ בוחר מספר בן 4 ספרות שונות (למשל 1528), ושחקן ב’ מנסה לנחש.
התשובה על כל ניחוש של ב’ צריכה להיות מספר ה"בולים" (כלומר- כמה ספרות מתוך ה-4 שבניחוש נמצאות במקום הנכון),
ומספר ה"פגיעות" (כלומר- כמה ספרות מתוך ה-4 מופיעות במספר שבחר א’ אך לא במקום הנכון).
למשל אם א’ בחר 0123 ו-ב’ מנחש שהמספר הוא 1283, אזי יש לו "בול" אחד (הספרה 3) ושתי "פגיעות" (הספרות 1 ו-2).
כעת ב’ מציע ניחוש חדש על סמך המידע החלקי שבידו, וחוזר חלילה עד שהוא מנחש נכונה את המספר.
אנחנו נבחר מספר והמחשב ינחש ויגלה,
ולשם כך נכתוב פרוצדורה שתיצור טבלה עם 10*9*8*7=5040 הצירופים החוקיים,
בטבלה יהיה שדה שיציין אם המספר אפשרי לאור המידע שקיבלנו עד כה (בהתחלה לכל המספרים אינדיקציה 1 ובכל איטרציה המחשב יאפס אותה עבור הלא רלוונטיים),
והמחשב יבחר רשומה אחת באופן אקראי ויציג אותה כניחוש:
Create Proc SP_BulPgia_Begin As
If (Select Count(*) From sys.tables Where name=’T_BulPgia’)=1 Table T_BulPgia;
Create Table T_BulPgia(A Char(1),B Char(1),C Char(1),D Char(1),YesNo Bit);
Create Unique Clustered Index T_BulPgia_Idx On T_BulPgia(A,B,C,D);
With Nm As
(Select 0 N
Union All
Select N+1
From Nm
Where N<9)
Insert Into T_BulPgia
Select Cast(N1.N As Char) A,
Cast(N2.N As Char) B,
Cast(N3.N As Char) C,
Cast(N4.N As Char) D,
1 YesNo
From Nm N1
Inner Join Nm N2
On N2.N<>N1.N
Inner Join Nm N3
On N3.N<>N1.N
And N3.N<>N2.N
Inner Join Nm N4
On N4.N<>N1.N
And N4.N<>N2.N
And N4.N<>N3.N;
Select Top 1 ’My guess: ’+A+B+C+D
From T_BulPgia
Order By NewID();
כעת נכתוב פרוצדורה נוספת שתקבל את הניחוש האחרון של המחשב, את מספר הבולים ואת מספר הפגיעות (שלושה פרמטרים בסה"כ),
המחשב יאפס את האינדיקציות של כל הרשומות שההשוואה שלהן לניחוש האחרון אינה מחזירה את מספר הבולים והפגיעות הנכון,
ומתוך הרשומות שהאינדיקציה שלהן היא עדיין 1 המחשב ישלוף אקראית ניחוש נוסף.
תהליך זה יחזוור על עצמו עד שתיוותר אינדיקציה 1 רק למספר אחד וזו התשובה הנכונה:
Create Proc SP_BulPgia_Guess(@Guess Char(4), @Bul Int, @Pgia Int) As
With T As
(Select *,
Case When SUBSTRING(@Guess,1,1)=A Then 1 Else 0 End +
Case When SUBSTRING(@Guess,2,1)=B Then 1 Else 0 End +
Case When SUBSTRING(@Guess,3,1)=C Then 1 Else 0 End +
Case When SUBSTRING(@Guess,4,1)=D Then 1 Else 0 End Bul,
Case When SUBSTRING(@Guess,2,3) Like ’%’+A+’%’ Then 1 Else 0 End +
Case When SUBSTRING(@Guess,1,1)+SUBSTRING(@Guess,3,2) Like ’%’+B+’%’ Then 1 Else 0 End +
Case When SUBSTRING(@Guess,1,2)+SUBSTRING(@Guess,4,1) Like ’%’+C+’%’ Then 1 Else 0 End +
Case When SUBSTRING(@Guess,1,3) Like ’%’+D+’%’ Then 1 Else 0 End Pgia
From T_BulPgia
Where YesNo=1)
Update T
Set YesNo=0
Where Not (Bul=@Bul And Pgia=@Pgia);
Select Top 1 Case (Select COUNT(*) From T_BulPgia Where YesNo=1) When 1 Then ’The answer is: ’ Else ’My guess: ’ End +A+B+C+D
From T_BulPgia
Where YesNo=1
Order By NewID();
נתחיל לשחק: בחרתי את המספר 1528 (לא לגלות למחשב- הוא צריך למצוא לבד!) והפעלתי את הפרוצדורה SP_BulPgia_Begin.
הניחוש שלו 6342 שזה 0 בולים ו-1 פגיעות ולכן אני מפעיל את הפרוצדורה SP_BulPgia_Guess עם הפרמטרים ’6342’,0,1.
הניחוש שלו עכשיו 2015 שזה 0 בולים ו-3 פגיעות,
הניחוש הבא שלו 7201 שזה 0 בולים ו-2 פגיעות,
הניחוש הבא שלו 1530 שזה 2 בולים ו-0 פגיעות,
הניחוש הבא (שבמקרה הוא גם התשובה הנכונה) הוא 1528 וזה 4 בולים ו-0 פגיעות,
ורק כעת הוא מכריז ש-1528 זו התשובה הנכונה:
SP_BulPgia_Begin; My guess: 6342
SP_BulPgia_Guess ’6342’,0,1;My guess: 2015
SP_BulPgia_Guess ’2015’,0,3;My guess: 7201
SP_BulPgia_Guess ’7201’,0,2;My guess: 1530
SP_BulPgia_Guess ’1530’,2,0;My guess: 1528
SP_BulPgia_Guess ’1528’,4,0;The answer is: 1528