Encontre a agulha no palheiro


38

Dado um palheiro retangular de tamanho pelo menos 2x2 composto pelos mesmos caracteres ASCII imprimíveis, produza a localização (contando a partir do canto superior esquerdo) da agulha, que é um caractere diferente.

Por exemplo, se o seguinte palheiro for inserido:

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

A saída deve ser 3,1quando indexada a zero (o que vou usar neste desafio) ou 4,2quando indexada a uma.

O palheiro pode ser composto por qualquer caractere ASCII imprimível:

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

saída: 1,2

e a agulha terá qualquer outro caractere ASCII imprimível:

jjjjjj
j@jjjj
jjjjjj

saída 1,1

Também é possível ter uma agulha no canto:

Z8
88

saída 0,0

88
8Z

saída 1,1

ou para ter a agulha na borda:

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

saída 9,1

Regras e esclarecimentos

  • A entrada e a saída podem ser fornecidas por qualquer método conveniente . Isso significa que você pode receber informações como uma lista de caracteres, como uma única sequência, etc.
  • Você pode imprimir o resultado em STDOUT ou retorná-lo como resultado da função. Indique em sua submissão em que ordem a saída está (por exemplo, horizontal e vertical, conforme usado no desafio ou vice-versa).
  • Um programa completo ou uma função são aceitáveis.
  • Você não escolhe quais caracteres usar. Esse é o desafio.
  • É garantido que o palheiro tenha pelo menos 2x2 de tamanho, por isso é inequívoco qual é a agulha e qual é o feno.
  • Existe apenas uma agulha na entrada e apenas um caractere.
  • As brechas padrão são proibidas.
  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

Caso de teste sugerido: 88\n8Z(com dois caracteres, é claro).
Kevin Cruijssen 01/02

Podemos considerar a entrada como uma matriz multidimensional? ou seja, [['#', '#', '#', '#', '#'], ['#', '#', '#', 'N', '#'], ['#' , '#', '#', '#', '#'], ['#', '#', '#', '#', '#']];
640KB 01/02

2
@gwaugh Gosta de uma lista de caracteres? Sim, tudo bem (e explicitamente chamado de OK).
AdmBorkBork

3
Podemos considerar a entrada como um par de cordas sem novas linhas e a largura (ou altura) do palheiro? ie("########N###########", 5)
meu pronome é monicareinstate

3
@ alguém Sim, embora não tenha um quorum real , acho que isso deve ser permitido.
AdmBorkBork

Respostas:


17

R , 49 47 44 bytes

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

Experimente online!

Recebe entrada como uma matriz, retorna coordenadas indexadas em 1


4
Essa whichtarefa é vergonhosamente suave.
CriminallyVulgar

4
Eu estava tão ansiosa para experimentar este desafio em R, então eu vi isso e decidiu grito no temor vez
Sumner18

9

Perl 6 ,41 38 37 bytes

3 bytes salvos graças a @nwellnhof.

1 byte economizado graças a Jo King.

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

Experimente online!

Explicação

Ele recebe a entrada como uma lista de listas de caracteres e retorna uma lista de comprimento 2 contendo as coordenadas X e Y baseadas em zero da agulha.

Ele funciona aplicando o bloco {[+] ^∞ Z* !<<.&[Z~~]}na entrada e na sua transposição. .&[Z~~]passa por todas as colunas do argumento e retorna Truese todos os elementos forem iguais, Falsecaso contrário. Negamos então todos os valores (para que tenhamos uma lista com um bool por coluna, onde o bool responde à pergunta "A agulha está nessa coluna?"), Multiplique-os por elemento com uma sequência 0,1,2 ,. .. ( True = 1e False = 0) e somar a lista, para que o resultado de todo o bloco seja o número baseado em 0 da coluna onde a agulha foi encontrada.

Melhor abordagem de Nwellnhof, Perl 6 , 34 bytes

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

Experimente online!

Explicação

Geralmente a mesma abordagem, apenas mais eficaz. Ele ainda usa um bloco na matriz e sua transposição, mas agora o bloco converte todas as linhas em Setse verifica o número de elementos. A firstfunção fornece o índice (devido ao :k) da primeira linha que continha mais de 1 elemento. Por esse motivo, a ordem $_e .&[Z]precisava ser trocada.


