From 5093a177676af4604914729d5104f157b6fb55bf Mon Sep 17 00:00:00 2001 From: kr0st Date: Sun, 9 Oct 2022 20:06:42 +0300 Subject: [PATCH] "837. New 21 Game" medium, trying to solve with probability manipulation --- 837-new-21-game.go | 85 +++++++++++++++++++++++++++++++++++++++-- 837-new-21-game_test.go | 2 +- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/837-new-21-game.go b/837-new-21-game.go index dd6305a..8f65ecf 100644 --- a/837-new-21-game.go +++ b/837-new-21-game.go @@ -3,6 +3,7 @@ package main import ( "math" "math/rand" + "strconv" "time" ) @@ -302,7 +303,7 @@ func new21GameExperimental(n int, k int, maxPts int, rngType RngType) float64 { makeExperiment := func() float64 { var sum uint64 - for sum = 0; sum <= uintK; sum += getNextRandom() { + for sum = 0; sum < uintK; sum += getNextRandom() { } kOrMoreCount++ @@ -333,6 +334,84 @@ func new21GameExperimental(n int, k int, maxPts int, rngType RngType) float64 { return probability } -func New21Game(n int, k int, maxPts int) float64 { - return new21GameExperimental(n, k, maxPts, FastRng) +func new21RecursiveBruteforceV2(n int, k int, p int, s int, str string) (int, int) { + moreThanK := 0 + lessThanN := 0 + + if p <= 0 || n <= 0 || k <= 0 || s >= k { + return 0, 0 + } + + sum := s + p + + if sum >= k { + str += strconv.Itoa(p) + "=" + strconv.Itoa(sum) + println(str) + moreThanK++ + if sum <= n { + lessThanN++ + } + } else { + str += strconv.Itoa(p) + "+" + + for i := p; i > 0; i-- { + retMoreThanK, retLessThanN := new21RecursiveBruteforceV2(n, k, i, sum, str) + moreThanK += retMoreThanK + lessThanN += retLessThanN + } + + return moreThanK, lessThanN + } + + return moreThanK, lessThanN +} + +func new21GameBruteforce(n int, k int, maxPts int) float64 { + moreThanK, lessThanN := 0, 0 + for m := maxPts; m > 0; m-- { + retMoreThanK, retLessThanN := new21RecursiveBruteforceV2(n, k, m, 0, "") + moreThanK += retMoreThanK + lessThanN += retLessThanN + } + + return float64(lessThanN) / float64(moreThanK) +} + +func New21Game(n int, k int, maxPts int) float64 { + if k < 0 || n < 0 || maxPts < 0 { + return 0 + } + + if k == 0 { + return 1 + } + + if maxPts == 0 { + return 0 + } + + if n < k { + return 1 + } + + p := make([]float64, n+1) + m := float64(maxPts) + + p[0] = 1 + p[1] = p[0] / m + + for i := 2; i <= k; i++ { + p[i] = p[i-1] + p[i-1]/m + } + + for i := k + 1; i <= n; i++ { + p[i] = p[i-1] + p[i-1]/m - p[i-k] + } + + sumP := float64(0) + for i := k; i <= n; i++ { + sumP += p[i] + } + + return sumP } diff --git a/837-new-21-game_test.go b/837-new-21-game_test.go index 882f2dc..24e2da6 100644 --- a/837-new-21-game_test.go +++ b/837-new-21-game_test.go @@ -6,7 +6,7 @@ import ( ) func TestNew21Game(t *testing.T) { - // assert.Equal(t, 1.0, New21Game(10, 1, 10)) + assert.Equal(t, 1.0, New21Game(10, 1, 10)) assert.Equal(t, 0.6, New21Game(6, 1, 10)) assert.Equal(t, 0.73278, New21Game(21, 17, 10)) }