Skip to content

Commit 34c0350

Browse files
committed
Merge pull request #48 from philnguyen/clean-up-racket
incorporate Eli's cleanups; explicitly use Fixnum + unsafe ops
2 parents 48d077e + 2d71e79 commit 34c0350

File tree

1 file changed

+29
-41
lines changed

1 file changed

+29
-41
lines changed

rkt.rkt

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,38 @@
11
#lang typed/racket
2+
(require (only-in racket/unsafe/ops [unsafe-fx+ +] [unsafe-fxmax max]))
23

3-
(struct route ([dest : Integer] [cost : Integer]) #:transparent)
4+
(struct route ([dest : node] [cost : Integer]) #:transparent)
5+
(struct node ([neighbours : (Listof route)] [visited? : Boolean]) #:transparent #:mutable)
46

5-
(struct node ([neighbours : (Listof route)]) #:transparent)
6-
7-
(: str->int (String -> Integer))
8-
(define (str->int str)
9-
(define n (string->number str))
10-
(if n (numerator (inexact->exact (real-part n))) 0))
11-
12-
(: read-places (-> (Vectorof node)))
7+
(: read-places : -> node)
138
(define (read-places)
14-
(define lines
15-
(file->lines "agraph"))
9+
(define (str->int [str : String])
10+
(assert (string->number str) exact-integer?))
11+
(define lines (file->lines "agraph"))
1612
(define num-lines (str->int (car lines)))
17-
(define nodes (build-vector num-lines (lambda (n) (node `()))))
18-
(let loop ([i : Integer 0])
19-
(define nums (string-split (list-ref (cdr lines) i)))
20-
(define len (length nums))
21-
(when (and (> len 2) (> (length lines) (+ i 2)))
22-
(let ([node-id (str->int (list-ref nums 0))]
23-
[neighbour (str->int (list-ref nums 1))]
24-
[cost (str->int (list-ref nums 2))])
25-
(define new-node (node
26-
(append (node-neighbours (vector-ref nodes node-id))
27-
(list (route neighbour cost)))))
28-
(vector-set! nodes node-id new-node)
29-
(loop (+ i 1)))))
30-
nodes)
13+
(define nodes (build-vector num-lines (λ (n) (node '() #f))))
14+
(for ([3nums (in-list (rest lines))])
15+
(define nums (map str->int (string-split 3nums)))
16+
(define node (vector-ref nodes (first nums)))
17+
(define neighbour (vector-ref nodes (second nums)))
18+
(define cost (third nums))
19+
(set-node-neighbours! node (cons (route neighbour (assert cost fixnum?))
20+
(node-neighbours node))))
21+
(vector-ref nodes 0))
3122

32-
(: get-longest-path ((Vectorof node) Integer (Vectorof Boolean) -> Integer))
33-
(define (get-longest-path nodes node-id visited)
34-
(vector-set! visited node-id #t)
35-
(define sum
36-
(for/fold ([max-acc : Integer 0])
37-
;; `in-list` significantly speeds things up here
38-
([neighbour (in-list (node-neighbours (vector-ref nodes node-id)))]
39-
#:unless (vector-ref visited (route-dest neighbour)))
40-
(max max-acc
41-
(+ (route-cost neighbour) (get-longest-path nodes (route-dest neighbour) visited)))))
42-
(vector-set! visited node-id #f)
43-
sum)
23+
(: get-longest-path : node -> Fixnum)
24+
(define (get-longest-path node)
25+
(set-node-visited?! node #t)
26+
(begin0
27+
(for/fold ([best : Fixnum 0])
28+
([neighbour (in-list (node-neighbours node))]
29+
#:unless (node-visited? (route-dest neighbour)))
30+
(max best (+ (route-cost neighbour)
31+
(get-longest-path (route-dest neighbour)))))
32+
(set-node-visited?! node #f)))
4433

45-
(define nodes (read-places))
46-
(define visited : (Vectorof Boolean) (build-vector (vector-length nodes) (lambda (n) #f)))
34+
(define root (read-places))
4735
(define start (current-inexact-milliseconds))
48-
(define len (get-longest-path nodes 0 visited))
36+
(define len (get-longest-path root))
4937
(define duration (- (current-inexact-milliseconds) start))
50-
(printf "~a LANGUAGE Racket ~a\n" len (inexact->exact (floor duration)))
38+
(printf "~a LANGUAGE Racket ~a\n" len (inexact->exact (floor duration)))

0 commit comments

Comments
 (0)