Getting the Vowel Square

Challenge

You will create a function which takes a matrix filled with letters from the alphabet and determine if a 2x2 square composed of vowels exists.

• If a 2x2 square of vowels is found, your function should return the top-left position (row-column) of the square.

• If no 2x2 square of vowels exists, then return the string "not found".

• If there are multiple squares of vowels, return the one that is at the most top-left position in the whole matrix.

Rules

• Matrix must be at least 2x2
• Matrix can only contain letters from the alphabet
• Input can be a String, where each line is separated by \n, ,, ., \t (\n means line break and \t TAB) or an array of strings.
• Vowels are a e i o u.

Example

Given ["abcd", "eikr", "oufj"]

a   b   c   d
e   i   k   r
o   u   f   j

Output: 1-0

Given ["gg", "ff"]

g   g
f   f

Test Cases

Given ["asd", "qie", "euo"]

a s d
q i e
e u o

Output: 1-1

Given ["aqrst", "ukaei", "ffooo"]

a   q   r   s   t
u   k   a   e   i
f   f   o   o   o

Output: 1-2

Given ["ghsdfhsd", "sdfgsdff", "sdfgsdfg"]

g   h   s   d   f   h   s   d
s   d   f   g   s   d   f   f
s   d   f   g   s   d   f   g

• Consider the examples as test cases as well

Update

• If you are going to use 1-based index, please clarify it in your answer.

This is , so the shortest answer in bytes win.

• If there are multiple squares of vowels, return the one that is at the most top-left position in the whole matrix. What should happen with that test case : [[p,d,e,o],[w,v,a,i],[e,u,n,c],[e,e,w,v]] ? – The random guy Apr 25 '18 at 13:26
• I'd recommend relaxing the return if nothing is found to either a false value or an impossible value, rather than a string – Jo King Apr 25 '18 at 13:37
• @LuisfelipeDejesusMunoz I phrased my question poorly; can we consistently take only uppercase letters or only lowercase letters in the matrix? – Giuseppe Apr 25 '18 at 13:40
• Having to return an index pair or a string makes this unnecessarily cumbersome in strictly typed languages. – Dennis Apr 25 '18 at 13:59
• Agreeing with Dennis, returning any falsy value would seem reasonable. – Nit Apr 26 '18 at 8:37

Python 2, 121 bytes

import re
s=input()
w=s.find(',')
v='[aeiou]'*2
m=re.search(v+'.'*~-w+v,s)

Try it online!

I feel like I don't get to use divmod often in Python, haha.

Takes input like "aqrst,ukaei,ffooo".

Explanation

We compute the width w of the matrix by finding the position of the first ,: in this case, that's 5.

Then, we build the regex [aeiou][aeiou]....[aeiou][aeiou] with (w − 1) dots: to match vowels on the next row, we skip (one row − 2 letters + 1 comma) = (w − 1) characters we don't care about.

To turn m.start() back into coordinates, we divmod by (w + 1) (minding the comma).

JavaScript (ES6), 89 88 bytes

Saved 1 byte thanks to @RickHitchcock

Takes input as a comma-separated string.

