{"size": 2419, "ext": "rktl", "max_stars_repo_path": "pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fannkuch.rktl", "max_stars_repo_name": "lkh01/racket", "max_stars_repo_stars_event_min_datetime": "2018-07-05T21:18:24.000Z", "max_stars_repo_stars_event_max_datetime": "2021-06-04T14:48:37.000Z", "max_issues_repo_path": "pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fannkuch.rktl", "max_issues_repo_name": "lkh01/racket", "max_issues_repo_issues_event_min_datetime": "2017-05-10T07:33:20.000Z", "max_issues_repo_issues_event_max_datetime": "2018-07-19T15:49:46.000Z", "max_forks_repo_path": "pkgs/racket-benchmarks/tests/racket/benchmarks/shootout/typed/fannkuch.rktl", "max_forks_repo_name": "lkh01/racket", "max_forks_repo_forks_event_min_datetime": "2016-04-25T11:47:57.000Z", "max_forks_repo_forks_event_max_datetime": "2017-05-09T14:52:48.000Z"}
{"max_stars_count": 4, "max_issues_count": 9, "max_forks_count": 3, "avg_line_length": 34.5571428571, "max_line_length": 106, "alphanum_fraction": 0.5204630012}
;; fannkuch benchmark for The Computer Language Shootout
;; Written by Dima Dorfman, 2004
;; Slightly improved by Sven Hartrumpf, 2005-2006
;; Ever-so-slightly tweaked for MzScheme by Brent Fulgham
;; PLT-ized for v4.0 by Matthew
;; Ported to Typed Scheme by Vincent

(require racket/cmdline)

(: fannkuch (Integer -> Integer))
(define (fannkuch n)
  (let: ([pi : (Vectorof Integer)
             (list->vector
              (for/list: : (Listof Integer) ([i : Integer (in-range n)]) i))]
        [tmp : (Vectorof Integer) (make-vector n)]
        [count : (Vectorof Integer) (make-vector n)])
    (let: loop : Integer
          ([flips : Integer 0]
           [perms : Integer 0]
           [r : Integer n])
      (when (< perms 30)
        (for ([x (in-vector pi)])
          (display (add1 x)))
        (newline))
      (for ([i (in-range r)])
        (vector-set! count i (add1 i)))
      (let ((flips2 (max (count-flips pi tmp) flips)))
        (let loop2 ([r 1])
          (if (= r n)
              flips2
              (let ((perm0 (vector-ref pi 0)))
                (for ([i (in-range r)])
                  (vector-set! pi i (vector-ref pi (add1 i))))
                (vector-set! pi r perm0)
                (vector-set! count r (sub1 (vector-ref count r)))
                (cond
                 [(<= (vector-ref count r) 0)
                  (loop2 (add1 r))]
                 [else (loop flips2 (add1 perms) r)]))))))))

(: count-flips ((Vectorof Integer) (Vectorof Integer) -> Integer))
(define (count-flips pi rho)
  (vector-copy! rho 0 pi)
  (let: loop : Integer ([i : Integer 0])
    (if (= (vector-ref rho 0) 0)
        i
        (begin
          (vector-reverse-slice! rho 0 (add1 (vector-ref rho 0)))
          (loop (add1 i))))))

(: vector-reverse-slice! (All (X) ((Vectorof X) Integer Integer -> Void)))
(define (vector-reverse-slice! v i j)
  (let: loop : Void
        ([i : Integer i]
         [j : Integer (sub1 j)])
    (when (> j i)
      (vector-swap! v i j)
      (loop (add1 i) (sub1 j)))))

(: vector-swap! (All (X) ((Vectorof X) Integer Integer -> Void)))
(define (vector-swap! v i j)
  (let ((t (vector-ref v i)))
    (vector-set! v i (vector-ref v j))
    (vector-set! v j t)))

(command-line #:args (n)
              (printf "Pfannkuchen(~a) = ~a\n" 
                      n 
                      (fannkuch (assert (string->number (assert n string?)) exact-nonnegative-integer?))))
