铁路围栏密码摆脱循环重复[关闭]
Posted
技术标签:
【中文标题】铁路围栏密码摆脱循环重复[关闭]【英文标题】:Rail fence cipher get rid of loop-recur [closed] 【发布时间】:2022-01-22 00:48:27 【问题描述】:我在 Clojure 中有这个带有加密和解密功能的围栏密码。我需要摆脱循环重复。如何摆脱 loop-recur 让它更优雅?感谢您的帮助。
(defn rail_fence_cipher [type key text]
(let [counter (* 2 (dec key))
groups (map
(fn [index]
(take-nth
counter
(drop index (range))))
(range counter))
encrypt-text
(take
(count text)
(loop [x (rest groups)
encrypt-text (take-while
#(> (count text) %)
(first groups))]
(if
(= 1 (count x))
(concat encrypt-text (last x))
(recur
(rest (drop-last x))
(concat
encrypt-text
(take-while
#(> (count text) %)
(interleave (first x) (last x))))))))
decrypt-text (->> encrypt-text
(map-indexed vector)
(sort-by second)
(map first))]
(cond
(= type "encrypt")
(apply str
(map #(nth text %) encrypt-text))
(= type "decrypt")
(apply str
(map #(nth text %) decrypt-text))
:else
"Please enter a valid cipher mode.")))
【问题讨论】:
请添加您尝试这样做的代码,以便我们对其进行改进。此外,如果此版本给您错误/堆栈跟踪/...请将它们添加到问题中。如果此版本有效并且您想删除循环/重复,它也将有助于您为什么要删除它以及您认为最好使用什么。 带有cmets的原始代码是here 【参考方案1】:风格说明:
Clojure 使用 kebab-case,而不是 snake_case。cond
可以替换为 case
或 condp
。
您的函数非常长且难以阅读 - 您应该将其拆分为更多部分。
参数名称可能更具描述性 - key
实际上是轨道数。
入口点可以改写为:
(defn rail-fence-cipher [action rails text]
(case action
"encrypt" (encrypt text rails)
"decrypt" (decrypt text rails)
"Unknown action."))
第一部分可以在没有recur
的情况下重写为:
(defn rails-pattern [rails]
(concat (range rails)
(drop 1 (range (dec rails) 0 -1))))
(defn encrypt [text rails]
(->> (clojure.string/replace text #" " "")
(map vector (cycle (rails-pattern rails)))
(sort-by first)
(map second)
(clojure.string/join)))
示例(来自Wikipedia):
(encrypt "WE ARE DISCOVERED RUN AT ONCE" 3)
=> "WECRUOERDSOEERNTNEAIVDAC"
【讨论】:
以上是关于铁路围栏密码摆脱循环重复[关闭]的主要内容,如果未能解决你的问题,请参考以下文章