added rest of the code

This commit is contained in:
Peter Hudec
2016-08-08 07:32:56 +02:00
parent 6e366d7ade
commit a9ceb0715a
26 changed files with 1244 additions and 0 deletions

3
21/input Normal file
View File

@ -0,0 +1,3 @@
Hit Points: 109
Damage: 8
Armor: 2

111
21/part1.py Normal file
View File

@ -0,0 +1,111 @@
#!/usr/bin/python
import re
from math import ceil
RE_STORE_HEADER = re.compile(r'^(.*):.*$')
RE_STORE_ITEM = re.compile(r'^(.*)\s+(\d+)\s+(\d+)\s+(\d+)')
RE_INPUT = re.compile(r'^(.*):\s+(\d+)$')
def read_file(filename):
file = open(filename, 'r')
while True:
line = file.readline()
if not line:
break
yield line
def simulate(me, boss):
myWinTurns = 0
bossWinTurns = 0
myWinTurns = int(ceil(boss['Hit Points'] / max(1, me['Damage'] - boss['Armor'])))
bossWinTurns = int(ceil(me['Hit Points'] / max(1, boss['Damage'] - me['Armor'])))
return(myWinTurns, bossWinTurns)
def calculate_possible_combinations(minSum, maxSum, pos, usage):
if pos == len(usage):
if sum(usage) >= minSum and sum(usage) <= maxSum:
yield usage
return
for x in range(2):
usage[pos] = x
for c in calculate_possible_combinations(minSum, maxSum, pos+1, usage):
yield c
usage[pos] = 0
def calculate_sum_product(item, usage, key):
sum = 0
for x in range(len(item)):
sum += item[x][key]*usage[x]
return sum
def buy(store):
# 1 Weapon
# 0-1 Armor
# 0-2 Rings
weapons = [0 for x in range(len(store['Weapons']))]
armor = [0 for x in range(len(store['Armor']))]
rings = [0 for x in range(len(store['Rings']))]
for w in calculate_possible_combinations(1, 1, 0, weapons):
for a in calculate_possible_combinations(0, 1, 0, armor):
for r in calculate_possible_combinations(0, 2, 0, rings):
costS = calculate_sum_product(store['Weapons'], w, 'Cost')
costS += calculate_sum_product(store['Armor'], a, 'Cost')
costS += calculate_sum_product(store['Rings'], r, 'Cost')
armorS = calculate_sum_product(store['Weapons'], w, 'Armor')
armorS += calculate_sum_product(store['Armor'], a, 'Armor')
armorS += calculate_sum_product(store['Rings'], r, 'Armor')
damageS = calculate_sum_product(store['Weapons'], w, 'Damage')
damageS += calculate_sum_product(store['Armor'], a, 'Damage')
damageS += calculate_sum_product(store['Rings'], r, 'Damage')
yield (costS, damageS, armorS)
def main():
boss = dict()
store = dict()
me = dict()
for line in read_file('input'):
match = re.match(RE_INPUT, line)
boss[match.group(1)] = int(match.group(2))
store_group = None
for line in read_file('store'):
match = re.match(RE_STORE_HEADER, line)
if match:
store_group = match.group(1)
store[store_group] = []
continue
match = re.match(RE_STORE_ITEM, line)
if match:
item = dict()
item['Name'] = match.group(1).strip()
item['Cost'] = int(match.group(2))
item['Damage'] = int(match.group(3))
item['Armor'] = int(match.group(4))
store[store_group].append(item)
me['Hit Points'] = 100
me['Damage'] = 0
me['Armor'] = 0
for (c, d, a) in buy(store):
me['Damage'] = d
me['Armor'] = a
(turnMe, trunBoss) = simulate(me, boss)
if turnMe <= trunBoss:
print c
if __name__ == "__main__":
main()

115
21/part2.py Normal file
View File

