From e9dee23350f764e73137304c1cda213d838b29f2 Mon Sep 17 00:00:00 2001 From: capo-at-the-5th-fret Date: Mon, 22 May 2023 21:45:03 -0400 Subject: [PATCH] Stats are now in line with tankathon --- CMakeLists.txt | 14 ++-- examples/main.cpp | 117 ++++++++++++++++++++-------------- src/lottery/lottery_print.ixx | 4 +- src/temp_std.ixx | 21 +++--- 4 files changed, 91 insertions(+), 65 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91c1089..603879e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,18 +14,18 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) option(NHL_BUILD_BENCHMARKS "Enable or disable the building of benchmarks" ON) #option(NHL_ENABLE_INSTALL "Enable or disable the install rule" ON) - if (NHL_BUILD_TESTS) - enable_testing() - add_subdirectory(tests) - endif() + # if (NHL_BUILD_TESTS) + # enable_testing() + # add_subdirectory(tests) + # endif() if (NHL_BUILD_EXAMPLES) add_subdirectory(examples) endif() - if (NHL_BUILD_BENCHMARKS) - add_subdirectory(benchmarks) - endif() + # if (NHL_BUILD_BENCHMARKS) + # add_subdirectory(benchmarks) + # endif() # if (NHL_ENABLE_INSTALL) diff --git a/examples/main.cpp b/examples/main.cpp index 869bde4..6c9720d 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -1,8 +1,11 @@ -#include +#include import temp_std; import nhl; +// NOTE: This include must come after the imports, otherwise errors +#include + inline constexpr std::string_view app_name{ "nhl_dls" }; inline constexpr std::string_view app_version{ "1.0" }; @@ -235,10 +238,10 @@ int main(int argc, char* argv[]) nhl::lottery::machine machine; nhl::lottery::combination_table combinations{ true }; - auto draft_order = nhl::lottery::rankings; + auto tentative_draft_order{ nhl::lottery::rankings }; + decltype(tentative_draft_order) final_draft_order{}; nhl::lottery::round_winners round_winners; - std::unordered_set winners; for (nhl::lottery::round_number round{ 1 }; round <= nhl::lottery::round_number{ static_cast(stats.rounds) };) @@ -319,70 +322,77 @@ int main(int argc, char* argv[]) combo, *winner); } - auto remaining_draft_order = draft_order | std::views::drop( - static_cast(round) - 1); + const auto winner_index = *winner - 1; - if (winners.contains(*winner)) + // winner was found in the final draft order list; this means + // the winner is already locked in from a previous round and a + // redraw is required + if (auto pos = std::ranges::find(final_draft_order, winner); + pos != std::ranges::end(final_draft_order)) { record_redraw(stats, round); - //stats.redraws[round]++; if (print_progress) { - temp::println("{} is a previous winner. Redraw required", - *winner); + temp::println( + "{} is already locked in to the {} pick. A redraw is required", + *winner, std::distance(final_draft_order.begin(), pos) + 1); } + continue; } - else if (auto pos = std::ranges::find(remaining_draft_order, - winner); pos != std::ranges::end(remaining_draft_order)) - { - const auto top_ranking = static_cast(round); - - const auto adjusted_ranking = - (winner <= nhl::lottery::max_ranking_jump) ? - top_ranking : - std::max(*winner - nhl::lottery::max_ranking_jump, - top_ranking); - const auto places_from_top = adjusted_ranking - top_ranking; + // find the first 'empty' slot in the final draft order list + auto slot_pos = std::ranges::find(final_draft_order, 0); + assert(slot_pos != std::ranges::end(final_draft_order)); - // Reference: - // https://stackoverflow.com/questions/26176001/c-easiest-most-efficient-way-to-move-a-single-element-to-a-new-position-within + // the slot up for grabs this round + const auto slot = slot_pos - + std::ranges::begin(final_draft_order) + 1; - std::ranges::rotate( - remaining_draft_order.begin() + places_from_top, - pos, - pos + 1 - ); - - winners.insert(*winner); - record_lottery_winner(stats, round, *winner); - round_winners.push(*winner); - //stats.lottery_winner_stats[round][*winner]++; - - ++round; + // team that won can jump to slot + if (winner <= (slot + nhl::lottery::max_ranking_jump)) + { + *slot_pos = *winner; + tentative_draft_order[winner_index] = 0; } + // team that won can't jump to slot else { - record_redraw(stats, round); - //stats.redraws[round]++; - - if (print_progress) - { - temp::println("{} is locked in from a previous round. " - "Redraw required", *winner); - } + // highest ranked team remaining in the pre-lottery draft order + // 'wins' the slot + auto surrogate_winner_pos = std::ranges::find_if_not( + tentative_draft_order, [](auto t) { return t == 0; }); + assert(surrogate_winner_pos != + std::ranges::end(tentative_draft_order)); + + *slot_pos = *surrogate_winner_pos; + *surrogate_winner_pos = 0; + + // The slot that the winner will move to + const auto jump_slot = *winner - + nhl::lottery::max_ranking_jump; + + auto jump_slot_pos = std::ranges::find( + std::ranges::begin(final_draft_order) + (jump_slot - 1), + std::ranges::end(final_draft_order), 0); + assert(jump_slot_pos != std::ranges::end(final_draft_order)); + + *jump_slot_pos = *winner; + tentative_draft_order[winner_index] = 0; } if (print_progress) { temp::println(""); } + + record_lottery_winner(stats, round, *winner); + round_winners.push(*winner); + ++round; } else { record_redraw(stats, round); - //stats.redraws[round]++; if (print_progress) { @@ -398,24 +408,35 @@ int main(int argc, char* argv[]) } } + // add remaining teams to final_draft_order, in order from 1 to 16 + auto empty_slots = final_draft_order | + std::views::filter([](auto t) { return t == 0; }); + auto remaining_seeds = tentative_draft_order | + std::views::filter([](auto t) { return t != 0; }); + + for (auto pos = empty_slots.begin(); const auto team : remaining_seeds) + { + assert(pos != std::ranges::end(empty_slots)); + *pos = team; + ++pos; + } + record_lottery_winners(stats, round_winners); - for (int ranking = 1; auto team : draft_order) + for (int ranking = 1; auto team : final_draft_order) { record_draft_order_ranking(stats, team, ranking); - //stats.draft_order_stats[team][ranking]++; ++ranking; } - if (std::ranges::is_sorted(draft_order)) + if (std::ranges::is_sorted(final_draft_order)) { record_original_draft_order_retained(stats); - //stats.original_draft_order_retained++; } if (print_progress) { - nhl::lottery::print_draft_order(draft_order); + nhl::lottery::print_draft_order(final_draft_order); } }); diff --git a/src/lottery/lottery_print.ixx b/src/lottery/lottery_print.ixx index b8b919d..a77e4f2 100644 --- a/src/lottery/lottery_print.ixx +++ b/src/lottery/lottery_print.ixx @@ -52,7 +52,7 @@ export namespace nhl::lottery math::percent(redraws, stats.simulations).to_ratio()); temp::println(""); - temp::println("{:^17} {:^10} {:^10}", "Potential Winners", "Count", "Pct."); + /*temp::println("{:^17} {:^10} {:^10}", "Potential Winners", "Count", "Pct."); temp::println("{0:17} {1:10} {1:10}", "-----------------", "----------"); { @@ -114,7 +114,7 @@ export namespace nhl::lottery flushes, math::percent(flushes, stats.simulations).to_ratio()); } - } + }*/ temp::println(""); } diff --git a/src/temp_std.ixx b/src/temp_std.ixx index 63a4ccb..c4a0fba 100644 --- a/src/temp_std.ixx +++ b/src/temp_std.ixx @@ -1,13 +1,20 @@ -export module temp_std; +// module; + +// #ifdef __cpp_lib_modules +// #warning "import std; is available, use it instead of std.ixx" +// #endif -#ifdef __cpp_lib_modules - #warning "import std; is available, use it instead of std.ixx" -#endif +// #ifdef __cpp_lib_print +// #warning " is available, use it instead of custom print" +// #endif + +export module temp_std; export import ; export import ; export import ; export import ; +export import ; export import ; export import ; export import ; @@ -19,21 +26,19 @@ export import ; export import ; export import ; export import ; +export import ; export import ; export import ; export import ; export import ; export import ; +export import ; export import ; export import ; export import ; export import ; export import ; -#ifdef __cpp_lib_print - #warning " is available, use it instead of custom print" -#endif - export namespace temp { template