-
תכנות שפת C\פסקל- פותר סודוקו
מאגר השאלות מפורום התמיכה שלנו. כאן תוכלו למצוא מגוון שאלות ותשובות העונות על קשת רחבת נושאים.
ידיעות חוץ
פורסם ב: 28 נובמבר 2007עוד במגזין ...
לאחרונה בפורוםתכנות שפת C\פסקל- פותר סודוקו
מאת: imper s
נכתב ב: 12/11/2007 23:35:35
בזמנו שלמדתי היינו בונים קצת משחקי לוח פשוטים.
לאחר הלימודים הגיע הסודוקו, ויצא לי לחשוב קצת תאורטית על האלגוריתם שפותר אותו. השיטות לפתירת סודוקו מגוונות יחסית ולכן יש כמה בדיקות.
המשימה אומרת כך: האלגוריתם מקבל מטריצה 9X9 של סודוקו סטנדרטי(בכל תא יש מספר 1-9 או מקום ריק). מקום ריק מוגדר כ-"0"(לצורך נוחיות) ומחזיר את הפיתרון של המטריצה.
יש כמה סוגי בדיקות שלפיהן אפשר להתקדם:
1. שלילת ספרות אחרות עבור משבצת\תא (אלימינציה). לדעתי נצטרך לשלב כאן מערך 1-9 עבור כל תא, לנפות ממנו מספרים שלא ייתכנו עבור תא, יהיה משתנה לאורך כל הפיתרון עד קביעת המספר עבור אותו תא. נצטרך להשתמש במערך 1-9 עבור עוד בדיקות. זאת בדיקה חזקה יחסית שצריכה לכלול השוואה לטור, שורה ומטריצה פנימית 3X3.
1.2 בדיקה עבור כל מערך 1-9 של כל תא אשר אומרת: אם יש רק מספר אחד במערך, אז המספר נכנס לתא. (אם זה לא 1,2,3,4,5,6,7,8 אז ערך התא 9).
2. השוואה בין מערכים 1-9 של כל תא במטריצה 3X3 עבור כל המספרים החוקיים (1-9). אם יש מספר כלשהו שלא יימצא באף מערך פרט לאחד, אז נכנס המספר אל התא. עבור תא שקיים בו מספר שונה מאפס אין צורך במערך 1-9. זאת תהיה פונקציה שמקבלת את כל ה-9 מטריצות 3X3 שיש בלוח.
3. תנאי העצירה יגיד כמובן שאם אין אפסים במטריצה(תא ריק)-החזר פתרון (מטריצה פתורה).
4. לגבי מטריצה לא חוקית, לאחר כל הבדיקות האלה להריץ בדיקה נוספת לגבי מספר אפסים (0). אם הוא לא ישתנה (קטן כמובן) אחרי כל הבדיקות אז הרי המטריצה שהתקבלה לא חוקית. עדיף שיהיה כפונקציה ראשונה האמת.
אני לא נזכר בעוד בדיקות נוספות כרגע, במידה ויש תרשמו את אופי הבדיקה והרעיון.
אפשר להריץ בדיקה עבור כל אחד מהדברים האלה בשפות הנ"ל בלי בעייה יחסית.
אני רוצה רק אלגוריתם בשביל לראות איך זה מתבצע ולא את התוכנה כתובה. יש עדיפות לשפת C אם כבר.13/11/2007 01:28:03הערה מאת: פבל פ
שחקתי עם זה פעם, ממשתי פותר ל-SUDOKU ב-++C, אולם הקוד אבד.
ישנו אלגוריתם פשוט הפותר SUDOKU באופן יעיל ביותר. הוא ממומש בשפת C#.
http://www.codeproject.com/csharp/sudoku.asp
במידה וישנו צורך בהסבר, תן לי לדעת.13/11/2007 02:30:07הערה מאת: imper s
הפיתרון הזה נורא דומה לשלי.
הוא אכן בונה בהתחלה מערך עבור כל תא. הוא מוחק את האפשרות של המספר ע"י איפוסו ואחר כך לוקח את המספר היחיד ששונה מאפס במערך, וזה טוב.
לא הבנתי את בדיקת המטריצה הפנימית שלו 3X3. כתוב שמסיבה גראפית כלשהי הוא לא כלל את המשבצת, וזה מסבך לי את ההבנה של מה בדיוק קרה שם. תיתכן ספרייה חיצונית?
כמו כן לא הבנתי איך הוא מרכז את תוצאות (איפוס מספרים) כל הבדיקות למערך 0-9. (M) יש כנראה פונקציה שהוא לא הוסיף את הקוד שלה.
בשורה הבאה אני מנחש שהוא מנסה לזהות אם ישנו תא יחיד ששונה מ-0. אני לא מכיר "?" בשפת C, תקן אותי אם אני טועה.
cM += M[d] == 0 ? 0 : 1;
שמתי לב שבמקום לעבור על המטריצה שוב ושוב הוא עובד ברקורסיה על כל תא ותא- זה לא מעלה את הסיבוכיות?
תנאי העצירה שלו לגבי לוח שלילי גם שונה בכך שהוא בעצם שולל את כל המספרים לגבי תא אחד, וזה גם בסדר.
אני רק רוצה להבין את הרעיון, לא משנה לי התחביר.
13/11/2007 08:29:45הערה מאת: פבל פ
תשובה מלאה ומפורטת תקבל ממני במהלך היום, כעת אני פשוט ממהר לעבודה.
cM += M[d] == 0 ? 0 : 1;
משול ל:
if (M[d] == 0)
cM += 0;
else
cM += 1;
קוראים לכך "תנאי טרינארי". תחביר זה נתמך גם ב-C; אם כבר, לא היה לו פה כל צורך בתנאי טרינארי מלכתחילה, היה נכון יותר לכתוב:
if (M[d] != 0)
++cM;
עדיין אין תגובות לכתבה זו.







![Apple-Mac-Vulnerable-Shellshock-Bash-Bug[1]](http://www.pcmagazine.co.il/lib/uploads/Apple-Mac-Vulnerable-Shellshock-Bash-Bug1-425x283.jpg)