SteveDinn

joined 2 years ago
[โ€“] [email protected] 2 points 6 months ago* (last edited 6 months ago) (1 children)

C#

using System.Diagnostics;
using Common;

namespace Day10;

static class Program
{
    static void Main()
    {
        var start = Stopwatch.GetTimestamp();

        var sampleInput = Input.ParseInput("sample.txt");
        var programInput = Input.ParseInput("input.txt");

        Console.WriteLine($"Part 1 sample: {Part1(sampleInput)}");
        Console.WriteLine($"Part 1 input: {Part1(programInput)}");

        Console.WriteLine($"Part 2 sample: {Part2(sampleInput)}");
        Console.WriteLine($"Part 2 input: {Part2(programInput)}");

        Console.WriteLine($"That took about {Stopwatch.GetElapsedTime(start)}");
    }

    static object Part1(Input i) => GetTrailheads(i)
        .Sum(th => CountTheNines(th, i, new HashSet<Point>(), false));

    static object Part2(Input i) => GetTrailheads(i)
        .Sum(th => CountTheNines(th, i, new HashSet<Point>(), true));

    static int CountTheNines(Point loc, Input i, ISet<Point> visited, bool allPaths)
    {
        if (!visited.Add(loc)) return 0;
        
        var result =
            (ElevationAt(loc, i) == 9) ? 1 :
            loc.GetCardinalMoves()
                .Where(move => move.IsInBounds(i.Bounds.Row, i.Bounds.Col))
                .Where(move => (ElevationAt(move, i) - ElevationAt(loc, i)) == 1)
                .Where(move => !visited.Contains(move))
                .Sum(move => CountTheNines(move, i, visited, allPaths));
        
        if(allPaths) visited.Remove(loc);
        
        return result;
    }

    static IEnumerable<Point> GetTrailheads(Input i) => Grid.EnumerateAllPoints(i.Bounds)
        .Where(loc => ElevationAt(loc, i) == 0);

    static int ElevationAt(Point p, Input i) => i.Map[p.Row][p.Col];
}

public class Input
{
    public required Point Bounds { get; init; }
    public required int[][] Map { get; init; }
    
    public static Input ParseInput(string file)
    {
        using var reader = new StreamReader(file);
        var map = reader.EnumerateLines()
            .Select(l => l.Select(c => (int)(c - '0')).ToArray())
            .ToArray();
        var bounds = new Point(map.Length, map.Max(l => l.Length));
        return new Input()
        {
            Map = map,
            Bounds = bounds,
        };
    }
}
[โ€“] [email protected] 1 points 6 months ago

I wish the web interface let you sort the sub categories both ways. I have a series of subcategories of Year/month that I'm using as a journal and the longer I keep writing, the further have to scroll down :/

[โ€“] [email protected] 2 points 6 months ago

C#

using System.Collections;
using System.Diagnostics;
using Common;

namespace Day09;

static class Program
{
    static void Main()
    {
        var start = Stopwatch.GetTimestamp();

        var sampleInput = Input.ParseInput("sample.txt");
        var programInput = Input.ParseInput("input.txt");

        Console.WriteLine($"Part 1 sample: {Part1(sampleInput)}");
        Console.WriteLine($"Part 1 input: {Part1(programInput)}");

        Console.WriteLine($"Part 2 sample: {Part2(sampleInput)}");
        Console.WriteLine($"Part 2 input: {Part2(programInput)}");

        Console.WriteLine($"That took about {Stopwatch.GetElapsedTime(start)}");
    }

    static object Part1(Input i)
    {
        var disk = i.Disk.ToList();
        
        while (true)
        {
            // Find the next free space with some blocks open.
            var nextFree = disk.FindIndex(d => (d is Free { Blocks: > 0 }));
            var nextUsed = disk.FindLastIndex(d => (d is Used { Blocks: > 0 }));

            if (nextFree > nextUsed) break;

            var free = disk[nextFree] as Free ?? throw new Exception("This is not a Free");
            var used = disk[nextUsed] as Used ?? throw new Exception("This is not a Used");
            var canMove = Math.Min(free.Blocks, used.Blocks);
            disk[nextFree] = free with { Blocks = free.Blocks - canMove };
            disk[nextUsed] = used with { Blocks = used.Blocks - canMove };

            var addingFree = disk[nextUsed - 1] as Free;
            disk[nextUsed - 1] = addingFree! with { Blocks = addingFree.Blocks + canMove };
            var addingUsed = used! with { Blocks = canMove };
            disk.Insert(nextFree, addingUsed);
        }

        // DumpString(disk);
        return CheckSum(disk);
    }

