Skip to content

Instantly share code, notes, and snippets.

@agam
Created August 19, 2014 21:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agam/3d82745c84c8f44dd51c to your computer and use it in GitHub Desktop.
Save agam/3d82745c84c8f44dd51c to your computer and use it in GitHub Desktop.
package main
import "fmt"
type Bignum struct {
digits []*Digit
add chan<- bool
stable chan bool
}
type Digit struct {
value int
pull_carry <-chan bool
push_carry chan<- bool
}
func print(b *Bignum) {
l := len(b.digits)
for i := 0; i < l; i++ {
fmt.Print(b.digits[l-i-1].value)
}
}
func add(n int, b *Bignum) {
sent := 0
done := 0
done_sending:
for {
select {
case b.add <- true:
sent++
if sent == n {
break done_sending
}
case <-b.stable:
done++
}
}
for ; done < n; done++ {
<- b.stable
}
}
func addDigit(b *Bignum, num int, in <-chan bool) chan bool {
new_out := make(chan bool)
d := &Digit{num, in, new_out}
b.digits = append(b.digits, d)
go carry(d)
return new_out
}
func carry(d *Digit) {
for in_msg := range d.pull_carry {
out_msg := false
if in_msg {
sum := d.value + 1
if sum >= 10 {
d.value = sum - 10
out_msg = true
} else {
d.value = sum
}
}
d.push_carry <- out_msg
}
}
func sentinel(b *Bignum, in <-chan bool) {
for {
var msg = <-in
if msg {
last_out := addDigit(b, 1, in)
go sentinel(b, last_out)
last_out <- false
break
} else {
b.stable <- true
}
}
}
func MakeBigNum(num_arr []int) *Bignum {
var digits []*Digit
last_out := make(chan bool)
stable := make(chan bool)
b := &Bignum{digits, last_out, stable}
l := len(num_arr)
for i := 0; i < l; i++ {
last_out = addDigit(b, num_arr[l-i-1], last_out)
}
go sentinel(b, last_out)
return b
}
func main() {
bignum := MakeBigNum([]int{9, 9, 8})
print(bignum)
fmt.Println("\nAnd after adding ... \n")
add(100000, bignum)
print(bignum)
fmt.Println()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment