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
|
|
|
}
|