Evening Commute Solver
Javascript (ES6), 1216 1206 1131 + 180 => 1311 bytes

a=&gt;{a=a.replace(/\s/g,'');b=[];d={};e=[];f=[];g=[];h='.';[].concat.apply([],a.split('.').filter(k=&gt;k).map(k=&gt;k.match(/([^.])(\1*)/g)||k)).forEach(k=&gt;k.length&gt;1?(b.push(k[0]),(k.length&lt;3?g:f).push(k[0])):(!e.includes(k)&amp;&amp;e.push(k),d[k]=d[k]?d[k]+1:1));Object.keys(d).forEach(k=&gt;(d[k]&lt;3?g:f).push(k));j=(l,m,n)=&gt;l.substr(0,m)+n+l.substr(m+n.length);o=(p,q)=&gt;~q.indexOf(p);I=(s,r,c)=&gt;s.charAt(r*6+c)||'@';t=(s,r,c,F,G)=&gt;{k=0;while(I(s,r+k*F,c+k*G)==h)k++;return k};u={};w=[];x={};x=(y,z,A)=&gt;u[y]===[][0]?(u[y]=z,x[y]=A,w.push(y)):0;C=B=&gt;{var z=u[B];return (!z?'':C(z))+x[B]};D=(B,r,c,q,E,F,G,n)=&gt;{r+=E*F;c+=E*G;H=I(B,r,c);if(!o(H,q))return;L=o(H,f)?3:o(H,g)?2:[][0];J=B;for(i=0;i&lt;n;i++){r-=F;c-=G;J=j(J,r*6+c,H);J=j(J,(r+L*F)*6+c+L*G,h);x(J,B,H+(!~F?'v':F?'^':!~G?'&gt;':'&lt;'));B=J}};x(a,null,'');K=!1;while(w.length) {B=w.splice(0,1)[0];if(I(B,2,5)=='R'&amp;&amp;!K){K=!0;break}for(r=0;r&lt;6;r++){for(c=0;c&lt;6;c++){if(I(B,r,c)!=h)continue;nU=t(B,r,c,-1,0);nD=t(B,r,c,1,0);nL=t(B,r,c,0,-1);nR=t(B,r,c,0,1);D(B,r,c,e,nU,-1,0,nU+nD-1);D(B,r,c,e,nD,1,0,nU+nD-1);D(B,r,c,b,nL,0,-1,nL+nR-1);D(B,r,c,b,nR,0,1,nL+nR-1)}}}return C(B).replace(/(R.)+$/,'Rx')}


I followed the algorithm and example from here. Rewriting the algorithm and input in the example to output moves cost a lot of bytes. I'm planning on rewriting the answer using an algorithm specifically designed for outputting moves instead of outputting board states.

Ungolfed:

func = inp =&gt; {
    inp = inp.replace(/\s/g, '');

    HORZS = [];
    tVERTS = {};
    VERTS = [];
    LONGS = [];
    SHORTS = [];
    EMPTY = '.';

    [].concat.apply([], inp.split('.').filter(k =&gt; k).map(k =&gt; k.match(/([^.])(\1*)/g) || k)).forEach(k =&gt;
        k.length &gt; 1 ? (
            HORZS.push(k[0]),
            (k.length &lt; 3 ? SHORTS : LONGS).push(k[0])
        ) : (
            !VERTS.includes(k) &amp;&amp; VERTS.push(k),
            tVERTS[k] = tVERTS[k] ? tVERTS[k] + 1 : 1
        )
    );
    Object.keys(tVERTS).forEach(k =&gt; (tVERTS[k] &lt; 3 ? SHORTS : LONGS).push(k));

    setCharAt = (str, index, character) =&gt; str.substr(0, index) + character + str.substr(index + character.length);

    isType = (entity, type) =&gt; ~type.indexOf(entity);

    at = (state, r, c) =&gt; state.charAt(r * 6 + c) || '@';

    countSpaces = (state, r, c, dr, dc) =&gt; {
        k = 0;
        while (at(state, r + k * dr, c + k * dc) == EMPTY) k++;
        return k;
    };

    pred = {};
    queue = [];
    moves = {};

    propose = (next, prev, move) =&gt; pred[next] === [][0] ? (pred[next] = prev, moves[next] = move, queue.push(next)) : 0;

    trace = current =&gt; {
        var prev = pred[current];
        return (!prev ? '' : trace(prev)) + moves[current];
    };

    slide = (current, r, c, type, distance, dr, dc, n) =&gt; {
        r += distance * dr;
        c += distance * dc;
        car = at(current, r, c);
        if (!isType(car, type)) return;
        L = isType(car, LONGS) ? 3 : isType(car, SHORTS) ? 2 : [][0];
        sb = current;
        for (i = 0; i &lt; n; i++) {
            r -= dr;
            c -= dc;
            sb = setCharAt(sb, r * 6 + c, car);
            sb = setCharAt(sb, (r + L * dr) * 6 + c + L * dc, EMPTY);
            propose(sb, current, car + (!~dr ? 'v' : dr ? '^' : !~dc ? '&gt;' : '&lt;'));
            current = sb;
        }
    };

    propose(inp, null, '');
    solved = !1;
    while (queue.length) {
        current = queue.splice(0, 1)[0];
        if (at(current, 2, 5) == 'R' &amp;&amp; !solved) {
            solved = !0;
            break;
        }

        for (r = 0; r &lt; 6; r++) {
            for (c = 0; c &lt; 6; c++) {
                if (at(current, r, c) != EMPTY) continue;
                nU = countSpaces(current, r, c, -1, 0);
                nD = countSpaces(current, r, c, 1,  0);
                nL = countSpaces(current, r, c, 0, -1);
                nR = countSpaces(current, r, c, 0,  1);
                slide(current, r, c, VERTS, nU, -1, 0, nU + nD - 1);
                slide(current, r, c, VERTS, nD, 1,  0, nU + nD - 1);
                slide(current, r, c, HORZS, nL, 0, -1, nL + nR - 1);
                slide(current, r, c, HORZS, nR, 0,  1, nL + nR - 1);
            }
        }
    }

    return trace(current).replace(/(R.)+$/, 'Rx');
}


Example usage and output:

func(`......
11..22
RRC...
..C..3
..C..3
..66..`); // ==&gt; "6&lt;6&lt;CvRx"

func(`11...C
D..E.C
DRRE.C
D..E..
2...33
2.FFF.`); // ==&gt; "1&gt;D^2^Cv3&lt;3&lt;3&lt;CvCvEvF&lt;F&lt;EvRx"

func(`112.33
442..C
DRR..C
DEEE.C
D..566
77.588`); // ==&gt; "3&lt;C^R&gt;R&gt;2vE&gt;E&gt;2v2v2v1&gt;4&gt;D^D^R&lt;R&lt;E&lt;E&lt;E&lt;5^5^5^Cv6&lt;Cv8&lt;Cv3&gt;5^Rx"

func(`C.1DDD
C.12..
CRR2..
3344.E
.....E
5566.E`); // ==&gt; "4&gt;3&gt;CvCvD&gt;2^Rx"

func(`C11.2.
C34.2D
C34RRD
EEE5.D
..6577
88699.`); // ==&gt; "D^9&gt;5vE&gt;E&gt;E&gt;E&gt;Cv1&lt;4^R&lt;3v3vR&lt;5^5^5^5^R&gt;R&gt;E&lt;E&lt;Dv7&lt;Dv9&lt;DvRx"