17
\$\begingroup\$

This is essentially the same thing as this question, except harder. You are again to write a program that gets from the lower-left corner of a rectangle to the upper-right corner. However, this time diagonal moves are allowed.

The program will accept an ordered pair (width, height), and use these as the dimensions for a rectangle. Your program will then create an ASCII-art of the solution (use . for an empty square, # for part of the solution, and X for starting square) and count the number of moves it takes to reach the endpoint.

Example

Input: (5, 6)

Output:

....#
....#
...#.
..#..
.#...
X....
Move count: 5

Shortest answer in bytes wins!

\$\endgroup\$
  • 7
    \$\begingroup\$ It isn't, the solutions will require LOTS of editing \$\endgroup\$ – Blue Apr 3 '16 at 12:21
  • 4
    \$\begingroup\$ This challenge, like the suggested duplicate, is a trivially simple problem that is non-trivial to golf, which is a great combination. Despite the similarity, this challenge requires a different approach and well golfed solutions to the previous challenge cannot be trivially amended to be competitive here. \$\endgroup\$ – trichoplax Apr 3 '16 at 12:30
  • \$\begingroup\$ It could do with a more distinguishing title though... \$\endgroup\$ – trichoplax Apr 3 '16 at 12:33
  • \$\begingroup\$ yeah, any ideas? \$\endgroup\$ – ericw31415 Apr 3 '16 at 12:42
  • 1
    \$\begingroup\$ @LuisMendo The minimum is the smallest possible grid; 1 by 1. \$\endgroup\$ – ericw31415 Apr 3 '16 at 16:01
1
\$\begingroup\$

MATL, 38 bytes

'.#X'!iSPXytf0)Jh1w(tzqDQI1()Gd0<?!]XP

Try it online!

Explanation

Let m and n be the sorted inputs, such that m is greater than or equal to n. The code initially builds an mxn matrix as follows:

  • Value 2 along the main diagonal, and on the lower part of the last column. This corresponds to character #. The number of these entries minus 1 is the move count.
  • Value 3 at entry (1,1), corresponding to the X.
  • The remaining entries contain 1, corresponding to character .

If needed, the matrix is now transposed so that it has the desired shape. Note that the first dimension of a matrix is its height, not width, so it corresponds to the second input.

The matrix is then flipped upside down so that X appears at the bottom of the first column, and its entries are used as indices into the string '.#X' to produce the desired 2D char array.

'.#X'    % push this string
!        % transpose into a column
i        % input array
SP       % sort it in non-increasing order
Xy       % identity matrix with that size: fill diagonal with 1, rest entries are 0
tf0)     % linear index of last 1
Jh       % append 1j (imaginary unit): linear index of lowest part of last column
1w(      % fill those entries with 1
tzq      % duplicate. Number of nonzero entries minus 1: this is the move count
D        % display move count (and remove it from the stack)
Q        % add 1. Matrix now contains values 1 and 2
I1(      % set first entry (in linear order) to value 3
)        % use matrix as index into the initial string. Gives 2D char array
Gd0<     % push input array again. Is it decreasing?
?        % if so
  !      %   transpose char array
]        % end
XP       % flip upside down. Implicitly display
\$\endgroup\$
  • 1
    \$\begingroup\$ It doesn't say the move count...? \$\endgroup\$ – ericw31415 Apr 3 '16 at 16:03
  • \$\begingroup\$ @ericw31415 Sorry. Solved now \$\endgroup\$ – Luis Mendo Apr 3 '16 at 16:13
5
\$\begingroup\$

Pyth, 46 45 44 bytes

eSKtMQjsM_mm?sJ,kd?q#J.umtWbbNeSKK\#\.\XhQeQ

Try it here.

Explanation:

move-count-printing:

  K     assign K to...
     Q  the input, a 2-length array...
   tM   with each element decremented
eS      take the max and output it (this is the number of moves)


main path-finding logic:

    mm                     hQeQ  map over x-values and y-values...
        J,kd                     assign J to [x,y]
      ?s                         if both x and y are NOT zero (sum is truthy)...
            ?q#J[...]              if [x,y] is present in [...] (see below)...
                     \#            ... put a # at this position in the output
                       \.          ... else, put a . at this position
                         \X      ... else, put the X here (at [0,0])
