Grains of rice on a chessboard (golang)

Updated vegaseat 2 Tallied Votes 878 Views Share

The story has it that a few hundred years ago the ruler of a big country wanted to reward the creator of the chess game. The creator of the game simply wanted one grain of rice put on the first square of the chessboard, two grains on the second, then doubling it for every remaining square. The ruler acted surprised by the humble request, had his helpers bring a bag of rice and started to fill the squares.

Did the creator of the chess game get a decent reward? Let's check it with some Go code.

Note: I printed out the loop results and corrected a mistake.

// chessboard_rice.go
//
// put one grain of rice on first square of a chessboard
// two grains of rice on the second square
// and keep doubling it every empty square
// an exercise with real big numbers
//
// some Google facts ...
// 29,000 grains of rice per pound
// rice production world wide (2012) = 740,000,000 tonnes
// 2,200 pounds per tonne
//
// total grains of rice (using Python)
// 2**64 - 1 = 18446744073709551615
//
// for imported package info see ...
// http://golang.org/pkg/fmt/
// http://golang.org/pkg/math/big/
//
// online play at:
// http://play.golang.org/p/zjs_lcCOjc
//
// tested with Go version 1.4.2   by vegaseat  10may2015

package main

import (
	"fmt"
	"math/big"
)

func main() {
	fmt.Println("Grains of rice on a chessboard (doubling every square):\n")

	// world wide rice production in 2012 = 740 million tonnes
	// = 1628000000000 pounds
	riceProduction2012 := big.NewInt(1628000000000)
	riceAnnual := big.NewInt(0)
	// assume 29000 grains in 1 pound of rice
	grainsPerPound := big.NewInt(29000)

	fmt.Println("---------------------------------------------")
	totalPound := big.NewInt(0)
	total := big.NewInt(0)
	grains := big.NewInt(1)
	// a chessboard has 64 squares
	for square := 1; square <= 64; square++ {
		// add to total
		total.Add(total, grains)
		fmt.Printf("square %v  grains = %v  total = %v\n",
			square, grains, total) // test
		// double grains
		grains.Add(grains, grains)
	}
	fmt.Println("---------------------------------------------")
	fmt.Printf("Total grains of rice = %v\n", total)
	fmt.Println("Assume 29000 grains per pound of rice:")
	fmt.Printf("That would be %v pounds of rice\n",
		totalPound.Div(total, grainsPerPound))

	fmt.Printf("Which would consume %v annual productions (2012) of rice\n",
		riceAnnual.Div(totalPound, riceProduction2012))
}

/* result ...
Grains of rice on a chessboard (doubling every square):

---------------------------------------------
square 1  grains = 1  total = 1
square 2  grains = 2  total = 3
square 3  grains = 4  total = 7
square 4  grains = 8  total = 15
square 5  grains = 16  total = 31
square 6  grains = 32  total = 63
square 7  grains = 64  total = 127
square 8  grains = 128  total = 255
square 9  grains = 256  total = 511
square 10  grains = 512  total = 1023
square 11  grains = 1024  total = 2047
square 12  grains = 2048  total = 4095
square 13  grains = 4096  total = 8191
square 14  grains = 8192  total = 16383
square 15  grains = 16384  total = 32767
square 16  grains = 32768  total = 65535
square 17  grains = 65536  total = 131071
square 18  grains = 131072  total = 262143
square 19  grains = 262144  total = 524287
square 20  grains = 524288  total = 1048575
square 21  grains = 1048576  total = 2097151
square 22  grains = 2097152  total = 4194303
square 23  grains = 4194304  total = 8388607
square 24  grains = 8388608  total = 16777215
square 25  grains = 16777216  total = 33554431
square 26  grains = 33554432  total = 67108863
square 27  grains = 67108864  total = 134217727
square 28  grains = 134217728  total = 268435455
square 29  grains = 268435456  total = 536870911
square 30  grains = 536870912  total = 1073741823
square 31  grains = 1073741824  total = 2147483647
square 32  grains = 2147483648  total = 4294967295
square 33  grains = 4294967296  total = 8589934591
square 34  grains = 8589934592  total = 17179869183
square 35  grains = 17179869184  total = 34359738367
square 36  grains = 34359738368  total = 68719476735
square 37  grains = 68719476736  total = 137438953471
square 38  grains = 137438953472  total = 274877906943
square 39  grains = 274877906944  total = 549755813887
square 40  grains = 549755813888  total = 1099511627775
square 41  grains = 1099511627776  total = 2199023255551
square 42  grains = 2199023255552  total = 4398046511103
square 43  grains = 4398046511104  total = 8796093022207
square 44  grains = 8796093022208  total = 17592186044415
square 45  grains = 17592186044416  total = 35184372088831
square 46  grains = 35184372088832  total = 70368744177663
square 47  grains = 70368744177664  total = 140737488355327
square 48  grains = 140737488355328  total = 281474976710655
square 49  grains = 281474976710656  total = 562949953421311
square 50  grains = 562949953421312  total = 1125899906842623
square 51  grains = 1125899906842624  total = 2251799813685247
square 52  grains = 2251799813685248  total = 4503599627370495
square 53  grains = 4503599627370496  total = 9007199254740991
square 54  grains = 9007199254740992  total = 18014398509481983
square 55  grains = 18014398509481984  total = 36028797018963967
square 56  grains = 36028797018963968  total = 72057594037927935
square 57  grains = 72057594037927936  total = 144115188075855871
square 58  grains = 144115188075855872  total = 288230376151711743
square 59  grains = 288230376151711744  total = 576460752303423487
square 60  grains = 576460752303423488  total = 1152921504606846975
square 61  grains = 1152921504606846976  total = 2305843009213693951
square 62  grains = 2305843009213693952  total = 4611686018427387903
square 63  grains = 4611686018427387904  total = 9223372036854775807
square 64  grains = 9223372036854775808  total = 18446744073709551615
---------------------------------------------
Total grains of rice = 18446744073709551615
Assume 29000 grains per pound of rice:
That would be 636094623231363 pounds of rice
Which would consume 390 annual productions (2012) of rice
*/
rubberman 1,355 Nearly a Posting Virtuoso Featured Poster

The answer is simple: 2^64 - 1. Why bother with the loop?

Ene Uran 638 Posting Virtuoso

There is no 2^64-1 for such large numbers.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague
In Go ^ is the exclusive or.
Python gives the accurate result 2**64 - 1    = 18446744073709551615

The code was meant to be a good exercise in big math and its accuracy.
Once you use the test print in the loop, you can illustrate the progression quite nicely.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

If you allow for small round-off errors you can use float64 calculations and simplify the code this way ...

// chessboard_rice2.go
//
// put one grain of rice on first square of a chessboard
// two grains of rice on the second square
// and keep doubling it every empty square
// allowing for small floating point round-off errors
//
// tested with Go version 1.4.2   by vegaseat  11may2015

package main

import (
    "fmt"
    "math"
)

func main() {
    fmt.Println("Grains of rice on a chessboard (doubling every square):n")

    // world wide rice production in 2012
    // = 740 million tonnes
    // = 1628000000000 pounds
    riceProduction2012 := 1628000000000.0
    // assume 29000 grains in 1 pound of rice
    grainsPerPound := 29000.0
    totalGrains := math.Pow(2, 64) - 1

    fmt.Printf("Total grains of rice = %.0fn", totalGrains)
    fmt.Println("Assume 29000 grains per pound of rice:")
    totalPound := totalGrains / grainsPerPound
    fmt.Printf("That would be %.0f pounds of ricen", totalPound)

    fmt.Printf("Which would consume %.1f annual productions (2012) of rice\n",
        totalPound/riceProduction2012)
}

/* result ...
Grains of rice on a chessboard (doubling every square):

Total grains of rice = 18446744073709551616
Assume 29000 grains per pound of rice:
That would be 636094623231364 pounds of rice
Which would consume 390.7 annual productions (2012) of rice
*/

The numbers are large, but the 64 bit float does not complain yet.

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Hmm, if you stacked the rice grains end to end, at what square would you have enough grains to reach the moon?

Assume that a grain of rice is 5 mm long.
On average, the distance from Earth to the moon is about 384,400 km.

The number of grains on each square 1 to 64 is equal to
math.Pow(2, (square-1))
and the number of total accumulated grains at this point is
math.Pow(2, square) - 1

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.