gocollatz/collatz/calculator.go

60 lines
1.2 KiB
Go
Raw Normal View History

2024-04-24 17:49:03 +00:00
package collatz
import (
2024-04-24 20:04:34 +00:00
"collatz/parsing"
2024-04-24 17:49:03 +00:00
"fmt"
"math/big"
)
type Calculator struct {
2024-04-24 20:04:34 +00:00
parser parsing.Parser
three *big.Int
two *big.Int
one *big.Int
iterations int
2024-04-24 17:49:03 +00:00
}
2024-04-24 20:04:34 +00:00
func NewCalculator(parser parsing.Parser) *Calculator {
r := &Calculator{
parser: parser,
three: big.NewInt(3),
two: big.NewInt(2),
one: big.NewInt(1),
iterations: 0,
2024-04-24 17:49:03 +00:00
}
return r
}
2024-04-24 20:04:34 +00:00
func (o *Calculator) CalculateCollatz() error {
2024-04-24 17:53:00 +00:00
number, err := o.parser.Parse()
2024-04-24 17:49:03 +00:00
if err != nil {
2024-04-24 20:04:34 +00:00
return fmt.Errorf("couldn't parse input: %w", err)
2024-04-24 17:49:03 +00:00
}
fmt.Print(number.Text(10))
2024-04-24 20:04:34 +00:00
err = o.nextNumber(*number)
if err != nil {
return err
}
2024-04-24 17:49:03 +00:00
fmt.Println()
2024-04-24 20:04:34 +00:00
fmt.Println("Iterations:", o.iterations)
return nil
2024-04-24 17:49:03 +00:00
}
2024-04-24 20:04:34 +00:00
func (o *Calculator) nextNumber(in big.Int) error {
2024-04-24 17:49:03 +00:00
if in.Cmp(o.one) < 0 {
2024-04-24 20:04:34 +00:00
return fmt.Errorf("must be greater than 0")
2024-04-24 17:49:03 +00:00
}
if in.Cmp(o.one) == 0 {
2024-04-24 20:04:34 +00:00
return nil
2024-04-24 17:49:03 +00:00
}
var newNumber *big.Int
2024-04-24 20:04:34 +00:00
if new(big.Int).And(&in, o.one).Cmp(o.one) == 0 {
newNumber = new(big.Int).Add(new(big.Int).Mul(&in, o.three), o.one)
2024-04-24 17:49:03 +00:00
} else {
2024-04-24 20:04:34 +00:00
newNumber = new(big.Int).Div(&in, o.two)
2024-04-24 17:49:03 +00:00
}
2024-04-24 20:04:34 +00:00
o.iterations++
2024-04-24 17:49:03 +00:00
fmt.Printf(" -> %s", newNumber.Text(10))
2024-04-24 20:04:34 +00:00
return o.nextNumber(*newNumber)
2024-04-24 17:49:03 +00:00
}