81

Re: Advent of Code

О, завершилося. Якихось 8 хвилин, а мені ліньки дочекатися було.
   Compiling advent_of_code v0.1.0 (C:\Users\Pavlo\Documents\Program Languages\rust\advent_of_code)
    Finished dev [unoptimized + debuginfo] target(s) in 4.40s
     Running `target\debug\advent_of_code.exe`
year2021 day22
Result 1: 648681
Result 2: 1302784472088899
Time elapsed: 416185ms
[Finished in 421.2s]

82

Re: Advent of Code

Dosjê ne zaveršyv jakyjsj rôk, xex. Ale tšas vôd tšasu proxodžu stari propuštšeni. Osj tut np. vôdkryv dlja sebe funktsiju maketrans, štšo korysna pry ssuvê Tsezara.

2016#04 Python 30.10.4
import re, string
from collections import Counter

with open("input.txt") as file:
    sum_sid = 0
    abc = string.ascii_lowercase

    for name, sid, checksum in re.findall(r"([a-z-]+)(\d+)\[(\w+)\]", file.read()):
        sid = int(sid)

        if "".join(l for _, l in sorted((-n, l) for l, n in Counter(name.replace("-", "")).most_common())).startswith(checksum):
            sum_sid += sid

        if "north" in name.translate(name.maketrans(abc, abc[sid % len(abc) :] + abc[: sid % len(abc)])):
            print(sid)  # Part Two: 324

    print(sum_sid)  # Part One: 245102

83 Востаннє редагувалося dot (11.10.2022 02:32:55)

Re: Advent of Code

AoC bude v 2022 roku.

84 Востаннє редагувалося dot (01.12.2022 18:55:42)

Re: Advent of Code

2022#01 Python
elves = sorted(map(sum, [map(int, elf.split()) for elf in open("input.txt").read().split("\n\n")]))

print(elves[-1])  # Part One: 68442
print(sum(elves[-3:]))  # Part Two: 204837
Подякували: leofun01, koala2

85

Re: Advent of Code

Умова: ельфи мають в рюкзаках смаколики, калорійність яких вказана в рядках завдання, різні ельфи відокремлені порожнім рядком. Знайти:
1. Найбільшу суму калорійностей смаколиків в одного ельфа
2. 3 найбільші суми

2022#01 Rust
pub fn parse_input(input: &str) -> Vec<u32> {
    let mut result = vec![0];
    for calories in input.lines() {
        if let Ok(calories) = calories.parse::<u32>() {
            let idx = result.len() - 1;
            result[idx] += calories;
        } else {
            result.push(0);
        }
    }
    result.sort();
    result
}

pub fn task1(elves: &[u32]) -> u32 {
    elves[elves.len() - 1]
}

pub fn task2(elves: &[u32]) -> u32 {
    elves[elves.len() - 3..].iter().sum()
}
Подякували: leofun01, dot2

86

Re: Advent of Code

2022#2, Python
by_selected: int = 0
by_outcome: int = 0

selected = {
    "X": 1,
    "Y": 2,
    "Z": 3,
}

outcome = {
    "A": [3, 6, 0],
    "B": [0, 3, 6],
    "C": [6, 0, 3],
}

with open("input.txt") as file:
    for line in file:
        elf, me = line.split()
        by_selected += selected[me] + outcome[elf][selected[me] - 1]
        result = (selected[me] - 1) * 3
        by_outcome += result + outcome[elf].index(result) + 1

print(by_selected)  # Part One: 10941
print(by_outcome)  # Part Two: 13071
Подякували: leofun011

87 Востаннє редагувалося koala (02.12.2022 13:40:23)

Re: Advent of Code

