Advent of Code 2021

https://adventofcode.com/2021/

Ce este advent of code? Din about page:

Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

Probabil ca mai sunt colegi de forum care participa.
Propun sa ne etalam solutiile, fie ele cat de hackish, ineficiente, indescifrabile sau alte calificative indezirabile.

Eu o sa-mi postez solutiile in limita timpului si capabilitatilor mele de programator.

5 Likes

Solutii in F#

Day 1-1

Trebuie sa compar valori in perechi (List.pairwise), sa marchez rezultatul comparatiei (Option + List.choose) si sa vad cate rezultate de interes sunt (List.length).
Nu e cea mai “pe domeniu” solutie, dar e acceptabila.

   let measurements = [|
        199
        200
        208
        210
        200
        207
        240
        269
        260
        263
    |]

    let count = 
        measurements
        |> Array.toList
        |> List.pairwise
        |> List.choose (fun (prev, current) -> 
            if (current > prev) 
            then Some 1
            else None
        )
        |> List.length

    printfn "%i" count
Day 1-2

Trebuie sa compar cate 3 valori consecutive (List.windowd 3), in perechi (List.pairwise). Apoi acelasi rationament ca mai sus.

    let measurements = [|
        199
        200
        208
        210
        200
        207
        240
        269
        260
        263
    |]
    
    let count = 
        measurements
        |> Array.toList
        |> List.windowed 3
        |> List.pairwise
        |> List.choose (fun (prevWindow, currentWindow) ->
            let prevSum = List.sumBy id prevWindow  
            let currentSum = List.sumBy id currentWindow  
            if (currentSum > prevSum) 
            then Some 1
            else None
        )
        |> List.length

    printfn "%i" count
Day 2-1

Citesc valorile dintr-un fisier ca o secventa de stringuri (1 string pt fiecare linie din fisier).
Stringurile le mapez pe ceva ce se aseamana cu un enum (Commands) ca apoi sa pot sa le bag in ceva ce seamana cu un switch (match).

Acum ca mi-am pregatit datele, pot sa incep sa lucrez la solutie.
Am nevoie ca pentru fiecare comanda sa tin evidenta a 2-a valori. Asa ca folosesc un fold si fac match pe comenzi.
La sfarsit, inmultesc valorile pentru solutie.

   type Commands = 
        | Forward of int
        | Down of int
        | Up of int

   let result = 
        Utils.readFileAsLineSeq "day2inputs.txt"
        |> Seq.map (fun s -> 
            let split = s.Split(' ') 

            match split.[0] with
            | "forward" -> Forward (int (Int16.Parse(split.[1])))
            | "up" -> Up (int (Int16.Parse(split.[1])))
            | "down" -> Down (int (Int16.Parse(split.[1])))
        )
        |> Seq.fold (fun (depth, horizontal) command -> 
            match command with
            | Forward i -> (depth, horizontal + i)
            | Up i -> (depth - i, horizontal)
            | Down i -> (depth + i, horizontal)
        ) (0, 0)
        |> (fun (depth, horizontal) -> 
            depth * horizontal
        )

    printfn "%i" result
Day 2-2

Refolosesc mare parte din codul de la Day 2-1.
Acum insa trebuie sa tin evidenta a 3 valori.

   type Commands = 
        | Forward of int
        | Down of int
        | Up of int

   let result = 
        Utils.readFileAsLineSeq "day2inputs.txt"
        |> Seq.map (fun s -> 
            let split = s.Split(' ') 

            match split.[0] with
            | "forward" -> Forward (int (Int16.Parse(split.[1])))
            | "up" -> Up (int (Int16.Parse(split.[1])))
            | "down" -> Down (int (Int16.Parse(split.[1])))
        )
        |> Seq.fold (fun (depth, horizontal, aim) command -> 
            match command with
            | Up i -> (depth, horizontal, aim - i)
            | Down i -> (depth, horizontal, aim + i)
            | Forward i -> (depth + (aim * i), (horizontal + i), aim)
        ) (0, 0, 0)
        |> (fun (depth, horizontal, aim) -> 
            depth * horizontal
        )

    printfn "%i" result
5 Likes

Văd că mulți încearcă/învață un nou limbaj cu ocazia asta: Advent of Code 2021 | Lobsters
Dacă aș avea timp aș încerca cu Zig sau Nim.

De solutia asta sunt cel mai mandru

Day 3 - 2 (Perl)
use v5.30;
use List::Util qw/reduce/;

open my $input, '<', 'd3_1.txt';
push my @lines, <$input>;
chomp @lines;

sub get_number {
	my ($bit, @bits) = @_;
	my $pos = 0;
	while (@bits > 1) {
		my $count = grep { substr($_, $pos, 1) == 1 } @bits;

		my $searched_bit = ($count >= @bits / 2) ^ $bit;
		@bits = grep { substr($_, $pos, 1) == $searched_bit } @bits;
		++$pos;
	}

	return reduce { $a * 2 + $b } split '', $bits[0];
}

say get_number(1, @lines) * get_number(0, @lines);
3 Likes

Fain F# :slight_smile:
Imi place ca are acest operator |> si poti sa faci pipe-uri ca in Linux. As vrea ca mai multe limbaje sa il aiba.

3 Likes

Am încercat și eu niște soluții în Rust:

Day 1
use std::fs::File;
use std::io::{self, BufRead};

fn read_lines(filename: &str) -> io::Result::<io::Lines::<io::BufReader::<File>>> {
    let file = File::open(filename)?;
    Ok(io::BufReader::new(file).lines())
}

fn main() -> io::Result<()> {
    let numbers = read_lines("./day1.txt")?
        .map(|line| line.unwrap().parse::<i32>().unwrap())
        .collect::<Vec::<i32>>();

    let result: i32 = numbers
        .windows(2)
        .map(|window| (window[1] > window[0]) as i32)
        .sum();

    println!("{}", result);

    Ok(())
}
Day 2
use std::fs::File;
use std::io::{self, BufRead};

fn read_lines(filename: &str) -> io::Result::<io::Lines::<io::BufReader::<File>>> {
    let file = File::open(filename)?;
    Ok(io::BufReader::new(file).lines())
}

#[derive(Copy, Clone)]
enum Direction {
    Up,
    Down,
    Forward,
}

