0

For reference I am programming Racket in DrRacket.

The "language" I am using is Intermediate Student with lambda.

That said, I should note that these are not using high-order functions or lambda.

I am writing a function called winner-by-all that consumes a list of candidates and a list of votes, and returns the name of the winner (one with the highest number of votes).

I can get it to output the largest number, but not name of the winner itself (string).

Here is my winner-by-all function, which is not correct:

;; Signature: winner-by-all: list-of-candidates list-of-votes -> string
;; Purpose: Consumes a list of candidates and a list of votes, and returns 
;;          the name of the winner by the winner-takes-all strategy.
;; Tests:
(check-expect (winner-by-all empty empty) empty)
(check-expect (winner-by-all listofCandidates listofVotes) "Blake")
;; Define:
(define (winner-by-all aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (voting-tally-candidate (max (voting-tally-numVotes (first (tally-by-all listofCandidates listofVotes)))))]
    )
  )

When run, I get an error saying:

voting-tally-candidate: expects a voting-tally, given 3

So my function makes more sense, here are a few other parts of my code to fill in the gaps:

tally-by:

;; Signature: tally-by: (helper function) list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a helper function, a list of candidate names, and a list of
;;          votes and produces a list of voting-tallies.
;; Define:
(define (tally-by helper aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (cons (make-voting-tally (first aloc) 
                                   (helper (first aloc) alov))
                (tally-by helper (rest aloc) alov))]
    )
  )

tally-by-all:

;; Signature: tally-by-all: list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a list of candidate names and a list of votes and produces a
;;          list of voting-tallies.
;;          (Winner-Takes-All strategy).
;; Tests:
(check-expect (tally-by-all empty empty) empty)
(check-expect (tally-by-all listofCandidates listofVotes) (cons (make-voting-tally "Blake" 3)
                                                          (cons (make-voting-tally "Ash" 0)
                                                          (cons (make-voting-tally "Bob" 0)
                                                          (cons (make-voting-tally "Will" 0)
                                                          (cons (make-voting-tally "Joey" 0) empty))))))
;; Define:
(define (tally-by-all aloc alov)
  (tally-by top-votes-for aloc alov))

listofVotes:

;; Data Definition
(define-struct vote (choice1 choice2 choice3))
;; A vote is a structure: (make-vote String String String). 
;; interp. 3 candidates that one person has voted for (String).

(define vote1
  (make-vote "Blake" "Joey" "Will"))

(define vote2
  (make-vote "Blake" "Bob" "Ash"))

(define vote3
  (make-vote "Blake" "Ash" "Blake"))

(define listofVotes
  (list vote1 vote2 vote3))

top-votes-for:

;; Signature: top-votes-for: string list-of-strings -> number
;; Purpose: Consumes a name and a list of votes and produces the number of
;;          times that the given name was the first choice vote in the list of votes.
;;          (This tallies points under winner-takes-all strategy.)
;; Tests:
(check-expect (top-votes-for "Blake" empty) 0)
(check-expect (top-votes-for "Blake" listofVotes) 3)
(check-expect (top-votes-for "Bob" listofVotes) 0)
(check-expect (top-votes-for "Ash" listofVotes) 0)
(check-expect (top-votes-for "Joey" listofVotes) 0)
(check-expect (top-votes-for "Will" listofVotes) 0)
;; Define:
(define (top-votes-for cand alov)
  (cond
    [(empty? alov) 0]
    [(string=? (vote-choice1 (first alov)) cand) (+ 1 (top-votes-for cand (rest alov)))]
    [else (top-votes-for cand (rest alov))]
    )
  )

listofCandidates:

(define listofCandidates
  (list "Blake" "Ash" "Bob" "Will" "Joey"))

voting-tally structure:

;; Data Definition
(define-struct voting-tally (candidate numVotes))
;; A voting-tally is a structure: (make-voting-tally String Number). 
;; interp. a candidate (String) and how many votes said
;;         candidate has gotten (Number).

I am hoping someone is able to assist me with winner-by-all function definitions as I am unsure how to make it work the way it is intended.

1 Answer 1

1

In Intermediate student with lambda you can use high-order functions such as argmax:

(define (winner-by-all aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (voting-tally-candidate (argmax voting-tally-numVotes
                                          (tally-by-all listofCandidates listofVotes)))]
    )
  )

If you really need to implement it without high-order functions and lambda expressions, you can simulate argmax with your own function that recursively iterate over all results of tally-by-all and select the voting-tally with the highest number of votes.

(define (best-candidate left-candidates best)
  (if (null? left-candidates)
      best
      (let ([fst (car left-candidates)])
        (if (or (null? best)
                (> (voting-tally-numVotes fst) (voting-tally-numVotes best)))
            (best-candidate (cdr left-candidates) fst)
            (best-candidate (cdr left-candidates) best)))))

Then use best-candidate to do the job instead of argmax:

(define (winner-by-all aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (voting-tally-candidate (best-candidate (tally-by-all listofCandidates listofVotes) null))]
    )
  )
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! One question, however. In best-candidate, what do left-candidates and best equate to? Like what would I have to type into the window below the definitions window (forgot the name) to test out the function best-candidate?
(best-candidate (tally-by-all listofCandidates listofVotes) null). The first argument (left-candidates) is a list of voting-tally structures and the second (best) is an accumulator representing the best voting-tally found so far (null for the first call).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.