ตัวอักษรระหว่างตัวอักษรสองตัว


22

เขียนโปรแกรมที่ยอมรับคำตัวพิมพ์เล็กคำเดียวเป็นอินพุตและเอาต์พุตจำนวนตัวอักษรคู่ที่มีจำนวนตัวอักษรเดียวกันระหว่างคำนั้น ๆ ในคำเดียวกับตัวอักษร

ตัวอย่างเช่นในคำว่า 'ธรรมชาติ' เรามี 4 คู่:

  • nr: เนื่องจากมีสามตัวอักษรระหว่างพวกเขาภายในคำ (a, t, u) และตัวอักษรสามตัวระหว่างพวกเขาในตัวอักษร (o, p, q)
  • ae: เนื่องจากมีสามตัวอักษรระหว่างพวกเขาภายในคำ (t, u, r) และสามตัวอักษรระหว่างพวกเขาในตัวอักษร (b, c, d)
  • tu: เนื่องจากไม่มีตัวอักษรระหว่างพวกเขาภายในคำและไม่มีตัวอักษรระหว่างพวกเขาในตัวอักษร
  • tr: เนื่องจากมีจดหมายหนึ่งฉบับอยู่ระหว่างพวกเขาภายในคำ (u) และจดหมายหนึ่งฉบับระหว่างพวกเขาในตัวอักษร (s)

เนื่องจากมีสี่คู่เอาต์พุตในกรณีนี้ควรเป็น 4


10
ถ้อยคำสามารถชี้แจงได้อีกเล็กน้อย
เครื่องมือเพิ่มประสิทธิภาพ

ฉันไม่ได้รับคำถาม วิธีการที่ตัวอักษร, T , Uจะต้องอยู่ภายในไม่มี ? และทุกตัวอย่างต่อไปนี้ ... (ซีซี @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หรือหนึ่งอัน?
ไม่ใช่ว่า Charles

คำตอบ:


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

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จะเข้าเราบันทึกไปยัง
  • เราตั้งค่าตัวแปร temp $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เมื่อลูปเสร็จแล้วเราเอาท์พุท โปรดทราบว่าเราจำเป็นต้องทำการเล่นกลแบบเดียวกัน+เพื่อหลีกเลี่ยงการพิมพ์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) ใน 'ธรรมชาติ' ดังนั้นไบต์มากถึง upweight :(

@(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, God อวยพรคณิตศาสตร์

  • Ps: วิธีนี้แตกต่างจากของ slvrbld

การกระทำ

  >> ans('abef')

  ans =

       2

  >> ans('abcd')

  ans =

       6

  >> ans('nature')

  ans =

       4

ฉันคิดว่ามันปลอดภัยที่จะลบ, 's'จากอาร์กิวเมนต์ของอินพุต () ช่วยให้คุณประหยัด 4 ไบต์ นอกจากนี้ดูเหมือนว่าจะล้มเหลวในสตริงที่ยาวขึ้น (เช่น 'supercalifragilisticexpialidocious' ที่ flodel ใช้เป็นกรณีทดสอบ) เนื่องจาก hardcoded for-loop range ... คุณอาจต้องการแก้ไข
slvrbld

@slvrbld ฉันไม่คิดว่าฉันต้องการสิ่งนั้นดูการแก้ไขใหม่ล่าสุด
Abr001am
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.