[Golang] Pandigital products - Problem 32 - Project Euler
Problem: [1]
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
Solution:
The form of the identity must be like:
M * MMMM = MMMMMM * MMM = MMMMBrute-forcely check all permutations [2] of 1~9 in above form. We will get the following satisfying identity.
12 * 483 = 579618 * 297 = 534627 * 198 = 534628 * 157 = 439639 * 186 = 725442 * 138 = 57964 * 1738 = 69524 * 1963 = 785248 * 159 = 763256370
package main
import (
      "fmt"
      "strconv"
)
var sum int64 = 0
// Swap the i-th byte and j-th byte of the string
func swap(s string, i, j int) string {
      var result []byte
      for k := 0; k < len(s); k++ {
              if k == i {
                      result = append(result, s[j])
              } else if k == j {
                      result = append(result, s[i])
              } else {
                      result = append(result, s[k])
              }
      }
      return string(result)
}
// Function to find all Permutations of a given string str[i:n]
// containing all distinct characters
func permutations(str string, i, n int) {
      // base condition
      if i == n-1 {
              checkProduct(str)
              return
      }
      // process each character of the remaining string
      for j := i; j < n; j++ {
              // swap character at index i with current character
              str = swap(str, i, j)
              // recursion for string [i+1:n]
              permutations(str, i+1, n)
              // backtrack (restore the string to its original state)
              str = swap(str, i, j)
      }
}
// MxMMMM=MMMM
// MMxMMM=MMMM
func checkProduct(s string) {
      // check M x MMMM = MMMM
      m1, _ := strconv.ParseInt(s[0:1], 10, 0)
      m2, _ := strconv.ParseInt(s[1:5], 10, 0)
      prd, _ := strconv.ParseInt(s[5:9], 10, 0)
      if m1*m2 == prd {
              fmt.Printf("%d * %d = %d\n", m1, m2, prd)
              sum += prd
      }
      // check MM x MMM = MMMM
      m1, _ = strconv.ParseInt(s[0:2], 10, 0)
      m2, _ = strconv.ParseInt(s[2:5], 10, 0)
      prd, _ = strconv.ParseInt(s[5:9], 10, 0)
      if m1*m2 == prd {
              fmt.Printf("%d * %d = %d\n", m1, m2, prd)
              sum += prd
      }
}
func main() {
      str := "123456789"
      permutations(str, 0, len(str))
      fmt.Println(sum)
}
Test on:
- Ubuntu 18.04, Go 1.11.1
- Go Playground
References:
| [1] | Pandigital products - Problem 32 - Project Euler | 
| [2] | [Golang] All Permutations of Given String With Distinct Characters | 
| [3] | [Golang] Lexicographic permutations - Problem 24 - Project Euler | 
| [4] | [Golang] Type Conversion between String and Integer |