Буквы между двумя буквами


22

Напишите программу, которая принимает одно строчное слово в качестве входных данных и выводит количество пар букв, которые имеют одинаковое количество букв между ними в слове и в алфавите.

Например, в слове «природа» у нас есть 4 пары:

  • nr: так как внутри слова есть три буквы (a, t, u) и три буквы между ними в алфавите (o, p, q)
  • ae: поскольку внутри слова есть три буквы между ними (t, u, r) и три буквы между ними в алфавите (b, c, d)
  • tu: так как между ними нет букв внутри слова и между ними нет букв в алфавите
  • tr: поскольку внутри слова (u) между ними есть одна буква, а в алфавите (-ах) - одна буква

Поскольку существует четыре пары, выход в этом случае должен быть 4.


10
Формулировка может быть уточнена немного больше.
Оптимизатор

Я не понимаю вопрос. Как буквы a , t , u будут внутри nr ? И все следующие примеры ... (cc @flodel)
nicael

Если вы объясните природу, n и r находятся на 1-й и 5-й позиции. Итак, между ними три буквы. Они a, t и u, на 2-й, 3-й и 4-й позиции. Это то, что текст означает, что есть три буквы между n и r внутри слова .
Flodel

@flodel Вы правы в редактировании; Я пропустил 4-ю пару.
ghosts_in_the_code

Что если бы слово было rjjjnfffr? Это будет одна пара ( nr) или две пары ( nrи rn)? А как насчет abzab? Это две пары abили одна?
Не то, что Чарльз

Ответы:


5

Pyth, 19 байт

lfqF-MSMCT.cCUBCMz2

Попробуйте онлайн: демонстрация

Объяснение:

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

4

R, 110 байт

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



2

J, 27 байт

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

Использование:

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

Объяснение:

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

Попробуйте это онлайн здесь.


2

CJam, 25 байтов

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

Попробуйте онлайн

Объяснение:

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.

2

JavaScript (ES6), 98 байт

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)

использование

f("nature")
=> 4

объяснение

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
)

1

Python 2, 91 символ

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

1

MATLAB, 84 байта

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

Эта строка запрашивает строку в качестве ввода. Затем он создает все возможные пары букв и делает то же самое для их соответствующих индексов. Затем мы определяем, соответствует ли (абсолютная) разность значений, чтобы в итоге суммировать все случаи, где это происходит. Результат отображается в командном окне.


1

JavaScript ES7, 93

Используя понимание массива . ES6 с .map.map.mapна 2 байта длиннее.

Попробуйте запустить фрагмент ниже с 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'))


1

PowerShell, 114 100 байт

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

Довольно просто, но использует пару трюков.

  • param(..)принимает наш вклад, сохраняет его $a.
  • Мы устанавливаем временную переменную $bдля .lengthнашего ввода. Это сохраняет байт позже.
  • 0..($b-1)|%{..}является эквивалентом for($i=0;$i-le($b-1);$i++){..}цикла, но намного короче.
  • Тем не менее, нам нужно установить переменную $i, чтобы сохранить это в ...
  • ($_+1)..$b|%{..}следующий forцикл, так $_как позиционируется только на внутренний цикл.
  • Затем мы используем длинный вызов .NET, чтобы проверить, соответствует ли абсолютное значение между нашими двумя символами (здесь мы используем неявное приведение с добавлением предваряющего +для сохранения группы байтов) -eqс позиционной разницей в массиве. Поскольку мы явно вводим строчные буквы, нам не нужно выполнять преобразование регистра. Это утверждение вернет либо Trueили False.
  • Мы явно злоупотребляем неявным приведением снова, чтобы накапливать этот результат $o, поэтому Trueдобавим 1, а Falseдобавим 0.
  • Как только циклы закончены, мы выводим $o. Обратите внимание, что нам нужно сделать то же самое tricksy-cast-to-int, +чтобы избежать печати, Falseесли совпадений не было.

0

Руби, 74

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

Ничего супер интересного здесь. Я хотел бы использовать, eval("s[i].#{["succ"]*(j-i)*?.}")но ... казалось слишком долго.


0

Matlab(94)(80)

Изменить: я не взял в случае обратного алфавитного порядка, как (t, r) в «природе», так что больше байтов для веса :(

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

  • Биноминальная функция выдает глупое исключение, когда k больше n, и я не могу перехватить исключения внутри arraycellфункции, в противном случае я мог бы играть в нее больше. Кому нужна встроенная функция ??

    Теперь я мог просто сделать это вручную, упрощая биномиальное (n, 2) = n / (2 (n-2)!) = N (n-1) / 2. Заметьте, что это последнее значение представляет собой сумму целых чисел от 1 до n-1, это не вызывает каких-либо исключений в matlab, благослови Бог математику.

  • PS: этот метод отличается от slvrbld

выполнение

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4

Я думаю, что безопасно удалить 's' из аргументов input (). Экономит 4 байта. Кроме того, кажется, что он не работает на более длинных строках (например, «supercalifragilisticexpialidocious», которые используются в качестве контрольного примера) из-за жестко закодированного диапазона for-loop ... вы можете это исправить.
slvrbld

@slvrbld Я не думаю, что мне это нужно, смотрите новейшую
редакцию
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.