חידה שצריך לפתור באמצעות שימוש במודל מתאים בפייתון - שני חברים נסעו לטייל במדבר. לאחד כלי בנפח 8 ליטרים ולשני כלי בנפח 5 ליטרים. הכלים היו מלאים במים אבל המים אזלו בגלל ששני החברים תעו במדבר וכעת יש להם שני כלים ריקים. לשמחתם מצאו מיכל בנפח 12 ליטרים המלא במים. על מנת שלא לריב החליטו לחלק את המים ביניהם חצי בחצי (כל אחד 6 ליטרים). כיצד הם יכולים לעשות את זה באמצעות העברת מים מכלי לכלי ? אנו מחפשים מודל בפייתון וכן את שלבי הפתרון.
top of page
bottom of page
הפתרון מורכב משתי פונקציות בלבד - הראשונה מוצאת מה האפשרויות הנובעות מכל מצב - כאשר המצב ההתחלתי שלנו הוא [12,0,0] כלומר כלי אחד מלא ב- 12 ליטר מים ושני כלים ריקים. כל רשימה כוללת שלושה איברים, השמאלי ביותר מייצג כלי בנפח 12 ליטר, האמצעים כלי בנפח 8 ליטר והימני כלי בנפח 5 ליטר. כל מספר ברשימה מייצג כמה מים יש בכלי.
def desert_options(lista): options=[] max_opt=[] max_opt.append(12-lista[0]) max_opt.append(8-lista[1]) max_opt.append(5-lista[2]) for place, item in enumerate (lista): for p,i in enumerate(max_opt): if item>0: if place !=p: if i>0: if item>i: opt=lista[::] #מוכרחים לייצר אובייקט חדש ולא מצביע בלבד opt[place]=item-i opt[p]=opt[p]+i options.append(opt) if item<i: opt = lista[::] opt[place]=0 opt[p]=opt[p]+item options.append(opt) return options answer = [[12,0,0]] #השלב ההתחלתי שלנו def solve_desert(): #הפונקציה השניה הפותרת את החידה if [6,6,0] in answer: #ששה ליטרים בשני הכלים הגדולים זה מה שמחפשים print(answer) exit() else: for item in desert_options(answer[-1]): #אנו תמיד עובדים על האיבר האחרון בתהליך if item not in answer: #על מנת שלא נשוב לנקודה שכבר היינו בה answer.append(item) solve_desert() #זו הרקורסיה answer.pop() #זה מחזיר את המצב לקדמותו solve_desert() #כאן קוראים לפונקציה
הפונקציה הרקורסיבית שלנו מכילה תנאי מפסיק והוא שיהיה שלב בתהליך השווה ל- [6,6,0] כלומר חילקנו 12 ליטרים של מים בין שני המתייבשים שלנו.
הפתרון הראשון המתקבל (שלאחריו הפונקציה מפסיקה לעבוד הוא -
answer:
>>>
[[12, 0, 0], [4, 8, 0], [0, 8, 4], [8, 0, 4], [8, 4, 0], [3, 4, 5], [3, 8, 1], [11, 0, 1], [11, 1, 0], [6, 1, 5], [6, 6, 0]]
אבל זה אינו הפתרון הקצר ביותר - הוא כולל עשרה שלבים אחרי המצב ההתחלתי. אם נותנים לפונקציה לרוץ מגלים גם פתרון יותר קצר -
answer:
[[12, 0, 0], [4, 8, 0], [4, 3, 5], [9, 3, 0], [9, 0, 3], [1, 8, 3], [1, 6, 5], [6, 6, 0]]
הכולל שבעה שלבים אחרי המצב ההתחלתי 12,0,0 - קבלו משימה לשנות את הקוד כך שיפלוט את הפתרון הקצר ביותר בלבד.