fn str_to_direction(input: &str) -> Direction {
    let possible_directions = [
        ("up", Direction::Up),
        ("down", Direction::Down),
        ("forward", Direction::Forward),
    ];

    for (dir, value) in possible_directions.iter() {
        if input.starts_with(dir) {
            return *value;
        }
    }

    panic!("Invalid input!");
}

#[derive(Debug)]
struct State {
    position: i32,
    depth: i32,
}

fn main() -> io::Result<()> {
    let state = read_lines("./day2.txt")?
        .map(|line| -> State {
            let line_str = line.unwrap();
            let info = line_str.split(' ').collect::<Vec::<&str>>();
            let offset = info[1].parse::<i32>().unwrap();

            return match str_to_direction(info[0]) {
                Direction::Up => State { position: 0, depth: offset },
                Direction::Down => State { position: 0, depth: -offset },
                Direction::Forward => State { position: offset, depth: 0 },
            };
        })
        .collect::<Vec::<State>>();

    let result: State = state
        .iter()
        .fold(State { position: 0, depth: 0 }, |acc, current| -> State {
            return State {
                position: acc.position + current.position,
                depth: acc.depth + current.depth,
            };
        });

    println!("{:?}", result);

    Ok(())
}
Day 3
use std::fs::File;
use std::io::{self, BufRead};

fn read_lines(filename: &str) -> io::Result::<io::Lines::<io::BufReader::<File>>> {
    let file = File::open(filename)?;
    Ok(io::BufReader::new(file).lines())
}

#[derive(Clone)]
struct State {
    count_ones: i32,
    count_zeroes: i32,
}

fn main() -> io::Result<()> {
    let mut rate = vec![State { count_ones: 0, count_zeroes: 0 }; 5];

    read_lines("./day3.txt")?.for_each(|line| {
        for (index, ch) in line.unwrap().chars().enumerate() {
            match ch {
                '0' => rate[index].count_zeroes += 1,
                '1' => rate[index].count_ones += 1,
                _ => panic!("Invalid input!"),
            }
        }
    });

    let (gamma_rate, epsilon_rate): (u32, u32) = rate
        .iter()
        .rev()
        .enumerate()
        .fold((0, 0), |(acc_gamma, acc_eps), (index, state)| {
            if state.count_zeroes > state.count_ones {
                return (acc_gamma + 2u32.pow(index as u32), acc_eps);
            } else {
                return (acc_gamma, acc_eps + 2u32.pow(index as u32));
            }
        });

    println!("{}", gamma_rate * epsilon_rate);

    Ok(())
}
3 Likes

Day 1
Merge pe ideea lui @std.bless

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Main {

    public static void main(String[] args) throws IOException {
        var measurements = Files.readAllLines(Path.of("E:\\Projects\\Java177_Lombok\\src\\measurements.txt"))
                .stream()
                .map(Integer::valueOf)
                .toList();

        var pairs = sliding(measurements, 2);
        var result = pairs
                .map(pair -> pair.get(1) > pair.get(0))
                .filter(f -> f)
                .count();
        System.out.println(result);
    }

    // Java does not have a window function, so we need to build one
    public static <T> Stream<List<T>> sliding(List<T> list, int size) {
        if(size > list.size())
            return Stream.empty();
        return IntStream.range(0, list.size() - size + 1)
                .mapToObj(start -> list.subList(start, start + size));
    }
}
3 Likes

Day 3 si 4, am renuntat la orice tentativa de a avea rezolvari eficiente. Din nou, in F#:

Day 3-1 Zero si Unu

Day 3 a introdus array-uri 2D. Din fericire, F# are cateva facilitati pentru array2D.
Nu am stiut mai niciodata operatiuni cu biti, asa ca fac niste lucruri dubioase pentru conversii.

    let bitArrayToInt bitArray = 
        let str = 
            bitArray
            |> Array.map (fun i -> i.ToString())
            |> String.Concat


        System.Convert.ToInt32(str, 2)

    let inputs = 
        Utils.readFileAsLineSeq "day3inputs.txt"
        |> Seq.map (fun s -> 
            s
            |> Array.ofSeq
            |> Array.map (fun c -> int (Int32.Parse(c.ToString())))
        )


    let arr2D = array2D inputs

    let (gammaRateBits, epsilonRateBits) = 
        //pentru fiecare coloana din matrice(?) fac un fold si tin evidenta celui mai comun / mai putin comun termen
        [|0..(Array2D.length2 arr2D - 1)|]
        |> Array.fold (fun (mostCommonArr: int[], leastCommonArr: int[]) (columnIndex: int) ->
            //ca sa iau o coloana dintr-o matice, pot sa folosesc .[*, index] unde * inseamna "tot" si val e index-ul coloanei
            let column = arr2D.[*, columnIndex]

            let count1 = Array.sum column
            let count0 = (Array.length column) - count1

            let (mostCommon, leastCommon) =
                if count1 > count0
                then (1, 0)
                else (0, 1)

            Array.append mostCommonArr [| mostCommon |],    
            Array.append leastCommonArr [| leastCommon |]
        ) ([||], [||])


    let gammaRate = bitArrayToInt gammaRateBits
    let epsilonRate = bitArrayToInt epsilonRateBits

    let result = gammaRate * epsilonRate

    printfn "%i" result

Day 3-2 Unu si Zero

Recursivitate, cine ar fi crezut ca e ceva util?

    let bitArrayToInt bitArray = 
        let str = 
            bitArray
            |> Array.map (fun i -> i.ToString())
            |> String.Concat


        System.Convert.ToInt32(str, 2)

    let inputs = 
        Utils.readFileAsLineSeq "day3inputs.txt"
        |> Seq.map (fun s -> 
            s
            |> Array.ofSeq
            |> Array.map (fun c -> int (Int32.Parse(c.ToString())))
        )
        |> Array.ofSeq

    let getMostCommonInArr arr = 
        let count1 = Array.sum arr
        let count0 = (Array.length arr) - count1

        if count1 >= count0
        then 1
        else 0

    let getLeastCommonInArr arr = 
        let count1 = Array.sum arr
        let count0 = (Array.length arr) - count1

        if count0 <= count1
        then 0
        else 1


    //Am nevoie sa lucrez pe inputs care se restrang
    //In practica, ar fi mers cu un fold, dar prima solutie ce mi-a venit in cap a fost sa folosesc explicit recursivitate
    let matching (inputs: int[][]) (matchingValueFn: int[] -> int) maxColumn = 
        let rec matchingRec (inputs: int[][]) (column: int) = 
            let arr2D = array2D inputs

            let arr = arr2D.[*, column]

            let matchingValue = matchingValueFn arr

            let filteredInputs =
                inputs
                |> Array.filter (fun row -> row.[column] = matchingValue)

            if (Array.length filteredInputs = 1)
            then filteredInputs.[0]
            else
                if column = maxColumn
                then filteredInputs.[0]
                else 
                    matchingRec filteredInputs (column + 1)

        matchingRec inputs 0

    let oxygenBits = matching inputs getMostCommonInArr (Array.length inputs.[0])
    let co2Bits = matching inputs getLeastCommonInArr (Array.length inputs.[0])

    let oxygen = bitArrayToInt oxygenBits
    let co2 = bitArrayToInt co2Bits

    let result = oxygen * co2

    printfn "%i" result