jsM_                             reverse and output in the proper format


the [...] part in the code above, which finds positions where #s go:

.u      eSKK  cumulative reduce on <number of moves> elements, starting at K,
                which is [max_x, max_y] as assigned at the beginning
  m    N      map over x and y...
   tWbb       decrement, only if the value is > 0
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 132

Edit 2 bytes saved thx @Neil

(w,h)=>[...Array(--h)].map((_,i)=>R(w-i)+'#'+R(i),--w,R=(n,c='.')=>c.repeat(n>w?w:n>0&&n)).join`
`+`
x${R(w-h,'#')+R(h)}
`+(h>w?h:w)

Test

f=(w,h)=>[...Array(--h)].map((_,i)=>R(w-i)+'#'+R(i),--w,R=(n,c='.')=>c.repeat(n>w?w:n>0&&n)).join`
`+`
x${R(w-h,'#')+R(h)}
`+(h>w?h:w)

function test() {
  var w,h
  [w,h]=I.value.match(/\d+/g)
  O.textContent=f(w,h)
}  

test()
Test <input id=I value="4 5"><button onclick="test()">-></button>
<pre id=O></pre>

\$\endgroup\$
  • \$\begingroup\$ Save 2 bytes by moving the w--,R=... into the map(). \$\endgroup\$ – Neil Apr 3 '16 at 18:40
0
\$\begingroup\$

Javascript (using external library) (235 bytes)

Jeez this was hard! Well...my library wasn't really the right task for this haha. But I liked the challenge

(x,y)=>{r=x-1;s=y-1;m=Math.max(r,s);n=Math.min(r,s);l=_.RangeDown(s,y).WriteLine(z=>_.Range(0,x).Write("",w=>z==0&&w==0?"X":(z==w||(z==s&&w>=n)||(w==r&&z>=n))?"#":"."));return l+"\r\nMove count: "+(l.length-l.split("#").join("").length)}

Link to lib: https://github.com/mvegh1/Enumerable

Code explanation: Create function of 2 variables. Store x-1 and y-1 into variables. Store max and min of those into variables. Create a vertically descending range of numbers from (y-1) for a count of y. For each element on the vertical range, write a line for the current element, according to the complex predicate. That predicate creates an ascending range of integers from 0, for a count of x. For each element in that range, concatenate into 1 string according to a complex predicate. That predicate checks if on bottom left, else checks if on diagonal, else checks we're at X or Y border. Finally, all of that was stored in a variable. Then to get the move count, we basically just count the #'s. Then concatenate that to the stored variable, and return the result

That was a mouthful haha. The screenshot has the wrong bytecount because I found a way to save 4 bytes while posting this

EDIT: I see other answers aren't putting "Move count: " in their output, but mine is. If that isn't a requirement, that shaves a bunch of bytes...

enter image description here

\$\endgroup\$
0
\$\begingroup\$

Python 3, 161 156 bytes

def f(w,h):
 x=[['.']*w for i in[0]*h];i=0
 while i<w or i<h:x[~min(i,h-1)][min(i,w-1)]=['#','X'][i<1];i+=1
 for i in x:print(''.join(i))
 print(max(w,h)-1)

A function that takes input via argument and prints the ascii-art, followed by the move count, to STDOUT.

How it works

The program first creates a list of lists, where each list represents one row of the grid and each element of the component lists is .. Each element that should be # has the property that if the output grid was square, the ordinates representing its location would be equal; hence, looping over some index i and inserting # at location (i, i) would give the desired output. However, the grid is not always square, and thus the indices are clamped to the grid by taking the minimum of the index and width/height (decremented due to zero-indexing) as required. If the index is zero, the current position must be the bottom-left entry, and thus X is instead inserted. Next, the elements in each line are concatenated, and each line is printed to STDOUT. The number of moves is the maximum of the width/height decremented; this is also printed.

Try it on Ideone

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.