Encuentra la aguja en el pajar

38

Dado un pajar rectangular de tamaño de al menos 2x2 compuesto por todos los mismos caracteres ASCII imprimibles, genera la ubicación (contando desde la parte superior izquierda) de la aguja, que es un carácter diferente.

Por ejemplo, si se ingresa el siguiente pajar:

#####
###N#
#####
#####

El resultado debe ser 3,1cuando está indexado a cero (lo que usaré en este desafío) o 4,2cuando está indexado.

El pajar puede estar compuesto de cualquier carácter ASCII imprimible:

^^^
^^^
^N^
^^^
^^^
^^^

salida: 1,2

y la aguja será cualquier otro carácter ASCII imprimible:

jjjjjj
j@jjjj
jjjjjj

salida 1,1

También es posible tener una aguja en la esquina:

Z8
88

salida 0,0

88
8Z

salida 1,1

o para tener la aguja en el borde:

>>>>>>>>>>
>>>>>>>>>:
>>>>>>>>>>

salida 9,1

Reglas y aclaraciones

  • La entrada y salida se pueden dar por cualquier método conveniente . Esto significa que puede tomar la entrada como una lista de caracteres, como una sola cadena, etc.
  • Puede imprimir el resultado en STDOUT o devolverlo como resultado de una función. Indique en su envío en qué orden está la salida (es decir, horizontal y luego vertical, como se usa en el desafío, o viceversa).
  • Un programa completo o una función son aceptables.
  • Usted no consigue escoger qué caracteres a utilizar. Ese es el reto.
  • Se garantiza que el pajar tendrá un tamaño de al menos 2x2, por lo que no es ambiguo cuál es la aguja y cuál es el heno.
  • Solo hay una aguja en la entrada, y solo tiene un carácter de tamaño.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).
AdmBorkBork
fuente
Caso de prueba sugerido: 88\n8Z(con dos caracteres cualquiera, por supuesto).
Kevin Cruijssen
¿Podemos tomar la entrada como una matriz multidimensional? es decir, [['#', '#', '#', '#', '#'], ['#', '#', '#', 'N', '#'], ['#' , '#', '#', '#', '#'], ['#', '#', '#', '#', '#']];
640 KB
2
@gwaugh ¿Te gusta una lista de personajes? Sí, está bien (y explícitamente llamado como OK).
AdmBorkBork
3
¿Podemos tomar la entrada como un par de cuerdas sin líneas nuevas y el ancho (o altura) del pajar? es decir("########N###########", 5)
mi pronombre es monicareinstalar
3
@ alguien Sí, aunque no tiene un quórum real , creo que debería permitirse.
AdmBorkBork

Respuestas:

17

R , 49 47 44 bytes

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

Pruébalo en línea!

Toma la entrada como una matriz, devuelve coordenadas indexadas 1

Kirill L.
fuente
44
Esa whichtarea es vergonzosamente suave.
Criminalmente
44
Estaba tan emocionado de intentar este desafío en R, luego lo vi y decidí llorar con asombro
Sumner18
9

Perl 6 ,41 38 37 bytes

3 bytes guardados gracias a @nwellnhof.

1 byte guardado gracias a Jo King.

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

Pruébalo en línea!

Explicación

Toma la entrada como una lista de listas de caracteres y devuelve una lista de longitud 2 que contiene las coordenadas X e Y basadas en cero de la aguja.

Funciona aplicando el bloque {[+] ^∞ Z* !<<.&[Z~~]}en la entrada y en su transposición. .&[Z~~]pasa por todas las columnas del argumento y devuelve Truesi todos los elementos son iguales, de lo Falsecontrario. Luego negamos todos los valores (por lo que tenemos una lista con un bool por columna, donde el bool responde a la pregunta "¿Está la aguja en esa columna?"), Multiplíquelos por elementos con una secuencia 0,1,2. .. ( True = 1y False = 0) y sume la lista, por lo que el resultado de todo el bloque es el número basado en 0 de la columna donde se encontró la aguja.

El mejor enfoque de Nwellnhof, Perl 6 , 34 bytes

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

Pruébalo en línea!

Explicación

Generalmente el mismo enfoque, solo que más efectivo. Se sigue utilizando un bloque de la matriz y su traspuesta, pero ahora el bloque convierte todas las filas en Setsy controles para el número de elementos. La firstfunción da entonces índice (debido a la :k) de la primera fila que contenía más de 1 elemento. Debido a eso, el orden $_y la .&[Z]necesidad de ser intercambiados.