У ельфів чемпіонат з Каменя-Ножиць-Паперу. Очки даються за фігуру (камінь-1, папір-2, ножиці-3) і результат (поразка-0, нічия-3, перемога-6), тобто якщо гравець показав камінь і виграв, то отримує 7 балів. Є інструкція (запис матчу) з рядків, де перша літера A,B,C, а друга (через пробіл) - X,Y,Z. A,B,C позначає відповідно камінь, папір і ножиці опонента. Знайти очки за матч, якщо:
1. X,Y,Z означає ваші камінь, папір і ножиці відповідно;
2. X,Y,Z означає ваші поразку, нічию і перемогу відповідно.

2022#2, Rust
pub fn parse_input(input: &str) -> Vec<&str> {
    input.lines().collect()
}

// score for the second player
fn outcome(line: &str) -> i32 {
    match line {
        "A X" => 3 + 1,
        "A Y" => 6 + 2,
        "A Z" => 0 + 3,
        "B X" => 0 + 1,
        "B Y" => 3 + 2,
        "B Z" => 6 + 3,
        "C X" => 6 + 1,
        "C Y" => 0 + 2,
        "C Z" => 3 + 3,
        _ => panic!(),
    }
}

pub fn task1(input: &[&str]) -> i32 {
    input.iter().map(|line| outcome(line)).sum()
}

fn correct_outcome(line: &str) -> i32 {
    match line {
        "A X" => 0 + 3,
        "A Y" => 3 + 1,
        "A Z" => 6 + 2,
        "B X" => 0 + 1,
        "B Y" => 3 + 2,
        "B Z" => 6 + 3,
        "C X" => 0 + 2,
        "C Y" => 3 + 3,
        "C Z" => 6 + 1,
        _ => panic!(),
    }
}

pub fn task2(input: &[&str]) -> i32 {
    input.iter().map(|line| correct_outcome(line)).sum()
}

Ліньки було з модулями розбиратися, всього 9 рядків. Мабуть, Спока і Ящірку б теж хардкодив. От якби щось таке було...

оновив картинку...

https://replace.org.ua/uploads/images/931/73b1aab452327bac976af4a62e3229a3.jpg

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

88 Востаннє редагувалося dot (02.12.2022 15:42:32)

Re: Advent of Code

Pobaćyv rêśennja zadaćy, de ne treba stvorjuvaty tablycjy, prosto ćerez ord i moduljnu matematiku. Dosytj elegantno.

2022#2, Python
score = 0
    for line in sys.stdin:
        rnd = line.split()
        opp = ord(rnd[0]) - ord('A')    # ascii
        me = ord(rnd[1]) - ord('X')     # haxx!
        score += me + 1 + ((me - opp + 1) % 3) * 3

    print(score)

Do druhojê zamênyty lyśe tyj rjadok:

        me = (ord(rnd[1]) - ord('X') - 1 + opp) % 3     # haxx!
Подякували: leofun011

89

Re: Advent of Code

dot написав:

zamnênyty

Це помилка чи якась особливість вашої латинки? В слові "замінити" одне н.

90

Re: Advent of Code

koala написав:
dot написав:

zamnênyty

Це помилка чи якась особливість вашої латинки? В слові "замінити" одне н.

Pomylka.

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

91 Востаннє редагувалося koala (03.12.2022 08:33:43)

Re: Advent of Code

Умова: ельфи несуть рюкзаки з речами (стрічки латинських символів). Кожна річ має вартість (маленька літера a-z - 1-26, велика A-Z - 27-52).
1. Знайти у кожному рюкзаку єдину річ, що повторюється в першій і другій половині, повернути суму вартостей цих речей.
2. Ельфи йдуть групами по троє (в заданому у вхідних даних порядку). Знайти у кожній трійці спільну річ, повернуту суму вартостей цих речей.

2022#3, Rust
fn value(c: char) -> u32 {
    if c.is_uppercase() {
        (c as u8 - b'A') as u32 + 27
    } else {
        (c as u8 - b'a') as u32 + 1
    }
}

pub fn parse_input(input: &str) -> Vec<Vec<u32>> {
    input
        .lines()
        .map(|line| line.chars().map(|c| value(c)).collect())
        .collect()
}

