Advent of Code 2019 🤯 (יום 4)

תגיות: ,

שרשור Advent of Code יום 1 נחל הצלחה גדולה, וגם ימים 2 ו־3 שהיו משמעותית קשוחים מקודמם.

אני מניח שהאתגר הזה ישאר פה לפחות ליומיים שלושה, אז קחו את הזמן :slight_smile:
ואם לא הספקתם לפתור את הימים הקודמים – לא חובה, אבל לכו על זה! אלו תרגילים נחמדים מאוד שישפרו את היכולות שלכם מאוד.

אז קדימה, פרסמו פה את הפתרונות שלכם ליום הרביעי של Advent of Code!

לייק 1
חלק 1

חלק 2

5 לייקים
חלק 1
def is_optional_password(numbers):
    couple = False
    for i in range(len(numbers) - 1):
        first , second = int(numbers[i]), int(numbers[i + 1])
        if first > second:
            return False
        elif first == second:
            couple = True
    return couple


def get_optional_paddword(x=125730, y=579381):
    counter = 0
    for number in range(x, y):
        if is_optional_password(list(str(number))):
            counter += 1
    return counter


get_optional_paddword()
חלק 2 - ההבדל הוא רק בשורת התנאי
def is_optional_password(numbers):
    couple = False
    for i in range(len(numbers) - 1):
        first , second = int(numbers[i]), int(numbers[i + 1])
        if first > second:
            return False
        elif first == second and numbers.count(str(first)) == 2:
            couple = True
    return couple


def get_optional_paddword(x=125730, y=579381):
    counter = 0
    for number in range(x, y):
        if is_optional_password(list(str(number))):
            counter += 1
    return counter


get_optional_paddword()
3 לייקים
שני החלקים
import collections

PUZZLE_INPUT = '264360-746325'


def len_is_6(pw):
    return len(str(pw)) == 6


def pw_has_doubles(pw):
    pw = str(pw)
    for i in range(1, len(pw)):
        if pw[i] == pw[i - 1]:
            return True
    return False


def pw_has_doubles_v2(pw):
    pw = str(pw)
    cnt = collections.Counter(pw)
    for char in pw:
        if cnt[char] == 2:
            return True
    return False



def never_decreasing(pw):
    pw = str(pw)
    for i in range(1, len(pw)):
        if pw[i] < pw[i - 1]:
            return False
    return True


def check_pw_validity(pw, v=1):
    doubles = (pw_has_doubles, pw_has_doubles_v2)
    functions = (len_is_6, doubles[v - 1], never_decreasing)
    for func in functions:
        if not func(pw):
            return False
    return True


def count_valid_passwords(min_num, max_num, v=1):
    valid_passwords = 0
    for pw in range(int(min_num), int(max_num) + 1):
        if check_pw_validity(pw, v):
            valid_passwords += 1

    return valid_passwords


print(count_valid_passwords(*PUZZLE_INPUT.split('-')))
print('-' * 10)
print(count_valid_passwords(*PUZZLE_INPUT.split('-'), v=2))
2 לייקים

:star2: :star2:
תרגיל כיפי - מעניין לאיפה החללית תגיע בסוף :flying_saucer:

Part 1 & 2
#  day 4
# part 1 & 2
def check_if_digits_increase_and_1_same_number(number):
    number = str(number)
    digit = 1
    ident = 0
    while digit < len(number):
        if int(number[digit - 1]) > int(number[digit]):
            return False
        if number[digit - 1] == number[digit]:
            ident = 1
        digit += 1
    if ident == 1:
        return True
    return False

def check_if_digits_increase_and_1_same_number_part2(number):
    number = str(number)
    digit = 1
    ident = {n: 0 for n in range(10)}
    while digit < len(number):
        if int(number[digit - 1]) > int(number[digit]):
            return False
        if number[digit - 1] == number[digit]:
            ident[int(number[digit])] += 1
        digit += 1
    if 1 in ident.values():
        return True
    return False


def count_in_range(num1, num2):
    counter = 0
    for num in range(num1, num2 + 1):
        if check_if_digits_increase_and_1_same_number(num):
            counter += 1
    return counter


def count_in_range2(num1, num2):
    counter = 0
    for num in range(num1, num2 + 1):
        if check_if_digits_increase_and_1_same_number_part2(num):
            counter += 1
    return counter


print(f"answer part 1 : {count_in_range(272091, 815432)}")
print(f"answer part 2 : {count_in_range2(272091, 815432)}")
2 לייקים
תשובה - חלק 1
# range input 254032-789860
def check_if_duplicates(num):
    set_of_digits = set()
    for digit in str(num):
        if digit in set_of_digits:
            return True
        else:
            set_of_digits.add(digit)
    return False


def is_valid_number(num):
    current_max = 0
    for digit in str(num):
        if int(digit) < current_max:
            return False
        else:
            current_max = int(digit)
    result = check_if_duplicates(num)
    return result


def find_valid_passwords_count(range_from, range_to):
    valid_pass = [num for num in range(range_from, range_to) if is_valid_number(num)]
    return len(valid_pass)


print(find_valid_passwords_count(254032, 789860))  # part I - 1033

תשובה - חלק 2
# range input 254032-789860
def is_valid_pass(num):
    result = False
    for i in range(5):
        x, y = (str(num)[i], str(num)[i+1])
        if x == y and str(num).count(x) == 2:
            result = True
    return result


def is_valid_number(num):
    current_max = 0
    for digit in str(num):
        if int(digit) < current_max:
            return False
        else:
            current_max = int(digit)
    result = is_valid_pass(num)
    return result


def find_valid_passwords_count(range_from, range_to):
    counter = 0
    for num in range(range_from, range_to + 1):
        if is_valid_number(num):
            counter += 1
    return counter


