Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'dart:math';
- import 'package:more/more.dart';
- var rolls = 0;
- Iterable<int> roll1to100() sync* {
- while (true) {
- for (var d in 1.to(101)) {
- rolls += 1;
- yield d;
- }
- }
- }
- Iterator<int>? g;
- int roll3_100() {
- g ??= roll1to100().iterator;
- var s = 0;
- for (var _ in 0.to(3)) {
- g!.moveNext();
- s += g!.current;
- }
- return s;
- }
- play1(int a, int b) {
- var ascore = 0, bscore = 0;
- while (true) {
- var d = roll3_100();
- a = (a + d + 9) % 10 + 1;
- ascore += a;
- if (ascore >= 1000) break;
- d = roll3_100();
- b = (b + d + 9) % 10 + 1;
- bscore += b;
- if (bscore >= 1000) break;
- }
- return (((a > b) ? bscore : ascore) * rolls);
- }
- class State {
- int posA, posB, scoreA, scoreB;
- State(this.posA, this.posB, this.scoreA, this.scoreB);
- factory State.copy(State s) => State(s.posA, s.posB, s.scoreA, s.scoreB);
- @override
- int get hashCode => Object.hash(posA, posB, scoreA, scoreB);
- @override
- bool operator ==(Object o) =>
- o is State &&
- posA == o.posA &&
- posB == o.posB &&
- scoreA == o.scoreA &&
- scoreB == o.scoreB;
- }
- // Number of times each score arises from 3 throws.
- var throws = {3: 1, 4: 3, 5: 6, 6: 7, 7: 6, 8: 3, 9: 1};
- play2(int a, int b) {
- // Counts the number of times each state has occurred so far.
- var tally = {State(a, b, 0, 0): 1};
- var winsA = 0;
- var winsB = 0;
- var turnA = false;
- while (tally.isNotEmpty) {
- turnA = !turnA;
- var newTally = <State, int>{};
- for (var e in tally.entries) {
- for (var t in throws.entries) {
- // Get the current state afresh each time
- var ns = State.copy(e.key);
- // Number of times this dice-throw occurs, times number of times the
- // original state occurred.
- var count = e.value * t.value;
- if (turnA) {
- ns.posA = (ns.posA + t.key + 9) % 10 + 1;
- ns.scoreA += ns.posA;
- if (ns.scoreA >= 21) {
- // update the counts, and leave this reality :-)
- winsA += count;
- continue;
- }
- } else {
- ns.posB = (ns.posB + t.key + 9) % 10 + 1;
- ns.scoreB += ns.posB;
- if (ns.scoreB >= 21) {
- winsB += count;
- continue;
- }
- }
- newTally[ns] = (newTally[ns] ?? 0) + count;
- }
- }
- tally = newTally;
- }
- return max(winsA, winsB);
- }
- main() {
- var t = DateTime.now();
- print(play1(1, 6));
- print(play2(1, 6));
- print('${DateTime.now().difference(t).inMilliseconds} milliseconds');
- }
Add Comment
Please, Sign In to add comment