Phát hiện bỏ phiếu nối tiếp


51

Stack Exchange tự động phát hiện bỏ phiếu nối tiếp (khi một người dùng nâng cấp hoặc hạ cấp nhiều bài đăng của người dùng khác) và đảo ngược nó. Trong thử thách này, bạn sẽ thực hiện một trình phát hiện "bỏ phiếu nối tiếp" rất, rất đơn giản.

Đầu vào

Đầu vào là một chuỗi đại diện cho một danh sách phiếu bầu. Mỗi nhóm gồm hai nhân vật đại diện cho một phiếu bầu, nhóm đầu tiên là người bầu chọn và nhóm thứ hai là người dùng được bình chọn. Ví dụ: đầu vào sau

ababbccd

có thể được phân tích cú pháp dưới dạng ab ab bc cdvà đại diện cho việc abỏ phiếu bhai lần, bbỏ phiếu cmột lần và cbỏ phiếu dmột lần.

Đầu vào sẽ chỉ bao gồm các chữ cái viết thường và nó sẽ luôn có độ dài chẵn> 0. Bạn cũng không thể bỏ phiếu cho chính mình (vì vậy không aahoặc hh).

Đầu ra

Đối với mục đích của thử thách này, bỏ phiếu nối tiếp được định nghĩa là bất kỳ người dùng cụ thể nào bỏ phiếu cho bất kỳ người dùng nào khác từ ba lần trở lên.

Đầu ra là số lượng phiếu nên được đảo ngược cho mỗi người dùng (nghĩa là có bao nhiêu phiếu trên mỗi người dùng bị đảo ngược, chứ không phải có bao nhiêu phiếu mà họ đã đưa ra bị đảo ngược), theo định dạng [user][votes][user2][votes2].... Ví dụ: đầu vào abababab( abỏ phiếu bbốn lần) sẽ xuất ra b4(bốn phiếu đã được đảo ngược từ asang b).

Đầu ra có thể theo bất kỳ thứ tự nào bạn muốn, nhưng cả đầu vào và đầu ra phải là các chuỗi đơn như mô tả ở trên.

Các trường hợp thử nghiệm

In                            Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa          b7a3
edfdgdhdfgfgfgih              g3
jkkjjkkjjkkjljljljmlmlnmnmnm  j6k3m3
opqrstuv                      <none>
vwvwwvwv                      <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz    y10z3
nanananananananabatman        a8
banana                        <none>

16
+1 cho nanananananananabatmantrường hợp thử nghiệm.
chín

Câu trả lời:


6

Bình thường, 22 byte

pM_srSsfttTtMM.gkcz2 8

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình:

pM_srSsfttTtMM.gkcz2 8
                 cz2     chop the input into pairs
              .gk        group these pairs by their value
           tMM           discard the first char in each pair in each group
       fttT              discard all groups, that contain less than three pairs
      s                  concatenate all groups to get a list of chars
     S                   sort all chars
    r                8   run-length-encoding
   s                     concatenate all (count,char) pairs 
  _                      reverse the order
pM                       print each element without separator

Thí dụ:

input:   ededgdhdfgfgfgihed
chop:    ['ed', 'ed', 'gd', 'hd', 'fg', 'fg', 'fg', 'ih', 'ed']
group:   [['ed', 'ed', 'ed'], ['fg', 'fg', 'fg'], ['gd'], ['hd'], ['ih']]
discard: [['d', 'd', 'd'], ['g', 'g', 'g'], ['d'], ['d'], ['h']]
discard: [['d', 'd', 'd'], ['g', 'g', 'g']]
concat.: ['d', 'd', 'd', 'g', 'g', 'g']
sort:    ['d', 'd', 'd', 'g', 'g', 'g']
rle:     [[3, 'd'], [3, 'g']]
concat.: [3, 'd', 3, 'g']
reverse: ['g', 3, 'd', 3]
print:   g3d3

34

Không thể đọc được , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 byte

Đầu ra theo thứ tự chữ cái ngược ( zto a) nhưng theo quy tắc của bạn có vẻ được cho phép.

"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "

Giải trình

Đầu tiên, để có ấn tượng về những gì Unreadable có thể làm, đây là thao tác cơ bản của nó:

  • Bạn có một băng vô hạn gồm các ô nguyên có kích thước tùy ý
  • Bạn không có con trỏ bộ nhớ như trong Brainfuck; thay vào đó, bạn chọn các ô theo vị trí của chúng trên băng. Điều này có nghĩa là bạn có thể đọc giá trị # 4 giá trị hoặc đọc giá trị # 4 (giá trị đọc số 4).
  • Bạn chỉ có thể đọc hoặc ghi các ô nhớ (không tăng / giảm trực tiếp như trong Brainfuck).
  • Bạn có thể tăng / giảm giá trị trong một biểu thức. Do đó, để tăng một ô nhớ bạn phải đọc , tăng , ghi hoặc đặt khác nhau : write(x, inc(read(x))).
  • Có những vòng lặp và điều kiện ternary chỉ có thể kiểm tra 0 so với khác không.

Chương trình này sử dụng băng như sau. Tên biến sẽ được sử dụng trong mã giả sau bên dưới. Ngoài ra, tài liệu này là phiên bản đầu tiên (là 1830 byte); xem các chỉnh sửa ở phía dưới để biết những gì đã thay đổi kể từ đó.

  • Ô 0: biếnq
  • Tế bào 1: biến a, p,ch
  • Ô 2: biến hash,v
  • Ô 3: biến b,r
  • Ô 4: biến aa,l
  • Ô 5: vẫn là 0 để đánh dấu đầu cuối của các chuỗi chữ số thập phân
  • Các ô 6 Mã 95: lưu trữ chuỗi các chữ số thập phân ngược
  • Các ôa 96 Kết luận z121 : lưu trữ số phiếu được trừ từ người dùng (96) đến (121) (mã ASCII của chữ cái trừ đi một).
  • Các tế bào 4657 Ném7380: hãy nhớ những kết hợp cử tri / cử tri đã gặp phải bao nhiêu lần. Các ô này chỉ có 4 giá trị có thể: 0= chưa thấy, -1= nhìn thấy một lần, -2= nhìn thấy hai lần, -3= thấy bất kỳ số lần nào nhiều hơn 2.

Thuật toán về cơ bản tiến hành như sau:

  • Tiếp tục đọc các cặp ký tự ab. Tính giá trị băm (a-2)*(a-1)+b-1, là giá trị duy nhất cho mọi tổ hợp chữ cái a z.
  • Kiểm tra ô nhớ tại giá trị băm đó ( *hash). Nếu đó -3, người dùng đã đủ điều kiện để bỏ phiếu, vì vậy hãy tăng dần *(b-1). Nếu không, giảm dần *hash. Nếu đó là hiện nay -3 , người dùng vừa trở thành đủ điều kiện để loại bỏ phiếu sau ba lần xuất hiện, do đó tăng *(b-1)do 3.
  • Sau đó, đi qua các ký tự theo thứ tự ngược ( zđến a) và xuất ra những ký tự cần bỏ phiếu. Điều này đòi hỏi phải chia số nguyên thủ công cho 10 để dịch số thành chữ số thập phân.

Với tất cả những gì đã làm rõ, đây là những gì chương trình trông giống như mã giả:

// Read pairs of characters
while (a = read) + 1 {
    b = read

    // Calculate hash = (a-1)*(a-2)/2 + b-1
    // This also sets a = b-1
    hash = 0
    while --a {
        aa = a
        while --aa {
            ++hash
        }
    }
    while --b {
        ++a
        ++hash
    }

    // If this combination has just been seen for the third time,
    // increment *a by 3; if more than third time, increment *a by 1
    *a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}

// Loop through the characters z to a
l = 27
while --l {                     // l loops from 26 to 1 (not 0)
    (v = *(ch = l + 95)) ? {    // 'a' is ASCII 97, but cell 96
        print (ch+1)            // print the votee

        // Now we need to turn the number v into decimal.
        // p points to where we are storing decimal digits.
        p = 5

        while v {
            // Integer division by 10 (q=quotient, r=remainder)
            r = (q = 0)
            while v {
                --v
                (++r - 10) ? 1 : {
                    r = 0
                    ++q
                }
            }
            // Store digit ASCII character
            *(++p) = r + 48     // 48 = '0'
            v = q
        }

        // Now output all the digit ASCII characters in reverse order
        while *p {
            print *(--p + 1)
        }

    } : 1
}

