g | x | w | all
Bytes Lang Time Link
110AWK250909T195624Zxrs
005Vyxal230513T023841Zlyxal
049Arturo230513T014600Zchunes
015Stax230513T010800Zemirps
091Lua230419T215945Zbluswimm
078Julia230419T175134ZAshlin H
098Scala230419T114255Z138 Aspe
043Ruby221019T195050ZJordan
009APL Dyalog Unicode191216T005316ZAdá
062Befunge98 PyFunge191023T044722Zdavid
077PowerShell191016T192615Zmazzy
538C VC++ Visual Studio 2017190218T151312Zder bend
058Python 3190202T083159Zsteenber
111C# .NET Core190207T083858ZHille
042R190203T235936Zniko
104Java 8190206T193711Zjkenney
074C clang190202T004215ZAZTECCO
063Python 2190206T171837ZTriggern
047Python 2190204T185853Zlynn
081C gcc190205T114026Zuser7740
045Perl 5 p00190202T072509ZNahuel F
057Python 2190201T182216ZJonathan
111Java 8190201T151656ZKevin Cr
066Python 3 + NumPy190201T162303Zhbaderts
022J190204T044835ZJonah
nan190204T015026Zsome_guy
142Kotlin190203T150615ZJohnWell
039APL+WIN190203T075702ZGraham
107C# Visual C# Interactive Compiler190201T154351Zthe defa
111C# .NET190201T151851ZKevin Cr
082C# Visual C# Interactive Compiler190201T175344ZGymhgy
nanPerl 6190201T145936ZRamillie
064Haskell190202T085149ZLaikoni
077Perl 5 n0190202T001015ZXcali
081Röda190201T231805Zfergusq
058Wolfram Language190201T150219ZDavidC
6822MATLAB190201T164608ZDimP
9985PHP190201T154701Z640KB
040Charcoal190201T182131ZNeil
041Retina 0.8.2190201T175128ZNeil
040Octave190201T170703ZLuis Men
008MATL190201T150541ZSundar R
012Pyth190201T165010Zuser4854
011MATL190201T164615ZLuis Men
055JavaScript ES6190201T150350ZArnauld
004Jelly190201T163222ZJonathan
005Jelly190201T161444ZMr. Xcod
00605AB1E190201T141159ZEmigna
044R190201T143756ZKirill L
020Brachylog190201T145211ZFatalize
093Python 3190201T143829ZKateba

AWK, 110 bytes

a[NR]=$0{for(i=0;i++<NF;$i!~x&&y=$i){c[$i]++;!x&&x=$i}}END{for(;j++<NR;)if(x=index(a[j],1~c[x]?x:y))print x,j}

Attempt This Online!

Vyxal, 5 bytes

ƒ⊍hÞḟ

Try it Online!

Takes a list of lines. Outputs 0-indexed [row, column]. Vyncode does nothing here apparently, it decided.

Explained

ƒ⊍hÞḟ
ƒ⊍    # reduce by set xor
  h   # get the first of that
   Þḟ # find it's multidimensional index

Arturo, 49 bytes

$[s w]->/%index s first select tally s[k v][1=v]w

Try it

Takes input as a single line and a width. Returns a 0-indexed [row col] pair.

Stax, 15 bytes

this can probably be golfed down a bit as there's a lot of register shenanigans i'm not a huge fan of. takes an array of a single string with a width

Ç║æ░·╝;J╕╤¢ⁿÿì<

Try it online! (With test cases)

This is Packed Stax, which unpacks to the following:

Stax, 17 bytes

Nc|!IYxhX%yx/2l|u

Run and debug it

N                 # get the string
 c|!              # get the rarest element
    I             # get the first index in the string of this
     Y            # store that in register Y
      xh          # get the width
        X         # and store this value in register x
         %        # modulo with what was stored in register Y
          yx      # register y and register x from above
            /     # divide them
             2l   # create an array of the top two elements on the stack
               |u # and put it in a format which can be printed

Lua, 103 91 bytes