Boa abordagem! 34 bytes com first(:k), Sete .&[Z].
nwellnhof

@nwellnhof, muito bem feito. Você basicamente encontrou o que eu queria encontrar, mas não conseguiu: --). (Também não fazia ideia de que você poderia escrever .&[Z].)
Ramillies

Em geral, .&[op]não parece ser equivalente, [op] $_mas funciona Zpor algum motivo.
nwellnhof

@JoKing, obrigado!
Ramillies

9

Python 2 , 57 bytes

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

Experimente online!


Uma porta disso para o Python 3 pode ter 62 bytes :

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

A compreensão da lista,, [len(set(v))for v in a]é menor do que o mapa duplo em dois bytes agora, pois precisaria ser convertida em uma lista comolist(map(len,map(set,a)))

Experimente online!


6

Braquilog , 20 bytes

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

Experimente online!

Saídas [I,J], onde Iestão o índice de linha e Jo índice de coluna, ambos indexados em 0.

Estupidamente longo, mas obter índices no Brachylog geralmente é muito detalhado.

Explicação

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]

6

PHP ,99 85 bytes

Usando string sem novas linhas e a largura (ou altura) ('########N###########', 5) como entrada.

  • -5 bytes removendo a chamada chr (), adota o @Titus
  • -9 bytes, tendo a entrada como duas funções args, também adota @Titus
function($a,$l){return[($p=strpos($a,array_flip(count_chars($a,1))[1]))%$l,$p/$l|0];}

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

}

Saída:

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

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

jjjjjj
j@jjjj
jjjjjj
[1,1]

1
1) não é necessário chr: se o segundo parâmetro para strpos for um número inteiro, ele será interpretado como um código ASCII. -> -5 bytes. 2) Dois parâmetros de função $s,$wpodem salvar outros 9 bytes.
Titus

@ Titus, removendo o chr () que é brilhante. THX! Os parâmetros de função também me ocorreram, eu simplesmente não queria executar um conjunto de solicitações de entrada. Vou esclarecer com OP.
640KB 01/02

5

05AB1E , 9 6 bytes

3 bytes salvos mudando o formato de entrada.

A entrada é tomada como uma sequência e um comprimento de linha.
Saída é uma lista baseada em zero do formulário[y, x]

D.mks‰

Experimente online! ou como um conjunto de testes

Explicação

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

Dang, você me venceu. Estava trabalhando em uma resposta. Tinha acabado de terminar um 13-byter. Mas a sua é muito melhor, então marque com +1. :) Esqueci completamente .m..
Kevin Cruijssen 01/02

@KevinCruijssen: Sim. Acho que nunca usei .mantes, mas tinha
quase

5

Python 3 + NumPy , 75 66 bytes

-9 bytes graças a @ ASCII-only

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

Experimente online!

Isso pressupõe que a entrada seja uma matriz NumPy. A saída é indexada a zero, primeiro vertical e depois horizontal.

Ele converte a entrada de charpara intentão calcula a mediana da matriz, que será o caractere do palheiro. Subtraímos isso da matriz, o que torna a agulha o único elemento diferente de zero. Por fim, retorne o índice desse elemento com numpy.where().


1
Como você sabe que a entrada será ASCII (ou seja, cabe em um byte), por que não usar uint8um byte a menos?
Draconis

1
A linguagem deve ser "Python 3 + numpy" aqui, pois o numpy não está incluído na distribuição normal do Python
somente ASCII

@ Draconis era realmente o meu plano, mas introduzia zeros entre os uint8códigos ASCII corretos . Suponho que isso ocorre porque o Python3 usa Unicode como formato de entrada padrão para strings.
hbaderts


1
Está tudo bem, afinal não é apenas baseado em sua solução, mas também não costumo usar numpy de qualquer maneira. Além disso, é meio inevitável que uma solução possa ser muito semelhante de qualquer maneira, uma vez que todas as soluções são públicas e esse é um desafio relativamente fácil
somente ASCII

4

Gelatina , 5 bytes

Saídas [altura, largura] (indexadas em 1).

ŒĠLÐṂ

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

Gelatina , 5 bytes

ŒĠḊÐḟ

Experimente online!


4

