Error: subscript out of bounds (knight's tour) - r

im new to R and im trying to solve for the minimum number of moves for a knight visit all the moves in a chess board.
I got the python code from:
https://www.geeksforgeeks.org/the-knights-tour-problem-backtracking-1/
and i tried to translate it to r.
But i am always getting the error and I don't know where I went wrong.
This is my code:
chess = rep(-1, times = 64)
board = matrix(data = chess, nrow = 8, ncol = 8, byrow = TRUE)
move_x = c(2, 1, -1, -2, -2, -1, 1, 2)
move_y = c(1, 2, 2, 1, -1, -2, -2, -1)
board[1, 1] = 0
pos = 1
valid_move <- function (x, y, board) {
if (x >= 1 & y >= 1 & x <= 8 & y <= 8 & board[x, y] == -1) {
return (T)
}
return (F)
}
solve <- function (board, curr_x, curr_y, move_x, move_y, pos) {
if (pos == 64) {
return (T)
}
for (i in seq(1:8)) {
new_x = curr_x + move_x[i]
new_y = curr_y + move_y[i]
if (valid_move(new_x, new_y, board)) {
board[new_x, new_y] = pos
if (solve(board, new_x, new_y, move_x, move_y, pos+1)) {
return (TRUE)
}
board[new_x, new_y] = -1
}
}
}
main <- function() {
sims = 10
ctr = 0
number_of_moves = c()
solve(board, 1, 1, move_x, move_y, pos)
print(paste("Minimum number of moves: ", pos))
}
main()
Thanks!

The problem is that the python code relies on short-circuiting to prevent out-of-bounds errors. & will not short-circuit so you need to use &&.
Here is an example
FALSE && stop()
#> [1] FALSE
FALSE & stop()
#> Error:
Update valid_move to this
valid_move <- function (x, y, board) {
# Changed to && to allow short-circuiting
# if (x >= 1 & y >= 1 & x <= 8 & y <= 8 & board[x, y] == -1) {
if (x >= 1 && y >= 1 && x <= 8 && y <= 8 && board[x, y] == -1) {
return (T)
}
return (F)
}

Related

Calculating a determinant in Lua

I'm trying to calculate determinants with any order using Lua. I can calculate determinants for order less than 4, but not for greater equals than 4 ones.
I have a 4x4 matrix and its determinant with the program is 0, but the real solution is 56.
I don't know if the problem is in getSubmatrix method or is in detMat method, because I don't have any error message from the console.
I've ported the methods from my own java code, where it works fine.
Here's all my code:
function numMat(n, A)
local S = {}
for i = 1, #A, 1 do
local T = {}
S[i] = T
for j =1, #A[1], 1 do
T[j] = n * A[i][j]
end
end
return S
end
function sumMat(A, B)
local C = {}
for i = 1, #A do
local D = {}
C[i] = D
for j = 1, #A[1] do
D[j] = A[i][j] + B[i][j]
end
end
return C
end
function subMat(A, B)
return sumMat(A, numMat(-1, B))
end
function printMatrix(A)
for i, v in ipairs(A) do
for j, w in ipairs(v) do
print(w)
end
end
end
function escalarProduct(u, v)
local w = 0
for i = 1, #u do
w = w + u[i] * v[i]
end
return w
end
function prodMat(A, B)
local C = {}
for i = 1, #A do
C[i] = {}
for j = 1, #B[1] do
local num = A[i][1] * B[1][j]
for k = 2, #A[1] do
num = num + A[i][k] * B[k][j]
end
C[i][j] = num
end
end
return C
end
function powMat(A, power)
local B = {}
local C = {}
C = A
for i = 1, power - 1 do
B = prodMat(C, A)
C = B
end
return B
end
function trasposeMat(A)
local B = {}
for i = 1, #A do
local C = {}
B[i] = C
for j = 1, #A[1] do
C[j] = A[j][i]
end
end
return B
end
function productDiag(m)
local prod = 1
for i = 1, #m do
for j = 1, #m do
if i == j then prod = prod * m[i][i] end
end
end
return prod
end
function isDiagonal(A)
for i = 1, #A do
for j = 1, #A do
if i ~= j and A[i][j] ~= 0 then return false end
end
end
return true
end
function isTriangSup(m)
for i = 1, #m do
for j = 1, i do
if m[i][j] == 0 then return true end
end
end
return false
end
function isTriangInf(m)
return isTriangSup(trasposeMat(m))
end
function isTriang(m)
if(isTriangSup(m)) then return true
else
return false
end
end
function getSubmatrix(A, rows, cols, col)
local submatrix = {}
local k = 1
for j = 1, cols do
--local D = {}
--submatrix[j] = D
if j == col then
break
end
for i = 2, rows do
submatrix[i-1][k] = A[i][j]
--D[k] = A[i][j]
end
k = k + 1
end
return submatrix
end
function det2Mat(A)
assert(#A == 2 and #A == #A[1], 'Error: The matrix must be squared, order 2.')
return A[1][1] * A[2][2] - A[1][2] * A[2][1]
end
function det3Mat(A)
assert(#A == 3 and #A == #A[1], 'Error: The matrix must be squared, order 3.')
s1 = A[1][1] * A[2][2] * A[3][3] + A[2][1] * A[3][2] * A[1][3] + A[1][2] * A[2][3] * A[3][1]
s2 = A[1][3] * A[2][2] * A[3][1] + A[1][2] * A[2][1] * A[3][3] + A[2][3] * A[3][2] * A[1][1]
return s1 - s2
end
function detMat(A)
local submatrix = {}
local det
local sign = 1
local rows = #A
local cols = #A[1]
assert(rows == cols, 'Error: The matrix must be squared.')
if rows == 1 then
return A[1][1]
end
if rows == 2 then
return det2Mat(A)
end
if rows == 3 then
return det3Mat(A)
end
if isDiagonal(A) or isTriang(A) then return productDiag(A) end
if rows > 3 then
for column = 1, cols do
submatrix = getSubmatrix(A, rows, cols, column)
det = det + sign * A[1][column] * detMat(submatrix)
sign = -sign
end
end
return det
end
A = {{1, 3}, {5, 6}}
B = {{2, 4}, {3, 1}}
C = {{2, 3, 4}, {-5, 4, 7}, {7, 1, 0}}
D = {{2, 0, 0, 0}, {0, 4, 0, 0}, {0, 0, 7, 0}, {0, 0, 0, 6}}
E = {{2, 3, 4, -3}, {-5, 4, 7, -2}, {7, 1, 0, 5}, {3, 4, 5, 6}}
--printMatrix(numMat(-1, A))
--printMatrix(sumMat(A, B))
--printMatrix(subMat(A, B))
--print(escalarProduct({1, 3}, {5, 6}))
--printMatrix(prodMat(A, B))
--printMatrix(trasposeMat(A))
--printMatrix(powMat(A, 2))
--printMatrix(powMat(A, 3))
print(detMat(A))
print(detMat(B))
print(detMat(C))
print(detMat(D))
print(detMat(E)) --The solution must be 56
And the console solution is:
-9
-10
1
336
0
The error is when I want to find out the determinant of the matrix E.

Issues with more than one "&" condition inside if statement in R

I'm doing an IF statement in R to create a variable in R.
I'm having an error that I can't detect to what it refers exactly so I can't fix it. Can somebody help me?
library(install.load)
install_load("checkmate", "expss")
amostra$escol <- NA
educd003 <- data.frame("d003" = 1:9, "codeduc" = c(1,1,3,3,5,5,7,9,9))
educd0091 <- data.frame("d009" = c(1,2,3,4,5,6,7,8,9,10,11,12),
"codeduc" = c(2,2,4,4,4,4,6,6,6,8,10,10))
educd0092 <- data.frame("d009" = c(1,2,3,4,5,6,7,8,9,10,11,12),
"codeduc" = c(1,1,3,3,3,3,5,5,5,7,9,9))
for (i in 1:nrow(amostra)) {
if (is.na(amostra$d001[i]) == TRUE) {
amostra$escol[i] <- 99
} else if (amostra$d001[i] == 2) {
amostra$escol[i] <- 0
} else if (amostra$d002[i] == 1) {
amostra$escol[i] <- vlookup(amostra$d003[i], educd003, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 2) {
amostra$escol[i] <- 2
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & amostra$d014[i] == 1) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0091, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & amostra$d014[i] == 2) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0092, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & is.na(amostra$d014[i]) == TRUE) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0092, result_column = 2, lookup_column = 1)
} else {
amostra$escol[i] <- NA
}
}
Error:
Error in if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & amostra$d014[i] == :
missing value where TRUE/FALSE needed
Thanks,
Wagner
I solved it.
The problem, apparently, was the order.
The code below ran ok:
for (i in 1:nrow(amostra)) {
if (is.na(amostra$d001[i]) == TRUE) {
amostra$escol[i] <- 99
} else if (amostra$d001[i] == 2) {
amostra$escol[i] <- 0
} else if (amostra$d002[i] == 1) {
amostra$escol[i] <- vlookup(amostra$d003[i], educd003, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 2) {
amostra$escol[i] <- 2
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & is.na(amostra$d014[i]) == TRUE) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0092, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & amostra$d014[i] == 1) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0091, result_column = 2, lookup_column = 1)
} else if (amostra$d002[i] == 2 & amostra$d008[i] == 1 & amostra$d014[i] == 2) {
amostra$escol[i] <- vlookup(amostra$d009[i], educd0092, result_column = 2, lookup_column = 1)
} else {
amostra$escol[i] <- NA
}
}
Thank you very much anyway!