Chỉnh sửa 1, 1830 → 1796: Nhận ra rằng tôi có thể sử dụng lại giá trị trả về của một vòng lặp while ở một nơi.

Chỉnh sửa 2, 1796 → 1791: Hóa ra chương trình nhỏ hơn một chút nếu, thay vì sử dụng các ô 6 Tắt95, tôi lưu các chữ số thập phân trong các ô có số âm (từ1 trở đi). Là một phần thưởng bổ sung, chương trình không còn giới hạn ở 10⁹⁰ phiếu bầu!

Chỉnh sửa 3, 1791 → 1771: Thay vì gán kết quả *(ch = l + 95)cho v, bây giờ tôi gán nó cho qvà sau đó di chuyển phép gán v = qvào điều kiện while, lấy mã thành 1777 byte. Sau đó trao đổi vị trí của qvtrên băng bởi vì qbây giờ là 1 phổ biến hơn v.

Chỉnh sửa 4, 1771 → 1762: Duh. Khởi tạo hashthành 1 thay vì 0 ngắn hơn 9 byte. Mã băm bây giờ là 1, điều đó không quan trọng.

Chỉnh sửa 5, 1762 → 1745: Nếu tôi khởi tạo qrthành 1 thay vì 0, tôi phải rắc một số -1vị trí để làm cho đúng, và tất cả dường như hủy bỏ - ngoại trừ việc while v { --v; [...] }vòng lặp bây giờ cần thực hiện một lần lặp ít hơn, mà tôi có thể làm bằng cách nói while --v { [...] }, ngắn hơn 26 ký tự.

Chỉnh sửa 6, 1745 → 1736: Thay vì { r = 1; ++q }, chúng ta có thể viết q = *((r = 1)+1)+1. Điều này phụ thuộc vào thực tế qlà trong khe số 2. Nếu nó ở vị trí số 1 thì điều này thậm chí còn ngắn hơn, nhưng sau đó toàn bộ chương trình sẽ dài hơn.

Chỉnh sửa 7, 1745 → 1727: Hoàn nguyên Chỉnh sửa 6 và thay vào đó đạt được sự tiết kiệm bằng cách đặt nội tuyến trong khi lặp vào biểu thức tính mã ASCII chữ số, cũng kết thúc ở 1736 byte ... nhưng sau đó đã lưu một lệnh giảm (9 byte ) bằng cách thay đổi ((++r) - 11) ? r :thành (r - 10) ? ++r :.

Chỉnh sửa 8, 1727 → 1626: Làm lại phép tính băm. Bây giờ nó sử dụng một vòng lặp while ít hơn. Các vị trí ô hiện đang ở mã ASCII thực tế của chúng (không phải là 1 nữa). Chia sẻ lại các biến đến các vị trí khác nhau trên băng bởi vì chúng hiện xảy ra với tần suất khác nhau.

Chỉnh sửa 9, 1626 → 1606: Nội tuyến điên rồ hơn. Phần thân của vòng lặp while đầu tiên trông giống như thế này:

// b = next char
*(b = (hash = read)) = {

    // hash = b + (a-1)*(a-2)/2
    while (a2 = --a) {
        while --a2 {
            ++hash
        }
    }

    // If this combination has just been seen for the third time,
    // increment *b by 3; if more than third time, increment *b by 1
    (*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}

và việc gán biến đã thay đổi gần như hoàn toàn.

Sửa 10, 1606 → 1577: Tôi quan sát thấy rằng aa2đều giảm đi tới 0 trong vòng lặp while, do đó nếu tôi có thể ghép pvới một trong những người, nhưng khôngch, tôi sẽ không cần phải khởi tạo pđể 0(mà chi phí 29 byte). Hóa ra tôi có thể làm điều đó bằng cách hoán đổi pr. Các giả định biến mới nhất (và tần suất xuất hiện của chúng trong mã) hiện là:

0 = v (3)                    (total  3)
1 = hash (6), r (5), ch (2)  (total 13)
2 = b (4), q (5)             (total  9)
3 = a (3), p (5)             (total  8)
4 = a2 (3), l (4)            (total  7)

1
Thấy như thế nào một novemvigintillion phiếu sẽ đòi hỏi một chuỗi của 2 * 10 ^ 90 byte, và khối lượng nhỏ nhất có thể hiện tại của 10 ^ 24 byte là khoảng 1/3 kích thước của kim tự tháp Giza , tôi không nghĩ rằng bạn có bất cứ điều gì để lo lắng. ;)
Sản phẩm ETH

