想这个题想了很久,也没想出提示中的简单的写法,后面在GitHub上找到了这个很精彩的答案,自己想的其实和这个离得
很近了,但是还是没突破。尤其是那个增加目标相当精妙,值得细细体会!
fun score_challenge (card_list, goal) = let
fun aux (count, min) = let
val this_min = score(card_list, goal + 10 * count)
in
if count = 0 then min
else if min < this_min
then aux (count - 1, min)
else aux (count - 1, this_min)
end
in
aux (count_aces(card_list),score(card_list, goal))
end
(*---------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------*)
fun officiate_challenge (card_list, move_list, goal) = let
fun aux_count_aces (card_list,sum,goal) =
case card_list of
[] => 0
| l::l' => if sum > goal then 0
else if card_value(l) = 11 then 1 + aux_count_aces(l',sum + 1,goal)
else aux_count_aces(l',sum + card_value(l),goal)
fun aux1 (count, min) =
let
val new_min = officiate (card_list, move_list, goal + 10 * count)
in
if count = 0 then min
else if min < new_min
then aux1(count - 1, min)
else aux1(count - 1, new_min)
end
in
aux1(aux_count_aces(card_list,0,goal),officiate(card_list,[],goal))
end
(*---------------------------------------------------------------------------------------*)
(*---------------------------------------------------------------------------------------*)
fun careful_player (card_list, goal) = let
fun get_card_matching_value (card_list, value) =
case card_list of
[] => NONE
| l::l' => if card_value(l) = value then SOME l
else get_card_matching_value(l',value)
fun aux (deck, sum, move_list, hand) = let
val cur_score = (hand,goal)
in
case (deck, sum, move_list, hand) of
([],_,moves,_) => moves
| (deck_card::deck,sum,moves,hand) =>
case get_card_matching_value(hand,sum + card_value(deck_card) - goal) of
NONE => if card_value(deck_card) + sum <= goal then aux(deck,sum + card_value(deck_card),moves @ [Draw],deck_card::hand)
else moves
| SOME c => moves @ [Discard c] @ [Draw]
end
in
aux(card_list, 0, [],[])
end