Comment detail

法演算 (Nested Flatten)
アルゴリズムよりも、言語ごとのイディオムを問うような問題かなと思いました。

用途によると思いますが、式を埋め込むならマクロが手軽です。

  (with-modular m <式> ...)

と書くと<式> 内の演算がmod m で行われます。


 gosh> (with-modular 10 (list (+ 1 2) (+ 7 3) (+ 11 12)))
 (3 0 3)
 gosh> (with-modular 10 (list (- 3 2) (- 2 3)))
 (1 9)
 gosh> (with-modular 10 (list (* 2 3) (* 11 12) (* 18 39)))
 (6 2 2)
 gosh> (with-modular 10 (+ (- 1 2) (* 3 4) (+ 5 6 7) (* 8 9)))
 1


1
2
3
4
5
6
7
8
9
(define-macro (with-modular m . body)
  `(let ((+ (make-modular + ,m))
         (- (make-modular - ,m))
         (* (make-modular * ,m)))
     ,@body))

(define (make-modular op m)
  (lambda xs
    (modulo (apply op (map (cut modulo <> m) xs)) m)))
一方、式を外部から与えたいなら、+, -, * の束縛がmodular arithmeticに置き換わったようなモジュールを用意してその中でevalするという手が使えます。

 gosh> (eval-modular 10 '(+ 2 9))
 1
 gosh> (eval-modular 10 '(- 2 9))
 3
 gosh> (eval-modular 10 '(* 2 9))
 8
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(define (make-modular op m)
  (lambda xs
    (modulo (apply op (map (cut modulo <> m) xs)) m)))

(define (make-modular-module m)
  (let1 mod (make-module #f)
    (eval `(define + ,(make-modular + m)) mod)
    (eval `(define - ,(make-modular - m)) mod)
    (eval `(define * ,(make-modular * m)) mod)
    mod))

(define (eval-modular m expr)
  (eval expr (make-modular-module m)))

Index

Feed

Other

Link

Pathtraq

loading...