8
\$\begingroup\$

Write a program or function that extracts a word from a wordsearch using its start and end coordinates.

The Input

Your program or function should accept three parameters: the start coordinate, the end coordinate, and a wordsearch from which to extract the word.

  • The start coordinate can be taken in any format.

    • It will always be an integer

    • The bottom left of the grid is (0, 0)

    • You will not be provided with coordinates that go outside the bounds of the grid

    • You will not be provided with coordinates that are not vertical, horizontal, or perfectly diagonal to each other, such as (7, 0) and (0, 6).

  • The end coordinate will be taken in the same format as the start coordinate

  • The wordsearch will be a string, or your language's closest equivalent

    • It will be a grid of characters separated by a single space, with each row on a newline. It can have any height or width - which can be different - but it will always be a rectangle. For example:

      A G O A T C A T
      E A T M E N O W
      W O R D S E A R
      A K L L K J H G
      N P L F G H F D
      A S P L K J H G
      O P I L F G H J
      T F A S E J K L
      
      J H P B L D J L T
      F J L N F N P W H
      W P R D T F J R Q
      J L L L L J H H W
      N P L F H H F D S
      J T P L L J H H K
      P P J L F H H J N
      L F J T F J L L O
      

The Output

You should output a string, or your language's closest equivalent. As no wordsearches in real life ever ask to find a single letter, you may output nothing if the coordinates are the same.

Examples and Test Cases

First Grid Above:
(0, 4) and (4, 0) --> "APPLE"

(4, 0) and (0, 4) --> "ELPPA"

(1, 7) and (4, 7) --> "GOAT"

(0, 5) and (7, 5) --> "WORDSEAR"

(0, 6) and (5, 6) --> "EATMEN"

(0, 6) and (0, 7) --> "EA"

(7, 0) and (0, 7) --> "LHJGLRAA"

----------

Second Grid Above:
(1, 0) and (8, 7) --> "FJLHJJWT"


(1, 4) and (4, 4) --> "LLLL"

(1, 4) and (1, 4) --> "L" or ""
\$\endgroup\$
  • \$\begingroup\$ Somewhat related. \$\endgroup\$ – Martin Ender Mar 5 '16 at 13:15
  • 2
    \$\begingroup\$ You should format the test cases differently. This is way too much repeated text. Just split them into the two grids and go with something like (1,4),(4,4) -> "LLLL" \$\endgroup\$ – Denker Mar 5 '16 at 13:23
  • \$\begingroup\$ @DenkerAffe Done :) \$\endgroup\$ – reubn Mar 5 '16 at 13:29
  • \$\begingroup\$ Can I take the wordsearch as a listoflistofchars? \$\endgroup\$ – CalculatorFeline Mar 5 '16 at 20:15
  • \$\begingroup\$ Test case 4 is incorrect. The correct output is "WORDSEAR" \$\endgroup\$ – CalculatorFeline Mar 5 '16 at 20:21
2
\$\begingroup\$

JavaScript (ES6) 108

(x,y,t,u,g)=>eval("for(g=g.split`\n`.reverse(),r=g[y][2*x];x-t|y-u;)r+=g[y+=u<y?-1:u>y][2*(x+=t<x?-1:t>x)]")

Less golfed

(x,y,t,u,g)=>{
    g=g.split`\n`.reverse();
    for(r = g[y][2*x]; x-t | y-u; )
        r+=g[y += u<y ? -1 : u>y][2*( x += t<x ? -1 : t>x)];
    return r
}   
\$\endgroup\$
0
\$\begingroup\$

Python 3.5 using Numpy, 251 bytes:

def r(t,y,z):import numpy;l=numpy.array([[*i.split()]for i in z.split('\n')]);A,B,C,D=t[0],y[0],t[1],y[1];p=[1,-1];a=p[A>B];b=p[C>D];n=range(A,B+a,a);m=range(C,D+b,b);w=[l[:,i][::-1][p]for i,p in zip([[A]*len(m),n][A!=B],[[C]*len(n),m][C!=D])];return w
  • Takes input in the following format:

    print(''.join(r((start1,start2),(end1,end2),'''grid''')))
    
  • Outputs in the format of a string (e.g. APPLE) as long as the function is called using the format above. Otherwise, a list containing each letter (e.g. ['A','P','P','L','E']) is returned.

