added rest of the code
This commit is contained in:
parent
6e366d7ade
commit
a9ceb0715a
32
20/part1.py
Normal file
32
20/part1.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from math import ceil, sqrt
|
||||||
|
|
||||||
|
def get_present_for_house(houseNumber):
|
||||||
|
result = 0
|
||||||
|
# print "house: %d" % houseNumber
|
||||||
|
for x in range(int(sqrt(houseNumber))):
|
||||||
|
elf = x+1
|
||||||
|
if houseNumber % (elf) == 0:
|
||||||
|
# print "elf: %d, %d" % (elf, houseNumber/elf)
|
||||||
|
result += (elf)*10
|
||||||
|
if elf != houseNumber / elf:
|
||||||
|
result += (houseNumber / elf) * 10
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
input = 36000000
|
||||||
|
houseNumber = int(sqrt(input))
|
||||||
|
while True:
|
||||||
|
giftNumber = get_present_for_house(houseNumber)
|
||||||
|
print "house: %d, gifts: %d" % (houseNumber, giftNumber)
|
||||||
|
if giftNumber >= input:
|
||||||
|
break
|
||||||
|
houseNumber += 1
|
||||||
|
print houseNumber
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
32
20/part2.py
Normal file
32
20/part2.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from math import ceil, sqrt
|
||||||
|
|
||||||
|
def get_present_for_house(houseNumber, delivered, max):
|
||||||
|
result = 0
|
||||||
|
for x in range(int(sqrt(houseNumber))):
|
||||||
|
elf = x+1
|
||||||
|
if houseNumber % (elf) == 0:
|
||||||
|
if houseNumber <= elf*max:
|
||||||
|
result += (elf)*delivered
|
||||||
|
if houseNumber <= (houseNumber/elf)*max:
|
||||||
|
if elf != houseNumber / elf:
|
||||||
|
result += (houseNumber/elf) * delivered
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
input = 36000000
|
||||||
|
houseNumber = int(sqrt(input))
|
||||||
|
while True:
|
||||||
|
giftNumber = get_present_for_house(houseNumber, 11, 50)
|
||||||
|
print "house: %d, gifts: %d" % (houseNumber, giftNumber)
|
||||||
|
if giftNumber >= input:
|
||||||
|
break
|
||||||
|
houseNumber += 1
|
||||||
|
print houseNumber
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
111
21/part1.py
Normal file
111
21/part1.py
Normal 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
115
21/part2.py
Normal 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
9
21/readme
Normal 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
21
21/store
Normal 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
|
110
22/part1.py
Normal file
110
22/part1.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
from copy import deepcopy
|
||||||
|
from sys import maxsize
|
||||||
|
|
||||||
|
RE_INPUT = re.compile(r'^(.*):\s+(\d+)$')
|
||||||
|
|
||||||
|
spells = [
|
||||||
|
{'name': 'Magic Missile', 'costs': 53, 'damage': 4, 'turns': 0},
|
||||||
|
{'name': 'Drain', 'costs': 73, 'damage': 2, 'heal': 2, 'turns': 0},
|
||||||
|
{'name': 'Shield', 'costs': 113, 'armor': 7, 'turns': 6},
|
||||||
|
{'name': 'Poison', 'costs': 173, 'damage': 3, 'turns': 6},
|
||||||
|
{'name': 'Recharge', 'costs': 229, 'mana': 101, 'turns': 5}
|
||||||
|
]
|
||||||
|
minManaUsed = maxsize
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def printSpells(s):
|
||||||
|
name = []
|
||||||
|
for (s1,t1) in s:
|
||||||
|
name.append("%s (%d)" % (spells[s1]['name'], t1))
|
||||||
|
print ", ".join(name)
|
||||||
|
|
||||||
|
def sim(me, boss, activeSpells, meTurn, manaUsed):
|
||||||
|
global minManaUsed
|
||||||
|
|
||||||
|
newSpells = []
|
||||||
|
newBoss = deepcopy(boss)
|
||||||
|
newMe = deepcopy(me)
|
||||||
|
|
||||||
|
newMe['Armor'] = 0
|
||||||
|
|
||||||
|
for (s, t) in activeSpells:
|
||||||
|
if t >= 0:
|
||||||
|
newBoss['Hit Points'] -= spells[s]['damage']
|
||||||
|
newMe['Hit Points'] += spells[s]['heal']
|
||||||
|
newMe['Armor'] += spells[s]['armor']
|
||||||
|
newMe['Mana'] += spells[s]['mana']
|
||||||
|
t -= 1
|
||||||
|
if t > 0:
|
||||||
|
newSpells.append((s, t))
|
||||||
|
else:
|
||||||
|
newSpells.append((s, -1))
|
||||||
|
|
||||||
|
if newBoss['Hit Points'] <= 0:
|
||||||
|
if manaUsed < minManaUsed:
|
||||||
|
minManaUsed = manaUsed
|
||||||
|
print manaUsed
|
||||||
|
printSpells(activeSpells)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if manaUsed > minManaUsed:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if meTurn:
|
||||||
|
for s1 in range(len(spells)):
|
||||||
|
spell = spells[s1]
|
||||||
|
isSpellUsed = False
|
||||||
|
for (s2, t2) in newSpells:
|
||||||
|
if s1 == s2 and t2 >= 0:
|
||||||
|
isSpellUsed = True
|
||||||
|
break
|
||||||
|
if spell['costs'] <= newMe['Mana'] and not isSpellUsed:
|
||||||
|
a = deepcopy(newSpells)
|
||||||
|
a.append((s1, spell['turns']))
|
||||||
|
m = deepcopy(newMe)
|
||||||
|
m['Mana'] -= spell['costs']
|
||||||
|
sim(m, newBoss, a, False, manaUsed+spell['costs'])
|
||||||
|
else:
|
||||||
|
if newMe['Armor'] >= boss['Damage']:
|
||||||
|
newMe['Hit Points'] -= 1
|
||||||
|
else:
|
||||||
|
newMe['Hit Points'] += newMe['Armor'] - newBoss['Damage']
|
||||||
|
if newMe['Hit Points'] > 0:
|
||||||
|
sim(newMe, newBoss, newSpells, True, manaUsed)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(len(spells)):
|
||||||
|
for k in ['costs', 'damage', 'armor', 'heal', 'mana', 'turns']:
|
||||||
|
if k not in spells[i].keys():
|
||||||
|
spells[i][k] = 0
|
||||||
|
|
||||||
|
boss = dict()
|
||||||
|
me = {
|
||||||
|
# 'Hit Points': 10,
|
||||||
|
# 'Mana': 250
|
||||||
|
'Hit Points': 50,
|
||||||
|
'Mana': 500
|
||||||
|
}
|
||||||
|
|
||||||
|
for line in read_file('input'):
|
||||||
|
match = re.match(RE_INPUT, line)
|
||||||
|
boss[match.group(1)] = int(match.group(2))
|
||||||
|
|
||||||
|
sim(me, boss, [], True, 0)
|
||||||
|
print minManaUsed
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
66
22/part1_x.py
Normal file
66
22/part1_x.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from copy import deepcopy
|
||||||
|
from sys import maxsize
|
||||||
|
# 0=manacost, 1=dmg, 2=hp, 3=armour, 4=mana, 5=turns, 6=index
|
||||||
|
missile = (53,4,0,0,0,0,0)
|
||||||
|
drain = (73,2,2,0,0,0,1)
|
||||||
|
shield = (113,0,0,7,0,6,2)
|
||||||
|
poison = (173,3,0,0,0,6,3)
|
||||||
|
recharge = (229,0,0,0,101,5,4)
|
||||||
|
spells = [missile, drain, shield, poison, recharge]
|
||||||
|
leastManaUsed = maxsize
|
||||||
|
partTwo = False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sim(55,50,500,[],True,0)
|
||||||
|
print leastManaUsed
|
||||||
|
|
||||||
|
def sim(bossHP, myHP, myMana, activespells, playerTurn, manaUsed):
|
||||||
|
bossDmg = 8
|
||||||
|
myArmour = 0
|
||||||
|
|
||||||
|
if partTwo and playerTurn:
|
||||||
|
myHP -= 1
|
||||||
|
if myHP <= 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
newActiveSpells = []
|
||||||
|
for activespell in activespells:
|
||||||
|
if activespell[5] >= 0: # spell effect applies now
|
||||||
|
bossHP -= activespell[1]
|
||||||
|
myHP += activespell[2]
|
||||||
|
myArmour += activespell[3]
|
||||||
|
myMana += activespell[4]
|
||||||
|
|
||||||
|
newActiveSpell = (activespell[0], activespell[1], activespell[2], activespell[3], activespell[4], activespell[5]-1, activespell[6])
|
||||||
|
if newActiveSpell[5] > 0: # spell carries over
|
||||||
|
newActiveSpells.append(newActiveSpell)
|
||||||
|
|
||||||
|
if bossHP <= 0:
|
||||||
|
global leastManaUsed
|
||||||
|
if manaUsed < leastManaUsed:
|
||||||
|
leastManaUsed = manaUsed
|
||||||
|
return True
|
||||||
|
|
||||||
|
if manaUsed >= leastManaUsed:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (playerTurn):
|
||||||
|
for i in range(len(spells)):
|
||||||
|
spell = spells[i]
|
||||||
|
spellAlreadyActive = False
|
||||||
|
for j in range(len(newActiveSpells)):
|
||||||
|
if newActiveSpells[j][6] == spell[6]:
|
||||||
|
spellAlreadyActive = True
|
||||||
|
break
|
||||||
|
|
||||||
|
spellManaCost = spell[0]
|
||||||
|
if spellManaCost <= myMana and not spellAlreadyActive:
|
||||||
|
a = deepcopy(newActiveSpells)
|
||||||
|
a.append(spell)
|
||||||
|
sim(bossHP, myHP, myMana - spellManaCost, a, False, manaUsed+spellManaCost)
|
||||||
|
else:
|
||||||
|
myHP += myArmour-bossDmg if myArmour-bossDmg < 0 else -1
|
||||||
|
if myHP > 0:
|
||||||
|
sim(bossHP,myHP,myMana,newActiveSpells, True,manaUsed)
|
||||||
|
|
||||||
|
main()
|
113
22/part2.py
Normal file
113
22/part2.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
from copy import deepcopy
|
||||||
|
from sys import maxsize
|
||||||
|
|
||||||
|
RE_INPUT = re.compile(r'^(.*):\s+(\d+)$')
|
||||||
|
|
||||||
|
spells = [
|
||||||
|
{'name': 'Magic Missile', 'costs': 53, 'damage': 4, 'turns': 0},
|
||||||
|
{'name': 'Drain', 'costs': 73, 'damage': 2, 'heal': 2, 'turns': 0},
|
||||||
|
{'name': 'Shield', 'costs': 113, 'armor': 7, 'turns': 6},
|
||||||
|
{'name': 'Poison', 'costs': 173, 'damage': 3, 'turns': 6},
|
||||||
|
{'name': 'Recharge', 'costs': 229, 'mana': 101, 'turns': 5}
|
||||||
|
]
|
||||||
|
minManaUsed = maxsize
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def printSpells(s):
|
||||||
|
name = []
|
||||||
|
for (s1,t1) in s:
|
||||||
|
name.append("%s (%d)" % (spells[s1]['name'], t1))
|
||||||
|
print ", ".join(name)
|
||||||
|
|
||||||
|
def sim(me, boss, activeSpells, meTurn, manaUsed):
|
||||||
|
global minManaUsed
|
||||||
|
|
||||||
|
newSpells = []
|
||||||
|
newBoss = deepcopy(boss)
|
||||||
|
newMe = deepcopy(me)
|
||||||
|
|
||||||
|
newMe['Armor'] = 0
|
||||||
|
|
||||||
|
newMe['Hit Points'] -= 1
|
||||||
|
if newMe['Hit Points'] <= 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for (s, t) in activeSpells:
|
||||||
|
if t >= 0:
|
||||||
|
newBoss['Hit Points'] -= spells[s]['damage']
|
||||||
|
newMe['Hit Points'] += spells[s]['heal']
|
||||||
|
newMe['Armor'] += spells[s]['armor']
|
||||||
|
newMe['Mana'] += spells[s]['mana']
|
||||||
|
t -= 1
|
||||||
|
if t > 0:
|
||||||
|
newSpells.append((s, t))
|
||||||
|
else:
|
||||||
|
newSpells.append((s, -1))
|
||||||
|
|
||||||
|
if newBoss['Hit Points'] <= 0:
|
||||||
|
if manaUsed < minManaUsed:
|
||||||
|
minManaUsed = manaUsed
|
||||||
|
print manaUsed
|
||||||
|
printSpells(activeSpells)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if manaUsed > minManaUsed:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if meTurn:
|
||||||
|
for s1 in range(len(spells)):
|
||||||
|
spell = spells[s1]
|
||||||
|
isSpellUsed = False
|
||||||
|
for (s2, t2) in newSpells:
|
||||||
|
if s1 == s2 and t2 >= 0:
|
||||||
|
isSpellUsed = True
|
||||||
|
break
|
||||||
|
if spell['costs'] <= newMe['Mana'] and not isSpellUsed:
|
||||||
|
s = deepcopy(newSpells)
|
||||||
|
s.append((s1, spell['turns']))
|
||||||
|
m = deepcopy(newMe)
|
||||||
|
m['Mana'] -= spell['costs']
|
||||||
|
sim(m, newBoss, s, False, manaUsed+spell['costs'])
|
||||||
|
else:
|
||||||
|
if newMe['Armor'] >= boss['Damage']:
|
||||||
|
newMe['Hit Points'] -= 1
|
||||||
|
else:
|
||||||
|
newMe['Hit Points'] += newMe['Armor']
|
||||||
|
newMe['Hit Points'] -= newBoss['Damage']
|
||||||
|
if newMe['Hit Points'] > 0:
|
||||||
|
sim(newMe, newBoss, newSpells, True, manaUsed)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
for i in range(len(spells)):
|
||||||
|
for k in ['costs', 'damage', 'armor', 'heal', 'mana', 'turns']:
|
||||||
|
if k not in spells[i].keys():
|
||||||
|
spells[i][k] = 0
|
||||||
|
|
||||||
|
boss = dict()
|
||||||
|
me = {
|
||||||
|
'Hit Points': 50,
|
||||||
|
'Mana': 500
|
||||||
|
}
|
||||||
|
|
||||||
|
for line in read_file('input'):
|
||||||
|
match = re.match(RE_INPUT, line)
|
||||||
|
boss[match.group(1)] = int(match.group(2))
|
||||||
|
|
||||||
|
sim(me, boss, [], True, 0)
|
||||||
|
print minManaUsed
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
66
22/part2_x.py
Normal file
66
22/part2_x.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from copy import deepcopy
|
||||||
|
from sys import maxsize
|
||||||
|
# 0=manacost, 1=dmg, 2=hp, 3=armour, 4=mana, 5=turns, 6=index
|
||||||
|
missile = (53,4,0,0,0,0,0)
|
||||||
|
drain = (73,2,2,0,0,0,1)
|
||||||
|
shield = (113,0,0,7,0,6,2)
|
||||||
|
poison = (173,3,0,0,0,6,3)
|
||||||
|
recharge = (229,0,0,0,101,5,4)
|
||||||
|
spells = [missile, drain, shield, poison, recharge]
|
||||||
|
leastManaUsed = maxsize
|
||||||
|
partTwo = True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sim(55,50,500,[],True,0)
|
||||||
|
print leastManaUsed
|
||||||
|
|
||||||
|
def sim(bossHP, myHP, myMana, activespells, playerTurn, manaUsed):
|
||||||
|
bossDmg = 8
|
||||||
|
myArmour = 0
|
||||||
|
|
||||||
|
if partTwo and playerTurn:
|
||||||
|
myHP -= 1
|
||||||
|
if myHP <= 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
newActiveSpells = []
|
||||||
|
for activespell in activespells:
|
||||||
|
if activespell[5] >= 0: # spell effect applies now
|
||||||
|
bossHP -= activespell[1]
|
||||||
|
myHP += activespell[2]
|
||||||
|
myArmour += activespell[3]
|
||||||
|
myMana += activespell[4]
|
||||||
|
|
||||||
|
newActiveSpell = (activespell[0], activespell[1], activespell[2], activespell[3], activespell[4], activespell[5]-1, activespell[6])
|
||||||
|
if newActiveSpell[5] > 0: # spell carries over
|
||||||
|
newActiveSpells.append(newActiveSpell)
|
||||||
|
|
||||||
|
if bossHP <= 0:
|
||||||
|
global leastManaUsed
|
||||||
|
if manaUsed < leastManaUsed:
|
||||||
|
leastManaUsed = manaUsed
|
||||||
|
return True
|
||||||
|
|
||||||
|
if manaUsed >= leastManaUsed:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (playerTurn):
|
||||||
|
for i in range(len(spells)):
|
||||||
|
spell = spells[i]
|
||||||
|
spellAlreadyActive = False
|
||||||
|
for j in range(len(newActiveSpells)):
|
||||||
|
if newActiveSpells[j][6] == spell[6]:
|
||||||
|
spellAlreadyActive = True
|
||||||
|
break
|
||||||
|
|
||||||
|
spellManaCost = spell[0]
|
||||||
|
if spellManaCost <= myMana and not spellAlreadyActive:
|
||||||
|
a = deepcopy(newActiveSpells)
|
||||||
|
a.append(spell)
|
||||||
|
sim(bossHP, myHP, myMana - spellManaCost, a, False, manaUsed+spellManaCost)
|
||||||
|
else:
|
||||||
|
myHP += myArmour-bossDmg if myArmour-bossDmg < 0 else -1
|
||||||
|
if myHP > 0:
|
||||||
|
sim(bossHP,myHP,myMana,newActiveSpells, True,manaUsed)
|
||||||
|
|
||||||
|
main()
|
49
23/input
Normal file
49
23/input
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
jio a, +19
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
jmp +23
|
||||||
|
tpl a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
inc a
|
||||||
|
tpl a
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
jio a, +8
|
||||||
|
inc b
|
||||||
|
jie a, +4
|
||||||
|
tpl a
|
||||||
|
inc a
|
||||||
|
jmp +2
|
||||||
|
hlf a
|
||||||
|
jmp -7
|
80
23/part1.py
Normal file
80
23/part1.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
RE_INSTR01 = re.compile(r'^(jio|jie) (a|b), ((\+|-)\d+)$')
|
||||||
|
RE_INSTR02 = re.compile(r'^(inc|tpl|hlf) (a|b)$')
|
||||||
|
RE_INSTR03 = re.compile(r'^(jmp) ((\+|-)\d+)$')
|
||||||
|
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def run_program(instrustions, a=0, b=0):
|
||||||
|
register = dict()
|
||||||
|
register['a'] = a
|
||||||
|
register['b'] = b
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
i = instrustions[pos]
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
|
||||||
|
if i[0] == 'hlf':
|
||||||
|
register[i[1]] = register[i[1]]/2
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'tpl':
|
||||||
|
register[i[1]] = register[i[1]]*3
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'inc':
|
||||||
|
register[i[1]] += 1
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'jmp':
|
||||||
|
pos += i[1]
|
||||||
|
continue
|
||||||
|
if i[0] == 'jie':
|
||||||
|
if register[i[1]] % 2 == 0:
|
||||||
|
pos += i[2]
|
||||||
|
continue
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'jio':
|
||||||
|
if register[i[1]] == 1:
|
||||||
|
pos += i[2]
|
||||||
|
continue
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
print i[0]
|
||||||
|
|
||||||
|
return (register['a'], register['b'])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
instructions = []
|
||||||
|
for line in read_file('input'):
|
||||||
|
match = re.match(RE_INSTR01, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), match.group(2), int(match.group(3))))
|
||||||
|
match = re.match(RE_INSTR02, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), match.group(2)))
|
||||||
|
match = re.match(RE_INSTR03, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), int(match.group(2))))
|
||||||
|
|
||||||
|
print run_program(instructions)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
80
23/part2.py
Normal file
80
23/part2.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
RE_INSTR01 = re.compile(r'^(jio|jie) (a|b), ((\+|-)\d+)$')
|
||||||
|
RE_INSTR02 = re.compile(r'^(inc|tpl|hlf) (a|b)$')
|
||||||
|
RE_INSTR03 = re.compile(r'^(jmp) ((\+|-)\d+)$')
|
||||||
|
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
def run_program(instrustions, a=0, b=0):
|
||||||
|
register = dict()
|
||||||
|
register['a'] = a
|
||||||
|
register['b'] = b
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
i = instrustions[pos]
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
|
||||||
|
if i[0] == 'hlf':
|
||||||
|
register[i[1]] = register[i[1]]/2
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'tpl':
|
||||||
|
register[i[1]] = register[i[1]]*3
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'inc':
|
||||||
|
register[i[1]] += 1
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'jmp':
|
||||||
|
pos += i[1]
|
||||||
|
continue
|
||||||
|
if i[0] == 'jie':
|
||||||
|
if register[i[1]] % 2 == 0:
|
||||||
|
pos += i[2]
|
||||||
|
continue
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
if i[0] == 'jio':
|
||||||
|
if register[i[1]] == 1:
|
||||||
|
pos += i[2]
|
||||||
|
continue
|
||||||
|
pos += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
print i[0]
|
||||||
|
|
||||||
|
return (register['a'], register['b'])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
instructions = []
|
||||||
|
for line in read_file('input'):
|
||||||
|
match = re.match(RE_INSTR01, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), match.group(2), int(match.group(3))))
|
||||||
|
match = re.match(RE_INSTR02, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), match.group(2)))
|
||||||
|
match = re.match(RE_INSTR03, line)
|
||||||
|
if match:
|
||||||
|
instructions.append((match.group(1), int(match.group(2))))
|
||||||
|
|
||||||
|
print run_program(instructions,1, 0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
3
24/1
Normal file
3
24/1
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0]
|
||||||
|
[1, 2, 3, 7, 11, 13, 17, 19, 23, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113]
|
||||||
|
0000000006 405925792351
|
29
24/input
Normal file
29
24/input
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
7
|
||||||
|
11
|
||||||
|
13
|
||||||
|
17
|
||||||
|
19
|
||||||
|
23
|
||||||
|
31
|
||||||
|
37
|
||||||
|
41
|
||||||
|
43
|
||||||
|
47
|
||||||
|
53
|
||||||
|
59
|
||||||
|
61
|
||||||
|
67
|
||||||
|
71
|
||||||
|
73
|
||||||
|
79
|
||||||
|
83
|
||||||
|
89
|
||||||
|
97
|
||||||
|
101
|
||||||
|
103
|
||||||
|
107
|
||||||
|
109
|
||||||
|
113
|
78
24/output
Normal file
78
24/output
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
0000000006 405925792351
|
||||||
|
0000000006 398297798863
|
||||||
|
0000000006 397378915159
|
||||||
|
0000000006 393825160111
|
||||||
|
0000000006 387870017503
|
||||||
|
0000000006 386081047967
|
||||||
|
0000000006 385169090599
|
||||||
|
0000000006 381724527871
|
||||||
|
0000000006 377138228059
|
||||||
|
0000000006 373687214839
|
||||||
|
0000000006 373135490311
|
||||||
|
0000000006 372367655983
|
||||||
|
0000000006 368186196751
|
||||||
|
0000000006 365035378879
|
||||||
|
0000000006 364518128159
|
||||||
|
0000000006 358405774439
|
||||||
|
0000000006 356454558899
|
||||||
|
0000000006 354361540807
|
||||||
|
0000000006 352397865679
|
||||||
|
0000000006 349530122299
|
||||||
|
0000000006 349149543271
|
||||||
|
0000000006 347210246311
|
||||||
|
0000000006 336766524151
|
||||||
|
0000000006 332275056199
|
||||||
|
0000000006 329266949191
|
||||||
|
0000000006 325569484327
|
||||||
|
0000000006 321046386319
|
||||||
|
0000000006 317773110799
|
||||||
|
0000000006 317427109771
|
||||||
|
0000000006 313613323159
|
||||||
|
0000000006 313099260847
|
||||||
|
0000000006 302233500799
|
||||||
|
0000000006 300915741871
|
||||||
|
0000000006 300588095659
|
||||||
|
0000000006 300521671999
|
||||||
|
0000000006 297576884767
|
||||||
|
0000000006 286658711767
|
||||||
|
0000000006 269014944199
|
||||||
|
0000000006 261581881039
|
||||||
|
0000000006 261028355059
|
||||||
|
0000000006 260720614927
|
||||||
|
0000000006 258165834991
|
||||||
|
0000000006 255593848319
|
||||||
|
0000000006 243457858951
|
||||||
|
0000000006 221020192639
|
||||||
|
0000000006 218126942599
|
||||||
|
0000000006 217678083247
|
||||||
|
0000000006 215545073551
|
||||||
|
0000000006 215233692559
|
||||||
|
0000000006 213124635247
|
||||||
|
0000000006 211189107967
|
||||||
|
0000000006 209242415383
|
||||||
|
0000000006 208759687519
|
||||||
|
0000000006 205122231079
|
||||||
|
0000000006 186804366079
|
||||||
|
0000000006 184973885407
|
||||||
|
0000000006 184711779647
|
||||||
|
0000000006 179565145831
|
||||||
|
0000000006 172879027843
|
||||||
|
0000000006 172523279179
|
||||||
|
0000000006 171196896679
|
||||||
|
0000000006 170450466391
|
||||||
|
0000000006 170264874739
|
||||||
|
0000000006 168926129839
|
||||||
|
0000000006 165189285379
|
||||||
|
0000000006 163845007999
|
||||||
|
0000000006 137053044739
|
||||||
|
0000000006 135719504167
|
||||||
|
0000000006 118782255031
|
||||||
|
0000000006 118264356199
|
||||||
|
0000000006 118135586371
|
||||||
|
0000000006 116986114663
|
||||||
|
0000000006 116716224559
|
||||||
|
0000000006 115672432711
|
||||||
|
0000000006 78362605279
|
||||||
|
0000000006 77336804839
|
||||||
|
0000000006 35307084999
|
||||||
|
0000000006 11846773891
|
14
24/output.2
Normal file
14
24/output.2
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
0000000004 89809099
|
||||||
|
0000000004 88730071
|
||||||
|
0000000004 88633459
|
||||||
|
0000000004 87936559
|
||||||
|
0000000004 87457819
|
||||||
|
0000000004 86600827
|
||||||
|
0000000004 85991299
|
||||||
|
0000000004 85814347
|
||||||
|
0000000004 85616371
|
||||||
|
0000000004 85291519
|
||||||
|
0000000004 84827179
|
||||||
|
0000000004 83439991
|
||||||
|
0000000004 83349139
|
||||||
|
0000000004 80393059
|
90
24/part1.py
Normal file
90
24/part1.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
mQ = None
|
||||||
|
mC = None
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_qe(packages, used):
|
||||||
|
|
||||||
|
if sum(used) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = 1
|
||||||
|
for i in range(len(packages)):
|
||||||
|
if used[i]:
|
||||||
|
result *= packages[i]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_weight(packages, used):
|
||||||
|
if sum(used) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = 0
|
||||||
|
for i in range(len(packages)):
|
||||||
|
result += packages[i]*used[i]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def find_group_packags(packagesList, packagesUsed, maxPackages, packagesWeight, pos):
|
||||||
|
|
||||||
|
global mC
|
||||||
|
global mQ
|
||||||
|
|
||||||
|
if sum(packagesUsed) > maxPackages:
|
||||||
|
return
|
||||||
|
|
||||||
|
weight = calculate_weight(packagesList, packagesUsed)
|
||||||
|
|
||||||
|
if weight > packagesWeight:
|
||||||
|
return
|
||||||
|
|
||||||
|
if mC is not None and sum(packagesUsed) > mC:
|
||||||
|
return
|
||||||
|
if mQ is not None and calculate_qe(packagesList, packagesUsed) > mQ:
|
||||||
|
return
|
||||||
|
|
||||||
|
if pos >= len(packagesList):
|
||||||
|
if weight == packagesWeight:
|
||||||
|
qe = calculate_qe(packagesList, packagesUsed)
|
||||||
|
yield (sum(packagesUsed), qe)
|
||||||
|
return
|
||||||
|
|
||||||
|
for i in range(2):
|
||||||
|
packagesUsed[pos] = i
|
||||||
|
for (c, q) in find_group_packags(packagesList, packagesUsed, maxPackages, packagesWeight, pos+1):
|
||||||
|
if mC is None:
|
||||||
|
mC = c
|
||||||
|
if c is not None:
|
||||||
|
mC = min (c, mC)
|
||||||
|
if mQ is None:
|
||||||
|
mQ = q
|
||||||
|
if q is not None:
|
||||||
|
mQ = min(q, mQ)
|
||||||
|
yield (c, q)
|
||||||
|
packagesUsed[pos] = 0
|
||||||
|
|
||||||
|
def main():
|
||||||
|
weights = []
|
||||||
|
packagesUsed = []
|
||||||
|
for line in read_file('input'):
|
||||||
|
weights.append(int(line))
|
||||||
|
packagesUsed.append(0)
|
||||||
|
|
||||||
|
weights_sum = sum(weights)
|
||||||
|
group_weight = int(weights_sum / 3)
|
||||||
|
group_1_max_packages = int(len(weights) / 3)
|
||||||
|
|
||||||
|
for (c, q) in find_group_packags(weights, packagesUsed, group_1_max_packages, group_weight, 0):
|
||||||
|
print "%010d %d" % (c, q)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
90
24/part2.py
Normal file
90
24/part2.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
mQ = None
|
||||||
|
mC = None
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_qe(packages, used):
|
||||||
|
|
||||||
|
if sum(used) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = 1
|
||||||
|
for i in range(len(packages)):
|
||||||
|
if used[i]:
|
||||||
|
result *= packages[i]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_weight(packages, used):
|
||||||
|
if sum(used) == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = 0
|
||||||
|
for i in range(len(packages)):
|
||||||
|
result += packages[i]*used[i]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def find_group_packags(packagesList, packagesUsed, maxPackages, packagesWeight, pos):
|
||||||
|
|
||||||
|
global mC
|
||||||
|
global mQ
|
||||||
|
|
||||||
|
if sum(packagesUsed) > maxPackages:
|
||||||
|
return
|
||||||
|
|
||||||
|
weight = calculate_weight(packagesList, packagesUsed)
|
||||||
|
|
||||||
|
if weight > packagesWeight:
|
||||||
|
return
|
||||||
|
|
||||||
|
if mC is not None and sum(packagesUsed) > mC:
|
||||||
|
return
|
||||||
|
if mQ is not None and calculate_qe(packagesList, packagesUsed) > mQ:
|
||||||
|
return
|
||||||
|
|
||||||
|
if pos >= len(packagesList):
|
||||||
|
if weight == packagesWeight:
|
||||||
|
qe = calculate_qe(packagesList, packagesUsed)
|
||||||
|
yield (sum(packagesUsed), qe)
|
||||||
|
return
|
||||||
|
|
||||||
|
for i in range(2):
|
||||||
|
packagesUsed[pos] = i
|
||||||
|
for (c, q) in find_group_packags(packagesList, packagesUsed, maxPackages, packagesWeight, pos+1):
|
||||||
|
if mC is None:
|
||||||
|
mC = c
|
||||||
|
if c is not None:
|
||||||
|
mC = min (c, mC)
|
||||||
|
if mQ is None:
|
||||||
|
mQ = q
|
||||||
|
if q is not None:
|
||||||
|
mQ = min(q, mQ)
|
||||||
|
yield (c, q)
|
||||||
|
packagesUsed[pos] = 0
|
||||||
|
|
||||||
|
def main():
|
||||||
|
weights = []
|
||||||
|
packagesUsed = []
|
||||||
|
for line in read_file('input'):
|
||||||
|
weights.append(int(line))
|
||||||
|
packagesUsed.append(0)
|
||||||
|
|
||||||
|
weights_sum = sum(weights)
|
||||||
|
group_weight = int(weights_sum / 4)
|
||||||
|
group_1_max_packages = int(len(weights) / 4)
|
||||||
|
|
||||||
|
for (c, q) in find_group_packags(weights, packagesUsed, group_1_max_packages, group_weight, 0):
|
||||||
|
print "%010d %d" % (c, q)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
1
25/input
Normal file
1
25/input
Normal file
@ -0,0 +1 @@
|
|||||||
|
To continue, please consult the code grid in the manual. Enter the code at row 3010, column 3019.
|
38
25/part1.py
Normal file
38
25/part1.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
RE_PARSE = re.compile(r'.* (\d+),.* (\d+).$')
|
||||||
|
|
||||||
|
def read_file(filename):
|
||||||
|
file = open(filename, 'r')
|
||||||
|
while True:
|
||||||
|
line = file.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
yield line
|
||||||
|
|
||||||
|
|
||||||
|
def get_position(row, col):
|
||||||
|
triangle = (row + col-1) * (row + col) / 2
|
||||||
|
return triangle - row + 1
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
code_first = 20151125
|
||||||
|
code_mul = 252533
|
||||||
|
code_mod = 33554393
|
||||||
|
|
||||||
|
for line in read_file('input'):
|
||||||
|
match = re.match(RE_PARSE, line)
|
||||||
|
row = int(match.group(1))
|
||||||
|
col = int(match.group(2))
|
||||||
|
code = code_first
|
||||||
|
iterations = get_position(row, col)
|
||||||
|
for x in range(iterations-1):
|
||||||
|
code = (code * code_mul) % code_mod
|
||||||
|
print code
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user