Ramillies
fuente
Buen enfoque! 34 bytes con first(:k), Sety .&[Z].
nwellnhof
@nwellnhof, muy bien hecho. Básicamente encontraste lo que quería encontrar pero no lo hiciste :—). (Tampoco tenía idea de que podrías escribir .&[Z]).
Ramillies
En general, .&[op]no parece ser equivalente a, [op] $_pero funciona Zpor alguna razón.
nwellnhof
@JoKing, gracias!
Ramillies
9

Python 2 , 57 bytes

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

Pruébalo en línea!


Un puerto de esto a Python 3 puede tener 62 bytes :

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

La comprensión de la lista [len(set(v))for v in a], es más corta que el mapa doble en dos bytes ahora, ya que necesitaría ser convertida en una lista comolist(map(len,map(set,a)))

Pruébalo en línea!

Jonathan Allan
fuente
6

Brachylog , 20 bytes

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

Pruébalo en línea!

Salidas [I,J], donde Iestá el índice de fila y Jel índice de columna, ambos indexados a 0.

Estúpidamente largo, pero obtener índices en Brachylog suele ser muy detallado.

Explicación

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]
Fatalizar
fuente
6

PHP ,99 85 bytes

Usar una cadena sin líneas nuevas y el ancho (o altura) ('########N###########', 5) como entrada.

  • -5 bytes eliminando la llamada chr (), accesorios a @Titus
  • -9 bytes tomando la entrada como dos argumentos de función, también apoyos a @Titus
function($a,$l){return[($p=strpos($a,array_flip(count_chars($a,1))[1]))%$l,$p/$l|0];}

Pruébalo en línea!

Sin golf:

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

}

Salida:

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

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

jjjjjj
j@jjjj
jjjjjj
[1,1]
640 KB
fuente
1
1) no es necesario chr: si el segundo parámetro para strpos es un número entero, se interpretará como un código ASCII. -> -5 bytes. 2) Dos parámetros de función $s,$wpueden guardar otros 9 bytes.
Titus
@Titus, quitando el chr () que es brillante. ¡Gracias! También se me ocurrieron los parámetros de func, simplemente no quería ejecutar una gran cantidad de requisitos de entrada. Aclararé con OP.
640 KB
5

05AB1E , 9 6 bytes

Formato de entrada de conmutación de 3 bytes guardado.

La entrada se toma como una cadena y una longitud de fila.
La salida es una lista del formulario basada en cero[y, x]

D.mks‰

Pruébalo en línea! o como un conjunto de pruebas

Explicación

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
Emigna
fuente
Dang, me ganaste. Estaba trabajando en una respuesta. Acababa de terminar un 13 byter. Pero el tuyo es mucho mejor, entonces +1 en su lugar. :) Se olvidó por completo de .m..
Kevin Cruijssen
@KevinCruijssen: Sí. No creo haberlo usado .mantes, pero estaba razonablemente seguro de haberlo visto en algún momento :)
Emigna
5

Python 3 + NumPy , 75 66 bytes

-9 bytes gracias a @ ASCII-only

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

Pruébalo en línea!

Esto supone que la entrada es una matriz NumPy. La salida está indexada a cero, y primero vertical, luego horizontal.

Convierte la entrada de chara y intluego calcula la mediana de la matriz, que será el carácter de pajar. Restamos eso de la matriz, lo que hace que la aguja sea el único elemento distinto de cero. Finalmente, devuelva el índice de ese elemento con numpy.where().

hbaderts
fuente
1
Dado que sabe que la entrada será ASCII (es decir, cabe en un byte), ¿por qué no usarla uint8para un byte menos?
Draconis
1
El lenguaje tiene que ser "Python 3 + numpy" aquí ya que numpy no está incluido en la distribución normal de Python
solo ASCII
@Draconis ese era en realidad mi plan, pero eso introdujo ceros entre los uint8códigos ASCII correctos . Supongo que esto se debe a que Python3 usa Unicode como formato de entrada estándar para cadenas.
hbaderts
1
66
Solo ASCII
1
Está bien, después de todo, no solo se basa en su solución, sino que tampoco suelo usar numpy de todos modos. Además, es inevitable que una solución sea muy similar de todos modos dado que todas las soluciones son públicas y esto es un desafío relativamente fácil
solo ASCII
4

Jalea , 5 bytes

Salidas [alto, ancho] (1 indexado).

ŒĠLÐṂ

Pruébalo en línea!

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

Jalea , 5 bytes

ŒĠḊÐḟ

Pruébalo en línea!

Sr. Xcoder
fuente
4

Gelatina , 4 bytes

Tal vez esto podría haber sido un comentario para el Sr. Xcoder, es bastante similar ...

