[racket] slow g^x=h mod p meet in the middle code

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Thu Feb 27 10:40:16 EST 2014

$ racket yourprogram.rkt
cpu time: 21269 real time: 21571 gc time: 14551

The Rackety version. 

#lang racket

(require math)

(define (main)
  (define run (caut (- B 1) (htbl) 1 0))
  (displayln (mx (car run) (cdr run))))

(define p 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084171)
(define g 11717829880366207009516117596335367088558084999998952205599979459063929499736583746670572176471460312928594829675428279466566527115212748467589894601965568)
(define h 3239475104050450443565264378728065788649097520952449527834792452971981976143292558073856937958553180532878928001494706097394108577585732452307673444020333)
(define B (expt 2 20))
(define gB (modular-expt g B p))
(define gm1 (modular-inverse g p))

(define (htbl)
  (hash (- B 1) (make-hasheqv) h 0))

(define (caut n ht l x0)
  (let caut ([n n][l l] [x0 x0])
    (define x1 (hash-ref ht l -1))
    (cond
      ((> n 0)
       (when (< x0 10)
         (displayln (list x0 l)))
       (if (= x1 -1) (caut (- n 1) (modulo (* l gB) p) (+ x0 1)) (cons x0 x1)))
      (else
       (if (= x1 -1) (cons -1 -1) (cons x0 x1))))))

(define (mx x0 x1)
  (+ (* B x0) x1))

;; this initializes a hashtable imperatively
(define (hash n ht l x1)
  (let L ([n n] [l l] [x1 x1])
    (hash-set! ht l x1)
    (when (> n 0)
      (when (< x1 10)
        (displayln (list x1 l)))
      (L (- n 1)  (modulo (* l gm1) p) (+ x1 1))))
  ht)

(time (main))



Posted on the users mailing list.