feat: reduce the size of the search space by acknowledging that there are <=10 distinct feedbacks vs 1330 targets
This commit is contained in:
parent
91a65cdb60
commit
8f07d1a83c
1 changed files with 24 additions and 19 deletions
43
Proj2.hs
43
Proj2.hs
|
|
@ -36,7 +36,13 @@
|
||||||
-- As the performer, we must guess the target in as few steps as possible given
|
-- As the performer, we must guess the target in as few steps as possible given
|
||||||
-- the feedback from the composer at each turn.
|
-- the feedback from the composer at each turn.
|
||||||
--
|
--
|
||||||
-- TODO: finish explanation of initialGuess and nextGuess
|
-- TODO: finish explanation of initialGuess
|
||||||
|
--
|
||||||
|
-- To pick the best next guess, we filter the game state to contain only
|
||||||
|
-- targets that are consistent with the received feedback from the previous
|
||||||
|
-- guess. We then calculate, for each candidate, the maximum number of guesses
|
||||||
|
-- that would remain if we chose it as the next guess. We can then choose the
|
||||||
|
-- candidate that has the smallest of this number as the next guess.
|
||||||
|
|
||||||
module Proj2
|
module Proj2
|
||||||
( Pitch,
|
( Pitch,
|
||||||
|
|
@ -49,10 +55,9 @@ module Proj2
|
||||||
where
|
where
|
||||||
|
|
||||||
import Data.List
|
import Data.List
|
||||||
|
import Data.Map qualified as M
|
||||||
import Data.Ord (comparing)
|
import Data.Ord (comparing)
|
||||||
import Data.Set qualified as S
|
import Data.Set qualified as S
|
||||||
import Debug.Trace
|
|
||||||
import Text.XHtml (target)
|
|
||||||
|
|
||||||
-- ==== DATA STRUCTURES =======================================================
|
-- ==== DATA STRUCTURES =======================================================
|
||||||
|
|
||||||
|
|
@ -163,8 +168,8 @@ initialGuess = (bestFirstGuess, allChords)
|
||||||
-- TODO: is this really the best first guess?
|
-- TODO: is this really the best first guess?
|
||||||
bestFirstGuess =
|
bestFirstGuess =
|
||||||
[ Pitch A One,
|
[ Pitch A One,
|
||||||
Pitch B Two,
|
Pitch D Two,
|
||||||
Pitch C Three
|
Pitch G Three
|
||||||
]
|
]
|
||||||
|
|
||||||
-- takes in the previous guess, the game state, and the feedback for the
|
-- takes in the previous guess, the game state, and the feedback for the
|
||||||
|
|
@ -173,25 +178,25 @@ initialGuess = (bestFirstGuess, allChords)
|
||||||
-- strategy:
|
-- strategy:
|
||||||
-- 1. reduce the size of the search space by removing all guesses inconsistent
|
-- 1. reduce the size of the search space by removing all guesses inconsistent
|
||||||
-- with the answer received for the previous guess.
|
-- with the answer received for the previous guess.
|
||||||
-- 2. TODO: mini-max?
|
-- 2. for each candidate, calculate the worst case number of remaining target
|
||||||
|
-- 3. choose the candidate with the smallest of this number
|
||||||
--
|
--
|
||||||
nextGuess :: ([Pitch], GameState) -> (Int, Int, Int) -> ([Pitch], GameState)
|
nextGuess :: ([Pitch], GameState) -> (Int, Int, Int) -> ([Pitch], GameState)
|
||||||
-- nextGuess (prevGuess, chords) answer | trace ("calling nextGuess with: " ++ show prevGuess ++ show chords ++ show answer) False = undefined
|
nextGuess (prevGuess, state) prevFeedback = (chosen, newState)
|
||||||
nextGuess (prevGuess, chords) answer = (guess, consistentChords)
|
|
||||||
where
|
where
|
||||||
consistentChords = filter (consistentWith answer) chords
|
chosen = fst $ minimumBy (comparing snd) scored
|
||||||
scoredGuesses = map (\x -> (x, averageNumTargets x)) consistentChords
|
newState = filter (/= chosen) candidates
|
||||||
guess = fst $ minimumBy (comparing snd) scoredGuesses
|
|
||||||
|
|
||||||
-- helper functions
|
scored = map (\x -> (x, score x candidates)) candidates
|
||||||
consistentWith answer chord = answer == feedback prevGuess chord
|
candidates = filter (\x -> prevFeedback == feedback prevGuess x) state
|
||||||
averageNumTargets answer = map (`squaredFreqs` consistentChords) consistentChords
|
|
||||||
squaredFreqs answer = map ((^ 2) . length) . group . sort . map (feedback answer)
|
|
||||||
averageFreqs answer chords = sum freqs `div` length freqs
|
|
||||||
where
|
|
||||||
freqs = squaredFreqs answer chords
|
|
||||||
|
|
||||||
-- TODO: implement me
|
-- maximum number of possible targets per candidate
|
||||||
|
score candidate candidates =
|
||||||
|
maximum $
|
||||||
|
M.elems $
|
||||||
|
M.fromListWith
|
||||||
|
(+)
|
||||||
|
[(feedback candidate target, 1) | target <- candidates]
|
||||||
|
|
||||||
-- ==== HELPER FUNCTIONS ======================================================
|
-- ==== HELPER FUNCTIONS ======================================================
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue