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