anchor.diff:  split_runs([Card|Rest]) ->
       split_runs(Rest, [Card], []).
   
  -% The last run, if it was a fifty, would be counted already
  -% Count the last run, it's the best twenty:
  -score_suit(_ExpectedValue, FirstValue, [], 3, none, _High, Score) ->
  -  make_best_run(twenty, FirstValue, Score + 20);
  -
  -% Count the last twenty, but it's not the bext:
  -score_suit(_ExpectedValue, _FirstValue, [], 3, Other, High, Score) ->
  -  make_best_run(Other, High, Score + 20);
  -
  -% No last run, return bests:
  -score_suit(_ExpectedValue, _FirstValue, [], _NoCount, Run, High, Score) ->
  -  make_best_run(Run, High, Score);
  -
  -% Start of new run:
  -score_suit(_ExpectedValue, _FirstValue, [NewCard|Rest], 0, Run, High, Score) ->
  -  score_suit(NewCard#card.value - 1, NewCard#card.value, Rest, 1, Run, High, Score);
  -
  -% New fifty, must be smaller (due to high-low sort):
  -score_suit(ExpectedValue, _FirstValue,
  -           [#card{value=ExpectedValue}|Rest], 3, fifty, High, Score) ->
  -  score_suit(none, none, Rest, 0, fifty, High, Score + 50);
  -
  -% First fifty, doesn't matter if there's twenties:
  -score_suit(ExpectedValue, FirstValue,
  -           [#card{value=ExpectedValue}|Rest],
  -           3, _NotFifty, _High, Score) ->
  -    score_suit(none, none, Rest, 0, fifty, FirstValue, Score + 50);
  -
  -% First twenty, and it's the best:
  -score_suit(_ExpectedValue, FirstValue, Cards, 3, none, _High, Score) ->
  -  score_suit(none, none, Cards, 0, twenty, FirstValue, Score + 20);
  -
  -% Higher twenty or fifty, but count the score:
  -score_suit(_ExpectedValue, _FirstValue, Cards, 3, Run, High, Score) ->
  -  score_suit(none, none, Cards, 0, Run, High, Score + 20);
  -
  -% Building a run:
  -score_suit(ExpectedValue, FirstValue,
  -           [#card{value=ExpectedValue}|Rest], Count,
  -           Run, High, Score) ->
  -    score_suit(ExpectedValue - 1, FirstValue, Rest, Count + 1, Run, High, Score);
  -
  -% No run, start again, doesn't matter the count:
  -score_suit(_ExpectedValue, _FirstValue, Cards, _Count, Run, High, Score) ->
  -  score_suit(none, none, Cards, 0, Run, High, Score).
  -
  -% Must be all the same suit:
  -score_suit(Cards) ->
  -  score_suit(none, none, Cards, 0, none, 0, 0).
  -
  -% fifty better than other:
  -fold_runs(ThisSuit, #best_run{type=fifty, high=High, score=Score1},
  -          #best_run{type=Type, score=Score} = Best, Trump) when Type =/= fifty ->
  -  Best#best_run{type=fifty, score=Score + Score1, high=High,
  -    trump=(ThisSuit==Trump)};
  -
  -% twenty when no other run:
  -fold_runs(ThisSuit, #best_run{type=twenty, high=High, score=Score1},
  -          #best_run{type=none, score=Score} = Best, Trump) ->
  -  Best#best_run{type=twenty, score=Score + Score1, high=High,
  -    trump=(ThisSuit==Trump)};
  -
  -% Same high card, same type, but this is trump:
  -fold_runs(Trump, #best_run{type=Type, high=High, score=Score1},
  -          #best_run{type=Type, high=High, score=Score} = Best, Trump) ->
  -  Best#best_run{score=Score + Score1, trump=true};
  -
  -% Better high card, same type:
  -fold_runs(_AnySuit, #best_run{type=Type, high=High, score=Score1},
  -          #best_run{type=Type, high=High2, score=Score} = Best, _Trump) when
  -          High > High2 ->
  -  Best#best_run{score=Score + Score1, high=High};
  -
  -% Worse run:
  -fold_runs(_AnySuit, #best_run{score=Score1},
  -          #best_run{score=Score} = Best, _Trump) ->
  -  Best#best_run{score=Score + Score1}.
  -
   %%
   %% Tests
   %%
  
positive.code: sort_cards_by_value(Cards) ->
    lists:sort(fun sort_cards_by_value2/2, Cards).
  
  split_by_suit([], Cards, Suit, Lists) ->
    lists:reverse([{lists:reverse(Cards), Suit}|Lists]);
  
  split_by_suit([#card{suit=Suit} = Card|Rest], Cards, Suit, Lists) ->
    split_by_suit(Rest, [Card|Cards], Suit, Lists);
  
  split_by_suit([Card|Rest], Cards, Suit, Lists) ->
    split_by_suit(Rest, [Card], Card#card.suit, [{Cards, Suit}|Lists]).
  
  % Stable split to keep sorted
  split_by_suit([Card|Rest]) ->
    split_by_suit(Rest, [Card], Card#card.suit, []).
  
  make_best_run(Type, High, Score) ->
    #best_run{type=Type, high=High, score=Score, trump=false}.
  
  % Split them into 4's and 3's:
  
  
negative.code:   Runs = lists:map(fun (Hand) -> new_run_record(Hand, TrumpSuit) end, Hands),
    Runs.
  
  new_run_record(Cards, TrumpSuit) ->
    SortedCards = sort_cards_by_value(Cards),
    CardsBySuit = split_by_suit(SortedCards),
  
    SplitByRuns = lists:reverse(lists:foldl(fun lists:append/2, [],
      lists:map(fun split_runs/1, CardsBySuit))),
  
    SortBySize = sort_runs(SplitByRuns, TrumpSuit),
  
    CardsToShow = lists:flatten(SortBySize),
    Score = score_runs(SplitByRuns),
    BestRun = make_best(SortBySize, TrumpSuit),
    #run_record{best_run=BestRun, score=Score, to_show=CardsToShow}.
  
  % This sorts top to bottom by values to make run finding easier
  sort_cards_by_value2(#card{suit=Suit, value=V1},
  