use std::collections::HashSet;

pub fn task1(input: &[Vec<u32>]) -> u32 {
    input
        .iter()
        .map(|backpack| {
            let (left, right) = backpack.split_at(backpack.len() / 2);
            let left: HashSet<_> = left.iter().collect();
            right
                .iter()
                .find_map(|item| {
                    if left.contains(&item) {
                        Some(item)
                    } else {
                        None
                    }
                })
                .unwrap()
        })
        .sum()
}

pub fn task2(input: &[Vec<u32>]) -> u32 {
    let mut result = 0;
    for group in input.chunks(3) {
        let mut badges: HashSet<_> = group[0].iter().collect();
        for i in 1..3 {
            badges = badges
                .intersection(&group[i].iter().collect())
                .copied()
                .collect();
        }
        result += *badges.iter().next().unwrap();
    }
    result
}

Для того, щоб не дарма займатися, поставив Clippy (досі без нього працював). Дуже цікаві попередження виявляє - і переважно одразу пропонує рішення, але в складних випадках не працює.

Подякували: leofun01, dot2

92

Re: Advent of Code

2022#03, Python
import string
from collections import Counter
from functools import reduce
from operator import and_

insert = open("input.txt").read().split()


def reorganization(length: int, count: int = 1) -> int:
    priorities: int = 0

    for line in range(0, len(insert) - count + 1, count):
        parts = list()

        for n in range(count):
            l = len(insert[line + n]) // length

            for div in range(0, len(insert[line + n]), l):
                parts.append(Counter(insert[line + n][div : div + l]))

        item = list(reduce(and_, parts).elements())[0]
        priorities += string.ascii_letters.index(item) + 1

    return priorities


print(reorganization(2))  # Part One: 7889
print(reorganization(1, 3))  # Part Two: 2825

93 Востаннє редагувалося dot (03.12.2022 13:03:36)

Re: Advent of Code

Znov ź taky, majstery Pajtona zavoroźujutj.

2022#02, Python
import string
import sys

