设计一种压缩算法,专门用于压缩ASCII迷宫。您需要同时创建压缩算法和解压缩算法。你的分数将基于你的压缩迷宫的大小。
这些迷宫主要由字符(地板)、+、-、|和# (墙壁)组成,而^ (开始)和$ (结束)恰恰各有一个。它们也可能包含ASCII字母,这些字母可以算作地砖。就这项挑战而言,迷宫不一定是可解的,迷宫内容的实际意义也是无关紧要的。
+将用于至少有一个水平相邻壁单元和至少一个垂直相邻壁单元的壁单元。|将用于至少有一个垂直相邻的壁单元,但没有水平相邻的壁单元的壁单元。-将用于至少有一个水平相邻的壁单元,但没有垂直相邻的壁单元的壁单元。#只用于不与其他壁单元正交相邻的壁单元。所有的迷宫都是矩形的,但不一定有规则的网格/墙壁排列。
迷宫1
+----+----
| o | |
| -- | o--+
| | | $
--^-+-+---迷宫2
+-----+---+
| a | |
^ +-+-+ # |
| | | B |
| | | --+ |
| c | $
+-------+--迷宫3
----------+-+-+-----+-+
^ | | | | |
+-- --+R # | |p| | | |
| | | | | |
+---+ +-+-+-- +-+ | | |
| m| | | | | | | |
| +-+ | | | | | --+ | |
| | | h | | | | |
| | | | | | # --+-+ |
| | | | | | S| $
+-----+-+-+-+-+---+----迷宫4
+-----+---+-+---+-------^-----+
| |x | | | tsrq |
+-+-- +-- | +-- # --+---- --+
| | | | | |
| | | | | +-+-+---+ | +-- | +-+
| | | u | | | | | | | | |
| +-+ | | | | +---- +-+---+ | |
| | | | | y | w |
| | --+ | --+ +-- | +---- | | |
| | | | | | | | | |
+-- --+ +-+ | | | | +-- | +-+-+
| | | | | | | | | |
$ | --+-+ | --+-+ | +-+-+-- --+
| | | z| | | v |
+-+---+-------+---+---+-------+迷宫5
++ -----------+
++- Beep|
$ ----+---+--+
+-+boop| | |
| +--- | | | ++
| | | +++
+------+-+--+ ^迷宫6
+-$---------------+-+--
| | |j
| |l ---- # ---+ | |
| | | m | +--+ |
| | | +-+---- # |
| | | | | +----+ |
|o| | | | +----+ | |
| | | | -- | |
| | | | | | -+ | | |
| | | | | | | +--- | |
| | | | +- | | | | ++
+-+ |n| | | ++ +--+ |
| | -+- | | | +-
+---+ +--- | | | ^
| | --+ --+ | |
| -- | | k | | ++
| | | +--- | ++
| | | | | |
+-- -+---- | +----+--+迷宫7
+---+-+-------------+-+^+-----+-------+---+-+---+-+---+-+---+
| |c| | | | c | | | | | | |c| |
+-- | | +-- +-- # | | | +-- --+ +---- +-- | +-+ | | +-+ | --+
| | | | | | | | |c| | |
| | +-- | +-+-- +-+ +-- # +- # -+-- +-- | | --+ | | | | --+C|
|c| | | | c | | |c | | | |
+-+-+---+-+-----+---------+---------+---+-------------+---+$|迷宫8
------+-+-+---+-+---+-----------+---+-----+---------------+-+
^ | | | | | | | | | r | |
+-- | | | t | | +-- +----- # ---+-- +-- --+-- ----+-+ --+ | |
| | | | | | | r | | | | | |
| | | | | +-+ --+ --+-- --------+-- | ----+ --+ | | | --+ | |
| |r| | rotation | | | | | | $
+-+-+-+-----------------------------------+---+-+---+---+-+--迷宫9
|$|^--+-+---+-----+-+---+-+-+---+---+-+---+-----+
| | | | | | | | | | f | | | | |
| +-+ | | # +-+ --+ +-+ | | | # | +-+ +-- | ----+
| | | | f| | | | | | f |
| |F+-+ | | | | +---+ | | | ----+-+ | | --+ --+-+
| | | | | | | | | f | | | |
| | | | +-+-+---+-- | | | +-+-+-+ +-+ +--- # -+ |
| | | | | | | | | | | | | | |
+-+-+ | +---+ --+ | +---+-+ | | --+ f | | | | --+
| | | | | | | | | |
| --+f| | | +-- --+--f--+ --+ | ----+ | +-+ +---+
| | | | | | | | | |
+---+-----+-+-----+-----+---+-+-----------+-----+迷宫10
+-----+-+-----------+
| q | | q |
|Q+-+ | +-+-+-+---- |
$ | | | | | q |
+-+ | | | | | +-- +-+
| | | | | | |
| +-- +-+ |q| +-+ | |
| q| | | | |
| | | +-- | +-+ | --+
| | | | | | | |
+-+-+-+ +-+-+ +-- | |
| | | |
+--- # -+ | | +-- | |
| q | | | | ^
+-+ +-- | | +-+ | +-+
| | | | |q| | |
| +-+-+ | +-+-- | | |
| | | | | | |
| | | +-+-+-- +-+ +-+
| | | | q |
+-+-+---------+-----+发布于 2019-03-17 10:34:46
这利用了这样一个事实:墙的特征是由它周围的环境决定的。因此,墙字符可以编码为位。需要存储的其余信息是迷宫的尺寸、开始和结束的位置以及任何其他非墙壁字符的位置。由于非墙壁字符是ASCII,我使用了每个字节中最重要的部分来指示是否有另一个字符在后面,这样迷宫中的一些单词就不必单独存储每个字符的位置。还请注意,对于小于或等于256个字符的迷宫(例如,多达16x16个或等效的矩形迷宫),位置可以存储在一个字节中,而对于较大的迷宫,位置需要两个字节。
r <- as.raw
int_as_raw <- function(int, bytes = 2) {
if (bytes == 1) {
r(int)
} else {
do.call(c, lapply(int, function(.x) r(c(.x %/% 256, .x %% 256))))
}
}
raw_as_int <- function(raw, bytes = 2) {
if (bytes == 1) {
as.integer(raw)
} else {
sapply(
seq(1, length(raw) - 1, 2),
function(.x) as.integer(as.integer(raw[.x + 0:1]) %*% c(256, 1))
)
}
}compress_maze <- function(maze) {
maze_array <- do.call(rbind, strsplit(maze, ""))
simple_maze <- r(maze_array %in% c("+", "#", "-", "|"))
simple_maze <- packBits(c(simple_maze, rep(r(0), (8 - length(simple_maze)) %% 8)))
maze_dim <- int_as_raw(dim(maze_array), 1)
bytes_needed <- 1 + (length(maze_array) > 256)
start_finish <- int_as_raw(sapply(c("^", "$"), function(.x) which(maze_array == .x)) - 1, bytes = bytes_needed)
other_ascii_locs_rle <- rle(!(maze_array %in% c(" ", "+", "#", "-", "|", "$", "^")))
other_ascii_locs <- cumsum(
c(1, other_ascii_locs_rle$lengths[-length(other_ascii_locs_rle$lengths)])
)[other_ascii_locs_rle$values]
other_ascii_locs_length <- other_ascii_locs_rle$lengths[other_ascii_locs_rle$values]
encode_ascii <- function(loc, len) {
text <- charToRaw(paste(maze_array[loc:(loc + len - 1)], collapse = ""))
if (len > 1) {
text[1:(len - 1)] <- text[1:(len - 1)] | r(128)
}
c(int_as_raw(loc - 1, bytes = bytes_needed), text)
}
other_ascii_encoded <- Map(encode_ascii,
other_ascii_locs,
other_ascii_locs_length
)
other_ascii_encoded <- do.call(c, other_ascii_encoded)
c(maze_dim, simple_maze, start_finish, other_ascii_encoded)
}decompress_maze <- function(c_maze) {
dim_maze <- as.integer(c_maze[1:2])
len_maze <- prod(dim_maze)
len_maze_b <- ceiling(len_maze / 8)
bit_maze <- rawToBits(c_maze[-(1:2)])[1:len_maze]
dim(bit_maze) <- dim_maze
bit_maze[-1, ] <- bit_maze[-1, ] | rawShift(bit_maze[-nrow(bit_maze), ] & r(1), 1)
bit_maze[-nrow(bit_maze), ] <- bit_maze[-nrow(bit_maze), ] | rawShift(bit_maze[-1, ] & r(1), 1)
bit_maze[, -1] <- bit_maze[, -1] | rawShift(bit_maze[, -ncol(bit_maze)] & r(1), 2)
bit_maze[, -ncol(bit_maze)] <- bit_maze[, -ncol(bit_maze)] | rawShift(bit_maze[, -1] & r(1), 2)
bit_maze[(bit_maze & r(1)) == r(0)] <- r(0)
array_maze <- c(" ", "#", "|", "-", "+")[(as.integer(bit_maze) + 1) %/% 2 + 1]
dim(array_maze) <- dim_maze
bytes_needed <- 1 + (len_maze > 256)
start_finish <- raw_as_int(c_maze[2 + len_maze_b + 1:(bytes_needed * 2)], bytes_needed) + 1
array_maze[start_finish] <- c("^", "$")
i <- 3 + len_maze_b + 2 * bytes_needed
while (i < length(c_maze)) {
loc <- raw_as_int(c_maze[i + 1:bytes_needed - 1], bytes_needed) + 1
i <- i + bytes_needed
text <- character(0)
while (c_maze[i] & r(128)) {
text <- c(text, rawToChar(c_maze[i] & r(127)))
i <- i + 1
}
text <- c(text, rawToChar(c_maze[i]))
array_maze[loc:(loc + length(text) - 1)] <- text
i <- i + 1
}
apply(array_maze, 1, paste, collapse = "")
}https://codegolf.stackexchange.com/questions/181556
复制相似问题