Day 4-1 BINGO

TLDR: Folds

module Day41 = 
    open System

    type BoardId = int

    type Board = {
        Id: BoardId
        Numbers: int[][]
    }

    type BoardLine = BoardId * int

    let convertToBoard id (lines: string[]) : Board = 
        let lines = Array.tail lines

        let numbers = 
            lines
            |> Array.map (fun line -> 
                line
                |> Seq.chunkBySize 3 
                |> Seq.map (fun numberString -> 
                    let numberString = 
                        (numberString |> Seq.map string)
                        |> (String.concat "") 

                    Int32.Parse((string numberString)
                ))
                |> Array.ofSeq
            )
        
        
        printfn "%A" (array2D numbers)
        {
            Id = id
            Numbers = numbers
        }


    let inputs = Utils.readFileAsLineSeq("day4inputs.txt")

    let numbers : seq<int> = 
        inputs 
        |> Seq.head
        |> (fun s -> s.Split(",")) 
        |> Seq.map (fun numberString -> 
            let numberString = 
                (numberString |> Seq.map string)
                |> (String.concat "") 

            Int32.Parse((string numberString)
        ))

    let boards: seq<Board> = 
        inputs
        |> Seq.tail
        |> Seq.chunkBySize 6
        |> Seq.mapi convertToBoard


    //Map ca sa stiu pe ce linii din fiecare Board apare un numar
    //Ex pt numarul "33" stiu ca apare pe Board 1 linia 7 (linia sau coloana sunt acelasi lucru) si pe Board 3 linia 1 
    let numbersMap : Map<int, seq<BoardLine>> =
        boards
        |> Seq.collect (fun board -> 
            let numbers2D = array2D board.Numbers
            [
                1, numbers2D.[*,0]
                2, numbers2D.[*,1]
                3, numbers2D.[*,2]
                4, numbers2D.[*,3]
                5, numbers2D.[*,4]
                6, numbers2D.[0,*]
                7, numbers2D.[1,*]
                8, numbers2D.[2,*]
                9, numbers2D.[3,*]
                10, numbers2D.[4,*]
            ]
            |> Seq.collect( fun (lineNumber, numbers) ->
                numbers
                |> Seq.map (fun number ->
                    number, (board.Id, lineNumber)
                )
            )
        )
        |> Seq.fold (fun map (number, boardLine) ->
            let boardLines = 
                (map |> Map.tryFind number |> Option.defaultValue Seq.empty)
                |> Seq.append [boardLine]

            Map.add number boardLines map
        ) Map.empty

    //Am fost foarte tentat sa folosesc valori mutabile, dar m-am abtinut
    //Fac un fold in fold in care tin evidenta a cate numere de pe o linie au fost extrase
    //Folosesc un map de forma Map<BoardLine, int> unde int e numarul de numere extrase de pe acel BoardLine
    //Cand sunt extrase 5 numere pe un BoardLine, am un board castigator si nu mai incerc sa gasesc alte boarduri castigatoare
    //De unde stiu pe ce BoardLine a aterizat un numar? Folosesc numbersMap de mai sus.
    let (maybeBoardLineAndNumber, _) =
        numbers
        |> Seq.fold (fun (maybeBoardLineAndNumber, hitsMap) number ->
            if Option.isSome maybeBoardLineAndNumber
            then (maybeBoardLineAndNumber, hitsMap)
            else
                let hits = numbersMap |> Map.tryFind number |> Option.defaultValue Seq.empty

                let (maybeBoardLineAndNumber, hitsMap) = 
                    hits
                    |> Seq.fold (fun (maybeBoardLineAndNumber, hitsMap) boardLine ->
                        if Option.isSome maybeBoardLineAndNumber
                        then (maybeBoardLineAndNumber, hitsMap)
                        else
                            let hitsForBoardline = hitsMap |> Map.tryFind boardLine |> Option.defaultValue 0

                            if hitsForBoardline = 4
                            then (Some (boardLine, number)), Map.add boardLine 5 hitsMap
                            else None, Map.add boardLine (hitsForBoardline + 1) hitsMap

                    ) (maybeBoardLineAndNumber, hitsMap)
                
                (maybeBoardLineAndNumber, hitsMap)
        ) (None, Map.empty)

    let matchingBoard, lastExtractedNumber = 
        match maybeBoardLineAndNumber with
        | Some ((boardId, line), lastExtractedNumber) ->
            boards |> Seq.find (fun b -> b.Id = boardId),
            lastExtractedNumber
        | None -> failwithf "No winning board"

    //Presupun ca numerele extrase sunt unice
    let numbersExtracted = 
        numbers 
        |> Seq.takeWhile (fun n -> n <> lastExtractedNumber)
        |> Seq.append [lastExtractedNumber]

    //De pe boardul castigator am nevoie sa aflu ce numere NU au fost extrase
    //Din toate numerele de pe board, le filtrez pe cele care se regasesc in numerele extrase
    let unmarkedNumbersSum = 
        matchingBoard.Numbers
        |> Array.concat
        |> Array.filter (fun n -> not (Seq.contains n numbersExtracted ))
        |> Array.sum

    let result = (unmarkedNumbersSum * lastExtractedNumber)
Day 4-2 BINGO dar vrei sa pierzi si sa nu bata la ochi

TLDR: Folds, again