1
@ETHproductions: Tuy nhiên, trong khi chơi golf chương trình tôi đã tình cờ khắc phục giới hạn đó :)
Timwi

22

CJam, 23 byte

Bữa tiệc kéo dài!

q2/$e`{3a>},e~Wf=$e`Wf%

hoặc là

qW%2/$e`{3a>},e~:ce`Wf%

Chạy tất cả các trường hợp thử nghiệm

Giải trình

q2/   e# Read input and split into pairs.
$e`   e# Sort and run-length encode - this tallies the pairs.
{     e# Filter the tallies...
  3a> e#   Keep only those which start with a 3 or greater.
},    e# Now we need to group the remaining pairs.
e~    e# Run-length decode the remaining pairs.
Wf=   e# Select the second character from each pair (the one being voted on).
$e`   e# Tally the characters by sorting and RLE'ing again.
Wf%   e# Reverse each pair, because CJam's RLE has the number first and the character last.

Phiên bản khác bắt đầu bằng cách đảo ngược các cặp, giúp lưu hai byte ở nơi khác: a) chọn ký tự đầu tiên trong mỗi chuỗi chỉ :cthay vì Wf=chọn thứ hai. b) Chúng ta không cần sắp xếp lại trước RLE thứ hai, vì các cặp đã được sắp xếp chủ yếu theo ký tự còn lại.


FWIW Qcâu trả lời thứ hai của bạn nên qdành cho mục đích không phải là trình bao bọc thử nghiệm.
Peter Taylor

@PeterTaylor Tôi làm điều đó mọi lúc -.-
Martin Ender

Tôi biết đó là một chi tiết nhỏ, nhưng chuyển đổi 3danh sách sang so sánh là một mẹo hay. Tôi đã giải quyết nó chỉ để giải trí và mất một byte ở đó vì tôi đã sử dụng 0=2>. Nếu không, tôi đã kết thúc với gần như giống như giải pháp đầu tiên của bạn, ngoại trừ việc sử dụng ::\ thay vì Wf%cho bước cuối cùng.
Reto Koradi

10

Bash, 95 94 85 81 byte

fold -2|sort|uniq -c|awk '$1>2{c[substr($2,2)]+=$1}END{for(x in c)printf x c[x]}'

Một giải pháp đầu tiên thanh lịch nhưng lâu dài để bắt đầu ...

Cảm ơn User112638726 vì đã tiết kiệm một byte với sed, DigitalTrauma để lưu 9 với foldRainer P. để tiết kiệm thêm 4 với awk's substr!

Để xem nó hoạt động như thế nào, hãy lấy đầu vào abababcbcbcbcbbababa.

  • Sau khi fold -2(bọc dòng thành chiều rộng bằng 2), chúng ta có

    ab
    ab
    cb
    cb
    cb
    cb
    ba
    ba
    ba
    
  • Sau sort | uniq -c( -clà một cờ rất tiện lợi để uniqxuất ra số lần mỗi dòng xuất hiện trong đầu vào), chúng tôi nhận được

          3 ab
          3 ba
          4 cb
    
  • Bây giờ hãy xem xét awklệnh cuối cùng :

    • $1>2: Chỉ công cụ đầu ra nếu bản ghi 1 (còn gọi là số phiếu giống hệt nhau) lớn hơn 2 (nghĩa là) 3). Nói cách khác, bỏ qua bất kỳ dòng nào bắt đầu bằng số ≤ 2.

    • {c[substr($2,2)]+=$1}: Nếu số lớn hơn 2, hãy thêm số đó vào cbảng băm, sử dụng char thứ hai của bản ghi 2 (còn gọi là biểu quyết-ee) làm khóa. (Chúng ta không phải khởi tạo mọi thứ về 0; awklàm điều đó cho chúng ta.)

    • END{...}: Điều này chỉ có nghĩa là "sau khi xử lý toàn bộ tệp, đây là việc cần làm tiếp theo."

    • for(x in c)printf x c[x]: Khá tự giải thích. In mọi khóa và giá trị tương ứng của nó.


