Letras entre dos letras

22

Escriba un programa que acepte una sola palabra en minúscula como entrada y genere la cantidad de pares de letras que tienen la misma cantidad de letras entre ellas en la palabra que en el alfabeto.

Por ejemplo, en la palabra 'naturaleza', tenemos 4 pares:

  • nr: dado que hay tres letras entre ellas dentro de la palabra (a, t, u) y tres letras entre ellas en el alfabeto (o, p, q)
  • ae: dado que hay tres letras entre ellas dentro de la palabra (t, u, r) y tres letras entre ellas en el alfabeto (b, c, d)
  • tu: ya que no hay letras entre ellas dentro de la palabra y no hay letras entre ellas en el alfabeto
  • tr: dado que hay una letra entre ellos dentro de la palabra (u) y una letra entre ellos en el alfabeto (s)

Como hay cuatro pares, la salida en este caso debería ser 4.

fantasmas_en_el_código
fuente
10
La redacción se puede aclarar un poco más.
Optimizador
No entiendo la pregunta. ¿Cómo van a estar las letras a , t , u dentro de nr ? Y todos los siguientes ejemplos ... (cc @flodel)
nicael
Si deletreas la naturaleza, los n y r están en la primera y quinta posición. Entonces hay tres letras entre ellos. Son a, t y u, en la 2da, 3ra y 4ta posición. Eso es lo que quiere decir el texto porque hay tres letras entre n y r dentro de la palabra .
Flodel
@flodel Tienes razón en la edición; Perdí el 4to par.
ghosts_in_the_code
¿Y si la palabra fuera rjjjnfffr? ¿Sería un par ( nr) o dos pares ( nry rn)? ¿Y de qué abzab? ¿Son dos pares de abo uno?
No es que Charles

Respuestas:

5

Pyth, 19 bytes

lfqF-MSMCT.cCUBCMz2

Pruébelo en línea: demostración

Explicación:

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

Degolfed:

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
flodel
fuente
3

Octava, 41 bytes

@(s)nnz(abs(s-s')==(t=1:(u=nnz(s)))-t')-u
alephalpha
fuente
2

J, 27 bytes

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

Uso:

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

Explicación:

#-:@-~#\+/@,@:=&(|@-/~)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)

Pruébelo en línea aquí.

randomra
fuente
2

CJam, 25 bytes

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

Pruébalo en línea

Explicación:

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

Explicación

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

MATLAB, 84 bytes

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

Esta línea solicita una cadena como entrada. Luego crea todos los pares de letras posibles y hace lo mismo para sus índices correspondientes. Luego determinamos si la diferencia (absoluta) de los valores coincide para finalmente sumar todos los casos en los que lo hace. El resultado se muestra en la ventana de comandos.

slvrbld
fuente
1

JavaScript ES7, 93

Usando la comprensión de la matriz . ES6 con .map.map.mapes 2 bytes más largo.

Pruebe a ejecutar el fragmento a continuación con 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
fuente
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

Bastante sencillo, pero usa un par de trucos.

  • param(..)toma nuestra entrada, la guarda en $a.
  • Establecemos una variable temporal $bpara que sea la .lengthde nuestra entrada. Esto ahorra un byte más tarde.
  • 0..($b-1)|%{..}es el equivalente de un for($i=0;$i-le($b-1);$i++){..}bucle, pero bastante más corto.
  • Sin embargo, necesitamos establecer variables $ipara mantener eso en ...
  • ($_+1)..$b|%{..}el siguiente forciclo, ya $_que solo es posicional al ciclo interno.
  • Luego usamos una larga llamada .NET para verificar si el valor absoluto entre nuestros dos caracteres (aquí usamos conversión implícita con anteposición +para guardar un montón de bytes) es -equal a la diferencia posicional en la matriz. Dado que se nos proporciona explícitamente una entrada en minúsculas, no necesitamos hacer la conversión de mayúsculas y minúsculas. Esta declaración devolverá Trueo False.
  • Abusamos abiertamente de nuevo el lanzamiento implícito para acumular ese resultado $o, por Truelo que agregaremos 1, mientras Falseque agregaremos 0.
  • Una vez que los bucles están terminados, sacamos $o. Tenga en cuenta que debemos hacer lo mismo con tricksy-cast-to-int +para evitar imprimir Falsesi no hay coincidencias.
AdmBorkBork
fuente
0

Rubí, 74

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

Nada súper interesante aquí. Me hubiera encantado usarlo eval("s[i].#{["succ"]*(j-i)*?.}")pero ... parecía demasiado largo.

No es que Charles
fuente
0

Matlab(94)(80)

Editar: no tomé en caso de orden alfabético inverso, como (t, r) en 'naturaleza', por lo que más bytes para subir de peso :(

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

  • La función binomial produce una estúpida excepción cuando k es mayor que n y no puedo detectar excepciones dentro de la arraycellfunción, de lo contrario podría jugar más. ¿Quién necesita una función incorporada?

    Ahora podría hacerlo a mano, simplificando binomial (n, 2) = n / (2 (n-2)!) = N (n-1) / 2. observe que este último valor representa la suma de enteros de 1 a n-1, esto no arroja ninguna excepción en matlab, que Dios bendiga las matemáticas.

  • Ps: este método es diferente al de slvrbld

Ejecución

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4
Abr001am
fuente
Creo que es seguro eliminar 's' de los argumentos de input (). Le ahorra 4 bytes. Además, parece fallar en cadenas más largas (por ejemplo, 'supercalifragilisticexpialidocious' que el flodel usó como caso de prueba) debido al rango codificado for-loop ... es posible que desee solucionarlo.
slvrbld
@slvrbld No creo que necesite eso, vea la edición más reciente
Abr001am