Skip to content
Snippets Groups Projects
Select Git revision
  • 8bd4d68364fc19959f52a4670c75ef072c397c37
  • main default protected
2 results

day_11_olle.py

Blame
  • day_11_olle.py 2.88 KiB
    from typing import List, Dict
    import time
    def read_file(filename:str) -> List[str]:
        with open(filename) as f:
            return f.read().strip().split(' ')
    
    def read_file_optimized(filename:str) -> Dict[str, int]:
        arrangement = read_file(filename)
        new_arrangement = {}
        for stone in arrangement:
            try:
                new_arrangement[stone] += 1
            except KeyError:
                new_arrangement[stone] = 1
        return new_arrangement
    
    
    def blink(arrangement:List[str]) -> List[str]:
        new_arrangement = []
        for stone in arrangement:
            if int(stone) == 0:
                new_arrangement.append('1')
            elif len(stone) % 2 == 0:
                first_half = stone[:len(stone)//2]
                second_half = stone[len(stone)//2:]
                # remove leading zeros of second half
                second_half = str(int(second_half))
                new_arrangement.append(first_half)
                new_arrangement.append(second_half)
            else:
                new_arrangement.append(str(int(stone) * 2024))
        return new_arrangement
    
    def blink_optimized(arrangement: Dict[str, int]) -> Dict[str, int]:
        new_arrangement = {}
        for stone, count in arrangement.items():
            if int(stone) == 0:
                try:
                    new_arrangement['1'] += count
                except KeyError:
                    new_arrangement['1'] = count
            elif len(stone) % 2 == 0:
                first_half = stone[:len(stone)//2]
                second_half = stone[len(stone)//2:]
                # remove leading zeros of second half
                second_half = str(int(second_half))
                try:
                    new_arrangement[first_half] += count
                except KeyError:
                    new_arrangement[first_half] = count
                try:
                    new_arrangement[second_half] += count
                except KeyError:
                    new_arrangement[second_half] = count
            else:
                try:
                    new_arrangement[str(int(stone) * 2024)] += count
                except KeyError:
                    new_arrangement[str(int(stone) * 2024)] = count
        return new_arrangement
    
    
    if __name__ == '__main__':
        arrangement = read_file('input')
        new_arrangement = read_file_optimized('input')
        tic = time.time()
        for i in range(25):
            arrangement = blink(arrangement)
        toc = time.time()
        print(f"25 blinks took {toc-tic} seconds with unoptimized version")
        print("Number of stones after 25 blinks:  ", len(arrangement))
        tic = time.time()
        for i in range(25):
            new_arrangement = blink_optimized(new_arrangement)
        toc = time.time()
        print(f"25 blinks took {toc-tic} seconds with optimized version")
        print("Number of stones after 25 blinks:  ", sum(new_arrangement.values()))
        new_arrangement = read_file_optimized('input')
        for i in range(75):
            new_arrangement = blink_optimized(new_arrangement)
        print("Number of stones after 75 blinks: ", sum(new_arrangement.values()))