mykdavies

AOC2021 Day21

Dec 21st, 2021 (edited)
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 2.59 KB | None | 0 0
  1. import 'dart:math';
  2. import 'package:more/more.dart';
  3.  
  4. var rolls = 0;
  5. Iterable<int> roll1to100() sync* {
  6.   while (true) {
  7.     for (var d in 1.to(101)) {
  8.       rolls += 1;
  9.       yield d;
  10.     }
  11.   }
  12. }
  13.  
  14. Iterator<int>? g;
  15. int roll3_100() {
  16.   g ??= roll1to100().iterator;
  17.   var s = 0;
  18.   for (var _ in 0.to(3)) {
  19.     g!.moveNext();
  20.     s += g!.current;
  21.   }
  22.   return s;
  23. }
  24.  
  25. play1(int a, int b) {
  26.   var ascore = 0, bscore = 0;
  27.   while (true) {
  28.     var d = roll3_100();
  29.     a = (a + d + 9) % 10 + 1;
  30.     ascore += a;
  31.     if (ascore >= 1000) break;
  32.     d = roll3_100();
  33.     b = (b + d + 9) % 10 + 1;
  34.     bscore += b;
  35.     if (bscore >= 1000) break;
  36.   }
  37.   return (((a > b) ? bscore : ascore) * rolls);
  38. }
  39.  
  40. class State {
  41.   int posA, posB, scoreA, scoreB;
  42.   State(this.posA, this.posB, this.scoreA, this.scoreB);
  43.   factory State.copy(State s) => State(s.posA, s.posB, s.scoreA, s.scoreB);
  44.  
  45.   @override
  46.   int get hashCode => Object.hash(posA, posB, scoreA, scoreB);
  47.  
  48.   @override
  49.   bool operator ==(Object o) =>
  50.       o is State &&
  51.       posA == o.posA &&
  52.       posB == o.posB &&
  53.       scoreA == o.scoreA &&
  54.       scoreB == o.scoreB;
  55. }
  56.  
  57. // Number of times each score arises from 3 throws.
  58. var throws = {3: 1, 4: 3, 5: 6, 6: 7, 7: 6, 8: 3, 9: 1};
  59.  
  60. play2(int a, int b) {
  61.   // Counts the number of times each state has occurred so far.
  62.   var tally = {State(a, b, 0, 0): 1};
  63.   var winsA = 0;
  64.   var winsB = 0;
  65.   var turnA = false;
  66.   while (tally.isNotEmpty) {
  67.     turnA = !turnA;
  68.     var newTally = <State, int>{};
  69.     for (var e in tally.entries) {
  70.       for (var t in throws.entries) {
  71.         // Get the current state afresh each time
  72.         var ns = State.copy(e.key);
  73.         // Number of times this dice-throw occurs, times number of times the
  74.         // original state occurred.
  75.         var count = e.value * t.value;
  76.         if (turnA) {
  77.           ns.posA = (ns.posA + t.key + 9) % 10 + 1;
  78.           ns.scoreA += ns.posA;
  79.           if (ns.scoreA >= 21) {
  80.             // update the counts, and leave this reality :-)
  81.             winsA += count;
  82.             continue;
  83.           }
  84.         } else {
  85.           ns.posB = (ns.posB + t.key + 9) % 10 + 1;
  86.           ns.scoreB += ns.posB;
  87.           if (ns.scoreB >= 21) {
  88.             winsB += count;
  89.             continue;
  90.           }
  91.         }
  92.         newTally[ns] = (newTally[ns] ?? 0) + count;
  93.       }
  94.     }
  95.     tally = newTally;
  96.   }
  97.   return max(winsA, winsB);
  98. }
  99.  
  100. main() {
  101.   var t = DateTime.now();
  102.   print(play1(1, 6));
  103.   print(play2(1, 6));
  104.   print('${DateTime.now().difference(t).inMilliseconds} milliseconds');
  105. }
  106.  
Add Comment
Please, Sign In to add comment