I am stuck in finding the source of the problem. According to traceback I guess the problem is with four.in.a.row function even though I have tested it.
four.in.a.row = function(player, v, debug=FALSE) {
if (debug) {
cat(sep="", "four.in.a.row(player=", player, ", v=", v, ")\n")
}
with(rle(v), any(lengths== 4 & values == player))
}
# Returns TRUE if (matrix) board (of character strings)
# contains at least four in a row of (string) player, who
# just played in position (r, c). (Here "r" means "row" and
# "c" means "column").
#
# Hint: this function should call four.in.a.row() four times.
won = function(player, board, r, c, debug=FALSE) {
if (debug) {
cat(sep="", "won(player=", player, ", board=\n")
print(board)
cat(sep="", ", r=", r, ", c=", c, ")\n")
}
row_w=board[r,]
cat("row is = ", row_w, "\n")
col_w=board[,c]
cat("col is = ", col_w, "\n")
reverse_diag_w=board[row(board) + col(board) == r + c]
cat("reverse diag is = ", reverse_diag_w, "\n")
diag_w=x[row(board) - col(board) == r - c]
cat("diag is = ", diag_w, "\n")
four.in.a.row(player,row_w,debug=FALSE)
four.in.a.row(player,col_w,debug=FALSE)
four.in.a.row(player,diag_w,debug=FALSE)
four.in.a.row(player,reverse_diag_w,debug=FALSE)
return(FALSE) # correct this return() statement
}
x = matrix(data=c(
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","X",
"X","X","X","X","O","E","X"
), nrow=6, ncol=7, byrow=TRUE)
stopifnot( won(player="X", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="O", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="X", board=x, r=1, c=7, debug=TRUE))
stopifnot( won(player="O", board=x, r=1, c=7, debug=TRUE))
Here's the run information:
> source("rle.R")
won(player=X, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=6, c=1)
row is = X X X X O E X
col is = E E E E E X
reverse diag is = X E E E E E
diag is = X
Error: won(player = "X", board = x, r = 6, c = 1, debug = TRUE) is not TRUE
My main problem is when I run the four.in.a.row function separately it returns TRUE as in the following:
> x = matrix(data=c(
+ "E","E","E","E","E","E","O",
+ "E","E","E","E","E","E","O",
+ "E","E","E","E","E","E","O",
+ "E","E","E","E","E","E","O",
+ "E","E","E","E","E","E","X",
+ "X","X","X","X","O","E","X"
+ ), nrow=6, ncol=7, byrow=TRUE)
> row_x=x[6,]
> row_x
[1] "X" "X" "X" "X" "O" "E" "X"
> four.in.a.row("X",row_x,debug=FALSE)
[1] TRUE
After changing the code to what #Flodel told me I have:
four.in.a.row = function(player, v, debug=FALSE) {
if (debug) {
cat(sep="", "four.in.a.row(player=", player, ", v=", v, ")\n")
}
with(rle(v), any(lengths== 4 & values == player))
}
# Returns TRUE if (matrix) board (of character strings)
# contains at least four in a row of (string) player, who
# just played in position (r, c). (Here "r" means "row" and
# "c" means "column").
#
# Hint: this function should call four.in.a.row() four times.
won = function(player, board, r, c, debug=FALSE) {
if (debug) {
cat(sep="", "won(player=", player, ", board=\n")
print(board)
cat(sep="", ", r=", r, ", c=", c, ")\n")
}
row_w=board[r,]
cat("row is = ", row_w, "\n")
col_w=board[,c]
cat("col is = ", col_w, "\n")
reverse_diag_w=board[row(board) + col(board) == r + c]
cat("reverse diag is = ", reverse_diag_w, "\n")
diag_w=board[row(board) - col(board) == r - c]
cat("diag is = ", diag_w, "\n")
#four.in.a.row(player,row_w,debug=FALSE)
#four.in.a.row(player,col_w,debug=FALSE)
#four.in.a.row(player,diag_w,debug=FALSE)
#four.in.a.row(player,reverse_diag_w,debug=FALSE)
#return(FALSE) # correct this return() statement
return(four.in.a.row(player,row_w,debug=FALSE) ||
four.in.a.row(player,col_w,debug=FALSE) ||
four.in.a.row(player,diag_w,debug=FALSE) ||
four.in.a.row(player,reverse_diag_w,debug=FALSE))
}
x = matrix(data=c(
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","X",
"X","X","X","X","O","E","X"
), nrow=6, ncol=7, byrow=TRUE)
stopifnot( won(player="X", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="O", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="X", board=x, r=1, c=7, debug=TRUE))
stopifnot( won(player="O", board=x, r=1, c=7, debug=TRUE))
And here's the error I receive:
> source("rle.R")
won(player=X, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=6, c=1)
row is = X X X X O E X
col is = E E E E E X
reverse diag is = X E E E E E
diag is = X
Show Traceback
Rerun with Debug
Error in x[-1L] != x[-n] : comparison of these types is not implemented
Here's the result of the traceback:
Error in x[-1L] != x[-n] : comparison of these types is not implemented
9 rle(v)
8 with(rle(v), any(lengths == 4 & values == player)) at rle.R#5
7 four.in.a.row(player, diag, debug = FALSE) at rle.R#32
6 won(player = "X", board = x, r = 6, c = 1, debug = TRUE)
5 stopifnot(won(player = "X", board = x, r = 6, c = 1, debug = TRUE)) at rle.R#46
4 eval(expr, envir, enclos)
3 eval(ei, envir)
2 withVisible(eval(ei, envir))
1 source("rle.R")
Here's the answer thanks to Flodel's guide:
four.in.a.row = function(player, v, debug=FALSE) {
if (debug) {
cat(sep="", "four.in.a.row(player=", player, ", v=", v, ")\n")
}
with(rle(v), any(lengths== 4 & values == player))
}
# Returns TRUE if (matrix) board (of character strings)
# contains at least four in a row of (string) player, who
# just played in position (r, c). (Here "r" means "row" and
# "c" means "column").
#
# Hint: this function should call four.in.a.row() four times.
won = function(player, board, r, c, debug=FALSE) {
if (debug) {
cat(sep="", "won(player=", player, ", board=\n")
print(board)
cat(sep="", ", r=", r, ", c=", c, ")\n")
}
row_w=board[r,]
cat("row is = ", row_w, "\n")
col_w=board[,c]
cat("col is = ", col_w, "\n")
reverse_diag_w=board[row(board) + col(board) == r + c]
cat("reverse diag is = ", reverse_diag_w, "\n")
diag_w=x[row(board) - col(board) == r - c]
cat("diag is = ", diag_w, "\n")
#four.in.a.row(player,row_w,debug=FALSE)
#four.in.a.row(player,col_w,debug=FALSE)
#four.in.a.row(player,diag_w,debug=FALSE)
#four.in.a.row(player,reverse_diag_w,debug=FALSE)
#return(FALSE) # correct this return() statement
return(four.in.a.row(player,row_w,debug=debug) ||
four.in.a.row(player,col_w,debug=debug) ||
four.in.a.row(player,diag_w,debug=debug) ||
four.in.a.row(player,reverse_diag_w,debug=debug))
}
x = matrix(data=c(
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","O",
"E","E","E","E","E","E","X",
"X","X","X","X","O","E","X"
), nrow=6, ncol=7, byrow=TRUE)
stopifnot( won(player="X", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="O", board=x, r=6, c=1, debug=TRUE))
stopifnot(!won(player="X", board=x, r=1, c=7, debug=TRUE))
stopifnot( won(player="O", board=x, r=1, c=7, debug=TRUE))
Here's what I get :
> source("rle.R")
won(player=X, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=6, c=1)
row is = X X X X O E X
col is = E E E E E X
reverse diag is = X E E E E E
diag is = X
four.in.a.row(player=X, v=XXXXOEX)
won(player=O, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=6, c=1)
row is = X X X X O E X
col is = E E E E E X
reverse diag is = X E E E E E
diag is = X
four.in.a.row(player=O, v=XXXXOEX)
four.in.a.row(player=O, v=EEEEEX)
four.in.a.row(player=O, v=X)
four.in.a.row(player=O, v=XEEEEE)
won(player=X, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=1, c=7)
row is = E E E E E E O
col is = O O O O X X
reverse diag is = X E E E E O
diag is = O
four.in.a.row(player=X, v=EEEEEEO)
four.in.a.row(player=X, v=OOOOXX)
four.in.a.row(player=X, v=O)
four.in.a.row(player=X, v=XEEEEO)
won(player=O, board=
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] "E" "E" "E" "E" "E" "E" "O"
[2,] "E" "E" "E" "E" "E" "E" "O"
[3,] "E" "E" "E" "E" "E" "E" "O"
[4,] "E" "E" "E" "E" "E" "E" "O"
[5,] "E" "E" "E" "E" "E" "E" "X"
[6,] "X" "X" "X" "X" "O" "E" "X"
, r=1, c=7)
row is = E E E E E E O
col is = O O O O X X
reverse diag is = X E E E E O
diag is = O
four.in.a.row(player=O, v=EEEEEEO)
four.in.a.row(player=O, v=OOOOXX)
I was mostly worried that rle won't work when I give a vector less that length 4 to it and then compare it to see if it contains a vector of length 4 of X or Os . Please let me know if the answer is not correct.
My apologies for the somewhat confusing title (any suggestion for improvement are welcome)..
Suppose I have a list which contains several (e.g. four) lists in which I would like to store 20 objects later on:
mylist <- vector(mode="list",length=4)
names(mylist) <- c("One","Two","Three","Four")
mylist$One <- mylist$Two <- mylist$Three <- mylist$Four <- vector(mode="list",
length=20)
I would like to define the names of those objects beforehand. Of course, I can do that as following:
names(mylist$One) <- c("A","B","C","D","E","F","G","H","I","J",
"K","L","M","N","O","P","Q","R","S","T")
names(mylist$Two) <- names(mylist$Three) <- names(mylist$Four) <- names(mylist$One)
But if the number of the lists would increase (as is the case in my actual data), this becomes rather cumbersome, so I was trying to do this with a function such as lapply :
mylist <- lapply(mylist,FUN=function(x) {names(x) <-
c("A","B","C","D","E","F","G","H","I","J",
"K","L","M","N","O","P","Q","R","S","T")})
This, however, does not give me the same result, but I can not seem to figure out what I am overlooking here. Any suggestions?
Thanks!
You need to return a value in your lapply call:
mylist <- lapply(mylist,FUN=function(x) {names(x) <-
c("A","B","C","D","E","F","G","H","I","J",
"K","L","M","N","O","P","Q","R","S","T")
x ## <- note the x here; you could also use return(x)
})
mylist
# $One
# A B C D E F G H I J K L M N O P Q R S T
# "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
#
# $Two
# A B C D E F G H I J K L M N O P Q R S T
# "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
#
# $Three
# A B C D E F G H I J K L M N O P Q R S T
# "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
#
# $Four
# A B C D E F G H I J K L M N O P Q R S T
# "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"
This is my implementation, which I think it produces the results you are expecting
mylist <- vector(mode="list",length=4)
names(mylist) <- c("One","Two","Three","Four")
mylist$One <- mylist$Two <- mylist$Three <- mylist$Four <- vector(mode="list",length=20)
renameList <- function(mylist,k){
names(mylist) <- LETTERS[1:k]
return(mylist)
}
mylist2 <- lapply(mylist, function(x) renameList(x,20))
# > str(mylist2)
# List of 4
# $ One :List of 20
# ..$ A: NULL
# ..$ B: NULL
# ..$ C: NULL