Will golf more over time where and when I can.

Try It Online! (Ideone) (Here, input is taken such that the grid is surrounded with double quotes ("") and input on one line, with \ns between each line of the grid. Then, the points are provided in a simple tuple form, with the starting on the second line, and the end on the third.)

Ungolfed code along with Explanation

def r(t,y,z):
    import numpy
    l=numpy.array([[*i.split()]for i in z.split('\n')])
    A,B,C,D=t[0],y[0],t[1],y[1]
    p=[1,-1]
    a=p[A>B]
    b=p[C>D]
    n=range(A,B+a,a)
    m=range(C,D+b,b)
    w=[l[:,i][::-1][p]for i,p in zip([[A]*len(m),n][A!=B],[[C]*len(n),m][C!=D])]
    return w

For the purposes of this explanation, assume this program was run with the inputs ((0,4),(4,0)) and the first grid of the question. Here, I will go through the 2 main parts of the code:

  • l=numpy.array([[*i.split()]for i in z.split('\n')])

    Here, l is a numpy array containing each line of the input in a separate "list". For instance, the first grid in the question, which is:

    A G O A T C A T
    E A T M E N O W
    W O R D S E A R
    A K L L K J H G
    N P L F G H F D
    A S P L K J H G
    O P I L F G H J
    T F A S E J K L
    

    returns this numpy array:

    [['A' 'G' 'O' 'A' 'T' 'C' 'A' 'T']
     ['E' 'A' 'T' 'M' 'E' 'N' 'O' 'W']
     ['W' 'O' 'R' 'D' 'S' 'E' 'A' 'R']
     ['A' 'K' 'L' 'L' 'K' 'J' 'H' 'G']
     ['N' 'P' 'L' 'F' 'G' 'H' 'F' 'D']
     ['A' 'S' 'P' 'L' 'K' 'J' 'H' 'G']
     ['O' 'P' 'I' 'L' 'F' 'G' 'H' 'J']
     ['T' 'F' 'A' 'S' 'E' 'J' 'K' 'L']]
    
  • w=[l[:,i][::-1][p]for i,p in zip([[A]*len(m),n][A!=B],[[C]*len(n),m][C!=D])]

    This is the main list of the function in which all of the letters corresponding to each point on the grid is found. Here, i corresponds to either each integer in n, which is a range object containing every number in the range start1=>end1+1 in increments of +1 if start1<end1 or -1 if the opposite is true. However, i only corresponds to this as long as start1 does not equal end1. Otherwise start1 is returned as many times as the length of m, where m is a range object containing each integer in the range start2=>end2+1 with the same conditions as n, and p corresponds to every integer in m. That being said, let us now walk through this step by step:

    • l[:,i] basically returns a row vector for each column, i, in the array, l. for instance, l[:,0] would return:

      ['A' 'E' 'W' 'A' 'N' 'A' 'O' 'T']
      

      l[:,1] would return:

      ['G' 'A' 'O' 'K' 'P' 'S' 'P' 'F']
      

      so on and so forth. You can read more about different ways of indexing in numpy, including this method, here.

    • Then, after that, the function reverses each array returned, using l[:,i][::-1], since each array is indexed from left to right, but since the point 0,0 on the grid in on the lower left hand corner of the grid, reversing each array would return the index values as if they were being looked for from right to left. For instance, l[:,0][::-1] would return:

      ['T' 'O' 'A' 'N' 'A' 'W' 'E' 'A']
      
    • After this, the function then indexes through that reversed array for the index value corresponding to p, which is your letter, and then adds that to the list being created. For instance, l[:,0][::-1][4], which corresponds to point (0,4), would return A.

    • This process keeps on repeating and adding new values to the list until the range objects are exhausted.

After all that, the output, which is list w, is finally returned. In this case, that would be APPLE if called with print(''.join(r((0,4),(4,0),'''The Grid'''))) or ['A','P','P','L','E'] if it is called without ''.join(). Either way, it returns the correct answer, and we are done!

\$\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.