t_cmdseq *cmdseq_optimize(t_state *state, t_cmdseq *seq) { t_state *s; t_cmdseq *oseq; int ra = 0; int rb = 0; int pb = 0; bool sa = false; bool sb = false; bool is_rotation; bool is_swap; bool is_push; s = state_dup(state); oseq = cmdseq_new(); // state_print(s); t_cmd cmd = cmdseq_next(seq); // seq = NULL; while (1) { is_rotation = (cmd == RA || cmd == RB || cmd == RR || cmd == RRA || cmd == RRB || cmd == RRR); is_swap = (cmd == SA || cmd == SB || cmd == SS); is_push = (cmd == PA || cmd == PB); // flush rotations if (!is_rotation) { // rotate shorter way if (s->a->top) { ra %= s->a->top; ra = (ra + s->a->top) % s->a->top; } if (s->b->top) { rb %= s->b->top; rb = (rb + s->b->top) % s->b->top; } if (ra > s->a->top / 2) ra -= s->a->top; if (rb > s->b->top / 2) rb -= s->b->top; // flush rotations while (ra > 0 && rb > 0) { state_do(s, oseq, RR); ra--; rb--; } while (ra < 0 && rb < 0) { state_do(s, oseq, RRR); ra++; rb++; } while (ra) { if (ra > 0) { state_do(s, oseq, RA); ra--; } else { state_do(s, oseq, RRA); ra++; } } while (rb) { if (rb > 0) { state_do(s, oseq, RB); rb--; } else { state_do(s, oseq, RRB); rb++; } } } // flush pushes if (!is_push) { while (pb > 0) { state_do(s, oseq, PB); pb--; } while (pb < 0) { state_do(s, oseq, PA); pb++; } } // flush swaps if (!is_swap) { if (sa && sb) state_do(s, oseq, SS); else if (sa) state_do(s, oseq, SA); else if (sb) state_do(s, oseq, SB); sa = sb = false; } // ======================= // rotations if (cmd == RA) ra++; else if (cmd == RB) rb++; else if (cmd == RR) { ra++; rb++; } else if (cmd == RRA) ra--; else if (cmd == RRB) rb--; else if (cmd == RRR) { ra--; rb--; // pushes } else if (cmd == PA) pb--; else if (cmd == PB) pb++; // swaps else if (cmd == SA) sa = !sa; else if (cmd == SB) sb = !sb; else if (cmd == SS) { sa = !sa; sb = !sb; } if (cmd == CMD_NONE) break ; cmd = cmdseq_next(NULL); } state_del(s); return (oseq); }