exercism/go/palindrome-products/palindrome_products.go

93 lines
1.9 KiB
Go

package palindrome
import (
"fmt"
"strconv"
)
// Product is a palindromic product and all of its
// factorizations
type Product struct {
Product int
Factorizations [][2]int
}
func createProduct(fac1, fac2 int) *Product {
p := Product{Product: (fac1 * fac2)}
p.addFactors(fac1, fac2)
return &p
}
func (p *Product) hasFactors(fac1, fac2 int) bool {
for i := 0; i < len(p.Factorizations); i++ {
if p.Factorizations[i][0] == fac1 && p.Factorizations[i][1] == fac2 {
return true
}
if p.Factorizations[i][1] == fac1 && p.Factorizations[i][0] == fac2 {
return true
}
}
return false
}
func (p *Product) addFactors(fac1, fac2 int) {
if (fac1 * fac2) == p.Product {
if !p.hasFactors(fac1, fac2) {
p.Factorizations = append(p.Factorizations, [2]int{fac1, fac2})
}
}
}
// Products takes a min and a max and finds
func Products(fmin, fmax int) (Product, Product, error) {
if fmin > fmax {
return Product{}, Product{}, fmt.Errorf("fmin > fmax")
}
var pMin, pMax Product
var allProducts []Product
for i := fmin; i <= fmax; i++ {
for j := fmin; j <= fmax; j++ {
if isPalindrome(strconv.Itoa(i * j)) {
var found bool
for k := 0; k < len(allProducts); k++ {
if allProducts[k].Product == (i * j) {
allProducts[k].addFactors(i, j)
found = true
break
}
}
if !found {
allProducts = append(allProducts, *createProduct(i, j))
}
}
}
}
for i := range allProducts {
if allProducts[i].Product > pMax.Product {
// is the old pMax the new pMin?
if len(pMin.Factorizations) == 0 {
pMin = pMax
}
pMax = allProducts[i]
} else {
if allProducts[i].Product < pMin.Product {
pMin = allProducts[i]
}
}
}
if len(allProducts) == 0 {
return pMin, pMax, fmt.Errorf("No palindromes")
}
return pMin, pMax, nil
}
func isPalindrome(s string) bool {
for i := 0; i < (len(s) / 2); i++ {
if s[i] != s[len(s)-1-i] {
return false
}
}
return true
}