This commit is contained in:
@@ -1,53 +1,59 @@
|
||||
package collatz
|
||||
|
||||
import (
|
||||
"collatz/io"
|
||||
"collatz/parsing"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
type Calculator struct {
|
||||
parser *io.Cliargs
|
||||
three *big.Int
|
||||
two *big.Int
|
||||
one *big.Int
|
||||
parser parsing.Parser
|
||||
three *big.Int
|
||||
two *big.Int
|
||||
one *big.Int
|
||||
iterations int
|
||||
}
|
||||
|
||||
func NewCalculator(parser *io.Cliargs) Calculator {
|
||||
r := Calculator{
|
||||
parser: parser,
|
||||
three: new(big.Int).SetInt64(3),
|
||||
two: new(big.Int).SetInt64(2),
|
||||
one: new(big.Int).SetInt64(1),
|
||||
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) Collatz() {
|
||||
func (o *Calculator) CalculateCollatz() error {
|
||||
number, err := o.parser.Parse()
|
||||
if err != nil {
|
||||
log.Panicf("Couldn't parse input: %s\n", err)
|
||||
return fmt.Errorf("couldn't parse input: %w", err)
|
||||
}
|
||||
fmt.Print(number.Text(10))
|
||||
o.nextNumber(number)
|
||||
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) {
|
||||
func (o *Calculator) nextNumber(in big.Int) error {
|
||||
if in.Cmp(o.one) < 0 {
|
||||
log.Panicln("Must be greater than 0")
|
||||
return fmt.Errorf("must be greater than 0")
|
||||
}
|
||||
if in.Cmp(o.one) == 0 {
|
||||
return
|
||||
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)
|
||||
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)
|
||||
newNumber = new(big.Int).Div(&in, o.two)
|
||||
}
|
||||
|
||||
o.iterations++
|
||||
fmt.Printf(" -> %s", newNumber.Text(10))
|
||||
o.nextNumber(newNumber)
|
||||
return o.nextNumber(*newNumber)
|
||||
}
|
||||
|
||||
45
collatz/calculator_test.go
Normal file
45
collatz/calculator_test.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package collatz
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type MockParser struct {
|
||||
value *big.Int
|
||||
}
|
||||
|
||||
func (m *MockParser) Parse() (*big.Int, error) {
|
||||
return m.value, nil
|
||||
}
|
||||
|
||||
func TestNewCalculator(t *testing.T) {
|
||||
parser := &MockParser{}
|
||||
calculator := NewCalculator(parser)
|
||||
|
||||
if calculator.parser != parser {
|
||||
t.Errorf("Expected parser to be %v, got %v", parser, calculator.parser)
|
||||
}
|
||||
|
||||
if calculator.one.Cmp(big.NewInt(1)) != 0 {
|
||||
t.Errorf("Expected one to be 1, got %v", calculator.one)
|
||||
}
|
||||
|
||||
if calculator.two.Cmp(big.NewInt(2)) != 0 {
|
||||
t.Errorf("Expected two to be 2, got %v", calculator.two)
|
||||
}
|
||||
|
||||
if calculator.three.Cmp(big.NewInt(3)) != 0 {
|
||||
t.Errorf("Expected three to be 3, got %v", calculator.three)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateCollatz(t *testing.T) {
|
||||
parser := &MockParser{value: big.NewInt(6)}
|
||||
calculator := NewCalculator(parser)
|
||||
|
||||
err := calculator.CalculateCollatz()
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user