Julia
using Test
##################################
# 解法一
##################################
"""
rules是依赖于一个初始化容器的
"""
#> "rules是依赖于一个初始化容器的\n"
gender_rules(output::Vector{Int64})::Dict{Char,Function} =
Dict(
'i' => x -> x + 1,
'd' => x -> x - 1,
's' => x -> x^2,
'o' => x -> push!(output, x)[end]
# 一行内既改变了output又返回了x
)
#> gender_rules (generic function with 1 method)
function deadfish1(commands::String)::Vector{Int64}
# initialize
x = 0
output = Int64[]
# gender rules
rules = gender_rules(output)
# operation
valid_commands = filter(∈("idso"), commands)
for c in valid_commands
x = rules[c](x) # 串行loop
end
return output
end
#> deadfish1 (generic function with 1 method)
@test deadfish1("iiisxxxdoso") == [8, 64]
#> Test Passed
#> Expression: deadfish1("iiisxxxdoso") == [8, 64]
#> Evaluated: [8, 64] == [8, 64]
##################################
# 解法二
##################################
# 写成返回两个值的函数,dict独立为不依赖其他变量的const
# 更彻底地解耦,使程序易于维护
const rules2 = Dict{Char,Function}(
'i' => (x, arr) -> (x + 1, arr),
'd' => (x, arr) -> (x - 1, arr),
's' => (x, arr) -> (x^2, arr),
'o' => (x, arr) -> (x, push!(arr, x))
)
#> Dict{Char, Function} with 4 entries:
#> 'd' => #54
#> 'i' => #53
#> 's' => #55
#> 'o' => #56
function deadfish2(commands::String)::Vector{Int64}
# initialize
x = 0
output = Int64[]
# operation
valid_commands = filter(∈("idso"), commands)
for c in valid_commands
x, output = rules2[c](x, output) # 串行操作
end
return output
end
#> deadfish2 (generic function with 1 method)
@test deadfish2("iiisxxxdoso") == [8, 64]
#> Test Passed
#> Expression: deadfish2("iiisxxxdoso") == [8, 64]
#> Evaluated: [8, 64] == [8, 64]
R
library(tidyverse)
library(magrittr)
# 写成返回两个值的函数,避免定义全局变量arr obj 包含两个分量:整数 n 和数组 arr
dict <- list(i = function(obj) list(n = obj$n + 1, arr = obj$arr), d = function(obj) list(n = obj$n -
1, arr = obj$arr), s = function(obj) list(n = obj$n^2, arr = obj$arr), o = function(obj) list(n = obj$n,
arr = c(obj$arr, obj$n)))
deadfish <- function(commands) {
valid_commands <- commands %>%
str_split("") %>%
unlist() %>%
keep(~.x %in% c("i", "d", "s", "o"))
# 此处不用 reduce 用 for 循环会更加清楚
obj <- list(n = 0, arr = integer(0))
for (char in valid_commands) {
obj <- dict[[char]](obj)
}
obj$arr
}
library(testthat)
test_that("Unit Test", {
expect_equal(deadfish("iiisxxxdoso"), c(8, 64))
})
#> Test passed 😀
JavaScript
const dict = new Map()
.set('i', ({ n: k, output: arr }) => ({ n: k + 1, output: arr }))
.set('d', ({ n: k, output: arr }) => ({ n: k - 1, output: arr }))
.set('s', ({ n: k, output: arr }) => ({ n: k ** 2, output: arr }))
.set('o', ({ n: k, output: arr }) => ({ n: k, output: arr.concat(k) }));
function parse(data) {
let result = data.split("")
.filter(c => "idso".includes(c))
.reduce(
callBack = (obj, c) => dict.get(c)(obj),
initialValue = { n: 0, output: [] }
);
return result.output;
}
console.log(parse("iiisxxxdoso")); // [8, 64]
#> [ 8, 64 ]