mykl

joined 1 year ago
MODERATOR OF
[–] mykl@lemmy.world 20 points 9 months ago* (last edited 9 months ago) (1 children)

We stayed in Sheerness (where this flight took place), and when my girlfriend saw this she immediately asked “Did pigs fly before women did?”. And the answer turned out to be no, women beat pigs by two weeks: “Sarah Van Deman … was the woman who flew with Wilbur Wright on October 27, 1909” source

[–] mykl@lemmy.world 5 points 10 months ago (1 children)

What does “zoomed in to check which colour they re-used in the second chart so didn’t even realise there was a third one” count as?

[–] mykl@lemmy.world 41 points 10 months ago (5 children)

Isn’t every video game just moving colourful blocks?

(Except Quake obviously)

[–] mykl@lemmy.world -1 points 11 months ago

i_understood_that_reference.jif

[–] mykl@lemmy.world 15 points 11 months ago (1 children)

Dad mode activated

[–] mykl@lemmy.world 1 points 11 months ago* (last edited 11 months ago)

Dart

~~I'm cheating a bit by posting this as it does take 11s for the full part 2 solution, but having tracked down and eliminated the excessively long path for part 1, I can't be bothered to do it again for part 2.~~

I'm an idiot. Avoiding recursively adding the same points to the seen set dropped total runtime to a hair under 0.5s, so line-seconds are around 35.

Map, Set>> seen = {};

Map fire(List> grid, Point here, Point dir) {
  seen = {};
  return _fire(grid, here, dir);
}

Map, Set>> _fire(
    List> grid, Point here, Point dir) {
  while (true) {
    here += dir;
    if (!here.x.between(0, grid.first.length - 1) ||
        !here.y.between(0, grid.length - 1)) {
      return seen;
    }
    if (seen[here]?.contains(dir) ?? false) return seen;
    seen[here] = (seen[here] ?? >{})..add(dir);

    Point split() {
      _fire(grid, here, Point(-dir.y, -dir.x));
      return Point(dir.y, dir.x);
    }

    dir = switch (grid[here.y][here.x]) {
      '/' => Point(-dir.y, -dir.x),
      r'\' => Point(dir.y, dir.x),
      '|' => (dir.x.abs() == 1) ? split() : dir,
      '-' => (dir.y.abs() == 1) ? split() : dir,
      _ => dir,
    };
  }
}

parse(List lines) => lines.map((e) => e.split('').toList()).toList();

part1(List lines) =>
    fire(parse(lines), Point(-1, 0), Point(1, 0)).length;

part2(List lines) {
  var grid = parse(lines);
  var ret = 0.to(grid.length).fold(
      0,
      (s, t) => [
            s,
            fire(grid, Point(-1, t), Point(1, 0)).length,
            fire(grid, Point(grid.first.length, t), Point(-1, 0)).length
          ].max);
  return 0.to(grid.first.length).fold(
      ret,
      (s, t) => [
            s,
            fire(grid, Point(t, -1), Point(0, 1)).length,
            fire(grid, Point(t, grid.length), Point(0, -1)).length
          ].max);
}
[–] mykl@lemmy.world 2 points 11 months ago

That’s why I normally let computers do my sums for me. Corrected now.

[–] mykl@lemmy.world 3 points 11 months ago* (last edited 11 months ago) (2 children)

Dart

Just written as specced. If there's any underlying trick, I missed it totally.

9ms * 35 LOC ~= 0.35, so it'll do.

int decode(String s) => s.codeUnits.fold(0, (s, t) => ((s + t) * 17) % 256);

part1(List lines) => lines.first.split(',').map(decode).sum;

part2(List lines) {
  var rules = lines.first.split(',').map((e) {
    if (e.contains('-')) return ('-', e.skipLast(1), 0);
    var parts = e.split('=');
    return ('=', parts.first, int.parse(parts.last));
  });
  var boxes = Map.fromEntries(List.generate(256, (ix) => MapEntry(ix, [])));
  for (var r in rules) {
    if (r.$1 == '-') {
      boxes[decode(r.$2)]!.removeWhere((l) => l.$1 == r.$2);
    } else {
      var box = boxes[decode(r.$2)]!;
      var lens = box.indexed().firstWhereOrNull((e) => e.value.$1 == r.$2);
      var newlens = (r.$2, r.$3);
      (lens == null) ? box.add(newlens) : box[lens.index] = newlens;
    }
  }
  return boxes.entries
      .map((b) =>
          (b.key + 1) *
          b.value.indexed().map((e) => (e.index + 1) * e.value.$2).sum)
      .sum;
}
[–] mykl@lemmy.world 4 points 11 months ago* (last edited 11 months ago)