module Day42 = 

    open System

    type BoardId = int

    type Board = {
        Id: BoardId
        Numbers: int[][]
    }

    type BoardLine = BoardId * int

    let convertToBoard id (lines: string[]) = 
        let lines = Array.tail lines

        let numbers = 
            lines
            |> Array.map (fun line -> 
                line
                |> Seq.chunkBySize 3 
                |> Seq.map (fun numberString -> 
                    let numberString = 
                        (numberString |> Seq.map string)
                        |> (String.concat "") 

                    Int32.Parse((string numberString)
                ))
                |> Array.ofSeq
            )
                
        {
            Id = id
            Numbers = numbers
        }

    let inputs = Utils.readFileAsLineSeq("day4inputs.txt")

    let numbers = 
        inputs 
        |> Seq.head
        |> (fun s -> s.Split(",")) 
        |> Seq.map (fun numberString -> 
            let numberString = 
                (numberString |> Seq.map string)
                |> (String.concat "") 

            Int32.Parse((string numberString)
        ))

    let boards = 
        inputs
        |> Seq.tail
        |> Seq.chunkBySize 6
        |> Seq.mapi convertToBoard


    //Map ca sa stiu pe ce linii din fiecare Board apare un numar
    //Ex pt numarul "33" stiu ca apare pe Board 1 linia 7 (linia sau coloana sunt acelasi lucru) si pe Board 3 linia 1 
    let numbersMap : Map<int, seq<BoardLine>> =
        boards
        |> Seq.collect (fun board -> 
            let numbers2D = array2D board.Numbers
            [
                1, numbers2D.[*,0]
                2, numbers2D.[*,1]
                3, numbers2D.[*,2]
                4, numbers2D.[*,3]
                5, numbers2D.[*,4]
                6, numbers2D.[0,*]
                7, numbers2D.[1,*]
                8, numbers2D.[2,*]
                9, numbers2D.[3,*]
                10, numbers2D.[4,*]
            ]
            |> Seq.collect( fun (lineNumber, numbers) ->
                numbers
                |> Seq.map (fun number ->
                    number, (board.Id, lineNumber)
                )
            )
        )
        |> Seq.fold (fun map (number, boardLine) ->
            let boardLines = 
                (map |> Map.tryFind number |> Option.defaultValue Seq.empty)
                |> Seq.append [boardLine]

            Map.add number boardLines map
        ) Map.empty

    //Am fost foarte tentat sa folosesc valori mutabile, dar m-am abtinut, din nou
    //Fac un fold in fold in care tin evidenta a cate numere de pe o linie au fost extrase
    //Folosesc un map de forma Map<BoardLine, int> unde int e numarul de numere extrase de pe acel BoardLine
    //Cand sunt extrase 5 numere pe un BoardLine, am un board castigator 
    //DAR spre deosebire de Day 4-1, aici
    //De unde stiu pe ce BoardLine a aterizat un numar? Folosesc numbersMap de mai sus.
    let (maybeBoardLineAndNumber, _, _) =
        numbers
        |> Seq.fold (fun (maybeBoardLineAndNumber, hitsMap, numbersMap) number ->
            let hits = numbersMap |> Map.tryFind number |> Option.defaultValue Seq.empty

            let (maybeBoardLineAndNumber, hitsMap, numbersMap) = 
                hits
                |> Seq.fold (fun (maybeBoardLineAndNumber, hitsMap, numbersMap) boardLine ->
                    let hitsForBoardline = hitsMap |> Map.tryFind boardLine |> Option.defaultValue 0

                    if hitsForBoardline = 4
                    then 
                        let hitsMap = 
                            (Map.add boardLine 5 hitsMap)
                            |> Map.filter (fun (boardId, _)  _ -> boardId <> (fst boardLine))

                        let numbersMap = 
                            numbersMap
                            |> Map.map (fun _ (boardLines: seq<BoardLine>) -> 
                                boardLines |> Seq.filter (fun (boardId, _) -> boardId <> (fst boardLine))
                            )

                        (Some (boardLine, number)), hitsMap, numbersMap
                    else maybeBoardLineAndNumber, Map.add boardLine (hitsForBoardline + 1) hitsMap, numbersMap

                ) (maybeBoardLineAndNumber, hitsMap, numbersMap)
            
            (maybeBoardLineAndNumber, hitsMap, numbersMap)
        ) (None, Map.empty, numbersMap)


    let (matchingBoard, lastExtractedNumber) =  
        match maybeBoardLineAndNumber with
        | Some ((boardId, line), number) ->
            boards |> Seq.find (fun b -> b.Id = boardId),
            number
        | None -> failwithf "No winning board"

    let numbersExtracted = 
        numbers 
        |> Seq.takeWhile (fun n -> n <> lastExtractedNumber)
        |> Seq.append [lastExtractedNumber]

    let unmarkedNumbersSum = 
        matchingBoard.Numbers
        |> Array.concat
        |> Array.filter (fun n -> not (Seq.contains n numbersExtracted))
        |> Array.sum


    let result = unmarkedNumbersSum * lastExtractedNumber

1 Like

Once you go |>, you never go back. E super. Si s-ar putea sa fie un feature mai mainstream in urmatorii ani. Stiu ca era un RFC pentru pipe operator pentru Javascript: GitHub - tc39/proposal-pipeline-operator: A proposal for adding a useful pipe operator to JavaScript.

Si pentru Php au fost 2 RFC pana acum, dar ambele au fost “declined”. Cel mai recent: PHP: rfc:pipe-operator-v2

3 Likes

un vis de-al meu :slight_smile:
Cel putin si pt Java si C# :grin:

Teoretic îl ai în C++ cu ranges, e |, singura problemă e că ranges în C++ sunt cam half-assed.

De obicei cele funcționale beneficiază de un operator de genul, știu că mai au și haskell și elm ceva asemănător

1 Like

Mama lor de pesti si cresteri exponentiale.

