You are sitting with your coworker, having lunch, and bragging to him/her about the latest and supposedly greatest project you've been working on. Getting sick and tired of your constant showcase of egoism, he/she gives you a challenge just so you'll shut up. Being the egoistic and happy-go-lucky person you are, you of course accept (because you must accept each and every challenge). The challenge, as he/she explains it is, given an input of a block of text containing 1 or more of each character in !@#$^&*, output in any reasonable format the coordinates of the switch(es) that is/are "on".

According to your coworker, a switch is a $, and a switch is classified as "on" if and only if it satisfies at least 1 of the following criteria:

  1. It is surrounded by all ^. So...


    results in an "on" switch.

  2. It is surrounded by all &. So...


    results in an "on" switch.

  3. It is completely covered on at least two sides with *. For instance,


    results in an "on" switch, but


    does not, since the switch is not completely covered on any two sides by *s.

  4. There is at least 1 ! and/or 1 @ in any of the corners around it. This does not count if either of these are not in a corner. So...


    results in an "on" switch, since there is at least 1 ! and/or @ in at least 1 of the corners (in the above case, there are 2 valid !s and 1 valid @ in 3 corners). And...


    does not, although there are 2 !s and 1 @, since none of them are in any of the corners.

  5. 1 or more # are not on any sides around the switch, unless at least 1 & surrounds the switch. In other words, if there is at least 1 # present on a side, it overrides all other rules, unless there is also a & present. Therefore:


    results in an "on" switch, although a # exists, since there is an & around the switch, and it follows at least 1 of the above rules. However, if the exclamation point were not present like so:


    The switch would be off, since it does not follow at least one of the above rules. Therefore, even though a switch may be surrounded by a # and a &, it would still be off unless it follows one or more of these rules. Also, there must always be a >=1:1 ratio between &s and #s for the switch to be valid. For instance,


    would still be an invalid switch, although it follows 1 of these rules, since there are 2 #s, but only 1 &, and therefore not a >=1:1 ratio between &s and #s. To make this valid, you must add 1 or more additional &s to any edge in order balance the number of #s and &s out, possibly like so:

    3:2 ratio between &s and #s



    results in an "off" switch, although it follows 1 or more of the above rules, since it contains at least 1 # around it, and no &s to outbalance it.

  6. The valid switches will only be inside an input, and therefore, each valid $ must be surrounded completely by any 8 of the valid characters. For instance, if the entire input were to be:


    the top $ is definitely not a valid switch since the switch is on an edge, and therefore the switch is not completely surrounded by 8 valid characters. In this instance, the switch should not even be considered. However, the switch in the middle is completely valid, and as a matter of fact is "on", since it meets at least one of the above requirements.

To demonstrate, consider this block of characters:


which we can label for coordinates like so, calling the vertical axis y and the horizontal axis x:


3 !@#^^$#!@
2 !@#$$*$&@
1 @$^!$!@&&

  123456789 x

The coordinates must always be returned in an (x,y) format, similar to a two-dimensional coordinate grid. Now, which switches are on? Well, let's first find them all. We can already see that there is 1 in the very top row, and another in the very bottom. However, those are automatically no-ops, since they are not completely surrounded by 8 characters.

Next comes the one in row 2. Specifically, this one:


We can see that there are 3 $ signs in this, but we just want to focus on the one in the middle, and, as you can probably see, it is already invalid, since it has 2 #s around it with no &s to balance them out. Additionally, this does not even follow any of the rules, so even if it was a valid switch, it would be "off" anyways.

Next comes another one in row 2:


Again, only focus on the switch in the middle. This switch is "on", since it has at least 1 ! in at least 1 corner. The coordinates of this one are (5,2).

Moving on, we finally move onto the last switch. This one is also in the second row and appears like so:


and, as you can probably see, this one is also a valid switch, although there is a # surrounding it, since there are 2 other &s to outbalance the #. In addition to that, it also has at least 1 ! in at least 1 of the corners, and therefore not only is the switch valid, but it's also "on". The coordinates of this switch are (7,2).

