Comment detail

議席数をドント方式で (Nested Flatten)
1. 各政党の獲得議席数リストを0にセット。正数リストを1にセット。
2. 各党の得票数を正数で割っていく。
3. 獲得議席数と正数リストを、商が最大の政党のところで+1する。
4. 2,3を繰り返し、定足数に達したら獲得議席数リストを返す。
と、考えてやってみました。

(dhondt 100 '(123 4 56 78))
=>(48 1 21 30)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
(define (dhondt seats votes)
  (define (max1+ l s d)
    (let1 m (apply max l)
      (do ((l l (cdr l)) (s s (cdr s)) (d d (cdr d))
           (a '() (if (= (car l) m) (cons (+ (car s) 1) a) (cons (car s) a)))
           (b '() (if (= (car l) m) (cons (+ (car d) 1) b) (cons (car d) b))))
          ((null? l) (cons (reverse! a) (reverse! b))))))
  (let1 len (length votes)
    (let loop ((score (make-list len 0))
               (denom (make-list len 1)))
      (if (>= (apply + score) seats)
          score
          (let1 s&d (max1+ (map (cut / <> <>) votes denom) score denom)
            (loop (car s&d) (cdr s&d)))))))
同じくEmacs Lispで。
(dhondt 100 '(123 4 56 78))
=>(48 1 21 30)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
(require 'cl)
(defun dhondt (seats votes)
  (let ((max1+ (lambda (l s d)
                 (let ((m (apply #'max l)))
                   (do ((l l (cdr l)) (i 0 (+ i 1)))
                       ((null l) (cons s d))
                     (when (= (car l) m)
                       (incf (car (nthcdr i s)))
                       (incf (car (nthcdr i d))))))))
        (len (length votes)))
    (do ((score (make-list len 0))
         (denom (make-list len 1)))
        ((>= (apply #'+ score) seats) score)
      (let ((s&d (funcall max1+ (map 'list #'(lambda (a b) (/ (* a 1.0) b))
                                     votes denom)
                          score denom)))
        (setq score (car s&d)
              denom (cdr s&d))))))

Index

Feed

Other

Link

Pathtraq

loading...