Read a crossword

11

Inspired by this question about packing into this format.

Occasionally I see a completed crossword and being as I am, I can't be bothered to find out what the solutions to the clues actually were.

Input:

  • A 2D string (any format, newline separated, 2d list etc.)
  • Blank squares will be represented with a (space character)
  • Every other square will be in the lower case alphabet.
  • You may assume that the input will be padded with spaces to form a rectangle

Output:

  • Each word found
    • You must search for words along and down
    • Words will be at least two letters long
    • If there are duplicate words, you have to output them for each time they appear
  • You don't have to do any validation
  • Words may be outputted in any order
  • No strict formatting rules

Test cases:

word
e e 
step
t d 

word, step, west, reed
---
pies
 not
  no
wasp

pies, not, no, wasp, in, eons, stop
---
igloo
    n
word

igloo, word, on

Blue

Posted 2016-04-03T16:31:45.083

Reputation: 26 661

Answers

8

Pyth - 11 10 8 7 bytes

saved one bytes thanks to @issacg.

t#cjsCB

Try it online here.

t#               Filter by if len > 1
 c               Chop by whitespace by default
  j              Join by newlines
   sCB           Input, implicit and its transpose in one list

Maltysen

Posted 2016-04-03T16:31:45.083

Reputation: 25 023

@Maltysen Wonderful. – Leaky Nun – 2016-04-03T17:20:52.230

1Pyth wins. As always. – Leaky Nun – 2016-04-03T17:41:55.190

1You can save one byte by removing the d, which makes j join on newlines, which are still chopped by c ... ) – isaacg – 2016-04-04T00:19:00.907

@isaacg that's really cool, thanks – Maltysen – 2016-04-04T00:27:15.113

2

CJam, 14 bytes

{_z+S*S%{,(},}

An unnamed block that expects a list of (padded) strings on top of the stack and leaves a list of words instead.

Test it here.

Explanation

_z    e# Duplicate and transpose the grid.
+     e# Append the transpose to the original grid.
S*    e# Join all lines by spaces to ensure that we don't get words 
      e# spanning multiple lines.
S%    e# Split around spaces, discarding empty segments.
{,(}, e# Filter: keep only those strings with length 2 or greater.

Martin Ender

Posted 2016-04-03T16:31:45.083

Reputation: 184 808

1

JavaScript (ES6), 83 bytes

s=>(s+` `+[...(t=s.split`
`)[0]].map((_,i)=>t.map(t=>t[i]).join``)).match(/\w\w+/g)

Neil

Posted 2016-04-03T16:31:45.083

Reputation: 95 035

0

Pyke, 9 bytes

,+Fdc#t(s

Try it here!

Or 7 bytes prettified

,+Fdc#t

Try it here!

Blue

Posted 2016-04-03T16:31:45.083

Reputation: 26 661

0

Pyth, 18 bytes

Lm:d"\S\S+"1byQyCQ

Try it online!

Sample input:

["pies"," not","  no","wasp"," t  "]

Sample output:

[['pies'], ['not'], ['no'], ['wasp'], []]
[[], ['in', 'at'], ['eons'], ['stop']]

How it works:

Lm:d"\S\S+"1byQyCQ                                 The "1" here is mode
                    assign('Q',eval_input())       "1" which means show
                    @memoized                      all matches
L                   def y(b):                               v
 m:d"\S\S+"1b           return map(lambda d:regex(d,"\S\S+",1),b)
             yQ     imp_print(y(Q))
               yCQ  imp_print(y(transpose(Q)))

Leaky Nun

Posted 2016-04-03T16:31:45.083

Reputation: 45 011

0

Haskell, 58 bytes

import Data.List
f x=[w|w@(_:_:_)<-words=<<x++transpose x]

Usage example: f ["pies"," not"," no","wasp"] -> ["pies", "not", "no", "wasp", "in", "eons", "stop"].

How it works: split each of the lines of the input and the transposition of it at spaces it into a single list words. Keep those that match (_:_:_), i.e. have at least two letters.

nimi

Posted 2016-04-03T16:31:45.083

Reputation: 34 639

0

C++14, 209207201 bytes

Ridiculously high amount of bytes... but oh well. Transpose matrix, split string. Easy. Too bad no native function for transposing

[](vector<string>; m){auto t=m;int C=size(m[0]),j=0;for(;++j<C*C;)t[j%C][j/C]=m[j/C][j%C];for(j=0;++j<C+C;){stringstream Z(j<C?m[j]:t[j-C]);string s;while(getline(Z,s,' '))cout<<(size(s)>1?s+' ':"");}}

Ungolfed:

using S=vector<string>;
[](S m){
  S t=m;
  int C=size(m[0]),j=0;
  for(;j<C*C;++j)t[j%C][j/C]=m[j/C][j%C]; // Transpose
  for(j=0;j<C+C;++j){ // since rectangle matrix, we can iterate like so
    stringstream Z(j<C?m[j]:t[j-C]); // Get string from m or t
    string s;
    while(getline(Z,s,' '))
      cout<<(size(s)>1?s+' ':"");
  }
}

How to use it (note you must enforce padding as the question states):

using S = vector<string>;[](S m) { ... }({"pies", " not", "  no", "wasp"});

STDQ

Posted 2016-04-03T16:31:45.083

Reputation: 131