diff options
| -rw-r--r-- | generator/generator.cpp | 134 |
1 files changed, 134 insertions, 0 deletions
| diff --git a/generator/generator.cpp b/generator/generator.cpp index aaf546c..9bef720 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp | |||
| @@ -530,6 +530,134 @@ void generator::run() { | |||
| 530 | } | 530 | } |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | // Red/Blue Top | ||
| 534 | { | ||
| 535 | std::map<std::list<std::string>, std::vector<size_t>> tokenized; | ||
| 536 | for (const auto& [phonemes, pronunciations] : | ||
| 537 | pronunciations_by_blank_phonemes_) { | ||
| 538 | tokenized[hatkirby::split<std::list<std::string>>(phonemes, " ")] = | ||
| 539 | pronunciations; | ||
| 540 | } | ||
| 541 | |||
| 542 | hatkirby::progress ppgs("Generating top red/blue puzzles...", | ||
| 543 | tokenized.size()); | ||
| 544 | for (const auto& [phonemes, pronunciations] : tokenized) { | ||
| 545 | ppgs.update(); | ||
| 546 | |||
| 547 | std::set<std::list<std::string>> visited; | ||
| 548 | for (int i = 0; i < phonemes.size(); i++) { | ||
| 549 | for (int l = 2; l <= phonemes.size() - i; l++) { | ||
| 550 | if (i == 0 && l == phonemes.size()) { | ||
| 551 | continue; | ||
| 552 | } | ||
| 553 | |||
| 554 | std::list<std::string> sublist; | ||
| 555 | for (auto j = std::next(phonemes.begin(), i); | ||
| 556 | j != std::next(phonemes.begin(), i + l); j++) { | ||
| 557 | sublist.push_back(*j); | ||
| 558 | } | ||
| 559 | |||
| 560 | if (tokenized.count(sublist) && !visited.count(sublist)) { | ||
| 561 | visited.insert(sublist); | ||
| 562 | |||
| 563 | for (size_t holophone_id : pronunciations) { | ||
| 564 | for (size_t merophone_id : tokenized[sublist]) { | ||
| 565 | const Pronunciation& holophone = | ||
| 566 | pronunciations_.at(holophone_id); | ||
| 567 | const Pronunciation& merophone = | ||
| 568 | pronunciations_.at(merophone_id); | ||
| 569 | |||
| 570 | for (size_t holo_form_id : holophone.form_ids) { | ||
| 571 | Form& holo_form = forms_.at(holo_form_id); | ||
| 572 | for (size_t mero_form_id : merophone.form_ids) { | ||
| 573 | Form& mero_form = forms_.at(mero_form_id); | ||
| 574 | |||
| 575 | holo_form.puzzles[kBlueTop].insert(mero_form_id); | ||
| 576 | mero_form.puzzles[kRedTop].insert(holo_form_id); | ||
| 577 | } | ||
| 578 | } | ||
| 579 | } | ||
| 580 | } | ||
| 581 | } | ||
| 582 | } | ||
| 583 | } | ||
| 584 | } | ||
| 585 | } | ||
| 586 | |||
| 587 | // Red/Blue Middle | ||
| 588 | std::unordered_map<size_t, std::set<size_t>> left_shorter_by_longer; | ||
| 589 | std::unordered_map<size_t, std::set<size_t>> left_longer_by_shorter; | ||
| 590 | std::unordered_map<size_t, std::set<size_t>> right_shorter_by_longer; | ||
| 591 | std::unordered_map<size_t, std::set<size_t>> right_longer_by_shorter; | ||
| 592 | { | ||
| 593 | hatkirby::progress ppgs("Generating red/blue middle puzzles...", | ||
| 594 | form_by_text_.size()); | ||
| 595 | for (const auto& [text, form_id] : form_by_text_) { | ||
| 596 | ppgs.update(); | ||
| 597 | |||
| 598 | Form& holograph = forms_.at(form_id); | ||
| 599 | std::unordered_set<std::string> visited; | ||
| 600 | for (int i = 0; i < text.size(); i++) { | ||
| 601 | for (int l = 3; l <= text.size() - i; l++) { | ||
| 602 | if (i == 0 && l == text.size()) { | ||
| 603 | continue; | ||
| 604 | } | ||
| 605 | |||
| 606 | std::string substr = text.substr(i, l); | ||
| 607 | if (form_by_text_.count(substr) && !visited.count(substr)) { | ||
| 608 | visited.insert(substr); | ||
| 609 | |||
| 610 | Form& merograph = forms_.at(form_by_text_.at(substr)); | ||
| 611 | |||
| 612 | holograph.puzzles[kBlueMiddle].insert(merograph.id); | ||
| 613 | merograph.puzzles[kRedMiddle].insert(form_id); | ||
| 614 | |||
| 615 | if (i == 0) { | ||
| 616 | left_shorter_by_longer[form_id].insert(merograph.id); | ||
| 617 | left_longer_by_shorter[merograph.id].insert(form_id); | ||
| 618 | } else if (i + l == text.size()) { | ||
| 619 | right_shorter_by_longer[form_id].insert(merograph.id); | ||
| 620 | right_longer_by_shorter[merograph.id].insert(form_id); | ||
| 621 | } | ||
| 622 | } | ||
| 623 | } | ||
| 624 | } | ||
| 625 | } | ||
| 626 | } | ||
| 627 | |||
| 628 | // Purple Middle | ||
| 629 | { | ||
| 630 | hatkirby::progress ppgs( | ||
| 631 | "Generating purple middle puzzles...", | ||
| 632 | left_shorter_by_longer.size() + right_shorter_by_longer.size()); | ||
| 633 | |||
| 634 | for (const auto& [holograph_id, merograph_ids] : left_shorter_by_longer) { | ||
| 635 | ppgs.update(); | ||
| 636 | |||
| 637 | Form& holograph = forms_.at(holograph_id); | ||
| 638 | for (size_t merograph_id : merograph_ids) { | ||
| 639 | for (size_t other_id : left_longer_by_shorter[merograph_id]) { | ||
| 640 | if (other_id != holograph_id) { | ||
| 641 | holograph.puzzles[kPurpleMiddle].insert(other_id); | ||
| 642 | } | ||
| 643 | } | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | for (const auto& [holograph_id, merograph_ids] : right_shorter_by_longer) { | ||
| 648 | ppgs.update(); | ||
| 649 | |||
| 650 | Form& holograph = forms_.at(holograph_id); | ||
| 651 | for (size_t merograph_id : merograph_ids) { | ||
| 652 | for (size_t other_id : right_longer_by_shorter[merograph_id]) { | ||
| 653 | if (other_id != holograph_id) { | ||
| 654 | holograph.puzzles[kPurpleMiddle].insert(other_id); | ||
| 655 | } | ||
| 656 | } | ||
| 657 | } | ||
| 658 | } | ||
| 659 | } | ||
| 660 | |||
| 533 | // Red/Blue Bottom | 661 | // Red/Blue Bottom |
| 534 | std::unordered_map<size_t, std::set<size_t>> meronyms_by_holonym; | 662 | std::unordered_map<size_t, std::set<size_t>> meronyms_by_holonym; |
| 535 | { | 663 | { |
| @@ -687,9 +815,15 @@ void generator::run() { | |||
| 687 | std::cout << "Black bottoms: " << per_puzzle_type[kBlackBottom] << std::endl; | 815 | std::cout << "Black bottoms: " << per_puzzle_type[kBlackBottom] << std::endl; |
| 688 | std::cout << "Black double bottoms: " << per_puzzle_type[kDoubleBlackBottom] | 816 | std::cout << "Black double bottoms: " << per_puzzle_type[kDoubleBlackBottom] |
| 689 | << std::endl; | 817 | << std::endl; |
| 818 | std::cout << "Red tops: " << per_puzzle_type[kRedTop] << std::endl; | ||
| 819 | std::cout << "Red middles: " << per_puzzle_type[kRedMiddle] << std::endl; | ||
| 690 | std::cout << "Red bottoms: " << per_puzzle_type[kRedBottom] << std::endl; | 820 | std::cout << "Red bottoms: " << per_puzzle_type[kRedBottom] << std::endl; |
| 821 | std::cout << "Blue tops: " << per_puzzle_type[kBlueTop] << std::endl; | ||
| 822 | std::cout << "Blue middles: " << per_puzzle_type[kBlueMiddle] << std::endl; | ||
| 691 | std::cout << "Blue bottoms: " << per_puzzle_type[kBlueBottom] << std::endl; | 823 | std::cout << "Blue bottoms: " << per_puzzle_type[kBlueBottom] << std::endl; |
| 692 | std::cout << "Purple tops: " << per_puzzle_type[kPurpleTop] << std::endl; | 824 | std::cout << "Purple tops: " << per_puzzle_type[kPurpleTop] << std::endl; |
| 825 | std::cout << "Purple middles: " << per_puzzle_type[kPurpleMiddle] | ||
| 826 | << std::endl; | ||
| 693 | } | 827 | } |
| 694 | 828 | ||
| 695 | size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { | 829 | size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { |
