我从不同的来源整理了几个代码片段,并在crude implementation上创建了Wolfram Blog文章的http://bit.ly/HWdUqK-对于那些在数学上倾向于的人,这非常有趣!
毫不奇怪,考虑到我还是Racket的新手,代码花费太多时间来计算结果(> 90分钟,而作者花费49秒),并且占用了大量内存。我怀疑所有关于定义(expListY)的信息都需要重新编写。
尽管我可以在DrRacket中使用它,但是我也遇到了字节编译源代码的问题,并且仍在使用它
(错误消息:+: expects type <number> as 1st argument, given: #f; other arguments were: 1 -1
)
是否有人想提高性能和效率?对于无法理解的代码和缺少更好的代码注释,我深表歉意。
PS:我应该直接在此处剪切和粘贴代码吗?
最佳答案
大概与soegaard的解决方案相似,不同之处在于该解决方案可以滚动自己的“解析器”,因此它是自包含的。它在我的机器上不到6秒的时间就能生成完整的100年 list 。这段代码使用了很多技巧,但实际上并没有以任何严肃的方式将其称为“优化”的东西:我敢肯定,可以通过一些备忘,最大化树共享等来使其变得更快。但是对于这么小的域,这是不值得的工作...(同样的代码质量也是如此...)
顺便说一句,除了解析之外,原始解决方案还使用eval
,但这并不能使事情变得更快。对于这种情况,通常最好手动编写“评估程序”。顺便说一句,这并不意味着Racket的速度要比Mathematica快-我相信那篇文章中的解决方案也可以使冗余的cpu循环变得更容易,并且类似的解决方案也可以更快。
#lang racket
(define (tuples list n)
(let loop ([n n])
(if (zero? n)
'(())
(for*/list ([y (in-list (loop (sub1 n)))] [x (in-list list)])
(cons x y)))))
(define precedence
(let ([t (make-hasheq)])
(for ([ops '((#f) (+ -) (* /) (||))] [n (in-naturals)])
(for ([op ops]) (hash-set! t op n)))
t))
(define (do op x y)
(case op
[(+) (+ x y)] [(-) (- x y)] [(*) (* x y)] [(/) (/ x y)]
[(||) (+ (* 10 x) y)]))
(define (run ops nums)
(unless (= (add1 (length ops)) (length nums)) (error "poof"))
(let loop ([nums (cddr nums)]
[ops (cdr ops)]
[numstack (list (cadr nums) (car nums))]
[opstack (list (car ops))])
(if (and (null? ops) (null? opstack))
(car numstack)
(let ([op (and (pair? ops) (car ops))]
[topop (and (pair? opstack) (car opstack))])
(if (> (hash-ref precedence op)
(hash-ref precedence topop))
(loop (cdr nums)
(cdr ops)
(cons (car nums) numstack)
(cons op opstack))
(loop nums
ops
(cons (do topop (cadr numstack) (car numstack))
(cddr numstack))
(cdr opstack)))))))
(define (expr ops* nums*)
(define ops (map symbol->string ops*))
(define nums (map number->string nums*))
(string-append* (cons (car nums) (append-map list ops (cdr nums)))))
(define nums (for/list ([i (in-range 10 0 -1)]) i))
(define year1 2012)
(define nyears 100)
(define year2 (+ year1 nyears))
(define years (make-vector nyears '()))
(for ([ops (in-list (tuples '(+ - * / ||) 9))])
(define r (run ops nums))
(when (and (integer? r) (<= year1 r) (< r year2))
(vector-set! years (- r year1)
(cons ops (vector-ref years (- r year1))))))
(for ([solutions (in-vector years)] [year (in-range year1 year2)])
(if (pair? solutions)
(printf "~a = ~a~a\n"
year (expr (car solutions) nums)
(if (null? (cdr solutions))
""
(format " (~a more)" (length (cdr solutions)))))
(printf "~a: no combination!\n" year)))
关于algorithm - 尝试字节编译时提高 Racket 代码的性能和错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10161971/