Description

Solutions

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 ]