Letras entre duas letras

22

Escreva um programa que aceite uma única palavra em minúscula como entrada e produza o número de pares de letras que possuem o mesmo número de letras entre eles na palavra e no alfabeto.

Por exemplo, na palavra "natureza", temos 4 pares:

  • nr: como existem três letras entre eles dentro da palavra (a, t, u) e três letras entre eles no alfabeto (o, p, q)
  • ae: como existem três letras entre eles dentro da palavra (t, u, r) e três letras entre eles no alfabeto (b, c, d)
  • tu: como não existem letras entre eles dentro da palavra e não há letras entre eles no alfabeto
  • tr: como existe uma letra entre eles dentro da palavra (u) e uma letra entre eles no (s) alfabeto (s)

Como existem quatro pares, a saída neste caso deve ser 4.

ghosts_in_the_code
fonte
10
A redação pode ser esclarecida um pouco mais.
Optimizer
Eu não entendi a pergunta. Como as letras a , t , u estarão dentro de nr ? E todos os exemplos a seguir ... (cc @flodel)
nicael
Se você soletrar a natureza, n e r estão na 1ª e 5ª posição. Portanto, existem três letras entre eles. Eles são a, t e u, na 2ª, 3ª e 4ª posição. É isso que o texto quer dizer com três letras entre n e r dentro da palavra .
usar o seguinte comando
@flodel Você está certo na edição; Eu perdi o quarto par.
ghosts_in_the_code
E se a palavra fosse rjjjnfffr? Seria um par ( nr) ou dois pares ( nre rn)? E que tal abzab? São dois pares de abou um?
Não que Charles

Respostas:

5

Pitão, 19 bytes

lfqF-MSMCT.cCUBCMz2

Experimente online: Demonstração

Explicação:

lfqF-MSMCT.cCUBCMz2
                 z   read a string from input
               CM    convert into list of ascii-values
            CUB      create a list of pairs (ascii-value, index in string)
          .c      2  all combinations of length 2
 f                   filter for combinations T, which satisfy:
        CT              transpose T ((ascii1, ascii2), (index1, index2)
      SM                sort each list
    -M                  create the the difference for each
  qF                    check if they are equal
l                    print the number of remaining combinations
Jakube
fonte
4

R, 110 bytes

function(s){w=strsplit(s,"")[[1]]
O=outer
n=nchar(s)
sum(abs(O(r<-match(w,letters),r,"-"))==O(1:n,1:n,"-"))-n}

Degolfado:

F = function(s){
   chars = strsplit(s,"")[[1]]
   num_chars = nchar(s)
   letter_rank = match(chars, letters)
   rank_dist = abs(outer(letter_rank, letter_rank, "-"))
   position_dist = outer(1:num_chars, 1:num_chars, "-")
   return(sum(rank_dist == position_dist) - num_chars)
}

F("nature")
# [1] 4
F("supercalifragilisticexpialidocious")
# [1] 25
modelo
fonte
3

Oitava, 41 bytes

@(s)nnz(abs(s-s')==(t=1:(u=nnz(s)))-t')-u
alefalpha
fonte
3

CJam, 36 bytes

r:A,{)Aew}%1>{{:B,B0=BW=-z)=}%}%e_:+

Experimente online.

geokavel
fonte
2

J, 27 bytes

#-:@-~#\+/@,@:=&(|@-/~)3&u:

