两个字母之间的字母


22

编写一个程序,该程序接受一个小写单词作为输入,并输出单词对中与字母中具有相同字母数的字母对数。

例如,在“自然”一词中,我们有4对:

  • nr:因为单词(a,t,u)中的三个字母之间以及字母(o,p,q)中的三个字母
  • ae:由于单词(t,u,r)中的三个字母之间以及字母(b,c,d)中的三个字母之间
  • 土:因为在单词中它们之间没有字母,在字母表中也没有字母
  • tr:因为在单词(u)中它们之间只有一个字母,而在字母(s)中它们之间只有一个字母

由于有四对,因此这种情况下的输出应为4。


10
措词可以进一步澄清。
Optimizer

我没问题。字母atunr里面如何?以及以下所有示例...(cc @flodel)
nicael

如果您说明自然,则n和r分别位于第1和第5位。因此,它们之间有三个字母。它们分别是a,t和u,分别位于第二,第三和第四位置。这就是文本的含义,因为单词内n和r之间有三个字母
flodel 2015年

@flodel您就在编辑中;我错过了第四对。
ghosts_in_the_code 2015年

如果这个词是rjjjnfffr什么?是一对(nr)还是两对(nrrn)?那又如何abzab呢?那是两双ab还是一对?
不是查尔斯(Charles)

Answers:


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}

已脱胶:

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与数组中的位置差异相同。由于我们已明确获得小写输入,因此无需进行大小写转换。该语句将返回TrueFalse
  • 我们公然再次滥用隐式转换将结果累加到$o,因此True将加1,而False将加0。
  • 循环完成后,我们输出$o。请注意,如果没有匹配项,我们需要进行同样的技巧转换+,以免打印False

0

Ruby,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)在'nature'中,所以更多的字节要增加:(

@(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

我认为从input()的参数中删除''是安全的。为您节省4个字节。此外,由于硬编码的for循环范围,它似乎在较长的字符串上失败(例如,flodel用作测试用例的“ supercalifragilisticexpialidocious”)……您可能要解决此问题。
slvrbld

@slvrbld我认为我不需要它,请参阅最新编辑
Abr001am 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.