print(find_valid_passwords_count(254032, 789860))  # part II - 670

לייק 1

תרגיל חדש יפורסם בבוקר יום שישי – מהרו להגיש! זה תרגיל לא קשה במיוחד ושווה לנסות אותו :slight_smile:

תרגיל 1
# Day 4

def key_options():
    return [
        key for key in range(136818, 685980)
        if is_bigger(list(str(key))) and is_got_couple(list(str(key)))
    ]


def is_bigger(digits):
    next_num = 1
    for num in range(len(digits) - 1):
        if int(digits[num]) <= int(digits[next_num]):
            next_num += 1
        else:
            return False
    return True


def is_got_couple(digits):
    next_num = 1
    for num in range(len(digits) - 1):
        if int(digits[num]) == int(digits[next_num]):
            return True
        next_num += 1
    return False

    
len(key_options())

תרגיל 2
# Day 4

def key_options():
    return [
        key for key in range(136818, 685980)
        if is_bigger(list(str(key))) and is_got_couple(list(str(key)))
    ]


def is_bigger(digits):
    next_num = 1
    for num in range(len(digits) - 1):
        if int(digits[num]) <= int(digits[next_num]):
            next_num += 1
        else:
            return False
    return True


def is_got_couple(digits):
    next_num = 1
    for num in range(len(digits) - 1):
        if int(digits[num]) == int(digits[next_num]) and digits.count(digits[num]) == 2:
            return True
        next_num += 1
    return False

    
len(key_options())

לייק 1
Advent of Code, Day 4
# Advent of Code, Day 4
def calc_passwords_amount(min_val, max_val):
    # Part 1
    count = 0
    for password in range(int(min_val), int(max_val) + 1):
        if is_valid_part1(password):
            count += 1
    print(count)
    # Part 2
    count = 0
    for password in range(int(min_val), int(max_val) + 1):
        if is_valid_part2(password):
            count += 1
    print(count)


def is_valid_part1(password):
    min_dig = 0
    doubles = 0
    i = 0
    while i < 6:
        digit = int(str(password)[i])
        if digit < min_dig:
            return False
        if digit == min_dig:
            doubles += 1
        min_dig = digit
        i += 1
    if doubles >= 1:
        return True


def is_valid_part2(password):
    min_dig = 0
    is_double = False
    is_triple = False
    digits_count = {num: 0 for num in range(10)}
    i = 0
    no_triples = True
    while i < 6:
        digit = int(str(password)[i])
        if digit < min_dig:
            return False
        min_dig = digit
        digits_count[digit] += 1
        i += 1
    for num in digits_count:
        if digits_count.get(num) == 2:
            is_double = True
    if is_double:
        return True


calc_passwords_amount('235741', '706948')
לייק 1
הפתרון שלי
def is_increase(i):
    return sorted(i) == list(i)


def is_two_adjacents(i):
    return any(i[j] == i[j-1] for j in range(1, len(i)))


def is_exactly_two_adjacents(i):
    return any(i.count(j) == 2 for j in set(i))


# Part 1
inputs = map(str, range(272091, 815432))
matched_numbers = [i for i in inputs if is_increase(i) and is_two_adjacents(i)]
print(len(matched_numbers))

# Part 2
print(sum(map(is_exactly_two_adjacents, matched_numbers)))
8 לייקים

אחלה פתרון! אלגנטי מאוד. לא חשבתי על זה ש-any שימושי ביותר פה

2 לייקים

def find_how_many(begin,end):
    c=0
    for i in range(begin,end+1):
        if good_pass(str(i)):
            c+=1
    return c  

def good_pass(password):
    password=list(password)
    return sorted(password) == password and find_two_digits_part_two(password)
    
def find_two_digits_part_one(password):
    for i in range(len(password)-1):
        if password[i] == password[i+1]:
            return True
    return False

def find_two_digits_part_two(password):
    a=[]
    for i in range(len(password)-1):
        if password[i] == password[i+1]:
            a.append(password.count(password[i]))
    return 2 in a
            


print(find_how_many(234208,765869))
לייק 1
def get_input(puzzle_input):
    return list(map(int, puzzle_input.split('-')))


def check_criteria_first(num):
    if len(str(num)) != 6: 
        return False

    return check_streak_first(num)


def check_criteria_second(num):
    str_num = str(num)
    str_num_length = len(str_num)
    if str_num_length != 6: 
        return False

    success = False
    for x in range(1, str_num_length):
        if str_num[x] < str_num[x - 1]:
            return False
 
    return check_streak_second(num)


def check_streak_first(num):
    str_num = str(num)
    str_num_length = len(str_num)

    success = False
    for x in range(1, int(str_num_length)):
        if str_num[x] < str_num[x - 1]:
            return False
        
        if str_num[x] == str_num[x - 1]:
            success = True
    
    return success


def check_streak_second(num):
    str_num = str(num)
    str_num_length = len(str_num)
    matching = {}

    streak = False
    for x in range(str_num_length):
        if str_num[x] == str_num[x - 1]:
            if str_num[x] not in matching or not streak:
                matching[str_num[x]] = 2
            else:
                matching[str_num[x]] += 1

            streak = True
        else:
            streak = False

    if 2 in matching.values():
        return True
    else:
        return False


def get_passwords(range_start, range_end, f):
    iterable = range(range_start, range_end + 1)
    return list(filter(f, iterable))


def main():
    puzzle_input = '273025-767253'
    range_start, range_end = get_input(puzzle_input)

    # First Part
    passwords = get_passwords_first(range_start, range_end, check_criteria_first)
    print(len(passwords))

    # Second Part
    passwords = get_passwords(range_start, range_end, check_criteria_second)
    print(len(passwords))


main()
לייק 1