예제 #1
0
    ruleExpression = ''.join(exprList)
    return ruleExpression


def partOne(data):
    pattern = parseRules(data)
    startIndex = data.index('') + 1
    validMessages = 0
    for line in data[startIndex:]:
        if regex.match(pattern, line):
            validMessages += 1
    return validMessages


def partTwo(data):
    data[data.index('8: 42')] = '8: 42 | 42 8'
    data[data.index('11: 42 31')] = '11: 42 31 | 42 11 31'
    pattern = parseRules(data)
    startIndex = data.index('') + 1
    validMessages = 0
    for line in data[startIndex:]:
        if regex.match(pattern, line):
            validMessages += 1
    return validMessages


puzzleInput = util.fileToStringList('input')

#print(f'Part one: Found {partOne(puzzleInput)} valid messages!')
print(f'Part two: Found {partTwo(puzzleInput)} valid messages!')
예제 #2
0
                unique.add(vals[0])
            else:
                for uq in unique:
                    if uq in vals: vals.remove(uq)
    return decipheredTicket


def partOne(data):
    parsedNotes = parseNotes(data)
    return sum(findInvalidVals(parsedNotes))


def partTwo(data):
    parsedNotes = parseNotes(data)
    ticketInfo = decipherTicket(parsedNotes)
    departureIndexes = set()
    for key in ticketInfo.keys():
        if key.startswith('departure'):
            departureIndexes.add(ticketInfo[key][0])
    departureVals = []
    for i in departureIndexes:
        departureVals.append(parsedNotes['your ticket'][i])
    res = reduce((lambda x, y: x * y), departureVals)
    return res


notes = util.fileToStringList('input')

print(f'Part one: Ticket scanning error rate: {partOne(notes)}')
print(f'Part two: Product of fields starting with departure: {partTwo(notes)}')
예제 #3
0
    maskedAddrs = applyMask_v2(mask, addr)
    for a in maskedAddrs:
        mem[a] = val


def runInit(mem, data, func):
    mask = ''
    for line in data:
        if line.startswith('mask = '):
            mask = line
        else:
            func(mem, mask, line)


def partOne(data):
    mem = {}
    runInit(mem, data, execValInst)
    return sum(mem.values())


def partTwo(data):
    mem = {}
    runInit(mem, data, execAddrInst)
    return sum(mem.values())


initData = util.fileToStringList('input')

print(f'Part one: Sum = {partOne(initData)}')
print(f'Part two: Sum = {partTwo(initData)}')
예제 #4
0
def evalShuntingYard(output):
    stack = deque()
    for token in output:
        if re.match('\d', token):
            stack.append(int(token))
        elif token == '+':
            stack.append(stack.pop() + stack.pop())
        else:
            stack.append(stack.pop() * stack.pop())
    return stack.pop()


def partOne(data):
    res = 0
    for line in data:
        res += solveLeftToRight(solveParentheses(line, solveLeftToRight))
    return res


def partTwo(data):
    res = 0
    for line in data:
        res += evalShuntingYard(shuntingYard(line))
    return res


homework = util.fileToStringList('input')

print(f'Part one: Sum of all expressions = {partOne(homework)}')
print(f'Part two: Sum of all expressions = {partTwo(homework)}')
예제 #5
0
            moveShip(currentState, eastWest, currentWaypoint[eastWest])
            i += 1
    elif op == 'L' or op == 'R':
        rotateWaypoint(currentWaypoint, op, amount)
    else:
        moveShip(currentWaypoint, op, amount)


def partOne(actions):
    state = {'N': 0, 'E': 0, 'S': 0, 'W': 0}
    facing = 90
    for action in actions:
        facing = executeAction(state, facing, action)
    return (max(state['N'], state['S']) + max(state['E'], state['W']))


def partTwo(actions):
    state = {'N': 0, 'E': 0, 'S': 0, 'W': 0}
    waypoint = {'N': 1, 'E': 10, 'S': 0, 'W': 0}
    for action in actions:
        executeWaypointAction(state, waypoint, action)
    return (max(state['N'], state['S']) + max(state['E'], state['W']))


directions = {0: 'N', 90: 'E', 180: 'S', 270: 'W'}

actions = util.fileToStringList('input')

print(f'Part one: Manhattan distance = {partOne(actions)}')
print(f'Part two: Manhattan distance = {partTwo(actions)}')
예제 #6
0
        for ing in ingredients:
            try:
                count[ing] += 1
            except KeyError:
                pass
    return sum(list(count.values()))


def getCanonicalList(allergens):
    keys = list(allergens.keys())
    keys.sort()
    ingredients = [allergens[key] for key in keys]
    return reduce((lambda x, y: x + ',' + y), ingredients)


