/** * Store partial product result lines in the Calculator output lines. */ func (calc *Calculator) setPartialLines() { var ( opDigits = calc.operands[1].String() opLength = len(opDigits) ) // From largest to smallest place values (i.e., last to first partial result // lines) for index, digit := range opDigits { var ( placeValue big.Int buffer bytes.Buffer // Amount of right indentation this line has and also the position // relative to the first partial result line (right after the first // ruler) offset = opLength - index - 1 ) placeValue.SetString(fmt.Sprintf("%c", digit), 10) placeValue.Mul(&placeValue, &calc.operands[0]) // We're right-padding with spaces, but these will be stripped out later buffer.WriteString(placeValue.String()) buffer.WriteString(strings.Repeat(" ", offset)) calc.lines[3+offset] = buffer.String() } }
func fibo(n *big.Int) *big.Int { s := n.String() if r, ok := fiboCache[s]; ok { return r } i0 := big.NewInt(0) if n.Cmp(i0) <= 0 { return i0 } if n.Cmp(big.NewInt(2)) <= 0 { return big.NewInt(1) } n1 := big.NewInt(-1) n1.Add(n1, n) n1 = fibo(n1) n2 := big.NewInt(-2) n2.Add(n2, n) n2 = fibo(n2) i0.Add(n1, n2) fiboCache[s] = i0 return i0 }
func digitSum(num *big.Int) (sum int) { sum = 0 str := num.String() for _, v := range str { sum += v - 48 } return }
func info(a *big.Int, n uint) { dtrunc := int64(float64(a.BitLen())*.30103) - 10 var first, rest big.Int rest.Exp(first.SetInt64(10), rest.SetInt64(dtrunc), nil) first.Quo(a, &rest) fstr := first.String() fmt.Printf("%d! begins %s... and has %d digits.\n", n, fstr, int64(len(fstr))+dtrunc) }
func sumDigits(in *big.Int) (out int) { s := in.String() for _, c := range s { out = out + (c - '0') } return }
// printNumber outputs the given big.Int and also appends a ".5" if there is an // apple that was divided in half. func (calc *Calculator) printNumber(number *big.Int) { fmt.Print(number.String()) if calc.odd { fmt.Print(".5") } fmt.Println() }
func SaveKeys(n, e, d, p, q *big.Int) { pu := strings.Bytes(n.String() + "\n" + e.String() + "\n") pr := strings.Bytes(p.String() + "\n" + q.String() + "\n" + d.String() + "\n") if ioutil.WriteFile(*publicKeyFile, pu, 0600) != nil || ioutil.WriteFile(*privateKeyFile, pr, 0600) != nil { panic("Writing problems") } }
/** * Store the solution in the Calculator output lines. */ func (calc *Calculator) setSolutionLine() { var solution big.Int if calc.operator == '+' { solution.Add(&calc.operands[0], &calc.operands[1]) } else if calc.operator == '-' { solution.Sub(&calc.operands[0], &calc.operands[1]) } else { solution.Mul(&calc.operands[0], &calc.operands[1]) } calc.lines[len(calc.lines)-1] = solution.String() }
func main() { const limit = 1000 fibonacci := make_fibonacci() var last_fib *big.Int var last_idx int for i := 1; ; i++ { last_fib = fibonacci() if len(last_fib.String()) >= limit { last_idx = i break } } fmt.Printf("Fib(%d) = %v, is the first term in the Fibonacci sequence >= %v\n", last_idx, last_fib, limit) }
func FindLastNonZeroDigit(val *big.Int) int { sval := val.String() slen := len(sval) fmt.Println("Len: ", slen) lastNonZero := slen for i := slen - 1; i >= 0; i-- { c := string(sval[i]) if c != string("0") { fmt.Println("i: ", i) lastNonZero = i break } } return lastNonZero }
/** * Find the next palindrome after the current number. */ func (factory *PalinFactory) Next() string { var ( buffer bytes.Buffer numberLen = len(factory.number) oddLength = numberLen%2 > 0 // Greedily split the number into two halves. Greedily meaning for // odd-length numbers, the middle digit belongs to both sides (e.g., // "987" splits into "98" and "87"). leftSide = factory.number[0 : (numberLen+1)/2] rightSide = factory.number[numberLen/2:] mirroredSide = Reverse(leftSide) leftLength = len(leftSide) ) // Before we create a palindrome, we can determine if the resulting // palindrome will not be greater than the original number by mirroring the // left side and comparing it to the right side. // // Using 123456 as an example, the palindrome will be 123321, which is less // than 123456. If we mirror the left side, we get 321. The right side is // 456. Since 321 <= 456, we know the palindrome will not be greater than // the original number. if !Greater(mirroredSide, rightSide) { // Since it is not greater, we can increment the palindrome by // incrementing the left side. This is essentially incrementing the // middle digits of the palindrome, which results in the very next // palindrome. Since we are also incrementing the left side, the // resulting palindrome will also be greater than the original number. leftSide = Increment(leftSide) // One obvious optimization is to set leftSide here and then set it // again in the next inner if {}, rather than calling leftValue.String() // twice, but that seems to consistently be slower for some reason. // If we introduced a new digit, this changes the evenness/oddness of // the number, and we need to account for this when constructing the // palindrome. Since we greedily split the number, going from odd to // even means we need to drop a digit on the left. // // For example, the left side of 999 is "99". The left side of 1001 is // "10". Notice both have two digits. However, if we increment "99" // (as a left side), we get "100", so we need to divide by 10 to get the // two digits that will be mirrored to form the palindrome 1001. This // doesn't need to be done when going from odd to even, because the left // side has one more digit (left side of 99 is "9", left side of 101 is // "10"). if len(leftSide) != leftLength { oddLength = !oddLength if !oddLength { var leftValue big.Int leftValue.SetString(leftSide, 10) leftValue.Div(&leftValue, big.NewInt(10)) leftSide = leftValue.String() } } mirroredSide = Reverse(leftSide) } buffer.WriteString(leftSide) // Mirror the left side onto the right to form a palindrome if oddLength { // When odd, the left and right sides "overlap" on the middle digit, so // don't include in on the right buffer.WriteString(mirroredSide[1:]) } else { buffer.WriteString(mirroredSide) } return buffer.String() }