class Player(object):
def __init__(self, deck):
self.deck = deck
self.battlefield = []
@property
def alive(self):
return bool(self.deck)
@property
def last_played(self):
return self.battlefield[-1][-1] if self.battlefield else None
def play(self, cards):
self.battlefield.append(self.deck[:cards])
del self.deck[:cards]
def battle(self, other):
self.play(1)
other.play(1)
def war(self, other):
length = min(4, len(self.deck), len(other.deck))
self.play(length)
other.play(length)
def ties(self, other):
return self.last_played == other.last_played
def beats(self, other):
return self.last_played > other.last_played
def claim(self, other):
while self.battlefield:
self.deck.extend(self.battlefield.pop())
self.deck.extend(other.battlefield.pop())
assert self.battlefield == other.battlefield == []
def _who_wins(deck_1, deck_2):
p1, p2 = Player(deck_1), Player(deck_2)
while p1.alive and p2.alive:
if p1.last_played is None:
p1.battle(p2)
if p1.ties(p2):
p1.war(p2)
if not p1.ties(p2):
winner, loser = (p1, p2) if p1.beats(p2) else (p2, p1)
winner.claim(loser)
return 1 if p1.alive else 2 if p2.alive else 0
def war(decks_text):
decks = (map(int, line.split()) for line in decks_text.splitlines())
return _who_wins(*decks)
# Testing
tests = (
'''5 1 13 10 11 3 2 10 4 12 5 11 10 5 7 6 6 11 9 6 3 13 6 1 8 1
9 12 8 3 11 10 1 4 2 4 7 9 13 8 2 13 7 4 2 8 9 12 3 12 7 5''',
'''3 11 6 12 2 13 5 7 10 3 10 4 12 11 1 13 12 2 1 7 10 6 12 5 8 1
9 10 7 9 5 2 6 1 11 11 7 9 3 4 8 3 4 8 8 4 6 9 13 2 13 5''',
'''1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13
1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 9 10 11 12 13''',
)
for test in tests:
print war(test)
Y2xhc3MgUGxheWVyKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgZGVjayk6CiAgICAgICAgc2VsZi5kZWNrID0gZGVjawogICAgICAgIHNlbGYuYmF0dGxlZmllbGQgPSBbXQoKICAgIEBwcm9wZXJ0eQogICAgZGVmIGFsaXZlKHNlbGYpOgogICAgICAgIHJldHVybiBib29sKHNlbGYuZGVjaykKCiAgICBAcHJvcGVydHkKICAgIGRlZiBsYXN0X3BsYXllZChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5iYXR0bGVmaWVsZFstMV1bLTFdIGlmIHNlbGYuYmF0dGxlZmllbGQgZWxzZSBOb25lCgogICAgZGVmIHBsYXkoc2VsZiwgY2FyZHMpOgogICAgICAgIHNlbGYuYmF0dGxlZmllbGQuYXBwZW5kKHNlbGYuZGVja1s6Y2FyZHNdKQogICAgICAgIGRlbCBzZWxmLmRlY2tbOmNhcmRzXQoKICAgIGRlZiBiYXR0bGUoc2VsZiwgb3RoZXIpOgogICAgICAgIHNlbGYucGxheSgxKQogICAgICAgIG90aGVyLnBsYXkoMSkKCiAgICBkZWYgd2FyKHNlbGYsIG90aGVyKToKICAgICAgICBsZW5ndGggPSBtaW4oNCwgbGVuKHNlbGYuZGVjayksIGxlbihvdGhlci5kZWNrKSkKICAgICAgICBzZWxmLnBsYXkobGVuZ3RoKQogICAgICAgIG90aGVyLnBsYXkobGVuZ3RoKQoKICAgIGRlZiB0aWVzKHNlbGYsIG90aGVyKToKICAgICAgICByZXR1cm4gc2VsZi5sYXN0X3BsYXllZCA9PSBvdGhlci5sYXN0X3BsYXllZAoKICAgIGRlZiBiZWF0cyhzZWxmLCBvdGhlcik6CiAgICAgICAgcmV0dXJuIHNlbGYubGFzdF9wbGF5ZWQgPiBvdGhlci5sYXN0X3BsYXllZAoKICAgIGRlZiBjbGFpbShzZWxmLCBvdGhlcik6CiAgICAgICAgd2hpbGUgc2VsZi5iYXR0bGVmaWVsZDoKICAgICAgICAgICAgc2VsZi5kZWNrLmV4dGVuZChzZWxmLmJhdHRsZWZpZWxkLnBvcCgpKQogICAgICAgICAgICBzZWxmLmRlY2suZXh0ZW5kKG90aGVyLmJhdHRsZWZpZWxkLnBvcCgpKQogICAgICAgIGFzc2VydCBzZWxmLmJhdHRsZWZpZWxkID09IG90aGVyLmJhdHRsZWZpZWxkID09IFtdCgoKZGVmIF93aG9fd2lucyhkZWNrXzEsIGRlY2tfMik6CiAgICBwMSwgcDIgPSBQbGF5ZXIoZGVja18xKSwgUGxheWVyKGRlY2tfMikKICAgIHdoaWxlIHAxLmFsaXZlIGFuZCBwMi5hbGl2ZToKICAgICAgICBpZiBwMS5sYXN0X3BsYXllZCBpcyBOb25lOgogICAgICAgICAgICBwMS5iYXR0bGUocDIpCiAgICAgICAgaWYgcDEudGllcyhwMik6CiAgICAgICAgICAgIHAxLndhcihwMikKICAgICAgICBpZiBub3QgcDEudGllcyhwMik6CiAgICAgICAgICAgIHdpbm5lciwgbG9zZXIgPSAocDEsIHAyKSBpZiBwMS5iZWF0cyhwMikgZWxzZSAocDIsIHAxKQogICAgICAgICAgICB3aW5uZXIuY2xhaW0obG9zZXIpCiAgICByZXR1cm4gMSBpZiBwMS5hbGl2ZSBlbHNlIDIgaWYgcDIuYWxpdmUgZWxzZSAwCiAgICAgICAgICAgIAogICAgICAgICAgICAKZGVmIHdhcihkZWNrc190ZXh0KToKICAgIGRlY2tzID0gKG1hcChpbnQsIGxpbmUuc3BsaXQoKSkgZm9yIGxpbmUgaW4gZGVja3NfdGV4dC5zcGxpdGxpbmVzKCkpCiAgICByZXR1cm4gX3dob193aW5zKCpkZWNrcykKCiMgVGVzdGluZwoKdGVzdHMgPSAoCiAgICAnJyc1IDEgMTMgMTAgMTEgMyAyIDEwIDQgMTIgNSAxMSAxMCA1IDcgNiA2IDExIDkgNiAzIDEzIDYgMSA4IDEgCjkgMTIgOCAzIDExIDEwIDEgNCAyIDQgNyA5IDEzIDggMiAxMyA3IDQgMiA4IDkgMTIgMyAxMiA3IDUnJycsCiAgICAnJyczIDExIDYgMTIgMiAxMyA1IDcgMTAgMyAxMCA0IDEyIDExIDEgMTMgMTIgMiAxIDcgMTAgNiAxMiA1IDggMSAKOSAxMCA3IDkgNSAyIDYgMSAxMSAxMSA3IDkgMyA0IDggMyA0IDggOCA0IDYgOSAxMyAyIDEzIDUnJycsCiAgICAnJycxIDIgMyA0IDUgNiA3IDggOSAxMCAxMSAxMiAxMyAxIDIgMyA0IDUgNiA3IDggOSAxMCAxMSAxMiAxMyAKMSAyIDMgNCA1IDYgNyA4IDkgMTAgMTEgMTIgMTMgMSAyIDMgNCA1IDYgNyA4IDkgMTAgMTEgMTIgMTMnJycsCikKCmZvciB0ZXN0IGluIHRlc3RzOgogICAgcHJpbnQgd2FyKHRlc3Qp