| Bytes | Lang | Time | Link |
|---|---|---|---|
| 326 | Python3 | 250908T195203Z | Ajax1234 |
| 207 | APL | 140111T155905Z | Tobia |
| 151 | Mathematica | 140109T002921Z | ybeltuko |
| nan | 140107T224625Z | Dr. beli | |
| nan | 140108T002144Z | Blau |
Python3, 326 bytes
from itertools import*
E=enumerate
def f(b):
d={(x,y):v for x,r in E(b)for y,v in E(r)}
q=[]
for i in permutations({*d.values()},4):
for j in d:t={**d};q+=[(*j,t.pop(j),dict(zip(i,[(0,1),(1,0),(0,-1),(-1,0)])),t)]
for x,y,D,M,d in q:
t={**d}
if{}==t:return M
X,Y=M[D]
if(D:=t.pop(V:=(x+X,y+Y),0)):q+=[(*V,D,M,t)]
APL (207)
I couldn't make it shorter than Mathematica, because I couldn't reason in terms of TopologicalSort and such. Smarter people are welcome to squeeze it further.
Golfed:
{u←∪,t←⍵⋄q r←↑(0≠+/¨r)/⊂[2]p,⍪r←{m←,⍵[u⍳t]⋄v r←⊂[1]⊃{{(↑⍴∪⍵),⊂(↑⍵)(↑⌽⍵)}n↑{3::⍬⋄i←↑⌽⍵⋄⍵,i+i⌷m}⍣n,⍵}¨⍳n←↑⍴,t⋄↑(v=n)/r}¨p←⊂[2]{1≥⍴⍵:⊃,↓⍵⋄⊃⍪/⍵,∘∇¨⍵∘~¨⍵}d←¯1 1,¯1 1×c←¯1↑⍴t⋄⊃('←→↑↓',¨u[q⍳d]),{1+(⌊⍵÷c)(c|⍵)}¨r-1}
Ungolfed:
D←{⎕ML ⎕IO←3 1
pmat←{1≥⍴⍵:⊃,↓⍵⋄⊃⍪/⍵,∘∇¨⍵∘~¨⍵} ⍝ utility: permutations of the given vector
u←∪,t←⍵ ⍝ the 4 unique symbols in t←⍵
n←↑⍴,t ⍝ number of elements in t
d←¯1 1,¯1 1×c←¯1↑⍴t ⍝ the four ∆i (+1, -1, +cols, -cols)
p←⊂[2]pmat d ⍝ list of permutations of the four ∆i
r←{ ⍝ for each permutation ⍵∊p (=interpretation of the 4 symbols)
m←,⍵[u⍳t] ⍝ (ravelled) t-shaped matrix of ∆i, using interpretation ⍵
v r←⊂[1]⊃{ ⍝ for each starting index ⍵∊⍳n
v←n↑{ ⍝ trail of visited cells after n steps
3::⍬ ⍝ if index out of bounds return empty list
i←↑⌽⍵ ⍝ take last visited index
⍵,i+i⌷m ⍝ follow the directions and add it to the list
}⍣n,⍵
(↑⍴∪v),⊂(↑v),↑⌽v ⍝ number of unique cells, plus start/end indices
}¨⍳n
↑(v=n)/r ⍝ 1st couple of start/end indices to visit all cells (if any)
}¨p
q r←↑(0≠+/¨r)/⊂[2]p,⍪r ⍝ select first perm. and start/end indices to visit all cells
⊃('←→↑↓',¨u[q⍳d]),{1+(⌊⍵÷c)(c|⍵)}¨r-1 ⍝ return char mapping and start/end indices
}
Examples:
(Indices start at 1)
D⊃'122221' '131414' '231342' '144213' '222323'
← 4
→ 2
↑ 3
↓ 1
1 1
3 6
D⊃'@..' 'e.@' 'HH@'
← .
→ H
↑ @
↓ e
2 2
1 1
D⊃'XXV' 'ICV' 'XIV' 'VCC' 'XXX'
← C
→ X
↑ I
↓ V
3 1
5 3
Mathematica (151)
L = {{1, 2, 2, 2, 2, 1}, {1, 3, 1, 4, 1, 4}, {2, 3, 1, 3, 4, 2},
{1, 4, 4, 2, 1, 3}, {2, 2, 2, 3, 2, 3}};
PathGraphQ@#~If~Print@{TopologicalSort[#]〚{1,-2}〛,r}&@
Graph@Flatten@MapIndexed[#2->#2+(#/.r)&,L,{2}]~Do~{r,
Thread[Union@@L->#]&/@{-1,0,1}~Tuples~{4,2}}
It returns start point, end point, and transition rules. The first index is row, the second is column
{{{1,1},{3,6}},{1->{1,0},2->{0,1},3->{-1,0},4->{0,-1}}}
Note that my code works even with {-1,0,1}~Tuples~{4,2}. For speeding up you can use Permutations@{{1, 0}, {0, 1}, {-1, 0}, {0, -1}} instead.
Mathematica 278
Spaces added for "clarity"
k@l_ := (s = #~Join~-# &@{{1, 0}, {0, 1}};
f@r_ := Flatten[MapIndexed[#2 -> #2 + (#1 /. r) &, l, {2}], 1];
g = Subgraph[#, t = Tuples@Range@Dimensions@l] & /@
Graph /@ f /@ (r = Thread[# -> s] & /@ Permutations[Union @@ l]);
{t[[#]] & /@ Ordering[Tr /@ IncidenceMatrix@g[[#]]][[{1, -1}]], r[[#]]} & @@@
Position[PathGraphQ /@ g, True])
Session & Output:
l = l1 = {{1, 2, 2, 2, 2, 1}, {1, 3, 1, 4, 1, 4}, {2, 3, 1, 3, 4, 2},
{1, 4, 4, 2, 1, 3}, {2, 2, 2, 3, 2, 3}}; ;
k@l1
{{{{1, 1}, {3, 6}},
{1 -> {1, 0}, 2 -> {0, 1}, 3 -> {-1, 0}, 4 -> {0, -1}}}}
Which is the start Vertex, End Vertex and the transition rules associated with each symbol.
Here is the complementary code to show the oriented graph:
sol = sg[[Position[PathGraphQ /@ sg, True][[1, 1]]]];
Framed@Graph[
VertexList@sol,
EdgeList@sol,
VertexCoordinates -> VertexList@sol /. {x_, y_} :> {y, -x},
VertexLabels -> MapThread[Rule, {VertexList@sol, Flatten@l}],
EdgeShapeFunction -> GraphElementData["FilledArcArrow", "ArrowSize" -> 0.03],
ImagePadding -> 20]

C#
EDIT: Fixed a division and formatting. And added the helper class.
This is the golfed code, 807 chars
class M{public int c,x,y,u;}
void G(string[] z){
M K;int[]x={0,0,-1,1},y={-1,1,0,0},I={0,0,0,0};
string[]T={"Up","Down","Left","Right"};
int X,Y,R,n=0,H=z.Length,W=z[0].Length;W-=W/2;var D= string.Join(" ", z).Where(c=>c!=' ').Select(c=>new M(){c=c,x=n%W,y=n++/W}).ToList();n=0;var S=D.GroupBy(k=>k.c).ToDictionary(k=>k.Key,k =>n++);
for(;I[0]<4;I[0]++)for(I[1]=0;I[1]<4;I[1]++)for(I[2]=0;I[2]<4;I[2]++)for(I[3]=0;I[3]<4;I[3]++){
if ((1<<I[0]|1<<I[1]|1<<I[2]|1<<I[3])!=15)continue;
foreach (var Q in D){D.ForEach(p=>p.u=-1);R=1;K=Q;j:if((X=K.x+x[n=I[S[K.c]]])>=0&&X<W&&(Y=K.y+y[n])>=0&&Y<H&&(K=D[X+Y*W]).u<0){
K.u=1;if(++R==D.Count){Console.WriteLine("{4} Start({0}:{1}) End({2}:{3})",Q.x,Q.y,K.x,K.y,string.Join(", ",S.Select(k=>string.Format("{1}: '{0}'",(char)k.Key,T[I[k.Value]])).ToArray()));return;}goto j;}}}
}
Results for the three test cases:
Down: '1', Right: '2', Up: '3', Left: '4' Start(0:0) End(5:2)
Up: '@', Left: '.', Down: 'e', Right: 'H' Start(1:1) End(0:0)
Right: 'X', Down: 'V', Up: 'I', Left: 'C' Start(0:2) End(2:4)
This is the raw code without "golf", almost 4,000 characters:
class Program
{
static string[] input1 = { "1 2 2 2 2 1",
"1 3 4 4 1 4",
"2 3 1 3 4 2",
"1 4 4 2 1 3",
"2 2 2 3 2 3"};
static string[] input2 = { "@ . .",
"e . @",
"H H @",
};
static string[] input3 = { "0 0 1",
"0 0 1",
"3 2 2",
};
static void Main(string[] args)
{
Resolve(input1);
Resolve(input2);
Resolve(input3);
Console.ReadLine();
}
class N { public int c; public int x, y, i, u; }
static void Resolve(string[] input)
{
int[] ox = { -1, 1, 0, 0 }, oy = { 0, 0, -1, 1 }, I = { 0, 0, 0, 0 };
string[] TXT = { "Left", "Right", "Up", "Down" };
int X, Y, R, n = 0, H = input.Length, W = input[0].Length;
W -= W / 2;
N K = null;
var data = string.Join(" ", input).Where(c => c != ' ').Select(c => new N() { c = c, x = (n % W), y = (n / W), i = n++, u = -1 }).ToList();
n = 0;
var S = data.GroupBy(k => k.c).ToDictionary(k => k.Key, k => n++);
for (; I[0] < 4; I[0]++)
for (I[1] = 0; I[1] < 4; I[1]++)
for (I[2] = 0; I[2] < 4; I[2]++)
for (I[3] = 0; I[3] < 4; I[3]++)
{
if (((1 << I[0]) | (1 << I[1]) | (1 << I[2]) | (1 << I[3])) != 15) continue;
foreach(var Q in data)
{
data.ForEach(p => p.u = -1);
R = 0;
K = Q;
while (K != null)
{
n = I[S[K.c]];
X = K.x + ox[n];
Y = K.y + oy[n];
if (X >= 0 && X < W && Y >= 0 && Y < H)
{
n = X + Y * W;
if (data[n].u < 0)
{
data[n].u = K.i;
K = data[n];
R++;
if (R == data.Count - 1)
{
Console.WriteLine();
Console.WriteLine("Start({0}:{1}) End({2}:{3})", Q.x, Q.y, K.x, K.y);
Console.WriteLine(string.Join(", ", S.Select(k => string.Format("'{0}': {1}", (char)k.Key, TXT[I[k.Value]])).ToArray()));
Action<N> Write = null;
Write = (k) =>
{
if (k.u != -1)
{
Write(data[k.u]);
}
Console.Write(string.Format("({0}:{1}){2}", k.x, k.y, k == K ? "\n" : " => "));
};
Write(K);
return;
}
continue;
}
}
K = null;
}
}
}
Console.WriteLine("Solution not found");
}
}
}
These are the results for the three examples:
Solution not found
Start(1:1) End(0:0) '@': Up, '.': Left, 'e': Down, 'H': Right
(1:1) => (0:1) => (0:2) => (1:2) => (2:2) => (2:1) => (2:0) => (1:0) => (0:0)
Start(0:0) End(1:1) '0': Right, '1': Down, '3': Up, '2': Left
(0:0) => (1:0) => (2:0) => (2:1) => (2:2) => (1:2) => (0:2) => (0:1) => (1:1)