Gelatina , 4 bytes

Talvez isso possa ter sido apenas um comentário para o Sr. Xcoder, é bem parecido ...

ŒĠEƇ

Um link monádico que aceita a matriz de caracteres que produz uma lista de um item, a coordenada 1 indexada (linha, coluna), coordenada a partir do canto superior esquerdo.
(... Como um programa completo, com um argumento formatado para que a análise resulte em uma lista de listas de caracteres - ou seja, uma lista de cadeias de caracteres no formato Python - a coordenada única é impressa.)

Experimente online!

Quão?

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

1
Bem ... isso parece limítrofe, já que é inteligente.
Erik the Outgolfer 01 de

4

JavaScript (ES6), 55 bytes

(s)(W)sW[x,y]

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

Experimente online!


JavaScript (ES6),  65  64 bytes

Guardado 1 byte graças a @Neil

[x,y]

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

Experimente online!

Quão?

Procuramos o primeiro personagem c(x,y)r[Y]Yy2×2Y=0 0yY=1y


1
~y&1salva um byte y&1^1.
Neil

4

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 (e -13 mais implicitamente) graças a @dana .

Entrada como matriz de caracteres.

Experimente online.

Explicação:

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

1
124 - a returndeclaração final nunca deve ser atingida. Pode haver uma maneira melhor de manter o loop externo funcionando?
dana

@dana Obrigado! Quanto a: " Pode haver uma maneira melhor de manter o loop externo funcionando? ", Certamente existe; apenas removê-lo para que ele se torne um loop infinito. E então o return"";é inacessível e pode ser removido também. : D Então -21 bytes, graças a você.
Kevin Cruijssen 02/02

Interessante ... Tentei remover a condição do loop externo e estava recebendo um unreachable codeerro. Não sabia que remover a final returnera a solução.
dana

O que exatamente o operador -> faz no loop interno? Eu estava tentando encontrar os documentos java para essa sintaxe, mas não consegui encontrar nada.
KBusc

1
@KBusc São dois operadores: i--e >. :) Veja esta resposta para mais informações. Portanto, o i > 0é executado primeiro, verificando se ié maior que 0. E depois ié diminuído em 1 com i--, antes de entrar no corpo do loop.
Kevin Cruijssen 04/02

3

MATL , 12 8 bytes

tX:XM-&f

Experimente online!

Usando a modefunção como detector majoritário. Retorna índices baseados em 1.

 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 caracteres graças a @LuisMendo


1
@LuisMendo Thanks. Eu não acho que sabia sobre a versão 2 de saída find, mesmo no MATLAB. (Oi, btw!)
sundar - Restabelece Monica

3

Wolfram Language 37 58 bytes

Minha entrada anterior não tratou corretamente o caso em que o "caractere ímpar" estava no canto superior esquerdo da matriz. Isso faz.

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

Counts@Flatten@#lista quantos de cada caractere há na matriz #,.

TakeSmallest[...,1] retorna a contagem menos frequente, na forma de uma regra de associação como <| "Z"->1|>

Keys...[[1]]retorna a "chave" para o único item da associação, o do caractere menos usado. ("Z" no presente caso)

#~Position~...retorna a posição da chave na matriz original #,.


3

Perl 5 -p00, 52 45 bytes

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

45 bytes

52 bytes

Quão

  • -p00: como -nmas também imprimir, modo de parágrafo
  • /^(.)(\1* )*(\1*)|^/ : corresponde a
    • do início $1: primeiro caractere $2,: repetição (não usada) $3,: caracteres antes da "agulha" na linha,$& correspondência inteira
    • ou sequência nula (posição 0) sem captura.
  • $_= : para atribuir a variável de entrada / argumento padrão
  • então $&=~y/ // o número de novas linhas de$&
  • .$". : concatenar com $" (caractere de espaço por padrão) e concatenar
  • length$3 : o comprimento do $3

3

R 42 bytes

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

Experimente online!

Entrada: uma matriz de palheirom

Saída: (row,col) vetor - índice a partir de1


1
Bom trabalho, e bem-vindo ao PPCG! Acredito que sejam 42 bytes, pois o f=pode ser omitido da contagem de bytes, mas não o function(m)=.
BLT

