# Ordering Arguments of Antisymmetric Functions in Cyclic Way

I have two functions ang and sqa, each of which take two arguments which must be distinct integers between 1 and 6. For instance I could have ang[2,1] or sqa[3,6].

Both of these functions are antisymmetric i.e. ang[a,b] == -ang[b,a] and sqa[a,b] == -sqa[b,a], and for reasons that aren't important I'd like to write a replacement rule (or any other implementation) so that if I have a product of angs and sqas which can be turned to the form ang[a,b]sqa[b,c]ang[c,d]sqa[d,a] or ang[a,b]sqa[b,c]ang[c,d]sqa[d,e]ang[e,f]sqa[f,a] (note the cyclic arguments of alternating ang/sqa, in specific arrangement ab bc cd de ef fa or ab bc cd da) then the antisymmetry of the ang and sqa should be used to do so. For instance if I had ang[1,2]sqa[3,2]ang[3,6]sqa[4,6]ang[5,4]sqa[5,1] then I'd want to flip the order on the sqa[3,2], sqa[4,6] and ang[4,5] to rewrite this as -ang[1,2]sqa[2,3]ang[3,6]sqa[6,4]ang[4,5]sqa[5,1]

Obviously there will be multiple ways to flip the signs to get things into the nice cyclic form, and I don't care which is used. I've tried very naive algorithms like just applying //. {ang[a,b]sqa[a,b] :> -ang[a,b]sqa[b,a]} but this doesn't always work for obvious reasons. I'm wondering if there is some clever way to use e.g. Sort to do this, but I'm coming up blank...

Make a graph with all allowed edges (going both ways), then find a Hamiltonian cycle:

makecycle[F_] := Module[{c, h},
c = Join @@ Cases[F,
(f : ang | sqa)[u_, v_] -> {{DirectedEdge[u, v], f[u, v]},
{DirectedEdge[v, u], -f[v, u]}}];
h = FindHamiltonianCycle[Graph[c[[All, 1]]]][[1]];
h /. Rule @@@ c]


Try it out:

makecycle[ang[1, 2] sqa[3, 2] ang[3, 6] sqa[4, 6] ang[5, 4] sqa[5, 1]]

(*    {ang[1, 2], -sqa[2, 3], ang[3, 6], -sqa[6, 4], -ang[4, 5], sqa[5, 1]}    *)


Multiply them to get the overall sign:

Times @@ %
(*    -ang[1, 2] ang[3, 6] ang[4, 5] sqa[2, 3] sqa[5, 1] sqa[6, 4]    *)


Unfortunately, Times is Orderless and so the cycle is reordered automatically. Maybe NonCommutativeMultiply could be useful too; it depends on what you are going to do with the result and what format you ultimately need.