aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2023-09-17 19:54:37 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2023-09-17 19:54:37 +0200
commit7c1cffb3f7c2be0d9ccc954a00b00db3bf4e2899 (patch)
tree1fbd4817fddc120cc789a35b6b2178b7e944f773 /src
parenta37185d488b90eb89f5e9a949819e905919c84a8 (diff)
downloadnissy-classic-7c1cffb3f7c2be0d9ccc954a00b00db3bf4e2899.tar.gz
nissy-classic-7c1cffb3f7c2be0d9ccc954a00b00db3bf4e2899.zip
Solution output sorting
Diffstat (limited to '')
-rw-r--r--src/alg.c163
-rw-r--r--src/alg.h1
-rw-r--r--src/commands.c6
3 files changed, 168 insertions, 2 deletions
diff --git a/src/alg.c b/src/alg.c
index 66b2704..435954b 100644
--- a/src/alg.c
+++ b/src/alg.c
@@ -13,6 +13,12 @@ static int axis(Move m);
13static void free_alglistnode(AlgListNode *aln); 13static void free_alglistnode(AlgListNode *aln);
14static void realloc_alg(Alg *alg, int n); 14static void realloc_alg(Alg *alg, int n);
15 15
16static int niss_type(Alg *a);
17static void find_last_moves(Alg *a, bool inv, int *, int *, int *);
18static int last_move_pair(Alg *a, bool inv);
19static int compare_algs_firstmoves(Alg * a, Alg *b, bool inv);
20static int compare_algs(const void * a, const void *b);
21
16/* Movesets ******************************************************************/ 22/* Movesets ******************************************************************/
17 23
18Moveset 24Moveset
@@ -459,6 +465,163 @@ realloc_alg(Alg *alg, int n)
459 alg->allocated = n; 465 alg->allocated = n;
460} 466}
461 467
468static int
469niss_type(Alg *a)
470{
471 /* 0 if all moves are on normal, 1 if all on inverse, 2 otherwise */
472
473 int i;
474 bool found_normal = false, found_inverse = false;
475
476 for (i = 0; i < a->len; i++) {
477 found_normal = found_normal || !a->inv[i];
478 found_inverse = found_inverse || a->inv[i];
479 }
480
481 if (found_normal && !found_inverse)
482 return 0;
483 if (!found_normal && found_inverse)
484 return 1;
485 return 2;
486}
487
488static void
489find_last_moves(Alg *a, bool inv, int *n, int *nlast, int *nslast)
490{
491 int i;
492
493 for (i = 0, *n = 0, *nlast = -1, *nslast = -1; i < a->len; i++) {
494 if (inv == a->inv[i]) {
495 (*n)++;
496 *nslast = *nlast;
497 *nlast = i;
498 }
499 }
500}
501
502static int
503last_move_pair(Alg *a, bool inv)
504{
505 /* The number of the move in the moves enum, or a higher number
506 * (working in base NMOVES) if the last two moves are parallel.
507 * -1 if there are no moves on the specified side of the alg.
508 */
509
510 int n, nlast, nslast;
511
512 find_last_moves(a, inv, &n, &nlast, &nslast);
513
514 if (n == 0)
515 return -1;
516 if (nlast == 0 || !commute(a->move[nlast], a->move[nslast]))
517 return a->move[nlast];
518 return a->move[nlast] * NMOVES + a->move[nslast];
519}
520
521static int
522compare_algs_firstmoves(Alg *a, Alg *b, bool inv)
523{
524 /* Compare algs up to the last or the last two moves if parallel */
525
526 int i, j, na, nlasta, nslasta, nb, nlastb, nslastb, ma, mb, m1, m2;
527
528 find_last_moves(a, inv, &na, &nlasta, &nslasta);
529 find_last_moves(b, inv, &nb, &nlastb, &nslastb);
530
531 ma = na > 0 ? ((na > 1 ? nslasta : nlasta) + 1) : 0;
532 mb = nb > 0 ? ((nb > 1 ? nslastb : nlastb) + 1) : 0;
533
534 if (ma == 0 && mb == 0)
535 return 0;
536 if (ma == 0)
537 return -1;
538 if (mb == 0)
539 return 1;
540
541 for (i = 0, j = 0; i < ma && j < mb; i++, j++) {
542 while (a->inv[i] != inv) i++;
543 while (a->inv[j] != inv) j++;
544 m1 = a->move[i];
545 m2 = b->move[j];
546 if (m1 - m2)
547 return m1 - m2;
548 }
549
550 return ma - mb;
551}
552
553static int
554compare_algs(const void *avoid, const void *bvoid)
555{
556 /* We sort a list of algs in a way that makes the most sense for the
557 * commands and steps where one usually wants many results, for
558 * example EO and DR. We sort by, in order:
559 * 1. Length of the solution
560 * 2. NISS type (first algs that are all on normal, then those that
561 * are all on inverse, then those that use NISS)
562 * 3. Last move on normal, or last two moves if they are parallel
563 * 4. All other moves on normal scramble
564 * 5. Last move on inverse, or last two moves if they are parallel
565 * 6. All other moves on inverse
566 */
567
568 Alg *a = *(Alg **)avoid;
569 Alg *b = *(Alg **)bvoid;
570
571 int ntype_a, ntype_b, last_a, last_b, cmp;
572
573 /* 1. Compare length */
574 if (a->len - b->len)
575 return a->len - b->len;
576
577 /* 2. Algs have the same length, compare NISS type */
578 ntype_a = niss_type(a);
579 ntype_b = niss_type(b);
580 if (ntype_a - ntype_b)
581 return ntype_a - ntype_b;
582
583 /* 3. Algs have same NISS type, compare last moves on normal */
584 last_a = last_move_pair(a, false);
585 last_b = last_move_pair(b, false);
586 if (last_a - last_b)
587 return last_a - last_b;
588
589 /* 4. Algs have same last moves on normal, compare all other moves */
590 cmp = compare_algs_firstmoves(a, b, false);
591 if (cmp)
592 return cmp;
593
594 /* 5. Algs have same moves on normal, compare last on inverse */
595 last_a = last_move_pair(a, true);
596 last_b = last_move_pair(b, true);
597 if (last_a - last_b)
598 return last_a - last_b;
599
600 /* 6. Algs have same last moves on inverse, compare other */
601 cmp = compare_algs_firstmoves(a, b, true);
602 if (cmp)
603 return cmp;
604
605 /* Algs are equal */
606 return 0;
607}
608
609void
610sort_alglist(AlgList *al)
611{
612 int i, n = al->len;
613 Alg* alg_array[n];
614 AlgListNode *node;
615
616 for (i = 0, node = al->first; i < n; i++, node = node->next)
617 alg_array[i] = node->alg;
618
619 qsort(alg_array, n, sizeof(Alg *), &compare_algs);
620
621 for (i = 0, node = al->first; i < n; i++, node = node->next)
622 node->alg = alg_array[i];
623}
624
462void 625void
463swapmove(Move *m1, Move *m2) 626swapmove(Move *m1, Move *m2)
464{ 627{
diff --git a/src/alg.h b/src/alg.h
index ee73b64..8f55c15 100644
--- a/src/alg.h
+++ b/src/alg.h
@@ -33,6 +33,7 @@ AlgList * new_alglist(void);
33Alg * on_inverse(Alg *alg); 33Alg * on_inverse(Alg *alg);
34void print_alg(Alg *alg, bool l); 34void print_alg(Alg *alg, bool l);
35void print_alglist(AlgList *al, bool l); 35void print_alglist(AlgList *al, bool l);
36void sort_alglist(AlgList *al);
36void swapmove(Move *m1, Move *m2); 37void swapmove(Move *m1, Move *m2);
37Alg * unniss(Alg *alg); 38Alg * unniss(Alg *alg);
38 39
diff --git a/src/commands.c b/src/commands.c
index 7dd2e45..78d7583 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -398,10 +398,12 @@ solve_exec(CommandArgs *args)
398 c = apply_alg(args->scramble, (Cube){0}); 398 c = apply_alg(args->scramble, (Cube){0});
399 sols = solve(c, args->step, args->opts); 399 sols = solve(c, args->step, args->opts);
400 400
401 if (args->opts->count_only) 401 if (args->opts->count_only) {
402 printf("%d\n", sols->len); 402 printf("%d\n", sols->len);
403 else 403 } else {
404 sort_alglist(sols);
404 print_alglist(sols, args->opts->print_number); 405 print_alglist(sols, args->opts->print_number);
406 }
405 407
406 free_alglist(sols); 408 free_alglist(sols);
407} 409}

Generated with cgit - Back to sebastiano.tronto.net