{ "cells": [ { "attachments": {}, "cell_type": "markdown", "id": "3c99bb5b-3e7b-486e-b888-440b5862b48c", "metadata": {}, "source": [ "# The Number Bracelets Game\n", "\n", "Susan Addington describes [the numbers bracelet game](http://www.geom.uiuc.edu/~addingto/number_bracelets/number_bracelets.html):\n", "\n", "*Imagine that you have lots of beads, numbered from 0 through 9, as many as you want of each kind. Here are the rules for making a number bracelet:*\n", "\n", "- *Pick a first and a second bead. They can have the same number.*\n", "- *To get the third bead, add the numbers on the first and second beads. If the sum is more than 9, just use the last (ones) digit of the sum.*\n", "- *To get the next bead, add the numbers on the last two beads you used, and use only the ones digit. So to get the fourth bead, add the numbers on the second and third beads, and use the ones digit.*\n", "- *Keep going until you get back to the first and second beads, in that order.*\n", "- *Then pop off the last two beads.*" ] }, { "cell_type": "markdown", "id": "3a10c327-1c04-400f-a2a8-d51cedfb89a9", "metadata": {}, "source": [ "# Making Bracelets\n", "\n", "The function `number_bracelet` will make a number bracelet, if you give it a pair of starting beads:" ] }, { "cell_type": "code", "execution_count": 1, "id": "2d5f4a73-f4eb-4afa-8592-2274c9d8aac8", "metadata": {}, "outputs": [], "source": [ "def number_bracelet(beads):\n", " \"\"\"Given a pair of beads, extend the beads until the first two match the last two.\"\"\"\n", " while True: \n", " next_bead = (beads[-1] + beads[-2]) % 10\n", " beads = (*beads, next_bead)\n", " if beads[:2] == beads[-2:]: return beads[:-2]" ] }, { "cell_type": "markdown", "id": "a1060352-f4c1-4d6e-b852-8273d2938847", "metadata": {}, "source": [ "For example:" ] }, { "cell_type": "code", "execution_count": 2, "id": "85ac6e69-7dc6-4fb2-9359-f38f606d1917", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 6, 8, 4)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "number_bracelet((2, 6))" ] }, { "cell_type": "markdown", "id": "4ca0ab11-17ed-43a2-8da4-2863a43ede3c", "metadata": {}, "source": [ "![](http://www.geom.uiuc.edu/~addingto/number_bracelets/2,6bracelet.gif)" ] }, { "cell_type": "code", "execution_count": 3, "id": "e4bb755e-d538-4443-8387-5784bb4e4211", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 3, 4, 7, 1, 8, 9, 7, 6, 3, 9, 2)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "number_bracelet((1, 3))" ] }, { "cell_type": "markdown", "id": "1a7ae42e-fc59-422d-b592-8e7defc04ffd", "metadata": {}, "source": [ "![](http://www.geom.uiuc.edu/~addingto/number_bracelets/1,3bracelet.gif)" ] }, { "cell_type": "markdown", "id": "72b69698-6e08-4dd9-a725-533a658a175a", "metadata": {}, "source": [ "One question: If the two starting beads are both 0, then all the following beads will also be 0. When do we stop? Do we stop after (0, 0, 0), drop the last two, and end up with a single 0? Or do we keep going to (0, 0, 0, 0), drop the last two, and end up with (0, 0)? I chose the former, but either choice would be ok, I think." ] }, { "cell_type": "markdown", "id": "85c13666-e925-49fd-b8ca-c3ea7dc100cd", "metadata": {}, "source": [ "# All Possible Bracelets\n", "\n", "There are 100 possible two-digit starting pairs, so there should be 100 possible bracelets. We can make all of them:" ] }, { "cell_type": "code", "execution_count": 4, "id": "f248d81c-2738-405c-a62e-b127a63a0a42", "metadata": {}, "outputs": [], "source": [ "digits = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n", "\n", "all_bracelets = [number_bracelet((first, second)) for first in digits for second in digits]" ] }, { "cell_type": "markdown", "id": "ae759911-d85e-4d53-9f2c-a637fb4ee7e9", "metadata": {}, "source": [ "I'll define `show` to print out each bracelet on a line, with the number of beads in the bracelet first:" ] }, { "cell_type": "code", "execution_count": 5, "id": "70773cb8-9359-401a-b79b-165aa12161a6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 1 beads: 0\n", "60 beads: 011235831459437077415617853819099875279651673033695493257291\n", "20 beads: 02246066280886404482\n", "60 beads: 033695493257291011235831459437077415617853819099875279651673\n", "20 beads: 04482022460662808864\n", " 3 beads: 055\n", "20 beads: 06628088640448202246\n", "60 beads: 077415617853819099875279651673033695493257291011235831459437\n", "20 beads: 08864044820224606628\n", "60 beads: 099875279651673033695493257291011235831459437077415617853819\n", "60 beads: 101123583145943707741561785381909987527965167303369549325729\n", "60 beads: 112358314594370774156178538190998752796516730336954932572910\n", "60 beads: 123583145943707741561785381909987527965167303369549325729101\n", "12 beads: 134718976392\n", "60 beads: 145943707741561785381909987527965167303369549325729101123583\n", "60 beads: 156178538190998752796516730336954932572910112358314594370774\n", "60 beads: 167303369549325729101123583145943707741561785381909987527965\n", "60 beads: 178538190998752796516730336954932572910112358314594370774156\n", "12 beads: 189763921347\n", "60 beads: 190998752796516730336954932572910112358314594370774156178538\n", "20 beads: 20224606628088640448\n", "12 beads: 213471897639\n", "20 beads: 22460662808864044820\n", "60 beads: 235831459437077415617853819099875279651673033695493257291011\n", "20 beads: 24606628088640448202\n", "60 beads: 257291011235831459437077415617853819099875279651673033695493\n", " 4 beads: 2684\n", "60 beads: 279651673033695493257291011235831459437077415617853819099875\n", "20 beads: 28088640448202246066\n", "60 beads: 291011235831459437077415617853819099875279651673033695493257\n", "60 beads: 303369549325729101123583145943707741561785381909987527965167\n", "60 beads: 314594370774156178538190998752796516730336954932572910112358\n", "60 beads: 325729101123583145943707741561785381909987527965167303369549\n", "60 beads: 336954932572910112358314594370774156178538190998752796516730\n", "12 beads: 347189763921\n", "60 beads: 358314594370774156178538190998752796516730336954932572910112\n", "60 beads: 369549325729101123583145943707741561785381909987527965167303\n", "60 beads: 370774156178538190998752796516730336954932572910112358314594\n", "60 beads: 381909987527965167303369549325729101123583145943707741561785\n", "12 beads: 392134718976\n", "20 beads: 40448202246066280886\n", "60 beads: 415617853819099875279651673033695493257291011235831459437077\n", " 4 beads: 4268\n", "60 beads: 437077415617853819099875279651673033695493257291011235831459\n", "20 beads: 44820224606628088640\n", "60 beads: 459437077415617853819099875279651673033695493257291011235831\n", "20 beads: 46066280886404482022\n", "12 beads: 471897639213\n", "20 beads: 48202246066280886404\n", "60 beads: 493257291011235831459437077415617853819099875279651673033695\n", " 3 beads: 505\n", "60 beads: 516730336954932572910112358314594370774156178538190998752796\n", "60 beads: 527965167303369549325729101123583145943707741561785381909987\n", "60 beads: 538190998752796516730336954932572910112358314594370774156178\n", "60 beads: 549325729101123583145943707741561785381909987527965167303369\n", " 3 beads: 550\n", "60 beads: 561785381909987527965167303369549325729101123583145943707741\n", "60 beads: 572910112358314594370774156178538190998752796516730336954932\n", "60 beads: 583145943707741561785381909987527965167303369549325729101123\n", "60 beads: 594370774156178538190998752796516730336954932572910112358314\n", "20 beads: 60662808864044820224\n", "60 beads: 617853819099875279651673033695493257291011235831459437077415\n", "20 beads: 62808864044820224606\n", "12 beads: 639213471897\n", "20 beads: 64044820224606628088\n", "60 beads: 651673033695493257291011235831459437077415617853819099875279\n", "20 beads: 66280886404482022460\n", "60 beads: 673033695493257291011235831459437077415617853819099875279651\n", " 4 beads: 6842\n", "60 beads: 695493257291011235831459437077415617853819099875279651673033\n", "60 beads: 707741561785381909987527965167303369549325729101123583145943\n", "12 beads: 718976392134\n", "60 beads: 729101123583145943707741561785381909987527965167303369549325\n", "60 beads: 730336954932572910112358314594370774156178538190998752796516\n", "60 beads: 741561785381909987527965167303369549325729101123583145943707\n", "60 beads: 752796516730336954932572910112358314594370774156178538190998\n", "12 beads: 763921347189\n", "60 beads: 774156178538190998752796516730336954932572910112358314594370\n", "60 beads: 785381909987527965167303369549325729101123583145943707741561\n", "60 beads: 796516730336954932572910112358314594370774156178538190998752\n", "20 beads: 80886404482022460662\n", "60 beads: 819099875279651673033695493257291011235831459437077415617853\n", "20 beads: 82022460662808864044\n", "60 beads: 831459437077415617853819099875279651673033695493257291011235\n", " 4 beads: 8426\n", "60 beads: 853819099875279651673033695493257291011235831459437077415617\n", "20 beads: 86404482022460662808\n", "60 beads: 875279651673033695493257291011235831459437077415617853819099\n", "20 beads: 88640448202246066280\n", "12 beads: 897639213471\n", "60 beads: 909987527965167303369549325729101123583145943707741561785381\n", "60 beads: 910112358314594370774156178538190998752796516730336954932572\n", "12 beads: 921347189763\n", "60 beads: 932572910112358314594370774156178538190998752796516730336954\n", "60 beads: 943707741561785381909987527965167303369549325729101123583145\n", "60 beads: 954932572910112358314594370774156178538190998752796516730336\n", "60 beads: 965167303369549325729101123583145943707741561785381909987527\n", "12 beads: 976392134718\n", "60 beads: 987527965167303369549325729101123583145943707741561785381909\n", "60 beads: 998752796516730336954932572910112358314594370774156178538190\n" ] } ], "source": [ "def show(bracelets):\n", " \"\"\"Print each of the bracelets, preceeded by its number of beads.\n", " Squish the beads together with no spaces between them, so they fit on one line.\"\"\"\n", " for bracelet in bracelets:\n", " print(f'{len(bracelet):2} beads: ', *bracelet, sep='')\n", "\n", "show(all_bracelets)" ] }, { "cell_type": "markdown", "id": "21dc3fe1-dc06-4b57-a7b8-e21502086ac9", "metadata": {}, "source": [ "# How Many Bracelets?\n", "\n", "I have a list of 100 bracelets, but consider the 4-bead bracelet I showed at the top of the page; the one with the list of beads `(2, 6, 8, 4)`. Bracelets are circular, so that's really the same bracelet as `(6, 8, 4, 2)` or `(8, 4, 2, 6)` or `(4, 2, 6, 8)`. So how many *different* bracelets are there?\n", "\n", "![](http://www.geom.uiuc.edu/~addingto/number_bracelets/1,3bracelet.gif)\n", "\n", "To find out, I'll put all bracelets in a *common form*: I'll choose the sequence that starts with the lowest number in the bracelet, so that would be `(2, 6, 8, 4)`. If a bracelet repeats the lowest number more than once, start with the lowest two-digit pair, and so on. Once I have all the bracelets in common form, make a set out of them and `show` the distinct members of this set:" ] }, { "cell_type": "code", "execution_count": 6, "id": "e3a97290-59bf-44dc-922c-6fbecaa21317", "metadata": {}, "outputs": [], "source": [ "def common_form(bracelet):\n", " \"\"\"Represent this bracelet by choosing the lowest numerical rotation out of all possible rotations.\"\"\"\n", " return min(rotations(bracelet))\n", "\n", "def rotations(bracelet):\n", " \"\"\"All possible rotations of bracelet.\"\"\"\n", " return [bracelet[i:] + bracelet[:i] for i in range(len(bracelet))]" ] }, { "cell_type": "code", "execution_count": 7, "id": "d8a8e358-b9cf-4bd3-88e2-789145329764", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(2, 6, 8, 4), (6, 8, 4, 2), (8, 4, 2, 6), (4, 2, 6, 8)]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rotations((2, 6, 8, 4))" ] }, { "cell_type": "code", "execution_count": 8, "id": "64f66bdd-f5ff-4861-8861-b33dc2707182", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 6, 8, 4)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "common_form((6, 8, 4, 2))" ] }, { "cell_type": "code", "execution_count": 9, "id": "0cb6ff68-e15a-4bdf-92e4-2ba63963b8f7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 4 beads: 2684\n", " 3 beads: 055\n", "12 beads: 134718976392\n", "60 beads: 011235831459437077415617853819099875279651673033695493257291\n", " 1 beads: 0\n", "20 beads: 02246066280886404482\n" ] } ], "source": [ "show({common_form(b) for b in all_bracelets})" ] }, { "cell_type": "markdown", "id": "5276c097-6a6b-4b6a-b146-ef2fae4a8ecd", "metadata": {}, "source": [ "We see there are only six distinct bracelets." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.15" } }, "nbformat": 4, "nbformat_minor": 5 }