14

R-help に関する興味深い質問がありました。

「1 から 17 までの数字を取ってください。隣り合った数字のすべてのペアが合計されて平方数になるように、それらを 1 行に書き出すことができますか?」

私の解決策は以下であり、特に特別なものではありません。よりエレガントで堅牢なソリューションに興味があります。可能であれば、任意の数字列を取り、このように並べ替えることができるソリューションでしょうか?

sq.test <- function(a, b) {
  ## test for number pairs that sum to squares.
  sqrt(sum(a, b)) == floor(sqrt(sum(a, b)))
}

ok.pairs <- function(n, vec) {
  ## given n as a member of vec,
  ## which other members of vec satisfiy sq.test
  vec <- vec[vec!=n]
  vec[sapply(vec, sq.test, b=n)]
}

grow.seq <- function(y) {
  ## given a starting point (y) and a pairs list (pl)
  ## grow the squaring sequence.
  ly <- length(y)
  if(ly == y[1]) return(y)

  ## this line is the one that breaks down on other number sets...
  y <- c(y, max(pl[[y[ly]]][!pl[[y[ly]]] %in% y]))
  y <- grow.seq(y)

  return(y)
}


## start vector
x <- 1:17

## get list of possible pairs
pl <- lapply(x, ok.pairs, vec=x)

## pick start at max since few combinations there.
y <- max(x)
grow.seq(y)
4

1 に答える 1

27

を使用outerして、許容されるペアを計算できます。結果の行列はグラフの隣接行列であり、その上にハミルトニアン パスが必要なだけです。

# Allowable pairs form a graph
p <- outer(
  1:17, 1:17, 
  function(u,v) round(sqrt(u + v),6) == floor(sqrt(u+v)) ) 
)
rownames(p) <- colnames(p) <- 1:17
image(p, col=c(0,1)) 

# Read the solution on the plot
library(igraph)
g <- graph.adjacency(p, "undirected")
V(g)$label <- V(g)$name 
plot(g, layout=layout.fruchterman.reingold)

ハミルトニアン パス

于 2012-04-14T03:40:47.343 に答える