def iterate(grid, use_surroundings):
    threshold = 4 if use_surroundings else 5
    changed = False
    copy = [[None] * len(grid[0]) for _ in range(len(grid))]
    for row in range(len(grid)):
        for col in range(len(grid[0])):
            # Use one of our two counting functions
            if use_surroundings:
                count = count_surrounding(grid, row, col)
            else:
                count = count_visibility(grid, row, col)

            if grid[row][col] == '.':
                copy[row][col] = '.'
            elif grid[row][col] == 'L':
                if count == 0:
                    copy[row][col] = '#'
                    changed = True
                else:
                    copy[row][col] = 'L'
            elif grid[row][col] == '#':
                if count >= threshold:
                    copy[row][col] = 'L'
                    changed = True
                else:
                    copy[row][col] = '#'
            else:
                log(f'PROBLEM CHARACTER: {grid[row][col]}')

    return copy, changed
def part_1():
    x, y, dir = 0, 0, 'E'
    log(f"({x}, {y}, {dir})")
    for instr_str in get_strings_by_lines('12.txt'):
        x, y, dir = handle_instruction(x, y, dir, instr_str)
        log(f"({x}, {y}, {dir})")

    return abs(x) + abs(y)
def part_2():
    x, y, wx, wy = 0, 0, 10, 1
    log(f"({x}, {y}), ({wx}, {wy})")
    for instr_str in get_strings_by_lines('12.txt'):
        x, y, wx, wy = handle_instruction_with_waypoint(
            x, y, wx, wy, instr_str)
        log(f"({x}, {y}), ({wx}, {wy})")

    return abs(x) + abs(y)
示例#4
0
 def onScreensaverActivated(self):
     if __addon__.getSetting("at_ss_start") == "true":
         delay = int(__addon__.getSetting("at_ss_start_delay"))
         log("Screensaver activated, scheduling projector shutdown")
         self._ss_activation_timer_ = threading.Timer(
             delay, lib.commands.stop)
         self._last_power_command_ = datetime.datetime.now(
         ) + datetime.timedelta(seconds=delay)
         self._ss_activation_timer_.start()
def count_trees(rows, slope):
    dx, dy = slope
    x = 0
    tree_count = 0

    for y in range(0, len(rows), dy):
        log(f"coordinate: ({x}, {y}) Tree: {rows[y][x]}")
        tree_count += 1 if rows[y][x] == "#" else 0
        x = (x + dx) % len(rows[0])

    return tree_count
示例#6
0
def part_1():
    groups = get_input('6.txt').split('\n\n')
    grouped_people = [group.split('\n') for group in groups]

    count = 0
    for group in grouped_people:
        pset = ''.join(set(''.join(group)))
        log(pset)
        count += len(pset)

    return count
示例#7
0
def part_1():
    earliest, bus_list = get_strings_by_lines('13.txt')
    current_time = int(earliest)
    busses = [ int(bus) for bus in bus_list.split(',') if bus and bus != 'x']
    while True:
        log(f'Testing: {current_time}')
        for bus in busses:
            if current_time % bus == 0:
                log('FOUND IT')
                return (current_time - int(earliest)) * bus
        current_time += 1
def part_2():
    input_arr = get_ints_by_lines('1.txt')
    for x in range(0, len(input_arr)):
        for y in range(x + 1, len(input_arr)):
            for z in range(y + 1, len(input_arr)):
                val1, val2, val3 = input_arr[x], input_arr[y], input_arr[z]
                if val1 + val2 + val3 == 2020:
                    log(f"{val1} + {val2} + {val3} = {val1 + val2 + val3}")
                    return val1 * val2 * val3

    log('No solution')
def part_1():
    input_arr = get_ints_by_lines('1.txt')
    # Loop through every pair in the array
    for x in range(0, len(input_arr)):
        for y in range(x + 1, len(input_arr)):
            val1, val2 = input_arr[x], input_arr[y]
            if val1 + val2 == 2020:
                log(f"{val1} + {val2} = {val1 + val2} (returning {val1 * val2})"
                    )
                return val1 * val2

    log('No solution')
def part_2():
    grid = [[char for char in line] for line in get_strings_by_lines('11.txt')]
    changed = True
    iterations = 0
    print_grid(grid)

    while changed:
        grid, changed = iterate(grid, False)
        iterations += 1
        log(f"iterated {iterations} times")

    print_grid(grid)
    return count_grid(grid)
def part_1():
    jolts = [0] + sorted(get_ints_by_lines('10.txt'))
    jolts += [jolts[-1] + 3]

    log(jolts)

    diffs = [0, 0, 0, 0]
    for idx in range(1, len(jolts)):
        d = jolts[idx] - jolts[idx - 1]
        diffs[d] += 1

    log(diffs)

    return diffs[1] * diffs[3]
示例#12
0
def part_2():
    instructions = get_strings_by_lines('8.txt')
    for idx in range(len(instructions)):
        # Copy the instructions
        copy = [] + instructions
        log(f'trying flipping instruction {idx}')
        if instructions[idx][:3] == 'jmp':
            copy[idx] = 'nop' + instructions[idx][3:]
        elif instructions[idx][:3] == 'nop':
            copy[idx] = 'jmp' + instructions[idx][3:]
        else:
            log('skipping instr: ' + instructions[idx])

        acc, pointer = 0, 0
        already_run = set()

        while pointer not in already_run:
            instr = copy[pointer]
            already_run.add(pointer)
            acc, pointer = run_instr(instr, acc, pointer)

            if pointer == len(instructions):
                log(f'found it flipping idx {idx}')
                return acc

        log('Failed idx {idx}')

    return None
示例#13
0
def set_register(memory, address, value, and_mask, or_mask):
    log(f'value: {format(value, "036b")}')
    log(f'and_mask: {format(and_mask, "036b")}')
    log(f'or_mask: {format(or_mask, "036b")}')
    log(f'result: {format(((value & and_mask) | or_mask), "036b")}')
    memory[address] = (value & and_mask) | or_mask
    return memory
示例#14
0
def part_1():
    instructions = get_strings_by_lines('14.txt')
    memory = {}
    and_mask, or_mask = 0, 0

    for inst in instructions:
        if inst[:4] == 'mask':
            (new_mask, ) = parse('mask = {}', inst)
            and_mask, or_mask = set_bitmask(new_mask)

        else:
            address, value = parse('mem[{:d}] = {:d}', inst)
            memory = set_register(memory, address, value, and_mask, or_mask)

    log(memory)
    return sum(memory.values())
示例#15
0
def part_2():
    instructions = get_strings_by_lines('14.txt')
    memory = {}
    mask = ''

    for inst in instructions:
        if inst[:4] == 'mask':
            (mask, ) = parse('mask = {}', inst)
            log(f"set mask to {mask}")

        else:
            address, value = parse('mem[{:d}] = {:d}', inst)
            memory = write_value_to_decoded_registers(memory, address, mask, value)

    log(memory)
    return sum(memory.values())
示例#16
0
def part_2():
    boarding_passes = get_strings_by_lines('5.txt')
    ids = []
    for bp in boarding_passes:
        row = bin_search(127, bp[:7])
        col = bin_search(8, bp[7:])
        ids += [(row * 8) + col]

    ids.sort()
    log(ids)

    for idx in range(1, len(ids)):
        # Did we skip a number?
        if ids[idx] - ids[idx - 1] != 1:
            return ids[idx] - 1  # Return the skipped number

    return None