@BLT Eu não tinha certeza disso, mas obrigado pelo aviso :) :)
niko




2

PowerShell , 107 98 82 77 bytes

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

Experimente online!

Toma uma sequência de splatted com LFs. Retorna o local indexado a zero x, y. Desenrolado:

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

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]

Experimente online!

A entrada é tomada como uma sequência multilinha. A saída é indexada em 0



1

Retina 0.8.2 , 41 bytes

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

Experimente online! Indexado a 0. Explicação:

s`

Permitir .a correspondência de novas linhas. Isso custa 3 bytes (o terceiro byte é ?anterior ao ), mas economiza 6 bytes.

(?=(.)+\1)

Olhe para a frente para dois caracteres idênticos. \1então se torna o feno.

(.*?¶)*

Conte o número de novas linhas antes da agulha.

(.*)

Capture o feno à esquerda da agulha.

(?!\1|¶)

Verifique se a agulha não é de feno ou uma nova linha.

.+

Combine o restante do feno para que o resultado o substitua.

$.3,$#2

Saída a largura do feno esquerdo e o número de novas linhas.


1

C # (compilador interativo do Visual C #) , 82 bytes

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

Graças à dana por eliminar 6 bytes!

Experimente online!

Solução antiga, 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);}

Ambos recebem a entrada como uma sequência e um número inteiro, especificando a quantidade de colunas.

Experimente online!


@dana nunca soube que Enumerable.Last()aceitou um delegado, obrigado
Modalidade de Ignorância

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

A entrada é uma matriz de caracteres e inteiro indicando a largura da linha.

A saída é baseada em zero, vertical e horizontal (ou seja, número da linha e número da coluna)

Explicação:

(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

1

Python 3 , 93 89 85 58 bytes

Reescrita completa, tendo a entrada como concatenated string, width:

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

Experimente online!


Resposta original:

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

EDIT: salvou 4 bytes trocando quebra de linha / recuo por ponto e vírgula. Salvo outros 4 bytes usando divmod(obrigado @JonathanFrech).

Experimente online!

Eu sei que isso poderia ser muito mais curto, mas eu só queria tentar uma abordagem em torno dessa dictcompreensão.


1
Usar divmodeconomizaria cinco bytes.
Jonathan Frech

0

MATL , 11 bytes

tX:YmyYk-&f

Saída é linha, depois coluna; Baseado em 1.

Experimente online!

Explicação

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

0

Pitão, 15 14 12 bytes

.Dxz-zh.-z{z

Toma a entrada como o comprimento da linha e a entrada sem linhas e sai como [linha, coluna].
Experimente aqui

Explicação

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

Abordagem antiga

mxJmt{kdeSJ.TB

Experimente aqui

Explicação

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.     

0

Carvão , 40 bytes

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

Experimente online! Link é a versão detalhada do código. Eu devo estar fazendo algo errado, porque isso é quase o tempo que a Retina responde. Explicação:

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

Verifique se o segundo caractere na primeira string também é o primeiro caractere e, se não houver, pegue o primeiro caractere da primeira string, caso contrário, o primeiro caractere da segunda string. Este é então o feno.

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

Continue lendo as strings até encontrar uma string cujo feno seja menor que seu comprimento.

I⌕Eθ⁼ιζ⁰,ILυ

Saída a posição do elemento incompatível e, em seguida, o número de sequências lidas anteriormente.


0

MATLAB, 68 22 bytes

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

Se eu pudesse excluir qualquer caso, como [1,1]nesta solução, poderia ter salvo vários bytes.

Solução atualizada :

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

Agradeço ao @sundar por me ajudar com o problema do caso especial e salvar 42 bytes! Além disso, obrigado a @Luis_Mendo pelas sugestões e me poupando mais 2 bytes!


Eu acho que você pode se livrar da verificação de [1,1]caso usando em mode(v(:))vez de v(1).
sundar - Restabelece Monica

Você precisa agrupar seu código para que ele seja um programa ou uma função completa; você não pode assumir que a entrada está em uma variável v. Além disso, você provavelmente pode substituir ~=por -e remover a 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]}

Experimente online!

Recebe entrada como uma sequência contendo linhas terminadas por nova linha. Retorna um fluxo contendo índices horizontais e verticais indexados a 0.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.