How to find the Markov Chain Probability?

I am trying to find the probability that the chain jumps from state k-1 to state 1 before it hits state k.
Can anyone spot my mistake?
I tried to simulate the markov chain, but i want to make a code that allows me to find probability of k ={1, 2, 3, ........17}. But I can really not get the code.
This is the error message I always get
Error in while (X[i] > 1 && X[i] < k) { :
missing value where TRUE/FALSE needed
Here is my code:
k <- 17
{ p <- 0.5
q <- 0.1
P <- matrix (0, nrow = k, ncol = k, byrow = TRUE)
for (i in 1:k)
{ for (j in 1:k)
{ if (i == 1 && i == j)
{ P[i,j] <- 1
}
else if (i == k && i == j)
{ P[i,j] <- 1
}
else if (i == j)
{ P[i,j] <- p*(1-q)
}
else if (j == k && i != 1)
{ P[i,j] <- q
}
else if (i == j+1 && i != k)
{ P[i,j] <- (1-p)*(1-q)
}
}
}
P
X <- (k-1)
trials <- 1000
hits <- 0 #counter for no. of hits
for (i in 1:trials)
{ i <- 1 #no. of steps
while(X[i] > 1 && X[i] < k)
{ Y <- runif(1) #uniform samples
p1 <- P[X[i],] #calculating the p-value
p1 <- cumsum(p1)
# changes in the chain
if(Y <= p1[1])
{ X[i+1] = 1}
else if(Y <= p1[2])
{ X[i+1] = 2}
else if(Y <= p1[3])
{ X[i+1] = 3}
else if(Y <= p1[4])
{ X[i+1] = 4}
else if(Y <= p1[5])
{ X[i+1] = 5}
else if(Y <= p1[6])
{ X[i+1] = 6}
else if(Y <= p1[7])
{ X[i+1] = 7}
else if(Y <= p1[8])
{ X[i+1] = 8}
else if(Y <= p1[9])
{ X[i+1] = 9}
else if(Y <= p1[10])
{ X[i+1] = 10}
else if(Y <= p1[11])
{ X[i+1] = 11}
else if(Y <= p1[12])
{ X[i+1] = 12}
else if(Y <= p1[13])
{ X[i+1] = 13}
else if(Y <= p1[14])
{ X[i+1] = 14}
else if(Y <= p1[15])
{ X[i+1] = 15}
else if(Y <= p1[16])
{ X[i+1] = 16}
else if(Y <= p1[17])
{ X[i+1] <= 17}
i <- i+1
}
if(X[i]==1)
{ hits <- hits+1}
else
{ hits <- hits+0}
}
Probability <- hits/trials
Probability
}
I think the line
i <- 1 #no. of steps
should not be there. Try this:
k <- 17
{ p <- 0.5
q <- 0.1
P <- matrix (0, nrow = k, ncol = k, byrow = TRUE)
for (i in 1:k)
{ for (j in 1:k)
{ if (i == 1 && i == j)
{ P[i,j] <- 1
}
else if (i == k && i == j)
{ P[i,j] <- 1
}
else if (i == j)
{ P[i,j] <- p*(1-q)
}
else if (j == k && i != 1)
{ P[i,j] <- q
}
else if (i == j+1 && i != k)
{ P[i,j] <- (1-p)*(1-q)
}
}
}
P
X <- (k-1)
trials <- 1000
hits <- 0 #counter for no. of hits
for (i in 1:trials)
{
while(X[i] > 1 && X[i] < k)
{ Y <- runif(1) #uniform samples
p1 <- P[X[i],] #calculating the p-value
p1 <- cumsum(p1)
# changes in the chain
if(Y <= p1[1])
{ X[i+1] = 1}
else if(Y <= p1[2])
{ X[i+1] = 2}
else if(Y <= p1[3])
{ X[i+1] = 3}
else if(Y <= p1[4])
{ X[i+1] = 4}
else if(Y <= p1[5])
{ X[i+1] = 5}
else if(Y <= p1[6])
{ X[i+1] = 6}
else if(Y <= p1[7])
{ X[i+1] = 7}
else if(Y <= p1[8])
{ X[i+1] = 8}
else if(Y <= p1[9])
{ X[i+1] = 9}
else if(Y <= p1[10])
{ X[i+1] = 10}
else if(Y <= p1[11])
{ X[i+1] = 11}
else if(Y <= p1[12])
{ X[i+1] = 12}
else if(Y <= p1[13])
{ X[i+1] = 13}
else if(Y <= p1[14])
{ X[i+1] = 14}
else if(Y <= p1[15])
{ X[i+1] = 15}
else if(Y <= p1[16])
{ X[i+1] = 16}
else if(Y <= p1[17])
{ X[i+1] <= 17}
i <- i+1
}
if(X[i]==1)
{ hits <- hits+1}
else
{ hits <- hits+0}
}
Probability <- hits/trials
Probability
}
You're setting X to k-1. In R, that's treated as a vector of length 1. As soon as i reaches 2, X[i] return an index error, because X does not have a second element.
Further notes: using the same index in two different nesting levels is very bad form. Also, when you start having a massive list of if-then-else statements, it's time to rethink your code. In this case, you could just subset 1:17 on p1[i] >=Y, take the minimum value, and then set X to that.

C++ Multidimensional Array help delete a row and column

I need someone to tell me how to write a code easy and understandable for this matrix
In this exercise is search to delete a row and a column:
const int n = 4, m = 4;
int A[n][m] = { { 2, -8, -7, 5 },{ 4, -7, -8, 2 },{ 1, 10, 3, 6 },{ 4, 7, 9, -3 } };
int i, j, r, k, B[n][m];
variable r stands for row which need to be deleted
variable k stands for column which needs to be deleted
B[n][m] stands for new matrix that will be showed on console
Waiting for answer
there's my code :
const int n = 4, m = 4;
int A[n][m] = { { 2, -8, -7, 5 },
{ 4, -7, -8, 2 },
{ 1, 10, 3, 6 },
{ 4, 7, 9, -3 } };
int i, j, r, k, B[n][m];
cout << "give a value r and k:";
cin >> r >> k;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
if ((i < r) && (j < k))
B[i][j] = A[i][j];
if ((i >= r) && (j < k))
B[i][j] = A[i + 1][j];
if ((i < r) && (j >= k))
B[i][j] = A[i][j + 1];
if ((i >= r) && (j >= k))
B[i][j] = A[i + 1][j + 1];
}
}
cout << "Matrix B ={" << endl;
for (i = 0; i < n - 1; i++)
{
for (j = 0; j < m - 1; j++)
{
cout.width(3);
cout << B[i][j];
}
cout << endl;
but here is what mix up things to me :
if ((i < r) && (j < k))
B[i][j] = A[i][j];
if ((i >= r) && (j < k))
B[i][j] = A[i + 1][j];
if ((i < r) && (j >= k))
B[i][j] = A[i][j + 1];
if ((i >= r) && (j >= k))
B[i][j] = A[i + 1][j + 1];
}
this is the part where i mess up more often
Can somebody tell me more easier way ?

