私はLisp Koansを使っています。とても楽しいです! しかし、私は Scoring Projects に固執しました (私は悪い解決策を持っていました)。このプロジェクトでは、 という単純なゲームの実装を依頼されました*Greed*
。問題の説明は次のとおりです。
; *Greed* is a dice game where you roll up to five dice to accumulate
; points. The following "score" function will be used to calculate the
; score of a single roll of the dice.
;
; A greed roll is scored as follows:
; * A set of three ones is 1000 points
; * A set of three numbers (other than ones) is worth 100 times the
; number. (e.g. three fives is 500 points).
; * A one (that is not part of a set of three) is worth 100 points.
; * A five (that is not part of a set of three) is worth 50 points.
; * Everything else is worth 0 points.
;
; Examples:
;
; (score '(1 1 1 5 1)) => 1150 points
; (score '(2 3 4 6 2)) => 0 points
; (score '(3 4 5 3 3)) => 350 points
; (score '(1 5 1 2 4)) => 250 points
;
; More scoring examples are given in the tests below:
;
; Your goal is to write the score method.
私の解決策は次のとおりです。
警告!これで遊んでいない場合。これを見ないでください!
関数を使用してoccurs
数値の出現回数を計算し、連想リストで表します。そして、formula-wrapper
関数に正しい引数を提供するformula
関数。formula
スコアを計算する関数。私の解決策は非常に醜いです!どんなアドバイスも大歓迎です!前もって感謝します。
(defun occurs (lst)
(let ((acc nil))
(dolist (obj lst)
(let ((p (assoc obj acc)))
(if p
(incf (cdr p))
(push (cons obj 1) acc))))
(sort acc #'> :key #'cdr)))
(defun formula-wrapper (lst)
(formula (car lst) (cdr lst)))
(defun formula (number times)
(cond ((= times 0) 0)
((= times 1)
(case number
(1 100)
(5 50)
(otherwise 0)))
((= times 2)
(case number
(1 200)
(5 100)
(otherwise 0)))
((= times 3)
(case number
(1 1000)
(otherwise (* 100 number))))
((= times 4)
(case number
(1 1100)
(5 550)
(otherwise 0)))
((= times 5)
(case number
(1 1200)
(5 600)
(otherwise 0)))
(times 0)))
(defun score (dice)
(let ((rolls (occurs dice)))
(if (null rolls)
0
(apply #'+ (mapcar #'formula-wrapper rolls))))))
テスト:
(define-test test-score-of-an-empty-list-is-zero
(assert-equal 0 (score nil)))
(define-test test-score-of-a-single-roll-of-5-is-50
(assert-equal 50 (score '(5))))
(define-test test-score-of-a-single-roll-of-1-is-100
(assert-equal 100 (score '(1))))
(define-test test-score-of-multiple-1s-and-5s-is-the-sum-of-individual-scores
(assert-equal 300 (score '(1 5 5 1))))
(define-test test-score-of-single-2s-3s-4s-and-6s-are-zero
(assert-equal 0 (score '(2 3 4 6))))
(define-test test-score-of-a-triple-1-is-1000
(assert-equal 1000 (score '(1 1 1))))
(define-test test-score-of-other-triples-is-100x
(assert-equal 200 (score '(2 2 2)))
(assert-equal 300 (score '(3 3 3)))
(assert-equal 400 (score '(4 4 4)))
(assert-equal 500 (score '(5 5 5)))
(assert-equal 600 (score '(6 6 6))))
(define-test test-score-of-mixed-is-sum
(assert-equal 250 (score '(2 5 2 2 3)))
(assert-equal 550 (score '(5 5 5 5))))