    static object Part2(Input i)
    {
        var disk = i.Disk.ToList();

        var lastUsedId = int.MaxValue;
        while (true)
        {
            // Find the next free space with some blocks open.
            var nextUsed = disk.FindLastIndex(d => (d is Used { Blocks: > 0 } u) && (u.Id < lastUsedId));
            if (nextUsed < 0) break;
            
            var nextFree = disk.FindIndex(d => (d is Free f) && (f.Blocks >= disk[nextUsed].Blocks));
            var used = disk[nextUsed] as Used ?? throw new Exception("This is not a Used");
            lastUsedId = used.Id;
            if ((nextFree < 0) || (nextFree > nextUsed)) continue; 

            var free = disk[nextFree] as Free ?? throw new Exception("This is not a Free");
            var canMove = Math.Min(free.Blocks, used.Blocks);
            disk[nextFree] = free with { Blocks = free.Blocks - canMove };
            disk[nextUsed] = used with { Blocks = used.Blocks - canMove };

            var addingFree = disk[nextUsed - 1] as Free;
            disk[nextUsed - 1] = addingFree! with { Blocks = addingFree.Blocks + canMove };
            var addingUsed = used! with { Blocks = canMove };
            disk.Insert(nextFree, addingUsed);
            
            // DumpString(disk);
        }

        return CheckSum(disk);
    }

    static long CheckSum(IEnumerable<DiskSpace> disk) => disk
        .SelectMany(d => Expand(d))
        .Select((d, i) => (d is Used u) ? (long)(i * u.Id) : 0)
        .Sum();
    
    static IEnumerable<DiskSpace> Expand(DiskSpace d)
    {
        for (int i = 0; i < d.Blocks; i++)
        {
            yield return d with { Blocks = 1 };
        }
    }

    static void DumpString(IEnumerable<DiskSpace> disk)
    {
        foreach(var s in disk.Select(d =>
            (d is Used u) ? new string((char)(u.Id + '0'), u.Blocks) :
            (d is Free { Blocks: > 0 } f) ? new string('.', f.Blocks) :
            ""))
        {
            Console.Write(s);
        }
        
        Console.WriteLine();
    }
}

public abstract record DiskSpace(int Blocks);
public record Free(int Blocks) : DiskSpace(Blocks);
public record Used(int Id, int Blocks) : DiskSpace(Blocks);

public class Input
{
    public DiskSpace[] Disk { get; private init; } = [];
    
    public static Input ParseInput(string file) => new Input()
    {
        Disk = File.ReadAllText(file)
            .TakeWhile(char.IsDigit)
            .Select(c => (int)(c - '0'))
            .Select((c, i) => ((i % 2) == 0) ? (DiskSpace)new Used(i / 2, c) : new Free(c))
            .ToArray(),
    };
}
[โ€“] [email protected] 1 points 6 months ago

C#

namespace Day04;

static class Program
{
    public record struct Point(int Row, int Col);

    static void Main(string[] args)
    {
        var sample = File.ReadAllLines("sample.txt");
        var data = File.ReadAllLines("data.txt");

        Console.WriteLine($"Part 1 (sample): {SolvePart1(sample)}");
        Console.WriteLine($"Part 1 (data): {SolvePart1(data)}");

        Console.WriteLine($"Part 2 (sample): {SolvePart2(sample)}");
        Console.WriteLine($"Part 2 (data): {SolvePart2(data)}");
    }

    private static readonly string Search = "XMAS";

    private static readonly Func<Point, Point>[] DirectionalMoves =
    {
        p => new Point(p.Row + 1, p.Col),
        p => new Point(p.Row + 1, p.Col + 1),
        p => new Point(p.Row, p.Col + 1),
        p => new Point(p.Row - 1, p.Col + 1),
        p => new Point(p.Row - 1, p.Col),
        p => new Point(p.Row - 1, p.Col - 1),
        p => new Point(p.Row, p.Col - 1),
        p => new Point(p.Row + 1, p.Col - 1),
    };

    private static readonly Func<Point, Point>[] ForwardSlashMoves =
    {
        p => new Point(p.Row - 1, p.Col - 1),
        p => new Point(p.Row + 1, p.Col + 1),
    };
    
    private static readonly Func<Point, Point>[] BackSlashMoves =
    {
        p => new Point(p.Row + 1, p.Col - 1),
        p => new Point(p.Row - 1, p.Col + 1),
    };

    static long SolvePart1(string[] data)
    {
        return Enumerable
            .Range(0, data.Length)
            .SelectMany(row => Enumerable.Range(0, data[row].Length)
                .Select(col => new Point(row, col)))
            .Where(p => IsMatch(data, p, Search[0]))
            .Sum(p => DirectionalMoves
                .Count(move => DeepMatch(data, move(p), move, Search, 1)));
    }

