שלב הבתים

לקראת סיום שלב הבתים במונדיאל כתבתי תוכנית קטנה שחישבה את כל האפשרויות שיכולות להיות לדירוג סופי של בית בן ארבע קבוצות. (זה היתרון בלדעת לתכנת).

בכל בית משחקים שישה משחקים:
קבוצה 1 מול קבוצה 2
קבוצה 3 מול קבוצה 4
קבוצה 1 מול קבוצה 3
קבוצה 2 מול קבוצה 4
קבוצה 1 מול קבוצה 4
קבוצה 2 מול קבוצה 3

כל משחק בין שתי קבוצות יכול להסתיים באחת משלושת התוצאות הבאות:
נצחון לקבוצה אחת
תיקו
נצחון לקבוצה השנייה

זאת אומרת שיש 3 (תוצאות למשחק) בחזקת 6 (מספר משחקים) שזה יוצא 729 קומבינציות של תוצאות משחקים בבית.
אם מצמצמים זאת רק לדירוגים יחודיים (זאת אומרת שלא חוזרים על עצמם) המספר הוא 40 והנה הרשימה:
(המספר הראשון הוא מספר הנקודות של הקבוצה במקום הראשון וכך הלאה)
[9, 6, 3, 0]
[9, 6, 1, 1]
[9, 4, 4, 0]
[9, 4, 3, 1]
[9, 4, 2, 1]
[9, 3, 3, 3]
[9, 2, 2, 2]
[7, 7, 3, 0]
[7, 7, 1, 1]
[7, 6, 4, 0]
[7, 6, 3, 1]
[7, 6, 2, 1]
[7, 5, 4, 0]
[7, 5, 3, 1]
[7, 5, 2, 1]
[7, 4, 4, 1]
[7, 4, 3, 3]
[7, 4, 3, 2]
[7, 4, 3, 1]
[7, 4, 2, 2]
[7, 3, 2, 2]
[6, 6, 6, 0]
[6, 6, 4, 1]
[6, 6, 3, 3]
[6, 5, 4, 1]
[6, 5, 2, 2]
[6, 4, 4, 3]
[6, 4, 4, 2]
[5, 5, 5, 0]
[5, 5, 4, 1]
[5, 5, 3, 2]
[5, 5, 3, 1]
[5, 5, 2, 2]
[5, 4, 4, 3]
[5, 4, 4, 2]
[5, 4, 3, 2]
[5, 3, 3, 2]
[4, 4, 4, 4]
[4, 4, 4, 3]
[3, 3, 3, 3]

מסקנות מעניינות:
1. אי אפשר לסיים את שלב הבתים עם 8 נקודות (אפשר עם 0,1,2,3,4,5,6,7,9)
2. מספר הנקודות המינימלי שאפשר להעפיל איתם לשלב הבא הוא 2 בסיטואציה הזאת: [9, 2, 2, 2] (זאת אומרת שאי אפשר לעלות לשלב הבא עם נקודה אחת בלבד)
3. מספר הנקודות המקסימלי שאיתן לא עולים לשלב הבא הוא 6 בסיטואציה הזאת: [6, 6, 6, 0] (זאת אומרת שאם יש לקבוצה 7 נקודות היא בטוח עולה לשלב הבא).
4. מספר הנקודות הכולל המקסימלי האפשרי בבית הוא 18 (זה קורה שאף משחק לא מסתיים בתיקו)
5. מספר הנקודות הכולל המינימלי האפשרי בבית הוא 12 (זה קורה שכל המשחקים מסתיימים בתיקו).

ואלו החוקים של פיפ"א מתוך ספר החוקים והתקנות למונדיאל 2018 שקובעים את הדירוג של הקבוצות בבית.

נקווה שבפעם הבאה כל זה יהיה רלוונטי גם לנבחרת ישראל.


לבקשת הקהל – הנה הקוד המהיר והמלוכלך (לא גאה בו אבל הוא עשה את העבודה).

import copy

def team_point_from_team_point(point):
    if point == 0:
        return 3
    elif point == 1:
        return 1
    else:
        return 0

all_options = []
g_counter = 1
for g_i1 in (0, 1, 3):
    g_team = [0, 0, 0, 0]
    g_team[0] = g_i1
    g_team[1] = team_point_from_team_point(g_i1)
    original_team_1 = copy.copy(g_team)
    for g_i2 in (0, 1, 3):
        g_team = copy.copy(original_team_1)
        g_team[2] = g_i2
        g_team[3] = team_point_from_team_point(g_i2)
        original_team_2 = copy.copy(g_team)
        for g_i3 in (0, 1, 3):
            g_team = copy.copy(original_team_2)
            g_team[0] = g_team[0] + g_i3
            g_team[2] = g_team[2] + team_point_from_team_point(g_i3)
            original_team_3 = copy.copy(g_team)
            for g_i4 in (0, 1, 3):
                g_team = copy.copy(original_team_3)
                g_team[1] = g_team[1] + g_i4
                g_team[3] = g_team[3] + team_point_from_team_point(g_i4)
                original_team_4 = copy.copy(g_team)
                for g_i5 in (0, 1, 3):
                    g_team = copy.copy(original_team_4)
                    g_team[0] = g_team[0] + g_i5
                    g_team[3] = g_team[3] + team_point_from_team_point(g_i5)
                    original_team_5 = copy.copy(g_team)
                    for g_i6 in (0, 1, 3):
                        g_team = copy.copy(original_team_5)
                        g_team[1] = g_team[1] + g_i6
                        g_team[2] = g_team[2] + team_point_from_team_point(g_i6)
                        g_team.sort(reverse=True)
                        if g_team not in all_options:
                            all_options.append(g_team)
                        print "{0} - {1} [{2} {3} {4} {5} {6} {7}]".\
                            format(g_counter, g_team, g_i1, g_i2, g_i3, g_i4, g_i5, g_i6)
                        g_counter = g_counter + 1

all_options.sort(reverse=True)
for option in all_options:
    print option