41

Re: Advent of Code

2021_9.rs
fn task1(map: &Vec<Vec<u8>>) -> usize {
    map.iter()
        .enumerate()
        .map(|(i, line)| {
            line.iter()
                .enumerate()
                .filter_map(|(j, &height)| {
                    if (i == 0 || height < map[i - 1][j])
                        && (j == 0 || height < map[i][j - 1])
                        && (i == map.len() - 1 || height < map[i + 1][j])
                        && (j == line.len() - 1 || height < map[i][j + 1])
                    {
                        Some(height as usize + 1)
                    } else {
                        None
                    }
                })
                .sum::<usize>()
        })
        .sum()
}

fn floodfill(map: &mut Vec<Vec<u8>>, i: i32, j: i32) -> usize {
    if i < 0
        || j < 0
        || i >= map.len() as i32
        || j >= map[i as usize].len() as i32
        || map[i as usize][j as usize] == 9
    {
        0
    } else {
        map[i as usize][j as usize] = 9;
        1 + floodfill(map, i - 1, j)
            + floodfill(map, i + 1, j)
            + floodfill(map, i, j - 1)
            + floodfill(map, i, j + 1)
    }
}

fn task2(map: &Vec<Vec<u8>>) -> usize {
    let mut map = map.clone();
    let mut result = Vec::new();
    for i in 0..map.len() {
        for j in 0..map[i].len() {
            result.push(floodfill(&mut map, i as i32, j as i32));
        }
    }
    result.sort();
    result.iter().rev().take(3).fold(1, |x, acc| acc * x)
}

fn main() {
    let input = aoc::get_input_from_ini_with_year("9", "2021").unwrap();
    let map: Vec<Vec<_>> = input
        .lines()
        .map(|line| {
            line.chars()
                .map(|digit| digit.to_digit(10).unwrap() as u8)
                .collect()
        })
        .collect();
    println!("Result1: {}", task1(&map));
    println!("Result2: {}", task2(&map));
}

42 Востаннє редагувалося dot (10.12.2021 09:50:55)

Re: Advent of Code

2021#10, Py3.9.5
pairs = {"(": ")", "[": "]", "{": "}", "<": ">"}
illegal = int()
incomplete = list()

for chunk in [line for line in open("input.txt").read().split()]:
    history = list()
    for ch in chunk:
        if ch not in pairs.keys():
            if ch == pairs[history[-1]]:
                history.pop(-1)
            else:
                illegal += {")": 3, "]": 57, "}": 1197, ">": 25137}[ch]
                history.clear()
                break
        else:
            history.append(ch)
    if history:
        points = int()
        for h in history[::-1]:
            points = points * 5 + {")": 1, "]": 2, "}": 3, ">": 4}[pairs[h]]
        incomplete.append(points)

