Skip to content

Instantly share code, notes, and snippets.

@shitchell
Last active November 30, 2021 19:28
Show Gist options
  • Select an option

  • Save shitchell/df42ebe1faf6e6cc173cb5385286fac1 to your computer and use it in GitHub Desktop.

Select an option

Save shitchell/df42ebe1faf6e6cc173cb5385286fac1 to your computer and use it in GitHub Desktop.

Revisions

  1. shitchell revised this gist Nov 30, 2021. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion hl.py
    Original file line number Diff line number Diff line change
    @@ -21,14 +21,16 @@ def run(mode: int = AUTO, ceil: int = 100, repeat: int = 10):
    if mode not in {HIGHER, EXACT, LOWER, AUTO}:
    raise ValueError("invalid run mode")

    # used to determine if we should automatically change the mode each round
    auto: bool = mode == AUTO
    for i in range(repeat):
    # generate two random numbers
    targetnum = random.randint(1, ceil)
    randomnum = random.randint(1, ceil)

    # make the guess
    correct_guess = False
    if mode == AUTO:
    if auto:
    # if auto is set, determine whether to guess higher or lower
    if randomnum < ((ceil // 2) + 1):
    mode = HIGHER
  2. shitchell revised this gist Nov 30, 2021. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion hl.py
    Original file line number Diff line number Diff line change
    @@ -100,7 +100,7 @@ def accuracy_rate(mode: int = AUTO, ceil: int = 100):
    help="show each trial")
    args = parser.parse_args()

    stats = {
    stats: dict = {
    "win": 0,
    "lose": 0,
    }
  3. shitchell created this gist Nov 30, 2021.
    135 changes: 135 additions & 0 deletions hl.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,135 @@
    #!/usr/bin/env python

    HIGHER: int = 3
    EXACT: int = 2
    LOWER: int = 1
    AUTO: int = 0

    def run(mode: int = AUTO, ceil: int = 100, repeat: int = 10):
    """
    Runs a sequence of Higher/Lower games using the given answering method and
    yields each individual game.
    :param mode <int> how to guess--one of AUTO, LOWER, HIGHER, or EXACT
    :param ceil <int> the upper bound for the range used to pick random numbers
    :param repeat <int> the number of rounds to play
    :yield <dict> a dict containing information about each round, e.g.:
    {"target": 38, "random": 8, "mode": HIGHER, "success": True}
    """
    import random

    if mode not in {HIGHER, EXACT, LOWER, AUTO}:
    raise ValueError("invalid run mode")

    for i in range(repeat):
    # generate two random numbers
    targetnum = random.randint(1, ceil)
    randomnum = random.randint(1, ceil)

    # make the guess
    correct_guess = False
    if mode == AUTO:
    # if auto is set, determine whether to guess higher or lower
    if randomnum < ((ceil // 2) + 1):
    mode = HIGHER
    else:
    mode = LOWER
    if (mode == HIGHER and targetnum > randomnum
    or mode == LOWER and targetnum < randomnum
    or mode == EXACT and targetnum == randomnum):
    correct_guess = True

    # return the results
    yield {
    "target": targetnum,
    "random": randomnum,
    "mode": mode,
    "success": correct_guess
    }

    # def run(mode: int = AUTO, ceil: int = 100, repeat: int = 10):
    # """
    # Runs a sequence of Higher/Lower games using the given answering method and
    # returns the win/loss statistics.
    #
    # :param mode <int> how to guess--one of AUTO, LOWER, HIGHER, or EXACT
    # :param ceil <int> the upper bound for the range used to pick random numbers
    # :param repeat <int> the number of rounds to play
    # :return <dict> contains information about the wins/losses. e.g.:
    # {"win": 98, "lose": 2, "mode": AUTO}
    # """
    # if mode not in {HIGHER, EXACT, LOWER, AUTO}:
    # raise ValueError("invalid run mode")

    def accuracy_rate(mode: int = AUTO, ceil: int = 100):
    """
    Calculate the expected percentage of correct answers for the given mode and
    ceiling
    :param mode <int> how to guess--one of AUTO, LOWER, HIGHER, or EXACT
    :param ceil <int> the upper bound for the range used to pick random numbers
    :returns <float> the expected percentage of wins as a float between 0-1
    """
    if mode == AUTO:
    return (ceil - 1) / ceil
    if mode == HIGHER or mode == LOWER:
    return ((ceil / 2) - 0.5) / ceil
    if mode == EXACT:
    return 1 / ceil

    if __name__ == "__main__":
    import random
    import argparse

    parser = argparse.ArgumentParser(description="Guess a random number.")
    guess_mode = parser.add_mutually_exclusive_group()

    parser.add_argument("-m", "--max", type=int, default=100,
    help="select random numbers between 1 and `max`")
    guess_mode.add_argument("-i", "--higher", dest="higher", action="store_true",
    help="always guess higher")
    guess_mode.add_argument("-l", "--lower", dest="lower", action="store_true",
    help="always guess lower")
    guess_mode.add_argument("-e", "--exact", dest="exact", action="store_true",
    help="always guess the exact value")
    guess_mode.add_argument("-a", "--auto", dest="auto", action="store_true",
    help="always guess based on highest probability")
    parser.add_argument("-r", "--repeat", dest="repeat", type=int, default=1,
    help="number of times to repeat")
    parser.add_argument("-v", "--verbose", dest="verbose", action="store_true",
    help="show each trial")
    args = parser.parse_args()

    stats = {
    "win": 0,
    "lose": 0,
    }

    if args.higher:
    mode = HIGHER
    elif args.lower:
    mode = LOWER
    elif args.exact:
    mode = EXACT
    else:
    mode = AUTO

    for result in run(mode, args.max, args.repeat):
    if args.verbose:
    print(f"{result['target']:<2}", end=" ")
    if mode == HIGHER:
    print(">", end=" ")
    elif mode == LOWER:
    print("<", end=" ")
    elif mode == EXACT:
    print("=", end=" ")
    else:
    print("?", end=" ")
    print(f"{result['random']:<2}", end=" ")
    print(result['success'])
    if result['success']:
    stats["win"] += 1
    else:
    stats["lose"] += 1

    print(stats)