การตรวจจับการลงคะแนนแบบอนุกรม


51

Stack Exchange จะตรวจจับการลงคะแนนแบบอนุกรมโดยอัตโนมัติ(เมื่อผู้ใช้รายหนึ่ง upvotes หรือ downvotes โพสต์ของผู้ใช้อื่นจำนวนมาก) และกลับรายการ ในการท้าทายนี้คุณจะต้องใช้เครื่องตรวจจับ "การลงคะแนนแบบอนุกรม" ที่ง่ายมาก ๆ

อินพุต

อินพุตเป็นสตริงที่แสดงรายการคะแนนโหวต ทุกกลุ่มของตัวละครทั้งสองแสดงถึงการลงคะแนน - กลุ่มแรกคือผู้ลงคะแนนเสียงและอีกกลุ่มคือผู้ใช้ที่ได้รับการโหวต ตัวอย่างเช่นอินพุตต่อไปนี้

ababbccd

สามารถแยกวิเคราะห์เป็นab ab bc cdและแสดงถึงการaลงคะแนนในbสองครั้งการ bลงคะแนนในcครั้งเดียวและการcลงคะแนนในdครั้งเดียว

การป้อนข้อมูลจะประกอบด้วยตัวอักษรตัวพิมพ์เล็กเท่านั้นและมันก็จะยิ่งยาว> 0 นอกจากนี้คุณยังไม่สามารถลงคะแนนในตัวเอง (จึงไม่มีaaหรือhh)

เอาท์พุต

สำหรับจุดประสงค์ของการท้าทายนี้การลงคะแนนแบบอนุกรมถูกกำหนดให้เป็นการลงคะแนนเสียงของผู้ใช้ที่ให้แก่ผู้ใช้รายอื่น ๆ สามครั้งขึ้นไป

ผลลัพธ์คือจำนวนโหวตควรกลับสำหรับผู้ใช้แต่ละ (นั่นคือวิธีการโหวตจำนวนมากเกี่ยวกับผู้ใช้แต่ละคนได้รับกลับไม่ได้เป็นจำนวนเสียงที่พวกเขาได้รับเป็นตรงกันข้าม) [user][votes][user2][votes2]...ในรูปแบบ ตัวอย่างเช่นอินพุทของabababab(การaลงคะแนนbสี่ครั้ง) ควรเอาท์พุท b4(โหวตสี่ครั้งถูกย้อนกลับจากaเป็นb)

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

กรณีทดสอบ

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

16
+1 สำหรับnanananananananabatmanกรณีทดสอบ
เก้า

คำตอบ:


6

Pyth, 22 ไบต์

pM_srSsfttTtMM.gkcz2 8

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

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

ตัวอย่าง:

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

ไม่สามารถอ่านได้ , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 ไบต์

เอาต์พุตอยู่ในลำดับตามตัวอักษรย้อนกลับ ( zถึงa) แต่เป็นไปตามกฎของคุณที่อนุญาต

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

คำอธิบาย

ก่อนอื่นเพื่อรับความประทับใจในสิ่งที่อ่านไม่ได้สามารถทำได้นี่คือการดำเนินการขั้นพื้นฐาน:

  • คุณมีเทปจำนวนเต็มของเซลล์จำนวนเต็มที่ไม่มีขีด จำกัด
  • คุณไม่มีตัวชี้หน่วยความจำเหมือนใน Brainfuck คุณทำการค้นหาเซลล์ซ้ำตามตำแหน่งของพวกเขาบนเทปแทน ซึ่งหมายความว่าคุณสามารถ“ อ่านค่า # 4” หรือ“ อ่านค่า # (อ่านค่า # 4)” (อ่านซ้ำสองครั้ง)
  • คุณสามารถอ่านหรือเขียนเซลล์หน่วยความจำเท่านั้น (ไม่เพิ่ม / ลดโดยตรงเช่นเดียวกับใน Brainfuck)
  • คุณสามารถเพิ่ม / ลดค่าภายในนิพจน์ ดังนั้นเพื่อเพิ่มเซลล์หน่วยความจำที่คุณต้องอ่าน , เพิ่มขึ้น , เขียนwrite(x, inc(read(x)))หรือแตกต่างกันใส่:
  • มีในขณะที่ลูปและเงื่อนไขแบบสามมิติที่สามารถตรวจสอบได้เฉพาะกับศูนย์กับที่ไม่ใช่ศูนย์

