From 409085a754cd3e9add35a3507120bfae833430eb Mon Sep 17 00:00:00 2001 From: Matthew Henderson Date: Sat, 29 Jun 2024 18:15:43 +0100 Subject: [PATCH] Add remaining verification functions and supporting internal functions. (#21) --- DESCRIPTION | 2 +- NAMESPACE | 3 ++ R/avail.R | 11 +++++++ R/distinct-pairs.R | 12 +++++++ R/room.R | 72 +++++++++++++++++++++++++++++++++++++++++ R/see.R | 28 ++++++++++++++++ man/avail.Rd | 21 ++++++++++++ man/distinct_pairs.Rd | 17 ++++++++++ man/is_maximal_proom.Rd | 17 ++++++++++ man/is_partial_room.Rd | 17 ++++++++++ man/is_room.Rd | 17 ++++++++++ man/see.Rd | 19 +++++++++++ man/see2.Rd | 21 ++++++++++++ 13 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 R/avail.R create mode 100644 R/distinct-pairs.R create mode 100644 R/room.R create mode 100644 R/see.R create mode 100644 man/avail.Rd create mode 100644 man/distinct_pairs.Rd create mode 100644 man/is_maximal_proom.Rd create mode 100644 man/is_partial_room.Rd create mode 100644 man/is_room.Rd create mode 100644 man/see.Rd create mode 100644 man/see2.Rd diff --git a/DESCRIPTION b/DESCRIPTION index d661fa7..976aa75 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: wallis Title: Room squares in R -Version: 0.0.0.9004 +Version: 0.0.0.9005 Authors@R: person("Matthew", "Henderson", , "matthew.james.henderson@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-7949-8208")) diff --git a/NAMESPACE b/NAMESPACE index 7965d7e..5160ef5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,6 +2,9 @@ export(empty_cells) export(empty_room) +export(is_maximal_proom) +export(is_partial_room) +export(is_room) export(n_filled_cells) export(plot_room_square) export(unused_pairs) diff --git a/R/avail.R b/R/avail.R new file mode 100644 index 0000000..89543a6 --- /dev/null +++ b/R/avail.R @@ -0,0 +1,11 @@ +#' Is pair p available in R at cell e? +#' +#' @param R A partial Room square. +#' @param p A pair. +#' @param e An empty cell of R. +#' +#' @return True if and only if the pair p can be placed in cell e in R. +avail <- function(R, p, e) { + available <- R[R$row == e[1] & R$col == e[2], "avail"]$avail[[1]] + p[1] %in% available && p[2] %in% available +} diff --git a/R/distinct-pairs.R b/R/distinct-pairs.R new file mode 100644 index 0000000..b61ace0 --- /dev/null +++ b/R/distinct-pairs.R @@ -0,0 +1,12 @@ +#' Pairs used in R +#' +#' @param R A Room square. +#' +#' @return A list of the distinct pairs that appear in R. +distinct_pairs <- function(R) { + R |> + tidyr::pivot_wider() |> + dplyr::filter(!is.na(first)) |> + dplyr::filter(!is.na(second)) |> + dplyr::distinct(first, second) +} \ No newline at end of file diff --git a/R/room.R b/R/room.R new file mode 100644 index 0000000..7d55531 --- /dev/null +++ b/R/room.R @@ -0,0 +1,72 @@ +#' Is R a partial Room square? +#' +#' @param R A partial Room square. +#' +#' @return True if and only if R is a partial Room square, False otherwise. +#' @export +is_partial_room <- function(R) { + expected_number_of_distinct_pairs <- choose(max(R$col) + 1, 2) + nfc <- n_filled_cells(R) + is_row_latin(R) && + is_col_latin(R) && + n_filled_cells(R) <= expected_number_of_distinct_pairs +} + +#' Is R a Room square? +#' +#' @param R A Room square. +#' +#' @return True if and only if R is a Room square, False otherwise. +#' @export +is_room <- function(R) { + nfc <- n_filled_cells(R) + is_partial_room(R) && nrow(distinct_pairs(R)) == nfc +} + +#' Is R a maximal partial Room square? +#' +#' @param R A partial Room square. +#' +#' @return True if and only if R is a maximal partial Room square, False otherwise. +#' @export +is_maximal_proom <- function(R) { + + result <- is_partial_room(R) + + n <- max(R$col) + + R <- R |> + dplyr::mutate( + see = purrr::map2(row, col, see2, R = R) + ) |> + dplyr::mutate( + avail = purrr::map(see, setdiff, x = 0:(n - 1)) + ) + + # iterate through the set of unusued pairs trying to place them + # return true if and only if no pairs can be placed + for(p in unused_pairs(R)) { + + E <- empty_cells(R) + # try to find a hole + x <- NULL + + # iterate through empty cells in given order + for(cell in E) { + + if(avail(R, p, cell)) { + x <- cell + } + + } + + # if we were successful then this is not a maximal proom + if(!is.null(x)) { + result <- FALSE + break() + } + + } + + return(result) +} \ No newline at end of file diff --git a/R/see.R b/R/see.R new file mode 100644 index 0000000..207a6a2 --- /dev/null +++ b/R/see.R @@ -0,0 +1,28 @@ +#' Symbols visible from cell e +#' +#' @param R A Room square. +#' @param e A cell in R. +#' +#' @return A list of symbols visible in R from cell e. +see <- function(R, e) { + first <- R[R$row == e[1] | R$col == e[2], "first"]$first + first_non_na <- first[!is.na(first)] + second <- R[R$row == e[1] | R$col == e[2], "second"]$second + second_non_na <- second[!is.na(second)] + sort(unique(c(first_non_na, second_non_na))) +} + +#' Symbols visible from cell (row, col) in R +#' +#' @param R A Room square. +#' @param row A row index. +#' @param col A column index. +#' +#' @return A list of symbols visible in R from cell (col, rol). +see2 <- function(R, row, col) { + first <- R[R$row == row | R$col == col, "first"]$first + first_non_na <- first[!is.na(first)] + second <- R[R$row == row | R$col == col, "second"]$second + second_non_na <- second[!is.na(second)] + sort(unique(c(first_non_na, second_non_na))) +} \ No newline at end of file diff --git a/man/avail.Rd b/man/avail.Rd new file mode 100644 index 0000000..2320798 --- /dev/null +++ b/man/avail.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/avail.R +\name{avail} +\alias{avail} +\title{Is pair p available in R at cell e?} +\usage{ +avail(R, p, e) +} +\arguments{ +\item{R}{A partial Room square.} + +\item{p}{A pair.} + +\item{e}{An empty cell of R.} +} +\value{ +True if and only if the pair p can be placed in cell e in R. +} +\description{ +Is pair p available in R at cell e? +} diff --git a/man/distinct_pairs.Rd b/man/distinct_pairs.Rd new file mode 100644 index 0000000..d46e557 --- /dev/null +++ b/man/distinct_pairs.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/distinct-pairs.R +\name{distinct_pairs} +\alias{distinct_pairs} +\title{Pairs used in R} +\usage{ +distinct_pairs(R) +} +\arguments{ +\item{R}{A Room square.} +} +\value{ +A list of the distinct pairs that appear in R. +} +\description{ +Pairs used in R +} diff --git a/man/is_maximal_proom.Rd b/man/is_maximal_proom.Rd new file mode 100644 index 0000000..afb86db --- /dev/null +++ b/man/is_maximal_proom.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/room.R +\name{is_maximal_proom} +\alias{is_maximal_proom} +\title{Is R a maximal partial Room square?} +\usage{ +is_maximal_proom(R) +} +\arguments{ +\item{R}{A partial Room square.} +} +\value{ +True if and only if R is a maximal partial Room square, False otherwise. +} +\description{ +Is R a maximal partial Room square? +} diff --git a/man/is_partial_room.Rd b/man/is_partial_room.Rd new file mode 100644 index 0000000..8ea2c91 --- /dev/null +++ b/man/is_partial_room.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/room.R +\name{is_partial_room} +\alias{is_partial_room} +\title{Is R a partial Room square?} +\usage{ +is_partial_room(R) +} +\arguments{ +\item{R}{A partial Room square.} +} +\value{ +True if and only if R is a partial Room square, False otherwise. +} +\description{ +Is R a partial Room square? +} diff --git a/man/is_room.Rd b/man/is_room.Rd new file mode 100644 index 0000000..d0e1e57 --- /dev/null +++ b/man/is_room.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/room.R +\name{is_room} +\alias{is_room} +\title{Is R a Room square?} +\usage{ +is_room(R) +} +\arguments{ +\item{R}{A Room square.} +} +\value{ +True if and only if R is a Room square, False otherwise. +} +\description{ +Is R a Room square? +} diff --git a/man/see.Rd b/man/see.Rd new file mode 100644 index 0000000..df902f3 --- /dev/null +++ b/man/see.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/see.R +\name{see} +\alias{see} +\title{Symbols visible from cell e} +\usage{ +see(R, e) +} +\arguments{ +\item{R}{A Room square.} + +\item{e}{A cell in R.} +} +\value{ +A list of symbols visible in R from cell e. +} +\description{ +Symbols visible from cell e +} diff --git a/man/see2.Rd b/man/see2.Rd new file mode 100644 index 0000000..2ff029b --- /dev/null +++ b/man/see2.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/see.R +\name{see2} +\alias{see2} +\title{Symbols visible from cell (row, col) in R} +\usage{ +see2(R, row, col) +} +\arguments{ +\item{R}{A Room square.} + +\item{row}{A row index.} + +\item{col}{A column index.} +} +\value{ +A list of symbols visible in R from cell (col, rol). +} +\description{ +Symbols visible from cell (row, col) in R +}