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 }