def partOne(data):
    allergens, nonAllergens = separateIngredients(data)
    return countAppearances(nonAllergens, data)


def partTwo(data):
    allergens, nonAllergens = separateIngredients(data)
    allergens = getAllergenPairs(allergens)
    return getCanonicalList(allergens)


foods = util.fileToStringList('input')

print(f'Part one: Non-allergens appear a total of {partOne(foods)} times!')
print(f'Part two: Canonical list of allergens = {partTwo(foods)}')
예제 #7
0
    return arr[0]


def computeSeatId(codes):
    rows = [*range(0, 128)]
    cols = [*range(0, 8)]
    rowCodes = codes[:7]
    colCodes = codes[7:]
    row = findMatch(rowCodes, rows)
    col = findMatch(colCodes, cols)
    return row * 8 + col


def partOne(codesList):
    return max([computeSeatId(code) for code in codesList])


def partTwo(codesList):
    seatIds = [computeSeatId(code) for code in codesList]
    missingSeatId = [
        x for x in range(min(seatIds),
                         max(seatIds) + 1, 1) if x not in seatIds
    ]
    return missingSeatId[0]


seatCodes = util.fileToStringList('input')

print('Part one: Highest seat ID = %d' % partOne(seatCodes))
print('Part two: Missing seat ID = %d' % partTwo(seatCodes))
예제 #8
0
                    bc += 1
            if bc == 2:
                nextBlack.add(whiteTile)
    return nextBlack


def partOne(data):
    flippedTiles = flipTiles(parseDirections(data))
    blackTiles = [x for x in flippedTiles.values() if x % 2 != 0]
    return len(blackTiles)


def partTwo(data):
    flippedTiles = flipTiles(parseDirections(data))
    blackTiles = {x for x, y in flippedTiles.items() if y % 2 != 0}
    for i in range(1, 101):
        blackTiles = flip(blackTiles)
        if i % 10 == 0:
            print(f'({i}) - Black tiles: {len(blackTiles)}')
    return len(blackTiles)


floorTiles = util.fileToStringList('input')

print(
    f'Part one: Number of tiles left with black side up = {partOne(floorTiles)}'
)
print(
    f'Part two: Number of tiles with black side facing up after 100 days: {partTwo(floorTiles)}'
)
예제 #9
0
        executed.append(nextInst)
        action, offset = parseInstruction(data[nextInst])
        acc, nextInst = executeInstruction(action, offset, nextInst, acc)
    return acc


def partTwo(data):
    executed = []
    acc = prevAcc = nextInst = prevInst = 0
    changed = False
    while nextInst < len(data):
        executed.append(nextInst)
        action, offset = parseInstruction(data[nextInst])
        if action != 'acc' and changed == False:
            prevAcc, prevInst, changed = acc, nextInst, True
            action = 'nop' if action == 'jmp' else 'jmp'
        acc, nextInst = executeInstruction(action, offset, nextInst, acc)
        if nextInst in executed:
            changed = False
            executed = executed[0:executed.index(prevInst)]
            action, offset = parseInstruction(data[prevInst])
            acc, nextInst = executeInstruction(action, offset, prevInst,
                                               prevAcc)
    return acc


bootCode = util.fileToStringList('input')

print('Part one: Acc = %d!' % partOne(bootCode))
print('Part two: Acc = %d!' % partTwo(bootCode))
예제 #10
0
    pattern = ['                  # ',
               '#    ##    ##    ###',
               ' #  #  #  #  #  #   ']
    totalHashes = 0
    for row in grid:
        totalHashes += row.count('#')
    i = 0
    matches = 0
    while matches == 0 and i < 8:
        matches = scanGrid(grid, pattern)
        if matches == 0:
            grid, b = rotateImg(grid, None)
            if i == 3:
                grid, b = flipVertical(grid, None)
        i += 1
    return totalHashes - (matches * 15)

def partOne(data):
    return reduce((lambda x,y: x*y), findCornerTiles(findAdjacentTiles(parseInput(data))))

def partTwo(data):
    tiles = parseInput(data)
    grid, gridTiles = buildImage(tiles)
    return findSeaMonster(grid)

imageData = util.fileToStringList('input')

print(f'Part one: Product of corner tile IDs = {partOne(imageData)}')
print(f'Part two: Water roughness = {partTwo(imageData)}')