s,l=...s:gsub('.',load'c=...b=b or not s:find(c..c,1,1)and s:find(c,1,1)')print(b%l-1,b//l)

Try it online!

Ungolfed version:

s,l=...                                           --Take in haystack and line width as args
s:gsub('.',function (d)                           --For each character in s
    b=b or not s:find(c..c,1,1)and s:find(c,1,1)  --If there is only one instance of c, store location
end)
print(b%l-1,b//l)                                 --Print results

Julia, 78 bytes

s->(n=argmin(x->count(x,'
's),s);q=split(s);~=findlast;b=~(n.∈q);(n~q[b],b))

Attempt This Online!

This function takes input as a single string, which probably isn't the most efficient approach. The output is 1-indexed.

-19 bytes thanks to MarcMush: add a newline to the haystack to guarantee that the needle is always the least frequent character, even in a 2x2 haystack.

Interestingly, concatenating a character literal with a string variable doesn't require an operator in Julia. Apparently, it's parsed just like numeric literal coefficients with variables. This saves a byte here, which is the best thing to come out of Julia's choice of concatenation operator.

Scala, 98 bytes

Golfed version. Try it online!

def f(m:Seq[String])=m.transpose.map(_.toSet.size).indexOf(2)::m.map(_.toSet.size).indexOf(2)::Nil

Ungolfed version. Try it online!

object Main {
  def main(args: Array[String]): Unit = {
    val tests = Seq(
      """#####
        |###N#
        |#####
        |#####""".stripMargin,
      """^^^
        |^^^
        |^N^
        |^^^
        |^^^
        |^^^""".stripMargin,
      """jjjjjj
        |j@jjjj
        |jjjjjj""".stripMargin,
      """Z8
        |88""".stripMargin,
      """88
        |8Z""".stripMargin
    )
    
    val f: Seq[String] => Seq[Int] = m => m.transpose.map(_.toSet.size).indexOf(2) :: m.map(_.toSet.size).indexOf(2) :: Nil

    tests.foreach { test =>
      val v = test.split("\n")
      v.foreach(println)
      println("   -> " + f(v) + "\n")
    }
  }
}

Ruby, 43 bytes

Takes the haystack as a single line and its width as arguments. Returns the 0-based row, then column as an array.

->s,w{(/[^#{s[/(.)(?=\1)/]}]/=~s).divmod w}

Attempt This Online!

APL (Dyalog Unicode), 9 bytesSBCS

Anonymous tacit prefix function. In a sense, this is actually a kind of poly-glot, as it takes as argument either a character matrix or a list of strings, with the code meaning something else in each case. Always returns [row,column] in which ever index origin is currently active. (APL lets you choose.)

⍸↑=∊~∘∊∩/

Try it online!

If the argument is a matrix, the function works like this:

∩/ intersection reduction of each row. Since there will be at least one all-hay row, this gives us at least one hay character. And since every row has at least one hay character, the intersection will always empty out the row that has the needle character.

ϵnlist (flatten) this, giving us one or more hay characters

 then…

~ remove all such characters from…

 the ϵnlisted (flattened) argument, leaving just the needle

↑= Boolean matrix indicating where the matrix equals the needle

the indices where true

If the argument is a list of strings, the function works like this:

∩/ intersection reduction of the strings. Since only one string will have a needle, and all strings have hay, this will give us one or more hay characters without the needle character.

ϵnlist (flatten) this, giving us the one or more hay characters

 then…

~ remove all such characters from…

 the ϵnlisted (flattened) argument, leaving just the needle

↑= Boolean matrix indicating where the matrix constructed by merging the strings equals the needle

the indices where true

Befunge-98 (PyFunge), 62 bytes

~:04p~-k#v>~:a-!2j6$_04g-!..@
-#v_$$1+0>  >~:a
.;>04g-#;_1+^@.

Try it online!

Output is: column row

PowerShell, 107 98 82 77 bytes

$l=@{}
$args|%{if($_-10){$l.$_+=$x++,+$y}else{$x=0;++$y}}
$l|% v*|? c*t -eq 2

Try it online!

Takes a splatted string with LFs. Returns zero-indexed location x,y. Unrolled:

$locations=@{}                      # make a hashtable. key=char, value=location array
$args|%{
    if($_-10){                      # if current char is not LF
        $locations.$_+=$x++,+$y     # add $x,$y to hashtable value and move $x to next pos
    }else{
        $x=0;++$y                   # move $x,$y to next line
    }
}
$locations|% Values|? Count -eq 2   # find and output location array with 2 elements (x,y)

C (VC++) Visual Studio 2017, 538bytes

well there can be a couple of Bytes be stripped of if the haystack and needle string is Input via command line Parameters but i can not get it to work proberly then so the haystack and needle string is hard coded in the source (ugly….. 😢) takes 50bytes

Maybe anyone wants to improve on that

anyway the Code i came up with is

#include"stdafx.h"
#define r v[1][i]
#define i(x,y) if(x==y)
void main(){const char*v[]={"haystack.exe","#####\n##+##\0" };int i=0,z=0,s=0,c=r,f=c,a=-1,h=0;do{c=r;i(c,f)a++;i(a,1)h=c;if(h&&c!=h&&c!=10)break;i(c,10){z++;s=0;}}while(s++,i++,c);printf("%d,%d",s-1,z);}

the ungolfed variant is

#include "stdafx.h"

int main(/*int argc, const char * argv[]*/)
{
    const char * argv[] = {"haystack.exe","#####\n##+##\0" };
    int i = 0,row = 0, col = 0;
    char character = argv[1][i];
    char firstChar = character;
    int howMany = -1;
    char hay = '\0';
    do
    {
        char character = argv[1][i];
        if (character == firstChar)
        {
            howMany++;
        }
        if (howMany ==1)
        {
            hay = character;
        }
        if ((hay != '\0') && (character != hay)&&(character!='\n'))
        {
            break;
        }
        if (character == '\n')
        {
            row++;
            col = 0;
        }
        col++;
        i++;
    } while (character != '\0');
    printf("%d,%d", col-1, row);
    while (1);
    return 0;
}

i dont expect this to be explained

Python 3, 93 89 85 58 bytes

Complete rewrite taking input as concatenated string, width:

lambda g,w:divmod(g.index({g.count(c):c for c in g}[1]),w)

Try it online!


Original answer:

def k(g):t=''.join(g);return divmod(t.index({t.count(c):c for c in t}[1]),len(g[0]))

EDIT: Saved 4 bytes by swapping linebreak/indent for semicolons. Saved another 4 bytes by using divmod(thanks @JonathanFrech).

Try it online!

I know this could be a lot shorter, but I just wanted to try an approach around this dict comprehension.

C# (.NET Core), 135 111 bytes

S=>{for(int x=0,y;;x++)try{for(y=0;;y++)if(S[x][y]!=(S[0][0]==S[0][1]?S[0][0]:S[1][0]))return y+","+x;}catch{}}

Try it online! (111 bytes)
Try it online! (135 bytes)

New one:

for (int x = 0, y; ; x++)
    try
    {
        for (y = 0; ; y++)
            if (S[x][y] != (S[0][0] == S[0][1] ? S[0][0] : S[1][0]))
                return y + "," + x;
    }
    catch { }

Previous one:

int i = 0, y;
var r = "";
for (; i < S.Length; i++)
    for (y = 0; y < S[i].Length; y++)
        r = S[i][y] != (S[0][0] == S[0][1] ? S[0][0] : S[1][0]) ? i + "," + y : r;
return r;

R 42 bytes

function(m)which(ave(m,m,FUN=length)==1,T)

Try it online!

Input: a haystack matrix m

Output: (row,col) vector - index starting at 1

Java 8, 104 Bytes

(x,w)->{int i=0,p=x.length;for(;i<p;i++)if(x[i]!=x[(i+1)%p]&&x[i]!=x[(i+2)%p])break;return i/w+","+i%w;}

Input is array of char, and integer indicating row width.

Output is zero-based, vertical then horizontal (i.e., row number then column number)

Explanation:

(x,w)->{
    int i=0, p=x.length;
    for (;i<p;i++)          //iterate through characters in x
      if (x[i]!=x[(i+1)%p] && x[i]!=x[(i+2)%p])    //compare x[i] with the two subsequent characters in array, wrapping around if necessary
        break;
    return i/w+","+i%w;}  //return row number then column number, zero-based

C (clang), 74 bytes

h(char*s,z,x){for(s+=z--;*s==*--s|*s==s[-1];)z--;printf("%d,%d",z%x,z/x);}

Try it online!

DEGOLF

int h(char*s,int z,int x){// z = string size, x = row size

 for(s+=z--;
 // move pointer just over the end of the string 
 // and move z counter to the end of string

*s-*--s?   ==>  *s==*--s|  @ceilingcat suggestion 
 // if the previous element is different we will check if the next element is also different
 // if not the result is 1 and the iteration continue
 // in the first iteration it will be different because the pointer is just  over the end

 *s-s[-1]? ==> changed to *s==s[-1]   @ceilingcat suggestion 
 // the second check returns 0 if the char changed again so it was the needle
 // if not it's because in the first iteration the first check finded a difference just because the pointer was just over the end

 /*0:1*/   :1;)z--;


 printf("%d,%d",z%x,z/x);
}

Python 2, 63 bytes

lambda s,w:divmod(s.find({s.count(c):c for c in s}[1]),w)[::-1]

Try it online!

Expects a string with no newlines and the width of the haystack as arguments.

Explanation:

                         # get a dictionary of (number of occurrences : character)
                         {s.count(c):c for c in s}
                         # only one character will have one occurrence, so get that character
                         .........................[1]
                  # get the 0-indexed index of the needle character
                  s.find(............................)
           # flat_index / width will give us how many rows "down" the needle is (the y-value)
           # the remainder will give us how many columns "over" the needle is (the x-value)
           # so take the divmod and reverse the returned values to get (x,y)
           divmod(....................................,w)[::-1]
# anonymous function, takes haystack string with no newlines and haystack width
lambda s,w:

Python 2, 53 47 bytes

lambda s,w:divmod(s.find(min(s,key=s.count)),w)

Try it online!

Call as f("########N###########", 5) (allowed in a comment). Outputs (y, x).

Erik saved 6 bytes, suggesting rearranging the output + using divmod. Thanks!

C (gcc), 81 bytes

Takes input as three pointers: one to the array, and two to the dimensions. Returns by modifying the dimensions to be the coordinates of the needle.

i;f(char*a,int*w,int*h){for(i=0;*a==a[i];i++);i=i-1?i:*a==a[2];*h=i/ *w,*w=i%*w;}

Try it online!

Degolf

i;f(char*a,int*w,int*h)
{
  for(i=0;*a==a[i];i++); // Count the number of elements equal to
                         // the one at (0,0)
  i=i-1?i:*a==a[2];  // Special case i==1, because it is 
          // ambiguous whether the needle is at 0 or 1 there.
  *h=i/ *w,*w=i%*w; // Modify pointers to indicate coordinates.
  // the space between i/ and *w is required, as /* starts a comment
}

Perl 5 -p00, 52 45 bytes

/^(.)(\1*
)*(\1*)|^/;$_=$&=~y/
//.$".length$3

45 bytes

52 bytes

How

Python 2, 57 bytes

lambda m:[map(len,map(set,a)).index(2)for a in zip(*m),m]

Try it online!


A port of this to Python 3 can be 62 bytes:

lambda m:[[len(set(v))for v in a].index(2)for a in(zip(*m),m)]

The list comprehension, [len(set(v))for v in a], is shorter than the double map by two bytes now as it would need to be cast to a list like list(map(len,map(set,a)))

Try it online!

Java 8, 132 111 bytes

m->{int c=m[0][0],i=0,j;for(c=m[1][0]!=c?m[1][1]:c;;i++)for(j=m[i].length;j-->0;)if(m[i][j]!=c)return i+","+j;}

-8 bytes (and -13 more implicitly) thanks to @dana.

Input as character-matrix.

Try it online.

Explanation:

m->{                    // Method with char-matrix parameter and String return-type
  int c=m[0][0],        //  Character to check, starting at the one at position 0,0
      i=0,j;            //  Index integers
  for(c=m[1][0]!=c?     //  If the second character does not equal the first:
         m[1][1]        //   Use the character at position 1,1 instead
        :c;             //  Else: keep the character the same
      ;i++)             //  Loop `i` from 0 indefinitely upwards:
    for(j=m[i].length;j-->0;)
                        //   Inner loop `j` in the range (amount_of_columns, 0]:
      if(m[i][j]!=c)    //    If the `i,j`'th character doesn't equal our character to check:
        return i+","+j;}//     Return `i,j` as result

Python 3 + NumPy, 75 66 bytes

-9 bytes thanks to @ASCII-only

lambda x:where(x.view('i')-median(x.view('i')))
from numpy import*

Try it online!

This assumes that the input is a NumPy array. The output is zero-indexed, and first vertical, then horizontal.

It converts the input from char to int then calculates the median of the array, which will be the haystack character. We subtract that from the array, which makes the needle the only non-zero element. Finally, return the index of that element with numpy.where().

J, 22 bytes

$#:(i.~.{~1 i.~#/.~)@,

Try it online!

NB. returns answer in (row, column) format.

Python3

Well I've never tried to do code golf before and I really can't compete with some of these really good solutions, so I've prepared a long-form answer just to demonstrate how I would solve this problem. This function takes a 2-D list of characters of any size as its input.

(edited to shorten the function up as much as I could)

def f(i):
    a = None
    b = 0
    c = None
    d = 0
    h = len(i)
    for y in range(h):
        for x in range(len(i[y])):
            if a == None:
                a = i[y][x]
            elif a != None:
                if i[y][x] != a:
                    c = i[y][x]
            if i[y][x] == a:
                b += 1
            elif i[y][x] == c:
                d += 1
    if b == 1:
        n = a
    elif d == 1:
        n = c
    for y in range(h):
        for x in range(len(i[y])):
            if i[y][x] == n:
                return (x, y)

Here is a longer version that demonstrates the example input. If you run this script it will show you the 2-D array and the needle (randomly generated every time) as well as solve it with the find_needle() function.

# Code golf! Needle in a haystack challenge
# sgibber2018 (my email handle)
"""
Notes: I can't really compete with what's already been done but I'm doing
       it just to do it. 
"""

import random

input_height = 10
input_width = 10
example_input = [["#" for x in range(input_width)] \
    for y in range(input_height)]
needle_spot_y = random.randrange(input_height)
needle_spot_x = random.randrange(input_width)
example_input[needle_spot_y][needle_spot_x] = "!"

for y in range(input_height):
    print(example_input[y])

# and now for the algorithm itself:
def find_needle(example_input):
    # declare two variables to count different char types
    c1 = None
    c1_count = 0
    c2 = None
    c2_count = 0
    # iterate through the whole list
    height = len(example_input)
    for y in range(height):
        for x in range(len(example_input[y])):
            # assign c1 or c2 accordingly
            if c1 == None:
                c1 = example_input[y][x]
            elif c1 != None:
                if example_input[y][x] != c1:
                    c2 = example_input[y][x]
            # count the symbols based on whether or not they match
            if example_input[y][x] == c1:
                c1_count += 1
            elif example_input[y][x] == c2:
                c2_count += 1
    # Find the value with just one increment
    if c1_count == 1:
        needle = c1
    elif c2_count == 1:
        needle = c2
    # go back through the list and find the needle and get it's pos
    for y in range(height):
        for x in range(len(example_input[y])):
            if example_input[y][x] == needle:
                return (x, y)

print(find_needle(example_input))

The function find_needle() takes a 2-D list and returns the coordinates of the character that only has one count. I could probably shorten this up a little but I don't think I can compete with the existing Python3 answer which is mighty impressive. How do you calculate the size of your answers?

Kotlin, 142 bytes

The result is zero based [vertical,horizontal].

{d:List<String>->val h=if(d[0][0]!=d[0][1])d[1][0]
else d[0][0]
var a=""
for(r in d.indices)for(c in d[r].indices)if(h!=d[r][c])a="[$r,$c]"
a}

Try it online!

APL+WIN, 39 bytes

Index origin =1. Prompts for character matrix as a string input followed by row width. Outputs row by column index position.

(,(⍳i÷n)∘.,⍳n←⎕)[((1=+/m∘.≡m)/⍳i←⍴m←⎕)]

Try it online! Courtesy of Dyalog Classic

Explanation:

⍳i←⍴m←⎕ Prompt for string and create a vector of indices from 1 to length string.

(1=+/m∘.≡m) Boolean vector identifying position of unique character in string.

(...)/⍳i Use Boolean to select index position of unique character.

,⍳n←⎕ Prompt for row width of character matrix and create a vector of indices.

,(⍳i÷n)∘., Create a nested vector of row by column indices of character matrix.

(...)[...] Select row by column index position of unique character.

C# (Visual C# Interactive Compiler), 109 108 107 bytes

First() => Last() for -1 byte

currying for -1 byte thanks to Embodiment of Ignorance

a=>w=>{var d=a.Where(b=>b!=a[0]).Select(b=>a.IndexOf(b));return d.Count()>1?(0,0):(d.Last()%w,d.Last()/w);}

Try it online!

C# .NET, 133 112 111 bytes

m=>{var c=m[0][0];c=m[1][0]!=c?m[1][1]:c;for(int i=0,j;;i++)for(j=m[i].Count;j-->0;)if(m[i][j]!=c)return(i,j);}

-1 byte thanks to @EmbodimentOfIgnorance.

Port of my Java answer, but with a List<List<char>> input and int-tuple output, instead of char[][] input and string output.

Try it online.

C# (Visual C# Interactive Compiler), 82 bytes

x=>w=>{int y=x.IndexOf(x.GroupBy(c=>c).Last(g=>g.Count()<2).Key);return(y%w,y/w);}

Thanks to dana for shaving off 6 bytes!

Try it online!

Old solution, 106 bytes

n=>m=>{var z=n.Distinct();int d=n.IndexOf(n.Count(c=>c==z.First())>1?z.Last():z.First());return(d%m,d/m);}

Both take input as a string and an integer specifying the amount of columns.

Try it online!

Perl 6, 41 38 37 bytes

3 bytes saved thanks to @nwellnhof.

1 byte saved thanks to Jo King.

{map {[+] ^∞Z*!<<.&[Z~~]},$_,.&[Z]}

Try it online!

Explanation

It takes the input as a list of lists of characters and returns list of length 2 containing zero-based X and Y coordinates of the needle.

It works by applying the block {[+] ^∞ Z* !<<.&[Z~~]} on the input and on its transpose. .&[Z~~] goes through all columns of the argument and returns True if all the elements are the same, False otherwise. We then negate all the values (so we have a list with one bool per column, where the bool answers the question "Is the needle in that column?"), multiply them element-wise with a sequence 0,1,2,... (True = 1 and False = 0) and sum the list, so the result of the whole block is the 0-based number of the column where the needle was found.

Nwellnhof's better approach, Perl 6, 34 bytes

{map *.first(:k,*.Set>1),.&[Z],$_}

Try it online!

Explanation

Generally the same approach, just more effective. It still uses a block on the array and its transpose, but now the block converts all rows intoSets and checks for the number of elements. The first function then gives index (due to the :k) of the first row that contained more than 1 element. Because of that, the order of $_ and .&[Z] needed to be swapped.

Haskell, 64 bytes

f s=[(r,c)|c<-[0..],r<-[0..length s-1],any(notElem$s!!r!!c)s]!!0

Try it online! f takes a list of lines and returns zero-indexed (row,column).

Works by iterating through the columns and rows and looking for a character which does not appear on all rows.

Perl 5 -n0, 77 bytes

$t=(@b=sort/./g)[0]eq$b[1]?pop@b:$b[0];++$y&/\Q$t/g&&say"$y,",pos for /.+$/mg

Try it online!

Output is row,column starting from the top left, 1-indexed

Röda, 81 bytes

f a{i=indexOf;l=i("
",a)+1;chars a|sort|count|[[_2,_1]]|min|i _[1],a|[_%l,_1//l]}

Try it online!

Takes input as a string containing newline-terminated lines. Returns a stream containing 0-indexed horizontal and vertical indexes.

Wolfram Language 37 58 bytes

My earlier entry did not correctly handle the case where the "odd character out" was at the upper left corner of the matrix. This does.

#~Position~Keys[TakeSmallest[Counts@Flatten@#,1]][[1]]&

Counts@Flatten@# lists how many of each character are in the array, #.

TakeSmallest[...,1] returns the least frequent count, in the form of an association rule such as <| "Z"->1|>

Keys...[[1]] returns the "key" to the only item in the association, that of the least used character. ("Z" in the present case)

#~Position~... returns then position of the key in the original matrix, #.

MATLAB, 68 22 bytes

[r,c]=find(v~=v(1));if size(r,1)>1 disp([1,1]);else disp([r,c]);end;

If I could exclude any one case, such as [1,1] in this solution, I could have saved several bytes.

Updated solution:

@(v)find(v-mode(v(:)))

Thanks to @sundar for helping me with the special case problem and saving 42 bytes! Also, thanks to @Luis_Mendo for the suggestions and saving me another 2 bytes!

PHP, 99 85 bytes

Using string without newlines and the width (or height) ('########N###########', 5) as input.

function($a,$l){return[($p=strpos($a,array_flip(count_chars($a,1))[1]))%$l,$p/$l|0];}

Try it online!

Ungolfed:

function need_hay( $a, $l ) {

    // identify the "needle" by counting the chars and 
    // looking for the char with exactly 1 occurrence
    // note: this is 1 byte shorter than using array_search()
    $n = array_flip( count_chars( $a, 1 ) )[1];

    // find the location in the input string
    $p = strpos( $a, $n );

    // row is location divided by row length, rounded down
    $r = floor( $p / $l );

    // column is remainder of location divided by row length
    $c = $p % $l;

    return array( $c, $r );

}

Output:

#####
###N#
#####
#####
[3,1]

^^^
^^^
^N^
^^^
^^^
^^^
[1,2]

jjjjjj
j@jjjj
jjjjjj
[1,1]

Charcoal, 40 bytes

≔§⎇⌕θ§θ¹ηθ⁰ζSθW⁼№θζLθ«⊞υωSθ»I⌕Eθ⁼ιζ⁰,ILυ

Try it online! Link is to verbose version of code. I must be doing something wrong because this is almost as long as the Retina answer. Explanation:

≔§⎇⌕θ§θ¹ηθ⁰ζ

Check whether the second character in the first string is also the first character, and take the first character of the first string if so otherwise the first character of the second string if not. This is then the hay.

SθW⁼№θζLθ«⊞υωSθ»

Keep reading strings until a string whose hay is less than its length is found.

I⌕Eθ⁼ιζ⁰,ILυ

Output the position of the mismatching element and then the number of strings previously read.

Retina 0.8.2, 41 bytes

s`(?=(.)+\1)(.*?¶)*(.*)(?!\1|¶).+
$.3,$#2

Try it online! 0-indexed. Explanation:

s`

Allow . to match newlines. This costs 3 bytes (3rd byte is the ? before the ) but saves 6 bytes.

(?=(.)+\1)

Look ahead for two identical characters. \1 then becomes the hay.

(.*?¶)*

Count the number of newlines before the needle.

(.*)

Capture the hay to the left of the needle.

(?!\1|¶)

Ensure that the needle isn't hay or a newline.

.+

Match the rest of the hay so that the result replaces it.

$.3,$#2

Output the width of the left hay and the number of newlines.

Octave, 40 bytes

@(x){[r,c]=find(x-mode(+x(:))) [c,r]}{2}

Port of @sundar's MATL answer. Output is a two-element vector with 1-based column and row indices.

Try it online!

MATL, 12 8 bytes

tX:XM-&f

Try it online!

Using the mode function as the majority-detector. Returns 1-based indices.

 t           % duplicate the input
  X:         % turn the copy into a linear array
    XM       % find the arithmetic mode of that (the 'haystack' character)
      -      % Subtract that from the original input
       &f    % find the position of the non-zero value in that result

-4 characters thanks to @LuisMendo

Pyth, 15 14 12 bytes

.Dxz-zh.-z{z

Takes input as the length of the row and the input without lines and outputs as [row, column].
Try it here

Explanation

.Dxz-zh.-z{z
       .-z{z    Subtract one of each character from the input.
      h         Take the first.
    -z          Remove all instances from the input.
  xz            Find the remaining character in the input.
.D          Q   Take the result divmod the (implicit) length of the row.

Old approach

mxJmt{kdeSJ.TB

Try it here

Explanation

mxJmt{kdeSJ.TB
           .TBQ   Take the (implicit) input and its transpose...
m      d          ... and for each...
   mt{k           ... deduplicate each row...
 xJ     eSJ       ... and find the index of the largest.     

MATL, 11 bytes

tX:YmyYk-&f

Output is row, then column; 1-based.

Try it online!

Explanation

t    % Implicit input. Duplicate
X:   % Linearize into a column
Ym   % Compute mean (characters are converted to ASCII codes)
y    % Duplicate from below: pushes input again
Yk   % Closest value: gives the input value that is closest to the mean
-    % Subtract, element-wise. Gives non-zero for the value farthest from the mean
&f   % Two-output find: gives row and column indices of nonzeros. Implicit display

JavaScript (ES6), 55 bytes

Takes input as \$(s)(w)\$, where \$s\$ is a string and \$w\$ is the width of the matrix. Returns \$[x,y]\$.

s=>w=>[(i=s.indexOf(/(.)\1+(.)/.exec(s+s)[2]))%w,i/w|0]

Try it online!


JavaScript (ES6),  65  64 bytes

Saved 1 byte thanks to @Neil

Takes input as a matrix of characters. Returns \$[x,y]\$.

m=>m.some((r,y)=>r.some((c,x)=>!m[p=[x,y],~y&1].includes(c)))&&p

Try it online!

How?

We look for the first character \$c\$ located at \$(x,y)\$ which does not appear anywhere in another row \$r[Y]\$. We can perform this test on any row, as long as \$Y\ne y\$. Because the input matrix is guaranteed to be at least \$2\times 2\$, we can simply use \$Y=0\$ if \$y\$ is odd or \$Y=1\$ if \$y\$ is even.

Jelly, 4 bytes

Maybe this could've just been a comment for Mr. Xcoder it is pretty similar...

ŒĠEƇ

A monadic link accepting the matrix of characters which yields a list of one item, the 1-indexed (row, column) co-ordinate from top-left.
(...As a full program given an argument formatted such that parsing results in a list of lists of characters -- that is a list of strings in Python format -- the single coordinate is printed.)

Try it online!

How?

ŒĠEƇ - Link: matrix, M
ŒĠ   - multi-dimensional indices grouped by Value
     -  ...due to the 2*2 minimum size and one needle this will be a list of two lists one
     -     of which will have length one (the needle coordinates as a pair) and the other
     -     containing all other coordinates as pairs
   Ƈ - filter keeping those for which this is truthy:
  E  -   all equal?
     -   ... 1 for the list of length 1, 0 for the list of at least 3 non-equal coordinates

Jelly, 5 bytes

Outputs [height, width] (1-indexed).

ŒĠLÐṂ

Try it online!

ŒĠLÐṂ – Monadic link / Full program. Takes a list of strings M as input.
ŒĠ    – Group the multidimensional indices by their values (treating M as a matrix).
  LÐṂ – And retrieve the shortest group of indices (those of the unique character).

Jelly, 5 bytes

ŒĠḊÐḟ

Try it online!

05AB1E, 9 6 bytes

Saved 3 bytes switching input format.

Input is taken as a string and a row-length.
Output is a zero-based list of the form [y, x]

D.mks‰

Try it online! or as a Test Suite

Explanation

D           # duplicate the input string
 .m         # get the least frequent character
   k        # get its index in the string
    s       # swap the row length to the top of the stack
     ‰      # divmod the index of the least frequent char with the row length

R, 49 47 44 bytes

function(m,`?`=which)m==names(?table(m)<2)?T

Try it online!

Takes input as a matrix, returns 1-indexed coordinates

Brachylog, 20 bytes

c≡ᵍ∋Ȯ&;I∋₎;J∋₎gȮ∧I;J

Try it online!

Outputs [I,J], where I is the row index and J the column index, both 0-indexed.

Stupidely long, but getting indexes in Brachylog is usually very verbose.

Explanation

c                       Concatenate the Input into a single string
 ≡ᵍ                     Group identical characters together
   ∋Ȯ                   Ȯ is a list of One element, which is the needle character
     &;I∋₎              Take the Ith row of the Input
          ;J∋₎          Take the Jth character of the Ith row
              gȮ        That character, when wrapped in a list, is Ȯ
                ∧I;J    The output is the list [I,J]

Python 3, 93 bytes

def f(s):x=s.find("\n")+1;return[(i%x,i//x)for i,c in enumerate(s)if s.count(c)<2and" "<c][0]

Try it online!

Input is taken as a multiline string. Output is 0-indexed