rucksacks = ((set(r[:(len(r) - 1) // 2]), set(r[(len(r) - 1) // 2:-1])) for r in sys.stdin)
priorities = (string.ascii_letters.index(next(iter(set.intersection(*r)))) + 1 for r in rucksacks)
print(sum(priorities))
import string
import sys

def group_sacks(rucksacks, size):
    for i in range(0, len(rucksacks), size):
        yield rucksacks[i:i + size]


groups = group_sacks([set(r[:-1]) for r in sys.stdin], 3)
priorities = (string.ascii_letters.index(next(iter(set.intersection(*r)))) + 1 for r in groups)
print(sum(priorities))

Kolysj pôdvezutj sjudy normaljnu kolorizatsiju kodôv…

94 Востаннє редагувалося dot (04.12.2022 07:55:39)

Re: Advent of Code

2022#04, Python
import re


def cleanup(full: bool = True) -> int:
    overlap: int = 0

    for line in open("input.txt"):
        a, b, c, d = map(int, re.findall(r"\d+", line))
        first = set(range(a, b + 1))
        second = set(range(c, d + 1))

        if full and (first.issubset(second) or second.issubset(first)) or not full and first.intersection(second):
            overlap += 1

    return overlap


print(cleanup())  # Part One: 498
print(cleanup(False))  # Part Two: 859

Moźna bulo śće prosto porôvnjuvaty granycjy, ale menê lênjky rozpysuvaty umovy, a programa vykonuje sja mytjovo.

Dekotra zmêna. Bulo:

if full and (first.issubset(second) or second.issubset(first)) or not full and first.intersection(second):

Ale zarady cêkavynky perevêryv i nastupnyj konstrukt cêlkom roboćyj:

if first.issubset(second) or second.issubset(first) if full else first.intersection(second):

Zrućno, tobto ne treba propysuvaty if X and A or not X and B, dostatnjo if A if X else B.

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

95

Re: Advent of Code

Умова: у ельфів є завдання за номерами, наприклад, 3-6 означає 3, 4, 5, 6. Ельфи поділені на пари. У деяких пар завдання накладаються і перетинаються (скажімо, 3-6,4-5 - завдання другого ельфа повністю вкладається в завдання першого). Треба знайти кількість:
1. Пар, завдання яких повністю накладаються
2. Пар, завдання яких перетинаються (включаючи п.1)

2022#04, Rust
pub struct Assignment {
    left: usize,
    right: usize,
    range: std::ops::RangeInclusive<usize>,
}

impl Assignment {
    fn new(input: &str) -> Assignment {
        let mut input = input.split('-');
        let left = input.next().unwrap().parse().unwrap();
        let right = input.next().unwrap().parse().unwrap();
        Assignment {
            left,
            right,
            range: left..=right,
        }
    }
    fn contains(&self, other: &Assignment) -> bool {
        self.range.contains(&other.left) && self.range.contains(&other.right)
    }
    fn overlaps(&self, other: &Assignment) -> bool {
        self.range.contains(&other.left)
            || self.range.contains(&other.right)
            || other.contains(self)
    }
}

pub fn parse_input(input: &str) -> Vec<(Assignment, Assignment)> {
    input
        .lines()
        .map(|line| {
            let mut pair = line.split(',');
            (
                Assignment::new(pair.next().unwrap()),
                Assignment::new(pair.next().unwrap()),
            )
        })
        .collect()
}

fn filter_count<T, F>(assignments: &[T], f: F) -> usize
where
    F: FnMut(&&T) -> bool,
{
    assignments.iter().filter(f).count()
}

pub fn task1(assignments: &[(Assignment, Assignment)]) -> usize {
    filter_count(assignments, |&(left, right)| {
        left.contains(right) || right.contains(left)
    })
}

pub fn task2(assignments: &[(Assignment, Assignment)]) -> usize {
    filter_count(assignments, |&(left, right)| left.overlaps(right))
}

У Rust все одно доводиться трохи більше писати (ну не виходить просто розібрати вираз на 4 числа), а я швидко починаю плутатися, де у мене там ліво, де право, де праве значення лівого ельфа і т.д. Тому типи і функції. На жаль, RangeInclusive не надає доступу до своїх елементів, тому довелося власний тип проголошувати.

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

96 Востаннє редагувалося koala (04.12.2022 21:25:15)

Re: Advent of Code

Переробив свій проєкт на Rust, код скоротився, тепер дописувати про наявність нового файла треба лише в одному місці. Заразом усе трохи причесав, замінив дещо застарілий lazy_static на OnceCell і нарешті пройшовся по всьому коду Clippy.
Засів переробляти 2019 рік - там треба емулятор запрограмувати (інструкції додаються поступово в нових завданнях). Зробив завдяки цьому раніше не зроблене 2019#7-2.

2019#07, багатолітер
//computer.rs
#[derive(Clone, PartialEq, Eq)]
pub enum ComputerState {
    Normal,
    Halt,
    Input,
}

use std::collections::VecDeque;

#[derive(Clone)]
pub struct Computer {
    pub memory: Vec<isize>,
    pub ip: usize,
    input: VecDeque<isize>,
    output: VecDeque<isize>,
    pub state: ComputerState,
}

impl Computer {
    pub fn is_halted(&self) -> bool {
        self.state == ComputerState::Halt
    }
    pub fn is_input_blocked(&self) -> bool {
        self.state == ComputerState::Input && self.input.is_empty()
    }

    pub fn step(&mut self) {
        if self.is_halted() || self.is_input_blocked() {
            return;
        }
        self.state = ComputerState::Normal;
        let opcode = self.memory[self.ip] % 100;
        match opcode {
            1 => {
                let src1 = self.get_value(1);
                let src2 = self.get_value(2);
                let tgt = self.memory[self.ip + 3];
                self.memory[tgt as usize] = src1 + src2;
                self.ip += 4;
            }
            2 => {
                let src1 = self.get_value(1);
                let src2 = self.get_value(2);
                let tgt = self.memory[self.ip + 3];
                self.memory[tgt as usize] = src1 * src2;
                self.ip += 4;
            }
            3 => {
                if self.input.is_empty() {
                    self.state = ComputerState::Input;
                    return;
                }
                let tgt = self.memory[self.ip + 1];
                self.memory[tgt as usize] = self.input.pop_front().unwrap();
                self.ip += 2;
            }
            4 => {
                let src = self.get_value(1);
                self.output.push_back(src);
                self.ip += 2;
            }
            5 => {
                let test = self.get_value(1);
                let tgt = self.get_value(2);
                self.ip = if test != 0 { tgt as usize } else { self.ip + 3 };
            }
            6 => {
                let test = self.get_value(1);
                let tgt = self.get_value(2);
                self.ip = if test == 0 { tgt as usize } else { self.ip + 3 };
            }
            7 => {
                let test1 = self.get_value(1);
                let test2 = self.get_value(2);
                let tgt = self.memory[self.ip + 3];
                self.memory[tgt as usize] = isize::from(test1 < test2);
                self.ip += 4;
            }
            8 => {
                let test1 = self.get_value(1);
                let test2 = self.get_value(2);
                let tgt = self.memory[self.ip + 3];
                self.memory[tgt as usize] = isize::from(test1 == test2);
                self.ip += 4;
            }
            99 => {
                self.state = ComputerState::Halt;
            }
            _ => unimplemented!(),
        }
    }
    pub fn new(code: &[isize]) -> Computer {
        Computer {
            memory: code.into(),
            ip: 0,
            input: VecDeque::new(),
            output: VecDeque::new(),
            state: ComputerState::Normal,
        }
    }

    fn get_value(&self, index: usize) -> isize {
        let mut mode = self.memory[self.ip] / 100;
        for _ in 1..index {
            mode /= 10;
        }
        match mode % 10 {
            0 => self.memory[self.memory[self.ip + index] as usize],
            1 => self.memory[self.ip + index],
            _ => unimplemented!(),
        }
    }
    pub fn run(&mut self) {
        while !self.is_halted() && !self.is_input_blocked() {
            self.step();
        }
    }
    pub fn write(&mut self, value: isize) {
        self.input.push_back(value);
    }
    pub fn read(&mut self) -> Option<isize> {
        self.output.pop_front()
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn test_memory(before: &[isize], after: &[isize]) {
        let mut comp = Computer::new(before);
        comp.run();
        assert_eq!(comp.memory, after);
    }

    #[test]
    fn test_day2() {
        test_memory(
            &[1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50],
            &[3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50],
        );
        test_memory(&[1, 0, 0, 0, 99], &[2, 0, 0, 0, 99]);
        test_memory(&[2, 3, 0, 3, 99], &[2, 3, 0, 6, 99]);
        test_memory(&[2, 4, 4, 5, 99, 0], &[2, 4, 4, 5, 99, 9801]);
        test_memory(
            &[1, 1, 1, 4, 99, 5, 6, 0, 99],
            &[30, 1, 1, 4, 2, 5, 6, 0, 99],
        );
    }

    fn test_io(code: &[isize], input: &[isize], output: &[isize], msg: &str) {
        let mut comp = Computer::new(code);
        comp.input.extend(input.iter().copied());
        comp.run();
        assert_eq!(comp.output, output, "{msg}");
    }

    #[test]
    fn test_day5() {
        test_io(&[3, 0, 4, 0, 99], &[42], &[42], "Copy input");
        test_memory(&[1002, 4, 3, 4, 33], &[1002, 4, 3, 4, 99]);
        //equal to 8
        test_io(
            &[3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
            &[8],
            &[1],
            "Equal to 8 - position",
        );
        test_io(
            &[3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8],
            &[42],
            &[0],
            "Equal to 8 - position",
        );

        test_io(
            &[3, 3, 1108, -1, 8, 3, 4, 3, 99],
            &[8],
            &[1],
            "Equal to 8 - immediate",
        );
        test_io(
            &[3, 3, 1108, -1, 8, 3, 4, 3, 99],
            &[42],
            &[0],
            "Equal to 8 - immediate",
        );

        //less then 8
        test_io(
            &[3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
            &[5],
            &[1],
            "Less than 8 - position",
        );
        test_io(
            &[3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8],
            &[42],
            &[0],
            "Less than 8 - position",
        );

        test_io(
            &[3, 3, 1107, -1, 8, 3, 4, 3, 99],
            &[5],
            &[1],
            "Less than 8 - immediate",
        );
        test_io(
            &[3, 3, 1107, -1, 8, 3, 4, 3, 99],
            &[42],
            &[0],
            "Less than 8 - immediate",
        );

        //equal to 0
        test_io(
            &[3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
            &[0],
            &[0],
            "Equal to 0 - position",
        );
        test_io(
            &[3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
            &[42],
            &[1],
            "Equal to 0 - position",
        );

        test_io(
            &[3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
            &[0],
            &[0],
            "Equal to 0 - immediate",
        );
        test_io(
            &[3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
            &[42],
            &[1],
            "Equal to 0 - immediate",
        );

        let larger_example = &[
            3, 21, 1008, 21, 8, 20, 1005, 20, 22, 107, 8, 21, 20, 1006, 20, 31,
            1106, 0, 36, 98, 0, 0, 1002, 21, 125, 20, 4, 20, 1105, 1, 46, 104,
            999, 1105, 1, 46, 1101, 1000, 1, 20, 4, 20, 1105, 1, 46, 98, 99,
        ];
        test_io(larger_example, &[5], &[999], "Large - less than");
        test_io(larger_example, &[8], &[1000], "Large - equal");
        test_io(larger_example, &[42], &[1001], "Large - greater");
    }
}

//day7.rs
use super::computer::Computer;

pub fn parse_input(input: &str) -> Vec<isize> {
    input
        .trim()
        .split(',')
        .map(|x| x.parse().unwrap())
        .collect()
}

use itertools::Itertools;

pub fn task1(code: &[isize]) -> isize {
    (0..5)
        .permutations(5)
        .map(|perm| {
            let mut data = 0;
            for phase in perm {
                let mut amplifier = Computer::new(code);
                amplifier.write(phase);
                amplifier.write(data);
                amplifier.run();
                data = amplifier.read().unwrap();
            }
            data
        })
        .max()
        .unwrap()
}

pub fn task2(code: &[isize]) -> isize {
    (5..10)
        .permutations(5)
        .map(|perm| {
            let mut amplifiers = Vec::new();
            for phase in perm {
                let mut amplifier = Computer::new(code);
                amplifier.write(phase);
                amplifiers.push(amplifier);
            }
            amplifiers[0].write(0);
            let mut changes = true;
            let mut last_data = -1;
            while changes {
                changes = false;
                for i in 0..5 {
                    amplifiers[i].run();
                    while let Some(data) = amplifiers[i].read() {
                        if i == 4 {
                            last_data = data;
                        }
                        amplifiers[(i + 1) % 5].write(data);
                        changes = true;
                    }
                }
            }
            last_data
        })
        .max()
        .unwrap()
}
Подякували: dot1

97 Востаннє редагувалося dot (05.12.2022 06:36:50)

Re: Advent of Code

Tym ćasom: <Placing #1 in Advent of Code with GPT-3, AI solves Advent of Code 2022>.

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

98

Re: Advent of Code

Умова: є схема розміщення коробок і план їх переміщення. З'ясувати, які коробки опиняться нагорі в результаті, якщо:
1. Коробки перекладають по одній (тобто якщо треба перекласти 2, то вони змінюють порядок)
2. Коробки перекладають групами (порядок не змінюється)

2022#8 Rust
pub struct Cargo {
    stacks: Vec<Vec<char>>,
    plan: Vec<(usize, usize, usize)>,
}

pub fn parse_input(input: &str) -> Cargo {
    let mut stacks = Vec::new();
    let mut plan = Vec::new();
    for line in input.lines() {
        if line.contains('[') {
            if stacks.len() < line.len() / 4 {
                stacks.resize(line.len() / 4 + 1, Vec::new());
            }
            for i in 0..line.len() / 4 + 1 {
                if let Some(crat) = line.chars().nth(i * 4 + 1) {
                    if crat != ' ' {
                        stacks[i].push(crat);
                    }
                }
            }
        } else if line.starts_with("move") {
            let mut line = line.split_whitespace();
            line.next();
            let number = line.next().unwrap().parse().unwrap();
            line.next();
            let from = line.next().unwrap().parse().unwrap();
            line.next();
            let to = line.next().unwrap().parse().unwrap();
            plan.push((number, from, to));
        }
    }
    for stack in &mut stacks {
        stack.reverse();
    }
    Cargo { stacks, plan }
}

pub fn task1(input: &Cargo) -> String {
    let mut stacks = input.stacks.clone();
    for &(number, from, to) in &input.plan {
        for _ in 0..number {
            if let Some(crat) = stacks[from - 1].pop() {
                stacks[to - 1].push(crat);
            }
        }
    }
    stacks
        .iter()
        .map(|stack| {
            stack.last().map(char::to_string).unwrap_or(" ".to_string())
        })
        .collect()
}

pub fn task2(input: &Cargo) -> String {
    let mut stacks = input.stacks.clone();
    for &(number, from, to) in &input.plan {
        let new_from_len = stacks[from - 1].len() - number;
        let crates = Vec::from(&stacks[from - 1][new_from_len..]);
        stacks[from - 1].truncate(new_from_len);
        stacks[to - 1].extend(crates);
    }
    stacks
        .iter()
        .map(|stack| {
            stack.last().map(char::to_string).unwrap_or(" ".to_string())
        })
        .collect()
}

Загалом, можна трохи скоротити, але це якраз той тип задач, який Rust ненавидить. Складні зміни всередині структури з перекиданням частин туди-сюди. Треба або unsafe робити, або купу проміжних змінних.

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

99 Востаннє редагувалося dot (05.12.2022 09:22:42)

Re: Advent of Code

2022#5, Python
from curses.ascii import isdigit
import collections, copy, re

file = [block.split("\n") for block in open("input.txt").read().split("\n\n")]
procedures = [list(map(int, re.findall("\d+", line))) for line in file[1]]
crates = collections.defaultdict(list)

for line in file[0][-2::-1]:
    for i, mark in enumerate(file[0][-1]):
        if isdigit(mark) and i < len(line) and line[i] != " ":
            crates[int(mark)].append(line[i])


def crateMover(version: int = 9000) -> str:
    cell = copy.deepcopy(crates)
    for move, a, b in procedures:
        moved = [cell[a].pop() for _ in range(move)]
        cell[b].extend(moved if version == 9000 else moved[::-1])

    return "".join([cell[i][-1] for i in cell])


print(crateMover())  # Part One: QNHWJVJZW
print(crateMover(9001))  # Part Two: BPCZJLFJW

Majźe peven, śćo moźna bulo vydobyty infu z fajla kraśće i oxajnêśe, ale naj.

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

100

Re: Advent of Code

Śće z cêkavoho ćy smêśnoho navkolo <AoC>: xtosj pomêtyv v sobê virus, śćo krade kriptovalutu, bo skopijovanyj tekst zô zadaćy ne zbêhav sja zô vstavlenym.