From 37f0af3a6248d8e8f0a8bfdefc59d216d18bf598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:44:04 -0800 Subject: [PATCH 1/3] add `camicia` --- config.json | 8 + .../practice/camicia/.docs/instructions.md | 84 + .../practice/camicia/.docs/introduction.md | 24 + exercises/practice/camicia/.meta/config.json | 19 + exercises/practice/camicia/.meta/example.py | 70 + exercises/practice/camicia/.meta/template.j2 | 12 + exercises/practice/camicia/.meta/tests.toml | 94 ++ exercises/practice/camicia/camicia.py | 2 + exercises/practice/camicia/camicia_test.py | 1408 +++++++++++++++++ 9 files changed, 1721 insertions(+) create mode 100644 exercises/practice/camicia/.docs/instructions.md create mode 100644 exercises/practice/camicia/.docs/introduction.md create mode 100644 exercises/practice/camicia/.meta/config.json create mode 100644 exercises/practice/camicia/.meta/example.py create mode 100644 exercises/practice/camicia/.meta/template.j2 create mode 100644 exercises/practice/camicia/.meta/tests.toml create mode 100644 exercises/practice/camicia/camicia.py create mode 100644 exercises/practice/camicia/camicia_test.py diff --git a/config.json b/config.json index 2bbf7486ad..22699f55e8 100644 --- a/config.json +++ b/config.json @@ -1738,6 +1738,14 @@ ], "difficulty": 5 }, + { + "slug": "camicia", + "name": "Camicia", + "uuid": "ec314b34-2ee3-4eec-9a97-aece9e5fd6c2", + "practices": [], + "prerequisites": [], + "difficulty": 5 + }, { "slug": "rational-numbers", "name": "Rational Numbers", diff --git a/exercises/practice/camicia/.docs/instructions.md b/exercises/practice/camicia/.docs/instructions.md new file mode 100644 index 0000000000..db62fcef27 --- /dev/null +++ b/exercises/practice/camicia/.docs/instructions.md @@ -0,0 +1,84 @@ +# Instructions + +In this exercise, you will simulate a game very similar to the classic card game **Camicia**. +Your program will receive the initial configuration of two players' decks and must simulate the game until it ends (or detect that it will never end). + +## Rules + +- The deck is split between **two players**. + The player's cards are read from left to right, where the leftmost card is the top of the deck. +- A round consists of both players playing at least one card. +- Players take turns placing the **top card** of their deck onto a central pile. +- If the card is a **number card** (2-10), play simply passes to the other player. +- If the card is a **payment card**, a penalty must be paid: + - **J** → opponent must pay 1 card + - **Q** → opponent must pay 2 cards + - **K** → opponent must pay 3 cards + - **A** → opponent must pay 4 cards +- If the player paying a penalty reveals another payment card, that player stops paying the penalty. + The other player must then pay a penalty based on the new payment card. +- If the penalty is fully paid without interruption, the player who placed the **last payment card** collects the central pile and places it at the bottom of their deck. + That player then starts the next round. +- If a player runs out of cards and is unable to play a card (either while paying a penalty or when it is their turn), the other player collects the central pile. +- The moment when a player collects cards from the central pile is called a **trick**. +- If a player has all the cards in their possession after a trick, the game **ends**. +- The game **enters a loop** as soon as the decks are identical to what they were earlier during the game, **not** counting number cards! + +## Examples + +A small example of a match that ends. + +| Round | Player A | Player B | Pile | Penalty Due | +| :---- | :----------- | :------------------------- | :------------------------- | :---------- | +| 1 | 2 A 7 8 Q 10 | 3 4 5 6 K 9 J | | - | +| 1 | A 7 8 Q 10 | 3 4 5 6 K 9 J | 2 | - | +| 1 | A 7 8 Q 10 | 4 5 6 K 9 J | 2 3 | - | +| 1 | 7 8 Q 10 | 4 5 6 K 9 J | 2 3 A | Player B: 4 | +| 1 | 7 8 Q 10 | 5 6 K 9 J | 2 3 A 4 | Player B: 3 | +| 1 | 7 8 Q 10 | 6 K 9 J | 2 3 A 4 5 | Player B: 2 | +| 1 | 7 8 Q 10 | K 9 J | 2 3 A 4 5 6 | Player B: 1 | +| 1 | 7 8 Q 10 | 9 J | 2 3 A 4 5 6 K | Player A: 3 | +| 1 | 8 Q 10 | 9 J | 2 3 A 4 5 6 K 7 | Player A: 2 | +| 1 | Q 10 | 9 J | 2 3 A 4 5 6 K 7 8 | Player A: 1 | +| 1 | 10 | 9 J | 2 3 A 4 5 6 K 7 8 Q | Player B: 2 | +| 1 | 10 | J | 2 3 A 4 5 6 K 7 8 Q 9 | Player B: 1 | +| 1 | 10 | - | 2 3 A 4 5 6 K 7 8 Q 9 J | Player A: 1 | +| 1 | - | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - | +| 2 | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - | - | + +status: `"finished"`, cards: 13, tricks: 1 + +This is a small example of a match that loops. + +| Round | Player A | Player B | Pile | Penalty Due | +| :---- | :------- | :------- | :---- | :---------- | +| 1 | J 2 3 | 4 J 5 | - | - | +| 1 | 2 3 | 4 J 5 | J | Player B: 1 | +| 1 | 2 3 | J 5 | J 4 | - | +| 2 | 2 3 J 4 | J 5 | - | - | +| 2 | 3 J 4 | J 5 | 2 | - | +| 2 | 3 J 4 | 5 | 2 J | Player A: 1 | +| 2 | J 4 | 5 | 2 J 3 | - | +| 3 | J 4 | 5 2 J 3 | - | - | +| 3 | J 4 | 2 J 3 | 5 | - | +| 3 | 4 | 2 J 3 | 5 J | Player B: 1 | +| 3 | 4 | J 3 | 5 J 2 | - | +| 4 | 4 5 J 2 | J 3 | - | - | + +The start of round 4 matches the start of round 2. +Recall, the value of the number cards does not matter. + +status: `"loop"`, cards: 8, tricks: 3 + +## Your Task + +- Using the input, simulate the game following the rules above. +- Determine the following information regarding the game: + - **Status**: `"finished"` or `"loop"` + - **Cards**: total number of cards played throughout the game + - **Tricks**: number of times the central pile was collected + +~~~~exercism/advanced +For those who want to take on a more exciting challenge, the hunt for other records for the longest game with an end is still open. +There are 653,534,134,886,878,245,000 (approximately 654 quintillion) possibilities, and we haven't calculated them all yet! +~~~~ diff --git a/exercises/practice/camicia/.docs/introduction.md b/exercises/practice/camicia/.docs/introduction.md new file mode 100644 index 0000000000..761d8a82c5 --- /dev/null +++ b/exercises/practice/camicia/.docs/introduction.md @@ -0,0 +1,24 @@ +# Introduction + +One rainy afternoon, you sit at the kitchen table playing cards with your grandmother. +The game is her take on [Camicia][bmn]. + +At first it feels like just another friendly match: cards slapped down, laughter across the table, the occasional victorious grin from Nonna. +But as the game stretches on, something strange happens. +The same cards keep cycling back. +You play card after card, yet the end never seems to come. + +You start to wonder. +_Will this game ever finish? +Or could we keep playing forever?_ + +Later, driven by curiosity, you search online and to your surprise you discover that what happened wasn't just bad luck. +You and your grandmother may have stumbled upon one of the longest possible sequences! +Suddenly, you're hooked. +What began as a casual game has turned into a quest: _how long can such a game really last?_ +_Can you find a sequence even longer than the one you played at the kitchen table?_ +_Perhaps even long enough to set a new world record?_ + +And so, armed with nothing but a deck of cards and some algorithmic ingenuity, you decide to investigate... + +[bmn]: https://en.wikipedia.org/wiki/Beggar-my-neighbour diff --git a/exercises/practice/camicia/.meta/config.json b/exercises/practice/camicia/.meta/config.json new file mode 100644 index 0000000000..9956e52178 --- /dev/null +++ b/exercises/practice/camicia/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "camicia.py" + ], + "test": [ + "camicia_test.py" + ], + "example": [ + ".meta/example.py" + ] + }, + "blurb": "Simulate the card game and determine whether the match ends or enters an infinite loop.", + "source": "Beggar-My-Neighbour", + "source_url": "https://www.richardpmann.com/beggar-my-neighbour-records.html" +} diff --git a/exercises/practice/camicia/.meta/example.py b/exercises/practice/camicia/.meta/example.py new file mode 100644 index 0000000000..7451490d95 --- /dev/null +++ b/exercises/practice/camicia/.meta/example.py @@ -0,0 +1,70 @@ +def simulate_game(player_a, player_b): + hand_a = list(map(get_value, player_a)) + hand_b = list(map(get_value, player_b)) + turn = "A" + pile = [] + seen = set() + total_tricks = 0 + cards_played = 0 + current_debt = 0 + + while True: + if not pile: + state = (tuple(hand_a), tuple(hand_b), turn) + if state in seen: + return { + "status": "loop", + "tricks": total_tricks, + "cards": cards_played + } + seen.add(state) + + active_hand = hand_a if turn == "A" else hand_b + other_hand = hand_b if turn == "A" else hand_a + + if not active_hand: + extra_trick = 0 if not pile else 1 + return { + "status": "finished", + "tricks": total_tricks + extra_trick, + "cards": cards_played, + } + + card_val = active_hand.pop(0) + pile.append(card_val) + cards_played += 1 + + if card_val > 0: + current_debt = card_val + turn = "B" if turn == "A" else "A" + else: + if current_debt > 0: + current_debt -= 1 + if not current_debt: + other_hand.extend(pile) + pile = [] + total_tricks += 1 + current_debt = 0 + + if not hand_a or not hand_b: + return { + "status": "finished", + "tricks": total_tricks, + "cards": cards_played + } + + turn = "B" if turn == "A" else "A" + else: + turn = "B" if turn == "A" else "A" + + +def get_value(card): + if card == "J": + return 1 + if card == "Q": + return 2 + if card == "K": + return 3 + if card == "A": + return 4 + return 0 diff --git a/exercises/practice/camicia/.meta/template.j2 b/exercises/practice/camicia/.meta/template.j2 new file mode 100644 index 0000000000..1bc055d62c --- /dev/null +++ b/exercises/practice/camicia/.meta/template.j2 @@ -0,0 +1,12 @@ +{%- import "generator_macros.j2" as macros with context -%} +{{ macros.canonical_ref() }} + +{{ macros.header() }} + +class {{ exercise | camel_case }}Test(unittest.TestCase): + {% for case in cases -%} + def test_{{ case["description"] | to_snake }}(self): + player_a = {{ case["input"]["playerA"] }} + player_b = {{ case["input"]["playerB"] }} + self.assertEqual(simulate_game(player_a, player_b), {{ case["expected"] }}) + {% endfor -%} diff --git a/exercises/practice/camicia/.meta/tests.toml b/exercises/practice/camicia/.meta/tests.toml new file mode 100644 index 0000000000..18d3fdd99f --- /dev/null +++ b/exercises/practice/camicia/.meta/tests.toml @@ -0,0 +1,94 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[0b7f737c-3ecd-4a55-b34d-e65c62a85c28] +description = "two cards, one trick" + +[27c19d75-53a5-48e5-b33b-232c3884d4f3] +description = "three cards, one trick" + +[9b02dd49-efaf-4b71-adca-a05c18a7c5b0] +description = "four cards, one trick" + +[fa3f4479-466a-4734-a001-ab79bfe27260] +description = "the ace reigns supreme" + +[07629689-f589-4f54-a6d1-8ce22776ce72] +description = "the king beats ace" + +[54d4a1c5-76fb-4d1e-8358-0e0296ac0601] +description = "the queen seduces the king" + +[c875500c-ff3d-47a4-bd1e-b60b90da80aa] +description = "the jack betrays the queen" + +[436875da-96ca-4149-be22-0b78173b8125] +description = "the 10 just wants to put on a show" + +[5be39bb6-1b34-4ce6-a1cd-0fcc142bb272] +description = "simple loop with decks of 3 cards" + +[2795dc21-0a2a-4c38-87c2-5a42e1ff15eb] +description = "the story is starting to get a bit complicated" + +[6999dfac-3fdc-41e2-b64b-38f4be228712] +description = "two tricks" + +[83dcd4f3-e089-4d54-855a-73f5346543a3] +description = "more tricks" + +[3107985a-f43e-486a-9ce8-db51547a9941] +description = "simple loop with decks of 4 cards" + +[dca32c31-11ed-49f6-b078-79ab912c1f7b] +description = "easy card combination" + +[1f8488d0-48d3-45ae-b819-59cedad0a5f4] +description = "easy card combination, inverted decks" + +[98878d35-623a-4d05-b81a-7bdc569eb88d] +description = "mirrored decks" + +[3e0ba597-ca10-484b-87a3-31a7df7d6da3] +description = "opposite decks" + +[92334ddb-aaa7-47fa-ab36-e928a8a6a67c] +description = "random decks #1" + +[30477523-9651-4860-84a3-e1ac461bb7fa] +description = "random decks #2" + +[20967de8-9e94-4e0e-9010-14bc1c157432] +description = "Kleber 1999" + +[9f2fdfe8-27f3-4323-816d-6bce98a9c6f7] +description = "Collins 2006" + +[c90b6f8d-7013-49f3-b5cb-14ea006cca1d] +description = "Mann and Wu 2007" + +[a3f1fbc5-1d0b-499a-92a5-22932dfc6bc8] +description = "Nessler 2012" + +[9cefb1ba-e6d1-4ab7-9d8f-76d8e0976d5f] +description = "Anderson 2013" + +[d37c0318-5be6-48d0-ab72-a7aaaff86179] +description = "Rucklidge 2014" + +[4305e479-ba87-432f-8a29-cd2bd75d2f05] +description = "Nessler 2021" + +[252f5cc3-b86d-4251-87ce-f920b7a6a559] +description = "Nessler 2022" + +[b9efcfa4-842f-4542-8112-8389c714d958] +description = "Casella 2024, first infinite game found" diff --git a/exercises/practice/camicia/camicia.py b/exercises/practice/camicia/camicia.py new file mode 100644 index 0000000000..61ac6ed552 --- /dev/null +++ b/exercises/practice/camicia/camicia.py @@ -0,0 +1,2 @@ +def simulate_game(player_a, player_b): + pass diff --git a/exercises/practice/camicia/camicia_test.py b/exercises/practice/camicia/camicia_test.py new file mode 100644 index 0000000000..8c8fb989b6 --- /dev/null +++ b/exercises/practice/camicia/camicia_test.py @@ -0,0 +1,1408 @@ +# These tests are auto-generated with test data from: +# https://github.com/exercism/problem-specifications/tree/main/exercises/camicia/canonical-data.json +# File last updated on 2026-01-24 + +import unittest + +from camicia import ( + simulate_game, +) + + +class CamiciaTest(unittest.TestCase): + def test_two_cards_one_trick(self): + player_a = ["2"] + player_b = ["3"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 2, "tricks": 1}, + ) + + def test_three_cards_one_trick(self): + player_a = ["2", "4"] + player_b = ["3"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 3, "tricks": 1}, + ) + + def test_four_cards_one_trick(self): + player_a = ["2", "4"] + player_b = ["3", "5", "6"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 4, "tricks": 1}, + ) + + def test_the_ace_reigns_supreme(self): + player_a = ["2", "A"] + player_b = ["3", "4", "5", "6", "7"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7, "tricks": 1}, + ) + + def test_the_king_beats_ace(self): + player_a = ["2", "A"] + player_b = ["3", "4", "5", "6", "K"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7, "tricks": 1}, + ) + + def test_the_queen_seduces_the_king(self): + player_a = ["2", "A", "7", "8", "Q"] + player_b = ["3", "4", "5", "6", "K"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 10, "tricks": 1}, + ) + + def test_the_jack_betrays_the_queen(self): + player_a = ["2", "A", "7", "8", "Q"] + player_b = ["3", "4", "5", "6", "K", "9", "J"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 12, "tricks": 1}, + ) + + def test_the_10_just_wants_to_put_on_a_show(self): + player_a = ["2", "A", "7", "8", "Q", "10"] + player_b = ["3", "4", "5", "6", "K", "9", "J"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 13, "tricks": 1}, + ) + + def test_simple_loop_with_decks_of_3_cards(self): + player_a = ["J", "2", "3"] + player_b = ["4", "J", "5"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "loop", "cards": 8, "tricks": 3}, + ) + + def test_the_story_is_starting_to_get_a_bit_complicated(self): + player_a = [ + "2", + "6", + "6", + "J", + "4", + "K", + "Q", + "10", + "K", + "J", + "Q", + "2", + "3", + "K", + "5", + "6", + "Q", + "Q", + "A", + "A", + "6", + "9", + "K", + "A", + "8", + "K", + "2", + "A", + "9", + "A", + "Q", + "4", + "K", + "K", + "K", + "3", + "5", + "K", + "8", + "Q", + "3", + "Q", + "7", + "J", + "K", + "J", + "9", + "J", + "3", + "3", + "K", + "K", + "Q", + "A", + "K", + "7", + "10", + "A", + "Q", + "7", + "10", + "J", + "4", + "5", + "J", + "9", + "10", + "Q", + "J", + "J", + "K", + "6", + "10", + "J", + "6", + "Q", + "J", + "5", + "J", + "Q", + "Q", + "8", + "3", + "8", + "A", + "2", + "6", + "9", + "K", + "7", + "J", + "K", + "K", + "8", + "K", + "Q", + "6", + "10", + "J", + "10", + "J", + "Q", + "J", + "10", + "3", + "8", + "K", + "A", + "6", + "9", + "K", + "2", + "A", + "A", + "10", + "J", + "6", + "A", + "4", + "J", + "A", + "J", + "J", + "6", + "2", + "J", + "3", + "K", + "2", + "5", + "9", + "J", + "9", + "6", + "K", + "A", + "5", + "Q", + "J", + "2", + "Q", + "K", + "A", + "3", + "K", + "J", + "K", + "2", + "5", + "6", + "Q", + "J", + "Q", + "Q", + "J", + "2", + "J", + "9", + "Q", + "7", + "7", + "A", + "Q", + "7", + "Q", + "J", + "K", + "J", + "A", + "7", + "7", + "8", + "Q", + "10", + "J", + "10", + "J", + "J", + "9", + "2", + "A", + "2", + ] + player_b = [ + "7", + "2", + "10", + "K", + "8", + "2", + "J", + "9", + "A", + "5", + "6", + "J", + "Q", + "6", + "K", + "6", + "5", + "A", + "4", + "Q", + "7", + "J", + "7", + "10", + "2", + "Q", + "8", + "2", + "2", + "K", + "J", + "A", + "5", + "5", + "A", + "4", + "Q", + "6", + "Q", + "K", + "10", + "8", + "Q", + "2", + "10", + "J", + "A", + "Q", + "8", + "Q", + "Q", + "J", + "J", + "A", + "A", + "9", + "10", + "J", + "K", + "4", + "Q", + "10", + "10", + "J", + "K", + "10", + "2", + "J", + "7", + "A", + "K", + "K", + "J", + "A", + "J", + "10", + "8", + "K", + "A", + "7", + "Q", + "Q", + "J", + "3", + "Q", + "4", + "A", + "3", + "A", + "Q", + "Q", + "Q", + "5", + "4", + "K", + "J", + "10", + "A", + "Q", + "J", + "6", + "J", + "A", + "10", + "A", + "5", + "8", + "3", + "K", + "5", + "9", + "Q", + "8", + "7", + "7", + "J", + "7", + "Q", + "Q", + "Q", + "A", + "7", + "8", + "9", + "A", + "Q", + "A", + "K", + "8", + "A", + "A", + "J", + "8", + "4", + "8", + "K", + "J", + "A", + "10", + "Q", + "8", + "J", + "8", + "6", + "10", + "Q", + "J", + "J", + "A", + "A", + "J", + "5", + "Q", + "6", + "J", + "K", + "Q", + "8", + "K", + "4", + "Q", + "Q", + "6", + "J", + "K", + "4", + "7", + "J", + "J", + "9", + "9", + "A", + "Q", + "Q", + "K", + "A", + "6", + "5", + "K", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 361, "tricks": 1}, + ) + + def test_two_tricks(self): + player_a = ["J"] + player_b = ["3", "J"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 5, "tricks": 2}, + ) + + def test_more_tricks(self): + player_a = ["J", "2", "4"] + player_b = ["3", "J", "A"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 12, "tricks": 4}, + ) + + def test_simple_loop_with_decks_of_4_cards(self): + player_a = ["2", "3", "J", "6"] + player_b = ["K", "5", "J", "7"] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "loop", "cards": 16, "tricks": 4}, + ) + + def test_easy_card_combination(self): + player_a = [ + "4", + "8", + "7", + "5", + "4", + "10", + "3", + "9", + "7", + "3", + "10", + "10", + "6", + "8", + "2", + "8", + "5", + "4", + "5", + "9", + "6", + "5", + "2", + "8", + "10", + "9", + ] + player_b = [ + "6", + "9", + "4", + "7", + "2", + "2", + "3", + "6", + "7", + "3", + "A", + "A", + "A", + "A", + "K", + "K", + "K", + "K", + "Q", + "Q", + "Q", + "Q", + "J", + "J", + "J", + "J", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 40, "tricks": 4}, + ) + + def test_easy_card_combination_inverted_decks(self): + player_a = [ + "3", + "3", + "5", + "7", + "3", + "2", + "10", + "7", + "6", + "7", + "A", + "A", + "A", + "A", + "K", + "K", + "K", + "K", + "Q", + "Q", + "Q", + "Q", + "J", + "J", + "J", + "J", + ] + player_b = [ + "5", + "10", + "8", + "2", + "6", + "7", + "2", + "4", + "9", + "2", + "6", + "10", + "10", + "5", + "4", + "8", + "4", + "8", + "6", + "9", + "8", + "5", + "9", + "3", + "4", + "9", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 40, "tricks": 4}, + ) + + def test_mirrored_decks(self): + player_a = [ + "2", + "A", + "3", + "A", + "3", + "K", + "4", + "K", + "2", + "Q", + "2", + "Q", + "10", + "J", + "5", + "J", + "6", + "10", + "2", + "9", + "10", + "7", + "3", + "9", + "6", + "9", + ] + player_b = [ + "6", + "A", + "4", + "A", + "7", + "K", + "4", + "K", + "7", + "Q", + "7", + "Q", + "5", + "J", + "8", + "J", + "4", + "5", + "8", + "9", + "10", + "6", + "8", + "3", + "8", + "5", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 59, "tricks": 4}, + ) + + def test_opposite_decks(self): + player_a = [ + "4", + "A", + "9", + "A", + "4", + "K", + "9", + "K", + "6", + "Q", + "8", + "Q", + "8", + "J", + "10", + "J", + "9", + "8", + "4", + "6", + "3", + "6", + "5", + "2", + "4", + "3", + ] + player_b = [ + "10", + "7", + "3", + "2", + "9", + "2", + "7", + "8", + "7", + "5", + "J", + "7", + "J", + "10", + "Q", + "10", + "Q", + "3", + "K", + "5", + "K", + "6", + "A", + "2", + "A", + "5", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 151, "tricks": 21}, + ) + + def test_random_decks_1(self): + player_a = [ + "K", + "10", + "9", + "8", + "J", + "8", + "6", + "9", + "7", + "A", + "K", + "5", + "4", + "4", + "J", + "5", + "J", + "4", + "3", + "5", + "8", + "6", + "7", + "7", + "4", + "9", + ] + player_b = [ + "6", + "3", + "K", + "A", + "Q", + "10", + "A", + "2", + "Q", + "8", + "2", + "10", + "10", + "2", + "Q", + "3", + "K", + "9", + "7", + "A", + "3", + "Q", + "5", + "J", + "2", + "6", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 542, "tricks": 76}, + ) + + def test_random_decks_2(self): + player_a = [ + "8", + "A", + "4", + "8", + "5", + "Q", + "J", + "2", + "6", + "2", + "9", + "7", + "K", + "A", + "8", + "10", + "K", + "8", + "10", + "9", + "K", + "6", + "7", + "3", + "K", + "9", + ] + player_b = [ + "10", + "5", + "2", + "6", + "Q", + "J", + "A", + "9", + "5", + "5", + "3", + "7", + "3", + "J", + "A", + "2", + "Q", + "3", + "J", + "Q", + "4", + "10", + "4", + "7", + "4", + "6", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 327, "tricks": 42}, + ) + + def test_kleber_1999(self): + player_a = [ + "4", + "8", + "9", + "J", + "Q", + "8", + "5", + "5", + "K", + "2", + "A", + "9", + "8", + "5", + "10", + "A", + "4", + "J", + "3", + "K", + "6", + "9", + "2", + "Q", + "K", + "7", + ] + player_b = [ + "10", + "J", + "3", + "2", + "4", + "10", + "4", + "7", + "5", + "3", + "6", + "6", + "7", + "A", + "J", + "Q", + "A", + "7", + "2", + "10", + "3", + "K", + "9", + "6", + "8", + "Q", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 5790, "tricks": 805}, + ) + + def test_collins_2006(self): + player_a = [ + "A", + "8", + "Q", + "K", + "9", + "10", + "3", + "7", + "4", + "2", + "Q", + "3", + "2", + "10", + "9", + "K", + "A", + "8", + "7", + "7", + "4", + "5", + "J", + "9", + "2", + "10", + ] + player_b = [ + "4", + "J", + "A", + "K", + "8", + "5", + "6", + "6", + "A", + "6", + "5", + "Q", + "4", + "6", + "10", + "8", + "J", + "2", + "5", + "7", + "Q", + "J", + "3", + "3", + "K", + "9", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 6913, "tricks": 960}, + ) + + def test_mann_and_wu_2007(self): + player_a = [ + "K", + "2", + "K", + "K", + "3", + "3", + "6", + "10", + "K", + "6", + "A", + "2", + "5", + "5", + "7", + "9", + "J", + "A", + "A", + "3", + "4", + "Q", + "4", + "8", + "J", + "6", + ] + player_b = [ + "4", + "5", + "2", + "Q", + "7", + "9", + "9", + "Q", + "7", + "J", + "9", + "8", + "10", + "3", + "10", + "J", + "4", + "10", + "8", + "6", + "8", + "7", + "A", + "Q", + "5", + "2", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7157, "tricks": 1007}, + ) + + def test_nessler_2012(self): + player_a = [ + "10", + "3", + "6", + "7", + "Q", + "2", + "9", + "8", + "2", + "8", + "4", + "A", + "10", + "6", + "K", + "2", + "10", + "A", + "5", + "A", + "2", + "4", + "Q", + "J", + "K", + "4", + ] + player_b = [ + "10", + "Q", + "4", + "6", + "J", + "9", + "3", + "J", + "9", + "3", + "3", + "Q", + "K", + "5", + "9", + "5", + "K", + "6", + "5", + "7", + "8", + "J", + "A", + "7", + "8", + "7", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7207, "tricks": 1015}, + ) + + def test_anderson_2013(self): + player_a = [ + "6", + "7", + "A", + "3", + "Q", + "3", + "5", + "J", + "3", + "2", + "J", + "7", + "4", + "5", + "Q", + "10", + "5", + "A", + "J", + "2", + "K", + "8", + "9", + "9", + "K", + "3", + ] + player_b = [ + "4", + "J", + "6", + "9", + "8", + "5", + "10", + "7", + "9", + "Q", + "2", + "7", + "10", + "8", + "4", + "10", + "A", + "6", + "4", + "A", + "6", + "8", + "Q", + "K", + "K", + "2", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7225, "tricks": 1016}, + ) + + def test_rucklidge_2014(self): + player_a = [ + "8", + "J", + "2", + "9", + "4", + "4", + "5", + "8", + "Q", + "3", + "9", + "3", + "6", + "2", + "8", + "A", + "A", + "A", + "9", + "4", + "7", + "2", + "5", + "Q", + "Q", + "3", + ] + player_b = [ + "K", + "7", + "10", + "6", + "3", + "J", + "A", + "7", + "6", + "5", + "5", + "8", + "10", + "9", + "10", + "4", + "2", + "7", + "K", + "Q", + "10", + "K", + "6", + "J", + "J", + "K", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7959, "tricks": 1122}, + ) + + def test_nessler_2021(self): + player_a = [ + "7", + "2", + "3", + "4", + "K", + "9", + "6", + "10", + "A", + "8", + "9", + "Q", + "7", + "A", + "4", + "8", + "J", + "J", + "A", + "4", + "3", + "2", + "5", + "6", + "6", + "J", + ] + player_b = [ + "3", + "10", + "8", + "9", + "8", + "K", + "K", + "2", + "5", + "5", + "7", + "6", + "4", + "3", + "5", + "7", + "A", + "9", + "J", + "K", + "2", + "Q", + "10", + "Q", + "10", + "Q", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 7972, "tricks": 1106}, + ) + + def test_nessler_2022(self): + player_a = [ + "2", + "10", + "10", + "A", + "J", + "3", + "8", + "Q", + "2", + "5", + "5", + "5", + "9", + "2", + "4", + "3", + "10", + "Q", + "A", + "K", + "Q", + "J", + "J", + "9", + "Q", + "K", + ] + player_b = [ + "10", + "7", + "6", + "3", + "6", + "A", + "8", + "9", + "4", + "3", + "K", + "J", + "6", + "K", + "4", + "9", + "7", + "8", + "5", + "7", + "8", + "2", + "A", + "7", + "4", + "6", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "finished", "cards": 8344, "tricks": 1164}, + ) + + def test_casella_2024_first_infinite_game_found(self): + player_a = [ + "2", + "8", + "4", + "K", + "5", + "2", + "3", + "Q", + "6", + "K", + "Q", + "A", + "J", + "3", + "5", + "9", + "8", + "3", + "A", + "A", + "J", + "4", + "4", + "J", + "7", + "5", + ] + player_b = [ + "7", + "7", + "8", + "6", + "10", + "10", + "6", + "10", + "7", + "2", + "Q", + "6", + "3", + "2", + "4", + "K", + "Q", + "10", + "J", + "5", + "9", + "8", + "9", + "9", + "K", + "A", + ] + self.assertEqual( + simulate_game(player_a, player_b), + {"status": "loop", "cards": 474, "tricks": 66}, + ) From f95009e9c190b0a65c911a79030c9e05f75850f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Fri, 23 Jan 2026 20:06:10 -0800 Subject: [PATCH 2/3] Conditionally format long inputs --- exercises/practice/camicia/.meta/template.j2 | 7 + exercises/practice/camicia/camicia_test.py | 1269 +----------------- 2 files changed, 71 insertions(+), 1205 deletions(-) diff --git a/exercises/practice/camicia/.meta/template.j2 b/exercises/practice/camicia/.meta/template.j2 index 1bc055d62c..f7e443d651 100644 --- a/exercises/practice/camicia/.meta/template.j2 +++ b/exercises/practice/camicia/.meta/template.j2 @@ -6,7 +6,14 @@ class {{ exercise | camel_case }}Test(unittest.TestCase): {% for case in cases -%} def test_{{ case["description"] | to_snake }}(self): + {%- if case["input"]["playerA"]|length > 10 or case["input"]["playerB"]|length > 10 %} + # fmt: off player_a = {{ case["input"]["playerA"] }} player_b = {{ case["input"]["playerB"] }} + # fmt: on + {%- else %} + player_a = {{ case["input"]["playerA"] }} + player_b = {{ case["input"]["playerB"] }} + {%- endif %} self.assertEqual(simulate_game(player_a, player_b), {{ case["expected"] }}) {% endfor -%} diff --git a/exercises/practice/camicia/camicia_test.py b/exercises/practice/camicia/camicia_test.py index 8c8fb989b6..6ad8db8a9f 100644 --- a/exercises/practice/camicia/camicia_test.py +++ b/exercises/practice/camicia/camicia_test.py @@ -83,371 +83,10 @@ def test_simple_loop_with_decks_of_3_cards(self): ) def test_the_story_is_starting_to_get_a_bit_complicated(self): - player_a = [ - "2", - "6", - "6", - "J", - "4", - "K", - "Q", - "10", - "K", - "J", - "Q", - "2", - "3", - "K", - "5", - "6", - "Q", - "Q", - "A", - "A", - "6", - "9", - "K", - "A", - "8", - "K", - "2", - "A", - "9", - "A", - "Q", - "4", - "K", - "K", - "K", - "3", - "5", - "K", - "8", - "Q", - "3", - "Q", - "7", - "J", - "K", - "J", - "9", - "J", - "3", - "3", - "K", - "K", - "Q", - "A", - "K", - "7", - "10", - "A", - "Q", - "7", - "10", - "J", - "4", - "5", - "J", - "9", - "10", - "Q", - "J", - "J", - "K", - "6", - "10", - "J", - "6", - "Q", - "J", - "5", - "J", - "Q", - "Q", - "8", - "3", - "8", - "A", - "2", - "6", - "9", - "K", - "7", - "J", - "K", - "K", - "8", - "K", - "Q", - "6", - "10", - "J", - "10", - "J", - "Q", - "J", - "10", - "3", - "8", - "K", - "A", - "6", - "9", - "K", - "2", - "A", - "A", - "10", - "J", - "6", - "A", - "4", - "J", - "A", - "J", - "J", - "6", - "2", - "J", - "3", - "K", - "2", - "5", - "9", - "J", - "9", - "6", - "K", - "A", - "5", - "Q", - "J", - "2", - "Q", - "K", - "A", - "3", - "K", - "J", - "K", - "2", - "5", - "6", - "Q", - "J", - "Q", - "Q", - "J", - "2", - "J", - "9", - "Q", - "7", - "7", - "A", - "Q", - "7", - "Q", - "J", - "K", - "J", - "A", - "7", - "7", - "8", - "Q", - "10", - "J", - "10", - "J", - "J", - "9", - "2", - "A", - "2", - ] - player_b = [ - "7", - "2", - "10", - "K", - "8", - "2", - "J", - "9", - "A", - "5", - "6", - "J", - "Q", - "6", - "K", - "6", - "5", - "A", - "4", - "Q", - "7", - "J", - "7", - "10", - "2", - "Q", - "8", - "2", - "2", - "K", - "J", - "A", - "5", - "5", - "A", - "4", - "Q", - "6", - "Q", - "K", - "10", - "8", - "Q", - "2", - "10", - "J", - "A", - "Q", - "8", - "Q", - "Q", - "J", - "J", - "A", - "A", - "9", - "10", - "J", - "K", - "4", - "Q", - "10", - "10", - "J", - "K", - "10", - "2", - "J", - "7", - "A", - "K", - "K", - "J", - "A", - "J", - "10", - "8", - "K", - "A", - "7", - "Q", - "Q", - "J", - "3", - "Q", - "4", - "A", - "3", - "A", - "Q", - "Q", - "Q", - "5", - "4", - "K", - "J", - "10", - "A", - "Q", - "J", - "6", - "J", - "A", - "10", - "A", - "5", - "8", - "3", - "K", - "5", - "9", - "Q", - "8", - "7", - "7", - "J", - "7", - "Q", - "Q", - "Q", - "A", - "7", - "8", - "9", - "A", - "Q", - "A", - "K", - "8", - "A", - "A", - "J", - "8", - "4", - "8", - "K", - "J", - "A", - "10", - "Q", - "8", - "J", - "8", - "6", - "10", - "Q", - "J", - "J", - "A", - "A", - "J", - "5", - "Q", - "6", - "J", - "K", - "Q", - "8", - "K", - "4", - "Q", - "Q", - "6", - "J", - "K", - "4", - "7", - "J", - "J", - "9", - "9", - "A", - "Q", - "Q", - "K", - "A", - "6", - "5", - "K", - ] + # fmt: off + player_a = ['2', '6', '6', 'J', '4', 'K', 'Q', '10', 'K', 'J', 'Q', '2', '3', 'K', '5', '6', 'Q', 'Q', 'A', 'A', '6', '9', 'K', 'A', '8', 'K', '2', 'A', '9', 'A', 'Q', '4', 'K', 'K', 'K', '3', '5', 'K', '8', 'Q', '3', 'Q', '7', 'J', 'K', 'J', '9', 'J', '3', '3', 'K', 'K', 'Q', 'A', 'K', '7', '10', 'A', 'Q', '7', '10', 'J', '4', '5', 'J', '9', '10', 'Q', 'J', 'J', 'K', '6', '10', 'J', '6', 'Q', 'J', '5', 'J', 'Q', 'Q', '8', '3', '8', 'A', '2', '6', '9', 'K', '7', 'J', 'K', 'K', '8', 'K', 'Q', '6', '10', 'J', '10', 'J', 'Q', 'J', '10', '3', '8', 'K', 'A', '6', '9', 'K', '2', 'A', 'A', '10', 'J', '6', 'A', '4', 'J', 'A', 'J', 'J', '6', '2', 'J', '3', 'K', '2', '5', '9', 'J', '9', '6', 'K', 'A', '5', 'Q', 'J', '2', 'Q', 'K', 'A', '3', 'K', 'J', 'K', '2', '5', '6', 'Q', 'J', 'Q', 'Q', 'J', '2', 'J', '9', 'Q', '7', '7', 'A', 'Q', '7', 'Q', 'J', 'K', 'J', 'A', '7', '7', '8', 'Q', '10', 'J', '10', 'J', 'J', '9', '2', 'A', '2'] + player_b = ['7', '2', '10', 'K', '8', '2', 'J', '9', 'A', '5', '6', 'J', 'Q', '6', 'K', '6', '5', 'A', '4', 'Q', '7', 'J', '7', '10', '2', 'Q', '8', '2', '2', 'K', 'J', 'A', '5', '5', 'A', '4', 'Q', '6', 'Q', 'K', '10', '8', 'Q', '2', '10', 'J', 'A', 'Q', '8', 'Q', 'Q', 'J', 'J', 'A', 'A', '9', '10', 'J', 'K', '4', 'Q', '10', '10', 'J', 'K', '10', '2', 'J', '7', 'A', 'K', 'K', 'J', 'A', 'J', '10', '8', 'K', 'A', '7', 'Q', 'Q', 'J', '3', 'Q', '4', 'A', '3', 'A', 'Q', 'Q', 'Q', '5', '4', 'K', 'J', '10', 'A', 'Q', 'J', '6', 'J', 'A', '10', 'A', '5', '8', '3', 'K', '5', '9', 'Q', '8', '7', '7', 'J', '7', 'Q', 'Q', 'Q', 'A', '7', '8', '9', 'A', 'Q', 'A', 'K', '8', 'A', 'A', 'J', '8', '4', '8', 'K', 'J', 'A', '10', 'Q', '8', 'J', '8', '6', '10', 'Q', 'J', 'J', 'A', 'A', 'J', '5', 'Q', '6', 'J', 'K', 'Q', '8', 'K', '4', 'Q', 'Q', '6', 'J', 'K', '4', '7', 'J', 'J', '9', '9', 'A', 'Q', 'Q', 'K', 'A', '6', '5', 'K'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 361, "tricks": 1}, @@ -478,930 +117,150 @@ def test_simple_loop_with_decks_of_4_cards(self): ) def test_easy_card_combination(self): - player_a = [ - "4", - "8", - "7", - "5", - "4", - "10", - "3", - "9", - "7", - "3", - "10", - "10", - "6", - "8", - "2", - "8", - "5", - "4", - "5", - "9", - "6", - "5", - "2", - "8", - "10", - "9", - ] - player_b = [ - "6", - "9", - "4", - "7", - "2", - "2", - "3", - "6", - "7", - "3", - "A", - "A", - "A", - "A", - "K", - "K", - "K", - "K", - "Q", - "Q", - "Q", - "Q", - "J", - "J", - "J", - "J", - ] + # fmt: off + player_a = ['4', '8', '7', '5', '4', '10', '3', '9', '7', '3', '10', '10', '6', '8', '2', '8', '5', '4', '5', '9', '6', '5', '2', '8', '10', '9'] + player_b = ['6', '9', '4', '7', '2', '2', '3', '6', '7', '3', 'A', 'A', 'A', 'A', 'K', 'K', 'K', 'K', 'Q', 'Q', 'Q', 'Q', 'J', 'J', 'J', 'J'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 40, "tricks": 4}, ) def test_easy_card_combination_inverted_decks(self): - player_a = [ - "3", - "3", - "5", - "7", - "3", - "2", - "10", - "7", - "6", - "7", - "A", - "A", - "A", - "A", - "K", - "K", - "K", - "K", - "Q", - "Q", - "Q", - "Q", - "J", - "J", - "J", - "J", - ] - player_b = [ - "5", - "10", - "8", - "2", - "6", - "7", - "2", - "4", - "9", - "2", - "6", - "10", - "10", - "5", - "4", - "8", - "4", - "8", - "6", - "9", - "8", - "5", - "9", - "3", - "4", - "9", - ] + # fmt: off + player_a = ['3', '3', '5', '7', '3', '2', '10', '7', '6', '7', 'A', 'A', 'A', 'A', 'K', 'K', 'K', 'K', 'Q', 'Q', 'Q', 'Q', 'J', 'J', 'J', 'J'] + player_b = ['5', '10', '8', '2', '6', '7', '2', '4', '9', '2', '6', '10', '10', '5', '4', '8', '4', '8', '6', '9', '8', '5', '9', '3', '4', '9'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 40, "tricks": 4}, ) def test_mirrored_decks(self): - player_a = [ - "2", - "A", - "3", - "A", - "3", - "K", - "4", - "K", - "2", - "Q", - "2", - "Q", - "10", - "J", - "5", - "J", - "6", - "10", - "2", - "9", - "10", - "7", - "3", - "9", - "6", - "9", - ] - player_b = [ - "6", - "A", - "4", - "A", - "7", - "K", - "4", - "K", - "7", - "Q", - "7", - "Q", - "5", - "J", - "8", - "J", - "4", - "5", - "8", - "9", - "10", - "6", - "8", - "3", - "8", - "5", - ] + # fmt: off + player_a = ['2', 'A', '3', 'A', '3', 'K', '4', 'K', '2', 'Q', '2', 'Q', '10', 'J', '5', 'J', '6', '10', '2', '9', '10', '7', '3', '9', '6', '9'] + player_b = ['6', 'A', '4', 'A', '7', 'K', '4', 'K', '7', 'Q', '7', 'Q', '5', 'J', '8', 'J', '4', '5', '8', '9', '10', '6', '8', '3', '8', '5'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 59, "tricks": 4}, ) def test_opposite_decks(self): - player_a = [ - "4", - "A", - "9", - "A", - "4", - "K", - "9", - "K", - "6", - "Q", - "8", - "Q", - "8", - "J", - "10", - "J", - "9", - "8", - "4", - "6", - "3", - "6", - "5", - "2", - "4", - "3", - ] - player_b = [ - "10", - "7", - "3", - "2", - "9", - "2", - "7", - "8", - "7", - "5", - "J", - "7", - "J", - "10", - "Q", - "10", - "Q", - "3", - "K", - "5", - "K", - "6", - "A", - "2", - "A", - "5", - ] + # fmt: off + player_a = ['4', 'A', '9', 'A', '4', 'K', '9', 'K', '6', 'Q', '8', 'Q', '8', 'J', '10', 'J', '9', '8', '4', '6', '3', '6', '5', '2', '4', '3'] + player_b = ['10', '7', '3', '2', '9', '2', '7', '8', '7', '5', 'J', '7', 'J', '10', 'Q', '10', 'Q', '3', 'K', '5', 'K', '6', 'A', '2', 'A', '5'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 151, "tricks": 21}, ) def test_random_decks_1(self): - player_a = [ - "K", - "10", - "9", - "8", - "J", - "8", - "6", - "9", - "7", - "A", - "K", - "5", - "4", - "4", - "J", - "5", - "J", - "4", - "3", - "5", - "8", - "6", - "7", - "7", - "4", - "9", - ] - player_b = [ - "6", - "3", - "K", - "A", - "Q", - "10", - "A", - "2", - "Q", - "8", - "2", - "10", - "10", - "2", - "Q", - "3", - "K", - "9", - "7", - "A", - "3", - "Q", - "5", - "J", - "2", - "6", - ] + # fmt: off + player_a = ['K', '10', '9', '8', 'J', '8', '6', '9', '7', 'A', 'K', '5', '4', '4', 'J', '5', 'J', '4', '3', '5', '8', '6', '7', '7', '4', '9'] + player_b = ['6', '3', 'K', 'A', 'Q', '10', 'A', '2', 'Q', '8', '2', '10', '10', '2', 'Q', '3', 'K', '9', '7', 'A', '3', 'Q', '5', 'J', '2', '6'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 542, "tricks": 76}, ) def test_random_decks_2(self): - player_a = [ - "8", - "A", - "4", - "8", - "5", - "Q", - "J", - "2", - "6", - "2", - "9", - "7", - "K", - "A", - "8", - "10", - "K", - "8", - "10", - "9", - "K", - "6", - "7", - "3", - "K", - "9", - ] - player_b = [ - "10", - "5", - "2", - "6", - "Q", - "J", - "A", - "9", - "5", - "5", - "3", - "7", - "3", - "J", - "A", - "2", - "Q", - "3", - "J", - "Q", - "4", - "10", - "4", - "7", - "4", - "6", - ] + # fmt: off + player_a = ['8', 'A', '4', '8', '5', 'Q', 'J', '2', '6', '2', '9', '7', 'K', 'A', '8', '10', 'K', '8', '10', '9', 'K', '6', '7', '3', 'K', '9'] + player_b = ['10', '5', '2', '6', 'Q', 'J', 'A', '9', '5', '5', '3', '7', '3', 'J', 'A', '2', 'Q', '3', 'J', 'Q', '4', '10', '4', '7', '4', '6'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 327, "tricks": 42}, ) def test_kleber_1999(self): - player_a = [ - "4", - "8", - "9", - "J", - "Q", - "8", - "5", - "5", - "K", - "2", - "A", - "9", - "8", - "5", - "10", - "A", - "4", - "J", - "3", - "K", - "6", - "9", - "2", - "Q", - "K", - "7", - ] - player_b = [ - "10", - "J", - "3", - "2", - "4", - "10", - "4", - "7", - "5", - "3", - "6", - "6", - "7", - "A", - "J", - "Q", - "A", - "7", - "2", - "10", - "3", - "K", - "9", - "6", - "8", - "Q", - ] + # fmt: off + player_a = ['4', '8', '9', 'J', 'Q', '8', '5', '5', 'K', '2', 'A', '9', '8', '5', '10', 'A', '4', 'J', '3', 'K', '6', '9', '2', 'Q', 'K', '7'] + player_b = ['10', 'J', '3', '2', '4', '10', '4', '7', '5', '3', '6', '6', '7', 'A', 'J', 'Q', 'A', '7', '2', '10', '3', 'K', '9', '6', '8', 'Q'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 5790, "tricks": 805}, ) def test_collins_2006(self): - player_a = [ - "A", - "8", - "Q", - "K", - "9", - "10", - "3", - "7", - "4", - "2", - "Q", - "3", - "2", - "10", - "9", - "K", - "A", - "8", - "7", - "7", - "4", - "5", - "J", - "9", - "2", - "10", - ] - player_b = [ - "4", - "J", - "A", - "K", - "8", - "5", - "6", - "6", - "A", - "6", - "5", - "Q", - "4", - "6", - "10", - "8", - "J", - "2", - "5", - "7", - "Q", - "J", - "3", - "3", - "K", - "9", - ] + # fmt: off + player_a = ['A', '8', 'Q', 'K', '9', '10', '3', '7', '4', '2', 'Q', '3', '2', '10', '9', 'K', 'A', '8', '7', '7', '4', '5', 'J', '9', '2', '10'] + player_b = ['4', 'J', 'A', 'K', '8', '5', '6', '6', 'A', '6', '5', 'Q', '4', '6', '10', '8', 'J', '2', '5', '7', 'Q', 'J', '3', '3', 'K', '9'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 6913, "tricks": 960}, ) def test_mann_and_wu_2007(self): - player_a = [ - "K", - "2", - "K", - "K", - "3", - "3", - "6", - "10", - "K", - "6", - "A", - "2", - "5", - "5", - "7", - "9", - "J", - "A", - "A", - "3", - "4", - "Q", - "4", - "8", - "J", - "6", - ] - player_b = [ - "4", - "5", - "2", - "Q", - "7", - "9", - "9", - "Q", - "7", - "J", - "9", - "8", - "10", - "3", - "10", - "J", - "4", - "10", - "8", - "6", - "8", - "7", - "A", - "Q", - "5", - "2", - ] + # fmt: off + player_a = ['K', '2', 'K', 'K', '3', '3', '6', '10', 'K', '6', 'A', '2', '5', '5', '7', '9', 'J', 'A', 'A', '3', '4', 'Q', '4', '8', 'J', '6'] + player_b = ['4', '5', '2', 'Q', '7', '9', '9', 'Q', '7', 'J', '9', '8', '10', '3', '10', 'J', '4', '10', '8', '6', '8', '7', 'A', 'Q', '5', '2'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 7157, "tricks": 1007}, ) def test_nessler_2012(self): - player_a = [ - "10", - "3", - "6", - "7", - "Q", - "2", - "9", - "8", - "2", - "8", - "4", - "A", - "10", - "6", - "K", - "2", - "10", - "A", - "5", - "A", - "2", - "4", - "Q", - "J", - "K", - "4", - ] - player_b = [ - "10", - "Q", - "4", - "6", - "J", - "9", - "3", - "J", - "9", - "3", - "3", - "Q", - "K", - "5", - "9", - "5", - "K", - "6", - "5", - "7", - "8", - "J", - "A", - "7", - "8", - "7", - ] + # fmt: off + player_a = ['10', '3', '6', '7', 'Q', '2', '9', '8', '2', '8', '4', 'A', '10', '6', 'K', '2', '10', 'A', '5', 'A', '2', '4', 'Q', 'J', 'K', '4'] + player_b = ['10', 'Q', '4', '6', 'J', '9', '3', 'J', '9', '3', '3', 'Q', 'K', '5', '9', '5', 'K', '6', '5', '7', '8', 'J', 'A', '7', '8', '7'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 7207, "tricks": 1015}, ) def test_anderson_2013(self): - player_a = [ - "6", - "7", - "A", - "3", - "Q", - "3", - "5", - "J", - "3", - "2", - "J", - "7", - "4", - "5", - "Q", - "10", - "5", - "A", - "J", - "2", - "K", - "8", - "9", - "9", - "K", - "3", - ] - player_b = [ - "4", - "J", - "6", - "9", - "8", - "5", - "10", - "7", - "9", - "Q", - "2", - "7", - "10", - "8", - "4", - "10", - "A", - "6", - "4", - "A", - "6", - "8", - "Q", - "K", - "K", - "2", - ] + # fmt: off + player_a = ['6', '7', 'A', '3', 'Q', '3', '5', 'J', '3', '2', 'J', '7', '4', '5', 'Q', '10', '5', 'A', 'J', '2', 'K', '8', '9', '9', 'K', '3'] + player_b = ['4', 'J', '6', '9', '8', '5', '10', '7', '9', 'Q', '2', '7', '10', '8', '4', '10', 'A', '6', '4', 'A', '6', '8', 'Q', 'K', 'K', '2'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 7225, "tricks": 1016}, ) def test_rucklidge_2014(self): - player_a = [ - "8", - "J", - "2", - "9", - "4", - "4", - "5", - "8", - "Q", - "3", - "9", - "3", - "6", - "2", - "8", - "A", - "A", - "A", - "9", - "4", - "7", - "2", - "5", - "Q", - "Q", - "3", - ] - player_b = [ - "K", - "7", - "10", - "6", - "3", - "J", - "A", - "7", - "6", - "5", - "5", - "8", - "10", - "9", - "10", - "4", - "2", - "7", - "K", - "Q", - "10", - "K", - "6", - "J", - "J", - "K", - ] + # fmt: off + player_a = ['8', 'J', '2', '9', '4', '4', '5', '8', 'Q', '3', '9', '3', '6', '2', '8', 'A', 'A', 'A', '9', '4', '7', '2', '5', 'Q', 'Q', '3'] + player_b = ['K', '7', '10', '6', '3', 'J', 'A', '7', '6', '5', '5', '8', '10', '9', '10', '4', '2', '7', 'K', 'Q', '10', 'K', '6', 'J', 'J', 'K'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 7959, "tricks": 1122}, ) def test_nessler_2021(self): - player_a = [ - "7", - "2", - "3", - "4", - "K", - "9", - "6", - "10", - "A", - "8", - "9", - "Q", - "7", - "A", - "4", - "8", - "J", - "J", - "A", - "4", - "3", - "2", - "5", - "6", - "6", - "J", - ] - player_b = [ - "3", - "10", - "8", - "9", - "8", - "K", - "K", - "2", - "5", - "5", - "7", - "6", - "4", - "3", - "5", - "7", - "A", - "9", - "J", - "K", - "2", - "Q", - "10", - "Q", - "10", - "Q", - ] + # fmt: off + player_a = ['7', '2', '3', '4', 'K', '9', '6', '10', 'A', '8', '9', 'Q', '7', 'A', '4', '8', 'J', 'J', 'A', '4', '3', '2', '5', '6', '6', 'J'] + player_b = ['3', '10', '8', '9', '8', 'K', 'K', '2', '5', '5', '7', '6', '4', '3', '5', '7', 'A', '9', 'J', 'K', '2', 'Q', '10', 'Q', '10', 'Q'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 7972, "tricks": 1106}, ) def test_nessler_2022(self): - player_a = [ - "2", - "10", - "10", - "A", - "J", - "3", - "8", - "Q", - "2", - "5", - "5", - "5", - "9", - "2", - "4", - "3", - "10", - "Q", - "A", - "K", - "Q", - "J", - "J", - "9", - "Q", - "K", - ] - player_b = [ - "10", - "7", - "6", - "3", - "6", - "A", - "8", - "9", - "4", - "3", - "K", - "J", - "6", - "K", - "4", - "9", - "7", - "8", - "5", - "7", - "8", - "2", - "A", - "7", - "4", - "6", - ] + # fmt: off + player_a = ['2', '10', '10', 'A', 'J', '3', '8', 'Q', '2', '5', '5', '5', '9', '2', '4', '3', '10', 'Q', 'A', 'K', 'Q', 'J', 'J', '9', 'Q', 'K'] + player_b = ['10', '7', '6', '3', '6', 'A', '8', '9', '4', '3', 'K', 'J', '6', 'K', '4', '9', '7', '8', '5', '7', '8', '2', 'A', '7', '4', '6'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "finished", "cards": 8344, "tricks": 1164}, ) def test_casella_2024_first_infinite_game_found(self): - player_a = [ - "2", - "8", - "4", - "K", - "5", - "2", - "3", - "Q", - "6", - "K", - "Q", - "A", - "J", - "3", - "5", - "9", - "8", - "3", - "A", - "A", - "J", - "4", - "4", - "J", - "7", - "5", - ] - player_b = [ - "7", - "7", - "8", - "6", - "10", - "10", - "6", - "10", - "7", - "2", - "Q", - "6", - "3", - "2", - "4", - "K", - "Q", - "10", - "J", - "5", - "9", - "8", - "9", - "9", - "K", - "A", - ] + # fmt: off + player_a = ['2', '8', '4', 'K', '5', '2', '3', 'Q', '6', 'K', 'Q', 'A', 'J', '3', '5', '9', '8', '3', 'A', 'A', 'J', '4', '4', 'J', '7', '5'] + player_b = ['7', '7', '8', '6', '10', '10', '6', '10', '7', '2', 'Q', '6', '3', '2', '4', 'K', 'Q', '10', 'J', '5', '9', '8', '9', '9', 'K', 'A'] + # fmt: on self.assertEqual( simulate_game(player_a, player_b), {"status": "loop", "cards": 474, "tricks": 66}, From c49120230ace932d2967e9cdd601a9f98dd7651d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Fri, 23 Jan 2026 20:18:29 -0800 Subject: [PATCH 3/3] Add prerequisites --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 22699f55e8..a436014ce7 100644 --- a/config.json +++ b/config.json @@ -1743,7 +1743,7 @@ "name": "Camicia", "uuid": "ec314b34-2ee3-4eec-9a97-aece9e5fd6c2", "practices": [], - "prerequisites": [], + "prerequisites": ["lists", "sets", "strings"], "difficulty": 5 }, {