Go big.Int factorial with recursion - go

I am trying to implement this bit of code:
func factorial(x int) (result int) {
if x == 0 {
result = 1;
} else {
result = x * factorial(x - 1);
}
return;
}
as a big.Int so as to make it effective for larger values of x.
The following is returning a value of 0 for fmt.Println(factorial(r))
The factorial of 7 should be 5040?
Any ideas on what I am doing wrong?
package main
import "fmt"
import "math/big"
func main() {
fmt.Println("Hello, playground")
//n := big.NewInt(40)
r := big.NewInt(7)
fmt.Println(factorial(r))
}
func factorial(n *big.Int) (result *big.Int) {
//fmt.Println("n = ", n)
b := big.NewInt(0)
c := big.NewInt(1)
if n.Cmp(b) == -1 {
result = big.NewInt(1)
}
if n.Cmp(b) == 0 {
result = big.NewInt(1)
} else {
// return n * factorial(n - 1);
fmt.Println("n = ", n)
result = n.Mul(n, factorial(n.Sub(n, c)))
}
return result
}
This code on go playground: http://play.golang.org/p/yNlioSdxi4

Go package math.big has func (*Int) MulRange(a, b int64). When called with the first parameter set to 1, it will return b!:
package main
import (
"fmt"
"math/big"
)
func main() {
x := new(big.Int)
x.MulRange(1, 10)
fmt.Println(x)
}
Will produce
3628800

In your int version, every int is distinct. But in your big.Int version, you're actually sharing big.Int values. So when you say
result = n.Mul(n, factorial(n.Sub(n, c)))
The expression n.Sub(n, c) actually stores 0 back into n, so when n.Mul(n, ...) is evaluated, you're basically doing 0 * 1 and you get back 0 as a result.
Remember, the results of big.Int operations don't just return their value, they also store them into the receiver. This is why you see repetition in expressions like n.Mul(n, c), e.g. why it takes n again as the first parameter. Because you could also sayresult.Mul(n, c) and you'd get the same value back, but it would be stored in result instead of n.
Here is your code rewritten to avoid this problem:
func factorial(n *big.Int) (result *big.Int) {
//fmt.Println("n = ", n)
b := big.NewInt(0)
c := big.NewInt(1)
if n.Cmp(b) == -1 {
result = big.NewInt(1)
}
if n.Cmp(b) == 0 {
result = big.NewInt(1)
} else {
// return n * factorial(n - 1);
fmt.Println("n = ", n)
result = new(big.Int)
result.Set(n)
result.Mul(result, factorial(n.Sub(n, c)))
}
return
}
And here is a slightly more cleaned-up/optimized version (I tried to remove extraneous allocations of big.Ints): http://play.golang.org/p/feacvk4P4O

For example,
package main
import (
"fmt"
"math/big"
)
func factorial(x *big.Int) *big.Int {
n := big.NewInt(1)
if x.Cmp(big.NewInt(0)) == 0 {
return n
}
return n.Mul(x, factorial(n.Sub(x, n)))
}
func main() {
r := big.NewInt(7)
fmt.Println(factorial(r))
}
Output:
5040

Non-recursive version:
func FactorialBig(n uint64) (r *big.Int) {
//fmt.Println("n = ", n)
one, bn := big.NewInt(1), new(big.Int).SetUint64(n)
r = big.NewInt(1)
if bn.Cmp(one) <= 0 {
return
}
for i := big.NewInt(2); i.Cmp(bn) <= 0; i.Add(i, one) {
r.Mul(r, i)
}
return
}
playground

Related

Can I use Go slice unpacking to streamline this permutation function?

I have written the following Go function that produces all permutations of a boolean list of any size. Playground here.
package main
import (
"fmt"
)
func permutations(m int) [][]bool {
if m == 0 {
panic("CRASH")
}
if m == 1 {
return [][]bool{{true}, {false}}
}
retVal := [][]bool{}
for _, x := range permutations(m - 1) {
slice1 := []bool{true}
slice2 := []bool{false}
for _, y := range x {
slice1 = append(slice1, y)
slice2 = append(slice2, y)
}
retVal = append(retVal, slice1)
retVal = append(retVal, slice2)
}
return retVal
}
func main() {
fmt.Println("Hello, playground")
m := permutations(3)
fmt.Println("m = ", m)
}
Can I streamline this function by using slice unpacking? If so, how?

Heapsort implementation in Go

I'm trying to implement code from Sedgewick's Algorithms textbook. The idea is to implement heapsort with the root of the heap stored in position 1 in the array.
Given the input S O R T E X A M P L E I expect a sorted output of A E E L M O P R S T X.
I'm having a bit of trouble implementing this, even when directly trying to translate the referenced Java code. This is what I have so far, which returns the following output:
package main
import (
"bufio"
"fmt"
"os"
"reflect"
"strings"
)
type Heap struct {
PQ []interface{}
}
func (h *Heap) Sort(pq []interface{}) {
n := len(pq)
for k := n / 2; k >= 1; k-- {
Sink(pq, k, n)
}
for n > 1 {
Exchange(pq, 1, n)
n = n - 1
Sink(pq, 1, n)
}
}
func Sink(pq []interface{}, k, n int) {
fmt.Println(k, n, pq)
for 2*k <= n {
j := 2 * k
if j < n && Less(pq, j, j+1) {
j = j + 1
}
Exchange(pq, k, j)
k = j
}
}
func Exchange(pq []interface{}, j, k int) {
curr := pq[j-1]
pq[j-1] = pq[k-1]
pq[k-1] = curr
}
func Less(pq []interface{}, j, k int) bool {
x, y := pq[j-1], pq[k-1]
if reflect.TypeOf(x) != reflect.TypeOf(y) {
fmt.Println("mismatched inputs", x, y)
panic("mismatched inputs")
}
switch x.(type) {
case int:
a, b := x.(int), y.(int)
if a > b {
return false
}
case float32:
a, b := x.(int), y.(int)
if a > b {
return false
}
case float64:
a, b := x.(int), y.(int)
if a > b {
return false
}
case string:
a, b := x.(string), y.(string)
if a > b {
return false
}
default:
panic("unhandled types, please add case.")
}
return true
}
func main() {
a := readStdin()
var h *Heap = new(Heap)
h.PQ = a
h.Sort(h.PQ)
fmt.Println(h.PQ)
}
func readStdin() []interface{} {
scanner := bufio.NewScanner(os.Stdin)
var items []interface{}
for scanner.Scan() {
item := scanner.Text()
tmp := strings.SplitAfter(item, " ")
items = make([]interface{}, len(tmp)+1)
for i, item := range tmp {
items[i+1] = item
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
return items
}
mismatched inputs E <nil>
panic: mismatched inputs
which panics as expected because of the comparison between nil value at index 0 and the currents slice value from 1..n. Perhaps I'm looking at this problem a bit too closely, or more than likely, I am missing a key point in the heapsort implementation altogether. Thoughts?
The standard library contains a heap package that you can use to directly implement this.
Even if you want to re-implement it yourself, the idea of using an interface to access the underlying slice is a good one -- allowing you to focus on the abstract heap operations without the mess of dealing with various types.
Here's a complete working example of heapsort, running on a slice of runes. Note that *runeSlice type implements heap.Interface by defining the three methods of sort.Interface: Len, Less, Swap, and the additional two methods from heap.Interface: Push and Pop.
package main
import (
"container/heap"
"fmt"
)
type runeSlice []rune
func (r runeSlice) Len() int { return len(r) }
func (r runeSlice) Less(i, j int) bool { return r[i] > r[j] }
func (r runeSlice) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r *runeSlice) Push(x interface{}) {
*r = append(*r, x.(rune))
}
func (r *runeSlice) Pop() interface{} {
x := (*r)[len(*r)-1]
*r = (*r)[:len(*r)-1]
return x
}
func main() {
a := []rune("SORTEXAMPLE")
h := runeSlice(a)
heap.Init(&h)
for i := len(a) - 1; i >= 0; i-- {
a[0], a[i] = a[i], a[0]
h = h[:i]
heap.Fix(&h, 0)
}
fmt.Println(string(a))
}

Lychrel Numbers in Go with the big Library

I'm trying to make a Lychrel number program in Go, but I'm running into some trouble. Using the "math/big" library, and with some extra print statements for debugging, my code looks like this:
func reverse(n *big.Int) *big.Int {
var (
m = n
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := num
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
While the analogous code without the big library works fine (save for eventual overflow errors), this version doesn't. When I do lychrel(196), for example, I get
Now testing 196
691 + 691 = 691
0 : 691
0 + 0 = 0
1 : 0
I can't figure out where it goes wrong. I hope I'm not missing something dumb, because I've spent all morning trying to get this to work.
Package big
import "math/big"
func NewInt
func NewInt(x int64) *Int
NewInt allocates and returns a new Int set to x.
func (*Int) Set
func (z *Int) Set(x *Int) *Int
Set sets z to x and returns z.
You are assigning pointers, instead of values.
m = n
newNum := num
Assign values,
m = new(big.Int).Set(n)
newNum := new(big.Int).Set(num)
For example,
package main
import (
"fmt"
"math/big"
)
func reverse(n *big.Int) *big.Int {
var (
m = new(big.Int).Set(n)
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := new(big.Int).Set(num)
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
func main() {
lychrel(196)
}
Output:
Now testing 196
196 + 691 = 887
0 : 887
. . .

Condition validation in for loop

my below code to get square root works fine
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(Sqrt(9))
}
func Sqrt(x float64) float64 {
v := float64(1)
p := float64(0)
for {
p = v
v -= (v*v - x) / (2 * v)
fmt.Println(toFixed(p, 5), toFixed(v, 5))
if toFixed(p, 5) == toFixed(v, 5) {
break
}
}
return v
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
but if I change the for loop in Sqrt function and remove if break from the loop like below then control flow do not get into for loop and Sqrt() function quits with value as 1.
for toFixed(p, 5) == toFixed(v, 5) {
p = v
v -= (v*v - x) / (2 * v)
fmt.Println(toFixed(p, 5), toFixed(v, 5))
}
Can you please suggest issue in above code?
Thanks
You should be checking for inequality != in your for condition.
I modified your code and it seems to be working fine now:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(Sqrt(9))
}
func Sqrt(x float64) float64 {
v := float64(1)
p := float64(0)
for toFixed(p, 5) != toFixed(v, 5) {
p = v
v -= (v*v - x) / (2 * v)
}
return v
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}

How to convert int to bigint in golang?

I'm trying to implement fast double Fibonacci algorithm as described here:
// Fast doubling Fibonacci algorithm
package main
import "fmt"
// (Public) Returns F(n).
func fibonacci(n int) int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (int, int) {
if n == 0 {
return 0, 1
}
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
}
}
func main() {
fmt.Println(fibonacci(13))
fmt.Println(fibonacci(14))
}
This works fine for small numbers; however, when the input number get larger, the program returns a wrong result. So I tried to use bigInt from math/big package:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
)
// (Public) Returns F(n).
func fibonacci(n int) big.Int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (big.Int, big.Int) {
if n == 0 {
return big.Int(0), big.Int(1)
}
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
}
}
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
}
However, go build complains that
cannot convert 0 (type int) to type big.Int
How to mitigate this problem?
Use big.NewInt() instead of big.Int(). big.Int() is just type casting.
You need to check out documentation of big package
You should mostly use methods with form func (z *T) Binary(x, y *T) *T // z = x op y
To multiply 2 arguments you need to provide result variable, after it call Mul method. So, for example, to get result of 2*2 you need to:
big.NewInt(0).Mul(big.NewInt(2), big.NewInt(2))
You can try working example on the Go playground
Also you can create extension functions like:
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
}
To make code more readable:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
)
// (Public) Returns F(n).
func fibonacci(n int) *big.Int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (*big.Int, *big.Int) {
if n == 0 {
return big.NewInt(0), big.NewInt(1)
}
a, b := fib(n / 2)
c := Mul(a, Sub(Mul(b, big.NewInt(2)), a))
d := Add(Mul(a, a), Mul(b, b))
if n%2 == 0 {
return c, d
} else {
return d, Add(c, d)
}
}
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
}
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
}
func Sub(x, y *big.Int) *big.Int {
return big.NewInt(0).Sub(x, y)
}
func Add(x, y *big.Int) *big.Int {
return big.NewInt(0).Add(x, y)
}
Try it on the Go playground

Resources