Table of Contents

Recently I attempted a Python challenge on HackerRank - ‘The Minion Game’. My curiosity was piqued and I wanted to find out if the odds were as stacked as I initially thought. I was surprised that this wasn’t already established publicly and so I worked it out ‘myself’.

The Game

The initial task was to complete code to calculate Kevin and Stuart’s scores programmatically for this game (I believe this description is free to reproduce)- via ChatGPT:

The Minion Game is a word game that involves creating different substrings from a given string and scoring points based on certain rules. Here’s a simplified description of the game:

  1. Players: There are two players in the game, one playing as ‘Stuart’ and the other as ‘Kevin’.
  2. Objective: The objective of the game is to create as many different substrings as possible from a given string. Each player scores points based on the substrings they create.
  3. Rules:
    • Stuart creates substrings that start with a consonant.
    • Kevin creates substrings that start with a vowel.
    • Each substring created scores a point. If a substring occurs multiple times in the original string, it scores multiple points.
    • The player with the highest score at the end of the game wins.

Example:

  • Given the string “BANANA”, Stuart can create the following substrings: B, BA, BAN, BANA, BANAN, BANANA, N, NA, NAN, NANA, A, AN, ANA, ANAN, ANANA. Stuart scores 12 points.
  • Kevin can create the following substrings: A, AN, ANA, ANAN, ANANA, A, A, AN, ANA. Kevin scores 9 points.
  • Stuart wins the game with 12 points.

The Question

I was distracted and did not come up with a correctly functioning solution on my own. I wound up reverting to ChatGPT which used significantly different design patterns. On reflection I realised that the passing code did not really examine substrings, but rather tallied vowels and consonants and their relative positions. Whilst this is the ‘correct’ behaviour here, it highlights that the substrings are just sequences of letters in this case- they don’t need to be ‘real’ words themselves. I became interested in the statistical odds, which seemed to me greatly in favour of Stuart (leading with consonants) winning. There are only 5 vowels in English, versus 21 consonants. On interrogating ChatGPT, it seemed there wasn’t an ‘obvious’ or established and ready answer, rather this would need to be my own statistical analysis. I did not bother to corroborate this elsewhere and I asked ChatGPT to extend the code to perform this analysis using the Python english_words package, and specifically the web2 set of words:

The ‘web2’ word list is one of the word lists that originated from the Unix operating system. It is a large list of English words that is often used in various software applications, including spell checkers and word games. The ‘web2’ list is derived from the “Webster’s Second International” dictionary and contains a comprehensive collection of English words, including both common and uncommon words.

Although there was some faff getting ChatGPT’s code working correctly with the current version of english_words and the web2 set, it was otherwise a breeze to have it extend the code to run ‘The Minions Game’ on every word in the set.

The Result

Running this code locally was surprisingly quick and the results are unambiguous:

Total Games: 234450
Stuart Wins: 206739 (88.18%)
Kevin Wins: 21991 (9.38%)
Draws: 5720 (2.44%)

Essentially Stuart wins 9 times out of 10 and Kevin only 1 time in 11. Clearly this is a game that only Minions could ever take seriously. On the plus side this is an interesting diversion into home-lab statistical analysis with basic Python.

The Analytic Code

For those who might like to run this themselves, the code is below- I did pip3 install english_words first:

from english_words import get_english_words_set

# Replace the arguments inside the function call with the appropriate word list identifier and flags
english_words_set = get_english_words_set(['web2'], lower=True)


# Define the minion_game function


def minion_game(word):
    vowels = "aeiou"
    stuart_score = 0
    kevin_score = 0

    n = len(word)
    for i in range(n):
        if word[i] in vowels:
            kevin_score += (n - i)
        else:
            stuart_score += (n - i)

    if stuart_score > kevin_score:
        return "Stuart"
    elif kevin_score > stuart_score:
        return "Kevin"
    else:
        return "Draw"


# Initialize counters for the results
stuart_wins = 0
kevin_wins = 0
draws = 0

# Iterate through the list of words and simulate the game
for word in english_words_set:
    winner = minion_game(word)
    if winner == "Stuart":
        stuart_wins += 1
    elif winner == "Kevin":
        kevin_wins += 1
    else:
        draws += 1

# Calculate and print the statistical results
total_games = len(english_words_set)
print(f"Total Games: {total_games}")
print(f"Stuart Wins: {stuart_wins} ({(stuart_wins / total_games) * 100:.2f}%)")
print(f"Kevin Wins: {kevin_wins} ({(kevin_wins / total_games) * 100:.2f}%)")
print(f"Draws: {draws} ({(draws / total_games) * 100:.2f}%)")