&tương đương với \0trong sed
User112638726

@ User112638726 Không biết điều đó, cảm ơn
Doorknob

Giảm một chútsed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
Người dùng112638726

@ User112638726 Chẳng hạn, điều đó không thành công cho đầu vào bacada.
Doorknob

Ôi trời ơi!
Người dùng112638726

8

JavaScript, 114 113 110

f=s=>eval('o={},s.replace(/../g,m=>s.search(`^((..)*${m}){3}`)?0:o[c=m[1]]=~~o[c]+1);r="";for(v in o)r+=v+o[v]');

Các trường hợp thử nghiệm:

Ở mức cao, mã này cư trú một đối tượng với các cặp khóa-giá trị ánh xạ người nhận phiếu bầu thành số phiếu, thích { b:7, a:3 }và sau đó nối chúng thành một chuỗi trong một forvòng lặp. Mã nằm trong một evalbiểu thức để cho phép sử dụng forbên trong hàm mũi tên mà không cần chi tiêu byte { };return r.

(Đạo cụ cho user81655 để lưu ba byte!)

Giải thích về evalmã:

o={},                             // object to hold name/vote mapping
s.replace(/../g,                  // for each pair of chars in input
  m=>s.search(`^((..)*${m}){3}`)  // see if pair appears 3 times
                                  //   (0 if true, -1 if not)
     ?0                           // if not, do nothing
     :o[c=m[1]]=~~o[c]+1          // if yes, increment the property named after
                                  //   the second character in the pair
);
r="";                       // return string
for(v in o)r+=v+o[v]        // populate string with characters and vote totals

6

Haskell, 103 byte

import Data.Lists
f s|c<-chunksOf 2 s,b<-[e!!1|e<-c,countElem e c>2]=nub b>>= \q->q:show(countElem q b)

Ví dụ sử dụng: f "jkkjjkkjjkkjljljljmlmlnmnmnm"->"k3j6m3"

Làm thế nào nó hoạt động:

c<-chunksOf 2 s                      -- split the input into lists of 2 elements
b<-[e!!1|e<-c,countElem e c>2]       -- for every element e of that list take the 2nd
                                     -- char if there are more than 2 copies of e
nub b>>= \q->q:show(countElem q b)   -- take every uniq element thereof and append
                                     -- the number how often it appears 

6

JavaScript (ES6), 195 174 169 167 158 byte

s=v=>eval("a={},b={},e='';(v.match(/../g)).forEach(c=>{a[c]=(a[c]||0)+1});for(var k in a){d=k[1];a[k]>2&&(b[d]=(b[d]||0)+a[k])};for(var k in b){e+=k+b[k]};e")

Kiểm tra


1
Chào mừng bạn đến với PPCG :) Chúng tôi có một số mẹo chơi golf trong JS ở đâyđây . Tôi không biết bản thân mình đủ tốt để thực sự giúp đỡ, nhưng chơi golf vui vẻ :)
FryAmTheEggman

1
Đối với một điều, bạn có thể loại bỏ vars. Ai quan tâm đến việc gây ô nhiễm phạm vi toàn cầu trong mã golf? ;)
Doorknob

Ngoài ra, /(\w{2})/gchỉ có thể là /../g- chúng ta đã biết đầu vào chỉ là các chữ cái và việc lặp lại một (hoặc hai) ký tự ngắn hơn {2}. Nếu bạn quan tâm, bạn có thể xem (và nhận xét câu hỏi về) câu trả lời JavaScript của tôi cho thử thách này. Chào mừng đến với PGCC!
apsillers

4

Toán học, 110 100 99 byte

g=Cases[Tr@#,#2,All]&;""<>g[g[BlockMap[$,Characters@#,2],i_*_/;i>2]/.$->Last,i_*x_:>x<>ToString@i]&

3

Perl, 86 84 83 byte

s/../$h{$&}++/eg;@l=%l=map{/./;$h{$_}>2?($',${$'}+=$h{$_}):()}keys%h;$"="";$_="@l"