Uso:

   (#-:@-~#\+/@,@:=&(|@-/~)3&u:) 'nature'
4

Explicação:

#-:@-~#\+/@,@:=&(|@-/~)3&u:
      #\                    lengths of input prefixes (1,2,...,length)
                       3&u: codepoints of input
               &(     )     with the last two do parallel:
                 |@-/~      create difference table with itself and take absolute values
              =             compare the elements of the two difference tables
        +/@,@:              sum the table              
#   -~                      subtract the length of the input (self-similar letters)
 -:@                        half the result (each pair was accounted twice)

Experimente online aqui.

randomra
fonte
2

CJam, 25 bytes

l:T,_2m*{_:-\Tf=:-z=},,\-

Experimente online

Explicação:

l     Get input.
:T    Store in variable T for later use.
,     Calculate length.
_     Copy for use at the very end.
2m*   Use Cartesian power to calculate all possible position pairs.
{     Start filter.
  _     Create copy of index pair.
  :-    Calculate difference between indices.
  \     Swap copy of index pair to top.
  T     Get input string stored in variable T.
  f=    Extract the letters for the index pair.
  :-    Calculate difference of the two letters.
  z     Take the absolute value.
  =     Compare index difference and letter difference.
},    End filter.
,\
-     Pairs of identical indices passed the filter. Eliminate them from the
      count by subtracting the length of the input.
Reto Koradi
fonte
2

JavaScript (ES6), 98 bytes

f=w=>(p=0,q="charCodeAt",[...w].map((c,a)=>{for(b=a;w[++b];)p+=Math.abs(w[q](a)-w[q](b))==b-a}),p)

Uso

f("nature")
=> 4

Explicação

f=w=>(
  p=0,                                 // p = number of pairs
  q="charCodeAt",
  [...w].map((c,a)=>{                  // iterate through each character of input
                                       // a = character A index
    for(b=a;w[++b];)                   // iterate through the remaining input characters
                                       // b = character B index
      p+=                              // add 1 to p if true or 0 if false
        Math.abs(w[q](a)-w[q](b))==b-a // compare absolute difference of character codes
                                       //     to difference of indices
  }),
  p                                    // return p
)
user81655
fonte
1

Python 2, 91 caracteres

lambda i:sum(y-x==abs(ord(i[y])-ord(i[x]))for x in range(len(i))for y in range(x+1,len(i)))
TFeld
fonte
1

MATLAB, 84 bytes

s=input('');disp(sum(diff(nchoosek(find(s),2),[],2)==abs(diff(nchoosek(s,2),[],2))))

Esta linha pede uma string como entrada. Em seguida, ele cria todos os pares possíveis de letras e faz o mesmo para os índices correspondentes. Em seguida, determinamos se a diferença (absoluta) dos valores corresponde para finalmente somar todos os casos em que ocorre. O resultado é exibido na janela de comando.

slvrbld
fonte
1

JavaScript ES7, 93

Usando compreensão de array . ES6 com .map.map.mapé 2 bytes mais longo.

Teste a execução do snippet abaixo com o Firefox

f=s=>[for(x of s)x.charCodeAt()].map((a,i,s)=>s.map((b,j)=>t+=j>i&(b>a?b-a:a-b)==j-i),t=0)&&t

document.write('nature'+'\n'+f('nature'))

edc65
fonte
1

PowerShell, 114 100 bytes

param($a)$b=$a.length;0..($b-1)|%{$i=$_;($_+1)..$b|%{$o+=[math]::Abs(+$a[$_]-$a[$i])-eq($_-$i)}};+$o

Bem direto, mas usa alguns truques.

  • param(..)pega nossa entrada e salva $a.
  • Definimos uma variável temp $bcomo a .lengthnossa entrada. Isso economiza um byte mais tarde.
  • 0..($b-1)|%{..}é o equivalente a um for($i=0;$i-le($b-1);$i++){..}loop, mas muito mais curto.
  • No entanto, precisamos definir variáveis $ipara manter isso em ...
  • ($_+1)..$b|%{..}o próximo forloop, uma vez que $_é apenas posicional ao loop interno.
  • Em seguida, usamos uma chamada .NET extensa para verificar se o valor absoluto entre nossos dois caracteres (aqui usamos a conversão implícita com prepending +para salvar um monte de bytes) é importante -eqpara a diferença de posição na matriz. Como recebemos explicitamente entradas em minúsculas, não precisamos fazer conversão de casos. Esta declaração retornará um Trueou False.
  • Abusamos descaradamente a conversão implícita novamente para acumular esse resultado $o, então Trueadicionamos 1, enquanto Falseadicionamos 0.
  • Quando os loops terminam, produzimos $o. Observe que precisamos fazer o mesmo truque de conversão para int +para evitar a impressão Falsese não houver correspondências.
AdmBorkBork
fonte
0

Ruby, 74

 ->s{[*0...s.size].permutation(2).count{|i,j|(s[i].ord-s[j].ord).abs==j-i}}

Nada super interessante aqui. Eu adoraria usar, eval("s[i].#{["succ"]*(j-i)*?.}")mas ... parecia muito longo.

Não que Charles
fonte
0

Matlab(94)(80)

Edit: Eu não levei no caso de ordem alfabética inversa, como (t, r) em 'nature', então mais bytes para upweight :(

@(a)sum(arrayfun(@(x)sum(1:nnz(find(a==fix(x/2)+(-1)^x*(1:1:nnz(a))))-1),2:244))

  • A função binomial lança uma exceção estúpida quando k é maior que n e eu não consigo capturar exceções dentro da arraycellfunção, caso contrário eu poderia jogar mais. Quem precisa de uma função integrada ??

    Agora eu poderia fazê-lo manualmente, simplificando o binômio (n, 2) = n / (2 (n-2)!) = N (n-1) / 2. observe que esse último valor representa a soma dos números inteiros de 1 a n-1, isso não gera nenhuma exceção no matlab, Deus abençoe a matemática.

  • Ps: este método é diferente do slvrbld

Execução

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4
Abr001am
fonte
Eu acho que é seguro remover 's' dos argumentos de input (). Economiza 4 bytes. Além disso, parece falhar em strings mais longas (por exemplo, 'supercalifragilisticexpialidocious' que esse modelo é usado como caso de teste) devido ao intervalo de loop for codificado ... você pode querer consertar isso.
slvrbld
@slvrbld eu não acho que preciso disso, veja a edição mais recente #
Abr001am