Extract words with clue numbers in a Crossword puzzle Related: Read a crossword

Task

Given a completed Crossword puzzle, extract the words in it with their respective clue numbers, with "across" (horizontal) and "down" (vertical) words grouped and ordered like a real crossword puzzle.

The words are numbered in the row-major order of their first letters. If an "across" word and a "down" word share the first letter, the two words share one number. (As in regular Crossword, single-letter words don't count; they should not be numbered or included in the output.)

The input is given as a character matrix (or equivalent), with letters being uppercase (or lowercase if you want) and non-letter cells being blank. You can assume that single-letter islands won't appear in the input. If you want, you can assume the grid is rectangular (shorter rows are padded with spaces).

The output must be clearly grouped into "across" and "down" (you don't need to return or print these strings though), and the words must be ordered in the increasing order of the clue number (see test cases).

Standard code-golf rules apply. The shortest code in bytes wins.

Test cases

Input:
MESS 
YAWN 
 SAID
 TYPO
Output:
Across: 1. MESS 5. YAWN 6. SAID 8. TYPO
Down: 1. MY 2. EAST 3. SWAY 4. SNIP 7. DO

Input:
   RECURS
  PARAPET
 TRIANGLE
COOLS RAW
HUTS MATE
ORE CODED
INCLUDES
RETIRES
SYSTEM
Output:
Across: 1. RECURS 7. PARAPET 8. TRIANGLE 9. COOLS 10. RAW 11. HUTS
        12. MATE 13. ORE 14. CODED 15. INCLUDES 17. RETIRES 18. SYSTEM
Down: 1. RAILS 2. ERAS 3. CAN 4. UPGRADES 5. RELATES 6. STEWED
      7. PROTECTS 8. TOURNEY 9. CHOIRS 12. MODEM 14. CURE 16. LIT

Input:
MICROWAVE
U       S
M OCEAN C
M  OWL  A
I SWELL P
E       E
SCHEDULES
Output:
Across: 1. MICROWAVE 3. OCEAN 7. OWL 8. SWELL 9. SCHEDULES
Down: 1. MUMMIES 2. ESCAPES 4. COW 5. EWE 6. ALL

Input:
TAB
A U
BUBBLE
  B O
  LOVED
  E E
Output:
Across: 1. TAB 3. BUBBLE 5. LOVED
Down: 1. TAB 2. BUBBLE 4. LOVE
Charcoal, 118 bytes

ＷＳ⊞υιＰ⪫υ¶≔⟦⟧θＦυ«Ｆι«Ｆ‹ κ«≔✂ιⅈＬι¹η≔⪫ＫＤ⁻Ｌυⅉ↓ωζ≡÷⌕2374ce6⍘↨ＥＫＶ‹ μ²φ³¦²⊞θ⟦ηζ⟧¹⊞θ⟦ηω⟧⁰⊞θ⟦ωζ⟧»→»⸿»⎚Ｅ²⪫ＥΦＥθ⟦⊕μ§⪪§λι ⁰⟧§λ¹⪫λ ¦ 


Try it online! Link is to verbose version of code. Takes input as a rectangular string of newline-terminated lines. Explanation:

ＷＳ⊞υιＰ⪫υ¶


Input the rectangle and print it to the canvas.

≔⟦⟧θ


Start off with no clues.

Ｆυ«Ｆι«


Loop over the rows and columns.

Ｆ‹ κ«


If the current character is not a space, then...

≔✂ιⅈＬι¹η


Get the substring of the current line starting at this character.

≔⪫ＫＤ⁻Ｌυⅉ↓ωζ


Get the substring of the current column starting at this character by reading it from the canvas.

≡÷⌕2374ce6⍘↨ＥＫＶ‹ μ²φ³


Check which orthogonally adjacent characters are spaces.

²⊞θ⟦ηζ⟧


If only the characters to the left and above are spaces, then a word starts both across and down.

¹⊞θ⟦ηω⟧


Otherwise if the character to the left is a space but the character to the right is not, then a word starts across but not down.

⁰⊞θ⟦ωζ⟧


Otherwise if the character above is a space but the character below is not, then a word starts down but not across.

»→»⸿»


Move on to consider the next character on each iteration.

⎚


Clear the canvas.

Ｅ²⪫ＥΦＥθ⟦⊕μ§⪪§λι ⁰⟧§λ¹⪫λ ¦ 


Map over the across and down clues, numbering them all, but keeping only those clues with words in the respective direction.

(Out of interest I tried using just string manipulation instead of canvas operations but that cost 29 bytes.)