sorting two dimensional array asp classic

So I have a 2d array that I want to Sort. I can sort it easily when one dimensional.
I Hope you can help me guys.
This is my Data.
top5(0,0) = Greeting
top5(0,1) = 2
top5(1,0) = VerifyingInformation
top5(1,1) = 5
top5(2,0) = Calibration
top5(2,1) = 4
I can sort It no problem when one dimensional.
I'm using this code for one dimensional.
For i = LBound(top5) to UBound(top5)
For j = LBound(top5) to UBound(top5) - 1
If top5(j,1) < top5(j + 1,1) Then
TempValue = top5(j + 1,1)
top5(j + 1,1) = top5(j,1)
top5(j,1) = TempValue
End If
next
Next
The result I want to have is this.
VerifyingInformation 5
Calibration 4
Greeting 2
THIS WORKS FOR ME
function sort_arr_mult(byref ArrTmp, ordPlace)
' ordPlace - the place of the order value in the array
' create the new array
Redim arrRet (Ubound(ArrTmp, 1), Ubound(ArrTmp, 2))
for j = 0 to Ubound(ArrTmp, 2)
orderVal = ArrTmp(ordPlace, j)
if j = 0 then ' first enter insert to first column
for i = 0 to Ubound(ArrTmp, 1)
arrRet(i, j) = ArrTmp(i, j)
next
else
' check the first value if smaller or equal
' move the columnbs one field up
' at the end insert to currenct column
for k = 0 to Ubound(arrRet, 2)
if isEmp(arrRet(0, k)) then ' if empty fied the column
for i = 0 to Ubound(arrRet, 1)
arrRet(i, k) = ArrTmp(i, j)
next
exit for
else
if orderVal<=arrRet(ordPlace, k) then
for x = Ubound(arrRet, 2) to k+1 step -1
for i = 0 to Ubound(arrRet, 1)
arrRet(i, x) = arrRet(i, x-1)
next
next
for i = 0 to Ubound(arrRet, 1)
arrRet(i, k) = ArrTmp(i, j)
next
exit for
end if
end if
next ' for k = 0 to Ubound(arrRet, 2)
end if
next
sort_arr_mult = arrRet
end function
It looks like you are actually performing a one-dimensional sort of the numeric value with an associated text string just along for the ride.
Your example code is close but you will need 2 temp values to represent the array values you will be shifting around.
For i = LBound(top5) to UBound(top5)
For j = LBound(top5) to UBound(top5) - 1
If top5(j,1) < top5(j + 1,1) Then
TempValue = top5(j + 1,1)
TempText = top5(j + 1,0)
top5(j + 1,1) = top5(j,1)
top5(j + 1,0) = top5(j,0)
top5(j,1) = TempValue
top5(j,0) = TempText
End If
Next
Next
Extending raam's answer with 3rd parameter as sorting direction "ASC" or "DESC"
Function sortArrayMulti(byref ArrTmp, ordPlace, so)
''so: sortorder "ASC" or "DESC"
Dim j, i, k, orderVal, x
Redim arrRet(Ubound(ArrTmp, 1), Ubound(ArrTmp, 2))
for j = 0 To Ubound(ArrTmp, 2)
orderVal = ArrTmp(ordPlace, j)
if j = 0 Then
for i = 0 to Ubound(ArrTmp, 1)
arrRet(i, j) = ArrTmp(i, j)
next
else
for k = 0 to Ubound(arrRet, 2)
if isEmpty(arrRet(0, k)) then
for i = 0 to Ubound(arrRet, 1)
arrRet(i, k) = ArrTmp(i, j)
next
exit for
else
if so = "ASC" then
if orderVal <= arrRet(ordPlace, k) then
for x = Ubound(arrRet, 2) to k + 1 step -1
for i = 0 to Ubound(arrRet, 1)
arrRet(i, x) = arrRet(i, x - 1)
next
next
for i = 0 to Ubound(arrRet, 1)
arrRet(i, k) = ArrTmp(i, j)
next
exit for
end if
else
if orderVal >= arrRet(ordPlace, k) then
for x = Ubound(arrRet, 2) to k + 1 step -1
for i = Ubound(arrRet, 1) to 0 step -1
arrRet(i, x) = arrRet(i, x - 1)
next
next
for i = 0 to Ubound(arrRet, 1)
arrRet(i, k) = ArrTmp(i, j)
next
exit for
end if
end if
end if
next
end if
next
sortArrayMulti = arrRet
End Function

Resources