func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} { var z big.Rat switch op { case token.ADD: return z.Add(x, y) case token.SUB: return z.Sub(x, y) case token.MUL: return z.Mul(x, y) case token.QUO: return z.Quo(x, y) case token.EQL: return x.Cmp(y) == 0 case token.NEQ: return x.Cmp(y) != 0 case token.LSS: return x.Cmp(y) < 0 case token.LEQ: return x.Cmp(y) <= 0 case token.GTR: return x.Cmp(y) > 0 case token.GEQ: return x.Cmp(y) >= 0 } panic("unreachable") }
func binaryCmplxOp(x cmplx, op token.Token, y cmplx) interface{} { a, b := x.re, x.im c, d := y.re, y.im switch op { case token.ADD: // (a+c) + i(b+d) var re, im big.Rat re.Add(a, c) im.Add(b, d) return cmplx{&re, &im} case token.SUB: // (a-c) + i(b-d) var re, im big.Rat re.Sub(a, c) im.Sub(b, d) return cmplx{&re, &im} case token.MUL: // (ac-bd) + i(bc+ad) var ac, bd, bc, ad big.Rat ac.Mul(a, c) bd.Mul(b, d) bc.Mul(b, c) ad.Mul(a, d) var re, im big.Rat re.Sub(&ac, &bd) im.Add(&bc, &ad) return cmplx{&re, &im} case token.QUO: // (ac+bd)/s + i(bc-ad)/s, with s = cc + dd var ac, bd, bc, ad, s big.Rat ac.Mul(a, c) bd.Mul(b, d) bc.Mul(b, c) ad.Mul(a, d) s.Add(c.Mul(c, c), d.Mul(d, d)) var re, im big.Rat re.Add(&ac, &bd) re.Quo(&re, &s) im.Sub(&bc, &ad) im.Quo(&im, &s) return cmplx{&re, &im} case token.EQL: return a.Cmp(c) == 0 && b.Cmp(d) == 0 case token.NEQ: return a.Cmp(c) != 0 || b.Cmp(d) != 0 } panic("unreachable") }
func split(turn, maxTurns int, blueDiscsDrawn int, current, result *big.Rat) { if blueDiscsDrawn > (maxTurns / 2) { result.Add(result, current) //fmt.Println(blueDiscsDrawn, current) return } else if turn > maxTurns { return } redCurrent := big.NewRat(1, 1) blueCurrent := big.NewRat(1, 1) redCurrent.Mul(current, big.NewRat(int64(turn), int64(turn+1))) blueCurrent.Mul(current, big.NewRat(1, int64(turn+1))) split(turn+1, maxTurns, blueDiscsDrawn, redCurrent, result) split(turn+1, maxTurns, blueDiscsDrawn+1, blueCurrent, result) }