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. 免费的HTML模板引导 - lonely

    ​在线演示 本地下载 今天和大家分享另一款模板-Lonely.它可以被用在一些个人或者类似简单一些的网站上,动画效果的滚动非常特别!

  2. 搭建一个SpringBoot项目

    1.创建项目 New->Spring Starter Project 2.添加支持 增加对mybatis plus的支持,修改pom.xml,增加如下内容: <dependency> ...

  3. UML 之 数据流图(DFD)

          数据流图(Data Flow Diagram):简称DFD,它从数据传递和加工角度,以图形方式来表达系统的逻辑功能.数据在系统内部的逻辑流向和逻辑变换过程,是结构化系统分析方法的主要表达工 ...

  4. Android 四大组件之 Activity(二)

    1.综述 Activity是Android四大组件(Application Components)之一,简单来说Activity就是平常所见到的用户界面,一般情况下,一个Activity所占的窗口是满 ...

  5. python mongodb ubuntu

    mongodb install: sudo apt-get install mongodb Install pip 1. $ sudo apt-get install python-pip pytho ...

  6. win10开启IE11企业模式

    .右击任务栏开始按钮,选择“运行”,打开运行框(或使用组合键Win+R打开运行) .输入gpedit.msc,进入“本地组策略编辑器”(注:该功能不支持Win8/Win8.1核心版.需要Win8/Wi ...

  7. Java根据两点的经纬度来计算之间的距离

    import java.util.HashMap; import java.util.Map; public class MapDistance { private static double EAR ...

  8. 【Android开发经验】Cannot generate texture from bitmap异常的解决方式

    异常现象: 今天在处理用户头像的过程中,由于头像的处理比較复杂,由于,没有使用afinal自带的自己主动载入.而是自己依据头像的下载路径.手动进行下载和使用.可是在手动回收bitmap对象的过程中,会 ...

  9. java instanceof和isInstance的关系 精析

      1.instanceof 用途:判断这个object对象是不是这种Class类型. 语法: boolean result = object instanceof Class; 用法: 判断obje ...

  10. reload基础

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #reload基础 #与import和from的不同之处: #reload是python的内置函数,而不是语句 ...