diff options
author | Franklin Wei <franklin@rockbox.org> | 2020-06-25 14:44:33 -0400 |
---|---|---|
committer | Franklin Wei <franklin@rockbox.org> | 2020-06-25 18:45:58 +0000 |
commit | 48b0ef1cf22ec37927116ac83ea7c7cfc1f9083e (patch) | |
tree | 148ced6ae04e578abc38a38e92879fa13b97a604 /apps/plugins/puzzles/src/keen.c | |
parent | dd3a8e08988308cf88c10a44176d83a8a152ec4a (diff) | |
download | rockbox-48b0ef1cf22ec37927116ac83ea7c7cfc1f9083e.tar.gz rockbox-48b0ef1cf22ec37927116ac83ea7c7cfc1f9083e.zip |
puzzles: resync with upstream
This brings the upstream version to 9aa7b7c (with some of my changes as
well).
Change-Id: I5bf8a3e0b8672d82cb1bf34afc07adbe12a3ac53
Diffstat (limited to 'apps/plugins/puzzles/src/keen.c')
-rw-r--r-- | apps/plugins/puzzles/src/keen.c | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/apps/plugins/puzzles/src/keen.c b/apps/plugins/puzzles/src/keen.c index baa1d81802..70e3e5432c 100644 --- a/apps/plugins/puzzles/src/keen.c +++ b/apps/plugins/puzzles/src/keen.c | |||
@@ -591,6 +591,92 @@ static int solver_hard(struct latin_solver *solver, void *vctx) | |||
591 | #define SOLVER(upper,title,func,lower) func, | 591 | #define SOLVER(upper,title,func,lower) func, |
592 | static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) }; | 592 | static usersolver_t const keen_solvers[] = { DIFFLIST(SOLVER) }; |
593 | 593 | ||
594 | static int transpose(int index, int w) | ||
595 | { | ||
596 | return (index % w) * w + (index / w); | ||
597 | } | ||
598 | |||
599 | static bool keen_valid(struct latin_solver *solver, void *vctx) | ||
600 | { | ||
601 | struct solver_ctx *ctx = (struct solver_ctx *)vctx; | ||
602 | int w = ctx->w; | ||
603 | int box, i; | ||
604 | |||
605 | /* | ||
606 | * Iterate over each clue box and check it's satisfied. | ||
607 | */ | ||
608 | for (box = 0; box < ctx->nboxes; box++) { | ||
609 | int *sq = ctx->boxlist + ctx->boxes[box]; | ||
610 | int n = ctx->boxes[box+1] - ctx->boxes[box]; | ||
611 | long value = ctx->clues[box] & ~CMASK; | ||
612 | long op = ctx->clues[box] & CMASK; | ||
613 | bool fail = false; | ||
614 | |||
615 | switch (op) { | ||
616 | case C_ADD: { | ||
617 | long sum = 0; | ||
618 | for (i = 0; i < n; i++) | ||
619 | sum += solver->grid[transpose(sq[i], w)]; | ||
620 | fail = (sum != value); | ||
621 | break; | ||
622 | } | ||
623 | |||
624 | case C_MUL: { | ||
625 | long remaining = value; | ||
626 | for (i = 0; i < n; i++) { | ||
627 | if (remaining % solver->grid[transpose(sq[i], w)]) { | ||
628 | fail = true; | ||
629 | break; | ||
630 | } | ||
631 | remaining /= solver->grid[transpose(sq[i], w)]; | ||
632 | } | ||
633 | if (remaining != 1) | ||
634 | fail = true; | ||
635 | break; | ||
636 | } | ||
637 | |||
638 | case C_SUB: | ||
639 | assert(n == 2); | ||
640 | if (value != labs(solver->grid[transpose(sq[0], w)] - | ||
641 | solver->grid[transpose(sq[1], w)])) | ||
642 | fail = true; | ||
643 | break; | ||
644 | |||
645 | case C_DIV: { | ||
646 | int num, den; | ||
647 | assert(n == 2); | ||
648 | num = max(solver->grid[transpose(sq[0], w)], | ||
649 | solver->grid[transpose(sq[1], w)]); | ||
650 | den = min(solver->grid[transpose(sq[0], w)], | ||
651 | solver->grid[transpose(sq[1], w)]); | ||
652 | if (den * value != num) | ||
653 | fail = true; | ||
654 | break; | ||
655 | } | ||
656 | } | ||
657 | |||
658 | if (fail) { | ||
659 | #ifdef STANDALONE_SOLVER | ||
660 | if (solver_show_working) { | ||
661 | printf("%*sclue at (%d,%d) is violated\n", | ||
662 | solver_recurse_depth*4, "", | ||
663 | sq[0]/w+1, sq[0]%w+1); | ||
664 | printf("%*s (%s clue with target %ld containing [", | ||
665 | solver_recurse_depth*4, "", | ||
666 | (op == C_ADD ? "addition" : op == C_SUB ? "subtraction": | ||
667 | op == C_MUL ? "multiplication" : "division"), value); | ||
668 | for (i = 0; i < n; i++) | ||
669 | printf(" %d", (int)solver->grid[transpose(sq[i], w)]); | ||
670 | printf(" ]\n"); | ||
671 | } | ||
672 | #endif | ||
673 | return false; | ||
674 | } | ||
675 | } | ||
676 | |||
677 | return true; | ||
678 | } | ||
679 | |||
594 | static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff) | 680 | static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff) |
595 | { | 681 | { |
596 | int a = w*w; | 682 | int a = w*w; |
@@ -638,7 +724,7 @@ static int solver(int w, int *dsf, long *clues, digit *soln, int maxdiff) | |||
638 | ret = latin_solver(soln, w, maxdiff, | 724 | ret = latin_solver(soln, w, maxdiff, |
639 | DIFF_EASY, DIFF_HARD, DIFF_EXTREME, | 725 | DIFF_EASY, DIFF_HARD, DIFF_EXTREME, |
640 | DIFF_EXTREME, DIFF_UNREASONABLE, | 726 | DIFF_EXTREME, DIFF_UNREASONABLE, |
641 | keen_solvers, &ctx, NULL, NULL); | 727 | keen_solvers, keen_valid, &ctx, NULL, NULL); |
642 | 728 | ||
643 | sfree(ctx.dscratch); | 729 | sfree(ctx.dscratch); |
644 | sfree(ctx.iscratch); | 730 | sfree(ctx.iscratch); |