Day 5-1
module Day51 = 

    open System

    //conversie dintr-un string "1,2 -> 3,4" intr-un tuple de tuples. ex: ((1,2), (3,4))
    let lineToPointPairs (line:string) =
        let pairs = 
            line.Split(" -> ")
            |> Seq.map (fun (pointString: string) -> 
            let numbers = 
                pointString.Split(",")
                |> Seq.map (fun (numberString: string) -> (int (Int32.Parse(numberString))))

            (Seq.head numbers), (Seq.head (Seq.tail numbers))
        )

        (Seq.head pairs), (Seq.head (Seq.tail pairs))
    
    //dintr-un tuple de tuples intr-o lista de tuples
    //deocamdata imi trebuie sa completeze lista pe orizontala si verticala
    let expandPointPairsToPointLine (point1, point2) =
        let startX, endX = 
            if fst point1 < fst point2
            then fst point1, fst point2
            else fst point2, fst point1

        let startY, endY = 
            if snd point1 < snd point2
            then snd point1, snd point2
            else snd point2, snd point1

        if startX = endX
        then 
            [ for y in startY .. endY  do (startX, y)]
        else
            if startY = endY
            then
                [ for x in startX .. endX  do (x, startY)]
            else
                []

    let inputs = Utils.readFileAsLineSeq("day5inputs.txt")

    let pairs = 
        inputs
        |> Seq.map lineToPointPairs

    let lines = 
        pairs
        |> Seq.map expandPointPairsToPointLine

    //o lista de toate punctele care se afla pe vreo linie
    let hits = 
        lines
        |> Seq.concat

    //daca 2 linii se intersecteaza, acel punct exista pe mai multe linii si ar trebui sa fie un duplicat in hits
    //pentru intersectii vad ce numar sunt (cel putin) duplicate in hits
    let intersections = 
        hits
        |> Seq.countBy id
        |> Seq.filter (fun (p, count) -> count > 1)

    //apoi vad cate intersectii sunt in total
    let result = intersections |> Seq.length

Day 5-2

Acelasi lucru ca la 5-1, dar acum si cu linii diagonale

module Day52 = 

    open System

    let lineToPointPairs (line:string) =
        let pairs = 
            line.Split(" -> ")
            |> Seq.map (fun (pointString: string) -> 
            let numbers = 
                pointString.Split(",")
                |> Seq.map (fun (numberString: string) -> (int (Int32.Parse(numberString))))

            (Seq.head numbers), (Seq.head (Seq.tail numbers))
        )

        (Seq.head pairs), (Seq.head (Seq.tail pairs))
    
    //F# nu stie sa faca automat range descrescator :(
    // [0..3] = [0; 1; 2; 3] dar
    // [3..0] = [] :(
    let range from to' =
        if from < to'
        then [from .. to']
        else [to' .. from] |> List.rev
        
    //am adaugat posibilitatea de a completa lista de puncte si pe diagonala
    let expandPointPairsToPointLine (point1, point2) =
        let startX, endX = 
            if fst point1 < fst point2
            then fst point1, fst point2
            else fst point2, fst point1

        let startY, endY = 
            if snd point1 < snd point2
            then snd point1, snd point2
            else snd point2, snd point1

        if startX = endX
        then 
            [ for y in (range startY  endY)  do (startX, y)]
        else
            if startY = endY
            then
                [ for x in startX .. endX  do (x, startY)]
            else
                //diagonal
                let xRange = range (fst point1) (fst point2)
                let yRange = range (snd point1) (snd point2)

                List.zip xRange yRange

    let inputs = Utils.readFileAsLineSeq("day5inputs.txt")

    let pairs = 
        inputs
        |> Seq.map lineToPointPairs


    let lines = 
        pairs
        |> Seq.map expandPointPairsToPointLine
    

    let hits = 
        lines
        |> Seq.concat

    let intersections = 
        hits
        |> Seq.countBy id
        |> Seq.filter (fun (p, count) -> count > 1)

    

    let result = intersections |> Seq.length

Day 6-1 ceva la puterea 80. PC-ul rezista.
module Day61 = 

    open System

    //cand mai trece o zi, scad toate zilele pestilor cu 1
    //si daca e vreunul car trebuie sa se reproduca, il resetez si adaug si un copil
    //Asta e varianta cu brute force
    let advanceDay fish = 
        fish
        |> Seq.collect (fun f -> 
            if f = 0
            then [6; 8]
            else [f - 1]
        )
        
   
    let inputs = Utils.readFileAsLineSeq("day6inputs.txt")

    let initialFish = 
        inputs
        |> Seq.head
        |> (fun str  -> str.Split(","))
        |> Seq.map (fun (numberString: string) -> (int (Int32.Parse(numberString))))

    //plecand de la o lista de pesti
    //fold pe acea lista avansand ziua
    let fishAfterDays days = 
        [0..days - 1] 
        |> List.fold (fun fish day -> 
            advanceDay fish
        ) initialFish
    
   
    let result = Seq.length (fishAfterDays 80)

Day 6-2 ceva la puterea 256. PC-ul nu rezista.
module Day62 = 

    open System

    //nu mai merge sa tin pestii in liste
    //asa ca folosesc un map care imi spune cati pesti am in fiecare zi al ciclului reproducator
    //ca sa avansez ziua, scad din key astfel:
    //din {0:2, 1:0, 2:1} ajung la {-1:2, 0:0, 1:1} dar
    //-1 inseamna ca trebuie sa se reproduca asa ca se transforma in 6 si adaug acelasi numar de pesti de la -1 la 8 (puii)
    //din {0:2, 1:0, 2:1} ajung la {-1:2, 0:0, 1:1} jung la {0:0, 1:1, 6:2, 8:2}
    let advanceDay fishDayCountMap = 
        let newMap = 
            fishDayCountMap
            |> Map.toList
            |> List.map (fun (day, count) -> 
                (day - 1, count)
            )
            |> Map.ofList
            
        //folosesc int64 pentru ca e un numar mare si face overflow
        let parents = newMap |> Map.tryFind -1 |> Option.defaultValue (int64 0)
        let existing = newMap |> Map.tryFind 6 |> Option.defaultValue (int64 0)

        newMap
        |> Map.add 6 (existing + parents) 
        |> Map.add 8 (parents) 
        |> Map.remove -1 

    let inputs = Utils.readFileAsLineSeq("day6inputs.txt")

    let initialFish = 
        inputs
        |> Seq.head
        |> (fun str  -> str.Split(","))
        |> Seq.map (fun (numberString: string) -> int (Int32.Parse(numberString)))

    let initialFishDayCountMap = 
        initialFish
        |> Seq.countBy id
        |> Seq.map (fun (f, c) -> f, (int64 c))
        |> Map.ofSeq

    let fishAfterDays days = 
        [0..days - 1] 
        |> List.fold (fun fishDayCountMap day -> 
            advanceDay fishDayCountMap
        ) initialFishDayCountMap


    let fishCount = 
        fishAfterDays 256
        |> Map.toList
        |> List.sumBy (fun (_, count) -> count)

    let result = fishCount
2 Likes

https://adventofcode.com/2021/day/7

Day 7-1

Ce am inteles din problema: sa aduc o lista de numere la aceeasi valoare si sa tin evidenta distantei dintre valoare initiala si cea dorita. La final suma. Din fericire, am putut sa rezolv “băbește”.

let inputs = Utils.readFileAsLineSeq("day7inputs.txt")

let initialCrabs = 
    inputs
    |> Seq.head
    |> (fun str  -> str.Split(","))
    |> Seq.map (fun (numberString: string) -> int (Int32.Parse(numberString)))

//ma intereseaza cati am si in ce pozitie
let counts = 
    initialCrabs
    |> Seq.countBy id

//min si max, ca sa stiu in ce plaja de valori trebuie sa verific
let minPos = initialCrabs |> Seq.min
let maxPos = initialCrabs |> Seq.max


//o functie care calculeaza cat costa sa aliniez totul la o pozitie
let calcFuelCostsForPosition position = 
    counts
    |> Seq.map (fun (pos, count) ->
        (Math.Abs(pos - position)), count
    )
    |> Seq.map (fun (fuelNeeded, count) -> fuelNeeded * count)
    |> Seq.sum

//pentru plaja de pozitii, verific costul fiecarei pozitii si aleg pe cea unde ies mai ieftin
let result =  
    [minPos .. maxPos ]
    |> Seq.map (fun position ->
        position, calcFuelCostsForPosition position
    )
    |> Seq.minBy snd

Day 7-2

Acelasi lucru ca la 7-1, doar ca calcFuelCostsForPosition nu mai foloseste distanta dintre initial si dorit, ci e o “progresie aritmetica” (cred). Mi-am amintit ca am facut ceva de genul prin generala si am gasit formula pe net.

let inputs = Utils.readFileAsLineSeq("day7inputs.txt")

let initialCrabs = 
    inputs
    |> Seq.head
    |> (fun str  -> str.Split(","))
    |> Seq.map (fun (numberString: string) -> int (Int32.Parse(numberString)))

let counts = 
    initialCrabs
    |> Seq.countBy id

let minPos = initialCrabs |> Seq.min
let maxPos = initialCrabs |> Seq.max


let calcFuelCostsForPosition position = 
    counts
    |> Seq.map (fun (pos, count) ->
        let constantFuel = (Math.Abs(pos - position));
        //singura diferenta fata de 7-1
        let sumFuel = constantFuel * (constantFuel + 1) / 2 //https://stackoverflow.com/a/55362075/1101584
        sumFuel, count
    )
    |> Seq.map (fun (fuelNeeded, count) -> fuelNeeded * count)
    |> Seq.sum

let result =  
    [minPos .. maxPos ]
    |> Seq.map (fun position ->
        position, calcFuelCostsForPosition position
    )
    |> Seq.minBy snd

https://adventofcode.com/2021/day/8

Day 8-1 Nu am salvat solutia :(

Solutia pentru partea 1 a fost simpla dupa ce mi-am dat seama ca trebuia sa tin evidenta unor strings de anumite lungimi

Day 8-2 B-ă-b-e-ș-t-e

Initial am inceput complicandu-ma si gandindu-ma la o solutie generala care sa afle ce litera corespunde fiecarui segment din display si apoi sa fac conversia inapoi in cifre. Dar m-am dat batut.
Am luat foaie si pix si am descris fiecare cifra in termeni de elemente comune cu celelate cifre stiute.
Urat, neelegant, ineficient, am folosit si mutable. Ar trebui sa imi fie rusine. Doesn’t matter, had (stars).


let sortString (str: string) = 
    str
    |> Seq.sort
    |> String.Concat


let lineToDigits (str: string) =
    let display =
        str.Split(" | ")
        |> Seq.head
        |> (fun str -> str.Split(" "))
        |> Array.map sortString
    
    let number =
        str.Split(" | ")
        |> Seq.last
        |> (fun str -> str.Split(" "))
        |> Array.map sortString

    display, number


let filterKnownDigits (digits: string []) = 
    digits
    |> Seq.choose (fun (d:string) -> 
        match String.length d with
        | 2 -> Some (1, d)
        | 3 -> Some (7, d)
        | 4 -> Some (4, d)
        | 7 -> Some (8, d)
        | _ -> None
    )

let stringToCharSet (str: string) = 
    str
    |> Set.ofSeq

let getDigitsByLength (length:int) (digits: string [])  =
    digits
    |> Seq.filter (fun digitString -> String.length digitString = length)

let getCommonLettersCount digitString1 digitString2 = 
    let d1 = stringToCharSet digitString1
    let d2 = stringToCharSet digitString2

    Set.intersect d1 d2
    |> Seq.length

let decode (digits: string []) = 
    let mutable knownDigitsMap: Map<int, string> = digits |> filterKnownDigits |> Map.ofSeq

    let six = 
        digits
        |> getDigitsByLength 6
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[7] = 2    
        )

    knownDigitsMap <- Map.add 6 six knownDigitsMap

    let nine = 
        digits
        |> getDigitsByLength 6
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[7] = 3 &&            
            getCommonLettersCount digitString knownDigitsMap.[4] = 4            
        )

    knownDigitsMap <- Map.add 9 nine knownDigitsMap

    let zero = 
        digits
        |> getDigitsByLength 6
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[7] = 3 &&       
            getCommonLettersCount digitString knownDigitsMap.[4] = 3        
        )

    knownDigitsMap <- Map.add 0 zero knownDigitsMap

    let three = 
        digits
        |> getDigitsByLength 5
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[1] = 2            
        )
    knownDigitsMap <- Map.add 3 three knownDigitsMap
    
    let five = 
        digits
        |> getDigitsByLength 5
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[6] = 5            
        )

    knownDigitsMap <- Map.add 5 five knownDigitsMap
    
    let two = 
        digits
        |> getDigitsByLength 5
        |> Seq.find (fun digitString -> 
            getCommonLettersCount digitString knownDigitsMap.[6] = 4 &&
            getCommonLettersCount digitString knownDigitsMap.[1] = 1 

        )

    knownDigitsMap <- Map.add 2 two knownDigitsMap

    knownDigitsMap
    |> Map.toList
    |> List.map (fun (k, v) -> (v, k))
    |> Map.ofList
    