@ -0,0 +1,115 @@
#!/usr/bin/python
import re
from math import ceil
RE_STORE_HEADER = re.compile(r'^(.*):.*$')
RE_STORE_ITEM = re.compile(r'^(.*)\s+(\d+)\s+(\d+)\s+(\d+)')
RE_INPUT = re.compile(r'^(.*):\s+(\d+)$')
def read_file(filename):
file = open(filename, 'r')
while True:
line = file.readline()
if not line:
break
yield line
def simulate(me, boss):
myWinTurns = 0
bossWinTurns = 0
myWinTurns = int(ceil(boss['Hit Points'] / max(1, me['Damage'] - boss['Armor'])))
bossWinTurns = int(ceil(me['Hit Points'] / max(1, boss['Damage'] - me['Armor'])))
return(myWinTurns, bossWinTurns)
def calculate_possible_combinations(minSum, maxSum, pos, usage):
if pos == len(usage):
if sum(usage) >= minSum and sum(usage) <= maxSum:
yield usage
return
for x in range(2):
usage[pos] = x
for c in calculate_possible_combinations(minSum, maxSum, pos+1, usage):
yield c
usage[pos] = 0
def calculate_sum_product(item, usage, key):
sum = 0
for x in range(len(item)):
sum += item[x][key]*usage[x]
return sum
def buy(store):
# 1 Weapon
# 0-1 Armor
# 0-2 Rings
numWeapons = len(store['Weapons'])
numArmor = len(store['Armor'])
numRings = len(store['Rings'])
weapons = [0 for x in range(numWeapons)]
armor = [0 for x in range(numArmor)]
rings = [0 for x in range(numRings)]
for w in calculate_possible_combinations(1, numWeapons, 0, weapons):
for a in calculate_possible_combinations(0, numArmor, 0, armor):
for r in calculate_possible_combinations(0, numRings, 0, rings):
costS = calculate_sum_product(store['Weapons'], w, 'Cost')
costS += calculate_sum_product(store['Armor'], a, 'Cost')
costS += calculate_sum_product(store['Rings'], r, 'Cost')
armorS = calculate_sum_product(store['Weapons'], w, 'Armor')
armorS += calculate_sum_product(store['Armor'], a, 'Armor')
armorS += calculate_sum_product(store['Rings'], r, 'Armor')
damageS = calculate_sum_product(store['Weapons'], w, 'Damage')
damageS += calculate_sum_product(store['Armor'], a, 'Damage')
damageS += calculate_sum_product(store['Rings'], r, 'Damage')
yield (costS, damageS, armorS)
def main():
boss = dict()
store = dict()
me = dict()
for line in read_file('input'):
match = re.match(RE_INPUT, line)
boss[match.group(1)] = int(match.group(2))
store_group = None
for line in read_file('store'):
match = re.match(RE_STORE_HEADER, line)
if match:
store_group = match.group(1)
store[store_group] = []
continue
match = re.match(RE_STORE_ITEM, line)
if match:
item = dict()
item['Name'] = match.group(1).strip()
item['Cost'] = int(match.group(2))
item['Damage'] = int(match.group(3))
item['Armor'] = int(match.group(4))
store[store_group].append(item)
me['Hit Points'] = 100
me['Damage'] = 0
me['Armor'] = 0
for (c, d, a) in buy(store):
me['Damage'] = d
me['Armor'] = a
(turnMe, trunBoss) = simulate(me, boss)
if turnMe >= trunBoss:
print c
if __name__ == "__main__":
main()

9
21/readme Normal file
View File

@ -0,0 +1,9 @@
## part1
python part1.py | sort -n | head -1
## part2
There must be at least one weapon
python part2.py | sort -nr | head -1

21
21/store Normal file
View File

@ -0,0 +1,21 @@
Weapons: Cost Damage Armor
Dagger 8 4 0
Shortsword 10 5 0
Warhammer 25 6 0
Longsword 40 7 0
Greataxe 74 8 0
Armor: Cost Damage Armor
Leather 13 0 1
Chainmail 31 0 2
Splintmail 53 0 3
Bandedmail 75 0 4
Platemail 102 0 5
Rings: Cost Damage Armor
Damage +1 25 1 0
Damage +2 50 2 0
Damage +3 100 3 0
Defense +1 20 0 1
Defense +2 40 0 2
Defense +3 80 0 3