Lettres entre deux lettres

22

Écrivez un programme qui accepte un seul mot en minuscule en entrée et génère le nombre de paires de lettres qui ont le même nombre de lettres entre elles dans le mot que dans l'alphabet.

Par exemple, dans le mot «nature», nous avons 4 paires:

  • nr: puisqu'il y a trois lettres entre elles à l'intérieur du mot (a, t, u) et trois lettres entre elles dans l'alphabet (o, p, q)
  • ae: puisqu'il y a trois lettres entre elles à l'intérieur du mot (t, u, r) et trois lettres entre elles dans l'alphabet (b, c, d)
  • tu: puisqu'il n'y a pas de lettres entre elles à l'intérieur du mot et pas de lettres entre elles dans l'alphabet
  • tr: puisqu'il y a une lettre entre eux à l'intérieur du mot (u) et une lettre entre eux dans l'alphabet (s)

Puisqu'il y a quatre paires, la sortie dans ce cas devrait être 4.

ghosts_in_the_code
la source
10
Le libellé peut être clarifié un peu plus.
Optimizer
Je ne comprends pas la question. Comment les lettres a , t , u vont-elles être à l'intérieur de nr ? Et tous les exemples suivants ... (cc @flodel)
nicael
Si vous épelez la nature, les n et r sont en 1ère et 5ème position. Il y a donc trois lettres entre eux. Ils sont a, t et u, aux 2e, 3e et 4e positions. C'est ce que le texte signifie par il y a trois lettres entre n et r à l'intérieur du mot .
flodel
@flodel Vous avez raison dans l'édition; J'ai raté la 4ème paire.
ghosts_in_the_code
Et si le mot était rjjjnfffr? Serait-ce une paire ( nr) ou deux paires ( nret rn)? Et qu'en est-il abzab? Est-ce deux paires abou une seule?
Pas que Charles

Réponses:

5

Pyth, 19 octets

lfqF-MSMCT.cCUBCMz2

Essayez-le en ligne: Démonstration

Explication:

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
la source
4

R, 110 octets

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}

Dégolfé:

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
la source
3

Octave, 41 octets

@(s)nnz(abs(s-s')==(t=1:(u=nnz(s)))-t')-u
alephalpha
la source
3

CJam, 36 octets

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

Essayez-le en ligne.

geokavel
la source
2

J, 27 octets

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

Usage:

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

Explication:

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

Essayez-le en ligne ici.

randomra
la source
2

CJam, 25 octets

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

Essayez-le en ligne

Explication:

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
la source
2

JavaScript (ES6), 98 octets

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)

Usage

f("nature")
=> 4

Explication

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
la source
1

Python 2, 91 caractères

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
la source
1

MATLAB, 84 octets

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

Cette ligne demande une chaîne en entrée. Il crée ensuite toutes les paires de lettres possibles et fait de même pour leurs indices correspondants. Ensuite, nous déterminons si la différence (absolue) des valeurs correspond pour finalement résumer tous les cas où elle le fait. Le résultat s'affiche dans la fenêtre de commande.

slvrbld
la source
1

JavaScript ES7, 93

Utilisation de la compréhension des tableaux . ES6 avec .map.map.mapest de 2 octets de plus.

Testez l'exécution de l'extrait ci-dessous avec 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
la source
1

PowerShell, 114100 octets

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

Assez simple, mais utilise quelques astuces.

  • param(..)prend notre entrée, l'enregistre $a.
  • Nous avons défini une variable temporaire $bcomme étant celle .lengthde notre entrée. Cela enregistre un octet plus tard.
  • 0..($b-1)|%{..}est l'équivalent d'une for($i=0;$i-le($b-1);$i++){..}boucle, mais beaucoup plus courte.
  • Cependant, nous devons définir une variable $ipour que cela continue ...
  • ($_+1)..$b|%{..}la forboucle suivante , car $_est uniquement positionnelle à la boucle intérieure.
  • Nous utilisons ensuite un long appel .NET pour vérifier si la valeur absolue entre nos deux caractères (ici, nous utilisons la conversion implicite avec pré-ajout +pour enregistrer un tas d'octets) correspond -eqà la différence de position dans le tableau. Comme nous recevons explicitement des entrées en minuscules, nous n'avons pas besoin de faire de conversion de casse. Cette instruction renverra soit Trueou False.
  • Nous abusons de manière flagrante du casting implicite à nouveau pour accumuler ce résultat $o, alors Truenous ajouterons 1, tandis que Falsenous ajouterons 0.
  • Une fois les boucles terminées, nous sortons $o. Notez que nous devons faire la même astuce avec cast +pour éviter d'imprimer Falses'il n'y a pas de correspondance.
AdmBorkBork
la source
0

Rubis, 74

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

Rien de super intéressant ici. J'aurais aimé utiliser eval("s[i].#{["succ"]*(j-i)*?.}")mais ... semblait trop long.

Pas que Charles
la source
0

Matlab(94)(80)

Edit: je n'ai pas pris dans le cas d'un ordre alphabétique inversé, comme (t, r) dans 'nature', donc plus d'octets pour augmenter le poids :(

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

  • la fonction binomiale lève une stupide exception lorsque k est plus grand que n et que je ne peux pas attraper d'exceptions à l'intérieur arraycell fonction, sinon je pourrais la jouer plus. Qui a besoin d'une fonction intégrée ??

    Maintenant, je pouvais simplement le faire à la main, en simplifiant binôme (n, 2) = n / (2 (n-2)!) = N (n-1) / 2. remarquez que cette dernière valeur représente la somme des entiers de 1 à n-1, cela ne lève aucune exception dans matlab, Dieu bénisse les maths.

  • Ps: cette méthode est différente de celle de slvrbld

Exécution

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4
Abr001am
la source
Je pense qu'il est sûr de supprimer , 's' des arguments de input (). Vous enregistre 4 octets. En outre, il semble échouer sur des chaînes plus longues (par exemple, 'supercalifragilisticexpialidocious' que flodel a utilisé comme cas de test) en raison de la plage de boucle for codée en dur ... vous voudrez peut-être résoudre ce problème.
slvrbld
@slvrbld je ne pense pas avoir besoin de ça, voir la dernière édition
Abr001am