    static long SolvePart2(string[] data)
    {
        return Enumerable
            .Range(0, data.Length)
            .SelectMany(row => Enumerable.Range(0, data[row].Length)
                .Select(col => new Point(row, col)))
            .Where(p => IsMatch(data, p, 'A'))
            .Count(p => CheckDiagonalMoves(data, p, ForwardSlashMoves)
                        && CheckDiagonalMoves(data, p, BackSlashMoves));
    }

    static bool CheckDiagonalMoves(string[] data, Point p, Func<Point, Point>[] moves)
        => (IsMatch(data, moves[0](p), 'S') && IsMatch(data, moves[1](p), 'M'))
           || (IsMatch(data, moves[0](p), 'M') && IsMatch(data, moves[1](p), 'S'));

    static bool DeepMatch(string[] data, Point p, Func<Point, Point> move, string search, int searchIndex) =>
        (searchIndex >= search.Length) ? true :
        (!IsMatch(data, p, search[searchIndex])) ? false :
        DeepMatch(data, move(p), move, search, searchIndex + 1);

    static bool IsMatch(string[] data, Point p, char searchChar)
        => IsInBounds(data, p) && (data[p.Row][p.Col] == searchChar);

    static bool IsInBounds(string[] data, Point p) =>
        (p.Row >= 0) && (p.Col >= 0) && (p.Row < data.Length) && (p.Col < data[0].Length);
}
[โ€“] [email protected] 1 points 6 months ago

C#

using System;
using System.Linq;

public record Point(int X, int Y); 

static class Program
{
    static async Task Main(string[] args)
    {
        var data = (await ReadInputFromFile("data.txt")).ToArray();

        var part1Answer = CalculateTotalDifference(data);
        Console.WriteLine($"Part 1 = {part1Answer}");

        var part2Answer = CountFrequencies(data);
        Console.WriteLine($"Part 2 = {part2Answer}");
    }

    public static int CountFrequencies(ICollection<Point> points)
    {
        var freq = points
            .GroupBy(p => p.Y)
            .ToDictionary(g => g.Key, g => g.Count());
        return points
            .Sum(p => freq.GetValueOrDefault(p.X, 0) * p.X);
    }

    public static int CalculateTotalDifference(ICollection<Point> points)
        => points.OrderBy(p => p.X)
            .Zip(
                points.OrderBy(p => p.Y),
                (px, py) => Math.Abs(px.X - py.Y))
            .Sum();

    public static readonly char[] Delimiter = new char[] { ' ' };
    public static async Task<IEnumerable<Point>> ReadInputFromFile(string path)
        => (await File.ReadAllLinesAsync(path))
            .Select(l =>
            {
                var parts = l.Split(
                    Delimiter,
                    StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
                return new Point(int.Parse(parts[0]), int.Parse(parts[1]));
            });
}
[โ€“] [email protected] 15 points 7 months ago* (last edited 7 months ago) (4 children)

I can already do this on my Samsung Galaxy S23. Has this been a Samsung-only thing?

That being said, Samsung's Bluetooth UI leaves much to be desired, IMO.

Edit: Granted, it doesn't work exactly as described in the article, but I can have multiple BT speakers playing the same content from my phone.

[โ€“] [email protected] 8 points 7 months ago

A girl walks into a bar and says to the bartender, "I'd like a double entendre."

So he gives it to her.

[โ€“] [email protected] 6 points 8 months ago

I don't think my kids have ever used a Windows machine. I have a couple of machines at home that both run Linux Mint and they use Chromebooks at school. There is not much software that they need that is not either a web page or also available natively.

[โ€“] [email protected] 2 points 8 months ago

Much of the time, the sites only put a small blurb and a link to the actual article in the feed, so you still have to click through to read it all.

[โ€“] [email protected] 10 points 8 months ago* (last edited 8 months ago) (6 children)

Yes, obviously, I could Google this, but I'm looking for real peoples' opinions. I've owned OnePlus and LG android phones previously to my current Samsung. I loved my OnePlus phones, but my current provider doesn't support them.

Edit: LOL. I just realized you were suggesting Google as an android phone manufacturer.

[โ€“] [email protected] 7 points 8 months ago (10 children)

What is the best Android phone manufacturer after we count out Samsung?

[โ€“] [email protected] 2 points 8 months ago* (last edited 8 months ago) (1 children)

Would that be Bob Mann, by any chance, fellow Lemmy.ca user? He's honestly the reason I picked up the show.

view more: โ€น prev next โ€บ