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)
}
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!
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 ?
FURTHER UPDATE
There's no input, because the program creates data.
The code below works for the first two patients, but I want to put it in a loop; there will be 200 patients eventually. Sorry about length.
s <- 42 #SHOULD BE 42
p <- 30 #SHOULD BE 400
p1 <- 8 #Should be 8
m <- 2 #shou;ld be higher
w <- 2
#CAPITAL LETTERS are counting versions of the lowercase
numses <- 12
mult <- 1
maxses <- round(mult*numses,0)
drop = .3; titrate = .2; complete = .3; noise = .5; other = .1
dropskip = .3; titrateskip = .2; completeskip = .3; noiseskip = .5; otherskip = .1;
dropnew = .3; titratenew = .2; completenew = .9; noisenew = .5; othernew = .1;
name = "Basic";
pdrop = .1; ptitrate = .2; pcomplete =.7; pnoise = .9; pother = 1;
# THESE HAVE TO BE ASCENDING.
w = 10
######################################################################################################################
patients <- matrix(nrow = p, ncol = s, "NA") #all patients attendance
invited <- matrix(nrow = p, ncol = s, 0) #number of sessions A or S
missinrow <- matrix(nrow = p, ncol = s, 0) #number of sessions missed in a row
insess <- vector("numeric", s) #number of people in a session
set.seed(83877201)
addlist <- rpois(s, w)
# Set up waitlist
waitlist <- vector("numeric", s)
waitlist[1] <- addlist[1]
for(i in 2:s)
{
waitlist[i] <- waitlist[i-1] + addlist[i]
}
for (i in 1:p)
{
for (j in 1:s)
{
if (i < waitlist[j]) patients[i,j] <- "W"
}
}
#Assign all patients to classes
classlist <- cut(runif(p), c(0, pdrop, ptitrate, pnoise, pcomplete, 1), labels = c("D", "T", "C", "N", "O"))
#First patient
#first session
{
invited[1,1] <- 1
insess[1] <- 1
if (classlist[1] == "D")
{
if (runif(1) < dropnew) {patients[1, 1] <- 'A'} else
{
patients[1, 1] <- 'S'
missinrow[1, 1] <- 1
}
}
if (classlist[1] == "T")
{
if (runif(1) < titratenew) {patients[1, 1] <- 'A'} else
{
patients[1, 1] <- 'S'
missinrow[1, 1] <- 1
}
}
if (classlist[1] == "C")
{
if (runif(1) < completenew) {patients[1, 1] <- 'A'} else
{
patients[1, 1] <- 'S'
missinrow[1, 1] <- 1
}
}
if (classlist[1] == "N")
{
if (runif(1) < noisenew) {patients[1, 1] <- 'A'} else
{
patients[1, 1] <- 'S'
missinrow[1, 1] <- 1
}
}
if (classlist[1] == "O")
{
if (runif(1) < othernew) {patients[1, 1] <- 'A'} else
{
patients[1, 1] <- 'S'
missinrow[1, 1] <- 1
}
}
}
#Later sessions
for (j in 2 : s)
{
if (patients[1,(j-1)] == 'A'|patients[1,(j-1)] == 'S')
{
invited[1,j] <- invited[1,(j-1)] + 1
} else
{
invited[1,j] <- invited[1,(j-1)]
}
if (invited[1,j] <= maxses & missinrow[1,j] < m)
{
# Skip or attend
# If attended previous session
if (patients[1, (j-1)] == 'A')
{
if (classlist[1] == "D")
{if (runif(1) < drop) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- 1
}
}
if (classlist[1] == "T")
{if (runif(1) < titrate) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- 1
}
}
if (classlist[1] == "C")
{if (runif(1) < complete) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- 1
}
}
if (classlist[1] == "N")
{
if (runif(1) < noise) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- 1
}
}
if (classlist[1] == "O")
{
if (runif(1) < other) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- 1
}
}
} else
# If skipped previous session
if (patients[1, (j-1)] == 'S')
{
if (classlist[1] == "D")
{
if (runif(1) < drop) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- missinrow[1, (j-1)] + 1
}
}
if (classlist[1] == "T")
{
if (runif(1) < titrate) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- missinrow[1, (j-1)] + 1
}
}
if (classlist[1] == "C")
{if (runif(1) < complete) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- missinrow[1, (j-1)] + 1
}
}
if (classlist[1] == "N")
{if (runif(1) < noise) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- missinrow[1, (j-1)] + 1
}
}
if (classlist[1] == "O")
{
if (runif(1) < other) {patients[1, j] <- 'A'} else
{
patients[1, j] <- 'S'
missinrow[1, j] <- missinrow[1, (j-1)] + 1
}
}
}
} else {patients[1,j] <- 'D'}
# check for number of attended or missed sessions
if (patients[1,(j-1)] == 'A' | patients[1,(j-1)] == 'S')
{
insess[j] <- 1
} else
{
insess[j] <- 0
}
}
#Second patients
#Patient is waiting and there is space
#First session
if (insess[1] < maxses & waitlist[1] > 0) #THIS MAY NEED TO BE A WHILE LOOP, FOR MULTIPLE PATIENTS
{
invited[2,1] <- 1
insess[1] <- insess[1] + 1
if (classlist[2] == "D")
{
if (runif(1) < dropnew) {patients[1, 1] <- 'A'} else
{
patients[2, 1] <- 'S'
missinrow[2, 1] <- 1
}
}
if (classlist[2] == "T")
{
if (runif(1) < titratenew) {patients[2, 1] <- 'A'} else
{
patients[2, 1] <- 'S'
missinrow[2, 1] <- 1
}
}
if (classlist[2] == "C")
{
if (runif(1) < completenew) {patients[2, 1] <- 'A'} else
{
patients[2, 1] <- 'S'
missinrow[2, 1] <- 1
}
}
if (classlist[2] == "N")
{
if (runif(1) < noisenew) {patients[2, 1] <- 'A'} else
{
patients[2, 1] <- 'S'
missinrow[2, 1] <- 1
}
}
if (classlist[2] == "O")
{
if (runif(1) < othernew) {patients[2, 1] <- 'A'} else
{
patients[2, 1] <- 'S'
missinrow[2, 1] <- 1
}
}
}
#Later sessions
#Patient invited previous session
for (j in 2 : s)
{
if (patients[2,(j-1)] == 'A'|patients[2,(j-1)] == 'S')
{
invited[2,j] <- invited[2,(j-1)] + 1
} else
{
invited[2,j] <- invited[2,(j-1)]
}
if (invited[2,j] <= maxses & missinrow[2,j] < m)
{
# Skip or attend
# If attended previous session
if (patients[2, (j-1)] == 'A')
{
if (classlist[2] == "D")
{if (runif(1) < drop) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- 1
}
}
if (classlist[2] == "T")
{if (runif(1) < titrate) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- 1
}
}
if (classlist[2] == "C")
{if (runif(1) < complete) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- 1
}
}
if (classlist[2] == "N")
{
if (runif(1) < noise) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- 1
}
}
if (classlist[2] == "O")
{
if (runif(1) < other) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- 1
}
}
} else
# If skipped previous session
if (patients[2, (j-1)] == 'S')
{
if (classlist[2] == "D")
{
if (runif(1) < drop) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- missinrow[2, (j-1)] + 1
}
}
if (classlist[2] == "T")
{
if (runif(1) < titrate) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- missinrow[2, (j-1)] + 1
}
}
if (classlist[2] == "C")
{if (runif(1) < complete) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- missinrow[2, (j-1)] + 1
}
}
if (classlist[2] == "N")
{if (runif(1) < noise) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- missinrow[2, (j-1)] + 1
}
}
if (classlist[2] == "O")
{
if (runif(1) < other) {patients[2, j] <- 'A'} else
{
patients[2, j] <- 'S'
missinrow[2, j] <- missinrow[2, (j-1)] + 1
}
}
}
} else {patients[2,j] <- 'D'}
# check for number of attended or missed sessions
if (patients[2,(j-1)] == 'A' | patients[2,(j-1)] == 'S')
{
insess[j] <- insess[j] + 1
} else
{
insess[j] <- insess[j]
}
}
UPDATED with additional information
Thanks, Joshua, for your help so far.
Joshua asked for additional information in order to be able to help further.
The overall problem is to create a dataset of patients who attend different sessions of therapy. Whether they attend or not depends on a number of parameters, including whether they attended the previous session (which is in patients), what "class" of patient they are (which is in classlist), how many sessions they have already either attended or skipped (invited) and how many sessions in a row they have missed (missinrow); all of those will vary. If the previous session is less than full, additional patients get assigned to the new session (provided someone is waiting (waitlist).
When I do this one patient at a time, it works well. But when I try to loop over all patients, I run into the
Hello
This is one part of a larger program. I cannot figure out why it doesn't work as I thought it would. The code is
for(i in 2:p)
{
while (insess[1] < maxses & waitlist[1] > 0)
{
invited[i,1] <- 1
waitlist[1] <- waitlist[1] - 1
insess[1] <- insess[1] + 1
if (classlist[i] == "D")
{
if (runif(1) < dropnew) {patients[i, 1] <- 'A'} else
{
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
if (classlist[i] == "T")
{
if (runif(1) < titratenew) {patients[i, 1] <- 'A'} else
{
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
if (classlist[i] == "C")
{
if (runif(1) < completenew) {patients[i, 1] <- 'A'} else
{
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
if (classlist[i] == "N")
{
if (runif(1) < noisenew) {patients[i, 1] <- 'A'} else
{
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
if (classlist[i] == "O")
{
if (runif(1) < othernew) {patients[i, 1] <- 'A'} else
{
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
}
}
When I run this, i goes to 30 (which is right), insess[1] goes to 10 (also right), waitlist[1] goes to 0 (also right) but the patients matrix is only updated for i = 2. I also checked that classlist has appropriate values.
I don't see where it is leaving the loop. I think I'm using while incorrectly, but not sure how.
thanks!
You're not resetting insess[1] and waitlist[1] in each iteration of the for loop. When i = 3, insess[1] = 10 and waitlist[1] = 0, so nothing in the while loop is executed.
As as added bonus, here's a more succinct version of your code using the switch function.
for(i in 2:p)
{
insess[1] <- INITME
waitlist[1] <- INITMETOO
while (insess[1] < maxses & waitlist[1] > 0)
{
invited[i,1] <- 1
waitlist[1] <- waitlist[1] - 1
insess[1] <- insess[1] + 1
newswitch <-
switch(classlist[i],
D = dropnew,
T = titratenew,
C = completenew,
N = noisenew,
O = othernew)
if (runif(1) < newswitch) {
patients[i, 1] <- 'A'
} else {
patients[i, 1] <- 'S'
missinrow[i, 1] <- 1
}
}
}