Facebook Pixel

Playing Cards

For this question, we ask you to design a card game using the traditional 52-card deck. We divide this question into three parts, so you can complete them in order.

Part One

For the first part, you must design a Game class representing the game, and these following functions associated with the class.

  • add_card(suit, value): Creates a new card object with a suit from one of the following strings: Hearts, Spades, Clubs, Diamonds, and a value from one of the following strings: A, 2~10, J, Q, K. This card is represented by i, where i is an integer indicating how many cards have been created before.
  • card_string(card): Returns the string representation of the card represented by i. It follows the format <value> of <suit>. For example, a card created by add_card("Spades", "3") should have a string representation of 3 of Spades.
  • card_beats(card_a, card_b): Check if the card represented by card_a beats the one represented by card_b. A card beats another card if and only if it has a greater value. The value of the cards are ordered from A to K.

You may implement these however you like. However, preferably this should be easily expandable to accommodate new requirements.

Try it yourself

Solution

There are numerous approaches we can take to design this problem. The sample solution will provide an object-oriented approach, since it allows us to easily add new types of cards to accommodate new requirements.

Different languages have different tools, but the most basic concept in object oriented programming is inheritance, which is a class deriving from a superclass and inheriting its methods. In this situation, a playing card from the 52 is a card. The reason for this design is that we can easily add other types of cards if we want.

Below is an implementation:

1from enum import Enum, auto
2
3class Card:
4    @property
5    def card_value(self) -> int:
6        raise NotImplementedError()
7
8    def __lt__(self, other):
9        return self.card_value < other.card_value
10
11class Suit(Enum):
12    CLUBS = auto()
13    DIAMONDS = auto()
14    HEARTS = auto()
15    SPADES = auto()
16
17class PlayingCard(Card):
18    SUITS = {
19        "Clubs": Suit.CLUBS,
20        "Diamonds": Suit.DIAMONDS,
21        "Hearts": Suit.HEARTS,
22        "Spades": Suit.SPADES,
23    }
24    SUIT_NAMES = {e: n for n, e in SUITS.items()}
25    VALUES = {
26        "A": 1,
27        **{str(i): i for i in range(2, 11)},
28        "J": 11,
29        "Q": 12,
30        "K": 13,
31    }
32    VALUE_NAMES = {e: n for n, e in VALUES.items()}
33
34    def __init__(self, suit: str, value: str):
35        super().__init__()
36        self.__suit = self.SUITS[suit]
37        self.__value = self.VALUES[value]
38
39    @property
40    def card_value(self) -> int:
41        return self.__value
42
43    def __str__(self) -> str:
44        value = self.VALUE_NAMES[self.__value]
45        suit = self.SUIT_NAMES[self.__suit]
46        return f"{value} of {suit}"
47
48class Game:
49    def __init__(self) -> None:
50        self.__cards: list[Card] = []
51
52    def add_card(self, suit: str, value: str) -> None:
53        self.__cards.append(PlayingCard(suit, value))
54
55    def card_string(self, card: int) -> str:
56        return str(self.__cards[card])
57
58    def card_beats(self, card_a: int, card_b: int) -> bool:
59        return self.__cards[card_a] > self.__cards[card_b]
60
61if __name__ == "__main__":
62    game = Game()
63    suit, value = input().split()
64    game.add_card(suit, value)
65    print(game.card_string(0))
66    suit, value = input().split()
67    game.add_card(suit, value)
68    print(game.card_string(1))
69    print("true" if game.card_beats(0, 1) else "false")
70
1import java.util.ArrayList;
2import java.util.HashMap;
3import java.util.Map;
4import java.util.Map.Entry;
5import java.util.Scanner;
6import java.util.stream.Collectors;
7
8class Solution {
9    public static abstract class Card implements Comparable<Card> {
10        public abstract int getValue();
11
12        @Override
13        public int compareTo(Card o) {
14            return Integer.compare(getValue(), o.getValue());
15        }
16    }
17
18    public enum Suit {
19        SPADES,
20        HEARTS,
21        DIAMONDS,
22        CLUBS,
23    }
24
25    public static class PlayingCard extends Card {
26        private Suit suit;
27        private int value;
28
29        public static final Map<String, Suit> SUITS = Map.of(
30            "Spades", Suit.SPADES,
31            "Hearts", Suit.HEARTS,
32            "Diamonds", Suit.DIAMONDS,
33            "Clubs", Suit.CLUBS);
34
35        // Inverts the above map to convert back to string.
36        public static final Map<Suit, String> SUIT_NAMES = SUITS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
37
38        // Map.of is limited to 10 entries, so we initialize a static map instead
39        public static final Map<String, Integer> VALUES = new HashMap<>();
40        static {
41            VALUES.put("A", 1);
42            for (int i = 2; i <= 10; i++) {
43                VALUES.put(String.valueOf(i), i);
44            }
45            VALUES.put("J", 11);
46            VALUES.put("Q", 12);
47            VALUES.put("K", 13);
48        }
49        // Inverts the above map to convert back to string.
50        public static final Map<Integer, String> VALUE_NAMES = VALUES.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
51
52        public PlayingCard(String suit, String value) {
53            this.suit = SUITS.get(suit);
54            this.value = VALUES.get(value);
55        }
56
57        @Override
58        public int getValue() {
59            return value;
60        }
61
62        @Override
63        public String toString() {
64            return String.format("%s of %s", VALUE_NAMES.get(value), SUIT_NAMES.get(suit));
65        }
66    }
67
68    public static class Game {
69        private ArrayList<Card> cards;
70
71        public Game() {
72            cards = new ArrayList<>();
73        }
74
75        public void addCard(String suit, String value) {
76            cards.add(new PlayingCard(suit, value));
77        }
78
79        public String cardString(int card) {
80            return cards.get(card).toString();
81        }
82
83        public boolean cardBeats(int cardA, int cardB) {
84            return cards.get(cardA).compareTo(cards.get(cardB)) > 0;
85        }
86    }
87
88    public static void main(String[] args) {
89        Scanner scanner = new Scanner(System.in);
90        Game game = new Game();
91        String[] segs = scanner.nextLine().split(" ");
92        game.addCard(segs[0], segs[1]);
93        System.out.println(game.cardString(0));
94        segs = scanner.nextLine().split(" ");
95        game.addCard(segs[0], segs[1]);
96        System.out.println(game.cardString(1));
97        System.out.println(game.cardBeats(0, 1));
98    }
99}
100
1using System;
2
3class Solution
4{
5    public abstract class Card
6    {
7        public abstract int CardValue { get; }
8    }
9
10    public enum Suit
11    {
12        Clubs,
13        Diamonds,
14        Hearts,
15        Spades
16    }
17
18    public class PlayingCard : Card
19    {
20        private Suit suit;
21        private int value;
22
23        public static readonly Dictionary<string, Suit> SUITS = new Dictionary<string, Suit>
24        {
25            {"Clubs", Suit.Clubs},
26            {"Diamonds", Suit.Diamonds},
27            {"Hearts", Suit.Hearts},
28            {"Spades", Suit.Spades}
29        };
30
31        public static readonly Dictionary<Suit, string> SUIT_NAMES = new Dictionary<Suit, string>
32        {
33            {Suit.Clubs, "Clubs"},
34            {Suit.Diamonds, "Diamonds"},
35            {Suit.Hearts, "Hearts"},
36            {Suit.Spades, "Spades"}
37        };
38
39        public static readonly Dictionary<string, int> VALUES = new Dictionary<string, int>
40        {
41            {"A", 1},
42            {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
43            {"J", 11},
44            {"Q", 12},
45            {"K", 13}
46        };
47
48        public static readonly Dictionary<int, string> VALUE_NAMES = new Dictionary<int, string>
49        {
50            {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
51            {11, "J"}, {12, "Q"}, {13, "K"}
52        };
53
54        public PlayingCard(string suit, string value)
55        {
56            this.suit = SUITS[suit];
57            this.value = VALUES[value];
58        }
59
60        public override int CardValue => value;
61
62        public override string ToString()
63        {
64            return $"{VALUE_NAMES[value]} of {SUIT_NAMES[suit]}";
65        }
66    }
67
68    public class Game
69    {
70        private List<Card> cards;
71
72        public Game()
73        {
74            cards = new List<Card>();
75        }
76
77        public void AddCard(string suit, string value)
78        {
79            cards.Add(new PlayingCard(suit, value));
80        }
81
82        public string CardString(int card)
83        {
84            return cards[card].ToString();
85        }
86
87        public bool CardBeats(int cardA, int cardB)
88        {
89            return cards[cardA].CardValue > cards[cardB].CardValue;
90        }
91    }
92
93    public static void Main()
94    {
95        Game game = new Game();
96        string[] segs = Console.ReadLine().Split(' ');
97        game.AddCard(segs[0], segs[1]);
98        Console.WriteLine(game.CardString(0));
99        segs = Console.ReadLine().Split(' ');
100        game.AddCard(segs[0], segs[1]);
101        Console.WriteLine(game.CardString(1));
102        Console.WriteLine(game.CardBeats(0, 1) ? "true" : "false");
103    }
104}
105
1"use strict";
2
3class Card {
4    get cardValue() {
5        throw new Error("Not implemented");
6    }
7}
8
9class PlayingCard extends Card {
10    constructor(suit, value) {
11        super();
12        this.suit = suit;
13        this.value = value;
14    }
15
16    static SUITS = {
17        "Clubs": "Clubs",
18        "Diamonds": "Diamonds",
19        "Hearts": "Hearts",
20        "Spades": "Spades"
21    };
22
23    static VALUES = {
24        "A": 1,
25        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
26        "J": 11,
27        "Q": 12,
28        "K": 13
29    };
30
31    static VALUE_NAMES = {
32        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
33        11: "J", 12: "Q", 13: "K"
34    };
35
36    get cardValue() {
37        return PlayingCard.VALUES[this.value];
38    }
39
40    toString() {
41        const valueName = PlayingCard.VALUE_NAMES[PlayingCard.VALUES[this.value]];
42        return `${valueName} of ${this.suit}`;
43    }
44}
45
46class Game {
47    constructor() {
48        this.cards = [];
49    }
50
51    addCard(suit, value) {
52        this.cards.push(new PlayingCard(suit, value));
53    }
54
55    cardString(card) {
56        return this.cards[card].toString();
57    }
58
59    cardBeats(cardA, cardB) {
60        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
61    }
62}
63
64function* main() {
65    const game = new Game();
66    let [suit, value] = (yield).split(" ");
67    game.addCard(suit, value);
68    console.log(game.cardString(0));
69    [suit, value] = (yield).split(" ");
70    game.addCard(suit, value);
71    console.log(game.cardString(1));
72    console.log(game.cardBeats(0, 1));
73}
74
75class EOFError extends Error {}
76{
77    const gen = main();
78    const next = (line) => gen.next(line).done && process.exit();
79    let buf = "";
80    next();
81    process.stdin.setEncoding("utf8");
82    process.stdin.on("data", (data) => {
83        const lines = (buf + data).split("\n");
84        buf = lines.pop();
85        lines.forEach(next);
86    });
87    process.stdin.on("end", () => {
88        buf && next(buf);
89        gen.throw(new EOFError());
90    });
91}
92
1abstract class Card {
2    abstract get cardValue(): number;
3}
4
5enum Suit {
6    CLUBS,
7    DIAMONDS,
8    HEARTS,
9    SPADES
10}
11
12class PlayingCard extends Card {
13    private suit: Suit;
14    private value: number;
15
16    static readonly SUITS: { [key: string]: Suit } = {
17        "Clubs": Suit.CLUBS,
18        "Diamonds": Suit.DIAMONDS,
19        "Hearts": Suit.HEARTS,
20        "Spades": Suit.SPADES
21    };
22
23    static readonly SUIT_NAMES: { [key: number]: string } = {
24        [Suit.CLUBS]: "Clubs",
25        [Suit.DIAMONDS]: "Diamonds",
26        [Suit.HEARTS]: "Hearts",
27        [Suit.SPADES]: "Spades"
28    };
29
30    static readonly VALUES: { [key: string]: number } = {
31        "A": 1,
32        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
33        "J": 11,
34        "Q": 12,
35        "K": 13
36    };
37
38    static readonly VALUE_NAMES: { [key: number]: string } = {
39        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
40        11: "J", 12: "Q", 13: "K"
41    };
42
43    constructor(suit: string, value: string) {
44        super();
45        this.suit = PlayingCard.SUITS[suit];
46        this.value = PlayingCard.VALUES[value];
47    }
48
49    get cardValue(): number {
50        return this.value;
51    }
52
53    toString(): string {
54        const valueName = PlayingCard.VALUE_NAMES[this.value];
55        const suitName = PlayingCard.SUIT_NAMES[this.suit];
56        return `${valueName} of ${suitName}`;
57    }
58}
59
60class Game {
61    private cards: Card[] = [];
62
63    constructor() {
64        // Implement initializer here
65    }
66
67    addCard(suit: string, value: string): void {
68        this.cards.push(new PlayingCard(suit, value));
69    }
70
71    cardString(card: number): string {
72        return this.cards[card].toString();
73    }
74
75    cardBeats(cardA: number, cardB: number): boolean {
76        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
77    }
78}
79
80function* main() {
81    const game = new Game();
82    let [suit, value] = (yield).split(" ");
83    game.addCard(suit, value);
84    console.log(game.cardString(0));
85    [suit, value] = (yield).split(" ");
86    game.addCard(suit, value);
87    console.log(game.cardString(1));
88    console.log(game.cardBeats(0, 1));
89}
90
91class EOFError extends Error {}
92{
93    const gen = main();
94    const next = (line?: string) => gen.next(line ?? "").done && process.exit();
95    let buf = "";
96    next();
97    process.stdin.setEncoding("utf8");
98    process.stdin.on("data", (data) => {
99        const lines = (buf + data).split("\n");
100        buf = lines.pop() ?? "";
101        lines.forEach(next);
102    });
103    process.stdin.on("end", () => {
104        buf && next(buf);
105        gen.throw(new EOFError());
106    });
107}
108
1#include <algorithm>
2#include <iostream>
3#include <iterator>
4#include <map>
5#include <memory>
6#include <sstream>
7#include <string>
8#include <vector>
9
10class Card {
11public:
12    virtual int getCardValue() const = 0;
13    virtual ~Card() = default;
14};
15
16enum class Suit {
17    CLUBS,
18    DIAMONDS,
19    HEARTS,
20    SPADES
21};
22
23class PlayingCard : public Card {
24private:
25    Suit suit;
26    int value;
27
28public:
29    static const std::map<std::string, Suit> SUITS;
30    static const std::map<Suit, std::string> SUIT_NAMES;
31    static const std::map<std::string, int> VALUES;
32    static const std::map<int, std::string> VALUE_NAMES;
33
34    PlayingCard(const std::string& suit, const std::string& value) {
35        this->suit = SUITS.at(suit);
36        this->value = VALUES.at(value);
37    }
38
39    int getCardValue() const override {
40        return value;
41    }
42
43    std::string toString() const {
44        return VALUE_NAMES.at(value) + " of " + SUIT_NAMES.at(suit);
45    }
46};
47
48const std::map<std::string, Suit> PlayingCard::SUITS = {
49    {"Clubs", Suit::CLUBS},
50    {"Diamonds", Suit::DIAMONDS},
51    {"Hearts", Suit::HEARTS},
52    {"Spades", Suit::SPADES}
53};
54
55const std::map<Suit, std::string> PlayingCard::SUIT_NAMES = {
56    {Suit::CLUBS, "Clubs"},
57    {Suit::DIAMONDS, "Diamonds"},
58    {Suit::HEARTS, "Hearts"},
59    {Suit::SPADES, "Spades"}
60};
61
62const std::map<std::string, int> PlayingCard::VALUES = {
63    {"A", 1},
64    {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
65    {"J", 11},
66    {"Q", 12},
67    {"K", 13}
68};
69
70const std::map<int, std::string> PlayingCard::VALUE_NAMES = {
71    {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
72    {11, "J"}, {12, "Q"}, {13, "K"}
73};
74
75class Game {
76private:
77    std::vector<std::unique_ptr<Card>> cards;
78
79public:
80    Game() {
81        // Implement initializer here
82    }
83
84    void add_card(const std::string& suit, const std::string& value) {
85        cards.push_back(std::make_unique<PlayingCard>(suit, value));
86    }
87
88    std::string card_string(int card) const {
89        return static_cast<const PlayingCard*>(cards[card].get())->toString();
90    }
91
92    bool card_beats(int card_a, int card_b) const {
93        return cards[card_a]->getCardValue() > cards[card_b]->getCardValue();
94    }
95};
96
97template<typename T>
98std::vector<T> get_words() {
99    std::string line;
100    std::getline(std::cin, line);
101    std::istringstream ss{line};
102    ss >> std::boolalpha;
103    std::vector<T> v;
104    std::copy(std::istream_iterator<T>{ss}, std::istream_iterator<T>{}, std::back_inserter(v));
105    return v;
106}
107
108int main() {
109    Game game;
110    std::vector<std::string> segs = get_words<std::string>();
111    game.add_card(segs.at(0), segs.at(1));
112    std::cout << game.card_string(0) << '\n';
113    segs = get_words<std::string>();
114    game.add_card(segs.at(0), segs.at(1));
115    std::cout << game.card_string(1) << '\n';
116    std::cout << std::boolalpha << game.card_beats(0, 1) << '\n';
117}
118
1use std::collections::HashMap;
2use std::error;
3use std::fmt::Display;
4use std::io::{BufRead, stdin};
5
6trait Card {
7    fn card_value(&self) -> i32;
8}
9
10#[derive(Clone, Copy, PartialEq, Eq, Hash)]
11enum Suit {
12    Clubs,
13    Diamonds,
14    Hearts,
15    Spades,
16}
17
18struct PlayingCard {
19    suit: Suit,
20    value: i32,
21}
22
23impl PlayingCard {
24    fn suits() -> HashMap<&'static str, Suit> {
25        HashMap::from([
26            ("Clubs", Suit::Clubs),
27            ("Diamonds", Suit::Diamonds),
28            ("Hearts", Suit::Hearts),
29            ("Spades", Suit::Spades),
30        ])
31    }
32
33    fn suit_names() -> HashMap<Suit, &'static str> {
34        HashMap::from([
35            (Suit::Clubs, "Clubs"),
36            (Suit::Diamonds, "Diamonds"),
37            (Suit::Hearts, "Hearts"),
38            (Suit::Spades, "Spades"),
39        ])
40    }
41
42    fn values() -> HashMap<&'static str, i32> {
43        HashMap::from([
44            ("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5),
45            ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10),
46            ("J", 11), ("Q", 12), ("K", 13),
47        ])
48    }
49
50    fn value_names() -> HashMap<i32, &'static str> {
51        HashMap::from([
52            (1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"),
53            (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"),
54            (11, "J"), (12, "Q"), (13, "K"),
55        ])
56    }
57
58    fn new(suit: &str, value: &str) -> Self {
59        PlayingCard {
60            suit: Self::suits()[suit],
61            value: Self::values()[value],
62        }
63    }
64}
65
66impl Card for PlayingCard {
67    fn card_value(&self) -> i32 {
68        self.value
69    }
70}
71
72impl Display for PlayingCard {
73    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74        let value_name = Self::value_names()[&self.value];
75        let suit_name = Self::suit_names()[&self.suit];
76        write!(f, "{} of {}", value_name, suit_name)
77    }
78}
79
80struct Game {
81    cards: Vec<PlayingCard>,
82}
83
84impl Game {
85    fn new() -> Self {
86        Game { cards: Vec::new() }
87    }
88
89    fn add_card(&mut self, suit: &str, value: &str) {
90        self.cards.push(PlayingCard::new(suit, value));
91    }
92
93    fn card_string(&self, card: usize) -> String {
94        self.cards[card].to_string()
95    }
96
97    fn card_beats(&self, card_a: usize, card_b: usize) -> bool {
98        self.cards[card_a].card_value() > self.cards[card_b].card_value()
99    }
100}
101
102fn main() -> Result<(), Box<dyn error::Error>> {
103    let stdin = stdin();
104    let mut lines = stdin.lock().lines();
105    let mut game = Game::new();
106    let line1 = lines.next().unwrap().unwrap();
107    let parts1: Vec<&str> = line1.split_whitespace().collect();
108    game.add_card(parts1[0], parts1[1]);
109    println!("{}", game.card_string(0));
110    let line2 = lines.next().unwrap().unwrap();
111    let parts2: Vec<&str> = line2.split_whitespace().collect();
112    game.add_card(parts2[0], parts2[1]);
113    println!("{}", game.card_string(1));
114    println!("{}", game.card_beats(0, 1));
115    Ok(())
116}
117
1package main
2
3import (
4    "bufio"
5    "fmt"
6    "os"
7    "strings"
8)
9
10type Card interface {
11    CardValue() int
12}
13
14type Suit int
15
16const (
17    Clubs Suit = iota
18    Diamonds
19    Hearts
20    Spades
21)
22
23var (
24    SUITS = map[string]Suit{
25        "Clubs":    Clubs,
26        "Diamonds": Diamonds,
27        "Hearts":   Hearts,
28        "Spades":   Spades,
29    }
30
31    SUIT_NAMES = map[Suit]string{
32        Clubs:    "Clubs",
33        Diamonds: "Diamonds",
34        Hearts:   "Hearts",
35        Spades:   "Spades",
36    }
37
38    VALUES = map[string]int{
39        "A": 1,
40        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
41        "J": 11,
42        "Q": 12,
43        "K": 13,
44    }
45
46    VALUE_NAMES = map[int]string{
47        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
48        11: "J", 12: "Q", 13: "K",
49    }
50)
51
52type PlayingCard struct {
53    suit  Suit
54    value int
55}
56
57func NewPlayingCard(suit string, value string) *PlayingCard {
58    return &PlayingCard{
59        suit:  SUITS[suit],
60        value: VALUES[value],
61    }
62}
63
64func (pc *PlayingCard) CardValue() int {
65    return pc.value
66}
67
68func (pc *PlayingCard) String() string {
69    return fmt.Sprintf("%s of %s", VALUE_NAMES[pc.value], SUIT_NAMES[pc.suit])
70}
71
72type Game struct {
73    cards []Card
74}
75
76func NewGame() *Game {
77    return &Game{
78        cards: make([]Card, 0),
79    }
80}
81
82func (g *Game) addCard(suit string, value string) {
83    g.cards = append(g.cards, NewPlayingCard(suit, value))
84}
85
86func (g *Game) cardString(card int) string {
87    return g.cards[card].(*PlayingCard).String()
88}
89
90func (g *Game) cardBeats(cardA int, cardB int) bool {
91    return g.cards[cardA].CardValue() > g.cards[cardB].CardValue()
92}
93
94func main() {
95    scanner := bufio.NewScanner(os.Stdin)
96    scanner.Scan()
97    var segs []string
98    segs = strings.Fields(scanner.Text())
99    game := Game{}
100    game.addCard(segs[0], segs[1])
101    fmt.Println(game.cardString(0))
102    scanner.Scan()
103    segs = strings.Fields(scanner.Text())
104    game.addCard(segs[0], segs[1])
105    fmt.Println(game.cardString(1))
106    fmt.Println(game.cardBeats(0, 1))
107}
108
1class Card
2  def card_value
3    raise NotImplementedError
4  end
5end
6
7class Suit
8  CLUBS = :clubs
9  DIAMONDS = :diamonds
10  HEARTS = :hearts
11  SPADES = :spades
12end
13
14class PlayingCard < Card
15  SUITS = {
16    "Clubs" => Suit::CLUBS,
17    "Diamonds" => Suit::DIAMONDS,
18    "Hearts" => Suit::HEARTS,
19    "Spades" => Suit::SPADES
20  }
21
22  SUIT_NAMES = SUITS.invert
23
24  VALUES = {
25    "A" => 1,
26    "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9, "10" => 10,
27    "J" => 11,
28    "Q" => 12,
29    "K" => 13
30  }
31
32  VALUE_NAMES = VALUES.invert
33
34  def initialize(suit, value)
35    @suit = SUITS[suit]
36    @value = VALUES[value]
37  end
38
39  def card_value
40    @value
41  end
42
43  def to_s
44    "#{VALUE_NAMES[@value]} of #{SUIT_NAMES[@suit]}"
45  end
46end
47
48class Game
49  def initialize
50    @cards = []
51  end
52
53  def add_card(suit, value)
54    @cards << PlayingCard.new(suit, value)
55  end
56
57  def card_string(card)
58    @cards[card].to_s
59  end
60
61  def card_beats(card_a, card_b)
62    @cards[card_a].card_value > @cards[card_b].card_value
63  end
64end
65
66if __FILE__ == $0
67  game = Game.new
68  suit, value = gets.split
69  game.add_card(suit, value)
70  puts game.card_string(0)
71  suit, value = gets.split
72  game.add_card(suit, value)
73  puts game.card_string(1)
74  puts game.card_beats(0, 1)
75end
76
1#lang racket
2
3(struct playing-card (suit value) #:transparent)
4
5(define suits
6  (hash "Clubs" 'clubs "Diamonds" 'diamonds "Hearts" 'hearts "Spades" 'spades))
7
8(define suit-names
9  (hash 'clubs "Clubs" 'diamonds "Diamonds" 'hearts "Hearts" 'spades "Spades"))
10
11(define values
12  (hash "A" 1 "2" 2 "3" 3 "4" 4 "5" 5 "6" 6 "7" 7 "8" 8 "9" 9 "10" 10
13        "J" 11 "Q" 12 "K" 13))
14
15(define value-names
16  (hash 1 "A" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" 10 "10"
17        11 "J" 12 "Q" 13 "K"))
18
19(define (parse-suit s)
20  (hash-ref suits s))
21
22(define (parse-value v)
23  (hash-ref values v))
24
25(define (card-value card)
26  (playing-card-value card))
27
28(define (card->string card)
29  (format "~a of ~a"
30          (hash-ref value-names (playing-card-value card))
31          (hash-ref suit-names (playing-card-suit card))))
32
33(struct game (cards) #:transparent)
34
35(define (make-game)
36  (game '()))
37
38(define (add-card g suit value)
39  (game (append (game-cards g)
40                (list (playing-card (parse-suit suit) (parse-value value))))))
41
42(define (game-card-string g idx)
43  (card->string (list-ref (game-cards g) idx)))
44
45(define (game-card-beats? g idx-a idx-b)
46  (> (card-value (list-ref (game-cards g) idx-a))
47     (card-value (list-ref (game-cards g) idx-b))))
48
49(let* ([line1 (string-split (read-line))]
50       [g1 (add-card (make-game) (first line1) (second line1))])
51  (displayln (game-card-string g1 0))
52  (let* ([line2 (string-split (read-line))]
53         [g2 (add-card g1 (first line2) (second line2))])
54    (displayln (game-card-string g2 1))
55    (displayln (if (game-card-beats? g2 0 1) "true" "false"))))
56
1import qualified Data.Map as M
2
3data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq, Ord, Show)
4
5data PlayingCard = PlayingCard { cardSuit :: Suit, cardVal :: Int }
6
7suits :: M.Map String Suit
8suits = M.fromList [("Clubs", Clubs), ("Diamonds", Diamonds), ("Hearts", Hearts), ("Spades", Spades)]
9
10suitNames :: M.Map Suit String
11suitNames = M.fromList [(Clubs, "Clubs"), (Diamonds, "Diamonds"), (Hearts, "Hearts"), (Spades, "Spades")]
12
13values :: M.Map String Int
14values = M.fromList [("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10), ("J", 11), ("Q", 12), ("K", 13)]
15
16valueNames :: M.Map Int String
17valueNames = M.fromList [(1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"), (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"), (11, "J"), (12, "Q"), (13, "K")]
18
19parseSuit :: String -> Suit
20parseSuit s = suits M.! s
21
22parseValue :: String -> Int
23parseValue v = values M.! v
24
25cardValue :: PlayingCard -> Int
26cardValue = cardVal
27
28cardToString :: PlayingCard -> String
29cardToString card = (valueNames M.! cardVal card) ++ " of " ++ (suitNames M.! cardSuit card)
30
31cardBeats :: PlayingCard -> PlayingCard -> Bool
32cardBeats a b = cardValue a > cardValue b
33
34makeCard :: String -> String -> PlayingCard
35makeCard suit value = PlayingCard (parseSuit suit) (parseValue value)
36
37main :: IO ()
38main = do
39  line1 <- getLine
40  let parts1 = words line1
41      (suit1, value1) = (head parts1, head (tail parts1))
42      card1 = makeCard suit1 value1
43  putStrLn $ cardToString card1
44  line2 <- getLine
45  let parts2 = words line2
46      (suit2, value2) = (head parts2, head (tail parts2))
47      card2 = makeCard suit2 value2
48  putStrLn $ cardToString card2
49  putStrLn $ if cardBeats card1 card2 then "true" else "false"
50

The Game class stores a list of cards which takes O(n) space where n is the number of cards added. Each method (add_card, card_string, card_beats) uses O(1) time and O(1) space.

Part Two

For this part, we ask you to implement the Jokers into the system.

In addition to the functionalities above, also implement the following functions:

  • add_joker(color): Creates a Joker card with color of either Red or Black.
    • Joker beats everything else except other jokers. This card is represented by i, where i is an integer indicating how many cards have been created before, including both normal cards and jokers.
    • A joker's string representation is Red Joker or Black Joker, depending on the color.

You may copy the code from the previous question here.

Try it yourself

Solution

We add a Joker class that inherits the base Card. For the purpose of this question, its value is 14, which is greater than other cards. We do not need to write extra logic for comparing Jokers with other cards, since that logic is already there under Card.

Below is the updated implementation:

1from enum import Enum, auto
2
3class Card:
4    @property
5    def card_value(self) -> int:
6        raise NotImplementedError()
7
8    def __lt__(self, other):
9        return self.card_value < other.card_value
10
11class Suit(Enum):
12    CLUBS = auto()
13    DIAMONDS = auto()
14    HEARTS = auto()
15    SPADES = auto()
16
17class PlayingCard(Card):
18    SUITS = {
19        "Clubs": Suit.CLUBS,
20        "Diamonds": Suit.DIAMONDS,
21        "Hearts": Suit.HEARTS,
22        "Spades": Suit.SPADES,
23    }
24    SUIT_NAMES = {e: n for n, e in SUITS.items()}
25    VALUES = {
26        "A": 1,
27        **{str(i): i for i in range(2, 11)},
28        "J": 11,
29        "Q": 12,
30        "K": 13,
31    }
32    VALUE_NAMES = {e: n for n, e in VALUES.items()}
33
34    def __init__(self, suit: str, value: str):
35        super().__init__()
36        self.__suit = self.SUITS[suit]
37        self.__value = self.VALUES[value]
38
39    @property
40    def card_value(self) -> int:
41        return self.__value
42
43    def __str__(self) -> str:
44        value = self.VALUE_NAMES[self.__value]
45        suit = self.SUIT_NAMES[self.__suit]
46        return f"{value} of {suit}"
47
48class JokerColor(Enum):
49    RED = auto()
50    BLACK = auto()
51
52class Joker(Card):
53    COLORS = {
54        "Red": JokerColor.RED,
55        "Black": JokerColor.BLACK,
56    }
57
58    COLOR_NAMES = {e: n for n, e in COLORS.items()}
59
60    def __init__(self, color: str):
61        super().__init__()
62        self.__color = self.COLORS[color]
63
64    @property
65    def card_value(self):
66        return 14
67
68    def __str__(self) -> str:
69        return f"{self.COLOR_NAMES[self.__color]} Joker"
70
71class Game:
72    def __init__(self):
73        self.__cards: list[Card] = []
74
75    def add_card(self, suit: str, value: str) -> None:
76        self.__cards.append(PlayingCard(suit, value))
77
78    def card_string(self, card: int) -> str:
79        return str(self.__cards[card])
80
81    def card_beats(self, card_a: int, card_b: int) -> bool:
82        return self.__cards[card_a] > self.__cards[card_b]
83
84    def add_joker(self, color: str) -> None:
85        self.__cards.append(Joker(color))
86
87if __name__ == "__main__":
88    game = Game()
89    suit, value = input().split()
90    game.add_joker(value) if suit == "Joker" else game.add_card(suit, value)
91    print(game.card_string(0))
92    suit, value = input().split()
93    game.add_joker(value) if suit == "Joker" else game.add_card(suit, value)
94    print(game.card_string(1))
95    print("true" if game.card_beats(0, 1) else "false")
96
1import java.util.ArrayList;
2import java.util.HashMap;
3import java.util.Map;
4import java.util.Map.Entry;
5import java.util.Scanner;
6import java.util.stream.Collectors;
7
8class Solution {
9    public static abstract class Card implements Comparable<Card> {
10        public abstract int getValue();
11
12        @Override
13        public int compareTo(Card o) {
14            return Integer.compare(getValue(), o.getValue());
15        }
16    }
17
18    public enum Suit {
19        SPADES,
20        HEARTS,
21        DIAMONDS,
22        CLUBS,
23    }
24
25    public static class PlayingCard extends Card {
26        private Suit suit;
27        private int value;
28
29        public static final Map<String, Suit> SUITS = Map.of(
30            "Spades", Suit.SPADES,
31            "Hearts", Suit.HEARTS,
32            "Diamonds", Suit.DIAMONDS,
33            "Clubs", Suit.CLUBS);
34
35        // Inverts the above map to convert back to string.
36        public static final Map<Suit, String> SUIT_NAMES = SUITS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
37
38        // Map.of is limited to 10 entries, so we initialize a static map instead
39        public static final Map<String, Integer> VALUES = new HashMap<>();
40        static {
41            VALUES.put("A", 1);
42            for (int i = 2; i <= 10; i++) {
43                VALUES.put(String.valueOf(i), i);
44            }
45            VALUES.put("J", 11);
46            VALUES.put("Q", 12);
47            VALUES.put("K", 13);
48        }
49        // Inverts the above map to convert back to string.
50        public static final Map<Integer, String> VALUE_NAMES = VALUES.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
51
52        public PlayingCard(String suit, String value) {
53            this.suit = SUITS.get(suit);
54            this.value = VALUES.get(value);
55        }
56
57        @Override
58        public int getValue() {
59            return value;
60        }
61
62        @Override
63        public String toString() {
64            return String.format("%s of %s", VALUE_NAMES.get(value), SUIT_NAMES.get(suit));
65        }
66    }
67
68    public enum JokerColor {
69        RED,
70        BLACK,
71    }
72
73    public static class Joker extends Card {
74        private JokerColor color;
75
76        public static final Map<String, JokerColor> COLORS = Map.of(
77            "Red", JokerColor.RED,
78            "Black", JokerColor.BLACK);
79
80        // Inverts the above map to convert back to string.
81        public static final Map<JokerColor, String> COLOR_NAMES = COLORS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
82
83        public Joker(String color) {
84            this.color = COLORS.get(color);
85        }
86
87        @Override
88        public int getValue() {
89            return 14;
90        }
91
92        @Override
93        public String toString() {
94            return String.format("%s Joker", COLOR_NAMES.get(color));
95        }
96    }
97
98    public static class Game {
99        private ArrayList<Card> cards;
100
101        public Game() {
102            cards = new ArrayList<>();
103        }
104
105        public void addCard(String suit, String value) {
106            cards.add(new PlayingCard(suit, value));
107        }
108
109        public String cardString(int card) {
110            return cards.get(card).toString();
111        }
112
113        public boolean cardBeats(int cardA, int cardB) {
114            return cards.get(cardA).compareTo(cards.get(cardB)) > 0;
115        }
116
117        public void addJoker(String color) {
118            cards.add(new Joker(color));
119        }
120    }
121
122    public static void main(String[] args) {
123        Scanner scanner = new Scanner(System.in);
124        Game game = new Game();
125        String[] segs = scanner.nextLine().split(" ");
126        if (segs[0].equals("Joker"))
127            game.addJoker(segs[1]);
128        else
129            game.addCard(segs[0], segs[1]);
130        System.out.println(game.cardString(0));
131        segs = scanner.nextLine().split(" ");
132        if (segs[0].equals("Joker"))
133            game.addJoker(segs[1]);
134        else
135            game.addCard(segs[0], segs[1]);
136        System.out.println(game.cardString(1));
137        System.out.println(game.cardBeats(0, 1));
138        scanner.close();
139    }
140}
141
1using System;
2using System.Collections.Generic;
3
4class Solution
5{
6    public abstract class Card
7    {
8        public abstract int CardValue { get; }
9    }
10
11    public enum Suit
12    {
13        Clubs,
14        Diamonds,
15        Hearts,
16        Spades
17    }
18
19    public enum JokerColor
20    {
21        Red,
22        Black
23    }
24
25    public class PlayingCard : Card
26    {
27        private Suit suit;
28        private int value;
29
30        public static readonly Dictionary<string, Suit> SUITS = new Dictionary<string, Suit>
31        {
32            {"Clubs", Suit.Clubs},
33            {"Diamonds", Suit.Diamonds},
34            {"Hearts", Suit.Hearts},
35            {"Spades", Suit.Spades}
36        };
37
38        public static readonly Dictionary<Suit, string> SUIT_NAMES = new Dictionary<Suit, string>
39        {
40            {Suit.Clubs, "Clubs"},
41            {Suit.Diamonds, "Diamonds"},
42            {Suit.Hearts, "Hearts"},
43            {Suit.Spades, "Spades"}
44        };
45
46        public static readonly Dictionary<string, int> VALUES = new Dictionary<string, int>
47        {
48            {"A", 1},
49            {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
50            {"J", 11},
51            {"Q", 12},
52            {"K", 13}
53        };
54
55        public static readonly Dictionary<int, string> VALUE_NAMES = new Dictionary<int, string>
56        {
57            {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
58            {11, "J"}, {12, "Q"}, {13, "K"}
59        };
60
61        public PlayingCard(string suit, string value)
62        {
63            this.suit = SUITS[suit];
64            this.value = VALUES[value];
65        }
66
67        public override int CardValue => value;
68
69        public override string ToString()
70        {
71            return $"{VALUE_NAMES[value]} of {SUIT_NAMES[suit]}";
72        }
73    }
74
75    public class Joker : Card
76    {
77        private JokerColor color;
78
79        public static readonly Dictionary<string, JokerColor> COLORS = new Dictionary<string, JokerColor>
80        {
81            {"Red", JokerColor.Red},
82            {"Black", JokerColor.Black}
83        };
84
85        public static readonly Dictionary<JokerColor, string> COLOR_NAMES = new Dictionary<JokerColor, string>
86        {
87            {JokerColor.Red, "Red"},
88            {JokerColor.Black, "Black"}
89        };
90
91        public Joker(string color)
92        {
93            this.color = COLORS[color];
94        }
95
96        public override int CardValue => 14;
97
98        public override string ToString()
99        {
100            return $"{COLOR_NAMES[color]} Joker";
101        }
102    }
103
104    public class Game
105    {
106        private List<Card> cards;
107
108        public Game()
109        {
110            cards = new List<Card>();
111        }
112
113        public void AddCard(string suit, string value)
114        {
115            cards.Add(new PlayingCard(suit, value));
116        }
117
118        public string CardString(int card)
119        {
120            return cards[card].ToString();
121        }
122
123        public bool CardBeats(int cardA, int cardB)
124        {
125            return cards[cardA].CardValue > cards[cardB].CardValue;
126        }
127
128        public void AddJoker(string color)
129        {
130            cards.Add(new Joker(color));
131        }
132    }
133
134    public static void Main()
135    {
136        Game game = new Game();
137        string[] segs = Console.ReadLine().Split(' ');
138        if (segs[0] == "Joker")
139            game.AddJoker(segs[1]);
140        else
141            game.AddCard(segs[0], segs[1]);
142        Console.WriteLine(game.CardString(0));
143        segs = Console.ReadLine().Split(' ');
144        if (segs[0] == "Joker")
145            game.AddJoker(segs[1]);
146        else
147            game.AddCard(segs[0], segs[1]);
148        Console.WriteLine(game.CardString(1));
149        Console.WriteLine(game.CardBeats(0, 1) ? "true" : "false");
150    }
151}
152
1"use strict";
2
3class Card {
4    get cardValue() {
5        throw new Error("Not implemented");
6    }
7}
8
9class PlayingCard extends Card {
10    constructor(suit, value) {
11        super();
12        this.suit = suit;
13        this.value = value;
14    }
15
16    static SUITS = {
17        "Clubs": "Clubs",
18        "Diamonds": "Diamonds",
19        "Hearts": "Hearts",
20        "Spades": "Spades"
21    };
22
23    static VALUES = {
24        "A": 1,
25        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
26        "J": 11,
27        "Q": 12,
28        "K": 13
29    };
30
31    static VALUE_NAMES = {
32        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
33        11: "J", 12: "Q", 13: "K"
34    };
35
36    get cardValue() {
37        return PlayingCard.VALUES[this.value];
38    }
39
40    toString() {
41        const valueName = PlayingCard.VALUE_NAMES[PlayingCard.VALUES[this.value]];
42        return `${valueName} of ${this.suit}`;
43    }
44}
45
46class Joker extends Card {
47    constructor(color) {
48        super();
49        this.color = color;
50    }
51
52    static COLORS = {
53        "Red": "Red",
54        "Black": "Black"
55    };
56
57    get cardValue() {
58        return 14;
59    }
60
61    toString() {
62        return `${this.color} Joker`;
63    }
64}
65
66class Game {
67    constructor() {
68        this.cards = [];
69    }
70
71    addCard(suit, value) {
72        this.cards.push(new PlayingCard(suit, value));
73    }
74
75    cardString(card) {
76        return this.cards[card].toString();
77    }
78
79    cardBeats(cardA, cardB) {
80        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
81    }
82
83    addJoker(color) {
84        this.cards.push(new Joker(color));
85    }
86}
87
88function* main() {
89    const game = new Game();
90    let [suit, value] = (yield).split(" ");
91    if (suit == "Joker") {
92        game.addJoker(value);
93    } else {
94        game.addCard(suit, value);
95    }
96    console.log(game.cardString(0));
97    [suit, value] = (yield).split(" ");
98    if (suit == "Joker") {
99        game.addJoker(value);
100    } else {
101        game.addCard(suit, value);
102    }
103    console.log(game.cardString(1));
104    console.log(game.cardBeats(0, 1));
105}
106
107class EOFError extends Error {}
108{
109    const gen = main();
110    const next = (line) => gen.next(line).done && process.exit();
111    let buf = "";
112    next();
113    process.stdin.setEncoding("utf8");
114    process.stdin.on("data", (data) => {
115        const lines = (buf + data).split("\n");
116        buf = lines.pop();
117        lines.forEach(next);
118    });
119    process.stdin.on("end", () => {
120        buf && next(buf);
121        gen.throw(new EOFError());
122    });
123}
124
1abstract class Card {
2    abstract get cardValue(): number;
3}
4
5enum Suit {
6    CLUBS,
7    DIAMONDS,
8    HEARTS,
9    SPADES
10}
11
12enum JokerColor {
13    RED,
14    BLACK
15}
16
17class PlayingCard extends Card {
18    private suit: Suit;
19    private value: number;
20
21    static readonly SUITS: { [key: string]: Suit } = {
22        "Clubs": Suit.CLUBS,
23        "Diamonds": Suit.DIAMONDS,
24        "Hearts": Suit.HEARTS,
25        "Spades": Suit.SPADES
26    };
27
28    static readonly SUIT_NAMES: { [key: number]: string } = {
29        [Suit.CLUBS]: "Clubs",
30        [Suit.DIAMONDS]: "Diamonds",
31        [Suit.HEARTS]: "Hearts",
32        [Suit.SPADES]: "Spades"
33    };
34
35    static readonly VALUES: { [key: string]: number } = {
36        "A": 1,
37        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
38        "J": 11,
39        "Q": 12,
40        "K": 13
41    };
42
43    static readonly VALUE_NAMES: { [key: number]: string } = {
44        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
45        11: "J", 12: "Q", 13: "K"
46    };
47
48    constructor(suit: string, value: string) {
49        super();
50        this.suit = PlayingCard.SUITS[suit];
51        this.value = PlayingCard.VALUES[value];
52    }
53
54    get cardValue(): number {
55        return this.value;
56    }
57
58    toString(): string {
59        const valueName = PlayingCard.VALUE_NAMES[this.value];
60        const suitName = PlayingCard.SUIT_NAMES[this.suit];
61        return `${valueName} of ${suitName}`;
62    }
63}
64
65class Joker extends Card {
66    private color: JokerColor;
67
68    static readonly COLORS: { [key: string]: JokerColor } = {
69        "Red": JokerColor.RED,
70        "Black": JokerColor.BLACK
71    };
72
73    static readonly COLOR_NAMES: { [key: number]: string } = {
74        [JokerColor.RED]: "Red",
75        [JokerColor.BLACK]: "Black"
76    };
77
78    constructor(color: string) {
79        super();
80        this.color = Joker.COLORS[color];
81    }
82
83    get cardValue(): number {
84        return 14;
85    }
86
87    toString(): string {
88        const colorName = Joker.COLOR_NAMES[this.color];
89        return `${colorName} Joker`;
90    }
91}
92
93class Game {
94    private cards: Card[] = [];
95
96    constructor() {
97        // Implement initializer here
98    }
99
100    addCard(suit: string, value: string): void {
101        this.cards.push(new PlayingCard(suit, value));
102    }
103
104    cardString(card: number): string {
105        return this.cards[card].toString();
106    }
107
108    cardBeats(cardA: number, cardB: number): boolean {
109        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
110    }
111
112    addJoker(color: string): void {
113        this.cards.push(new Joker(color));
114    }
115}
116
117function* main() {
118    const game = new Game();
119    let [suit, value] = (yield).split(" ");
120    if (suit == "Joker") {
121        game.addJoker(value);
122    } else {
123        game.addCard(suit, value);
124    }
125    console.log(game.cardString(0));
126    [suit, value] = (yield).split(" ");
127    if (suit == "Joker") {
128        game.addJoker(value);
129    } else {
130        game.addCard(suit, value);
131    }
132    console.log(game.cardString(1));
133    console.log(game.cardBeats(0, 1));
134}
135
136class EOFError extends Error {}
137{
138    const gen = main();
139    const next = (line?: string) => gen.next(line ?? "").done && process.exit();
140    let buf = "";
141    next();
142    process.stdin.setEncoding("utf8");
143    process.stdin.on("data", (data) => {
144        const lines = (buf + data).split("\n");
145        buf = lines.pop() ?? "";
146        lines.forEach(next);
147    });
148    process.stdin.on("end", () => {
149        buf && next(buf);
150        gen.throw(new EOFError());
151    });
152}
153
1#include <algorithm>
2#include <iostream>
3#include <iterator>
4#include <limits>
5#include <map>
6#include <memory>
7#include <sstream>
8#include <string>
9#include <vector>
10
11class Card {
12public:
13    virtual int getCardValue() const = 0;
14    virtual std::string toString() const = 0;
15    virtual ~Card() = default;
16};
17
18enum class Suit {
19    CLUBS,
20    DIAMONDS,
21    HEARTS,
22    SPADES
23};
24
25enum class JokerColor {
26    RED,
27    BLACK
28};
29
30class PlayingCard : public Card {
31private:
32    Suit suit;
33    int value;
34
35public:
36    static const std::map<std::string, Suit> SUITS;
37    static const std::map<Suit, std::string> SUIT_NAMES;
38    static const std::map<std::string, int> VALUES;
39    static const std::map<int, std::string> VALUE_NAMES;
40
41    PlayingCard(const std::string& suit, const std::string& value) {
42        this->suit = SUITS.at(suit);
43        this->value = VALUES.at(value);
44    }
45
46    int getCardValue() const override {
47        return value;
48    }
49
50    std::string toString() const override {
51        return VALUE_NAMES.at(value) + " of " + SUIT_NAMES.at(suit);
52    }
53};
54
55class Joker : public Card {
56private:
57    JokerColor color;
58
59public:
60    static const std::map<std::string, JokerColor> COLORS;
61    static const std::map<JokerColor, std::string> COLOR_NAMES;
62
63    Joker(const std::string& color) {
64        this->color = COLORS.at(color);
65    }
66
67    int getCardValue() const override {
68        return 14;
69    }
70
71    std::string toString() const override {
72        return COLOR_NAMES.at(color) + " Joker";
73    }
74};
75
76const std::map<std::string, Suit> PlayingCard::SUITS = {
77    {"Clubs", Suit::CLUBS},
78    {"Diamonds", Suit::DIAMONDS},
79    {"Hearts", Suit::HEARTS},
80    {"Spades", Suit::SPADES}
81};
82
83const std::map<Suit, std::string> PlayingCard::SUIT_NAMES = {
84    {Suit::CLUBS, "Clubs"},
85    {Suit::DIAMONDS, "Diamonds"},
86    {Suit::HEARTS, "Hearts"},
87    {Suit::SPADES, "Spades"}
88};
89
90const std::map<std::string, int> PlayingCard::VALUES = {
91    {"A", 1},
92    {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
93    {"J", 11},
94    {"Q", 12},
95    {"K", 13}
96};
97
98const std::map<int, std::string> PlayingCard::VALUE_NAMES = {
99    {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
100    {11, "J"}, {12, "Q"}, {13, "K"}
101};
102
103const std::map<std::string, JokerColor> Joker::COLORS = {
104    {"Red", JokerColor::RED},
105    {"Black", JokerColor::BLACK}
106};
107
108const std::map<JokerColor, std::string> Joker::COLOR_NAMES = {
109    {JokerColor::RED, "Red"},
110    {JokerColor::BLACK, "Black"}
111};
112
113class Game {
114private:
115    std::vector<std::unique_ptr<Card>> cards;
116
117public:
118    Game() {
119        // Implement initializer here
120    }
121
122    void add_card(const std::string& suit, const std::string& value) {
123        cards.push_back(std::make_unique<PlayingCard>(suit, value));
124    }
125
126    std::string card_string(int card) const {
127        return cards[card]->toString();
128    }
129
130    bool card_beats(int card_a, int card_b) const {
131        return cards[card_a]->getCardValue() > cards[card_b]->getCardValue();
132    }
133
134    void add_joker(const std::string& color) {
135        cards.push_back(std::make_unique<Joker>(color));
136    }
137};
138
139template<typename T>
140std::vector<T> get_words() {
141    std::string line;
142    std::getline(std::cin, line);
143    std::istringstream ss{line};
144    ss >> std::boolalpha;
145    std::vector<T> v;
146    std::copy(std::istream_iterator<T>{ss}, std::istream_iterator<T>{}, std::back_inserter(v));
147    return v;
148}
149
150void ignore_line() {
151    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
152}
153
154int main() {
155    Game game;
156    std::vector<std::string> segs = get_words<std::string>();
157    if (segs.at(0) == "Joker")
158        game.add_joker(segs.at(1));
159    else
160        game.add_card(segs.at(0), segs.at(1));
161    std::cout << game.card_string(0) << '\n';
162    segs = get_words<std::string>();
163    if (segs.at(0) == "Joker")
164        game.add_joker(segs.at(1));
165    else
166        game.add_card(segs.at(0), segs.at(1));
167    std::cout << game.card_string(1) << '\n';
168    std::cout << std::boolalpha << game.card_beats(0, 1) << '\n';
169}
170
1use std::collections::HashMap;
2use std::error;
3use std::io::{BufRead, stdin};
4
5trait Card {
6    fn card_value(&self) -> i32;
7}
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash)]
10enum Suit {
11    Clubs,
12    Diamonds,
13    Hearts,
14    Spades,
15}
16
17#[derive(Clone, Copy, PartialEq, Eq, Hash)]
18enum JokerColor {
19    Red,
20    Black,
21}
22
23struct PlayingCard {
24    suit: Suit,
25    value: i32,
26}
27
28impl PlayingCard {
29    fn suits() -> HashMap<&'static str, Suit> {
30        HashMap::from([
31            ("Clubs", Suit::Clubs),
32            ("Diamonds", Suit::Diamonds),
33            ("Hearts", Suit::Hearts),
34            ("Spades", Suit::Spades),
35        ])
36    }
37
38    fn suit_names() -> HashMap<Suit, &'static str> {
39        HashMap::from([
40            (Suit::Clubs, "Clubs"),
41            (Suit::Diamonds, "Diamonds"),
42            (Suit::Hearts, "Hearts"),
43            (Suit::Spades, "Spades"),
44        ])
45    }
46
47    fn values() -> HashMap<&'static str, i32> {
48        HashMap::from([
49            ("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5),
50            ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10),
51            ("J", 11), ("Q", 12), ("K", 13),
52        ])
53    }
54
55    fn value_names() -> HashMap<i32, &'static str> {
56        HashMap::from([
57            (1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"),
58            (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"),
59            (11, "J"), (12, "Q"), (13, "K"),
60        ])
61    }
62
63    fn new(suit: &str, value: &str) -> Self {
64        PlayingCard {
65            suit: Self::suits()[suit],
66            value: Self::values()[value],
67        }
68    }
69}
70
71impl Card for PlayingCard {
72    fn card_value(&self) -> i32 {
73        self.value
74    }
75}
76
77impl std::fmt::Display for PlayingCard {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        let value_name = Self::value_names()[&self.value];
80        let suit_name = Self::suit_names()[&self.suit];
81        write!(f, "{} of {}", value_name, suit_name)
82    }
83}
84
85struct Joker {
86    color: JokerColor,
87}
88
89impl Joker {
90    fn colors() -> HashMap<&'static str, JokerColor> {
91        HashMap::from([
92            ("Red", JokerColor::Red),
93            ("Black", JokerColor::Black),
94        ])
95    }
96
97    fn color_names() -> HashMap<JokerColor, &'static str> {
98        HashMap::from([
99            (JokerColor::Red, "Red"),
100            (JokerColor::Black, "Black"),
101        ])
102    }
103
104    fn new(color: &str) -> Self {
105        Joker {
106            color: Self::colors()[color],
107        }
108    }
109}
110
111impl Card for Joker {
112    fn card_value(&self) -> i32 {
113        14
114    }
115}
116
117impl std::fmt::Display for Joker {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        let color_name = Self::color_names()[&self.color];
120        write!(f, "{} Joker", color_name)
121    }
122}
123
124enum CardType {
125    Playing(PlayingCard),
126    Joker(Joker),
127}
128
129impl Card for CardType {
130    fn card_value(&self) -> i32 {
131        match self {
132            CardType::Playing(c) => c.card_value(),
133            CardType::Joker(j) => j.card_value(),
134        }
135    }
136}
137
138impl std::fmt::Display for CardType {
139    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140        match self {
141            CardType::Playing(c) => write!(f, "{}", c),
142            CardType::Joker(j) => write!(f, "{}", j),
143        }
144    }
145}
146
147struct Game {
148    cards: Vec<CardType>,
149}
150
151impl Game {
152    fn new() -> Self {
153        Game { cards: Vec::new() }
154    }
155
156    fn add_card(&mut self, suit: &str, value: &str) {
157        self.cards.push(CardType::Playing(PlayingCard::new(suit, value)));
158    }
159
160    fn card_string(&self, card: usize) -> String {
161        self.cards[card].to_string()
162    }
163
164    fn card_beats(&self, card_a: usize, card_b: usize) -> bool {
165        self.cards[card_a].card_value() > self.cards[card_b].card_value()
166    }
167
168    fn add_joker(&mut self, color: &str) {
169        self.cards.push(CardType::Joker(Joker::new(color)));
170    }
171}
172
173fn main() -> Result<(), Box<dyn error::Error>> {
174    let stdin = stdin();
175    let mut lines = stdin.lock().lines();
176    let mut game = Game::new();
177    let line1 = lines.next().unwrap().unwrap();
178    let parts1: Vec<&str> = line1.split_whitespace().collect();
179    if parts1[0] == "Joker" {
180        game.add_joker(parts1[1]);
181    } else {
182        game.add_card(parts1[0], parts1[1]);
183    }
184    println!("{}", game.card_string(0));
185    let line2 = lines.next().unwrap().unwrap();
186    let parts2: Vec<&str> = line2.split_whitespace().collect();
187    if parts2[0] == "Joker" {
188        game.add_joker(parts2[1]);
189    } else {
190        game.add_card(parts2[0], parts2[1]);
191    }
192    println!("{}", game.card_string(1));
193    println!("{}", game.card_beats(0, 1));
194    Ok(())
195}
196
1package main
2
3import (
4    "bufio"
5    "fmt"
6    "os"
7    "strings"
8)
9
10type Card interface {
11    CardValue() int
12}
13
14type Suit int
15
16const (
17    Clubs Suit = iota
18    Diamonds
19    Hearts
20    Spades
21)
22
23type JokerColor int
24
25const (
26    Red JokerColor = iota
27    Black
28)
29
30var (
31    SUITS = map[string]Suit{
32        "Clubs":    Clubs,
33        "Diamonds": Diamonds,
34        "Hearts":   Hearts,
35        "Spades":   Spades,
36    }
37
38    SUIT_NAMES = map[Suit]string{
39        Clubs:    "Clubs",
40        Diamonds: "Diamonds",
41        Hearts:   "Hearts",
42        Spades:   "Spades",
43    }
44
45    VALUES = map[string]int{
46        "A": 1,
47        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
48        "J": 11,
49        "Q": 12,
50        "K": 13,
51    }
52
53    VALUE_NAMES = map[int]string{
54        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
55        11: "J", 12: "Q", 13: "K",
56    }
57
58    JOKER_COLORS = map[string]JokerColor{
59        "Red":   Red,
60        "Black": Black,
61    }
62
63    JOKER_COLOR_NAMES = map[JokerColor]string{
64        Red:   "Red",
65        Black: "Black",
66    }
67)
68
69type PlayingCard struct {
70    suit  Suit
71    value int
72}
73
74func NewPlayingCard(suit string, value string) *PlayingCard {
75    return &PlayingCard{
76        suit:  SUITS[suit],
77        value: VALUES[value],
78    }
79}
80
81func (pc *PlayingCard) CardValue() int {
82    return pc.value
83}
84
85func (pc *PlayingCard) String() string {
86    return fmt.Sprintf("%s of %s", VALUE_NAMES[pc.value], SUIT_NAMES[pc.suit])
87}
88
89type Joker struct {
90    color JokerColor
91}
92
93func NewJoker(color string) *Joker {
94    return &Joker{
95        color: JOKER_COLORS[color],
96    }
97}
98
99func (j *Joker) CardValue() int {
100    return 14
101}
102
103func (j *Joker) String() string {
104    return fmt.Sprintf("%s Joker", JOKER_COLOR_NAMES[j.color])
105}
106
107type Game struct {
108    cards []Card
109}
110
111func NewGame() *Game {
112    return &Game{
113        cards: make([]Card, 0),
114    }
115}
116
117func (g *Game) addCard(suit string, value string) {
118    g.cards = append(g.cards, NewPlayingCard(suit, value))
119}
120
121func (g *Game) cardString(card int) string {
122    switch c := g.cards[card].(type) {
123    case *PlayingCard:
124        return c.String()
125    case *Joker:
126        return c.String()
127    }
128    return ""
129}
130
131func (g *Game) cardBeats(cardA int, cardB int) bool {
132    return g.cards[cardA].CardValue() > g.cards[cardB].CardValue()
133}
134
135func (g *Game) addJoker(color string) {
136    g.cards = append(g.cards, NewJoker(color))
137}
138
139func main() {
140    scanner := bufio.NewScanner(os.Stdin)
141    scanner.Scan()
142    var segs []string
143    segs = strings.Fields(scanner.Text())
144    game := Game{}
145    if segs[0] == "Joker" {
146        game.addJoker(segs[1])
147    } else {
148        game.addCard(segs[0], segs[1])
149    }
150    fmt.Println(game.cardString(0))
151    scanner.Scan()
152    segs = strings.Fields(scanner.Text())
153    if segs[0] == "Joker" {
154        game.addJoker(segs[1])
155    } else {
156        game.addCard(segs[0], segs[1])
157    }
158    fmt.Println(game.cardString(1))
159    fmt.Println(game.cardBeats(0, 1))
160}
161
1class Card
2  def card_value
3    raise NotImplementedError
4  end
5end
6
7class Suit
8  CLUBS = :clubs
9  DIAMONDS = :diamonds
10  HEARTS = :hearts
11  SPADES = :spades
12end
13
14class JokerColor
15  RED = :red
16  BLACK = :black
17end
18
19class PlayingCard < Card
20  SUITS = {
21    "Clubs" => Suit::CLUBS,
22    "Diamonds" => Suit::DIAMONDS,
23    "Hearts" => Suit::HEARTS,
24    "Spades" => Suit::SPADES
25  }
26
27  SUIT_NAMES = SUITS.invert
28
29  VALUES = {
30    "A" => 1,
31    "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9, "10" => 10,
32    "J" => 11,
33    "Q" => 12,
34    "K" => 13
35  }
36
37  VALUE_NAMES = VALUES.invert
38
39  def initialize(suit, value)
40    @suit = SUITS[suit]
41    @value = VALUES[value]
42  end
43
44  def card_value
45    @value
46  end
47
48  def to_s
49    "#{VALUE_NAMES[@value]} of #{SUIT_NAMES[@suit]}"
50  end
51end
52
53class Joker < Card
54  COLORS = {
55    "Red" => JokerColor::RED,
56    "Black" => JokerColor::BLACK
57  }
58
59  COLOR_NAMES = COLORS.invert
60
61  def initialize(color)
62    @color = COLORS[color]
63  end
64
65  def card_value
66    14
67  end
68
69  def to_s
70    "#{COLOR_NAMES[@color]} Joker"
71  end
72end
73
74class Game
75  def initialize
76    @cards = []
77  end
78
79  def add_card(suit, value)
80    @cards << PlayingCard.new(suit, value)
81  end
82
83  def card_string(card)
84    @cards[card].to_s
85  end
86
87  def card_beats(card_a, card_b)
88    @cards[card_a].card_value > @cards[card_b].card_value
89  end
90
91  def add_joker(color)
92    @cards << Joker.new(color)
93  end
94end
95
96if __FILE__ == $0
97  game = Game.new
98  suit, value = gets.split
99  if suit == "Joker"
100    game.add_joker(value)
101  else
102    game.add_card(suit, value)
103  end
104  puts game.card_string(0)
105  suit, value = gets.split
106  if suit == "Joker"
107    game.add_joker(value)
108  else
109    game.add_card(suit, value)
110  end
111  puts game.card_string(1)
112  puts game.card_beats(0, 1)
113end
114
1#lang racket
2
3(struct playing-card (suit value) #:transparent)
4(struct joker-card (color) #:transparent)
5
6(define suits
7  (hash "Clubs" 'clubs "Diamonds" 'diamonds "Hearts" 'hearts "Spades" 'spades))
8
9(define suit-names
10  (hash 'clubs "Clubs" 'diamonds "Diamonds" 'hearts "Hearts" 'spades "Spades"))
11
12(define values
13  (hash "A" 1 "2" 2 "3" 3 "4" 4 "5" 5 "6" 6 "7" 7 "8" 8 "9" 9 "10" 10
14        "J" 11 "Q" 12 "K" 13))
15
16(define value-names
17  (hash 1 "A" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" 10 "10"
18        11 "J" 12 "Q" 13 "K"))
19
20(define joker-colors
21  (hash "Red" 'red "Black" 'black))
22
23(define joker-color-names
24  (hash 'red "Red" 'black "Black"))
25
26(define (parse-suit s)
27  (hash-ref suits s))
28
29(define (parse-value v)
30  (hash-ref values v))
31
32(define (parse-joker-color c)
33  (hash-ref joker-colors c))
34
35(define (card-value card)
36  (cond
37    [(playing-card? card) (playing-card-value card)]
38    [(joker-card? card) 14]))
39
40(define (card->string card)
41  (cond
42    [(playing-card? card)
43     (format "~a of ~a"
44             (hash-ref value-names (playing-card-value card))
45             (hash-ref suit-names (playing-card-suit card)))]
46    [(joker-card? card)
47     (format "~a Joker"
48             (hash-ref joker-color-names (joker-card-color card)))]))
49
50(struct game (cards) #:transparent #:mutable)
51
52(define (make-game)
53  (game '()))
54
55(define (add-card! g suit value)
56  (set-game-cards! g
57    (append (game-cards g)
58            (list (playing-card (parse-suit suit) (parse-value value))))))
59
60(define (add-joker! g color)
61  (set-game-cards! g
62    (append (game-cards g)
63            (list (joker-card (parse-joker-color color))))))
64
65(define (game-card-string g idx)
66  (card->string (list-ref (game-cards g) idx)))
67
68(define (game-card-beats? g idx-a idx-b)
69  (> (card-value (list-ref (game-cards g) idx-a))
70     (card-value (list-ref (game-cards g) idx-b))))
71
72(define g (make-game))
73(define line1 (string-split (read-line)))
74(if (equal? (first line1) "Joker")
75    (add-joker! g (second line1))
76    (add-card! g (first line1) (second line1)))
77(displayln (game-card-string g 0))
78(define line2 (string-split (read-line)))
79(if (equal? (first line2) "Joker")
80    (add-joker! g (second line2))
81    (add-card! g (first line2) (second line2)))
82(displayln (game-card-string g 1))
83(displayln (if (game-card-beats? g 0 1) "true" "false"))
84
1import Data.IORef (modifyIORef, newIORef, readIORef)
2import qualified Data.Map as M
3
4data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq, Ord, Show)
5data JokerColor = Red | Black deriving (Eq, Ord, Show)
6
7data Card = PlayingCard Suit Int
8          | JokerCard JokerColor
9
10suits :: M.Map String Suit
11suits = M.fromList [("Clubs", Clubs), ("Diamonds", Diamonds), ("Hearts", Hearts), ("Spades", Spades)]
12
13suitNames :: M.Map Suit String
14suitNames = M.fromList [(Clubs, "Clubs"), (Diamonds, "Diamonds"), (Hearts, "Hearts"), (Spades, "Spades")]
15
16values :: M.Map String Int
17values = M.fromList [("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10), ("J", 11), ("Q", 12), ("K", 13)]
18
19valueNames :: M.Map Int String
20valueNames = M.fromList [(1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"), (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"), (11, "J"), (12, "Q"), (13, "K")]
21
22jokerColors :: M.Map String JokerColor
23jokerColors = M.fromList [("Red", Red), ("Black", Black)]
24
25jokerColorNames :: M.Map JokerColor String
26jokerColorNames = M.fromList [(Red, "Red"), (Black, "Black")]
27
28parseSuit :: String -> Suit
29parseSuit s = suits M.! s
30
31parseValue :: String -> Int
32parseValue v = values M.! v
33
34parseJokerColor :: String -> JokerColor
35parseJokerColor c = jokerColors M.! c
36
37cardValue :: Card -> Int
38cardValue (PlayingCard _ v) = v
39cardValue (JokerCard _) = 14
40
41cardToString :: Card -> String
42cardToString (PlayingCard s v) = (valueNames M.! v) ++ " of " ++ (suitNames M.! s)
43cardToString (JokerCard c) = (jokerColorNames M.! c) ++ " Joker"
44
45cardBeats :: Card -> Card -> Bool
46cardBeats a b = cardValue a > cardValue b
47
48makeCard :: String -> String -> Card
49makeCard suit value = PlayingCard (parseSuit suit) (parseValue value)
50
51makeJoker :: String -> Card
52makeJoker color = JokerCard (parseJokerColor color)
53
54main :: IO ()
55main = do
56  cardsRef <- newIORef []
57  line1 <- getLine
58  let parts1 = words line1
59  let card1 = if head parts1 == "Joker"
60              then makeJoker (parts1 !! 1)
61              else makeCard (head parts1) (parts1 !! 1)
62  modifyIORef cardsRef (++ [card1])
63  putStrLn $ cardToString card1
64  line2 <- getLine
65  let parts2 = words line2
66  let card2 = if head parts2 == "Joker"
67              then makeJoker (parts2 !! 1)
68              else makeCard (head parts2) (parts2 !! 1)
69  modifyIORef cardsRef (++ [card2])
70  putStrLn $ cardToString card2
71  cards <- readIORef cardsRef
72  putStrLn $ if cardBeats (cards !! 0) (cards !! 1) then "true" else "false"
73

The method add_joker uses O(1) time and O(1) space.

Part Three

This game also involve a concept of a Hand and comparing the size of the two hands. For this part, add these following functions to the Game class:

  • add_hand(card_indices): Create a new Hand with cards represented by the list of integer representation of cards card_indices. The hand can be represented by i, where i is the number of hands added before.
  • hand_string(hand): Return the string representation of the hand represented by hand. It is a list of string representation of cards by their insertion order, separated by ", ". For example, if hand has a 9 of Clubs, K of Hearts, and a Black Joker, the string representation is "9 of Clubs, K of Hearts, Black Joker".
  • beats_hand(hand_a, hand_b): Check if the hand represented by hand_a beats the hand represented by hand_b according to the following rules:
    • Starting from the largest card in each hand, compare them. If a card beats another, that hand beats the other hand. Otherwise, compare the next largest card.
    • Repeat this process until one hand beats the other, or one hand runs out of cards. If a hand runs out of cards, neither hand beat each other.

Try it yourself

Solution

For this part, we implement the Hand class by having it contain a list of cards. When we compare two hands, because we defined a comparison function between two cards, we can sort them using the default sorting algorithm.

Below is the implementation:

1from enum import Enum, auto
2
3class Card:
4    @property
5    def card_value(self) -> int:
6        raise NotImplementedError()
7
8    def __lt__(self, other):
9        return self.card_value < other.card_value
10
11class Suit(Enum):
12    CLUBS = auto()
13    DIAMONDS = auto()
14    HEARTS = auto()
15    SPADES = auto()
16
17class PlayingCard(Card):
18    SUITS = {
19        "Clubs": Suit.CLUBS,
20        "Diamonds": Suit.DIAMONDS,
21        "Hearts": Suit.HEARTS,
22        "Spades": Suit.SPADES,
23    }
24    SUIT_NAMES = {e: n for n, e in SUITS.items()}
25    VALUES = {
26        "A": 1,
27        **{str(i): i for i in range(2, 11)},
28        "J": 11,
29        "Q": 12,
30        "K": 13,
31    }
32    VALUE_NAMES = {e: n for n, e in VALUES.items()}
33
34    def __init__(self, suit: str, value: str) -> None:
35        super().__init__()
36        self.__suit = self.SUITS[suit]
37        self.__value = self.VALUES[value]
38
39    @property
40    def card_value(self) -> int:
41        return self.__value
42
43    def __str__(self) -> str:
44        value = self.VALUE_NAMES[self.__value]
45        suit = self.SUIT_NAMES[self.__suit]
46        return f"{value} of {suit}"
47
48class JokerColor(Enum):
49    RED = auto()
50    BLACK = auto()
51
52class Joker(Card):
53    COLORS = {
54        "Red": JokerColor.RED,
55        "Black": JokerColor.BLACK,
56    }
57
58    COLOR_NAMES = {e: n for n, e in COLORS.items()}
59
60    def __init__(self, color: str) -> None:
61        super().__init__()
62        self.__color = self.COLORS[color]
63
64    @property
65    def card_value(self) -> int:
66        return 14
67
68    def __str__(self) -> str:
69        return f"{self.COLOR_NAMES[self.__color]} Joker"
70
71class Hand:
72    def __init__(self, cards: list[Card]) -> None:
73        super().__init__()
74        self.cards = list(cards)
75
76    def __str__(self) -> str:
77        return ", ".join(str(card) for card in self.cards)
78
79    def __lt__(self, other):
80        for card_a, card_b in zip(
81            sorted(self.cards, reverse=True),
82            sorted(other.cards, reverse=True),
83        ):
84            if card_a < card_b:
85                return True
86            elif card_b < card_a:
87                return False
88        return False
89
90class Game:
91    def __init__(self):
92        self.__cards: list[Card] = []
93        self.__hands: list[Hand] = []
94
95    def add_card(self, suit: str, value: str) -> None:
96        self.__cards.append(PlayingCard(suit, value))
97
98    def card_string(self, card: int) -> str:
99        return str(self.__cards[card])
100
101    def card_beats(self, card_a: int, card_b: int) -> bool:
102        return self.__cards[card_a] > self.__cards[card_b]
103
104    def add_joker(self, color: str) -> None:
105        self.__cards.append(Joker(color))
106
107    def add_hand(self, card_indices: list[int]) -> None:
108        self.__hands.append(Hand([self.__cards[i] for i in card_indices]))
109
110    def hand_string(self, hand: int) -> str:
111        return str(self.__hands[hand])
112
113    def hand_beats(self, hand_a: int, hand_b: int) -> bool:
114        return self.__hands[hand_a] > self.__hands[hand_b]
115
116if __name__ == "__main__":
117    game = Game()
118    offset = 0
119    for hand in range(2):
120        hand_list = []
121        n = int(input())
122        for i in range(n):
123            suit, value = input().split()
124            if suit == "Joker":
125                game.add_joker(value)
126            else:
127                game.add_card(suit, value)
128            hand_list.append(offset + i)
129        offset += n
130        game.add_hand(hand_list)
131        print(game.hand_string(hand))
132    print("true" if game.hand_beats(0, 1) else "false")
133
1import java.util.ArrayList;
2import java.util.Collections;
3import java.util.HashMap;
4import java.util.List;
5import java.util.Map;
6import java.util.Map.Entry;
7import java.util.Scanner;
8import java.util.stream.Collectors;
9
10class Solution {
11    public static abstract class Card implements Comparable<Card> {
12        public abstract int getValue();
13
14        @Override
15        public int compareTo(Card o) {
16            return Integer.compare(getValue(), o.getValue());
17        }
18    }
19
20    public enum Suit {
21        SPADES,
22        HEARTS,
23        DIAMONDS,
24        CLUBS,
25    }
26
27    public static class PlayingCard extends Card {
28        private Suit suit;
29        private int value;
30
31        public static final Map<String, Suit> SUITS = Map.of(
32            "Spades", Suit.SPADES,
33            "Hearts", Suit.HEARTS,
34            "Diamonds", Suit.DIAMONDS,
35            "Clubs", Suit.CLUBS);
36
37        // Inverts the above map to convert back to string.
38        public static final Map<Suit, String> SUIT_NAMES = SUITS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
39
40        // Map.of is limited to 10 entries, so we initialize a static map instead
41        public static final Map<String, Integer> VALUES = new HashMap<>();
42        static {
43            VALUES.put("A", 1);
44            for (int i = 2; i <= 10; i++) {
45                VALUES.put(String.valueOf(i), i);
46            }
47            VALUES.put("J", 11);
48            VALUES.put("Q", 12);
49            VALUES.put("K", 13);
50        }
51        // Inverts the above map to convert back to string.
52        public static final Map<Integer, String> VALUE_NAMES = VALUES.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
53
54        public PlayingCard(String suit, String value) {
55            this.suit = SUITS.get(suit);
56            this.value = VALUES.get(value);
57        }
58
59        @Override
60        public int getValue() {
61            return value;
62        }
63
64        @Override
65        public String toString() {
66            return String.format("%s of %s", VALUE_NAMES.get(value), SUIT_NAMES.get(suit));
67        }
68    }
69
70    public enum JokerColor {
71        RED,
72        BLACK,
73    }
74
75    public static class Joker extends Card {
76        private JokerColor color;
77
78        public static final Map<String, JokerColor> COLORS = Map.of(
79            "Red", JokerColor.RED,
80            "Black", JokerColor.BLACK);
81
82        // Inverts the above map to convert back to string.
83        public static final Map<JokerColor, String> COLOR_NAMES = COLORS.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
84
85        public Joker(String color) {
86            this.color = COLORS.get(color);
87        }
88
89        @Override
90        public int getValue() {
91            return 14;
92        }
93
94        @Override
95        public String toString() {
96            return String.format("%s Joker", COLOR_NAMES.get(color));
97        }
98    }
99
100    public static class Hand implements Comparable<Hand> {
101        public ArrayList<Card> cards;
102
103        public Hand(List<Card> cards) {
104            this.cards = new ArrayList<>(cards);
105        }
106
107        @Override
108        public String toString() {
109            return cards.stream().map(String::valueOf).collect(Collectors.joining(", "));
110        }
111
112        @Override
113        public int compareTo(Hand o) {
114            ArrayList<Card> selfCards = new ArrayList<>(cards);
115            ArrayList<Card> otherCards = new ArrayList<>(o.cards);
116            Collections.sort(selfCards);
117            Collections.sort(otherCards);
118            for (int i = selfCards.size() - 1, j = otherCards.size() - 1; i >= 0 && j >= 0; i--, j--) {
119                int res = selfCards.get(i).compareTo(otherCards.get(j));
120                if (res != 0) {
121                    return res;
122                }
123            }
124            return 0;
125        }
126    }
127
128    public static class Game {
129        private ArrayList<Card> cards;
130        private ArrayList<Hand> hands;
131
132        public Game() {
133            cards = new ArrayList<>();
134            hands = new ArrayList<>();
135        }
136
137        public void addCard(String suit, String value) {
138            cards.add(new PlayingCard(suit, value));
139        }
140
141        public String cardString(int card) {
142            return cards.get(card).toString();
143        }
144
145        public boolean cardBeats(int cardA, int cardB) {
146            return cards.get(cardA).compareTo(cards.get(cardB)) > 0;
147        }
148
149        public void addJoker(String color) {
150            cards.add(new Joker(color));
151        }
152
153        public void addHand(List<Integer> cardIndices) {
154            ArrayList<Card> cardObjects = new ArrayList<>();
155            for (int i : cardIndices) {
156                cardObjects.add(cards.get(i));
157            }
158            hands.add(new Hand(cardObjects));
159        }
160
161        public String handString(int hand) {
162            return hands.get(hand).toString();
163        }
164
165        public boolean handBeats(int handA, int handB) {
166            return hands.get(handA).compareTo(hands.get(handB)) > 0;
167        }
168    }
169
170    public static void main(String[] args) {
171        Scanner scanner = new Scanner(System.in);
172        Game game = new Game();
173        int i = 0;
174        int end = 0;
175        for (int hand = 0; hand < 2; hand++) {
176            ArrayList<Integer> handList = new ArrayList<>();
177            end += Integer.parseInt(scanner.nextLine());
178            for (; i < end; i++) {
179                String[] segs = scanner.nextLine().split(" ");
180                if (segs[0].equals("Joker"))
181                    game.addJoker(segs[1]);
182                else
183                    game.addCard(segs[0], segs[1]);
184                handList.add(i);
185            }
186            game.addHand(handList);
187            System.out.println(game.handString(hand));
188        }
189        System.out.println(game.handBeats(0, 1));
190        scanner.close();
191    }
192}
193
1using System;
2using System.Collections.Generic;
3
4class Solution
5{
6    public abstract class Card
7    {
8        public abstract int CardValue { get; }
9    }
10
11    public enum Suit
12    {
13        Clubs,
14        Diamonds,
15        Hearts,
16        Spades
17    }
18
19    public enum JokerColor
20    {
21        Red,
22        Black
23    }
24
25    public class PlayingCard : Card
26    {
27        private Suit suit;
28        private int value;
29
30        public static readonly Dictionary<string, Suit> SUITS = new Dictionary<string, Suit>
31        {
32            {"Clubs", Suit.Clubs},
33            {"Diamonds", Suit.Diamonds},
34            {"Hearts", Suit.Hearts},
35            {"Spades", Suit.Spades}
36        };
37
38        public static readonly Dictionary<Suit, string> SUIT_NAMES = new Dictionary<Suit, string>
39        {
40            {Suit.Clubs, "Clubs"},
41            {Suit.Diamonds, "Diamonds"},
42            {Suit.Hearts, "Hearts"},
43            {Suit.Spades, "Spades"}
44        };
45
46        public static readonly Dictionary<string, int> VALUES = new Dictionary<string, int>
47        {
48            {"A", 1},
49            {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
50            {"J", 11},
51            {"Q", 12},
52            {"K", 13}
53        };
54
55        public static readonly Dictionary<int, string> VALUE_NAMES = new Dictionary<int, string>
56        {
57            {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
58            {11, "J"}, {12, "Q"}, {13, "K"}
59        };
60
61        public PlayingCard(string suit, string value)
62        {
63            this.suit = SUITS[suit];
64            this.value = VALUES[value];
65        }
66
67        public override int CardValue => value;
68
69        public override string ToString()
70        {
71            return $"{VALUE_NAMES[value]} of {SUIT_NAMES[suit]}";
72        }
73    }
74
75    public class Joker : Card
76    {
77        private JokerColor color;
78
79        public static readonly Dictionary<string, JokerColor> COLORS = new Dictionary<string, JokerColor>
80        {
81            {"Red", JokerColor.Red},
82            {"Black", JokerColor.Black}
83        };
84
85        public static readonly Dictionary<JokerColor, string> COLOR_NAMES = new Dictionary<JokerColor, string>
86        {
87            {JokerColor.Red, "Red"},
88            {JokerColor.Black, "Black"}
89        };
90
91        public Joker(string color)
92        {
93            this.color = COLORS[color];
94        }
95
96        public override int CardValue => 14;
97
98        public override string ToString()
99        {
100            return $"{COLOR_NAMES[color]} Joker";
101        }
102    }
103
104    public class Hand
105    {
106        private List<Card> cards;
107
108        public Hand(List<Card> cards)
109        {
110            this.cards = new List<Card>(cards);
111        }
112
113        public override string ToString()
114        {
115            return string.Join(", ", cards.Select(c => c.ToString()));
116        }
117
118        public int CompareTo(Hand other)
119        {
120            var selfCards = cards.OrderByDescending(c => c.CardValue).ToList();
121            var otherCards = other.cards.OrderByDescending(c => c.CardValue).ToList();
122
123            int minLen = Math.Min(selfCards.Count, otherCards.Count);
124            for (int i = 0; i < minLen; i++)
125            {
126                int diff = selfCards[i].CardValue - otherCards[i].CardValue;
127                if (diff != 0) return diff;
128            }
129            return 0;
130        }
131    }
132
133    public class Game
134    {
135        private List<Card> cards;
136        private List<Hand> hands;
137
138        public Game()
139        {
140            cards = new List<Card>();
141            hands = new List<Hand>();
142        }
143
144        public void AddCard(string suit, string value)
145        {
146            cards.Add(new PlayingCard(suit, value));
147        }
148
149        public string CardString(int card)
150        {
151            return cards[card].ToString();
152        }
153
154        public bool CardBeats(int cardA, int cardB)
155        {
156            return cards[cardA].CardValue > cards[cardB].CardValue;
157        }
158
159        public void AddJoker(string color)
160        {
161            cards.Add(new Joker(color));
162        }
163
164        public void AddHand(List<int> cardIndices)
165        {
166            var handCards = cardIndices.Select(i => cards[i]).ToList();
167            hands.Add(new Hand(handCards));
168        }
169
170        public string HandString(int hand)
171        {
172            return hands[hand].ToString();
173        }
174
175        public bool HandBeats(int handA, int handB)
176        {
177            return hands[handA].CompareTo(hands[handB]) > 0;
178        }
179    }
180
181    public static void Main()
182    {
183        Game game = new Game();
184        int i = 0;
185        int end = 0;
186        for (int hand = 0; hand < 2; hand++)
187        {
188            List<int> handList = new List<int>();
189            end += int.Parse(Console.ReadLine());
190            for (; i < end; i++)
191            {
192                string[] segs = Console.ReadLine().Split(' ');
193                if (segs[0] == "Joker")
194                    game.AddJoker(segs[1]);
195                else
196                    game.AddCard(segs[0], segs[1]);
197                handList.Add(i);
198            }
199            game.AddHand(handList);
200            Console.WriteLine(game.HandString(hand));
201        }
202        Console.WriteLine(game.HandBeats(0, 1) ? "true" : "false");
203    }
204}
205
1"use strict";
2
3class Card {
4    get cardValue() {
5        throw new Error("Not implemented");
6    }
7}
8
9class PlayingCard extends Card {
10    constructor(suit, value) {
11        super();
12        this.suit = suit;
13        this.value = value;
14    }
15
16    static SUITS = {
17        "Clubs": "Clubs",
18        "Diamonds": "Diamonds",
19        "Hearts": "Hearts",
20        "Spades": "Spades"
21    };
22
23    static VALUES = {
24        "A": 1,
25        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
26        "J": 11,
27        "Q": 12,
28        "K": 13
29    };
30
31    static VALUE_NAMES = {
32        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
33        11: "J", 12: "Q", 13: "K"
34    };
35
36    get cardValue() {
37        return PlayingCard.VALUES[this.value];
38    }
39
40    toString() {
41        const valueName = PlayingCard.VALUE_NAMES[PlayingCard.VALUES[this.value]];
42        return `${valueName} of ${this.suit}`;
43    }
44}
45
46class Joker extends Card {
47    constructor(color) {
48        super();
49        this.color = color;
50    }
51
52    static COLORS = {
53        "Red": "Red",
54        "Black": "Black"
55    };
56
57    get cardValue() {
58        return 14;
59    }
60
61    toString() {
62        return `${this.color} Joker`;
63    }
64}
65
66class Hand {
67    constructor(cards) {
68        this.cards = [...cards];
69    }
70
71    toString() {
72        return this.cards.map(card => card.toString()).join(", ");
73    }
74
75    compareTo(other) {
76        const selfCards = [...this.cards].sort((a, b) => b.cardValue - a.cardValue);
77        const otherCards = [...other.cards].sort((a, b) => b.cardValue - a.cardValue);
78
79        for (let i = 0; i < Math.min(selfCards.length, otherCards.length); i++) {
80            const diff = selfCards[i].cardValue - otherCards[i].cardValue;
81            if (diff !== 0) {
82                return diff;
83            }
84        }
85        return 0;
86    }
87}
88
89class Game {
90    constructor() {
91        this.cards = [];
92        this.hands = [];
93    }
94
95    addCard(suit, value) {
96        this.cards.push(new PlayingCard(suit, value));
97    }
98
99    cardString(card) {
100        return this.cards[card].toString();
101    }
102
103    cardBeats(cardA, cardB) {
104        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
105    }
106
107    addJoker(color) {
108        this.cards.push(new Joker(color));
109    }
110
111    addHand(cardIndices) {
112        const handCards = cardIndices.map(i => this.cards[i]);
113        this.hands.push(new Hand(handCards));
114    }
115
116    handString(hand) {
117        return this.hands[hand].toString();
118    }
119
120    handBeats(handA, handB) {
121        return this.hands[handA].compareTo(this.hands[handB]) > 0;
122    }
123}
124
125function* main() {
126    const game = new Game();
127    let i = 0;
128    let end = 0;
129    for (let hand = 0; hand < 2; hand++) {
130        const handList = [];
131        end += parseInt(yield);
132        for (; i < end; i++) {
133            const [suit, value] = (yield).split(" ");
134            if (suit == "Joker") {
135                game.addJoker(value);
136            } else {
137                game.addCard(suit, value);
138            }
139            handList.push(i);
140        }
141        game.addHand(handList);
142        console.log(game.handString(hand));
143    }
144    console.log(game.handBeats(0, 1));
145}
146
147class EOFError extends Error {}
148{
149    const gen = main();
150    const next = (line) => gen.next(line).done && process.exit();
151    let buf = "";
152    next();
153    process.stdin.setEncoding("utf8");
154    process.stdin.on("data", (data) => {
155        const lines = (buf + data).split("\n");
156        buf = lines.pop();
157        lines.forEach(next);
158    });
159    process.stdin.on("end", () => {
160        buf && next(buf);
161        gen.throw(new EOFError());
162    });
163}
164
1abstract class Card {
2    abstract get cardValue(): number;
3}
4
5enum Suit {
6    CLUBS,
7    DIAMONDS,
8    HEARTS,
9    SPADES
10}
11
12enum JokerColor {
13    RED,
14    BLACK
15}
16
17class PlayingCard extends Card {
18    private suit: Suit;
19    private value: number;
20
21    static readonly SUITS: { [key: string]: Suit } = {
22        "Clubs": Suit.CLUBS,
23        "Diamonds": Suit.DIAMONDS,
24        "Hearts": Suit.HEARTS,
25        "Spades": Suit.SPADES
26    };
27
28    static readonly SUIT_NAMES: { [key: number]: string } = {
29        [Suit.CLUBS]: "Clubs",
30        [Suit.DIAMONDS]: "Diamonds",
31        [Suit.HEARTS]: "Hearts",
32        [Suit.SPADES]: "Spades"
33    };
34
35    static readonly VALUES: { [key: string]: number } = {
36        "A": 1,
37        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
38        "J": 11,
39        "Q": 12,
40        "K": 13
41    };
42
43    static readonly VALUE_NAMES: { [key: number]: string } = {
44        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
45        11: "J", 12: "Q", 13: "K"
46    };
47
48    constructor(suit: string, value: string) {
49        super();
50        this.suit = PlayingCard.SUITS[suit];
51        this.value = PlayingCard.VALUES[value];
52    }
53
54    get cardValue(): number {
55        return this.value;
56    }
57
58    toString(): string {
59        const valueName = PlayingCard.VALUE_NAMES[this.value];
60        const suitName = PlayingCard.SUIT_NAMES[this.suit];
61        return `${valueName} of ${suitName}`;
62    }
63}
64
65class Joker extends Card {
66    private color: JokerColor;
67
68    static readonly COLORS: { [key: string]: JokerColor } = {
69        "Red": JokerColor.RED,
70        "Black": JokerColor.BLACK
71    };
72
73    static readonly COLOR_NAMES: { [key: number]: string } = {
74        [JokerColor.RED]: "Red",
75        [JokerColor.BLACK]: "Black"
76    };
77
78    constructor(color: string) {
79        super();
80        this.color = Joker.COLORS[color];
81    }
82
83    get cardValue(): number {
84        return 14;
85    }
86
87    toString(): string {
88        const colorName = Joker.COLOR_NAMES[this.color];
89        return `${colorName} Joker`;
90    }
91}
92
93class Hand {
94    private cards: Card[];
95
96    constructor(cards: Card[]) {
97        this.cards = [...cards];
98    }
99
100    toString(): string {
101        return this.cards.map(card => card.toString()).join(", ");
102    }
103
104    compareTo(other: Hand): number {
105        const selfCards = [...this.cards].sort((a, b) => b.cardValue - a.cardValue);
106        const otherCards = [...other.cards].sort((a, b) => b.cardValue - a.cardValue);
107
108        for (let i = 0; i < Math.min(selfCards.length, otherCards.length); i++) {
109            const diff = selfCards[i].cardValue - otherCards[i].cardValue;
110            if (diff !== 0) {
111                return diff;
112            }
113        }
114        return 0;
115    }
116}
117
118class Game {
119    private cards: Card[] = [];
120    private hands: Hand[] = [];
121
122    constructor() {
123        // Implement initializer here
124    }
125
126    addCard(suit: string, value: string): void {
127        this.cards.push(new PlayingCard(suit, value));
128    }
129
130    cardString(card: number): string {
131        return this.cards[card].toString();
132    }
133
134    cardBeats(cardA: number, cardB: number): boolean {
135        return this.cards[cardA].cardValue > this.cards[cardB].cardValue;
136    }
137
138    addJoker(color: string): void {
139        this.cards.push(new Joker(color));
140    }
141
142    addHand(cardIndices: number[]): void {
143        const handCards = cardIndices.map(i => this.cards[i]);
144        this.hands.push(new Hand(handCards));
145    }
146
147    handString(hand: number): string {
148        return this.hands[hand].toString();
149    }
150
151    handBeats(handA: number, handB: number): boolean {
152        return this.hands[handA].compareTo(this.hands[handB]) > 0;
153    }
154}
155
156function* main() {
157    const game = new Game();
158    let i = 0;
159    let end = 0;
160    for (let hand = 0; hand < 2; hand++) {
161        const handList = [];
162        end += parseInt(yield);
163        for (; i < end; i++) {
164            const [suit, value] = (yield).split(" ");
165            if (suit == "Joker") {
166                game.addJoker(value);
167            } else {
168                game.addCard(suit, value);
169            }
170            handList.push(i);
171        }
172        game.addHand(handList);
173        console.log(game.handString(hand));
174    }
175    console.log(game.handBeats(0, 1));
176}
177
178class EOFError extends Error {}
179{
180    const gen = main();
181    const next = (line?: string) => gen.next(line ?? "").done && process.exit();
182    let buf = "";
183    next();
184    process.stdin.setEncoding("utf8");
185    process.stdin.on("data", (data) => {
186        const lines = (buf + data).split("\n");
187        buf = lines.pop() ?? "";
188        lines.forEach(next);
189    });
190    process.stdin.on("end", () => {
191        buf && next(buf);
192        gen.throw(new EOFError());
193    });
194}
195
1#include <algorithm>
2#include <iostream>
3#include <iterator>
4#include <limits>
5#include <map>
6#include <memory>
7#include <sstream>
8#include <string>
9#include <vector>
10
11class Card {
12public:
13    virtual int getCardValue() const = 0;
14    virtual std::string toString() const = 0;
15    virtual ~Card() = default;
16};
17
18enum class Suit {
19    CLUBS,
20    DIAMONDS,
21    HEARTS,
22    SPADES
23};
24
25enum class JokerColor {
26    RED,
27    BLACK
28};
29
30class PlayingCard : public Card {
31private:
32    Suit suit;
33    int value;
34
35public:
36    static const std::map<std::string, Suit> SUITS;
37    static const std::map<Suit, std::string> SUIT_NAMES;
38    static const std::map<std::string, int> VALUES;
39    static const std::map<int, std::string> VALUE_NAMES;
40
41    PlayingCard(const std::string& suit, const std::string& value) {
42        this->suit = SUITS.at(suit);
43        this->value = VALUES.at(value);
44    }
45
46    int getCardValue() const override {
47        return value;
48    }
49
50    std::string toString() const override {
51        return VALUE_NAMES.at(value) + " of " + SUIT_NAMES.at(suit);
52    }
53};
54
55class Joker : public Card {
56private:
57    JokerColor color;
58
59public:
60    static const std::map<std::string, JokerColor> COLORS;
61    static const std::map<JokerColor, std::string> COLOR_NAMES;
62
63    Joker(const std::string& color) {
64        this->color = COLORS.at(color);
65    }
66
67    int getCardValue() const override {
68        return 14;
69    }
70
71    std::string toString() const override {
72        return COLOR_NAMES.at(color) + " Joker";
73    }
74};
75
76class Hand {
77private:
78    std::vector<Card*> cards;
79
80public:
81    Hand(const std::vector<Card*>& cardPtrs) : cards(cardPtrs) {}
82
83    std::string toString() const {
84        std::string result;
85        for (size_t i = 0; i < cards.size(); i++) {
86            if (i > 0) result += ", ";
87            result += cards[i]->toString();
88        }
89        return result;
90    }
91
92    int compareTo(const Hand& other) const {
93        std::vector<int> selfValues, otherValues;
94
95        for (const auto& card : cards) {
96            selfValues.push_back(card->getCardValue());
97        }
98        for (const auto& card : other.cards) {
99            otherValues.push_back(card->getCardValue());
100        }
101
102        std::sort(selfValues.begin(), selfValues.end(), std::greater<int>());
103        std::sort(otherValues.begin(), otherValues.end(), std::greater<int>());
104
105        size_t minSize = std::min(selfValues.size(), otherValues.size());
106        for (size_t i = 0; i < minSize; i++) {
107            if (selfValues[i] != otherValues[i]) {
108                return selfValues[i] - otherValues[i];
109            }
110        }
111        return 0;
112    }
113};
114
115const std::map<std::string, Suit> PlayingCard::SUITS = {
116    {"Clubs", Suit::CLUBS},
117    {"Diamonds", Suit::DIAMONDS},
118    {"Hearts", Suit::HEARTS},
119    {"Spades", Suit::SPADES}
120};
121
122const std::map<Suit, std::string> PlayingCard::SUIT_NAMES = {
123    {Suit::CLUBS, "Clubs"},
124    {Suit::DIAMONDS, "Diamonds"},
125    {Suit::HEARTS, "Hearts"},
126    {Suit::SPADES, "Spades"}
127};
128
129const std::map<std::string, int> PlayingCard::VALUES = {
130    {"A", 1},
131    {"2", 2}, {"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9}, {"10", 10},
132    {"J", 11},
133    {"Q", 12},
134    {"K", 13}
135};
136
137const std::map<int, std::string> PlayingCard::VALUE_NAMES = {
138    {1, "A"}, {2, "2"}, {3, "3"}, {4, "4"}, {5, "5"}, {6, "6"}, {7, "7"}, {8, "8"}, {9, "9"}, {10, "10"},
139    {11, "J"}, {12, "Q"}, {13, "K"}
140};
141
142const std::map<std::string, JokerColor> Joker::COLORS = {
143    {"Red", JokerColor::RED},
144    {"Black", JokerColor::BLACK}
145};
146
147const std::map<JokerColor, std::string> Joker::COLOR_NAMES = {
148    {JokerColor::RED, "Red"},
149    {JokerColor::BLACK, "Black"}
150};
151
152class Game {
153private:
154    std::vector<std::unique_ptr<Card>> cards;
155    std::vector<Hand> hands;
156
157public:
158    Game() {
159        // Implement initializer here
160    }
161
162    void add_card(const std::string& suit, const std::string& value) {
163        cards.push_back(std::make_unique<PlayingCard>(suit, value));
164    }
165
166    std::string card_string(int card) const {
167        return cards[card]->toString();
168    }
169
170    bool card_beats(int card_a, int card_b) const {
171        return cards[card_a]->getCardValue() > cards[card_b]->getCardValue();
172    }
173
174    void add_joker(const std::string& color) {
175        cards.push_back(std::make_unique<Joker>(color));
176    }
177
178    void add_hand(const std::vector<int>& card_indices) {
179        std::vector<Card*> handCards;
180        for (int index : card_indices) {
181            handCards.push_back(cards[index].get());
182        }
183        hands.emplace_back(handCards);
184    }
185
186    std::string hand_string(int hand) const {
187        return hands[hand].toString();
188    }
189
190    bool hand_beats(int hand_a, int hand_b) const {
191        return hands[hand_a].compareTo(hands[hand_b]) > 0;
192    }
193};
194
195template<typename T>
196std::vector<T> get_words() {
197    std::string line;
198    std::getline(std::cin, line);
199    std::istringstream ss{line};
200    ss >> std::boolalpha;
201    std::vector<T> v;
202    std::copy(std::istream_iterator<T>{ss}, std::istream_iterator<T>{}, std::back_inserter(v));
203    return v;
204}
205
206void ignore_line() {
207    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
208}
209
210int main() {
211    Game game;
212    int i = 0;
213    int end = 0;
214    for (int hand = 0; hand < 2; hand++) {
215        std::vector<int> hand_list;
216        int length;
217        std::cin >> length;
218        end += length;
219        ignore_line();
220        for (; i < end; i++) {
221            std::vector<std::string> segs = get_words<std::string>();
222            if (segs.at(0) == "Joker")
223                game.add_joker(segs.at(1));
224            else
225                game.add_card(segs.at(0), segs.at(1));
226            hand_list.emplace_back(i);
227        }
228        game.add_hand(hand_list);
229        std::cout << game.hand_string(hand) << '\n';
230    }
231    std::cout << std::boolalpha << game.hand_beats(0, 1) << '\n';
232}
233
1use std::collections::HashMap;
2use std::error;
3use std::io::{BufRead, stdin};
4
5trait Card {
6    fn card_value(&self) -> i32;
7}
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash)]
10enum Suit {
11    Clubs,
12    Diamonds,
13    Hearts,
14    Spades,
15}
16
17#[derive(Clone, Copy, PartialEq, Eq, Hash)]
18enum JokerColor {
19    Red,
20    Black,
21}
22
23struct PlayingCard {
24    suit: Suit,
25    value: i32,
26}
27
28impl PlayingCard {
29    fn suits() -> HashMap<&'static str, Suit> {
30        HashMap::from([
31            ("Clubs", Suit::Clubs),
32            ("Diamonds", Suit::Diamonds),
33            ("Hearts", Suit::Hearts),
34            ("Spades", Suit::Spades),
35        ])
36    }
37
38    fn suit_names() -> HashMap<Suit, &'static str> {
39        HashMap::from([
40            (Suit::Clubs, "Clubs"),
41            (Suit::Diamonds, "Diamonds"),
42            (Suit::Hearts, "Hearts"),
43            (Suit::Spades, "Spades"),
44        ])
45    }
46
47    fn values() -> HashMap<&'static str, i32> {
48        HashMap::from([
49            ("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5),
50            ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10),
51            ("J", 11), ("Q", 12), ("K", 13),
52        ])
53    }
54
55    fn value_names() -> HashMap<i32, &'static str> {
56        HashMap::from([
57            (1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"),
58            (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"),
59            (11, "J"), (12, "Q"), (13, "K"),
60        ])
61    }
62
63    fn new(suit: &str, value: &str) -> Self {
64        PlayingCard {
65            suit: Self::suits()[suit],
66            value: Self::values()[value],
67        }
68    }
69}
70
71impl Card for PlayingCard {
72    fn card_value(&self) -> i32 {
73        self.value
74    }
75}
76
77impl std::fmt::Display for PlayingCard {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        let value_name = Self::value_names()[&self.value];
80        let suit_name = Self::suit_names()[&self.suit];
81        write!(f, "{} of {}", value_name, suit_name)
82    }
83}
84
85struct Joker {
86    color: JokerColor,
87}
88
89impl Joker {
90    fn colors() -> HashMap<&'static str, JokerColor> {
91        HashMap::from([
92            ("Red", JokerColor::Red),
93            ("Black", JokerColor::Black),
94        ])
95    }
96
97    fn color_names() -> HashMap<JokerColor, &'static str> {
98        HashMap::from([
99            (JokerColor::Red, "Red"),
100            (JokerColor::Black, "Black"),
101        ])
102    }
103
104    fn new(color: &str) -> Self {
105        Joker {
106            color: Self::colors()[color],
107        }
108    }
109}
110
111impl Card for Joker {
112    fn card_value(&self) -> i32 {
113        14
114    }
115}
116
117impl std::fmt::Display for Joker {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        let color_name = Self::color_names()[&self.color];
120        write!(f, "{} Joker", color_name)
121    }
122}
123
124enum CardType {
125    Playing(PlayingCard),
126    Joker(Joker),
127}
128
129impl Card for CardType {
130    fn card_value(&self) -> i32 {
131        match self {
132            CardType::Playing(c) => c.card_value(),
133            CardType::Joker(j) => j.card_value(),
134        }
135    }
136}
137
138impl std::fmt::Display for CardType {
139    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140        match self {
141            CardType::Playing(c) => write!(f, "{}", c),
142            CardType::Joker(j) => write!(f, "{}", j),
143        }
144    }
145}
146
147struct Hand {
148    cards: Vec<i32>,  // Store card values for comparison
149    card_strings: Vec<String>,  // Store string representations
150}
151
152impl Hand {
153    fn new(cards: &[&CardType]) -> Self {
154        Hand {
155            cards: cards.iter().map(|c| c.card_value()).collect(),
156            card_strings: cards.iter().map(|c| c.to_string()).collect(),
157        }
158    }
159
160    fn to_string(&self) -> String {
161        self.card_strings.join(", ")
162    }
163
164    fn compare_to(&self, other: &Hand) -> i32 {
165        let mut self_values = self.cards.clone();
166        let mut other_values = other.cards.clone();
167        self_values.sort_by(|a, b| b.cmp(a));
168        other_values.sort_by(|a, b| b.cmp(a));
169
170        let min_len = self_values.len().min(other_values.len());
171        for i in 0..min_len {
172            if self_values[i] != other_values[i] {
173                return self_values[i] - other_values[i];
174            }
175        }
176        0
177    }
178}
179
180struct Game {
181    cards: Vec<CardType>,
182    hands: Vec<Hand>,
183}
184
185impl Game {
186    fn new() -> Self {
187        Game { cards: Vec::new(), hands: Vec::new() }
188    }
189
190    fn add_card(&mut self, suit: &str, value: &str) {
191        self.cards.push(CardType::Playing(PlayingCard::new(suit, value)));
192    }
193
194    fn add_joker(&mut self, color: &str) {
195        self.cards.push(CardType::Joker(Joker::new(color)));
196    }
197
198    fn add_hand(&mut self, card_indices: Vec<usize>) {
199        let hand_cards: Vec<&CardType> = card_indices.iter().map(|&i| &self.cards[i]).collect();
200        self.hands.push(Hand::new(&hand_cards));
201    }
202
203    fn hand_string(&self, hand: usize) -> String {
204        self.hands[hand].to_string()
205    }
206
207    fn hand_beats(&self, hand_a: usize, hand_b: usize) -> bool {
208        self.hands[hand_a].compare_to(&self.hands[hand_b]) > 0
209    }
210}
211
212fn main() -> Result<(), Box<dyn error::Error>> {
213    let stdin = stdin();
214    let mut lines = stdin.lock().lines();
215    let mut game = Game::new();
216    let mut i = 0;
217    let mut end = 0;
218    for hand in 0..2 {
219        let mut hand_list: Vec<usize> = Vec::new();
220        let n: usize = lines.next().unwrap().unwrap().trim().parse().unwrap();
221        end += n;
222        while i < end {
223            let line = lines.next().unwrap().unwrap();
224            let parts: Vec<&str> = line.split_whitespace().collect();
225            if parts[0] == "Joker" {
226                game.add_joker(parts[1]);
227            } else {
228                game.add_card(parts[0], parts[1]);
229            }
230            hand_list.push(i);
231            i += 1;
232        }
233        game.add_hand(hand_list);
234        println!("{}", game.hand_string(hand));
235    }
236    println!("{}", game.hand_beats(0, 1));
237    Ok(())
238}
239
1package main
2
3import (
4    "bufio"
5    "fmt"
6    "os"
7    "sort"
8    "strconv"
9    "strings"
10)
11
12type Card interface {
13    CardValue() int
14    String() string
15}
16
17type Suit int
18
19const (
20    Clubs Suit = iota
21    Diamonds
22    Hearts
23    Spades
24)
25
26type JokerColor int
27
28const (
29    Red JokerColor = iota
30    Black
31)
32
33var (
34    SUITS = map[string]Suit{
35        "Clubs":    Clubs,
36        "Diamonds": Diamonds,
37        "Hearts":   Hearts,
38        "Spades":   Spades,
39    }
40
41    SUIT_NAMES = map[Suit]string{
42        Clubs:    "Clubs",
43        Diamonds: "Diamonds",
44        Hearts:   "Hearts",
45        Spades:   "Spades",
46    }
47
48    VALUES = map[string]int{
49        "A": 1,
50        "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
51        "J": 11,
52        "Q": 12,
53        "K": 13,
54    }
55
56    VALUE_NAMES = map[int]string{
57        1: "A", 2: "2", 3: "3", 4: "4", 5: "5", 6: "6", 7: "7", 8: "8", 9: "9", 10: "10",
58        11: "J", 12: "Q", 13: "K",
59    }
60
61    JOKER_COLORS = map[string]JokerColor{
62        "Red":   Red,
63        "Black": Black,
64    }
65
66    JOKER_COLOR_NAMES = map[JokerColor]string{
67        Red:   "Red",
68        Black: "Black",
69    }
70)
71
72type PlayingCard struct {
73    suit  Suit
74    value int
75}
76
77func NewPlayingCard(suit string, value string) *PlayingCard {
78    return &PlayingCard{
79        suit:  SUITS[suit],
80        value: VALUES[value],
81    }
82}
83
84func (pc *PlayingCard) CardValue() int {
85    return pc.value
86}
87
88func (pc *PlayingCard) String() string {
89    return fmt.Sprintf("%s of %s", VALUE_NAMES[pc.value], SUIT_NAMES[pc.suit])
90}
91
92type Joker struct {
93    color JokerColor
94}
95
96func NewJoker(color string) *Joker {
97    return &Joker{
98        color: JOKER_COLORS[color],
99    }
100}
101
102func (j *Joker) CardValue() int {
103    return 14
104}
105
106func (j *Joker) String() string {
107    return fmt.Sprintf("%s Joker", JOKER_COLOR_NAMES[j.color])
108}
109
110type Hand struct {
111    cards []Card
112}
113
114func NewHand(cards []Card) *Hand {
115    cardsCopy := make([]Card, len(cards))
116    copy(cardsCopy, cards)
117    return &Hand{cards: cardsCopy}
118}
119
120func (h *Hand) String() string {
121    strs := make([]string, len(h.cards))
122    for i, c := range h.cards {
123        strs[i] = c.String()
124    }
125    return strings.Join(strs, ", ")
126}
127
128func (h *Hand) CompareTo(other *Hand) int {
129    selfValues := make([]int, len(h.cards))
130    for i, c := range h.cards {
131        selfValues[i] = c.CardValue()
132    }
133    otherValues := make([]int, len(other.cards))
134    for i, c := range other.cards {
135        otherValues[i] = c.CardValue()
136    }
137
138    sort.Sort(sort.Reverse(sort.IntSlice(selfValues)))
139    sort.Sort(sort.Reverse(sort.IntSlice(otherValues)))
140
141    minLen := len(selfValues)
142    if len(otherValues) < minLen {
143        minLen = len(otherValues)
144    }
145
146    for i := 0; i < minLen; i++ {
147        if selfValues[i] != otherValues[i] {
148            return selfValues[i] - otherValues[i]
149        }
150    }
151    return 0
152}
153
154type Game struct {
155    cards []Card
156    hands []*Hand
157}
158
159func NewGame() *Game {
160    return &Game{
161        cards: make([]Card, 0),
162        hands: make([]*Hand, 0),
163    }
164}
165
166func (g *Game) addCard(suit string, value string) {
167    g.cards = append(g.cards, NewPlayingCard(suit, value))
168}
169
170func (g *Game) cardString(card int) string {
171    return g.cards[card].String()
172}
173
174func (g *Game) cardBeats(cardA int, cardB int) bool {
175    return g.cards[cardA].CardValue() > g.cards[cardB].CardValue()
176}
177
178func (g *Game) addJoker(color string) {
179    g.cards = append(g.cards, NewJoker(color))
180}
181
182func (g *Game) addHand(cardIndices []int) {
183    handCards := make([]Card, len(cardIndices))
184    for i, idx := range cardIndices {
185        handCards[i] = g.cards[idx]
186    }
187    g.hands = append(g.hands, NewHand(handCards))
188}
189
190func (g *Game) handString(hand int) string {
191    return g.hands[hand].String()
192}
193
194func (g *Game) handBeats(handA int, handB int) bool {
195    return g.hands[handA].CompareTo(g.hands[handB]) > 0
196}
197
198func main() {
199    scanner := bufio.NewScanner(os.Stdin)
200    game := &Game{}
201    i := 0
202    end := 0
203    for hand := 0; hand < 2; hand++ {
204        handList := []int{}
205        scanner.Scan()
206        n, _ := strconv.Atoi(scanner.Text())
207        end += n
208        for ; i < end; i++ {
209            scanner.Scan()
210            segs := strings.Fields(scanner.Text())
211            if segs[0] == "Joker" {
212                game.addJoker(segs[1])
213            } else {
214                game.addCard(segs[0], segs[1])
215            }
216            handList = append(handList, i)
217        }
218        game.addHand(handList)
219        fmt.Println(game.handString(hand))
220    }
221    fmt.Println(game.handBeats(0, 1))
222}
223
1class Card
2  def card_value
3    raise NotImplementedError
4  end
5end
6
7class Suit
8  CLUBS = :clubs
9  DIAMONDS = :diamonds
10  HEARTS = :hearts
11  SPADES = :spades
12end
13
14class JokerColor
15  RED = :red
16  BLACK = :black
17end
18
19class PlayingCard < Card
20  SUITS = {
21    "Clubs" => Suit::CLUBS,
22    "Diamonds" => Suit::DIAMONDS,
23    "Hearts" => Suit::HEARTS,
24    "Spades" => Suit::SPADES
25  }
26
27  SUIT_NAMES = SUITS.invert
28
29  VALUES = {
30    "A" => 1,
31    "2" => 2, "3" => 3, "4" => 4, "5" => 5, "6" => 6, "7" => 7, "8" => 8, "9" => 9, "10" => 10,
32    "J" => 11,
33    "Q" => 12,
34    "K" => 13
35  }
36
37  VALUE_NAMES = VALUES.invert
38
39  def initialize(suit, value)
40    @suit = SUITS[suit]
41    @value = VALUES[value]
42  end
43
44  def card_value
45    @value
46  end
47
48  def to_s
49    "#{VALUE_NAMES[@value]} of #{SUIT_NAMES[@suit]}"
50  end
51end
52
53class Joker < Card
54  COLORS = {
55    "Red" => JokerColor::RED,
56    "Black" => JokerColor::BLACK
57  }
58
59  COLOR_NAMES = COLORS.invert
60
61  def initialize(color)
62    @color = COLORS[color]
63  end
64
65  def card_value
66    14
67  end
68
69  def to_s
70    "#{COLOR_NAMES[@color]} Joker"
71  end
72end
73
74class Hand
75  def initialize(cards)
76    @cards = cards.dup
77  end
78
79  def to_s
80    @cards.map(&:to_s).join(", ")
81  end
82
83  def <=>(other)
84    self_cards = @cards.sort_by(&:card_value).reverse
85    other_cards = other.instance_variable_get(:@cards).sort_by(&:card_value).reverse
86
87    [self_cards.length, other_cards.length].min.times do |i|
88      diff = self_cards[i].card_value - other_cards[i].card_value
89      return diff if diff != 0
90    end
91    0
92  end
93
94  protected
95  attr_reader :cards
96end
97
98class Game
99  def initialize
100    @cards = []
101    @hands = []
102  end
103
104  def add_card(suit, value)
105    @cards << PlayingCard.new(suit, value)
106  end
107
108  def card_string(card)
109    @cards[card].to_s
110  end
111
112  def card_beats(card_a, card_b)
113    @cards[card_a].card_value > @cards[card_b].card_value
114  end
115
116  def add_joker(color)
117    @cards << Joker.new(color)
118  end
119
120  def add_hand(card_indices)
121    hand_cards = card_indices.map { |i| @cards[i] }
122    @hands << Hand.new(hand_cards)
123  end
124
125  def hand_string(hand)
126    @hands[hand].to_s
127  end
128
129  def hand_beats(hand_a, hand_b)
130    (@hands[hand_a] <=> @hands[hand_b]) > 0
131  end
132end
133
134if __FILE__ == $0
135  game = Game.new
136  i = 0
137  end_idx = 0
138  for hand in 0...2
139    hand_list = []
140    end_idx += gets.to_i
141    while i < end_idx
142      suit, value = gets.split
143      if suit == "Joker"
144        game.add_joker(value)
145      else
146        game.add_card(suit, value)
147      end
148      hand_list << i
149      i += 1
150    end
151    game.add_hand(hand_list)
152    puts game.hand_string(hand)
153  end
154  puts game.hand_beats(0, 1)
155end
156
1#lang racket
2
3(struct playing-card (suit value) #:transparent)
4(struct joker-card (color) #:transparent)
5(struct hand (cards) #:transparent)
6
7(define suits
8  (hash "Clubs" 'clubs "Diamonds" 'diamonds "Hearts" 'hearts "Spades" 'spades))
9
10(define suit-names
11  (hash 'clubs "Clubs" 'diamonds "Diamonds" 'hearts "Hearts" 'spades "Spades"))
12
13(define values
14  (hash "A" 1 "2" 2 "3" 3 "4" 4 "5" 5 "6" 6 "7" 7 "8" 8 "9" 9 "10" 10
15        "J" 11 "Q" 12 "K" 13))
16
17(define value-names
18  (hash 1 "A" 2 "2" 3 "3" 4 "4" 5 "5" 6 "6" 7 "7" 8 "8" 9 "9" 10 "10"
19        11 "J" 12 "Q" 13 "K"))
20
21(define joker-colors
22  (hash "Red" 'red "Black" 'black))
23
24(define joker-color-names
25  (hash 'red "Red" 'black "Black"))
26
27(define (parse-suit s)
28  (hash-ref suits s))
29
30(define (parse-value v)
31  (hash-ref values v))
32
33(define (parse-joker-color c)
34  (hash-ref joker-colors c))
35
36(define (card-value card)
37  (cond
38    [(playing-card? card) (playing-card-value card)]
39    [(joker-card? card) 14]))
40
41(define (card->string card)
42  (cond
43    [(playing-card? card)
44     (format "~a of ~a"
45             (hash-ref value-names (playing-card-value card))
46             (hash-ref suit-names (playing-card-suit card)))]
47    [(joker-card? card)
48     (format "~a Joker"
49             (hash-ref joker-color-names (joker-card-color card)))]))
50
51(define (hand->string h)
52  (string-join (map card->string (hand-cards h)) ", "))
53
54(define (hand-compare a b)
55  (let ([a-vals (sort (map card-value (hand-cards a)) >)]
56        [b-vals (sort (map card-value (hand-cards b)) >)])
57    (let loop ([av a-vals] [bv b-vals])
58      (cond
59        [(or (null? av) (null? bv)) 0]
60        [(not (= (car av) (car bv))) (- (car av) (car bv))]
61        [else (loop (cdr av) (cdr bv))]))))
62
63(struct game (cards hands) #:transparent #:mutable)
64
65(define (make-game)
66  (game '() '()))
67
68(define (add-card! g suit value)
69  (set-game-cards! g
70    (append (game-cards g)
71            (list (playing-card (parse-suit suit) (parse-value value))))))
72
73(define (add-joker! g color)
74  (set-game-cards! g
75    (append (game-cards g)
76            (list (joker-card (parse-joker-color color))))))
77
78(define (game-card-string g idx)
79  (card->string (list-ref (game-cards g) idx)))
80
81(define (game-card-beats? g idx-a idx-b)
82  (> (card-value (list-ref (game-cards g) idx-a))
83     (card-value (list-ref (game-cards g) idx-b))))
84
85(define (add-hand! g card-indices)
86  (let ([hand-cards (map (lambda (i) (list-ref (game-cards g) i)) card-indices)])
87    (set-game-hands! g (append (game-hands g) (list (hand hand-cards))))))
88
89(define (game-hand-string g idx)
90  (hand->string (list-ref (game-hands g) idx)))
91
92(define (game-hand-beats? g idx-a idx-b)
93  (> (hand-compare (list-ref (game-hands g) idx-a)
94                   (list-ref (game-hands g) idx-b)) 0))
95
96(define g (make-game))
97(define i 0)
98(define end-idx 0)
99(for ([hand-num (in-range 2)])
100  (define hand-list '())
101  (set! end-idx (+ end-idx (string->number (read-line))))
102  (let loop ()
103    (when (< i end-idx)
104      (define parts (string-split (read-line)))
105      (if (equal? (first parts) "Joker")
106          (add-joker! g (second parts))
107          (add-card! g (first parts) (second parts)))
108      (set! hand-list (append hand-list (list i)))
109      (set! i (+ i 1))
110      (loop)))
111  (add-hand! g hand-list)
112  (displayln (game-hand-string g hand-num)))
113(displayln (if (game-hand-beats? g 0 1) "true" "false"))
114
1import Data.IORef (modifyIORef, newIORef, readIORef)
2import Data.List (intercalate, sortBy)
3import qualified Data.Map as M
4
5data Suit = Clubs | Diamonds | Hearts | Spades deriving (Eq, Ord, Show)
6data JokerColor = Red | Black deriving (Eq, Ord, Show)
7
8data Card = PlayingCard Suit Int
9          | JokerCard JokerColor
10
11data Hand = Hand [Card]
12
13suits :: M.Map String Suit
14suits = M.fromList [("Clubs", Clubs), ("Diamonds", Diamonds), ("Hearts", Hearts), ("Spades", Spades)]
15
16suitNames :: M.Map Suit String
17suitNames = M.fromList [(Clubs, "Clubs"), (Diamonds, "Diamonds"), (Hearts, "Hearts"), (Spades, "Spades")]
18
19values :: M.Map String Int
20values = M.fromList [("A", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10), ("J", 11), ("Q", 12), ("K", 13)]
21
22valueNames :: M.Map Int String
23valueNames = M.fromList [(1, "A"), (2, "2"), (3, "3"), (4, "4"), (5, "5"), (6, "6"), (7, "7"), (8, "8"), (9, "9"), (10, "10"), (11, "J"), (12, "Q"), (13, "K")]
24
25jokerColors :: M.Map String JokerColor
26jokerColors = M.fromList [("Red", Red), ("Black", Black)]
27
28jokerColorNames :: M.Map JokerColor String
29jokerColorNames = M.fromList [(Red, "Red"), (Black, "Black")]
30
31parseSuit :: String -> Suit
32parseSuit s = suits M.! s
33
34parseValue :: String -> Int
35parseValue v = values M.! v
36
37parseJokerColor :: String -> JokerColor
38parseJokerColor c = jokerColors M.! c
39
40cardValue :: Card -> Int
41cardValue (PlayingCard _ v) = v
42cardValue (JokerCard _) = 14
43
44cardToString :: Card -> String
45cardToString (PlayingCard s v) = (valueNames M.! v) ++ " of " ++ (suitNames M.! s)
46cardToString (JokerCard c) = (jokerColorNames M.! c) ++ " Joker"
47
48makeCard :: String -> String -> Card
49makeCard suit value = PlayingCard (parseSuit suit) (parseValue value)
50
51makeJoker :: String -> Card
52makeJoker color = JokerCard (parseJokerColor color)
53
54makeHand :: [Card] -> Hand
55makeHand cards = Hand cards
56
57handToString :: Hand -> String
58handToString (Hand cards) = intercalate ", " (map cardToString cards)
59
60handCompare :: Hand -> Hand -> Ordering
61handCompare (Hand aCards) (Hand bCards) =
62  let aVals = sortBy (flip compare) (map cardValue aCards)
63      bVals = sortBy (flip compare) (map cardValue bCards)
64      compareVals [] [] = EQ
65      compareVals [] _ = EQ
66      compareVals _ [] = EQ
67      compareVals (x:xs) (y:ys)
68        | x > y = GT
69        | x < y = LT
70        | otherwise = compareVals xs ys
71  in compareVals aVals bVals
72
73handBeats :: Hand -> Hand -> Bool
74handBeats a b = handCompare a b == GT
75
76main :: IO ()
77main = do
78  cardsRef <- newIORef []
79  handsRef <- newIORef []
80  let processHands :: Int -> Int -> IO ()
81      processHands 0 _ = return ()
82      processHands remaining offset = do
83          nStr <- getLine
84          let n = read nStr :: Int
85          let loop i cards
86                | i >= offset + n = return (cards, i)
87                | otherwise = do
88                    line <- getLine
89                    let parts = words line
90                    let card = if head parts == "Joker"
91                               then makeJoker (parts !! 1)
92                               else makeCard (head parts) (parts !! 1)
93                    modifyIORef cardsRef (++ [card])
94                    loop (i + 1) (cards ++ [card])
95          (handCards, newOffset) <- loop offset []
96          let h = makeHand handCards
97          modifyIORef handsRef (++ [h])
98          putStrLn $ handToString h
99          processHands (remaining - 1) newOffset
100  processHands 2 0
101  hands <- readIORef handsRef
102  putStrLn $ if handBeats (hands !! 0) (hands !! 1) then "true" else "false"
103

add_hand is to initialize a Hand instance; it uses O(n) time complexity and stores the list of cards using O(n) space, where n is the number of cards given to the hand. both hand_string and hand_beats take O(1) space. hand_string takes O(1) time and hand_beats takes O(min(n,m)) time where n and m are the size of the two hands respectively.

Invest in Yourself
Your new job is waiting. 83% of people that complete the program get a job offer. Unlock unlimited access to all content and features.
Go Pro