this post was submitted on 01 Dec 2023
17 points (100.0% liked)

NotAwfulTech

364 readers
1 users here now

a community for posting cool tech news you don’t want to sneer at

non-awfulness of tech is not required or else we wouldn’t have any posts

founded 1 year ago
MODERATORS
 

Rules: no spoilers.

The other rules are made up as we go along.

Share code by link to a forge, home page, pastebin (Eric Wastl has one here) or code section in a comment.

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 3 points 11 months ago* (last edited 11 months ago)

3b reduxI took out the union find, the code is simpler and more readable now. I also leaned in to using null values, which is gross but whatever, it works.

void day3s() {
  List lines = [
    for (String? line = stdin.readLineSync();
        line != null;
        line = stdin.readLineSync())
      line
  ];

  // lazy processing + memoization
  List> digs = [for (int i = 0; i < lines.length; i++) Map()];
  int? isDigitMem(int r, int c) {
    if (r < 0 || r > lines.length || c < 0 || c > lines[0].length) return null;
    return digs[r].putIfAbsent(c, () => isDigit(lines[r][c]));
  }

  int stoi(int row, int col) {
    int acc = 0;
    for (int i = col; i < lines[0].length; i++) {
      int? d = isDigitMem(row, i);
      if (d != null) {
        acc = (acc * 10) + d;
      } else {
        break;
      }
    }
    return acc;
  }

  int? stoiSearch(int row, int col) {
    assert(row >= 0 && col >= 0 && row < lines.length && col < lines[0].length);
    if (isDigitMem(row, col) == null) {
      return null;
    }
    int i = col - 1;
    while (i >= 0) {
      if (isDigitMem(row, i) == null) {
        return stoi(row, i + 1);
      }
      i--;
    }
    return stoi(row, 0);
  }

  List> s2i = [for (int i = 0; i < lines.length; i++) Map()];
  int? stoiSearchMem(int row, int col) {
    if (row < 0 || row >= lines.length) return null;
    if (col < 0 || col >= lines[0].length) return null;
    return s2i[row].putIfAbsent(col, () => stoiSearch(row, col));
  }

  int count = 0;
  for (int i = 0; i < lines.length; i++) {
    for (int j = 0; j < lines[0].length; j++) {
      if (lines[i][j] != "*") {
        continue;
      }

      List gearVals = List.empty(growable: true);
      for (int x = -1; x <= 1; x++) {
        int? left = stoiSearchMem(i + x, j - 1);
        int? mid = stoiSearchMem(i + x, j);
        int? right = stoiSearchMem(i + x, j + 1);

        if (isDigitMem(i + x, j) == null) {
          if (left != null) {
            gearVals.add(left);
          }

          if (right != null) {
            gearVals.add(right);
          }
        } else if (left != null) {
          gearVals.add(left);
        } else if (mid != null) {
          gearVals.add(mid);
        } else if (right != null) {
          gearVals.add(right);
        }
      }

      if (gearVals.length == 2) {
        count += gearVals[0] * gearVals[1];
      }
    }
  }

  print(count);
}