Dart

Big lump of code. I built a general slide function which ended up being tricksy in order to visit rocks in the correct order, but it works.

int hash(List> rocks) =>
    (rocks.map((e) => e.join('')).join('\n')).hashCode;

/// Slide rocks in the given (vert, horz) direction.
List> slide(List> rocks, (int, int) dir) {
  // Work out in which order to check rocks for most efficient movement.
  var rrange = 0.to(rocks.length);
  var crange = 0.to(rocks.first.length);
  var starts = [
    for (var r in (dir.$1 == 1) ? rrange.reversed : rrange)
      for (var c in ((dir.$2 == 1) ? crange.reversed : crange)
          .where((c) => rocks[r][c] == 'O'))
        (r, c)
  ];

  for (var (r, c) in starts) {
    var dest = (r, c);
    var next = (dest.$1 + dir.$1, dest.$2 + dir.$2);
    while (next.$1.between(0, rocks.length - 1) &&
        next.$2.between(0, rocks.first.length - 1) &&
        rocks[next.$1][next.$2] == '.') {
      dest = next;
      next = (dest.$1 + dir.$1, dest.$2 + dir.$2);
    }
    if (dest != (r, c)) {
      rocks[r][c] = '.';
      rocks[dest.$1][dest.$2] = 'O';
    }
  }
  return rocks;
}

List> oneCycle(List> rocks) =>
    [(-1, 0), (0, -1), (1, 0), (0, 1)].fold(rocks, (s, t) => slide(s, t));

spin(List> rocks, {int target = 1}) {
  var cycle = 1;
  var seen = {};
  while (cycle != target) {
    rocks = oneCycle(rocks);
    var h = hash(rocks);
    if (seen.containsKey(h)) {
      var diff = cycle - seen[h]!;
      var count = (target - cycle) ~/ diff;
      cycle += count * diff;
      seen = {};
    } else {
      seen[h] = cycle;
      cycle += 1;
    }
  }
  return weighting(rocks);
}

parse(List lines) => lines.map((e) => e.split('').toList()).toList();

weighting(List> rocks) => 0
    .to(rocks.length)
    .map((r) => rocks[r].count((e) => e == 'O') * (rocks.length - r))
    .sum;

part1(List lines) => weighting(slide(parse(lines), (-1, 0)));

part2(List lines) => spin(parse(lines), target: 1000000000);
[–] mykl@lemmy.world 3 points 11 months ago

Dart

Just banging strings together again. Simple enough once I understood that the original reflection may also be valid after desmudging. I don't know if we were supposed to do something clever for part two, but my part 1 was fast enough that I could just try every possible smudge location and part 2 still ran in 80ms

bool reflectsH(int m, List p) => p.every((l) {
      var l1 = l.take(m).toList().reversed.join('');
      var l2 = l.skip(m);
      var len = min(l1.length, l2.length);
      return l1.take(len) == l2.take(len);
    });

bool reflectsV(int m, List p) {
  var l1 = p.take(m).toList().reversed.toList();
  var l2 = p.skip(m).toList();
  var len = min(l1.length, l2.length);
  return 0.to(len).every((ix) => l1[ix] == l2[ix]);
}

int findReflection(List p, {int butNot = -1}) {
  var mirrors = 1
      .to(p.first.length)
      .where((m) => reflectsH(m, p))
      .toSet()
      .difference({butNot});
  if (mirrors.length == 1) return mirrors.first;

  mirrors = 1
      .to(p.length)
      .where((m) => reflectsV(m, p))
      .toSet()
      .difference({butNot ~/ 100});
  if (mirrors.length == 1) return 100 * mirrors.first;

  return -1; //never
}

int findSecondReflection(List p) {
  var origMatch = findReflection(p);
  for (var r in 0.to(p.length)) {
    for (var c in 0.to(p.first.length)) {
      var pp = p.toList();
      var cells = pp[r].split('');
      cells[c] = (cells[c] == '#') ? '.' : '#';
      pp[r] = cells.join();
      var newMatch = findReflection(pp, butNot: origMatch);
      if (newMatch > -1) return newMatch;
    }
  }
  return -1; // never
}

Iterable> parse(List lines) => lines
    .splitBefore((e) => e.isEmpty)
    .map((e) => e.first.isEmpty ? e.skip(1).toList() : e);

