Racket 版本的 24 点实现

#lang racket

; Author: woodfox
; Date: Oct 11, 2014 ; ==================== 1. Non-determinism implementation for Racket ==================
; refer to <On Lisp> by Paul Graham
(define *paths* '())
(define failsym '@)
(define (choose choices)
(if (null? choices)
(fail)
(call-with-current-continuation
(lambda (cc)
(set! *paths*
(cons (lambda ()
(cc (choose (cdr choices))))
*paths*))
(car choices)))))
(define fail '())
(call-with-current-continuation
(lambda (cc)
(set! fail
(lambda ()
(if (null? *paths*)
(cc failsym)
(let ((p1 (car *paths*)))
(set! *paths* (cdr *paths*))
(p1)))))))
; ==================== Non-determinism implementation ENDs ============== ; ========= 2. implement permute function ==================================
; refer to: http://stackoverflow.com/questions/4180101/creating-an-n-sized-permutation-with-scheme-using-only-basic-constructs
(define (seq start end)
(if (= start end)
(list end) ; if start and end are the same number, we are done
(cons start (seq (+ start 1) end)))) (define (insert cdrList n carItem)
(if (= 0 n)
(cons carItem cdrList) ; if n is 0, prepend carItem to cdrList
(cons (car cdrList)
(insert (cdr cdrList) (- n 1) carItem)))) ; (map (lambda (n)
; (insert '(b c) n 'a))
; '(0 1 2)) -> output of seq function given n = 2, which is length of '(b c)
; '((a b c) (b a c) (b c a)) ---> will be the output (define (permute mylist)
(if (null? mylist)
'(())
(apply append (map (lambda (plist)
(map (lambda (n)
(insert plist n (car mylist)))
(seq 0 (length plist))))
(permute (cdr mylist)))))) ;(permute '(a b c)) ; ========= permute function implemenetation END ========= ; ================ Calculate 24 implementation ===================
(define operators '(+ - * /)) (define-syntax-rule (mytest a b c d f1 f2 f3)
(let ((combinations (list `(,f3 (,f1 ,a ,b) (,f2 ,c ,d))
`(,f3 (,f2 (,f1 ,a ,b) ,c) ,d)
`(,f3 (,f2 ,a (,f1 ,b ,c)) ,d)
`(,f3 ,a (,f2 (,f1 ,b ,c) ,d))
`(,f3 ,a (,f2 ,b (,f1 ,c ,d))))))
(let ((expr (choose combinations)))
(with-handlers ([exn:fail:contract:divide-by-zero?
(lambda (exn) (fail))])
(if (= 24 (eval expr))
(displayln expr)
(fail)))))) (define (calc24 nums)
(let ((nums2 (choose (permute nums))))
(let ((a (car nums2))
(b (cadr nums2))
(c (caddr nums2))
(d (cadddr nums2))
(f1 (choose operators))
(f2 (choose operators))
(f3 (choose operators)))
(mytest a b c d f1 f2 f3))))

真正跟 24点逻辑相关的是最后一小段, “Calculate 24 implementation” 注释开始后的代码,代码不多。

前面都是准备工作,一小段代码实现了不确定性计算的自动回溯功能;

另一小段代码是实现了全排列的辅助函数。

测试:

欢迎使用 DrRacket, 版本 5.3.3 [3m].
语言: racket; memory limit: 128 MB.
> (calc24 '(4 5 6 7))
(* 4 (+ (- 5 6) 7))
> (fail)
(* 4 (- 5 (- 6 7)))
> (fail)
(* (+ (- 5 6) 7) 4)
> (calc24 '(3 3 8 8))
(/ 8 (- 3 (/ 8 3)))
>

每次调用可以输出一个解。如果想要更多的解,执行一次 (fail) 函数就可以了,每执行一次会自动回溯,找到下一个解,直到无解为止。

在用 '(3 3 8 8) 这个例子尝试的时候,顺带发现了前面 Haskell 版本写的一个 bug, 即:

想当然的以为全排列后每次取到的4个数应该不一样,因此把有重复数字的情况都排除掉了,求不到解。

这个 Racket 版本在做的时候,顺带修正了这个 bug.

回头晚一点把 Haskell 的也 fix 一下。

完毕。

Racket 版本的 24 点实现的更多相关文章

  1. C# 版本的24点实现

    C# 版本的24点实现. 已经实现基本功能,可以正确的算 3, 3, 8, 8 这类组合. 稍加修改就可以支持任意数目的操作数和操作符组合形成的四则运算表达式,不限于24点. 代码还比较简单粗糙,晚一 ...

  2. 团队作业4--第一次项目冲刺(Alpha版本)预备工作

    小组说明 我们组是从周一开始对项目进行研究讨论并编程的,因为我们看截止日期是周日,就从周一才开始,起步晚了,是我们认识上的失误,导致我们周一周二的步伐没有协调好,项目进展的不稳定,但是我们在上周末并不 ...

  3. ESP-IDF版本2.1.1

    版本2.1.1是一个错误修复版本.它包括对KRACK和BlueBorne漏洞的修复. 版本2.1.1的文档可在http://esp-idf.readthedocs.io/en/v2.1.1/上找到. ...

  4. Android 7.0以上版本 系统解决拍照的问题 exposed beyond app through ClipData.Item.getUri()

    解决方案1: android.os.FileUriExposedException: file:///storage/emulated/0/ilive/images/photophoto.jpeg e ...

  5. 交叉编译OpenCV的Android版本

    交叉编译OpenCV的Android版本 OpenCV作为一个强大的图像处理库,在Android上也有强大的应用. OpenCV官网提供了SDK的下载,可以直接下载使用 OpenCV官网地址:http ...

  6. selenium:chromedriver与chrome版本的对应关系

    转自:http://blog.csdn.NET/huilan_same/article/details/51896672 再使用selenium打开chrome浏览器的时候,需要用chromedriv ...

  7. 四、10分钟ToPandas_0.24.2

    # Author:Zhang Yuan整理,版本Pandas0.24.2 # 0. 习惯上,我们会按下面格式引入所需要的包: import pandas as pd import numpy as n ...

  8. OpenCV.3.4.6_VS2015&cmake编译x86版本的bin&lib

    ZC:<<OpenCV3编程入门>> 的 2.2.2 中也有该内容的讲解 1.参考网址:opencv3.3.0+vs2015+cmake编译opencv x86 - wowo的 ...

  9. PDF 文件编写器 C# 类库(版本 1.28.0)使用详解

    PDF File Writer 是一个 C# .NET 类库,允许应用程序创建 PDF 文件. PDF File Writer C# 类库使 .NET 应用程序能够生成 PDF 文档.该库使应用程序免 ...

随机推荐

  1. java基础-类变量,类方法

  2. lenovo E431 win8系统 安装win7

    事由:新买的lenovo e431 原装win8系统.win8系统本来就不好用,又傻傻的装了win10的预览版,丑死不说,还各种驱动不兼容,每次开机都提示不兼容——本人有点洁癖,见不得这种,本想把不兼 ...

  3. JSP的页面连接和提交方式(web基础学习笔记六)

    一.GET请求新页面 1.1.超链接请求新页面 <!-- 超链接到page2 --> <a href="page2.jsp">链接到page2</a& ...

  4. mac 安装升级python3

    如果没有安装过python3的话那就直接下载dmg文件安装升级,一般下载安装后的路径为 /Library/Frameworks/Python.framework/Versions 如果同时安装了多个p ...

  5. linux sar命令详细说明相关参数

    详细说明linux的sar命令 sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括: ...

  6. openerp发送给群组信息

    发送给群组 self.pool.get('mail.group').message_post(cr, uid, [1],             body=_('Welcome to ! Please ...

  7. SoapUI 测试接口演示

      SoapUI 测试接口演示 CreateTime--2018年4月2日15:54:05 Author:Marydon 以webservice为例 1.安装:  SoapUI-x64-5.4.0-E ...

  8. HTTP所承载的货物(图像、文本、软件等)要满足的条件

    HTTP所承载的货物(图像.文本.软件等)要满足的条件: •可以被正确识别 通过Content-Type 首部说明媒体格式,Content-Language 说明语言,以便浏览器和其他客户端能正确处理 ...

  9. python第三方包的windows安装文件exe格式

    今天弄了一上午的python-ldap,发现要么安装vc,要么用其他比较麻烦的方法,都比较麻烦.幸好找到这个地址: http://www.lfd.uci.edu/~gohlke/pythonlibs/ ...

  10. mybatis实现多表联合查询

    本文转自:http://www.cnblogs.com/xdp-gacl/p/4264440.html#!comments 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) ...