โปรแกรมนี้ใช้เทปดังนี้ ชื่อตัวแปรจะถูกใช้ใน pseudocode ภายหลังด้านล่าง นอกจากนี้เอกสารฉบับแรก (ซึ่งเป็น 1830 ไบต์); ดูการแก้ไขที่ด้านล่างสำหรับสิ่งที่เปลี่ยนแปลงไปตั้งแต่

  • เซลล์ 0:ตัวแปรq
  • มือถือ 1:ตัวแปรa, p,ch
  • มือถือ 2:ตัวแปรhash,v
  • มือที่ 3:ตัวแปรb,r
  • มือถือ 4:ตัวแปรaa,l
  • เซลล์ 5:เหลือ 0 เพื่อทำเครื่องหมาย "สิ้นสุด" ของสตริงตัวเลขทศนิยม
  • เซลล์ 6–95:จัดเก็บสตริงทศนิยมหลัง
  • เซลล์ 96–121:เก็บจำนวนคะแนนที่จะถูกหักจากผู้ใช้a(96) ถึงz(121) (รหัส ASCII ของจดหมายลบหนึ่ง)
  • เซลล์ 4657–7380:จำได้ว่ามีการรวมกันของผู้มีสิทธิเลือกตั้ง / ผู้มีสิทธิเลือกตั้งจำนวนกี่ครั้ง เซลล์เหล่านี้มีค่าที่เป็นไปได้เพียง 4 ค่า: 0= ยังไม่เห็น, -1= เห็นหนึ่งครั้ง, -2= เห็นสองครั้ง, -3= เห็นจำนวนครั้งใด ๆ ที่มากกว่า 2

อัลกอริทึมเป็นหลักดำเนินการดังนี้

  • ให้อ่านคู่ของตัวละครและa bคำนวณค่าแฮช(a-2)*(a-1)+b-1ซึ่งเป็นค่าเฉพาะสำหรับการรวมกันของตัวอักษร a – z
  • ตรวจสอบเซลล์หน่วยความจำด้วยค่าแฮช ( *hash) ถ้าเป็นผู้ใช้ที่มีอยู่แล้วมีสิทธิ์ในการกำจัดการลงคะแนนเสียงเพื่อให้เพิ่มขึ้น-3 มิฉะนั้นพร่อง*(b-1) *hashถ้าเป็นตอนนี้ -3ผู้ใช้เพิ่งกลายเป็นมีสิทธิ์ลงคะแนนเสียงสำหรับการกำจัดหลังจากที่สามเกิดขึ้นดังนั้นการเพิ่มขึ้นโดย*(b-1)3
  • หลังจากนี้ไปถึงตัวละครในลำดับย้อนกลับ ( zไปa) และส่งออกตัวละครที่ต้องได้รับคะแนนโหวตหัก ต้องมีการหารจำนวนเต็มด้วยตนเอง 10 เพื่อแปลตัวเลขเป็นเลขทศนิยม

ด้วยสิ่งที่ทำให้กระจ่างนี่คือสิ่งที่โปรแกรมดูเหมือนว่าเป็นรหัสเทียม:

// 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
}

แก้ไข 1, 1830 → 1796:ตระหนักว่าฉันสามารถใช้ค่าส่งคืนของลูป while อีกครั้งในที่เดียว

แก้ไข 2, 1796 → 1791:เปิดโปรแกรมให้เล็กลงเล็กน้อยถ้าแทนที่จะใช้เซลล์ 6–95 ฉันจะเก็บตัวเลขทศนิยมไว้ในเซลล์ติดลบ (–1 เป็นต้นไป) เป็นโบนัสที่เพิ่มเข้ามาโปรแกรมไม่ จำกัด เพียง10⁹⁰โหวต!