part1(lines) => parse(lines).map(findReflection).sum;

part2(lines) => parse(lines).map(findSecondReflection).sum;
[–] mykl@lemmy.world 2 points 11 months ago* (last edited 11 months ago)

Imagine you're looking at a grid with your path drawn out on it. On any given row, start from the left and move right, cell by cell. You're outside the area enclosed by your path at the start of the row. As you move across that row, you remain outside it until you meet and cross the line made by your path. Every non-path cell you now pass can be added to your 'inside' count, until you next cross your path, when you stop counting until you cross the path again, and so on.

In this problem, you can tell you're crossing the path when you encounter one of:

  • a '|'
  • a 'F' (followed by 0 or more '-'s) followed by 'J'
  • a 'L' (followed by 0 or more '-'s) followed by '7'

If you encounter an 'F' (followed by 0 or more '-'s) followed by '7', you've actually just skimmed along the line and not actually crossed it. Same for the 'L'/ 'J' pair.

Try it out by hand on the example grids and you should get the hang of the logic.

[–] mykl@lemmy.world 4 points 11 months ago

Uiua

As promised, just a little later than planned. I do like this solution as it's actually using arrays rather than just imperative programming in fancy dress. Run it here

Grid ← =@# [
  "...#......"
  ".......#.."
  "#........."
  ".........."
  "......#..."
  ".#........"
  ".........#"
  ".........."
  ".......#.."
  "#...#....."
]

GetDist! ← (
  # Build arrays of rows, cols of galaxies
  ⊙(⊃(◿)(⌊÷)⊃(⧻⊢)(⊚=1/⊂)).
  # check whether each row/col is just space
  # and so calculate its relative position
  ∩(\++1^1=0/+)⍉.
  # Map galaxy co-ords to these values
  ⊏:⊙(:⊏ :)
  # Map to [x, y] pairs, build cross product, 
  # and sum all topright values.
  /+≡(/+↘⊗0.)⊠(/+⌵-).⍉⊟
)
GetDist!(×1) Grid
GetDist!(×99) Grid
 
 

Am I in danger?

 

Thanks Homer.

 

Hi All, I posted here recently that I was spending November revisiting my AOC 2022 solutions (written in Dart) and posting them for reading, running and editing online.

With my last solution being posted yesterday, the series is now complete, and might be interesting if anyone's looking for an idea of the level of difficulty involved in a typical year.

To ensure that this post isn't just about posts on other communities, I've added a little bonus content - a simple visualisation I created for my solution for day 14 (flowing sand).

 

The !adventofcode@lemmy.world community is currently without an active mod: the original creator does not seem to have been active on Lemmy in months. I PM’d them to check whether they were still interested in the community and have received no reply.

I'm presently more or less the only active poster there, though that may change next month when this year's Advent of Code kicks off.

 

Hi all,

As the title says, I'm currently going through my entries (written in Dart) to last year's challenge and rewriting them to run in your browser using DartPad. I'll be posting one a day until 25th November to the Advent of Code community on lemmy.world.

I chose that community as it is a bit larger and had a bit more recent activity than this one, but if there's enough interest here, I can certainly cross-post my posts, and perhaps re-consider which I should treat as the primary community.

Cheers, Michael

 

Hi all,

As many people here may already know, Advent of Code is an annual programming challenge that runs from 1st to 25th December each year where each day a new puzzle is published for you to solve. The puzzles ramp up in difficulty during the month and can test your familiarity with core computer science principles and algorithms.

As the title says, I'm currently going through my entries (written in Dart) to last year's challenge and rewriting them to run in your browser using DartPad. I'll be posting one a day until 25th November to the Advent of Code community on lemmy.world.

It's fairly quiet there at the moment, but I hope that with enough awareness of the community, it will liven up enough over the coming weeks that I don't have to go back to the other place for interesting discussions and hints next month!

Cheers, Michael

-1
Too old to be a meme (ualuealuealeuale.ytmnd.com)
 

I’ll be amazed if this even works.

 
 

It's about 10 cm (4") long. Metal and plastic.

~~Hopefully this will stump people a little longer than the other challenges have managed.~~ What a naive fool I was! < 1 minute again...

If you do find the answer using Google Lens, hold onto it for a while to see if unaugmented humans can work it out :-)

Please add spoiler tags to any guesses to add to the element of suspense.

 

We think it is, but it would be great if someone with a little more knowledge could post a more authoritative response in that thread.

 

Sorry for the quality of the pic. Beer had been taken.

view more: next ›