~edwargix/tallyard

9ec174658afbc01c85f54b71f22e56915199cc15 — David Florness 5 years ago 62ad1cf
Allow candidates to tie and assume all unlisted candidates are last
1 files changed, 32 insertions(+), 32 deletions(-)

M client.rkt
M client.rkt => client.rkt +32 -32
@@ 99,41 99,41 @@
                    (λ ([s : String]) : Integer
                       (let ([entry (assert (string->number s)
                                            exact-integer?)])
                         (if (and (>= entry 1) (<= entry num-cands))
                             (sub1 entry)
                             (raise-user-error
                              (format "every entry in your ballot should be a valid integer ∈ [~a,~a]"
                                      1 num-cands)))))
                         (when (or (< entry 1) (> entry num-cands))
                           (raise-user-error
                            (format "every entry in your ballot should be a valid integer ∈ [~a,~a]"
                                    1 num-cands)))
                         (sub1 entry)))
                    (string-split
                     (readline
                      "Rank the candidates (most to least preferable): ")))])
             (if (members-unique? entries)
                 (let* ([m num-cands]
                        [n m]
                        [arr (array->mutable-array
                              (make-array (vector m n) 0))]
                        [num-peers (cast (length peer-inputs) Positive-Integer)])
                   (let loop ([entry (car entries)]
                              [rst (cdr entries)])
                     (for ([other rst])
                       (when (< entry other)
                         (array-set! arr (vector entry other) 1)))
                     (when (not (empty? rst))
                       (loop (car rst) (cdr rst))))
                   (bytes->integer
                    (for*/fold : Bytes
                       ([bstr : Bytes #""])
                       ([i : Natural (in-range m)]
                        [j : Natural (in-range n)]
                        #:when (< i j))
                     (bytes-append bstr
                                   (integer->bytes
                                    (array-ref arr (vector i j))
                                    (cast (min (integer-bytes-length num-peers #t) 1)
                                          Positive-Integer)
                                    #t)))
                    #t))
                 (raise-user-error "every entry in your ballot must be unique"))))))
             (when (not (members-unique? entries))
               (raise-user-error "every entry in your ballot must be unique"))
             (let* ([m num-cands]
                    [n m]
                    [arr (array->mutable-array
                          (make-array (vector m n) 0))]
                    [num-peers (cast (length peer-inputs) Positive-Integer)])
               (let loop ([entry (car entries)]
                          [rst (cdr entries)]
                          [remaining (set-remove (list->set (range num-cands))
                                                 (car entries))])
                 (for ([other remaining])
                   (array-set! arr (vector entry other) 1))
                 (when (not (empty? rst))
                   (loop (car rst) (cdr rst) (set-remove remaining (car rst)))))
               (bytes->integer
                (for*/fold : Bytes
                    ([bstr : Bytes #""])
                    ([i : Natural (in-range m)]
                     [j : Natural (in-range n)])
                  (bytes-append bstr
                                (integer->bytes
                                 (array-ref arr (vector i j))
                                 (cast (min (integer-bytes-length num-peers #t) 1)
                                       Positive-Integer)
                                 #t)))
                #t))))))

  (define poly (random-poly
                (cast (sub1 (length peer-inputs)) Natural)