~shironeko/lotte

44fa83f03350a57c4a944c58274691f38347c995 — shironeko 3 years ago 249929d
use vectors
2 files changed, 28 insertions(+), 35 deletions(-)

M lotte-cli.scm
M lotte/main.scm
M lotte-cli.scm => lotte-cli.scm +6 -6
@@ 49,12 49,12 @@
  (iter '()))

(define (print-winners winners)
  (if (not (null? winners))
      (let ((winner (car winners)))
        (if (not (null? winner))
            (begin
              (format #t "~A score: ~A\n" (car winner) (cdr winner))
              (print-winners (cdr winners)))))))
  (define (iter i)
    (if (< i (vector-length winners))
        (let ((winner (vector-ref winners i)))
          (format #t "~A score: ~A\n" (car winner) (cdr winner))
          (iter (1+ i)))))
  (iter 0))

(define opt (cdr (command-line)))
(call-with-input-file

M lotte/main.scm => lotte/main.scm +22 -29
@@ 23,36 23,29 @@
(define (lotte lotte-name lucky-num num-of-winners users)
  ; User's score is the smallest value obtained by
  ; hash(num from 1 to lucky-num + ' ' + lotte-name + ' ' + username)
  (define (get-score user)
  (define (score-user user)
    (define (iter num score)
      (if (zero? num)
          score
          (iter (1- num) (string-min score (hash-strs (number->string num)
                                                      lotte-name user)))))
    (iter lucky-num max-score))
  (define (iter winners-rev len users-left)
    ; Insert new winner into the list sorted from highest to lowest
    (define (insert-winner winner winners-rev)
      (define (iter winners winners-left)
        (if (null? winners-left)
            (reverse (cons winner winners))
            (if (string<? (cdr winner) (cdar winners-left))
                (iter (cons (car winners-left) winners) (cdr winners-left))
                (append (reverse winners) (cons winner winners-left)))))
      (iter '() winners-rev))
          (iter (1- num)
                (string-min (hash-strs (number->string num) lotte-name user)
                            score))))
    (cons user (iter lucky-num max-score)))
  (define (iter winners users-left)
    ; Insert user into the winners list sorted from lowest to highest if they
    ; score smaller than any of them
    (define (insert-user! user)
      (define (iter i)
        (if (< i (vector-length winners))
            (if (string<? (cdr user) (cdr (vector-ref winners i)))
                (begin (vector-move-right!
                         winners i (1- (vector-length winners))
                         winners (1+ i))
                       (vector-set! winners i user))
                (iter (1+ i)))))
      (iter 0))
    (if (null? users-left)
        (reverse winners-rev)
        (let* ((user (car users-left))
               (score (get-score user)))
          (if (< len num-of-winners)
              (iter (insert-winner (cons user score) winners-rev)
                    (1+ len)
                    (cdr users-left))
              (if (string<? score (cdar winners-rev))
                  (iter (insert-winner (cons user score) (cdr winners-rev))
                        len
                        (cdr users-left))
                  (iter winners-rev len (cdr users-left)))))))
  (let* ((user (car users))
         (score (get-score user)))
    (iter (list (cons user score)) 1 (cdr users))))
        winners
        (begin (insert-user! (score-user (car users-left)))
               (iter winners (cdr users-left)))))
  (iter (make-vector num-of-winners (cons "" max-score)) users))