แก้ไข 3, 1791 → 1771:แทนการกำหนดผลลัพธ์ของ*(ch = l + 95)ถึงvตอนนี้ฉันกำหนดให้qและจากนั้นย้ายการมอบหมายv = qไปยังเงื่อนไขในขณะที่นำรหัสไปที่ 1777 ไบต์ จากนั้นสลับตำแหน่งของqและvบนเทปเพราะqตอนนี้เป็นเรื่องธรรมดามากกว่าv1

แก้ไข 4, 1771 → 1762: Duh การเริ่มต้นhashที่ 1 แทน 0 จะมีความยาว 9 ไบต์ ตอนนี้รหัสแฮชเพิ่มอีก 1 รายการซึ่งไม่สำคัญ

แก้ไข 5, 1762 → 1745:ถ้าฉันเริ่มต้นqและrเป็น 1 แทน 0 ฉันต้องโรยบาง-1ที่เพื่อให้ถูกต้องและดูเหมือนว่ามันจะถูกยกเลิก - ยกเว้นว่าwhile v { --v; [...] }ตอนนี้ลูปจะต้องดำเนินการซ้ำหนึ่งครั้งน้อยลง ซึ่งฉันสามารถทำได้โดยการพูดwhile --v { [...] }ซึ่งสั้นกว่า 26 ตัวอักษร

แก้ไข 6, 1745 → 1736:แทนที่จะเราสามารถเขียน{ r = 1; ++q } q = *((r = 1)+1)+1สิ่งนี้ขึ้นอยู่กับข้อเท็จจริงที่qอยู่ในตัวแปรสล็อต # 2 หากอยู่ใน slot # 1 สิ่งนี้จะสั้นกว่านี้ แต่โปรแกรมทั้งหมดจะมีความยาวโดยรวมมากกว่า

แก้ไข 7, 1745 → 1727:ย้อนกลับแก้ไข 6 และแทนการประหยัดโดยการฝังอินทราสต์ในขณะที่วนเข้าสู่นิพจน์ที่คำนวณรหัส ASCII หลักซึ่งสิ้นสุดที่ 1736 ไบต์ ... แต่บันทึกคำสั่งลดลง (9 ไบต์) ) โดยการเปลี่ยนไป((++r) - 11) ? r :(r - 10) ? ++r :

แก้ไข 8, 1727 → 1626:ทำการคำนวณแฮชทำใหม่ ตอนนี้ใช้น้อยลงหนึ่งขณะที่วนซ้ำ ตอนนี้ที่ตั้งของเซลล์นั้นอยู่ที่รหัส ASCII จริงของพวกเขา (ไม่ปิดอีก 1) ปรับเปลี่ยนตัวแปรไปยังตำแหน่งต่างๆบนเทปเนื่องจากตอนนี้เกิดขึ้นกับความถี่ที่แตกต่างกัน

แก้ไข 9, 1626 → 1606: การอินไลน์อย่างบ้าคลั่งมากขึ้น เนื้อความของแรกในขณะที่วนรอบตอนนี้มีลักษณะดังนี้:

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

และการมอบหมายตัวแปรเปลี่ยนแปลงเกือบทั้งหมดแล้ว

แก้ไข 10 1606 → 1577:ผมสังเกตว่าaและa2มีทั้ง decremented 0 ในขณะที่ลูปดังนั้นถ้าฉันจะจับคู่pกับทั้งของเหล่านั้น แต่ไม่ได้กับchผมจะไม่จำเป็นต้องเริ่มต้นpที่จะ0(ซึ่งค่าใช้จ่าย 29 bytes) เปิดออกฉันจะทำโดยการแลกเปลี่ยนและp rการกำหนดตัวแปรใหม่ล่าสุด (และความถี่ของการเกิดขึ้นในโค้ด) คือ:

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
เมื่อเห็นว่าคะแนนโหวตnovemvigintillionจะต้องมีสตริง 2 * 10 ^ 90 ไบต์และปริมาณที่เล็กที่สุดที่เป็นไปได้ในปัจจุบันคือ 10 ^ 24 ไบต์มีขนาดประมาณ 1/3 ของมหาปิรามิดแห่งกิซ่าผมไม่คิดว่าคุณมี สิ่งที่ต้องกังวล ;)
ETHproductions