예제 #11
0
class TestPuzzle(unittest.TestCase):

    data = util.fileToStringList('testinput')
    data2 = ['#..', '..#', '.##']
    borders = {'top': 1, 'rgt': 2, 'btm': 3, 'lft': 4}

    def testFindAdjacentTiles(self):
        expected = {'top': '1427', 'lft': '1951', 'btm': None, 'rgt': '3079'}
        result = findAdjacentTiles(parseInput(self.data))['2311']
        self.assertEqual(result, expected)

    def testFindCornerTiles(self):
        expected = [1951, 1171, 2971, 3079]
        result = findCornerTiles(findAdjacentTiles(parseInput(self.data)))
        self.assertEqual(result, expected)

    def testRotateImg(self):
        expectedTiles = ['..#', '#..', '##.']
        expectedBorders = {'top': 4, 'rgt': 1, 'btm': 2, 'lft': 3}
        resTiles, resBorders = rotateImg(self.data2, self.borders)
        self.assertEqual(resTiles, expectedTiles)
        self.assertEqual(resBorders, expectedBorders)

    def testAddToGrid(self):
        expectedGrid = [
            '.#.#..#.', '###....#', '##.##.##', '###.####', '##.#....',
            '...#####', '....#..#', '.####...'
        ]
        expectedGridTiles = {(0, 0): '1951'}
        grid = []
        gridTiles = {}
        allTiles = parseInput(self.data)
        adjacents = findAdjacentTiles(allTiles)
        addToGrid('1951', 0, 0, allTiles, adjacents, grid, gridTiles)
        self.assertEqual(grid, expectedGrid)
        self.assertEqual(gridTiles, expectedGridTiles)

    def testAddToGrid_withExisting(self):
        expectedGrid = [
            '.#.#..#.##...#.#', '###....#.#....#.', '##.##.###.#.#..#',
            '###.#####...#.##', '##.#....#.##.###', '...########.#...',
            '....#..#...##..#', '.####...#..#....'
        ]
        expectedGridTiles = {(0, 0): '1951', (1, 0): '2311'}
        grid = [
            '.#.#..#.', '###....#', '##.##.##', '###.####', '##.#....',
            '...#####', '....#..#', '.####...'
        ]
        gridTiles = {(0, 0): '1951'}
        allTiles = parseInput(self.data)
        adjacents = findAdjacentTiles(allTiles)
        addToGrid('2311', 1, 0, allTiles, adjacents, grid, gridTiles)
        self.assertEqual(grid, expectedGrid)
        self.assertEqual(gridTiles, expectedGridTiles)

    def testBuildImage(self):
        expectedGrid = [
            '.#.#..#.##...#.##..#####', '###....#.#....#..#......',
            '##.##.###.#.#..######...', '###.#####...#.#####.#..#',
            '##.#....#.##.####...#.##', '...########.#....#####.#',
            '....#..#...##..#.#.###..', '.####...#..#.....#......',
            '#..#.##..#..###.#.##....', '#.####..#.####.#.#.###..',
            '###.#.#...#.######.#..##', '#.####....##..########.#',
            '##..##.#...#...#.#.#.#..', '...#..#..#.#.##..###.###',
            '.#.#....#.##.#...###.##.', '###.#...#..#.##.######..',
            '.#.#.###.##.##.#..#.##..', '.####.###.#...###.#..#.#',
            '..#.#..#..#.#.#.####.###', '#..####...#.#.#.###.###.',
            '#####..#####...###....##', '#.##..#..#...#..####...#',
            '.#.###..##..##..####.##.', '...###...##...#...#..###'
        ]
        expectedGridTiles = {
            (0, 0): '1951',
            (1, 0): '2311',
            (2, 0): '3079',
            (0, 1): '2729',
            (1, 1): '1427',
            (2, 1): '2473',
            (0, 2): '2971',
            (1, 2): '1489',
            (2, 2): '1171'
        }
        resGrid, resGridTiles = buildImage(parseInput(self.data))
        self.assertEqual(resGrid, expectedGrid)
        self.assertEqual(resGridTiles, expectedGridTiles)

    def testPartOne(self):
        expected = 20899048083289
        result = partOne(self.data)
        self.assertEqual(result, expected)

    def testPartTwo(self):
        expected = 273
        result = partTwo(self.data)
        self.assertEqual(result, expected)
예제 #12
0
            bagSet.add(key)
            collectContainers(key, dictionary, bagSet)


def countBags(search, dictionary):
    count = sum(dictionary[search].values())
    for key in dictionary[search].keys():
        amount = dictionary[search][key]
        count += amount * countBags(key, dictionary)
    return count


def partOne(data):
    bagDict = parseToDict(data)
    bag = 'shiny gold'
    bagSet = set()
    collectContainers(bag, bagDict, bagSet)
    return len(bagSet)


def partTwo(data):
    bagDict = parseToDict(data)
    bag = 'shiny gold'
    return countBags(bag, bagDict)


bagRules = util.fileToStringList('input')

print('Part one: %d possible outer bags!' % partOne(bagRules))
print('Part two: %d contained bags!' % partTwo(bagRules))