https://projecteuler.net/problem=54
各役をC++のように基底クラスを継承したいのですが、どうやったらいいのでしょうね。同じくTraitを使うRustは頑張れば同じVecに入れられるのですが、MojoだとListに入れられるのでしょうか。
import sys #################### List #################### trait Printable(CollectionElement, Stringable): pass fn print_list[T: Printable](a: List[T]): if a.size > 0: var s = "[" + str(a[0]) for i in range(1, a.size): s += ", " + str(a[i]) s += "]" print(s) else: print("[]") fn reverse_list[T: CollectionElement](a: List[T]) -> List[T]: var b = List[T]() for i in range(len(a) - 1, -1, -1): b.append(a[i]) return b #################### Card #################### @value struct Card: var suit: String var number: Int @staticmethod fn create(s: String) raises -> Card: var suit = s[1] if s[0] == 'T': return Card(suit, 10) elif s[0] == 'J': return Card(suit, 11) elif s[0] == 'Q': return Card(suit, 12) elif s[0] == 'K': return Card(suit, 13) elif s[0] == 'A': return Card(suit, 14) else: var num = atol(s[0]) return Card(suit, num) #################### Rank #################### @value struct Rank: var freq: List[Int] var rank: Int fn __init__(inout self, freq: List[Int], name: String): self.freq = freq if name == "HighCard": self.rank = 1 elif name == "OnePair": self.rank = 2 elif name == "TwoPairs": self.rank = 3 elif name == "ThreeCard": self.rank = 4 elif name == "Straight": self.rank = 5 elif name == "Flush": self.rank = 6 elif name == "FullHouse": self.rank = 7 elif name == "FourCards": self.rank = 8 elif name == "StraightFlush": self.rank = 9 else: self.rank = 10 fn sum_cards(self) -> Int: var s = 0 for elem in self.freq: var num = elem[] & 15 var f = elem[] >> 4 s += num * f return s fn __gt__(self, other: Rank) -> Bool: if self.rank != other.rank: return self.rank > other.rank for i in range(len(self.freq)): if self.freq[i] != other.freq[i]: return self.freq[i] > other.freq[i] else: return False @staticmethod fn create(hand: Hand) -> Rank: var freq = hand.frequency() if hand.is_straight(): if hand.is_flush(): if hand.sum() == 60: return Rank(freq, "RolyalFlush") else: return Rank(freq, "StraightFlush") else: return Rank(freq, "Straight") elif hand.is_flush(): return Rank(freq, "Flush") elif len(freq) == 5: return Rank(freq, "HighCard") elif len(freq) == 4: return Rank(freq, "OnePair") elif len(freq) == 3: if (freq[0] & 15) == 2: return Rank(freq, "TwoPairs") else: return Rank(freq, "ThreeCard") else: if (freq[0] & 15) == 3: return Rank(freq, "FullHouse") else: return Rank(freq, "FourCards") #################### Hand #################### @value struct Hand: var cards: List[Card] fn frequency(self) -> List[Int]: var s = 0 for card in self.cards: s += 1 << (3 * card[].number) # [num + (freq << 4)] var freq = List[Int]() for num in range(2, 15): var f = (s >> (num * 3)) & 7 if f != 0: freq.append(num + (f << 4)) sort(freq) return reverse_list(freq) fn is_flush(self) -> Bool: for card in self.cards: if card[].suit != self.cards[0].suit: return False else: return True fn is_straight(self) -> Bool: var s = 0 for card in self.cards: s |= 1 << card[].number while (s & 1) == 0: s >>= 1 return s == 31 fn sum(self) -> Int: var s = 0 for card in self.cards: s += card[].number return s fn compare_straight(self, other: Hand) -> Bool: var bf1 = self.is_flush() var bf2 = other.is_flush() if bf1 == bf2: return self.sum() > other.sum() else: return bf1 fn __gt__(self, other: Hand) -> Bool: var rank1 = Rank.create(self) var rank2 = Rank.create(other) return rank1 > rank2 @staticmethod fn read(path: String) -> List[Hand]: try: var hands = List[Hand]() with open(path, "r") as f: var data = f.read() var lines = data.split("\n") for line in lines: if line[] == "": break var v = line[].split(" ") hands.append(Hand.create(v[:5])) hands.append(Hand.create(v[5:])) return hands except: return List[Hand]() @staticmethod fn create(v: List[String]) raises -> Hand: var cards = List[Card]() for s in v: cards.append(Card.create(s[])) return Hand(cards) #################### process #################### fn f(path: String) -> Int: var hands = Hand.read(path) var counter = 0 for i in range(0, len(hands), 2): if hands[i] > hands[i+1]: counter += 1 return counter fn main() raises: var args = sys.argv() var path = args[1] print(f(path))