57 lines
1.7 KiB
Scheme
57 lines
1.7 KiB
Scheme
;;; The Great Computer Language Shootout
|
|
;;; http://shootout.alioth.debian.org/
|
|
|
|
#lang scheme/base
|
|
(require scheme/cmdline)
|
|
|
|
(define (change c1 c2)
|
|
(case c1
|
|
[(red)
|
|
(case c2 [(blue) 'yellow] [(yellow) 'blue] [else c1])]
|
|
[(yellow)
|
|
(case c2 [(blue) 'red] [(red) 'blue] [else c1])]
|
|
[(blue)
|
|
(case c2 [(yellow) 'red] [(red) 'yellow] [else c1])]))
|
|
|
|
(define (place meeting-ch n)
|
|
(thread
|
|
(lambda ()
|
|
(let loop ([n n])
|
|
(if (zero? n)
|
|
;; Fade all:
|
|
(let loop ()
|
|
(let ([c (channel-get meeting-ch)])
|
|
(channel-put (car c) #f)
|
|
(loop)))
|
|
;; Let two meet:
|
|
(let ([c1 (channel-get meeting-ch)]
|
|
[c2 (channel-get meeting-ch)])
|
|
(channel-put (car c1) (cdr c2))
|
|
(channel-put (car c2) (cdr c1))
|
|
(loop (sub1 n))))))))
|
|
|
|
(define (creature color meeting-ch result-ch)
|
|
(thread
|
|
(lambda ()
|
|
(let ([ch (make-channel)])
|
|
(let loop ([color color][met 0])
|
|
(channel-put meeting-ch (cons ch color))
|
|
(let ([other-color (channel-get ch)])
|
|
(if other-color
|
|
;; Meet:
|
|
(loop (change color other-color) (add1 met))
|
|
;; Done:
|
|
(channel-put result-ch met))))))))
|
|
|
|
(let ([result-ch (make-channel)]
|
|
[meeting-ch (make-channel)])
|
|
(place meeting-ch (command-line #:args (n) (string->number n)))
|
|
(creature 'blue meeting-ch result-ch)
|
|
(creature 'red meeting-ch result-ch)
|
|
(creature 'yellow meeting-ch result-ch)
|
|
(creature 'blue meeting-ch result-ch)
|
|
(printf "~a\n" (+ (channel-get result-ch)
|
|
(channel-get result-ch)
|
|
(channel-get result-ch)
|
|
(channel-get result-ch))))
|