示例#17
0
def part_2():
    rows = get_strings_by_lines('3.txt')
    x = 0

    tree_counts = [
        count_trees(rows, slope)
        for slope in [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
    ]
    log(tree_counts)

    # return functools.reduce(lambda x, y: x*y, tree_counts)
    # Yeah, Robin, I know how to reduce stuff too

    product = 1
    for count in tree_counts:
        product *= count
    return product
示例#18
0
def part_1():
    parse_tree()

    root = tree['shiny gold']
    possible_containers = set()
    queue = [] + list(root.parents)

    while len(queue) != 0:
        log(queue)
        curr_str = queue.pop(0)
        curr_node = tree[curr_str]

        possible_containers.add(curr_str)
        for parent in list(curr_node.parents):
            if parent not in possible_containers:
                queue.append(parent)

    return len(list(possible_containers))
示例#19
0
def part_2():
    code = get_ints_by_lines('9.txt')
    goal = part_1()

    for idx in range(len(code)):
        list = []
        sub_idx = idx
        total = 0
        while total < goal and sub_idx < len(code):
            total += code[sub_idx]
            list += [code[sub_idx]]
            sub_idx += 1

        if total == goal:
            log('FOUND IT')
            log(list)
            return min(list) + max(list)

    return None
def handle_instruction(x, y, dir, instr_str):
    instr, amount = instr_str[0], int(instr_str[1:])
    log(instr)
    log(amount)

    if instr == 'E':
        x += amount
    elif instr == 'N':
        y += amount
    elif instr == 'W':
        x -= amount
    elif instr == 'S':
        y -= amount
    elif instr == 'R':
        dir = rotate(dir, amount)
    elif instr == 'L':
        dir = rotate(dir, -1 * amount)
    elif instr == 'F':
        x, y, dir = handle_instruction(x, y, dir, dir + str(amount))

    return x, y, dir
示例#21
0
def part_2():
    earliest, bus_list = get_strings_by_lines('13.txt')
    busses = [ bus for bus in bus_list.split(',') if bus ]

    # Fulfill the constraints one at a time - Once you find a number satisfying
    # Two divisors, future values must be a multiple of that value.
    # AKA for divisors w,x,y,z the minimum value satisfying y must be
    #   <the minimum value satisfying w,x> + (w * x)
    # And then the minimum value satisfying z must be
    #   <the minimum value satisfying w,x,y> + (w * x * y)
    # ETC.
    current_time = 0
    inc = 1
    for idx in range(len(busses)):
        if busses[idx] == 'x':
            log(f'Skipping idx {idx}')
            continue
        curr_bus = int(busses[idx])

        while (current_time + idx) % curr_bus != 0:
            current_time += inc

        log(f'constraint fulfilled! {curr_bus}')
        inc *= curr_bus
        log(f'New Inc: {inc}')

    return current_time
    def _send_command(self, cmd_str):
        """Send command to the projector.

        :param cmd_str: Full raw command string to send to the projector
        """
        ret = None
        try:
            self.serial.write("{}\r".format(cmd_str))
        except OSError as e:
            raise lib.errors.ProjectorError(
                    "Error when Sending command '{}' to projector: {}".\
                        format(cmd_str, e)
                    )
            return ret

        if cmd_str.endswith('?'):
            ret = self._read_response()
            while "=" not in ret and ret != 'ERR':
                ret = self._read_response()
            if ret == 'ERR':
                log("Projector responded with Error!")
                return None
            log("Command sent successfully")
            ret = ret.split('=', 1)[1]
            if ret == "01":
                ret = True
            elif ret == "00":
                ret = False
            elif ret in [
                    _valid_sources_[self.model][x]
                    for x in _valid_sources_[self.model]
            ]:
                ret = [
                    x for x in _valid_sources_[self.model]
                    if _valid_sources_[self.model][x] == ret
                ][0]

            return ret
    def _read_response(self):
        """Read response from projector"""
        read = ""
        res = ""
        while not read.endswith(":"):
            r, w, x = select.select([self.serial.fileno()], [], [],
                                    self.timeout)
            if len(r) == 0:
                raise lib.errors.ProjectorError(
                    "Timeout when reading response from projector")
            for f in r:
                try:
                    read = os.read(f, 256)
                    res += read
                except OSError as e:
                    raise lib.errors.ProjectorError(
                        "Error when reading response from projector: {}".
                        format(e), )
                    return None

        part = res.split('\r', 1)
        log("projector responded: '{}'".format(part[0]))
        return part[0]
    def send_command(self, command, **kwargs):
        """Send command to the projector.

        :param command: A valid command from lib
        :param **kwargs: Optional parameters to the command. For Epson the only
            valid keyword is "source_id" on CMD_SRC_SET.

        :return: True or False on CMD_PWR_QUERY, a source string on
            CMD_SRC_QUERY, otherwise None.
        """
        if not command in _command_mapping_:
            raise lib.errors.InvalidCommandError(
                "Command {} not supported".format(command))

        if command == lib.CMD_SRC_SET:
            cmd_str = _command_mapping_[command].format(**kwargs)
        else:
            cmd_str = _command_mapping_[command]

        log("sending command '{}'".format(cmd_str))
        res = self._send_command(cmd_str)
        log("send_command returned {}".format(res))
        return res
示例#25
0
def in_preamble(search_arr, value):
    log(search_arr)
    log(value)
    for i in range(len(search_arr) - 1):
        for j in range(i + 1, len(search_arr)):
            if search_arr[i] + search_arr[j] == value:
                log(f'found: {search_arr[i]}, {search_arr[j]}')
                return True
    return False
示例#26
0
    def _read_response(self):
        """Read response from projector"""
        read = ""
        res = ""
        # Match either (PWR0) or (LMP?)(0-65535,2344)
        while not re.match('(\([^?]*\)|\(.*\?\)\([-0-9]*,[0-9]*\))', res):
            r, w, x = select.select([self.serial.fileno()], [], [],
                                    self.timeout)
            if len(r) == 0:
                raise lib.errors.ProjectorError(
                    "Timeout when reading response from projector")
            for f in r:
                try:
                    read = os.read(f, 256)
                    res += read
                except OSError as e:
                    raise lib.errors.ProjectorError(
                        "Error when reading response from projector: {}".
                        format(e), )
                    return None

        part = res.split('\n', 1)
        log("projector responded: '{}'".format(part[0]))
        return part[0]
示例#27
0
def part_1():
    code = get_ints_by_lines('9.txt')
    log(code)

    for idx in range(PREAMBLE_LEN, len(code)):
        log(f"checking {idx}")
        if not in_preamble(code[idx - PREAMBLE_LEN:idx], code[idx]):
            log(f"Found {code[idx]} at idx {idx}")
            return code[idx]
    return None
示例#28
0
    def onScreensaverDeactivated(self):
        if self._ss_activation_timer_:
            log("Screensaver deactivated, aborting any scheduled projector shutdown"
                )
            self._ss_activation_timer_.cancel()

        if __addon__.getSetting("at_ss_shutdown") == "true":
            min_turnaround = int(__addon__.getSetting("min_turnaround"))
            time_since_stop = datetime.datetime.now(
            ) - self._last_power_command_
            if time_since_stop.days == 0 and time_since_stop.seconds < min_turnaround:
                log("Screensaver deactivated too soon, will sleep a while before starting projector"
                    )
                xbmc.sleep((min_turnaround - time_since_stop.seconds) * 1000)
            log("Screensaver deactivated, starting projector")
            lib.commands.start()
示例#29
0
def part_1():
    input_arr = get_strings_by_lines('2.txt')
    valid_count = 0

    # Loop through every pair in the array
    for input in input_arr:
        min, max, char, password = parse('{:d}-{:d} {:l}: {:w}', input)
        count = password.count(char)
        log(f"Testing {password} for {min} to {max} {char}'s")

        if min <= count <= max:
            log(f"\tYES")
            valid_count += 1
        else:
            log(f"\tNO")

    return valid_count
示例#30
0
    def _send_command(self, cmd_str):
        """Send command to the projector.

        :param cmd_str: Full raw command string to send to the projector
        """
        ret = None
        try:
            self.serial.write("{}\n".format(cmd_str))
        except OSError as e:
            raise lib.errors.ProjectorError(
                    "Error when Sending command '{}' to projector: {}".\
                        format(cmd_str, e)
                    )
            return ret

        ret = self._read_response()
        while ")" not in ret and ret != '?':
            ret = self._read_response()
        if ret == '?':
            log("Error, command not understood by projector!")
            return None
        log("Command sent successfully!")
        if cmd_str.endswith('?)'):
            r = re.match('\(.+\)\(([-\d]+),(\d+)\)', ret)
            ret = r.group(2)
            if cmd_str in _boolean_commands:
                if int(ret) == 1:
                    ret = True
                elif int(ret) == 0:
                    ret = False
                else:
                    log("Error, unable to parse boolean value!")
                    return None
            elif ret in [
                    _valid_sources_[self.model][x]
                    for x in _valid_sources_[self.model]
            ]:
                ret = [
                    x for x in _valid_sources_[self.model]
                    if _valid_sources_[self.model][x] == ret
                ][0]

            return ret
        else:
            return None