בעיה ה'

הוראות המופיעות בגוף של מבנה while ומתבצעות כל עוד תנאי הלולאה מתקיים צריכות להיות מוזזות ימינה ביחס לשורה הראשונה במבנה. הקוד התקין:
age = input(‘Insert age; -1 to stop: ‘)
while age != ‘-1’:
print(age)
age = input(‘Insert age; -1 to stop: ‘)
(א) נתונה books – רשימה של שמות ספרים. ברשימה שלושה שמות או יותר, ואין שם המופיע בה יותר מפעם אחת. לדוגמה זו רשימה שיש בה ארבעה שמות ספרים –
[‘book1’, ‘book2’, ‘book3’, ‘book4’]
יש לכתוב קוד המדפיס את כל תת הרשימות של הרשימה books שהן בגודל 3 ומקיימות את שני התנאים האלה: אין תת רשימה שבה שם ספר מופיע יותר מפעם אחת, ואין תת רשימה שכל שמות הספרים המופיעים בה מופיעים גם בתת רשימה אחרת. שמות הספרים בכל תת רשימה יכולים להופיע בסדר כלשהו. לדוגמה, עבור רשימות הדוגמה books הקוד יוכל להדפיס את תת הרשימות האלה:
[‘book1’, ‘book2’, ‘book3’]
[‘book1’, ‘book2’, ‘book4’]
[‘book1’, ‘book3’, ‘book4’]
[‘book2’, ‘book3’, ‘book4’]
אם הודפסו תת רשימות אלו, לא תודפס תת רשימה המכילה שלשת שמות נוספת, גם אם סדר השלשה הוא אחר. למשל לא יודפסו תת הרשימות האלה –
[‘book2’, ‘book1, ‘book3’]
[‘book1’, ‘book4, ‘book2’]
(ב) כתבו את הפונקציה triad –
def triad(books, prices, total):
לפונקציה שלושה פרמטרים אלה –
books – רשימה של שמות ספרים. ברשימה שלושה שמות או יותר, ואין שם המופיע בה יותר מפעם אחת. לדוגמה זו רשימה שיש בה ארבעה שמות ספרים –
[‘book1’, ‘book2’, ‘book3’, ‘book4’]
(1) prices – רשימה של מחירי הספרים ששמותיהם מופיעים ברשימה books: המחיר המופיע באינדקס i ברשימה prices הוא מחירו של הספר ששמו מופיע באינדקס זה ברשימה books. הנה דוגמה לרשימת מחירי הספרים שברשימה המדגימה את books –
[80.15, 90.5, 100.8, 100.8]
לפי רשימה זו, מחירו של הספר ששמו ‘book1’ הוא 80.15.
תנו דעתכם שאפשר שלשני ספרים או יותר יהיה מחיר זהה; כך למשל בדוגמה 100.8 הוא מחירם של שני ספרים שונים זה מזה.
(2) total – מספר עשרוני.
הפונקציה מחזירה רשימה שיש בה את כל השלשות של שמות ספרים שסכומם שסכום מחיריהם גדול מ-total, כל שלשה בתוך רשימה פנימית; אם אין שלשות כאלה היא מחזירה רשימה ריקה. ברשימה המוחזרת לא תהיה רשימה פנימית ששלשת הספרים בה מופיעה ברשימה פנימית אחרת (גם בסדר שונה). הרשימות הפנימיות יכולות להופיע בסדר כלשהו ברשימה החיצונית. בנוסף שמות הספרים ברשימות הפנימיות יכולים להופיע בסדר כלשהו. עבור רשימות הדוגמה books ו-prices, ועבור total == 280, הפונקציה תחזיר רשימה שיש בה שתי שלשות, למשל –
[[‘book1’, ‘book3’, ‘book4’], [‘book2’, ‘book3’, ‘book4’]]
פתרון
(א) הבעיה העקרונית העומדת בבסיס השאלה היא זו:
נתון אוסף של ערכים שמספר הערכים בו אינו קטן מ-n. יש ליצור את כל תתי האוספים של האוסף הנתון שהם בגודל n, אין בהם כפילויות (כלומר ערך המופיע יותר מפעם אחת), והם שונים זה מזה מבחינת תכנם.
בניסוחה הקונקרטי כאן הבעיה היא למצוא, על יסוד הרשימה books (הכוללת לפי השאלה לפחות שלושה שמות ספרים), את כל שלשות שמות הספרים השונות זו מזו מבחינת תכנן, ושבכל אחת מהן אין שם ספר המופיע יותר מפעם אחת. קודם שנפתור בעיה זו ננסה לפתור בעיה פשוטה יותר ממנה: נמצא את כל זוגות שמות הספרים השונים זה מזה שיש ברשימה books. הנה כל הזוגות האלה –
[‘book1’, ‘book2’]
[‘book1’, ‘book3’]
[‘book1’, ‘book4’]
[‘book2’, ‘book3’]
[‘book2’, ‘book4’]
[‘book3’, ‘book4’]
והנה נסיון ראשון למצוא את הזוגות האלה, בשימוש בלולאה מקוננת –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
for book1 in books:
for book2 in books:
print([book1, book2])
הלולאה החיצונית סורקת את כל שמות הספרים ברשימה books. עבור כל שם ספר, הלולאה הפנימית סורקת גם היא את כל שמות הספרים ברשימה, ועבור כל שם ספר מדפיסה זוג שיש בו את השם הזה (שני בזוג) ואת השם הנסרק בלולאה החיצונית (ראשון בזוג). הנה הפלט של קטע הקוד –
[‘book1’, ‘book1’]
[‘book1’, ‘book2’]
[‘book1’, ‘book3’]
[‘book1’, ‘book4’]
[‘book2’, ‘book1’]
[‘book2’, ‘book2’]
[‘book2’, ‘book3’]
[‘book2’, ‘book4’]
[‘book3’, ‘book1’]
[‘book3’, ‘book2’]
[‘book3’, ‘book3’]
[‘book3’, ‘book4’]
[‘book4’, ‘book1’]
[‘book4’, ‘book2’]
[‘book4’, ‘book3’]
[‘book4’, ‘book4’]
כפי שאפשר להיווכח מהפלט, הקוד אינו מפיק בדיוק את הזוגות הנדרשים בהגדרת הבעיה. בראש ובראשונה הוא יוצר זוגות שבהם שם ספר מופיע פעמיים. הזוגות האלה נוצרים כיוון שהלולאה הפנימית סורקת את כל שמות הספרים ברשימה books, כולל שם הספר הנסרק בלולאה החיצונית. למשל כשהלולאה החיצונית סורקת את שם הספר ‘book1’, גם הלולאה הפנימית סורקת אותו, ולכן נוצרת הרשומה [‘book1’, ‘book1’]. אפשר לנסות לפתור את הבעיה באופן זה –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
for book1 in books:
for book2 in books:
if book1 != book2:
print([book1, book2])
כאן התנינו הדפסה של זוג שמות ספרים בשוני בין השמות בזוג. הפעם בפלט לא יהיו רשומות המכילות ערכים שווים –
[[‘book1’, ‘book2’],
[‘book1’, ‘book3’],
[‘book1’, ‘book4’],
[‘book2’, ‘book1’],
[‘book2’, ‘book3’],
[‘book2’, ‘book4’],
[‘book3’, ‘book1’],
[‘book3’, ‘book2’],
[‘book3’, ‘book4’],
[‘book4’, ‘book1’],
[‘book4’, ‘book2’],
[‘book4’, ‘book3’]]
כפי שאפשר להיווכח מהפלט, הקוד עדיין אינו מפיק בדיוק את הזוגות הנדרשים בהגדרת הבעיה: הוא יוצר זוגות זהים מבחינת תכנם, הגם שלא מבחינת סדרם. למשל מודפסים הן הזוג [‘book2’, ‘book4’] הן הזוג [‘book4’, ‘book2’]. נראה שתי גישות להימנע מהכפילויות האלה. גישה אחת היא להימָנע מהדפסה של זוג אם כבר הודפס זוג זהה לו מבחינת תכנו. בניסוח כללי יותר הגישה דנן פותרת בעיה זו –
נתון קוד הסורק ערכים באוסף נתון.
יש לזהות אם אחד או יותר מהערכים שנסרקו זהה לערך הנסרק הנוכחי.
כיצד נבצע את הזיהוי הנדרש? דרך אחת היא להכניס כל ערך שכבר נסרק לתוך אוסף ייעודי. קודם שהקוד יבוא לטפל בערך הבא באוסף, הוא יבדוק אם הערך הזה הוכנס לאוסף הייעודי. הנה שלד לקוד המממש גישה זו במקרה שלפנינו –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
printed = []
for book1 in books:
for book2 in books:
if book1 != book2:
sortedPair = sorted([book1, book2])
if sortedPair not in printed:
print([book1, book2])
printed.append(sortedPair)
>>>
[‘book1’, ‘book2’]
[‘book1’, ‘book3’]
[‘book1’, ‘book4’]
[‘book2’, ‘book3’]
[‘book2’, ‘book4’]
[‘book3’, ‘book4’]
לפני הלולאות יצרנו רשימת עזר בשם printed ואתחלנו אותה לרשימה ריקה. לאחר כל הדפסה של רשימת זוג, הכנסנו רשימה ממוינת של הזוג הזה לרשימה printed. בכל פעם שבאנו להדפיס רשימה של הזוג הבא, בדקנו אם רשימה ממוינת של הזוג הזה עדיין לא הוכנסה לרשימה printed, כלומר אם הזוג הזה טרם הודפס, ורק אם זה המצב הוא הודפס. מדוע הרשימות המוכנסות והנבדקות הן ממוינות? נעיין למשל בשני הזוגות האלה –
[‘book2’, ‘book4’]
[‘book4’, ‘book2’]
זוגות אלה שונים מבחינת סדרם אך זהים מבחינת תכנם. לכן יש להדפיס רק אחד מהם. כבר ראינו למעלה כי הזוג [‘book2’, ‘book4’] הוא הראשון שנסרק, ולכן הוא מודפס. נניח שהוא מוכנס לרשימה printed כפי שהוא, כלומר בלי למיינו. כשנסרק הזוג [‘book4’, ‘book2’] אין להדפיס אותו. אך כשנבדוק אם הוא קיים ברשימה printed לא נמצא אותו שם, ולכן בכל זאת נדפיס אותו. כדי שנמצא אותו שם, עלינו להכניס את רשימת הזוג [‘book2’, ‘book4’]לרשימה printed כשהיא ממוינת, ובנוסף, כשנבוא לבדוק אם רשימת הזוג [‘book4’, ‘book2’] נמצאת ברשימה printed – לבדוק אותה כשהיא ממוינת, כלומר לבדוק אם הרשימה [‘book2’, ‘book4’]נמצאת ברשימה printed; או אז נמצא אותה שם, ונמָנע מהדפסתה, כנדרש.
גישה אחרת להתמודדות עם בעיית הכפילויות בהדפסה היא להימנע מראש מיצירתה. בקוד נשיג זאת באמצעות סריקת אינדקסים חלקית. עיינו בקטע הקוד הזה –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
for i in range(len(books)):
for j in range(i + 1, len(books)):
print([books[i], books[j]])
>>>
[‘book1’, ‘book2’]
[‘book1’, ‘book3’]
[‘book1’, ‘book4’]
[‘book2’, ‘book3’]
[‘book2’, ‘book4’]
[‘book3’, ‘book4’]
שלא כמו בקוד הקודם, הפעם לולאת ה-for הפנימית לא סרקה את כל הרשימה books. עבור כל אינדקס i שסורקת לולאת ה-for החיצוונית, הלולאה הפנימית סורקת רק חלק מהאינדקסים של הרשימה, כדלקמן –
• עבור i == 0, הלולאה הפנימית מציבה באינדקס j את האינדקסים 1, 2, ו-3, ולכן הודפסו רשימות הזוגות האלה –
[‘book1’, ‘book2’]
[‘book1’, ‘book3’]
[‘book1’, ‘book4’]
• עבור i == 1, הלולאה הפנימית מציבה באינדקס j את האינדקסים 2, ו-3, ולכן הודפסו רשימות הזוגות האלה –
[‘book2’, ‘book3’]
[‘book2’, ‘book4’]
• עבור i == 2, הלולאה הפנימית מציבה באינדקס j את האינדקס 3, ולכן הודפסה רשימת הזוג הזאת –
[‘book3’, ‘book4’]
• ועבור i == 3, הלולאה הפנימית כלל לא תרוץ, כיוון שהפונקציה range תחזיר סדרה ריקה (בצורה מפורשת הזימון שלה הוא range(4,4)). ובאמת אין ליצור זוג שהשם הראשון בו הוא ‘book4’ כי כבר הודפסו כל הזוגות המכילים שם זה.
אם כן בניסוח כללי, בפתרון זה אנו סורקים, עבור כל ספר ברשימה books, את כל הספרים הבאים ברשימה אחריו. באופן זה אנחנו מוודאים שלא יווצרו זוגות הזהים מבחינת תכנם.
עד כאן הפתרון לבעיית הדפסת הזוגות. נעבור מכאן לפתרון הבעיה המקורית, דהיינו הדפסת השלשות. נציע שני פתרונות, וכל אחד מהם הוא שכתוב של פתרון לבעיית הזוגות. הנה פתרון המבוסס על סריקת אינדקסים חלקית –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
for i in range(len(books)):
for j in range(i + 1, len(books)):
for k in range(j + 1, len(books)):
print([books[i], books[j], books[k]])
>>>
[‘book1’, ‘book2’, ‘book3’]
[‘book1’, ‘book2’, ‘book4’]
[‘book1’, ‘book3’, ‘book4’]
[‘book2’, ‘book3’, ‘book4’]
עקרון הפעולה כאן זהה לעקרון הפעולה בהדפסת הזוגות, והוא מבטיח שלא ייווצרו שלשות זהות מבחינת תכנן. ואמנם כפי שאפשר לראות בפלט מודפסות כל השלשות המקיימות את הנדרש בשאלה. ספציפית הוספנו כאן לולאת for שלישית, הסורקת אינדקסים, וסורקת את סדרת האינדקסים שבה האינדקס הראשון הוא זה הבא לאחר האינדקס שסורקת לולאת ה-for הפנימית הראשונה. הנה מעקב מפורט אחר ביצוע הקוד –
• שלשת האינדקסים הראשונה הנסרקת היא i == 0, j == 1, k == 2. נוצרת השלשה הזאת –
[‘book1’, ‘book2’, ‘book3’]
• שלשת האינדקסים השניה הנסרקת היא i == 0, j == 1, k == 3. נוצרת השלשה הזאת –
[‘book1’, ‘book2’, ‘book4’]
כאן מסתיימים הסיבובים של לולאת ה-for הפנימית ביותר, עבור i == 0, j == 1.
• שלשת האינדקסים השלישית הנסרקת היא i == 0, j == 2, k == 3. נוצרת השלשה הזאת –
[‘book1’, ‘book3’, ‘book4’]
כאן מסתיימים הסיבובים של לולאת ה-for הפנימית ביותר, עבור i == 0, j == 2.
• שלשת האינדקסים הרביעית הנסרקת היא i == 0, j == 3, k == 4. כאן הלולאה הפנימית ביותר אינה מתבצעת אפילו פעם אחת כיוון שהפונקציה range מחזירה סדרה ריקה (הצורה המפורשת של הזימון הוא range(4, 4)).
כאן מסתיימים הסיבובים של לולאת ה-for הפנימית הראשונה, עבור i == 0.
• שלשת האינדקסים החמשית הנסרקת היא i == 1, j == 2, k == 3. נוצרת השלשה הזאת –
[‘book2’, ‘book3’, ‘book4’]
• שלשת האינדקסים הששית הנסרקת היא i == 1, j == 3, k == 4. גם כאן הלולאה הפנימית ביותר אינה מתבצעת אפילו פעם אחת כיוון שהפונקציה range מחזירה סדרה ריקה.
כאן מסתיימים הסיבובים של לולאת ה-for הפנימית הראשונה, עבור i == 1.
• שלשת האינדקסים השביעית הנסרקת היא i == 2, j == 3, k == 4. גם כאן הלולאה הפנימית ביותר אינה מתבצעת אפילו פעם אחת כיוון שהפונקציה range מחזירה סדרה ריקה.
כאן מסתיימים הסיבובים של לולאת ה-for הפנימית הראשונה, עבור i == 2.
• שלשת האינדקסים השמינית והאחרונה הנסרקת היא i == 3, j == 4, k == 5. כאן הלולאה הפנימית הראשונה אינה מתבצעת אפילו פעם אחת כיוון שהפונקציה range מחזירה סדרה ריקה.
עד כאן הפתרון ליצירת שלשות שמות הספרים המבוסס על סריקת אינדקסים חלקית. עכשיו נפנה לפתרון המבוסס על שימוש ברשימת עזר. הנה המימוש –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
printed = []
for book1 in books:
for book2 in books:
for book3 in books:
if book1 != book2 and book2 != book3 and book1 != book3:
sortedTriad = sorted([book1, book2, book3])
if sortedTriad not in printed:
print([book1, book2, book3])
printed.append(sortedTriad)
>>>
[‘book1’, ‘book2’, ‘book3’]
[‘book1’, ‘book2’, ‘book4’]
[‘book1’, ‘book3’, ‘book4’]
[‘book2’, ‘book3’, ‘book4’]
גם כאן הוספנו לולאת for שלישית. כשתי קודמותיה אף היא סורקת את כל הספרים ברשימה books. התנאי הנבדק בהוראת ה-if הוא הרחבה של התנאי שהופיע בהוראה זו בגרסת הקוד שיצרה את כל זוגות השמות: גם כאן הוא בא לוודא שאין ברשימה המודפסת שם של ספר המופיע יותר מפעם אחת. שאר הקוד נסמך על העקרון שהוסבר קודם בנוגע לשימוש ברשימת העזר ולמיון של הרשימות המוכנסות והנבדקות.
(ב) קל לראות כי גם בבסיס השאלה הזאת נמצאת בעיית יצירת השלשות שפתרנו בסעיף הקודם: עלינו למצוא את כל השלשות השונות זו מזו ברשימה שיש בה שלושה מחירים או יותר. תובנה זו תקל על עבודתנו כיוון שהיא תוביל אותנו לכתוב את הפתרון לשאלה בסעיף הנוכחי בהסתמך על הפתרונות שהוצעו לשאלה בסעיף א’. בכל זאת יש הבדל חשוב בין מצב העניינים בשאלה הנוכחית לבין זה בקודמתה. בשאלה בסעיף א’ לא היו כפילויות באוסף שנדרשנו למצוא את כל תת האוספים שלו השונים זה מזה – צוין בה במפורש שברשימת שמות הספרים אין שם המופיע יותר מפעם אחת. לאור זאת ברשימה זו –
[‘book1’, ‘book2’, ‘book3’]
[‘book1’, ‘book2’, ‘book4’]
[‘book1’, ‘book3’, ‘book4’]
[‘book2’, ‘book3’, ‘book4’]
לעומת זאת, ברשימת המחירים אפשר שיש כפילויות, ולמצב זה יש השלכה על מספר השלשות השונות זו מזו שיש ברשימה. כך למשל אם נבוא להדפיס את כל שלשות הרשימות השונות זו מזו שיש ברשימה הזאת –
[80.15, 90.5, 100.8, 100.8]
יהיה עלינו להדפיס רק רשימה אחת (!) זו (שתכנה אינו מאורגן בהכרח בסדר הזה) –
[80.15, 90.5, 100.8]
לכן, אם נשכתב את הפתרון לשאלת יצירת שלשות הספרים, ספציפית: הפתרון שנסמך על רשימת עזר, באופן שייצור את כל שלשות המחירים השונות זו מזו, לא נופתע למצוא שהוא מדפיס רשימה אחת בלבד. הנה השכתוב והפלט –
prices = [80.15, 90.5, 100.8, 100.8]
printed = []
for price1 in prices:
for price2 in prices:
for price3 in prices:
if price1!=price2 and price2!=price3 and price1 != price3:
sortedTriad = sorted([price1, price2, price3])
if sortedTriad not in printed:
print([price1, price2, price3])
printed.append(sortedTriad)
>>>
[80.15, 90.5, 100.8]
הקוד הזה זהה לגמרי לקוד ששימש אותנו ביצירת שלשות הספרים, חוץ מזה שהוא עובד על רשימת המחירים ולא על רשימת הספרים. כפי שאפשר לראות הוא מפיק רשימה אחת בלבד.
נשים לב כי מן האמור יוצא כי השכתוב כפשוטו אינו מתאים לגמרי לצרכינו. הדבר ברור מיד מזה שהוא מפיק שלשה אחת בלבד: הרי השאלה עצמה הראתה לנו כי עבור רשימות ספרים ומחירים אלו –
books = [‘book1’, ‘book2’, ‘book3’, ‘book4’]
prices = [80.15, 90.5, 100.8, 100.8]
ועבור total = 280, יש להחזיר רשימה שיש בה שתי שלשות של ספרים –
[[‘book1’, ‘book3’, ‘book4’], [‘book2’, ‘book3’, ‘book4’]]
סכום המחירים של כל אחת משלשות ספרים אלה הוא גדול מ-280, ולכן שתיהן צריכות להופיע ברשימה. אם כן היינו רוצים שהשכתוב של הקוד המוצא את שלשות שמות הספרים לקוד המוצא את שלשות המחירים ידפיס שתי שלשות של מחירים אלו –
[80.15, 100.8, 100.8]
[90.5, 100.8, 100.8]
הרשימה הראשונה מכילה את מחירי הספר הראשון, הספר השלישי, והספר הרביעי, ואילו הרשימה השניה מכילה את מחירי הספר השני, הספר השלישי, והספר הרביעי. לאור ההסבר בסעיף א’ מובן מדוע השכתוב הנוכחי של הקוד מדפיס רק את אחת מהן: הדבר נעוץ בתנאי הנבדק בהוראת ה-if. כך היא הופיעה בקוד שמצא את שלשות שמות הספרים –
if book1 != book2 and book2 != book3 and book1 != book3:
מטרת הבדיקה כאן הייתה לוודא שלא יודפסו רשימות שבהם שם של ספר מסוים הופיע יותר מפעם אחת – זו הייתה הדרישה בסעיף א’. כאשר שכתבנו את הקוד באופן שימצא שלשות של מחירים, ובשכתוב כתבנו את ההוראה כך –
if price1 != price2 and price2 != price3 and price1 != price3:
התנאי הזה מנע יצירה של שלשות מחירים שיש בהן מחיר המופיע יותר מפעם אחת, כגון 100.8 . כפי שמתברר עתה, זה לא תנאי רצוי במצב שברשימת המחירים מחיר אחד מופיע יותר מפעם אחת, כלומר שלשני ספרים או יותר יש מחיר אחד.
מה בנוגע לפתרון האחר, זה היוצר את השלשות על פי סריקת אינדקסים חלקית? הנה שכתוב של הקוד המוצא שלשות של שמות ספרים באופן שימצא שלשות של מחירים, והפלט המתקבל מהרצת הקוד –
prices = [80.15, 90.5, 100.8, 100.8]
for i in range(len(prices)):
for j in range(i + 1, len(prices)):
for k in range(j + 1, len(prices)):
print([prices[i], prices[j], prices[k]])
>>>
[80.15, 90.5, 100.8]
[80.15, 90.5, 100.8]
[80.15, 100.8, 100.8]
[90.5, 100.8, 100.8]
הפעם קיבלנו ארבע שלשות, וגם בכך אין להפתיע: הרי כבר ראינו בדיוק כיצד הקוד זורם במקרה של רשימת הספרים, והזרימה כאן זהה לגמרי. החשוב הוא כי שלא כמו הפתרון המבוסס על רשימת עזר, הקוד הזה “עיוור” לכפילויות בתוך שלשה, ולכן הוא לא יימנע מהדפסה של רשימה שמחיר מסוים אחד מופיע בה יותר מפעם אחת. זה מה שרצוי לנו כאן, ולכן נבסס את מימוש הפונקציה triad על השכתוב הזה. הנה הגרסה הסופית של הפונקציה –
def triad(books, price, total):
triads = []
for i in range(len(prices)):
for j in range(i + 1, len(prices)):
for k in range(j + 1, len(prices)):
if sum([prices[i], prices[j], prices[k]]) > total:
triads.append([books[i], books[j], books[k]])
return triads
print(triad([‘book1’, ‘book2’, ‘book3’, ‘book4’],
[80.15, 90.5, 100.8, 100.8],
280))
>>>
[[‘book1’, ‘book3’, ‘book4’], [‘book2’, ‘book3’, ‘book4’]]
הקוד בגוף הפונקציה ערוך בתבנית שראינו כבר בבעיות קודמות: יצירת אוסף ריק, והוספת ערכים לסופו בלולאה על פי ערכים באוסף נתון (ראו לעיל בעיה א’). ספציפית התחלנו ביצירת הרשימה הריקה triads, והוספנו לסופה שלשות של שמות ספרים בלולאה. כל שלשה הוכנסה לרשימה אך ורק לאחר שנבדקו מחירי שלושת הספרים ונמצא כי סכומם גדול מ-total. בזכות סריקת האינדקסים ברשימת המחירים יכולנו, לאחר שמצאנו כי שלשת סכומים מסוימת מקיימת את התנאי הנדרש, לגשת מיד לשלשת שמות הספרים האלה ולהשתמש בה כדי לבנות את רשימת השלשה המוכנסת לרשימה triads.