summary refs log tree commit diff stats
path: root/generator
diff options
context:
space:
mode:
Diffstat (limited to 'generator')
-rw-r--r--generator/generator.cpp134
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
695size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) { 829size_t generator::LookupOrCreatePronunciation(const std::string& phonemes) {