diff --git a/20/part1.py b/20/part1.py new file mode 100644 index 0000000..4375e23 --- /dev/null +++ b/20/part1.py @@ -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() diff --git a/20/part2.py b/20/part2.py new file mode 100644 index 0000000..384aefc --- /dev/null +++ b/20/part2.py @@ -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() diff --git a/21/input b/21/input new file mode 100644 index 0000000..c5f2409 --- /dev/null +++ b/21/input @@ -0,0 +1,3 @@ +Hit Points: 109 +Damage: 8 +Armor: 2 diff --git a/21/part1.py b/21/part1.py new file mode 100644 index 0000000..96a94e2 --- /dev/null +++ b/21/part1.py @@ -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() diff --git a/21/part2.py b/21/part2.py new file mode 100644 index 0000000..2a80fb0 --- /dev/null +++ b/21/part2.py @@ -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() diff --git a/21/readme b/21/readme new file mode 100644 index 0000000..8c371b4 --- /dev/null +++ b/21/readme @@ -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 diff --git a/21/store b/21/store new file mode 100644 index 0000000..8637bef --- /dev/null +++ b/21/store @@ -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 diff --git a/22/input b/22/input new file mode 100644 index 0000000..0001c6b --- /dev/null +++ b/22/input @@ -0,0 +1,2 @@ +Hit Points: 55 +Damage: 8 diff --git a/22/input1 b/22/input1 new file mode 100644 index 0000000..8b0b636 --- /dev/null +++ b/22/input1 @@ -0,0 +1,2 @@ +Hit Points: 14 +Damage: 8 diff --git a/22/part1.py b/22/part1.py new file mode 100644 index 0000000..8a612cf --- /dev/null +++ b/22/part1.py @@ -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() diff --git a/22/part1_x.py b/22/part1_x.py new file mode 100644 index 0000000..2dd0935 --- /dev/null +++ b/22/part1_x.py @@ -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() diff --git a/22/part2.py b/22/part2.py new file mode 100644 index 0000000..f5fc10c --- /dev/null +++ b/22/part2.py @@ -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() diff --git a/22/part2_x.py b/22/part2_x.py new file mode 100644 index 0000000..21ff4e8 --- /dev/null +++ b/22/part2_x.py @@ -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() diff --git a/23/input b/23/input new file mode 100644 index 0000000..07b1c76 --- /dev/null +++ b/23/input @@ -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 diff --git a/23/part1.py b/23/part1.py new file mode 100644 index 0000000..de6ed37 --- /dev/null +++ b/23/part1.py @@ -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() diff --git a/23/part2.py b/23/part2.py new file mode 100644 index 0000000..a97bae9 --- /dev/null +++ b/23/part2.py @@ -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() diff --git a/24/1 b/24/1 new file mode 100644 index 0000000..f2f93d6 --- /dev/null +++ b/24/1 @@ -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 diff --git a/24/input b/24/input new file mode 100644 index 0000000..bcdfa26 --- /dev/null +++ b/24/input @@ -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 diff --git a/24/input1 b/24/input1 new file mode 100644 index 0000000..f4909b4 --- /dev/null +++ b/24/input1 @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +7 +8 +9 +10 +11 diff --git a/24/output b/24/output new file mode 100644 index 0000000..493b1b9 --- /dev/null +++ b/24/output @@ -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 diff --git a/24/output.2 b/24/output.2 new file mode 100644 index 0000000..df8e836 --- /dev/null +++ b/24/output.2 @@ -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 diff --git a/24/part1.py b/24/part1.py new file mode 100644 index 0000000..c8ddf73 --- /dev/null +++ b/24/part1.py @@ -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() diff --git a/24/part2.py b/24/part2.py new file mode 100644 index 0000000..d10e290 --- /dev/null +++ b/24/part2.py @@ -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() diff --git a/25/input b/25/input new file mode 100644 index 0000000..9dcb923 --- /dev/null +++ b/25/input @@ -0,0 +1 @@ +To continue, please consult the code grid in the manual. Enter the code at row 3010, column 3019. diff --git a/25/part1.py b/25/part1.py new file mode 100644 index 0000000..b710f30 --- /dev/null +++ b/25/part1.py @@ -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() + diff --git a/README b/README.md similarity index 100% rename from README rename to README.md