Еще один быстрый сегодня. Просто несколько простых старых манипуляций с списком питона и рекурсии
Ссылка на вызов на веб -сайте Advent of Code 2020
Задача включает в себя разыгрывание карточной игры, которая имеет простой набор правил. Таким образом, включает в себя отслеживание двух стеков карт. Правила просты: оба игрока играют в одну карту с вершины своей колоды, выигрыш с самыми высокими картами, победившая игрок сохраняет обе карты.
Решение
Начиная с импорта без излишеств: просто разделить данные вручную, чтобы сэкономить время, и поднять все на INTS
data = open("input.txt").read().splitlines() player1 = list(map(int, data[1:26])) player2 = list(map(int, data[28:54]))
Тогда в значительной степени просто цикл, пока один игрок не пуст, используя .pop ()
удалить элемент из списка
while player1 and player2: card1 = player1.pop(0) card2 = player2.pop(0) if card1 > card2: player1.extend([card1, card2]) else: player2.extend([card2, card1])
Наконец, рассчитайте сумму в соответствии с правилами задачи: последняя карта стоит 1, следующая стоит 2 и т. Д.
win = player1 if player1 else player2 print("sum", sum((a+1) * b for a, b in enumerate(reversed(win))))
Полный код для решения для части 1:
data = open("input.txt").read().splitlines() player1 = list(map(int, data[1:26])) player2 = list(map(int, data[28:54])) while player1 and player2: card1 = player1.pop(0) card2 = player2.pop(0) if card1 > card2: player1.extend([card1, card2]) else: player2.extend([card2, card1]) win = player1 if player1 else player2 print("sum", sum((a+1) * b for a, b in enumerate(reversed(win))))
Задача, часть 2
Во 2 -й части вызова правила игры расширяются, чтобы включать рекурсивный вызов, где в определенные моменты во время игры подмножество карт используется для игры в другую, меньшую игру, чтобы определить победителя. Сама подгруппа может появиться в дальнейших играх.
Существует также дополнительное положение для записи каждой руки подгруппы и прерывать, если он начинает цикл.
Итак … нам нужно отслеживать руки. Поскольку DICTS – это (1) поиск, мы будем использовать это, и мы просто задаем твердые (так как это удобно).
Здесь мы возвращаем 0 для победы Player1 (как того требует правила)
def game(player1, player2): records = {} while player1 and player2: key = str(player1)+str(player2) if key in records: return 0 records[key] = None ...
Далее мы добавляем дополнительное правило игры для повторения в подгры и возвращаем победителя. В подмножестве используется подмножество карт, которое генерируется с использованием среза. Это копирует список, поэтому он оставляет оригинал нетронутым, что желательно. Остальные правила игры одинаковы
card1 = player1.pop(0) card2 = player2.pop(0) if len(player1) >= card1 and len(player2) >= card2: winner = game(player1[:card1], player2[:card2]) else: winner = card2 > card1 if winner: player2.extend([card2, card1]) else: player1.extend([card1, card2])
Полный цикл выглядит так:
def game(player1, player2): records = {} while player1 and player2: key = str(player1)+str(player2) if key in records: return 0 records[key] = None card1 = player1.pop(0) card2 = player2.pop(0) if len(player1) >= card1 and len(player2) >= card2: winner = game(player1[:card1], player2[:card2]) else: winner = card2 > card1 if winner: player2.extend([card2, card1]) else: player1.extend([card1, card2]) return winner winner = game(player1, player2)
К сожалению, эта функция возвращается, кто выиграл, но нам действительно нужна их рука, поэтому давайте сделаем небольшую регулировку, чтобы вывести последнюю победную руку, и это наше решение.
Полный код:
data = open("input.txt").read().splitlines() player1 = list(map(int, data[1:26])) player2 = list(map(int, data[28:54])) def game(depth, player1, player2): records = {} while player1 and player2: key = str(player1)+str(player2) if key in records: return 0 records[key] = None card1 = player1.pop(0) card2 = player2.pop(0) if len(player1) >= card1 and len(player2) >= card2: winner = game(depth+1, player1[:card1], player2[:card2]) else: winner = card2 > card1 if winner: player2.extend([card2, card1]) else: player1.extend([card1, card2]) if depth == 0: return (player2 if winner else player1) return winner windeck = game(0, player1, player2) print("sum", sum((a+1) * b for a, b in enumerate(reversed(windeck ))))
Все сделано. Впереди!
Оригинал: “https://dev.to/meseta/advent-of-code-day-22-263i”