Đó là 82 byte cộng với 1 cho -pđối số dòng lệnh:

$ echo xyxyxyxyxyxyxyxyzyzyzyxzxzxz | perl -p 86.pl
y11z3


Hơi vô dụng:

s/../$h{$&}++/eg;     # construct hash %h with pair counts

@l = %l = map         # assign to array via hash to filter dupes
{                     
  /./;                # match the first character

  $h{$_}>2?           # filter on 3 or more identical votes
  (                   # return a 2 element list (k/v pair for %l):
    $',               # $POSTMATCH: the 2nd character (votee)
    ${$'} += $h{$_}   # increment votee total votes, value is new total
  )
  :()
}
keys %h;              # iterate the unique pairs

$" = "";              # set $LIST_SEPARATOR to empty string
$_ = "@l"             # implicit join using $";  $_ gets printed with -p
  • cập nhật 84 Lưu 2 byte bằng cách nội tuyến grep
  • cập nhật 83 Lưu 1 byte bằng cách sử dụng các vars tạm thời toàn cầu ${$'}thay vì $g{$'}. Thật không may, $$'không hoạt động.

3

Bash tinh khiết, 151

Lâu hơn tôi mong đợi, nhưng đây rồi.

declare -A a n
for((;v<${#1};v+=2));{((a[${1:v:2}]++));}
for u in ${!a[@]};{((a[$u]>2))&&((n[${u:1}]+=a[$u]));}
for u in ${!n[@]};{ printf $u${n[$u]};}

Sử dụng lập chỉ mục mảng kết hợp để làm việc đếm cần thiết. Yêu cầu bash phiên bản 4.0 trở lên.


1

Nhân vật PHP 247

(ouch)

$f='';for($i=0;$i<strlen($s);$i=$i+2){$a[]=$s[$i].$s[$i+1];}$r=[];for($i=0;$i<count($a);$i++){$t=array_count_values($a);$c=$t[$a[$i]];if($c>=3){$r[$a[$i][1]][$a[$i][0]]=$c;}}for($i=0;$i<count($r);$i++){$f.=key($r).array_sum(current($r));next($r);}

Giải thích

// Test Case
$s = 'nanananananananabatman';

// Final result here
$f = '';

// Seperate strings into array in 2 character chunks
for ($i = 0; $i < strlen($s); $i = $i + 2)
{
    $a[] = $s[$i] . $s[$i + 1];
}

// Make an array of data
// The first level of array has voted on user as key
// Inside of that array is a dictionary with the voter user as the key, and the number of votes as the value
$r = [];
for ($i = 0; $i < count($a); $i++)
{
    $t = array_count_values($a);
    $c = $t[$a[$i]];
    if ($c >= 3)
    {
        $r[$a[$i][1]][$a[$i][0]] = $c;
    }
}

// Combine votes from different users to the same user into the final result string
for ($i = 0; $i < count($r); $i++)
{
    $f .= key($r) . array_sum(current($r));
    next($r);
}

echo $f;

Đã làm điều này mà không nhìn trộm các câu trả lời khác. Đây là mã golf khó nhất mà tôi đã giải quyết. Tôi hoan nghênh tất cả các tối ưu hóa.


0

R, 221 byte

f=function(s){t=strsplit(gsub("(.{2})","\\1 ", s)," ")[[1]];z=table(t)[table(t)>2];n=substr(names(z),2,2);x=data.frame(y=z,t=n);a=aggregate(x$y,by=list(x$t),sum);for(i in nrow(a):1)cat(as.character(a[i,1]),a[i,2],sep="")}

vô dụng

f <- function(s){
  l <- gsub("(.{2})", "\\1 ", s)
  t <- strsplit(l," ")[[1]]
  z <- table(t)[table(t)>2]
  n <- substr(names(z),2,2)
  x <- data.frame(y=z,t=n)
  a <- aggregate(x$y, by=list(x$t),sum)
  for(i in nrow(a):1){
    cat(as.character(a[i,1]),a[i,2],sep="")
  }
}

Có rất nhiều phòng để cải thiện ở đây.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.