print("Part One:", illegal)
print("Part Two:", sorted(incomplete)[len(incomplete) // 2])

43 Востаннє редагувалося dot (10.12.2021 10:10:08)

Re: Advent of Code

Troxy zapizno, ale vyrjicyv zrobyty osobystu docku percostjy, tam je otcky i zironjky vykonanyx vprav.

Jak potrapyty: [Leaderboard] → [Private Leaderboard] → You can join a private leaderboard by entering its join code here, de vvodyte 728806-963332f3.

Подякували: koala1

44

Re: Advent of Code

2021/10.py
import aoc

import os
import unittest

NUMBER = os.path.basename(__file__).removesuffix('.py')

def check_brackets(line):
    stack = []
    PAIRS = {'(':')','[':']','{':'}','<':'>'}
    for symb in line:
        if symb in PAIRS:
            stack.append(PAIRS[symb])
        else:
            if not stack or stack.pop()!=symb:
                return (symb, [])
    return ('', stack)

def task1(data: str) -> int:
    VALUES = {'':0,')':3,']':57,'}':1197,'>':25137}
    return sum(VALUES[check_brackets(line)[0]] for line in data.splitlines())
        
def task2(data: str) -> int:
    VALUES = {')':1,']':2,'}':3,'>':4}
    results = []
    for line in data.splitlines():
        result = 0
        symb, closing = check_brackets(line)
        if not symb:
            for brack in reversed(closing):
                result = 5*result + VALUES[brack]
            #print(''.join(closing), result)
            results.append(result)
    results.sort()
    return results[len(results)//2]

class Test(unittest.TestCase):
    def test_brack(self):
        symb, stack = check_brackets('[({(<(())[]>[[{[]{<()<>>')
        self.assertEqual(symb, '')
        self.assertEqual(''.join(reversed(stack)),'}}]])})]')
    def test_task2(self):
        inp = '''[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]'''
        self.assertEqual(task2(inp), 288957)

if __name__ == '__main__':
    #unittest.main()
    data = aoc.load_data(NUMBER, verbose=True)
    print('Task1:', task1(data))
    print('Task2:', task2(data))
Подякували: dot1

45 Востаннє редагувалося koala (10.12.2021 11:09:09)

Re: Advent of Code

2021_10.rs
enum Brackets {
    Correct(Vec<char>),
    Incorrect(char),
}

fn check_brackets(line: &str) -> Brackets {
    let mut stack = Vec::new();
    for symbol in line.chars() {
        match symbol {
            '(' => stack.push(')'),
            '[' => stack.push(']'),
            '{' => stack.push('}'),
            '<' => stack.push('>'),
            closing => {
                if symbol != stack.pop().unwrap() {
                    return Brackets::Incorrect(closing);
                }
            }
        }
    }
    Brackets::Correct(stack)
}

fn task1(data: &str) -> usize {
    data.lines()
        .map(|line| match check_brackets(line) {
            Brackets::Incorrect(')') => 3,
            Brackets::Incorrect(']') => 57,
            Brackets::Incorrect('}') => 1197,
            Brackets::Incorrect('>') => 25137,
            _ => 0,
        })
        .sum()
}

fn task2(data: &str) -> usize {
    let mut scores: Vec<_> = data
        .lines()
        .filter_map(|line| match check_brackets(line) {
            Brackets::Correct(rest) => Some(rest.iter().rev().fold(0, |acc, br| {
                5 * acc
                    + match br {
                        ')' => 1,
                        ']' => 2,
                        '}' => 3,
                        '>' => 4,
                        _ => panic!("wrong char in ending!"),
                    }
            })),
            _ => None,
        })
        .collect();
    scores.sort();
    scores[scores.len() / 2]
}

fn main() {
    let input = aoc::get_input_from_ini_with_year("10", "2021").unwrap();
    println!("Result1: {}", task1(&input));
    println!("Result2: {}", task2(&input));
}

День 10. 1. Є некоректні дужкові вирази. Для виразів з неправильними дужками знайти суму значень (табличних) першої некоректної дужки. 2. Для незакінчених виразів обчислити за формулою значення рядка, який би доповнював до коректного, і знайти медіану цих значень.

Подякували: leofun011

46

Re: Advent of Code

Переробив усю структуру своїх advent_of_code. Раніше у мене була окрема бібліотека для завантаження даних, я створював окремі проєкти для кожної задачі й будував з нуля з усіма залежностями. Тепер у мене майже фреймворк :), окремі задачі лежать по модулях, функції називаються типово, перша побудова нового модуля займає пару секунд проти ~20с раніше. Принагідно звільнилося (з попередніми роками) >5GB старих побудов.

День 11. 1. Є мапа 10х10 восьминогів, що вміють світитися, якщо їхній заряд 10 або більше. На кожному кроці восьминоги накопичують 1 заряд, і якщо спалахують, то додатково заряджають на 1 усіх сусідів, включно з діагональними. Після спалаху заряд стає 0 (зокрема, на цьому кроці не іде зарядка від сусідів). Скільки буде спалахів за 100 кроків? 2. Який перший крок, на якому спалахнуть усі восьминоги одночасно?

year2021/day11.rs
#[derive(Clone)]
pub struct Octopuses {
    map: Vec<Vec<u8>>,
    last_flashed: usize,
}

impl Octopuses {
    fn new(input: &str) -> Octopuses {
        Octopuses {
            map: input.lines()
                      .map(|line|line.chars()
                                     .map(|c|c.to_digit(10).unwrap() as u8)
                                     .collect()
                      ).collect(),
            last_flashed: 0,
        }
    }
    
    fn step(&mut self) -> usize {
        for y in 0..self.map.len() {
            for x in 0..self.map[y].len() {
                self.map[y][x] += 1;
            }
        }
        self.last_flashed = 0;
        loop {
            let mut flashed = 0;
            for y in 0..self.map.len() {
                for x in 0..self.map[y].len() {
                    if self.try_flash(y, x) {
                        flashed += 1;
                    }
                }
            }
            if flashed == 0 {
                break;
            } else {
                self.last_flashed += flashed;
            }
        }
        self.last_flashed
    }

    fn try_flash(&mut self, y: usize, x: usize) -> bool {
        use std::cmp::{min, max};
        if self.map[y][x]<=9 {
            false
        } else {
            self.map[y][x] = 0;
            for dy in max(0, y as i32-1) as usize..min(self.map.len(), y+2) {
                for dx in max(0, x as i32-1) as usize..min(self.map[y].len(), x+2) {
                    if self.map[dy][dx] != 0 {
                        self.map[dy][dx] += 1;
                    }
                }
            }
            true
        }
    }

    fn area(&self) -> usize {
        self.map.len() * self.map[0].len()
    }
}

pub fn parse_input(input: &str) -> Octopuses {
    Octopuses::new(input)
}

pub fn task1(octopuses: &Octopuses) -> usize {
    let mut octopuses = octopuses.clone();
    (0..100).map(|_|octopuses.step()).sum()
}

pub fn task2(octopuses: &Octopuses) -> usize {
    let mut octopuses = octopuses.clone();
    let area = octopuses.area();
    (0..).take_while(|_|octopuses.step() != area).count() + 1
}
Подякували: dot1

47 Востаннє редагувалося dot (11.12.2021 11:39:27)

Re: Advent of Code

2021#11, Py3.9.5
octopuses = [[int(x) for x in l] for l in open("input.txt").read().split()]
grid = {(x, y) for y, l in enumerate(octopuses) for x, _ in enumerate(l)}
count = int()
step = int()

while octopuses != [[0] * 10] * 10:
    octopuses = [[e + 1 for e in l] for l in octopuses]
    fresh = {(x, y) for y, l in enumerate(octopuses) for x, e in enumerate(l) if e > 9}
    exhausted = set()

    sides = lambda x, y: {
        (_x, _y) for _x in (x - 1, x, x + 1) for _y in (y - 1, y, y + 1) if (_x, _y) != (x, y) and (_x, _y) in grid
    }

    while fresh:
        exhausted |= fresh.copy()
        charge = set()
        for f in fresh:
            for x, y in sides(*f):
                octopuses[y][x] += 1
                if octopuses[y][x] > 9 and (x, y) not in exhausted:
                    charge.add((x, y))
        fresh = charge

    for y, l in enumerate(octopuses):
        for x, e in enumerate(l):
            if e > 9:
                octopuses[y][x] = 0
                count += 1

    if step == 99:
        print("Part One", count)

    step += 1

print("Part Two", step)
Подякували: koala1

48

Re: Advent of Code

Гм. Полагодив решту старого коду, призвів до ладу старі тести і залежності і спробував почати з 2015 року. Перша ж задача (1 грудня 2015, задача 1) - у мене відповідь на 1 менша за правильну, і я не бачу, в чому проблема. Загальна кількість дужок у мене непарна, а відповідь на сайті (яку я колись увів) - парна. WTF?

year2015/day1.rs
pub fn task1(instructions: &str) -> i32 {
    instructions.chars()
                .map(|c|match c {
                    '(' =>  1,
                    ')' => -1,
                    _ => panic!("Wrong input"),
                })
                .sum()
}
Подякували: dot1

49

Re: Advent of Code

А ще для ідіотів є така фігня: https://crates.io/crates/advent-of-code
Ні, я розумію, чому таке написали; але кому може захотітися таким користуватися?

Подякували: dot1

50

Re: Advent of Code

Ja davno robyv 2015, a rozbyraty sja ljinky.

2015#1, Py
f = open("input.txt", "r")
floor = pos = 0

for s in f.read():
    if s == '(':
        floor += 1
    else:
        floor -= 1
    pos += 1
    if floor == -1:
        print(f"Basement: {pos}") # Part Two

print(f"Floor: {floor}")  # Part One
f.close()

Pravda, ne zavercyv ctce, spynyv sja na 21, a 19 rozvjazav lyce percu tcastynu.

51

Re: Advent of Code

year2021/day12.rs
use unicode_categories::UnicodeCategories;

type CaveName = String;

#[derive(Clone)]
pub struct CaveNode {
    ways_out: Vec<CaveName>,
    visited: Option<bool>,
}

impl CaveNode {
    fn new(name: &str, neighbor: &str) -> CaveNode {
        CaveNode{
            ways_out: vec![neighbor.to_owned()],
            visited: if name.chars().all(|c|c.is_letter_uppercase())  {
                None
            } else {
                Some(false)
            },
        }
    }
}

type CaveMap = std::collections::HashMap<CaveName, CaveNode>;

pub fn parse_input(input: &str) -> CaveMap {
    let mut map = CaveMap::new();
    for line in input.lines() {
        if let Some(dash) = line.find('-') {
            let left = line[..dash].to_string();
            let right = line[dash+1..].to_string();
            map.entry(left.to_owned())
               .and_modify(|node|node.ways_out.push(right.to_owned()))
               .or_insert(CaveNode::new(&left, &right));
            map.entry(right.to_owned())
               .and_modify(|node|node.ways_out.push(left.to_owned()))
               .or_insert(CaveNode::new(&right, &left));
        }
    }
    map
}

fn count_ways(map: &mut CaveMap, start: &str, end: &str) -> usize {
    if start == end {
        return 1;
    }
    if map[start].visited == Some(true) {
            return 0;
    }
    let start = start.to_string();
    if map[&start].visited.is_some() {
        map.entry(start.to_owned()).and_modify(|node|node.visited = Some(true));
    }
    let result = (0..map[&start].ways_out.len()).map(|i|{
        let name = map[&start].ways_out[i].to_owned();
        count_ways(map, &name, end)
    }).sum();
    if map[&start].visited.is_some() {
        map.entry(start).and_modify(|node|node.visited = Some(false));
    }
    result
}

pub fn task1(map: &CaveMap) -> usize {
    let mut map = map.clone();
    count_ways(&mut map, "start", "end")
}

fn count_ways2(map: &mut CaveMap, start: &str, end: &str, start_visited: bool, small_visited_twice: bool) -> usize {
    if start == end {
        return 1;
    }
    if start=="start" && start_visited {
        return 0;
    }
    let in_visited_small = map[start].visited.unwrap_or(false);
    if small_visited_twice && in_visited_small {
        return 0;
    }
    let start = start.to_string();
    if map[&start].visited.is_some() {
        map.entry(start.to_owned()).and_modify(|node|node.visited = Some(true));
    }
    let result = (0..map[&start].ways_out.len()).map(|i|{
        let name = map[&start].ways_out[i].to_owned();
        count_ways2(map, &name, end, true, small_visited_twice || in_visited_small)
    }).sum();
    if !in_visited_small && map[&start].visited.is_some() {
        map.entry(start).and_modify(|node|node.visited = Some(false));
    }
    result
}

pub fn task2(map: &CaveMap) -> usize {
    let mut map = map.clone();
    count_ways2(&mut map, "start", "end", false, false)
}

День 12. 1. Є граф печери з початком і кінцем. Деякі вузли можна відвідувати кілька разів, решту - лише один. Скільки існує шляхів крізь печеру? 2. Можна один раз відвідати уже відвіданий вузол, який зазвичай не можна відвідувати повторно. Скільки тепер?

Подякували: dot1

52

Re: Advent of Code

Боюся, що я на тиждень зникну з форуму. Можливо, завтра вранці ще допишу. А потім же доробляти... ех...

Подякували: 0xDADA11C71

53 Востаннє редагувалося dot (12.12.2021 22:59:31)

Re: Advent of Code

Ne duge ljubju taki rekursivni zadatcky.

2021#12, Py3.9.5
from collections import defaultdict

caves = defaultdict(set)
for one, two in [line.split("-") for line in open("input.txt").read().splitlines()]:
    caves[one].add(two)
    caves[two].add(one)

caves = {i: caves[i] - {"start"} for i in caves}


def visit(twice=True, c="start", visited=set()):
    count = int()
    for cave in caves[c]:
        if cave == "end":
            count += 1
        elif cave.isupper():
            count += visit(twice, cave, visited)
        elif cave not in visited:
            count += visit(twice, cave, visited | {cave})
        elif not twice:
            count += visit(True, cave, visited | {cave})
    return count


print("Part One:", visit())
print("Part Two:", visit(False))

54

Re: Advent of Code

До речі, мій ҐітГаб з AoC/Rust.

Подякували: dot, leofun012

55 Востаннє редагувалося dot (13.12.2021 00:42:13)

Re: Advent of Code

koala написав:

Боюся, що я на тиждень зникну з форуму. Можливо, завтра вранці ще допишу. А потім же доробляти... ех...

Nitcʼ stracnoho! Raptovi spravy tcy ctcosj svojo buvaʼ. Tcekaju za tygdenj! Koly ctco, poskladneni zadatcky zazvytcaj buvajutj na vyxidnyx, jakctco ne pomyljaju sja.

56 Востаннє редагувалося dot (14.12.2021 18:25:14)

Re: Advent of Code

2021, Py.3.9.5

13
from re import findall


def folding(axis: str, number: int) -> list:
    folded = list()
    for n in range(1, number + 1):
        for x, y in set(dots):
            if axis == "x" and x in (number - n, number + n):
                folded.append((number - n, y))
            elif axis == "y" and y in (number - n, number + n):
                folded.append((x, number - n))
    return folded


def visualing() -> None:
    max_x, max_y = [max(el) + 1 for el in [*zip(*dots)]]
    for y in range(max_y):
        for x in range(max_x):
            print("#" if (x, y) in dots else " ", end="")
        print("\n", end="")
    print()


dots = list()
actions = list()
instructions = False

for line in open("input.txt").read().splitlines():
    if not line:
        instructions = True
        continue
    if instructions:
        axis, number = findall(r"([xy])=(\d+)", line)[0]
        actions.append((axis, int(number)))
    else:
        dots.append(tuple(map(int, findall(r"\d+", line))))

for number, action in enumerate(actions):
    dots = folding(*action)
    if number == 1:
        print("Part One:", len(dots))

print("Part Two:")
visualing()
14
from collections import Counter

polymer, _, *rules = open("input.txt").read().splitlines()
rules = dict(rule.split(" -> ") for rule in rules)
pairs = Counter(polymer[i] + polymer[i + 1] for i in range(len(polymer) - 1))
chars = Counter(polymer)
steps = (10, 40)

for i in range(1, steps[-1] + 1):
    for (a, b), count in pairs.copy().items():
        if a + b in rules.keys():
            insert = rules[a + b]
            pairs[a + b] -= count
            pairs[a + insert] += count
            pairs[insert + b] += count
            chars[insert] += count
    if i in steps:
        print("Answer:", max(chars.values()) - min(chars.values()))

57 Востаннє редагувалося dot (16.12.2021 05:54:44)

Re: Advent of Code

2021#15, Py3.9.5
from queue import PriorityQueue
from collections import defaultdict


def plus_form_sides(_y, _x, y_len, x_len):
    for side_y, side_x in ((1, 0), (-1, 0), (0, 1), (0, -1)):
        y, x = (_y + dr, _x + dc)
        if 0 <= y < y_len and 0 <= x < x_len:
            yield (y, x)


# Updated from:
# https://stackabuse.com/dijkstras-algorithm-in-python
def dijkstra(graf: list) -> int:
    y_len, x_len = len(graf), len(graf[0])
    visited = set()

    start_vertex = (0, 0)
    stop_vertex = (y_len - 1, x_len - 1)

    min_distances = defaultdict(lambda: float("inf"))
    min_distances[start_vertex] = 0

    pq = PriorityQueue()
    pq.put((0, start_vertex))

    while not pq.empty():
        distance, current_vertex = pq.get()

        if current_vertex == stop_vertex:
            return distance

        if current_vertex in visited:
            continue

        visited.add(current_vertex)

        for y, x in plus_form_sides(*current_vertex, y_len, x_len):
            if (y, x) in visited:
                continue

            new_distance = distance + graf[y][x]

            if new_distance < min_distances[(y, x)]:
                min_distances[(y, x)] = new_distance
                pq.put((new_distance, (y, x)))

    return float("inf")


cavern = [list(map(int, list(line))) for line in open("input.txt").read().splitlines()]

print("Part One:", dijkstra(cavern))

blocks = [[[v + s if v + s < 10 else v + s - 9 for v in row] for row in cavern] for s in range(9)]
y_len, x_len = len(blocks), len(blocks[0])

cavern = list()
larger = 5

for s in range(larger):
    for x in range(x_len):
        row = list()
        for y in range(larger):
            row.extend(blocks[y + s if y + s < y_len else y + s - y_len][x])
        cavern.append(row)

print("Part Two:", dijkstra(cavern))
Sutj

Zadatca osnovana na alqoritmi Dejkstry, mogna, hadaju, takog tcerez A* (pro njoho piznav piznjice, ale sprobuju, pry nahodji), hlybynoju i cyrynoju. Ljinjky bulo z nula pysaty, tomu tupo vzjav hotovu funtsiju — vkazano vidky, ale pryiclo sja perepysaty, a potim, sebto dlja druhoji zadatcy, znov perepysaty, bo tak poviljno robylo, ctco mij komp vge vbyvav Xroma, VS Koda i, lybonj, samoho sebe.

Tcas druhoji.

time python3 main.py  
6,05s user 
0,14s system 

58

Re: Advent of Code

І я знову тут!

2021/day13.rs
#[derive(Copy, Clone)]
pub enum Fold {
    X,
    Y,
}

#[derive(Clone)]
pub struct InvisiblePaper {
    dots: std::collections::HashSet<(i32, i32)>,
    folds: Vec<(Fold, i32)>,
}

impl InvisiblePaper {
    fn do_fold(&mut self, fold: (Fold, i32)) {
        self.dots = self.dots
                        .iter()
                        .map(|dot|
                            match fold.0 {
                                Fold::X => (fold.1 - (fold.1-dot.0).abs(), dot.1),
                                Fold::Y => (dot.0, fold.1 - (fold.1-dot.1).abs()),
                            })
                        .collect();
    }
}

pub fn parse_input(input: &str) -> InvisiblePaper {
    let lines = input.lines();
    let mut dots_done = false;
    let mut data = InvisiblePaper {
        dots: std::collections::HashSet::new(), 
        folds: Vec::new(),
    };
    for line in lines {
        if line.is_empty() {
            dots_done = true;
        } else {
            if !dots_done {
                let mut dot = line.split(',');
                data.dots.insert((dot.next().unwrap().parse().unwrap(),
                                dot.next().unwrap().parse().unwrap()));
            } else {
                let mut fold = line.split('=');
                let fold_type = if fold.next().unwrap().chars().nth(11)==Some('x') {
                    Fold::X
                } else {
                    Fold::Y
                };
                data.folds.push((fold_type,fold.next().unwrap().parse().unwrap()));
            }
        }
    }
    data
}

pub fn task1(data: &InvisiblePaper) -> usize {
    let mut data = data.clone();
    data.do_fold(data.folds[0]);
    data.dots.len()
}

pub fn task2(data: &InvisiblePaper) -> usize {
    let folds = &data.folds;
    let mut data = data.clone();
    for &fold in folds {
        data.do_fold(fold);
    }
    let max_x = data.dots.iter().map(|(x, _)|x).max().unwrap() + 1;
    let max_y = data.dots.iter().map(|(_, y)|y).max().unwrap() + 1;
    for y in 0..max_y {
        for x in 0..max_x {
            print!("{}", if data.dots.contains(&(x,y)) {"#"} else {"."});
        }
        println!("");
    }
    0
}

59

Re: Advent of Code

Z povernennjem! A ja sprobuju vge pidkljutcyty sja pislja/zavtra.

60

Re: Advent of Code

Перша частина є:

year2021/day14.rs
#[derive(Clone)]
pub struct PolymerData {
    polymer: Vec<char>,
    rules: std::collections::HashMap<(char, char), char>,
}

pub fn parse_input(input: &str) -> PolymerData {
    let mut lines = input.lines();
    let mut polymer_data = PolymerData {
        polymer: lines.next().unwrap().chars().collect(),
        rules: std::collections::HashMap::new(),
    };
    lines.next();
    for line in lines {
        let mut parts = line.split(" -> ");
        let left = parts.next().unwrap();
        let right = parts.next().unwrap();
        polymer_data.rules.insert(
            (left.chars().nth(0).unwrap(), left.chars().nth(1).unwrap()),
            right.chars().nth(0).unwrap(),
        );
    }
    polymer_data
}

pub fn task1(data: &PolymerData) -> usize {
    let mut polymer = data.polymer.clone();
    for _ in 0..10 {
        let mut new_polymer = vec![polymer[0]];
        for pair in polymer.windows(2) {
            if let &[left, right] = pair {
                match data.rules.get(&(left, right)) {
                    Some(&v) => new_polymer.push(v),
                    _ => (),
                }
                new_polymer.push(right);
            }
        }
        polymer = new_polymer;
    }

    let mut counter = std::collections::HashMap::new();
    for element in polymer {
        *counter.entry(element).or_insert(0) += 1;
    }
    let min = counter.values().min().unwrap();
    let max = counter.values().max().unwrap();
    max - min
}

pub fn task2(data: &PolymerData) -> usize {
    let mut polymer = data.polymer.clone();
    for _ in 0..40 {
        let mut new_polymer = vec![polymer[0]];
        for pair in polymer.windows(2) {
            if let &[left, right] = pair {
                match data.rules.get(&(left, right)) {
                    Some(&v) => new_polymer.push(v),
                    _ => (),
                }
                new_polymer.push(right);
            }
        }
        polymer = new_polymer;
    }

    let mut counter = std::collections::HashMap::new();
    for element in polymer {
        *counter.entry(element).or_insert(0) += 1;
    }
    let min = counter.values().min().unwrap();
    let max = counter.values().max().unwrap();
    max - min
}

Другу скопіював з першої, дістав

memory allocation of 34359738368 bytes failed

Завтра зроблю мемоїзацію, ніби очевидно, як.