Optimal solution to go to opposite corner of a rectangle
Retina, 54 53 bytes

\d+
$*.
S_`(?&lt;=(.+)¶.*).|\D
T`.`#`.¶|.*$
:m-1=`^#
X
#


Takes input separated by a linefeed and outputs the solution grid followed by the move count.

Try it online!

Explanation

\d+
$*.


Turn both integers into that many .s, i.e. convert them to unary.

S_`(?&lt;=(.+)¶.*).|\D


This builds a grid of .s, by matching each . in the unary height and capturing the unary representation of the width. The S activates split mode which returns the captured strings, and the |\D and _ together ensure that everything else is removed from the string.

T`.`#`.¶|.*$


This turns the last character of each line as well as the entire last line into #s.

:m-1=`^#
X


This uses a ton of options to convert only the first # on the last row to X (we need to make sure that only the last row is affected because of width-1 inputs). m activates multi-line mode which makes ^ match the beginning of lines. -1= tells Retina to perform the substitution only on the last match. Finally, : switches off the default silent mode such that the grid is printed to STDOUT as an intermediate result.

#


Finally, we simply count the number # in the string, which corresponds to the number of moves.