We have finally reached the end, and have found 2 "on" switches in that entire block on text. Their coordinates are (5,2) and (7,2), which is our final answer, and what the output should be. However, this input was very simple. Inputs can get a lot bigger, as there is not limit on how big the block of text can get. For instance, the input could even be a randomized 200x200 block of text.


  • Standard Loopholes are prohibited.

  • There can't possibly be a built-in for this, but just in case there is (looking at you Mathematica), the use of built-ins that directly solve this are prohibited.

Test Cases:

Given in the format string input -> [array output]:

$!#*$@#@$!   ->  [[7,3],[9,2]]

#^#*#$@$@*&^*#^!^@&* -> [[19,3],[15,3],[8,2]]

**$#@$@@#!  -> [[2,8],[5,8],[6,6],[9,3]]

@*#&@#&*$!&^&*!@*&** -> [[9,4],[9,3]]

More coming soon

Additional Notes

  • You can assume that the input will always be in the form of a complete block (i.e. a rectangle or square)
  • There will never be any other character in the input than those in !@#$^&*.

Remember, this is a so the shortest code wins!

  • 13
    \$\begingroup\$ Seems a bit long and arbitrary. \$\endgroup\$
    – orlp
    Commented Apr 23, 2016 at 20:28
  • \$\begingroup\$ @orlp That's what I'm going for. It's a challenge anyways. Why do you say it's arbitrary though? \$\endgroup\$
    – R. Kap
    Commented Apr 23, 2016 at 20:29
  • 6
    \$\begingroup\$ @R.Kap There's no justification for any of the rules; they seem made up to add complexity for no reason. \$\endgroup\$
    – anon
    Commented Apr 24, 2016 at 3:39
  • 6
    \$\begingroup\$ @QPaysTaxes What justification does this need? These are made up for the sake of the challenge. It is a challenge, and a challenge can literally be anything. All it really needs is a set of rules, an input, and what the output should be based on those rules. \$\endgroup\$
    – R. Kap
    Commented Apr 24, 2016 at 3:42
  • 1
    \$\begingroup\$ I'm not saying I'm agree, I'm explaining why it looks arbitrary. Take my most popular challenge as an example: If you stripped away all the context and just said, "You are given a set of strings. Based on indentation, group them, shuffle the groups, then shuffle the interior groups, but keep members of interior groups at the bottom if they exist", that wouldn't make much sense. However, because it has context, all of those weird rules and restrictions at least pretend to make sense. \$\endgroup\$
    – anon
    Commented Apr 24, 2016 at 4:49

3 Answers 3


Haskell, 304 bytes

import Data.List
f t|Just w<-elemIndex '\n't,h<-t!'\n'=[c|c<-mapM(\a->[2..a-1])[w,h],s<-[(\[x,y]->t!!((h-y-1)*(w+1)+x))<$>mapM(\a->[a-2..a])c],s!!4=='$',foldr1(-)((s!)<$>"#&")<1,or$("@!"/="@!"\\map(s!!)[0,2..8]):zipWith(\c i->all(==c)$(s!!)<$>[0..8]\\(4:i))"^&**"[[],[],[1,7],[3,5]]]

This defines the function f which performs the given task.


JavaScript (ES6), 363 339 312 309 298 bytes

This is a function taking the input as a string and returning a list of coordinates. It's split into 2 main parts: a transformation of switches into a pair of coordinates and its surrounding characters, and a 'is it on' check based on the rules of the challenge on the surrounding characters.


Python 2, 299 297 279 275 261 259 bytes

for y in R(h-2):
 for x in R(len(m[0])-2):
	a=''.join(m[y+o][x:x+3]for o in R(3))
	if(a.count('&')>=a.count('#'))*(a[:4]+a[5:]in('^'*8,'&'*8)or'*'*6in(a[:3]+a[6:],a[::3]+a[2::3])or'!'in a[::2]or'@'in a[::2])*a[4]=='$':print x+2,h+~y

Try it online!

Takes input as a list of strings

Prints the output as a pair of x,y coordinates on each line


Your Answer

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

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