1
@ETHproductions: อย่างไรก็ตามในขณะที่การเล่นกอล์ฟโปรแกรมฉันเกิดขึ้นเพื่อแก้ไขปัญหาที่ข้อ จำกัด :)
Timwi

22

CJam, 23 ไบต์

ปาร์ตี้วิ่งยาว!

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

หรือ

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

เรียกใช้กรณีทดสอบทั้งหมด

คำอธิบาย

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.

รุ่นอื่นเริ่มต้นด้วยการย้อนกลับคู่ซึ่งจะช่วยประหยัดสองไบต์ที่อื่น: a) การเลือกตัวอักษรตัวแรกในแต่ละสายจะเป็นเพียง:cแทนWf=การเลือกที่สอง b) เราไม่จำเป็นต้องจัดเรียงอีกครั้งก่อน RLE ตัวที่สองเพราะคู่นั้นถูกเรียงลำดับโดยตัวละครที่เหลืออยู่แล้ว


FWIW Qในคำตอบที่สองของคุณควรเป็นไปqเพื่อวัตถุประสงค์ที่ไม่ใช่การห่อหุ้ม
Peter Taylor

@PeterTaylor ฉันทำอย่างนั้นตลอดเวลา -.
มาร์ตินเอนเดอร์

ฉันรู้ว่ามันเป็นรายละเอียดเล็กน้อย แต่การแปลง3เป็นรายการสำหรับการเปรียบเทียบนั้นเป็นเคล็ดลับที่ดี 0=2>ฉันจะแก้ไขมันเพียงเพื่อความบันเทิงของตัวเองและการสูญเสียไบต์มีเพราะผมใช้ มิฉะนั้นฉันก็เกือบจะเหมือนกันกับโซลูชั่นแรกของคุณยกเว้นการใช้::\ แทนWf%สำหรับขั้นตอนสุดท้าย
Reto Koradi

10

Bash, 95 94 85 81 ไบต์

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

วิธีการแก้ปัญหาที่สง่างาม แต่ยาวก่อนที่จะเริ่ม ...

ขอขอบคุณที่User112638726สำหรับการบันทึกไบต์ด้วยsed, DigitalTrauma สำหรับการบันทึก 9 foldและเรนเนอร์พีสำหรับการบันทึก 4 มากขึ้นด้วยawk's substr!

abababcbcbcbcbbababaเพื่อดูว่ามันทำงานได้ลองการป้อนข้อมูล

  • หลังจากfold -2(ตัดบรรทัดเป็นความกว้าง 2) เรามี

    ab
    ab
    cb
    cb
    cb
    cb
    ba
    ba
    ba
    
  • หลังจากsort | uniq -c( -cเป็นแฟล็กที่ดีมากในการuniqแสดงผลจำนวนครั้งที่แต่ละบรรทัดปรากฏในอินพุต) เราจะได้รับ

          3 ab
          3 ba
          4 cb
    
  • ตอนนี้ลองตรวจสอบawkคำสั่งสุดท้าย:

    • $1>2: เฉพาะสิ่งที่ส่งออกถ้าบันทึก 1 (หรือที่เรียกว่าจำนวนโหวตที่เหมือนกัน) มากกว่า 2 (นั่นคือ≥ 3) กล่าวอีกนัยหนึ่งไม่ต้องสนใจบรรทัดใด ๆ ที่ขึ้นต้นด้วยตัวเลข≤ 2

    • {c[substr($2,2)]+=$1}: หากตัวเลขมากกว่า 2 ให้เพิ่มหมายเลขนั้นลงในcตารางแฮชโดยใช้อักขระที่สองของระเบียน 2 (aka the-vote) เป็นคีย์ (เราไม่จำเป็นต้องเริ่มต้นทุกอย่างให้เป็นศูนย์awkทำแบบนั้นกับเรา

    • END{...}: นี่หมายถึง "หลังจากประมวลผลไฟล์ทั้งหมดนี่คือสิ่งที่ต้องทำต่อไป"

    • for(x in c)printf x c[x]: อธิบายตนเองอย่างยุติธรรม พิมพ์ทุกคีย์และค่าที่เกี่ยวข้อง


&เทียบเท่ากับ\0ใน sed
User112638726

@ User112638726 ไม่ทราบว่าเป็นเช่นนั้นขอบคุณ
Doorknob

ลดลงเล็กน้อยsed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
User112638726

@ User112638726 ที่ล้มเหลวสำหรับอินพุตbacadaตัวอย่างเช่น
ลูกบิดประตู

โอ้ใช่ฉันไม่ดี!
User112638726

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]');

