16
\$\begingroup\$

I've been doing word searches recently, and I thought it would be so much easier if all of the words read left-to-right. But rewriting all the lines takes a lot of effort! So I'm enlisting code golfers to help.

(Disclaimer: The above story may or may not be remotely accurate.)

Your code will take a rectangular grid and output all of the lines through it in both directions.

The output must contain all 8 rotations of the grid (cardinals and main diagonals), 'read off' top to bottom, left to right. (This means that every "row" will be duplicated - once forwards, and once backwards.)

The line divisions can either be a space or a line break. If you choose spaces, the grid rotation divisions must be line breaks; otherwise, the grid rotation divisions must be two line breaks.

Example input (taken as an array of characters, multiline string, or other reasonable format)

ABCDE
FGHIJ
KLMNO
PQRST

Example output (using the first option for divisions)

ABCDE FGHIJ KLMNO PQRST
E DJ CIO BHNT AGMS FLR KQ P
EJOT DINS CHMR BGLQ AFKP
T OS JNR EIMQ DHLP CGK BF A
TSRQP ONMLK JIHGF EDBCA
P QK RLF SMGA TNHB OIC JD E
PKFA QLGB RMHC SNID TOJE
A FB KGC PLHD QMIE RNJ SO T

The order of the rotations "read off" does not matter as long as all eight cardinals and primary intercardinals are done once.

This is , so shortest code wins. Standard loopholes apply.

\$\endgroup\$
3
  • \$\begingroup\$ Does the grid only contain uppercase letters or can it be the whole printable ASCII? \$\endgroup\$
    – Denker
    Mar 11, 2016 at 10:14
  • \$\begingroup\$ Almost duplicate (without the diagonals) codegolf.stackexchange.com/questions/37940/word-search-puzzle \$\endgroup\$ Mar 11, 2016 at 16:39
  • 1
    \$\begingroup\$ @DigitalTrauma: No, not really - this one doesn't ask you to find any words at all. \$\endgroup\$
    – Deusovi
    Mar 11, 2016 at 16:50

5 Answers 5

5
\$\begingroup\$

Python 3, 181 bytes

def f(s):
 for k in [1,0]*4:
  b=list(zip(*[([' ']*(len(s)-1-n)*k+list(i)+[' ']*n*k)[::-1] for n,i in enumerate(s)]))
  print([' '.join(i).replace(' ','') for i in b])
  if k==0:s=b

Explanation

def f(s):
 for k in [0]*4:                  # loop 4 times, we don't need the index so [0]*4 is shorter than range(4)
  l=len(s)-1                      # number of line

  # rotation of 45°
  a=[(['.']*(l-n)+list(i)+['.']*n)[::-1] for n,i in enumerate(s)]
  # tranform matrice :
  #  ABC      ..ABC      CBA..
  #  DEF  --> .DEF.  --> .FED.
  #  GHI      GHI..      ..IHG
  b=list(zip(*a))                 # transpose 
  #  CBA..      C..
  #  .FED.  --> BF.
  #  ..IHG      AEI
  #             .DH
  #             ..G
  print(' '.join(''.join(i).replace('.','') for i in b))

  # rotation of 90°
  a=[(list(i))[::-1] for n,i in enumerate(s)]
  # tranform matrice :
  #  ABC      CBA
  #  DEF  --> FED
  #  GHI      IHG
  b=list(zip(*a))                 # transpose 
  #  CBA       CFI
  #  FED   --> BEH
  #  IHG       ADG
  print(' '.join(''.join(i) for i in b))
  s=b

Results

>>> f(['ABCDE','FGHIJ','KLMNO','PQRST'])
['E', 'DJ', 'CIO', 'BHNT', 'AGMS', 'FLR', 'KQ', 'P']
['EJOT', 'DINS', 'CHMR', 'BGLQ', 'AFKP']
['T', 'OS', 'JNR', 'EIMQ', 'DHLP', 'CGK', 'BF', 'A']
['TSRQP', 'ONMLK', 'JIHGF', 'EDCBA']
['P', 'QK', 'RLF', 'SMGA', 'TNHB', 'OIC', 'JD', 'E']
['PKFA', 'QLGB', 'RMHC', 'SNID', 'TOJE']
['A', 'FB', 'KGC', 'PLHD', 'QMIE', 'RNJ', 'SO', 'T']
['ABCDE', 'FGHIJ', 'KLMNO', 'PQRST']

>>> f(['ABCDEF','GHIJKL','MNOPQR','STUVWX'])
['F', 'EL', 'DKR', 'CJQX', 'BIPW', 'AHOV', 'GNU', 'MT', 'S']
['FLRX', 'EKQW', 'DJPV', 'CIOU', 'BHNT', 'AGMS']
['X', 'RW', 'LQV', 'FKPU', 'EJOT', 'DINS', 'CHM', 'BG', 'A']
['XWVUTS', 'RQPONM', 'LKJIHG', 'FEDCBA']
['S', 'TM', 'UNG', 'VOHA', 'WPIB', 'XQJC', 'RKD', 'LE', 'F']
['SMGA', 'TNHB', 'UOIC', 'VPJD', 'WQKE', 'XRLF']
['A', 'GB', 'MHC', 'SNID', 'TOJE', 'UPKF', 'VQL', 'WR', 'X']
['ABCDEF', 'GHIJKL', 'MNOPQR', 'STUVWX']

with a cleaner output (189 bytes)

j=' '.join
def f(s):
 for k in [1,0]*4:
  b=list(zip(*[([' ']*(len(s)-1-n)*k+list(i)+[' ']*n*k)[::-1] for n,i in enumerate(s)]))
  print(j(j(i).replace(' ','') for i in b))
  if k==0:s=b

.

>>> f(['ABCDE','FGHIJ','KLMNO','PQRST'])
E DJ CIO BHNT AGMS FLR KQ P
EJOT DINS CHMR BGLQ AFKP
T OS JNR EIMQ DHLP CGK BF A
TSRQP ONMLK JIHGF EDCBA
P QK RLF SMGA TNHB OIC JD E
PKFA QLGB RMHC SNID TOJE
A FB KGC PLHD QMIE RNJ SO T
ABCDE FGHIJ KLMNO PQRST
\$\endgroup\$
5
  • \$\begingroup\$ How do you tranforme a matrix? (code block 2) \$\endgroup\$ Mar 11, 2016 at 14:35
  • \$\begingroup\$ @CatsAreFluffy I added one more step in explanations \$\endgroup\$
    – Erwan
    Mar 11, 2016 at 15:27
  • \$\begingroup\$ I'm pretty sure tranforme isn't a word. (transform?) \$\endgroup\$ Mar 11, 2016 at 15:34
  • \$\begingroup\$ @CatsAreFluffy ^^ ok, i think that was obvious that English is not my native language \$\endgroup\$
    – Erwan
    Mar 11, 2016 at 15:44
  • \$\begingroup\$ Very nice answer! \$\endgroup\$
    – Timtech
    Mar 11, 2016 at 15:52
2
\$\begingroup\$

MATL, 40 bytes

t!tP!tP!GXKZyqXI"IZ}w_w2$:"K@2$Xd!]K!XKx

Input is a 2D char array in Matlab notation:

['ABCDE'; 'FGHIJ'; 'KLMNO'; 'PQRST']

The output contains each "word" on a separate line.

Try it online!

t          % input 2D char array. Duplicate. The original copy will produce
           % the words left to right when displayed
!          % transpose. This will produce the words up to down
tP!        % duplicate, flip upside down, transpose. This will produce the
           % words right to left
tP!        % Same. This will produce the words down to up 
GXK        % push input again. Copy to clipboard K
Zy         % get size (length-2 vector; [4 5] in the example)
q          % decrement by 1 (gives  [3 4] in the example)
XI         % copy to clipboard I
"          % loop: do this twice, consuming the decremented length-2 vector
  I        %   push decremented size vector again
  Z}       %   split into its two elements (pushes 3 and 4 in the example)
  w_w      %   swap, negave, swap (results in -3, 4 in the example)
  2$:      %   binary range: indices of diagonals  ([-3 -2 -1 0 1 2 3 4]
           %   in the first iteration in the example, [-4 -3 -2 -1 0 1 2 3]
           %   in the second)
  "        %   for each
    K      %     push input (first iteration) or its tranposed version (second)
    @      %     push index of diagonal
    2$Xd!  %     extract that diagonal as a row vector
  ]        %   end for each
  K!XKx    %   update clipboard K with transposed version for next iteration
           % end loop. Display
