Skip to content

Instantly share code, notes, and snippets.

@lnsp
Created March 19, 2018 19:32
Show Gist options
  • Save lnsp/b8b3edc723acb9b1fe8c7658e6071bce to your computer and use it in GitHub Desktop.
Save lnsp/b8b3edc723acb9b1fe8c7658e6071bce to your computer and use it in GitHub Desktop.
Find a sequence from 1..n where each adjacent pair adds up to a perfect square.
package main
import (
"fmt"
"os"
"strconv"
)
// PerfectSquaresIn builds a list of perfect squares smaller or equal than n.
func PerfectSquaresIn(n int) []int {
squares := make([]int, 0)
sum := 1
for i := 3; sum <= n; i += 2 {
squares = append(squares, sum)
sum += i
}
return squares
}
// PerfectSquareGraph builds a edge hashmap of a graph,
// where each node is connected to another node if they
// both add up to a perfect square number.
func PerfectSquareGraph(n int) map[int][]int {
squares := PerfectSquaresIn(2*n - 1)
edges := make(map[int][]int)
for i := 1; i <= n; i++ {
to := make([]int, 0)
for _, s := range squares {
if s <= i || s-i > n {
continue
}
to = append(to, s-i)
}
edges[i] = to
}
return edges
}
// FindHamiltonianPath looks for a hamiltonian path in the graph.
// Returns nil, if none is found.
func FindHamiltonianPath(n int, graph map[int][]int, path []int) []int {
if path != nil {
l := len(path)
if l == n {
return path
}
head := path[l-1]
for _, edge := range graph[head] {
alreadyVisited := false
for _, visited := range path {
if edge == visited {
alreadyVisited = true
break
}
}
if !alreadyVisited {
pathCopy := make([]int, l+1)
copy(pathCopy, path)
pathCopy[l] = edge
finished := FindHamiltonianPath(n, graph, pathCopy)
if finished != nil {
return finished
}
}
}
} else {
for i := 1; i <= n; i++ {
path := FindHamiltonianPath(n, graph, []int{i})
if path != nil {
return path
}
}
}
return nil
}
func main() {
if len(os.Args) != 2 {
fmt.Println("USAGE: parker [n]")
return
}
n, err := strconv.Atoi(os.Args[1])
if err != nil {
fmt.Println("USAGE: parker[n]")
return
}
if n <= 0 {
fmt.Println("n must be greater than zero.")
return
}
graph := PerfectSquareGraph(n)
path := FindHamiltonianPath(n, graph, nil)
fmt.Println(path)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment