Litery między dwiema literami

22

Napisz program, który akceptuje pojedyncze małe litery jako dane wejściowe i wypisuje liczbę par liter, które mają taką samą liczbę liter w słowie jak w alfabecie.

Na przykład w słowie „natura” mamy 4 pary:

  • nr: ponieważ między słowem (a, t, u) są trzy litery i trzy litery między nimi w alfabecie (o, p, q)
  • ae: ponieważ są trzy litery między słowem (t, u, r) i trzy litery między nimi w alfabecie (b, c, d)
  • tu: ponieważ nie ma między nimi liter i nie ma liter w alfabecie
  • tr: ponieważ jest jedna litera między nimi w słowie (u) i jedna litera między nimi w alfabecie (ach)

Ponieważ są cztery pary, wynik w tym przypadku powinien wynosić 4.

ghosts_in_the_code
źródło
10
Sformułowanie można nieco wyjaśnić.
Optymalizator
Nie dostaję pytania. Jak litery a , t , u będą w środku nr ? I wszystkie następujące przykłady ... (cc @flodel)
nicael
Jeśli przeliterujesz naturę, n i r znajdują się na 1. i 5. pozycji. Więc są między nimi trzy litery. Są to a, ti u, na 2., 3. i 4. pozycji. To właśnie oznacza tekst, ponieważ wewnątrz słowa znajdują się trzy litery od n do r .
flodel
@flodel Masz rację w edycji; Brakowało mi czwartej pary.
ghosts_in_the_code
Co by było, gdyby to było słowo rjjjnfffr? Czy byłaby to jedna para ( nr) czy dwie pary ( nri rn)? A co abzab? Czy to dwie pary abczy jedna?
Nie to, że Charles

Odpowiedzi:

5

Pyth, 19 bajtów

lfqF-MSMCT.cCUBCMz2

Wypróbuj online: demonstracja

Wyjaśnienie:

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
źródło
4

R, 110 bajtów

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
źródło
3

Oktawa, 41 bajtów

@(s)nnz(abs(s-s')==(t=1:(u=nnz(s)))-t')-u
alephalpha
źródło
3

CJam, 36 bajtów

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

Wypróbuj online.

geokavel
źródło
2

J, 27 bajtów

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

Stosowanie:

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

Wyjaśnienie:

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

Wypróbuj online tutaj.

randomra
źródło
2

CJam, 25 bajtów

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

Wypróbuj online

Wyjaśnienie:

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
źródło
2

JavaScript (ES6), 98 bajtów

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)

Stosowanie

f("nature")
=> 4

Wyjaśnienie

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
)
użytkownik 81655
źródło
1

Python 2, 91 znaków

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
źródło
1

MATLAB, 84 bajty

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

Ten wiersz wymaga podania ciągu jako danych wejściowych. Następnie tworzy wszystkie możliwe pary liter i robi to samo dla odpowiadających im indeksów. Następnie ustalamy, czy (bezwzględna) różnica wartości się zgadza, aby ostatecznie zsumować wszystkie przypadki, w których ma to miejsce. Wynik zostanie wyświetlony w oknie poleceń.

slvrbld
źródło
1

JavaScript ES7, 93

Korzystanie ze zrozumienia tablic . ES6 z .map.map.mapjest o 2 bajty dłuższy.

Przetestuj poniższy fragment kodu w przeglądarce 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
źródło
1

PowerShell, 114 100 bajtów

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

Całkiem proste, ale wykorzystuje kilka sztuczek.

  • param(..)bierze nasz wkład, zapisuje go $a.
  • Możemy ustawić zmienną temp $bbyć .lengthnaszego wejścia. To oszczędza bajt później.
  • 0..($b-1)|%{..}jest odpowiednikiem for($i=0;$i-le($b-1);$i++){..}pętli, ale o wiele krótszym.
  • Musimy jednak ustawić zmienną $i, aby utrzymać ją w ...
  • ($_+1)..$b|%{..}następna forpętla, ponieważ $_jest tylko pozycjonowana względem wewnętrznej pętli.
  • Następnie używamy długiego wywołania .NET, aby sprawdzić, czy wartość bezwzględna między naszymi dwoma znakami (tutaj używamy niejawnego rzutowania z poprzedzaniem, +aby zapisać wiązkę bajtów) jest zgodna z różnicą -eqpozycyjną w tablicy. Ponieważ otrzymaliśmy wyraźnie małe litery, nie musimy wykonywać konwersji wielkości liter. To stwierdzenie powróci albo Truealbo False.
  • Rażąco nadużywamy niejawnego rzucania ponownie, aby zgromadzić ten wynik $o, więc Truedodamy 1, a Falsedodamy 0.
  • Po zakończeniu pętli generujemy dane wyjściowe $o. Zauważ, że musimy wykonać tę samą sztuczkę z cast-to-int, +aby uniknąć drukowania, Falsejeśli nie było żadnych dopasowań.
AdmBorkBork
źródło
0

Ruby, 74

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

Nic super interesującego tutaj. Chciałbym używać, eval("s[i].#{["succ"]*(j-i)*?.}")ale ... wydawało się, że jest za długi.

Nie ten Charles
źródło
0

Matlab(94)(80)

Edycja: Nie wziąłem w przypadku odwróconej kolejności alfabetycznej, ponieważ (t, r) w 'nature', więc więcej bajtów do upweight :(

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

  • funkcja dwumianowa rzuca głupi wyjątek, gdy k jest większe niż n i nie mogę złapać wyjątków wewnątrz arraycellfunkcji, w przeciwnym razie mógłbym zagrać w nią bardziej. Kto potrzebuje wbudowanej funkcji?

    Teraz mógłbym to zrobić ręcznie, upraszczając dwumianowy (n, 2) = n / (2 (n-2)!) = N (n-1) / 2. zauważ, że ta ostatnia wartość reprezentuje sumę liczb całkowitych od 1 do n-1, nie rzuca to żadnego wyjątku w matlab, Boże błogosław matematykę.

  • Ps: ta metoda różni się od metody slvrbld

Wykonanie

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4
Abr001am
źródło
Myślę, że można bezpiecznie usunąć argumenty „s” z argumentów input (). Oszczędza 4 bajty. Co więcej, wydaje się, że zawiedzie na dłuższych ciągach (np. „Superkalifragilisticexpialidocious”, których flodel używał jako przypadku testowego) z powodu zakodowanego zakresu dla pętli for ... możesz to naprawić.
slvrbld,
@slvrbld Nie sądzę, że potrzebuję tego, zobacz najnowszą edycję
Abr001am,