let inputs = Utils.readFileAsLineSeq("day8inputs.txt")

let lines =
    inputs
    |> Seq.map lineToDigits
    |> Seq.map (fun (display, numbers) ->
        let stringToNumberMap = decode display

        Utils.log stringToNumberMap
        Utils.log numbers
        Utils.log "---"


        stringToNumberMap.[numbers.[0]] * 1000 +        
        stringToNumberMap.[numbers.[1]] * 100 +        
        stringToNumberMap.[numbers.[2]] * 10 +        
        stringToNumberMap.[numbers.[3]] * 1         
    )

let result = Seq.sum lines

1 Like

Ma dau batut. Descrierile puzzle-urilor sunt destul de complicate si ma intreb destul de des “ce a vrut sa zica autorul?”. Dureaza cam 1.5h pe zi sa le rezolv si nu mai ma mai bucura.

Daca vreti sa vedeti cum rezolva “profesionistii” puzzle-urile in ~5 minute:

https://www.youtube.com/channel/UCuWLIm0l4sDpEe28t41WITA

Day 9-1
let lineToNumbers (str: string) =
    str
    |> Seq.map(fun c -> int (Int32.Parse(string c)))

let inputs = Utils.readFileAsLineSeq("day9inputs.txt")

let arr = 
    inputs
    |> Seq.map (lineToNumbers >> Array.ofSeq)
    |> Array.ofSeq

let getNumbersAround x y (arr: int[][]) : int list = 
    let getItemAt x y = 
        arr |> Array.tryItem x |> Option.bind (fun yRow -> yRow |> Array.tryItem y)
    
    let around = 
        [
            getItemAt (x - 1) (y + 1)
            getItemAt (x) (y + 1)
            getItemAt (x + 1) (y + 1)
            getItemAt (x + 1) (y)
            getItemAt (x - 1) (y)
            getItemAt (x - 1) (y - 1)
            getItemAt (x) (y - 1)
            getItemAt (x + 1) (y - 1)
        ] |> List.choose id 
    
    around

let localMinimums = 
    arr
    |> array2D
    |> Array2D.mapi (fun x y number -> 
        let around = getNumbersAround x y arr

        match around |> Seq.tryFind (fun n -> n <= number) with
        | Some _ -> None
        | None -> Some (x, y)
    )
    |> Seq.cast<int option>
    |> Seq.choose id

let riskLevels = 
    localMinimums 
    |> Seq.map (fun m -> m + 1)

let result = Seq.sum riskLevels
Day 9-2
let lineToNumbers (str: string) =
    str
    |> Seq.map(fun c -> int (Int32.Parse(string c)))

let inputs = Utils.readFileAsLineSeq("day9inputs.txt")

let arr = 
    inputs
    |> Seq.map (lineToNumbers >> Array.ofSeq)
    |> Array.ofSeq

let getNumbersAround x y (arr: int[][]) : (int * int * int) list = 
    let getItemAt x y = 
        arr |> Array.tryItem x 
        |> Option.bind (fun yRow -> yRow |> Array.tryItem y)
        |> Option.map (fun number -> number, x, y)
    
    let around = 
        [
            getItemAt (x) (y + 1)
            getItemAt (x + 1) (y)
            getItemAt (x - 1) (y)
            getItemAt (x) (y - 1)
        ] |> List.choose id 
    
    around

let localMinimums = 
    arr
    |> array2D
    |> Array2D.mapi (fun x y number -> 
        let around = getNumbersAround x y arr

        match around |> Seq.tryFind (fun (n, _, _) -> n <= number) with
        | Some _ -> None
        | None -> Some (x, y)
    )
    |> Seq.cast<(int * int) option>
    |> Seq.choose id


let floodFrom x y arr =
    let getNeighbours x y = 
        getNumbersAround x y arr
        |> List.filter (fun (number, x, y) -> number < 9)
        |> List.map (fun (number, x, y) -> (x, y))

    let rec expand checkedItems toCheck (basinItems: (int * int) list) = 
        let basinNeighbours = 
            toCheck
            |> List.collect (fun (x, y) -> 
                getNeighbours  x y
            )
            |> List.distinct
            |> List.filter (fun (x, y) -> not (List.contains (x, y) checkedItems ))

        let allNeighbours = 
            toCheck
            |> List.collect (fun (x, y) -> 
                getNumbersAround  x y arr
                |> List.map (fun (number, x, y) -> (x, y))

            )
            |> List.distinct

        if List.isEmpty basinNeighbours 
        then basinItems
        else
            let checkedItems = List.append checkedItems allNeighbours |> List.distinct
            let basinItems = List.append basinItems basinNeighbours |> List.distinct
 
            expand checkedItems basinNeighbours basinItems

    expand [] [(x, y)] []


let basins = 
    localMinimums
    |> Seq.map (fun (x, y) -> floodFrom x y arr)
    |> Seq.map (Seq.length)
    |> Seq.sortDescending
    |> Seq.take 3
    |> Seq.reduce (*)


let result = basins
Day 10-1

let lineToChars (str: string) =
    str
    |> Seq.map id

let inputs = Utils.readFileAsLineSeq("day10inputs.txt")


let openers = ['('; '['; '<'; '{' ]
let closers = [')'; ']'; '>'; '}' ]

let openersToClosersMap =
    [
        '(', ')'
        '[', ']'
        '{', '}'
        '<', '>'
    ] |> Map.ofList

let canClose opener potentialCloser = 
    let closer = openersToClosersMap.[opener]

    closer = potentialCloser 

let (|Opener|Closer|) input = 
    if List.contains input openers
    then Opener
    else Closer


let parseLine chars = 
    let rec search openersStack remainingChars maybeWrongCloser = 
        if Seq.isEmpty remainingChars
        then maybeWrongCloser
        else
            let char = Seq.head remainingChars

            let openersStack, maybeWrongCloser = 
                match char with
                | Opener -> 
                    char :: openersStack, None
                | Closer -> 
                    let opener = List.tryHead openersStack

                    match opener with
                    | Some opener when canClose opener char ->
                        (List.tail openersStack), None

                    | _ -> openersStack, Some char
            
            match maybeWrongCloser with
            | Some char -> Some char
            | None ->
                search openersStack (Seq.tail remainingChars) maybeWrongCloser

    search [] chars None

