• 1 Post
  • 17 Comments
Joined 1 year ago
cake
Cake day: June 20th, 2023

help-circle

  • [LANGUAGE: C#]

    I kept trying to create clever solutions, but ended up falling back on regex when it was taking to long. THE TLDR is we scan the list of strings for a symbol, then parse the three lines above, below and inline with the symbol for digits. Then we try and match the indexes of the match and the area around the symbol. Part 2 was a small modification, and was mostly about getting the existing code to conform the data into a pattern for each of the three lines.

    Part 1

    static char[] Symbols = { '@', '#', '$', '%', '&', '*', '/', '+', '-', '=' };
    string pattern = @"\d+";
    static List? list;
    list = new List((await File.ReadAllLinesAsync(@".\Day 3\PuzzleInput.txt")));
    
    int count = 0;
    for (int row = 0; row < list.Count; row++)
    {
        for (int col = 0; col < list[row].Length; col++)
        {
            var c = list[row][col];
            if (c == '.')
            {
                continue;
            }
    
            if (Symbols.Contains(c))
            {
                var res = Calculate(list[row - 1], col);
                res += Calculate(list[row], col);
                res += Calculate(list[row + 1], col);
                count += res;
            }
    
        }
    }
    Console.WriteLine(count);
    
    private static int Calculate(string line, int col)
    {
        List indexesToCheck = new List { col - 1, col, col + 1 };
        int count = 0;
        MatchCollection matches = Regex.Matches(line, pattern);
    
        foreach (Match match in matches)
        {
            string number = match.Value;
    
            if (AnyIndexInList(indexesToCheck, match.Index, match.Length))
            {
                count += Int32.Parse(number);
            }
        }
        return count;
    }
    
    static bool AnyIndexInList(List list, int startIndex, int length)
    {
        for (int i = startIndex; i < startIndex + length; i++)
        {
            if (list.Contains(i))
            {
                return true;
            }
        }
        return false;
    }
    

    Part 2:

    list = new List((await File.ReadAllLinesAsync(@".\Day 3\PuzzleInput.txt")));
    
    int count = 0;
    for (int row = 0; row < list.Count; row++)
    {
        for (int col = 0; col < list[row].Length; col++)
        {
            var c = list[row][col];
            if (c == '.')
                continue;
            
            if (c == '*')
            {
                var res1 = Calculate2(list[row - 1], col);
                var res2 = Calculate2(list[row], col);
                var res3 = Calculate2(list[row + 1], col);
    
                count += (res1, res2, res3) switch 
                {
                    {res1: not null, res2: null, res3: null } when  res1[1] != null => res1[0].Value * res1[1].Value,
                    {res1:  null, res2: not null, res3: null } when res2[1] != null => res2[0].Value * res2[1].Value,
                    {res1:  null, res2: null, res3: not null } when res3[1] != null => res3[0].Value * res3[1].Value,
    
                    {res1: not null, res2: not null, res3: null } => res1[0].Value * res2[0].Value,
                    {res1: not null, res2: null, res3: not null } => res1[0].Value * res3[0].Value,
                    {res1: null, res2: not null, res3: not null } => res2[0].Value * res3[0].Value,
                    {res1: not null, res2: not null, res3: not null } => res1[0].Value * res2[0].Value * res3[0].Value,
    
                    _ => 0
                } ;
            }
        }
    }
                    
    Console.WriteLine(count);
    
    
    private static int?[]? Calculate2(string line, int col)
    {
        List indexesToCheck = new List { col - 1, col, col + 1 };
        int?[]? count = null;
        MatchCollection matches = Regex.Matches(line, pattern);
    
        foreach (Match match in matches)
        {
            string number = match.Value;
    
            if (AnyIndexInList(indexesToCheck, match.Index, match.Length))
            {
                if (count == null)
                    count = new int?[2] { Int32.Parse(number), null };
                else {
                    count[1] = Int32.Parse(number);
                };
            }
        }
        return count;
    }
    

  • [LANGUAGE: C#]

    Part 1:

    var list = new List((await File.ReadAllLinesAsync(@".\Day 2\PuzzleInput.txt")));
    int conter = 0;
    foreach (var line in list)
    {
        string[] split = line.Split(":");
        int game = Int32.Parse( split[0].Split(" ")[1]);
        string[] bagContents = split[1].Split(";");
        var max = new Dictionary() { { "red", 0 }, { "green", 0 }, { "blue", 0 } };
        foreach (var content in bagContents)
        {
            string pattern = @"(\d+) (\w+)";
            MatchCollection matches = Regex.Matches(content, pattern);
    
            foreach (Match match in matches)
            {
                int number = Int32.Parse(match.Groups[1].Value);
                string color = match.Groups[2].Value;
                max[color] = (max[color] >= number)? max[color] : number;
            }
        }
        conter += (max["red"] <= 12 && max["green"] <= 13 && max["blue"] <= 14) ? game : 0;
    
    }
    Console.WriteLine(conter);
    

    Part 2:

    var list = new List((await File.ReadAllLinesAsync(@".\Day 2\PuzzleInput.txt")));
    
    int conter = 0;
    foreach (var line in list)
    {
        string[] split = line.Split(":");
        int game = Int32.Parse(split[0].Split(" ")[1]);
        string[] bagContents = split[1].Split(";");
            var max = new Dictionary();
        foreach (var content in bagContents)
        {
            string pattern = @"(\d+) (\w+)";
    
            MatchCollection matches = Regex.Matches(content, pattern);
    
            foreach (Match match in matches)
            {
                int number = Int32.Parse(match.Groups[1].Value);
                string color = match.Groups[2].Value;
                if (!max.ContainsKey(color))
                    max[color] = number;
                else if(max[color] < number)
                    max[color] = number;
            }
        }
        conter += max.Values.Aggregate(1, (total, value) => total *  value );
    
    }
    Console.WriteLine(conter);
    

  • [Language: C#]

    This isn't the most performant or elegant, it's the first one that worked. I have 3 kids and a full time job. If I get through any of these, it'll be first pass through and first try that gets the correct answer.

    Part 1 was very easy, just iterated the string checking if the char was a digit. Ditto for the last, by reversing the string. Part 2 was also not super hard, I settled on re-using the iterative approach, checking each string lookup value first (on a substring of the current char), and if the current char isn't the start of a word, then checking if the char was a digit. Getting the last number required reversing the string and the lookup map.

    Part 1:

    var list = new List((await File.ReadAllLinesAsync(@".\Day 1\PuzzleInput.txt")));
    
    int total = 0;
    foreach (var item in list)
    {
        //forward
        string digit1 = string.Empty;
        string digit2 = string.Empty;
    
    
        foreach (var c in item)
        {
            if ((int)c >= 48 && (int)c <= 57)
            {
                digit1 += c;
            
                break;
            }
        }
        //reverse
        foreach (var c in item.Reverse())
        {
            if ((int)c >= 48 && (int)c <= 57)
            {
                digit2 += c;
    
                break;
            }
    
        }
        total += Int32.Parse(digit1 +digit2);
    }
    
    Console.WriteLine(total);
    

    Part 2:

    var list = new List((await File.ReadAllLinesAsync(@".\Day 1\PuzzleInput.txt")));
    var numbers = new Dictionary() {
        {"one" ,   1}
        ,{"two" ,  2}
        ,{"three" , 3}
        ,{"four" , 4}
        ,{"five" , 5}
        ,{"six" , 6}
        ,{"seven" , 7}
        ,{"eight" , 8}
        , {"nine" , 9 }
    };
    int total = 0;
    string digit1 = string.Empty;
    string digit2 = string.Empty;
    foreach (var item in list)
    {
        //forward
        digit1 = getDigit(item, numbers);
        digit2 = getDigit(new string(item.Reverse().ToArray()), numbers.ToDictionary(k => new string(k.Key.Reverse().ToArray()), k => k.Value));
        total += Int32.Parse(digit1 + digit2);
    }
    
    Console.WriteLine(total);
    
    string getDigit(string item,                 Dictionary numbers)
    {
        int index = 0;
        int digit = 0;
        foreach (var c in item)
        {
            var sub = item.AsSpan(index++);
            foreach(var n in numbers)
            {
                if (sub.StartsWith(n.Key))
                {
                    digit = n.Value;
                    goto end;
                }
            }
    
            if ((int)c >= 48 && (int)c <= 57)
            {
                digit = ((int)c) - 48;
                break;
            }
        }
        end:
        return digit.ToString();
    }
    








  • I find ORMs exist best in a mid-sized project, most valuable in a CQRS context.

    For anything small, they massively over complicate the architecture. For the large enterprise systems, they always seem to choke on an already large and complex domain.

    So a mid size project, maybe with less than a hundred or so data objects works best with an ORM. In that way, they've also been most productive mainly for the CUD of the CRUD approach. I'd rather write my domain logic with the speed and safety of an ORM during writes, but leverage the flexibility and expressiveness of SQL when I'm crafting efficient read queries.



  • SPAs are mostly garbage, and the internet has been irreparably damaged by lazy devs chasing trends just to building simple sites with overly complicated fe frameworks.

    90% of the internet actually should just be rendered server side with a bit of js for interactivity. JQuery was fine at the time, Javascript is better now and Alpinejs is actually awesome. Nowadays, REST w/HTMX and HATEOAS is the most productive, painless and enjoyable web development can get. Minimal dependencies, tiny file sizes, fast and simple.

    Unless your web site needs to work offline (it probably doesn't), or it has to manage client state for dozen/hundreds of data points (e.g. Google Maps), you don't need a SPA. If your site only needs to track minimal state, just use a good SSR web framework (Rails, asp.net, Django, whatever).