Getting the Vowel Square

-3

2

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

Output not found


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

Output: "not found"

  • 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.

Luis felipe De jesus Munoz

Posted 2018-04-25T13:10:13.337

Reputation: 9 639

2If 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 – 2018-04-25T13:26:27.470

@Therandomguy You will take the one that is at the most top-left, so first check the top and then the left. The result in that test case would be 0-2 – Luis felipe De jesus Munoz – 2018-04-25T13:29:05.470

4I'd recommend relaxing the return if nothing is found to either a false value or an impossible value, rather than a string – Jo King – 2018-04-25T13:37:30.480

1@LuisfelipeDejesusMunoz I phrased my question poorly; can we consistently take only uppercase letters or only lowercase letters in the matrix? – Giuseppe – 2018-04-25T13:40:35.773

@Giuseppe. Yes. Sorry, i misunderstood the question. – Luis felipe De jesus Munoz – 2018-04-25T13:41:21.513

16Having to return an index pair or a string makes this unnecessarily cumbersome in strictly typed languages. – Dennis – 2018-04-25T13:59:10.417

1Agreeing with Dennis, returning any falsy value would seem reasonable. – Nit – 2018-04-26T08:37:17.580

1

This challenge is taken from coderbyte, which is not allowed.

– Laikoni – 2018-04-27T22:22:37.323

1

@Laikoni It's allowed to take the challenge from somewhere else and rewrite the statements. Although {@}OP you should link to the source.

– user202729 – 2018-04-28T01:54:57.710

Answers

7

Python 2, 121 bytes

import re
s=input()
w=s.find(',')
v='[aeiou]'*2
m=re.search(v+'.'*~-w+v,s)
print m and divmod(m.start(),-~w)or'not found'

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).

Lynn

Posted 2018-04-25T13:10:13.337

Reputation: 55 648

6

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!

Arnauld

Posted 2018-04-25T13:10:13.337

Reputation: 111 334

4

Python 3, 143 132 130 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"])[0]

Try it online!

Jonathan Frech

Posted 2018-04-25T13:10:13.337

Reputation: 6 681

Also another interesting but longer solution, but worth posting in case it inspires someone else: Python 3 139 bytes

– musicman523 – 2018-04-25T13:55:28.940

2@musicman523 Thanks; when using Python 3, one can also use the splat operator on strings: {*"aeiou"}. – Jonathan Frech – 2018-04-25T14:12:20.997

You can use < instead of <= as the 2x2 square will never contain all vowels – ovs – 2018-04-25T18:37:15.157

@ovs Wow. true. – Jonathan Frech – 2018-04-25T18:47:22.337

4

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"

Kevin Cruijssen

Posted 2018-04-25T13:10:13.337

Reputation: 67 575

2

Jelly, 26 bytes

e€€ØcaƝ⁺€T€µT,FZḢȯ“¤Ø#"ȯ"»

Indexing is 1-based.

Try it online!

Dennis

Posted 2018-04-25T13:10:13.337

Reputation: 196 637

2

Retina 0.8.2, 82 bytes

(.*¶)*?(.)*?[aeiou]{2}.*¶(?>(?<-2>(.))*)[aeiou]{2}(.|¶)*
$#1-$#3
^[^-]*$
not found

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.

^[^-]*$
not found

If the input doesn't yet contain a - then the match must have failed.

Neil

Posted 2018-04-25T13:10:13.337

Reputation: 95 035

1

Jelly, 35 bytes

FḟØcṆ
ZÇ€T,€
ṡ€2ṡ2ç"JṖFḣ2Uȯ“¤Ø#"ȯ"»

Try it online! (comes with test-suite)

Way too long, but I guess it'll improve. Uses 1-based indexing.

PurkkaKoodari

Posted 2018-04-25T13:10:13.337

Reputation: 16 699

1

APL+WIN, 73 bytes

Prompts for character matrix input:

z←,(,r)/(⍴r)⊤(⍳⍴,r←<⍀<\(2^/m,0)×2^⌿(m←⎕∊'aeiou')⍪0)⋄z,(~×⍴z)↑⊂'not found'

Graham

Posted 2018-04-25T13:10:13.337

Reputation: 3 184

1

Python 2, 134 bytes

f=lambda m,i=0,y=0:m[i+1:]and(m[i][y+1:]and(set(m[i][y:y+2]+m[i+1][y:y+2])<set('aeiou')and(i,y)or f(m,i,y+1))or f(m,i+1))or'not found'

Try it online!

ovs

Posted 2018-04-25T13:10:13.337

Reputation: 21 408

1

Haskell, 146 140 bytes

l x=[0..length x-2]
h x|p<-(!!).(x!!)=([show(i,j)|i<-l x,j<-l(x!!0),all(`elem`"aeiou")[p i j,p(i+1)j,p i$j+1,p(i+1)$j+1]]++["not found"])!!0

Try it online!

Explanation

This just generates a list of possible indices, nothing special:

l x=[0..length x-2]

This is just a little helper, that allows quickly accessing the element at (i,j) with p i j (due to operator precedence it's shorter not to use an operator):

    p<-(!!).(x!!)

This generates a list with all the indices (as strings...) of 2x2 sub-matrices that consist of vowels in order:

h x|             = [show(i,j)|i<-l x,j<-l(x!!0),all(`elem`"aeiou")[p i j,p(i+1)j,p i$j+1,p(i+1)$j+1]]

Now we just need to append the "not found" string:

                  (                                                                                  ++["not found"])

This way we can simply retrieve the first element in this list (since it's generated in order and in case of no such indices, there's always the "not found" string):

                                                                                                                     !!0

ბიმო

Posted 2018-04-25T13:10:13.337

Reputation: 15 345

1

J, 61 bytes

[:'not found'"_`($#:t)@.(#@,~:t=.4:i.~,)2 2+/@,;.3'aoeiu'e.~]

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

u`v@.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, $) 

Galen Ivanov

Posted 2018-04-25T13:10:13.337

Reputation: 13 815