let scoringMap = 
    [
        ')', 3
        ']', 57
        '}', 1197
        '>', 25137
    ] |> Map.ofList

let parsedLines = 
    inputs
    |> Seq.map (lineToChars)
    |> Seq.choose parseLine
    

let result = 
    parsedLines
    |> Seq.map (fun c -> scoringMap.[c])
    |> Seq.sum

Day 10-2

let lineToChars (str: string) =
    str
    |> Seq.map id

let inputs = Utils.readFileAsLineSeq("day10inputs.txt")


let openers = ['('; '['; '<'; '{' ]
let closers = [')'; ']'; '>'; '}' ]

let openersToClosersMap =
    [
        '(', ')'
        '[', ']'
        '{', '}'
        '<', '>'
    ] |> Map.ofList

let canClose opener potentialCloser = 
    let closer = openersToClosersMap.[opener]

    closer = potentialCloser 

let (|Opener|Closer|) input = 
    if List.contains input openers
    then Opener
    else Closer


let parseLine chars = 
    let rec search openersStack remainingChars = 
        if Seq.isEmpty remainingChars
        then Some openersStack
        else
            let char = Seq.head remainingChars

            let openersStack, maybeWrongCloser = 
                match char with
                | Opener -> 
                    char :: openersStack, None
                | Closer -> 
                    let opener = List.tryHead openersStack

                    match opener with
                    | Some opener when canClose opener char ->
                        (List.tail openersStack), None

                    | _ -> openersStack, Some char
            
            match maybeWrongCloser with
            | Some char -> None
            | None ->
                search openersStack (Seq.tail remainingChars)

    search [] chars

let scoringMap = 
    [
        ')', 1
        ']', 2
        '}', 3
        '>', 4
    ] |> Map.ofList

let parsedLines = 
    inputs
    |> Seq.map (lineToChars)
    |> Seq.choose parseLine


let scoreLine chars = 
    chars
    |> List.fold (fun score c ->
        (score * 5L) + (int64 scoringMap.[c])
    ) 0L
    

let lineScores = 
    parsedLines
    |> Seq.map (fun openers ->  
        openers
        |> List.map (fun c -> openersToClosersMap.[c])
    )
    |> Seq.map (scoreLine)
    |> Seq.sort

let middlePoint = int (System.Math.Floor(float (Seq.length lineScores) / 2.))

let result = lineScores |> Array.ofSeq |> Array.item middlePoint

Day 11-1 Nu am salvat solutia

Day 11-2

let lineToNumbers (str: string) =
    str
    |> Seq.map(fun c -> int (Int32.Parse(string c)))

let inputs = Utils.readFileAsLineSeq("day11inputs.txt")

let arr = 
    inputs
    |> Seq.map (lineToNumbers >> Array.ofSeq)
    |> array2D

let zeroArr = 
    arr
    |> Array2D.map (fun n -> 0)

let getNumbersAround x y (arr: int[,]) : (int * int * int) list = 
    let getItemAt x y = 
        try
            Some (x, y, Array2D.get arr x y) 
        with 
            | :? System.ArgumentException -> None
            | :? System.IndexOutOfRangeException -> None

    let around = 
        [
            getItemAt (x - 1) (y + 1)
            getItemAt (x) (y + 1)
            getItemAt (x + 1) (y + 1)
            getItemAt (x + 1) (y)
            getItemAt (x - 1) (y)
            getItemAt (x - 1) (y - 1)
            getItemAt (x) (y - 1)
            getItemAt (x + 1) (y - 1)
        ] 
        |> List.choose id 
    
    around

let step (arr: int[,]) stepNumber = 
    let getPositionsToFlash (arr: int[,]) = 
        arr
        |> Array2D.mapi (fun x y number ->
            if number > 9
            then Some (x, y)
            else None
        )
        |> Seq.cast<(int * int) option>
        |> Seq.choose id
        |> Seq.toList

    let rec flash toFlash flashed (arr: int [,]) = 
        match toFlash with
        | [] -> arr, flashed
        | _ ->
            toFlash
            |> List.collect (fun (x, y) -> getNumbersAround x y arr)
            |> List.iter (fun (x, y, n) -> 
                arr.[x,y] <- arr.[x,y] + 1 
            )

            let newFlashed = (List.append flashed toFlash)

            let newFlashing =
                getPositionsToFlash arr
                |> List.filter (fun (x,y) -> 
                    not (List.contains (x, y) newFlashed)
                )
              

            flash newFlashing newFlashed arr
        

    let increased = 
        arr
        |> Array2D.mapi (fun x y number ->
            number + 1
        )

   

    let finished, flashedPositions = flash (getPositionsToFlash increased) [] increased

    let reset = 
        finished
        |> Array2D.map (fun n ->
            if n > 9
            then 0
            else n
        )

    let allFlashed = 
        if (reset = zeroArr)
        then Some stepNumber
        else None

    reset, allFlashed

let (a, maybeAllFlashed) = 
    [1..400]
    |> List.fold (fun (arr, maybeAllFlashed) stepNumber -> 
        if Option.isSome maybeAllFlashed
        then (arr, maybeAllFlashed)
        else 
            let arr, maybeAllFlashed = step arr stepNumber 
          
            (arr, maybeAllFlashed)
    ) (arr, None)
    



let result = maybeAllFlashed

2 Likes

Bloc citat
Daca vreti sa vedeti cum rezolva “profesionistii” puzzle-urile in ~5 minute:
https://www.youtube.com/channel/UCuWLIm0l4sDpEe28t41WITA

Vai de capul lui :joy:.

Bloc citat
Ma dau batut. Descrierile puzzle-urilor sunt destul de complicate si ma intreb destul de des “ce a vrut sa zica autorul?”

Spre deosebire de alte concursuri de programare sau probleme de interviuri, pana acum au fost destul de straight forward. Unde ai intampinat probleme?

Daca fac ceva pentru ca e distractiv, dar mai tarziu nu mai e distractiv, nu mai fac acel ceva.