กรณีทดสอบ:

ในระดับสูงรหัสนี้บรรจุวัตถุที่มีคู่คีย์ - ค่าที่จับคู่ผู้รับการโหวตกับจำนวนการลงคะแนนเช่น{ b:7, a:3 }จากนั้นรวมเข้ากับสตริงในforลูป รหัสในevalการแสดงออกในการอนุญาตให้ใช้forภายในฟังก์ชั่นลูกศรโดยไม่จำเป็นต้องไบต์ใช้จ่ายและ{ };return r

(อุปกรณ์ประกอบฉากเพื่อuser81655สำหรับการบันทึกสามไบต์!)

คำอธิบายของevalรหัส:

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 ไบต์

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)

ตัวอย่างการใช้: f "jkkjjkkjjkkjljljljmlmlnmnmnm"->"k3j6m3"

มันทำงานอย่างไร:

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 ไบต์

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

ทดสอบ


1
ยินดีต้อนรับสู่ PPCG :) เรามีเคล็ดลับในการเล่นกอล์ฟใน JS ที่นี่และที่นี่ ฉันไม่รู้จักตัวเองดีพอที่จะช่วยได้จริงๆ แต่การเล่นกอล์ฟที่มีความสุข :)
FryAmTheEggman

1
สำหรับสิ่งหนึ่งคุณสามารถลบvars ใครที่ห่วงเรื่องมลพิษโลกาภิวัฒน์ในการเล่นกอล์ฟ ;)
Doorknob

นอกจากนี้/(\w{2})/gก็สามารถจะเป็น/../g- เรารู้อยู่แล้วว่าการป้อนข้อมูลที่เป็นตัวอักษรและการทำซ้ำ (หรือสอง) {2}ตัวละครจะสั้นกว่า หากคุณสนใจคุณสามารถดู (และคำถามแสดงความคิดเห็นใน) คำตอบ JavaScript ของฉันกับความท้าทายนี้ ยินดีต้อนรับสู่ PGCC!
apsillers


3

Perl, 86 84 83 ไบต์

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

นั่นคือ 82 ไบต์บวก 1 สำหรับ-pอาร์กิวเมนต์ commandline:

$ echo xyxyxyxyxyxyxyxyzyzyzyxzxzxz | perl -p 86.pl
y11z3


ค่อนข้าง ungolfed:

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
  • อัปเดต 84บันทึก 2 ไบต์ด้วยการฝัง grep
  • อัปเดต 83บันทึก 1 ไบต์โดยใช้ vars ชั่วคราวทั่วโลกแทน${$'} $g{$'}น่าเสียดายที่$$'มันใช้ไม่ได้

3

Pure Bash, 151

นานกว่าที่ฉันคาดหวัง แต่ที่นี่มันเป็น

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]};}

ใช้การจัดทำดัชนีอาเรย์แบบเชื่อมโยงเพื่อทำการนับที่จำเป็น ต้องการ bash เวอร์ชั่น 4.0 หรือสูงกว่า


1

PHP 247 ตัวละคร

(อุ๊ย)

$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);}

อธิบาย

// 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;

ทำสิ่งนี้โดยไม่แอบดูคำตอบอื่น ๆ นี่คือรหัสกอล์ฟที่ยากที่สุดที่ฉันเคยเล่นมา ฉันยินดีต้อนรับการเพิ่มประสิทธิภาพทั้งหมด


0

R, 221 ไบต์

รหัส

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="")}

ungolfed

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="")
  }
}

มีห้องพักมากมายสำหรับการปรับปรุงที่นี่

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