buildInitialState[n_,m_]:=If[And[n>1,m>1],
Table[Table[{0,0},{i,n}],{j,m}]//
ReplacePart[#,{1,1,1}->"a"]&//
{#,0}&,
-1];
painterAutomaton[state_,action_]:=Module[{
checkBoundary,checkDry,checkWhite,
pos,step,dir,act,
automatonpos,newpos},
(* Function *)
checkBoundary[pos_,newpos_]:=Dimensions[pos]//
And[0<newpos[[1]]<=#[[1]],0<newpos[[2]]<=#[[2]]]&;
checkDry[pos_,newpos_]:=Extract[pos,newpos+{0,0,1}]<=1;
checkWhite[pos_,newpos_]:=Extract[pos,newpos+{0,0,1}]==0;
(* Data & Parameter *)
{pos,step}=state;
{dir,act}=action;
(* Analysis *)
automatonpos=pos//
Position[#,"a"]&//
#[[1]]&;
newpos=automatonpos//
{#[[1]],#[[2]],#[[3]]}+
Which[
dir=="u",{-1,0,0},
dir=="d",{1,0,0},
dir=="c",{0,0,0},
dir=="r",{0,1,0},
dir=="l",{0,-1,0},
True,{}]&;
(* Results *)
Which[
act=="mv",
If[And[checkBoundary[pos,newpos],checkDry[pos,newpos]],
ReplacePart[pos,automatonpos->0]//
ReplacePart[#,newpos->"a"]&//
{#,step}&,
"Stop"],
And[act=="pa",dir!="c"],
If[And[checkBoundary[pos,newpos],checkWhite[pos,newpos]],
ReplacePart[pos,newpos+{0,0,1}->6]//
{#,step}&,
"Stop"],
True,
"Stop"]
];
mapOneStep[states_]:=Module[{oneStep,changeState},
(* Function *)
oneStep[state_]:=Module[{dir,act,possibleaction,newstate},
dir={"u","d","c","r","l"};
act={"mv","pa"};
possibleaction={dir,act}//
Outer[List,#[[1]],#[[2]]]&//
Flatten[#,1]&;
newstate=state//
changeState;
possibleaction//
Map[painterAutomaton[newstate,#]&,#]&//
Select[#,Not[AtomQ[#]]&]&
];
changeState[state_]:=Module[{pos,step},
{pos,step}=state;
pos//
Map[Map[If[#[[2]]>1,
{#[[1]],#[[2]]-1},
#]&,#]&,#]&//
{#,step+1}&
];
(* Results *)
states//
ParallelMap[oneStep,#]&//
Flatten[#,1]&
];
allPaintedMemberQ[states_]:=Module[{allPaintedQ},
(* Function *)
allPaintedQ[state_]:=state//
#[[1]]&//
Flatten[#,1]&//
Map[#[[2]]&,#]&//
Map[#>=1&,#]&//
Apply[And,#]&;
(* Results *)
states//
Map[allPaintedQ,#]&//
Apply[Or,#]&
];
minStepToPaintAll[n_,m_]:=Module[{initialstate},
(* Data & Parameter *)
initialstate=buildInitialState[n,m];
(* Results *)
If[ListQ[initialstate],
NestWhile[mapOneStep,{initialstate},Not[allPaintedMemberQ[#]]&]//
#[[1,2]]&,
-1]
];
YnVpbGRJbml0aWFsU3RhdGVbbl8sbV9dOj1JZltBbmRbbj4xLG0+MV0sCglUYWJsZVtUYWJsZVt7MCwwfSx7aSxufV0se2osbX1dLy8KCQlSZXBsYWNlUGFydFsjLHsxLDEsMX0tPiJhIl0mLy8KCQl7IywwfSYsCgktMV07CgoKcGFpbnRlckF1dG9tYXRvbltzdGF0ZV8sYWN0aW9uX106PU1vZHVsZVt7CgljaGVja0JvdW5kYXJ5LGNoZWNrRHJ5LGNoZWNrV2hpdGUsCglwb3Msc3RlcCxkaXIsYWN0LAoJYXV0b21hdG9ucG9zLG5ld3Bvc30sCgoJKCogRnVuY3Rpb24gKikKCWNoZWNrQm91bmRhcnlbcG9zXyxuZXdwb3NfXTo9RGltZW5zaW9uc1twb3NdLy8KCQkJQW5kWzA8bmV3cG9zW1sxXV08PSNbWzFdXSwwPG5ld3Bvc1tbMl1dPD0jW1syXV1dJjsKCgljaGVja0RyeVtwb3NfLG5ld3Bvc19dOj1FeHRyYWN0W3BvcyxuZXdwb3MrezAsMCwxfV08PTE7CgoJY2hlY2tXaGl0ZVtwb3NfLG5ld3Bvc19dOj1FeHRyYWN0W3BvcyxuZXdwb3MrezAsMCwxfV09PTA7CgoJKCogRGF0YSAmIFBhcmFtZXRlciAqKQoJe3BvcyxzdGVwfT1zdGF0ZTsKCgl7ZGlyLGFjdH09YWN0aW9uOwoKCSgqIEFuYWx5c2lzICopCglhdXRvbWF0b25wb3M9cG9zLy8KCQlQb3NpdGlvblsjLCJhIl0mLy8KCQkjW1sxXV0mOwoKCW5ld3Bvcz1hdXRvbWF0b25wb3MvLwoJCXsjW1sxXV0sI1tbMl1dLCNbWzNdXX0rCgkJCVdoaWNoWwoJCQkJZGlyPT0idSIsey0xLDAsMH0sCgkJCQlkaXI9PSJkIix7MSwwLDB9LAoJCQkJZGlyPT0iYyIsezAsMCwwfSwKCQkJCWRpcj09InIiLHswLDEsMH0sCgkJCQlkaXI9PSJsIix7MCwtMSwwfSwKCQkJCVRydWUse31dJjsKCgkoKiBSZXN1bHRzICopCglXaGljaFsKCQlhY3Q9PSJtdiIsCgkJCUlmW0FuZFtjaGVja0JvdW5kYXJ5W3BvcyxuZXdwb3NdLGNoZWNrRHJ5W3BvcyxuZXdwb3NdXSwKCQkJCVJlcGxhY2VQYXJ0W3BvcyxhdXRvbWF0b25wb3MtPjBdLy8KCQkJCQlSZXBsYWNlUGFydFsjLG5ld3Bvcy0+ImEiXSYvLwoJCQkJeyMsc3RlcH0mLAoJCQkJIlN0b3AiXSwKCQlBbmRbYWN0PT0icGEiLGRpciE9ImMiXSwKCQkJSWZbQW5kW2NoZWNrQm91bmRhcnlbcG9zLG5ld3Bvc10sY2hlY2tXaGl0ZVtwb3MsbmV3cG9zXV0sCgkJCQlSZXBsYWNlUGFydFtwb3MsbmV3cG9zK3swLDAsMX0tPjZdLy8KCQkJCQl7IyxzdGVwfSYsCgkJCQkiU3RvcCJdLAoJCVRydWUsCgkJCSJTdG9wIl0KXTsKCgptYXBPbmVTdGVwW3N0YXRlc19dOj1Nb2R1bGVbe29uZVN0ZXAsY2hhbmdlU3RhdGV9LAoKCSgqIEZ1bmN0aW9uICopCglvbmVTdGVwW3N0YXRlX106PU1vZHVsZVt7ZGlyLGFjdCxwb3NzaWJsZWFjdGlvbixuZXdzdGF0ZX0sCgoJCWRpcj17InUiLCJkIiwiYyIsInIiLCJsIn07CgoJCWFjdD17Im12IiwicGEifTsKCgkJcG9zc2libGVhY3Rpb249e2RpcixhY3R9Ly8KCQkJT3V0ZXJbTGlzdCwjW1sxXV0sI1tbMl1dXSYvLwoJCQlGbGF0dGVuWyMsMV0mOwoKCQluZXdzdGF0ZT1zdGF0ZS8vCgkJCWNoYW5nZVN0YXRlOwoKCQlwb3NzaWJsZWFjdGlvbi8vCgkJCU1hcFtwYWludGVyQXV0b21hdG9uW25ld3N0YXRlLCNdJiwjXSYvLwoJCQlTZWxlY3RbIyxOb3RbQXRvbVFbI11dJl0mCgldOwoKCWNoYW5nZVN0YXRlW3N0YXRlX106PU1vZHVsZVt7cG9zLHN0ZXB9LAoKCQl7cG9zLHN0ZXB9PXN0YXRlOwoKCQlwb3MvLwoJCQlNYXBbTWFwW0lmWyNbWzJdXT4xLAoJCQkJeyNbWzFdXSwjW1syXV0tMX0sCgkJCQkjXSYsI10mLCNdJi8vCgkJCXsjLHN0ZXArMX0mCgldOwoKCSgqIFJlc3VsdHMgKikKCXN0YXRlcy8vCgkJUGFyYWxsZWxNYXBbb25lU3RlcCwjXSYvLwoJCUZsYXR0ZW5bIywxXSYKXTsKCgphbGxQYWludGVkTWVtYmVyUVtzdGF0ZXNfXTo9TW9kdWxlW3thbGxQYWludGVkUX0sCgoJKCogRnVuY3Rpb24gKikKCWFsbFBhaW50ZWRRW3N0YXRlX106PXN0YXRlLy8KCQkjW1sxXV0mLy8KCQlGbGF0dGVuWyMsMV0mLy8KCQlNYXBbI1tbMl1dJiwjXSYvLwoJCU1hcFsjPj0xJiwjXSYvLwoJCUFwcGx5W0FuZCwjXSY7CgoJKCogUmVzdWx0cyAqKQoJc3RhdGVzLy8KCQlNYXBbYWxsUGFpbnRlZFEsI10mLy8KCQlBcHBseVtPciwjXSYKXTsKCgptaW5TdGVwVG9QYWludEFsbFtuXyxtX106PU1vZHVsZVt7aW5pdGlhbHN0YXRlfSwKCgkoKiBEYXRhICYgUGFyYW1ldGVyICopCglpbml0aWFsc3RhdGU9YnVpbGRJbml0aWFsU3RhdGVbbixtXTsKCgkoKiBSZXN1bHRzICopCglJZltMaXN0UVtpbml0aWFsc3RhdGVdLAoJCU5lc3RXaGlsZVttYXBPbmVTdGVwLHtpbml0aWFsc3RhdGV9LE5vdFthbGxQYWludGVkTWVtYmVyUVsjXV0mXS8vCgkJCSNbWzEsMl1dJiwKCQktMV0KXTsK