-
   nana10

, . .

:

:






:





RSS:
:


3/2010

בול פגיעה


כנראה שנגמרו הבעיות אם יש לנו זמן לשחק ב-"בול פגיעה".
החוקים למי שבמקרה אינו מכיר: שחקן א’ בוחר מספר בן 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

, 4/3/201005:10
1





1,691


/
2024 (")