ŒĠEƇ

Un enlace monádico que acepta la matriz de caracteres que produce una lista de un elemento, la coordenada indexada 1 (fila, columna) desde la parte superior izquierda.
(... Como un programa completo dado un argumento con formato tal que el análisis resulta en una lista de listas de caracteres, es decir, una lista de cadenas en formato Python, se imprime la coordenada única).

Pruébalo en línea!

¿Cómo?

ŒĠ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
Jonathan Allan
fuente
1
Bueno ... esto parece límite, ya que es inteligente.
Erik the Outgolfer
4

JavaScript (ES6), 55 bytes

Toma entrada como (s)(w), dónde s es una cuerda y wes el ancho de la matriz. Devoluciones[X,y].

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

Pruébalo en línea!


JavaScript (ES6),  65  64 bytes

Guardado 1 byte gracias a @Neil

Toma la entrada como una matriz de caracteres. Devoluciones[X,y].

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

Pruébalo en línea!

¿Cómo?

Buscamos el primer personaje do situado en (X,y) que no aparece en ninguna otra fila r[Y]. Podemos realizar esta prueba en cualquier fila, siempre queYy. Porque se garantiza que la matriz de entrada sea al menos2×2, simplemente podemos usar Y=0 0 Si y es extraño o Y=1 Si y incluso.

Arnauld
fuente
1
~y&1guarda un byte encima y&1^1.
Neil
4

Java 8, 132111 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 (y -13 más implícitamente) gracias a @dana .

Entrada como matriz de caracteres.

Pruébalo en línea.

Explicación:

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
Kevin Cruijssen
fuente
1
124 - the final return statement should never get hit. There might be a better way to keep the outer loop going?
dana
@dana Thanks! As for: "There might be a better way to keep the outer loop going?", there certainly is; just removing it so it becomes an infinite loop. And then the return""; is unreachable and can be removed as well. :D So -21 bytes thanks to you.
Kevin Cruijssen
Interesting... I had tried removing the outer loop condition and was getting an unreachable code error. Didn't know that removing the final return was the fix.
dana
What exactly does the --> operator do in the inner loop? I was trying to find the java docs for that syntax but couldnt find anything
KBusc
1
@KBusc It's two operators: i-- and >. :) See this SO answer for more info. So the i > 0 is executed first, checking if i is larger than 0. And then i is decreased by 1 with i--, before it enters the body of the loop.
Kevin Cruijssen
3

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

sundar - Reinstate Monica
fuente
1
@LuisMendo Thanks. I don't think I knew about the 2 output version of find, even in MATLAB. (Hi, btw!)
sundar - Reinstate Monica
3

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, #.

DavidC
fuente
3

Perl 5 -p00, 52 45 bytes

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

45 bytes

52 bytes

How

  • -p00 : like -n but also print, paragraph mode
  • /^(.)(\1* )*(\1*)|^/ : matches either
    • from start $1: first character, $2: repetition (not used), $3: characters before the "needle" in the line, $& whole match
    • or null string (position 0) no capture.
  • $_= : to assign the default input/argument variable
  • so $&=~y/ // the number of newlines of $&
  • .$". : concatenate with $" (space character by default) and concatenate
  • length$3 : the length of $3
Nahuel Fouilleul
fuente
3

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

niko
fuente
1
Nice job, and welcome to PPCG! I believe this is 42 bytes, since the f= can be omitted from the byte count, but not the function(m)=.
BLT
@BLT I wasn't sure about that but thanks for the heads up :)
niko
2

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!

my pronoun is monicareinstate
fuente
2

J, 22 bytes

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

Try it online!

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

Jonah
fuente
2

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!

Lynn
fuente
You can reorder the output, so you can use the divmod builtin.
Erik the Outgolfer
2

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)
mazzy
fuente
1

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

Black Owl Kai
fuente
1

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.

Neil
fuente
1

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!

Embodiment of Ignorance
fuente
@dana never knew that Enumerable.Last() accepted a delegate, thanks
Embodiment of Ignorance
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
jkenney
fuente
1

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.

steenbergh
fuente
1
Using divmod would save five bytes.
Jonathan Frech
0

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
Luis Mendo
fuente
0

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.     

fuente
0

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.

Neil
fuente
0

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!

DimP
fuente
I think you can get rid of the check for [1,1] case by using mode(v(:)) instead of v(1).
sundar - Reinstate Monica
You need to wrap your code so that it is a full program or a function; you cannot assume that the input is in a variable v. Also, you can probably replace ~= by -, and remove the final ;
Luis Mendo
0

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.

fergusq
fuente