hades

joined 2 years ago
[–] hades@lemm.ee 7 points 1 month ago

that's not like JSON at all. JSON is human readable, while this is clearly a binary format

[–] hades@lemm.ee 3 points 1 month ago

any chance it's overheating? did you clean the vents and checked the fans?

[–] hades@lemm.ee 1 points 2 months ago (2 children)

That just makes sense -- the top-1k are competitive programmers, and today's puzzle had nothing to do with competitive programming :)

[–] hades@lemm.ee 3 points 2 months ago (1 children)

Feels like a really bad way to get the solution, though.

Does that come from an expectation that AoC is a programming challenge, where you typically are expected to come up with an implementation that works for all possible inputs? Because AoC is intentionally not that. Some tasks in AoC can/should be solved by hand, and I don't think you should feel bad about it :)

[–] hades@lemm.ee 4 points 2 months ago (1 children)

In my input (and I suppose in everyone else's too) the swaps only occurred within the adder subcircuit for a single bit. In general, however, the way the problem is phrased, any two outputs can be swapped, which can lead to two broken bits per swap (but this just doesn't happen).

[–] hades@lemm.ee 4 points 2 months ago (4 children)

Good, although it took some time. Actually, I got my personal best global rank on that problem.

[–] hades@lemm.ee 12 points 2 months ago

good start to your new collection of abstract art

[–] hades@lemm.ee 2 points 2 months ago (1 children)

Could you fix the year in the title? Will get confusing in four years :)

[–] hades@lemm.ee 3 points 2 months ago

C#

public class Day19 : Solver {
  private string[] designs;

  private class Node {
    public Dictionary<char, Node> Children = [];
    public bool Terminal = false;
  }

  private Node root;

  public void Presolve(string input) {
    List<string> lines = [.. input.Trim().Split("\n")];
    designs = lines[2..].ToArray();
    root = new();
    foreach (var pattern in lines[0].Split(", ")) {
      Node cur = root;
      foreach (char ch in pattern) {
        cur.Children.TryAdd(ch, new());
        cur = cur.Children[ch];
      }
      cur.Terminal = true;
    }
  }

  private long CountMatches(Node cur, Node root, string d) {
    if (d.Length == 0) return cur.Terminal ? 1 : 0;
    if (!cur.Children.TryGetValue(d[0], out var child)) return 0;
    return CountMatches(child, root, d[1..]) + (child.Terminal ? CountMatches(root, d[1..]) : 0);
  }

  private readonly Dictionary<string, long> cache = [];
  private long CountMatches(Node root, string d) {
    if (cache.TryGetValue(d, out var cached_match)) return cached_match;
    long match = CountMatches(root, root, d);
    cache[d] = match;
    return match;
  }

  public string SolveFirst() => designs.Where(d => CountMatches(root, d) > 0).Count().ToString();

  public string SolveSecond() => designs.Select(d => CountMatches(root, d)).Sum().ToString();
}
[–] hades@lemm.ee 2 points 2 months ago
  • A* algorithm
  • honestly a lot of other graph algorithms, just be aware of them, and be able to find algorithms you didn't know before
  • OEIS
  • SMT solvers
  • set operations on intervals
[–] hades@lemm.ee 2 points 2 months ago

C#

using QuickGraph;
using QuickGraph.Algorithms.ShortestPath;

namespace aoc24;

public class Day18 : Solver {
  private int width = 71, height = 71, bytes = 1024;
  private HashSet<(int, int)> fallen_bytes;
  private List<(int, int)> fallen_bytes_in_order;
  private record class Edge((int, int) Source, (int, int) Target) : IEdge<(int, int)>;
  private DelegateVertexAndEdgeListGraph<(int, int), Edge> MakeGraph() => new(GetAllVertices(), GetOutEdges);

  private readonly (int, int)[] directions = [(-1, 0), (0, 1), (1, 0), (0, -1)];

  private bool GetOutEdges((int, int) arg, out IEnumerable<Edge> result_enumerable) {
    List<Edge> result = [];
    foreach (var (dx, dy) in directions) {
      var (nx, ny) = (arg.Item1 + dx, arg.Item2 + dy);
      if (nx < 0 || ny < 0 || nx >= width || ny >= height) continue;
      if (fallen_bytes.Contains((nx, ny))) continue;
      result.Add(new(arg, (nx, ny)));
    }
    result_enumerable = result;
    return true;
  }

  private IEnumerable<(int, int)> GetAllVertices() {
    for (int i = 0; i < width; i++) {
      for (int j = 0; j < height; j++) {
        yield return (i, j);
      }
    }
  }

  public void Presolve(string input) {
    fallen_bytes_in_order = [..input.Trim().Split("\n")
      .Select(line => line.Split(","))
      .Select(pair => (int.Parse(pair[0]), int.Parse(pair[1])))];
    fallen_bytes = [.. fallen_bytes_in_order.Take(bytes)];
  }

  private double Solve() {
    var graph = MakeGraph();
    var search = new AStarShortestPathAlgorithm<(int, int), Edge>(graph, _ => 1, vtx => vtx.Item1 + vtx.Item2);
    search.SetRootVertex((0, 0));
    search.ExamineVertex += vertex => {
      if (vertex.Item1 == width - 1 && vertex.Item2 == width - 1) search.Abort();
    };
    search.Compute();
    return search.Distances[(width - 1, height - 1)];
  }

  public string SolveFirst() => Solve().ToString();

  public string SolveSecond() {
    foreach (var b in fallen_bytes_in_order[bytes..]) {
      fallen_bytes.Add(b);
      if (Solve() > width*height) return $"{b.Item1},{b.Item2}";
    }
    throw new Exception("solution not found");
  }
}
[–] hades@lemm.ee 1 points 2 months ago

Great find, thanks for sharing!

 
view more: next ›