s=>~(k=s.search((v='[aeiou]{2}')+.{${(w=s.search,+1)-2}}+v))?[k/w|0,k%w]:'not found' Try it online! Java 8, 156 bytes m->{for(int i=0,j;++i<m.length;)for(j=0;++j<m[i].length;)if((m[i][j]+m[i][j-1]+m[i-1][j]+m[i-1][j-1]).matches("[aeiou]+"))return i+"-"+j;return"not found";} 1-indexed output. Try it online. m->{ // Method with String-matrix input and String return-type for(int i=0,j;++i<m.length;) // Loop over the rows, skipping the first for(j=0;++j<m[i].length;) // Inner loop over the columns, skipping the first if((m[i][j]+m[i][j-1]+m[i-1][j]+m[i-1][j-1]) // If four characters in a square appended to each other, .matches("[aeiou]+")) // are only vowels return i+"-"+j; // Return the 1-indexed output return"not found";} // Return "not found" Python 3, 143132130 129 bytes • Thanks to musicman523 for golfing eleven bytes; golfed {m[y][x],m[y][x+1],m[y+1][x],m[y+1][x+1]} to {*(m[y][x:x+2]+m[y+1][x:x+2])}. • Thanks to ovs, golfed {...}<={*"aeiou"} to {...}<{*"aeiou"}; using the fact that five vowels do not fit into four cells. lambda m:([(y,x)for y in range(len(m)-1)for x in range(len(m[y])-1)if{*(m[y][x:x+2]+m[y+1][x:x+2])}<{*"aeiou"}]+["not found"]) Try it online! • Also another interesting but longer solution, but worth posting in case it inspires someone else: Python 3 139 bytes – musicman523 Apr 25 '18 at 13:55 • @musicman523 Thanks; when using Python 3, one can also use the splat operator on strings: {*"aeiou"}. – Jonathan Frech Apr 25 '18 at 14:12 • You can use < instead of <= as the 2x2 square will never contain all vowels – ovs Apr 25 '18 at 18:37 • @ovs Wow. true. – Jonathan Frech Apr 25 '18 at 18:47 Jelly, 26 bytes e€€ØcaƝ⁺€T€µT,FZḢȯ“¤Ø#"ȯ"» Indexing is 1-based. Try it online! Retina 0.8.2, 82 bytes (.*¶)*?(.)*?[aeiou]{2}.*¶(?>(?<-2>(.))*)[aeiou]{2}(.|¶)*$#1-$#3 ^[^-]*$

Try it online! Explanation:

(.*¶)*?

Match an optional number of rows which are stacked into capture group 1.

(.)*?

Match an optional number of columns which are stacked into capture group 2.

[aeiou]{2}

Match two vowels.

.*¶

Match the rest of the line.

(?>(?<-2>(.))*)

Match an equal number of columns on the next line, which are stacked into capture group 3, as the matching empties the capture group 2 stack.

[aeiou]{2}

Match two more vowels.

(.|¶)*

Match the rest of the input.

$#1-$#3

If there's a match, replace the entire input with the number of rows and columns matched.

Try it online!

Explanation:

] a =. 'asd','qie',:'euo'   Let a be the first test case
asd
qie
euo
'aoeiu'e.~] a        creates an equality table between the input and the vowels
1 0 0
0 1 1
1 1 1

2 2<;.3'aoeiu'e.~] a      2 2 u ,. 3 x splits the table into 2x2 overlapping windows
┌───┬───┬─┐
│1 0│0 0│0│
│0 1│1 1│1│
├───┼───┼─┤
│0 1│1 1│1│
│1 1│1 1│1│
├───┼───┼─┤
│1 1│1 1│1│
└───┴───┴─┘

I need to check if all the 4 chars are vowels, so I add the numbers (reduce with addition +/ the flattened list):

2 2+/@,;.3'aoeiu'e.~] a
2 2 1
3 4 2
2 2 1
(t=.4:i.~,)2 2+/@,;.3'aoeiu'e.~] a   flattens the list, finds the first
4                                        occurence of 4 in it and saves it in t

If 4 is not found J returns the length of the list. That's why I compare the result with the length of the flattened list:

(#@,~:t=.4:i.~,)2 2+/@,;.3'aoeiu'e.~] a    (0 means not found; 1 - found)
0

uv@.y     '@.' is 'agenda' - checks the value of y and uses it as an index to the
train of verbs on the left. 0 > u; 1 -> v and so on.

If 0, it simply returns 'not found'
If 1, finds the position by converting the index to a pair of numbers in a number system denoted by the size of the input $#:t: 3 3#:4 (t is the index of 4, #: convert to antibase, the base is 1 1 the shape of the table,$)