【Clojure】在loop-recur中实现多重循环

理解clojure语法(1) 然后counter被绑定到匿名函数`#(swap! tick inc)`的地址。 当counter绑定完之后,每次调用counter :`(counter)` 解释器就会找到counter ,也就是匿名函数的那个地址,然后调用它,就相当于执行了匿名函数 `#(swap! tick inc)`,也就是给tick的值加1 阅读详情

问题

在loop-recur中实现多重循环(里:如何造一个轮子)

描述

在loop-recur中使用一个N重循环是很痛苦的(脑细胞在燃烧),这时候可以使用一个生成N重循环下标列表的工具,在loop-recur中实现多重循环

代码

(defn smooth
  [cur config]
  (let [cur (reverse cur) 
        config (reverse config) 
        ps (map #(list % %2) cur config)]
    (loop [carry 0 
           head (first ps) 
           tail (rest ps)
           ret '()]
      (if (nil? head)
        ret
        (let [[x y] head
              the-carry (quot (+ carry x) y)
              the-rest (mod (+ carry x) y)] 
          (recur the-carry (first tail) (rest tail) (conj ret the-rest)))))))

; only for test!
(smooth (map + [1 2 3] [3 9 9]) [10 10 10]) 
(smooth (map + [1 2 3] [1 1 1]) [10 10 10]) 
(smooth [0 2 2] [2 2 2])                    

(defn smooth-ex
  [numbers limits]
  (let [numbers (reverse numbers)
        limits (reverse limits)
        pairs (map #(list % %2) numbers limits)]
    (loop [carry 0
           head (first pairs)
           tail (rest pairs)
           ret '()]
      (if (nil? head)
        ret
        (let [[number limit] head
              the-carry (quot (+ carry number) limit)
              the-rest (mod (+ carry number) limit)] 
          (recur the-carry (first tail) (rest tail) (conj ret the-rest)))))))

(defn looper-unit
  [looper]
  (if (= (count looper) 0)
    '()
    (let [zero-cnt (dec (count looper))]
      (into '(1) (repeat zero-cnt 0)))))

(defn is-looper-end?
  [looper looper-end]
  (= (map inc looper) looper-end))

(defn looper-next
  [looper looper-end]
  (smooth (map + looper (looper-unit looper)) looper-end))

(defn looper-demo
  [looper-end]
    (loop [looper (repeat (count looper-end) 0) ret []]
     (let [[i j] looper looper-string (str "row:" i " " "col:" j)]
       (if (is-looper-end? looper looper-end)
         (ret conj looper-string)
         (recur (looper-next looper looper-end) (conj ret looper-string))))))

; just for test!
(map println (looper-demo [3 3]))

说明

smooth : 类似大数加法中的进位操作,处理循环中下标的进位操作

smooth-ex : smooth 的容易阅读的版本 …

looper-unit : 生成循环的递增单位,即一个形如 (0 ... 0 1) 的列表, 可能不含0

其他函数顾名思义,不解释了

核心思想即产生一系列列表,例如一个二重循环:

for(int i = 0; i < 2; ++i) 
    for(int j = 0; j < 2; ++j) 
        { /* excuse me */}

其下标对应的序列为:

[ (0 0) (0 1) (1 0) (1 1) ]

那么对于任意循环,我们只需要生成该列表组就可以进行循环操作, 那么在哪里可以买到呢:

注意 (0 0) 到 (0 1) 的变化过程:

(= '(0 1) (map + '(0 0) '(0 1)))

而 (0 1) 到 (1 0) 的变化过程则较为复杂,但这一变化可以看作二进制下 01 + 01 => 10 的过程

宗上可以看出,生成列表的过程可以看作是一个N进制数字自增的过程,特别的是这里的每一个位可能对应不同的进制(比如上面那个循环把j的限制改成 j < 100, 就变成了i是2进制,j是100进制的自增过程)

利用这一性质产生了如上的编码(轮子),具体使用方法参考 looper-demo, 配合解构操作可以顺利获得各循环变量, 然后瞎鸡巴乱搞

最后需要注意的是,对循环的限制是左闭右开区间, (looper-end [5 5]) 得到的是一个 0-4 的二重循环

clojure多行注释太麻烦了,最后补上 (map println (looper-demo [3 3])) 的输出结果

; 不是代码 仅供参考

=> (map println (looper-demo [3 3]))

row:0 col:0
row:0 col:1
row:0 col:2
row:1 col:0
row:1 col:1
row:1 col:2
row:2 col:0
row:2 col:1
row:2 col:2
(nil nil nil nil nil nil nil nil nil)

; 最后的一串nil是prinln的返回值被map收集了, 因为这里我们需要的是副作用
clojure-grpc-example:在Clojure中使用GRPC的最小示例 clojure-grpc-示例 这是如何在Clojure中进行GRPC调用的演示。 目前,这仅涵盖最基本的用例。 这将使用mount启动服务器。 用法 运行gradle build从proto文件生成Java类。 服务器从core.clj的(mount/start) 在client.clj运行客户端。 注意 一些帮助程序代码来自Captial One 。 执照 版权所有:copyright:2017 FIXME 根据Eclipse公共许可证1.0版或(可选)任何更高版本分发。 立即下载

相关推荐

国央企创新负责人如何通过平台实现科研成果的快速识别与转化?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

clojure-程序流程二

函数式循环 while loop/recur Clojure没有传统的for循环,程序可以通过使用高阶函数实现类似的行为 Clojure版本的循环流程使用loop和recur 上图定义了一个函数fact-loop 传入参数n 然后loop循环 首先通过let形式,将n绑定到current,将1绑定到fact 之后通过if判断current是否等于1 等于1则返回fact 如果不等于1...

itaha的博客 197

HTB_Bike靶机之模板注入

船到桥头自然直 文章目录信息收集模板引擎SSIT 模板注入后放答案 信息收集 日常 A 扫描,两个端口 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA) | 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:.

网络安全学习 797

Clojure - Loop/Recur

You may need to understand if and let to fully grasp recursion in Clojure. for and while Clojure does not have for loops or while loops. This makes sense, if you think about it. A for loop c

DViewer的专栏 652

HBM PHY 架构解析:从主控模块到DWORD设计的深度探索

本文深入解析了HBM PHY的完整架构,从作为系统大脑的PUB主控模块出发,详细阐述了其CSR控制、初始化与训练引擎的核心功能。进而剖析了负责命令传输的AWORDX2模块与作为数据高速公路的DWORD模块的设计奥秘,包括其双向数据流、精密时钟对齐与延迟线校准机制。最后,探讨了顶层MASTER PHY的整合作用及从DFI到DRAM的完整数据通路,为理解这一高性能内存接口的关键物理层设计提供了全面视角。

weixin_29306011的博客 294

Innovus快捷键大全:从入门到精通的效率提升指南

本文是Innovus快捷键从入门到精通的效率提升指南,旨在帮助芯片后端设计工程师通过掌握核心快捷键,将重复性鼠标操作转化为高效的肌肉记忆,从而显著提升版图设计、编辑和分析的工作流速度。文章系统讲解了视图导航、对象选择编辑、流程管理等关键快捷键组合,并提供了个性化配置与实战策略,助力工程师突破效率瓶颈,实现人机合一的流畅设计体验。

silver的专栏 797

Clojure的recur尾递归优化探秘

Clojure由于是基于JVM,同样无法支持完全的尾递归优化(TCO),这主要是Java的安全模型决定的,可以看看这个久远的bug描述。但是Clojure和Scala一样支持同一个函数的直接调用的尾递归优化,也就是同一个函数在函数体的最后调用自身,会优化成循环语句。让我们看看这是怎么实现的。 Clojure的recur的特殊形式(speci...

weixin_34279184的博客 266

【CV论文精读】【协同感知综述】Collaborative Perception for Autonomous Driving :Current Status and Future Trend

感知是自动驾驶系统的关键模块之一,近年来取得了很大进展。然而,单个车辆的有限能力导致感知性能提高的瓶颈。为了突破个体感知的局限,协作感知被提出,它使车辆能够共享信息来感知视线和视野之外的环境。本文综述了有前途的协作感知技术的相关工作,包括介绍了基本概念,概括了协作模式,总结了协作感知的关键要素和应用。最后,我们讨论了这一研究领域面临的挑战和问题,并给出了一些潜在的进一步方向。

weixin_44184852的博客 4689

Clojure语法学习-循环

do和块语句 在Scala中,花括号{}括起来的语句构成一个block,它的值就是最后一个语句的值。 scala> val a = { | println("a") | 1} a a: Int = 1 {println("a"); 1}的值为1。 在Clojure中,有时需要使多个form组成一个block, 这个block的值是最后一个for...

weixin_30819163的博客 163

Win11家庭版彻底关闭Hyper-V的3种方法(实测有效)

本文详细介绍了Win11家庭版彻底关闭Hyper-V的3种实测有效方法,解决与VMware的兼容性问题。包括命令行禁用虚拟化功能、微软官方工具DG_Readiness深度清理以及组策略与功能组件联用方案,帮助用户高效禁用Hyper-V并优化系统性能。

weixin_33728268的博客 2670

【C语言】初识C语言(上篇)

初识C语言第一部分

StackFrame 4009

clojure中的小细节

1.&可变参数(defn add [v1 v2 & others] ;;&后面的是可变参数 (+ v1 v2 (if others ;;判断可变参数列表是否是空,如果不是累加列表中的值,否则返回0 (reduce + 0 others) ;;使用reduce函数计算others的数字之和。 0 ) ) )2.defn - (defn -name & decls)作用和defn类似,唯一的不同是创

小小八卦姐的专栏 1563

matlab从无到有系列(九):Simulink基础仿真详解(全网最全,从入门到放弃)

🔗 运行环境:Matlab 🚩 作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 📚 选自专栏:《数学建模》 🧿 优秀专栏:《Matlab神经网络案例分析》 目前持续更新的专栏: 🥇 专栏:Matlab GUI编程技巧 🔥 专栏:Matlab从无到有系列 📚 专栏:《数学建模》 💗 大家好,我是左手の明天!💗 📆 最近更新:2022 年 4 月 2 日,左手の明天的第215 篇原创博客 🌟🌟往期必看🌟🌟 matlab从无到有系列(二):矩阵运算基础...

左手の明天的博客 9万+

grill-me 使用教程:4 轮提问,把模糊想法变成敢拍板的决策

你有个半成型的想法,让 AI 写了份计划,读着读着发现每段都是"如你所言"。计划很自信,你很心虚。grill-me 是 Skills for Real Engineers 仓库里的访谈技能:它不替你写计划,只按轮次向你发问,问完你手里才会有一份真正出自你手的决定。 ## 一句话判断:5 种场景,何时用 grill-me、何时别用 先看想法处于什么状态,再挑流程: | 场景 | 工具 | 区别

gitblog_00289的博客 493

【现代人形机器人:从物理建模到大模型驱动的控制与学习】第1章 机器人建模回顾

本章建立读者进行后续控制 / 优化 / 学习工作的数学与计算基础。内容分为三大块:刚体运动学:位姿表示、坐标变换、旋转参数与李代数/李群(指数映射、twist)多关节机构的正/逆运动学:DH 与 POE 两种建模、雅可比矩阵推导、数值/解析逆解方法与奇异性问题约束动力学:拉格朗日公式、牛顿—欧拉递归算法、接触/冲击模型、受约束系统的方程(拉格朗日乘子与互补性条件)每一节同时给出与练习题。假设读者已具备线性代数(矩阵、特征分解、SVD)、多变量微积分与基础力学(牛顿第二定律)知识。

u012133341的博客 185

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

理解clojure语法(2)

注:本文长期更新 本文梳理一些clojure的常用知识点,惯用法?maybe 1.#'表示取得变量对象本身,var-quote (#') #'x ⇒ (var x)这是#的一个reader宏,作用是: get Var object instead of the value of a symbol (var-quote), . The reader macro #’x expands to (

yin_wuzhe的专栏 6037

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Clojure的recur

因为clojure的首要平台依然是JVM,而JVM对尾递归和LCO/TCO都没有支持,所以clojure引入了一个 recur spec-form。 recur 其实就是函数内的goto,感觉实在是很受限。 JVM啥时候发力把以上的缺陷都改进就好了。 或者Clojure移植到LLVM平台。 YY一下。。。...

Linker Lin的Blog 373

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Clojure 学习入门(14)—— 循环控制

一、基于函数的流程控制 repeatedly: repeatedly字面意思为重复函数。一般的用法如下: Java代码  user=> (repeatedly 5 #(rand-int 11))  (6 8 2 6 6)  重复产生5次随机数。rand-int 11表示0至11的随机数。 这里顺便提一下repeat函数:repeat函数接受一/两个常量参数,用法如下: Java代码  user=>

阳光岛主 1万+

Clojure语言九:for循环

宏for可以支持循环下面继续前面的xml的例子,演示如何用for遍历xml-seq返回的sequence.user=> (for [x r] (println "^" x)) (^ {:tag :service, :attrs nil, :content [{:tag :mongodb, :attrs nil, :content [{:tag :uri, :attrs nil, :content

Dean Chen的专栏 4689

Clojure循环-----Doseq循环和for循环的区别

Clojure的循环在clojure编程之路占着重要地位,然而在使用循环的时候,一不小心就是一个大坑!!!新手的我就是踩了很大的坑,折腾得我午饭读没吃好。。。。。 1、 Clojue循环有哪些? S.no 方法和说明 1 While循环 :'while’语句通过首先计算条件表达式(一个布尔值)来执行,如果结果为真,则执行while循环中的语句 2 Doseq循环 : '...

smile_68的博客 634

Clojure API之数组操作

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33860737的博客 352

Clojure遍历数组

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33924220的博客 379

clojure-基本语法-流程控制(一)

[b][color=red]一、标准的流程控制[/color][/b] if: 将一个判断表达式作为它的第一个参数进行求值。如果求值为true,那么就返回它的第二个参数(相当于“then”子句)的求值结果。如果结果为false(包括nil)就返回第三个参数的求值结果(相当于“else”子句),前提是有提供第三个参数并且不为空。 [code="java"] user=> (defn is-s...

Dead_Knight的专栏 341

clojure入门(一)-- 综述和预备知识

该部分包括:   Clojure语言基础  表达式,标识符(locals,vars)  let forms  函数  基本数据类型  不可变数据结构入门  Clojure应用类型总览(vars,atoms,agents,refs)  循环和递归  Clojure宏入门  该项目遵循Creative Commons Attribution 3.0 UnportedLicense (包

Dead_MIcKy 1204

clojure/core comp

点我查看原文及更多示例 (ns $clojureDoc.core.comp) ;; 使用方法:(comp)(comp f)(comp f g)(comp f g & fs) ;; Takes a set of functions and returns a fn that is the composition ;; of those fns. The returned fn take...

ningDr的博客 221

java outterLoop跳出多重循环写法

public static void main(String[] args) { outterLoop: for (int i = 0; i &lt; 17; i++){ for (int j = 0; j &lt; 16; j++){ // …… break outterLoop; ...

榴莲真的香吗 1674
上一篇: 【Java】深夜代码祭(2)
下一篇: 【JavaScript】call, apply, bind
古明地觉
博客等级 码龄15年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值