\$\endgroup\$
2
\$\begingroup\$

05AB1E (legacy), 24 bytes

4F=íøDεÐS0:«NFÁ}}øí0мõK,

Input as a list of lines; outputs as list of strings as well, each on a separated newline to STDOUT.

Try it online.

Explanation:

Unfortunately 05AB1E doesn't have an (anti-)diagonals builtin, so 17 of the bytes are to accomplish that in a similar matter as my 05AB1E answer for the Diamondize a Matrix challenge.

Uses the legacy version of 05AB1E, since it can zip/transpose on a list of strings, whereas the new 05AB1E version requires it to be a character-matrix.

4F             # Loop 4 times:
  =            #  Print the current list with trailing newline (without popping)
               #  (which will use the implicit input-list in the first iteration)
   íø          #  Rotate once 90 degrees clockwise:
   í           #   Reverse each line
    ø          #   Zip/transpose; swapping rows/columns
     D         #  Duplicate this rotated grid
      ε        #  Map over each line:
       ÐS0:«   #   Append the length amount of "0"s:
       Ð       #    Triplicate the string
        S      #    Convert the top copy to a list of characters
         0:    #    Replace all these characters in another copy to "0"
           NF  #   Loop the (0-based) map-index amount of times:
             Á #    Rotate once towards the right
            }  #   Close the loop
      }        #  Close the map
       øí      #  Rotate once 90 degrees counterclockwise
         0м    #  Remove all "0"s from each inner string
           õK  #  Remove potential empty strings
             , #  Pop and output this list of diagonals with trailing newline
\$\endgroup\$
1
\$\begingroup\$

Jelly, 13 bytes

KṄḲ
ZUÇƊƬŒDÇ€

Try it online!

Ok, so this is fairly liberal with I/O, but I don't think any of the assumptions are a major issue:

  • The output for each row is in a different order than specified in the question. Because of

    The order of the rotations "read off" does not matter as long as all eight cardinals and primary intercardinals are done once.

    I assumed this was OK

  • The output for half of the diagonals is in "reverse" order (i.e. the output includes PLHD instead of DHLP)

    If this isn't ok, then +3 bytes

  • This is a "link" in Jelly, which is Jelly's version of a function. This takes takes input via ARGV and outputs to STDIN rather than "returning" a value. The ȧ“” in the Footer suppresses Jelly implicitly outputting the return value for the link

  • This takes input as a matrix of characters. This seems to be allowed by

    Example input (taken as an array of characters, multiline string, or other reasonable format)


How it works

KṄḲ - Helper link. Takes a string S on the left
K   - Join S by spaces
 Ṅ  - Print S
  Ḳ - Split S on spaces

ZUÇƊƬŒDÇ€ - Main link. Takes a matrix M of characters
   Ɗ      - Group the previous 3 links into a monad f(M):
Z         -   Transpose
 U        -   Reverse
  Ç       -   Call the helper link
    Ƭ     - Yield [f(M), f(f(M)), f(f(f(M))), f(f(f(f(M))) = M]
            This outputs and returns all rotations of M
     ŒD   - Get the diagonals of each
       ǀ - Call the helper link on each diagonal
\$\endgroup\$
1
  • \$\begingroup\$ "(i.e. the output includes PLHD instead of DHLP)" it correctly includes both, as per spec \$\endgroup\$ Feb 1, 2022 at 17:11
1
\$\begingroup\$

JavaScript (Node.js), 135 bytes

f=(s,n=8)=>n?[s.flatMap(t=>t.join``||[]),...f([...Array(L=(s+0).length)].map((_,y,p)=>p.map((_,x)=>(s[y+x-L>>1]||0)[(x-y)/2])),n-1)]:[]

Try it online!

Slow. Complexity O(n^256) Proof that the rotation work Fast run

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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