Stack Exchange secara otomatis mendeteksi pemungutan suara serial (ketika satu pengguna menaikkan atau menurunkan banyak pos pengguna lain) dan membalikkannya. Dalam tantangan ini, Anda akan menerapkan detektor "suara serial" yang sangat, sangat sederhana.
Memasukkan
Input adalah string yang mewakili daftar suara. Setiap kelompok yang terdiri dari dua karakter mewakili suara — yang pertama adalah pemilih, dan yang kedua adalah pengguna yang dipilih. Misalnya input berikut
ababbccd
dapat diuraikan sebagai ab
ab
bc
cd
, dan mewakili a
suara b
dua kali,
b
suara c
satu kali, dan c
suara d
satu kali.
Input hanya akan terdiri dari huruf kecil, dan itu akan selalu panjang> 0. Anda juga tidak dapat memilih diri sendiri (jadi tidak ada aa
atau hh
).
Keluaran
Untuk keperluan tantangan ini, pemungutan suara seri didefinisikan sebagai setiap pemungutan suara yang diberikan pada pemakai lain sebanyak tiga kali atau lebih.
Outputnya adalah berapa banyak suara yang harus dibalik untuk setiap pengguna (yaitu, berapa banyak suara pada setiap pengguna dibalik, bukan berapa banyak suara yang telah mereka berikan dibalik), dalam format [user][votes][user2][votes2]...
. Misalnya, input abababab
( a
pemungutan suara b
empat kali) harus menampilkan
b4
(empat suara telah terbalik dari a
ke b
).
Output mungkin dalam urutan apa pun yang Anda inginkan, tetapi input dan output harus berupa string tunggal seperti yang dijelaskan di atas.
Uji kasus
In Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa b7a3
edfdgdhdfgfgfgih g3
jkkjjkkjjkkjljljljmlmlnmnmnm j6k3m3
opqrstuv <none>
vwvwwvwv <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz y10z3
nanananananananabatman a8
banana <none>
nanananananananabatman
kasus uji.Jawaban:
Pyth, 22 byte
Cobalah online: Demonstrasi atau Test Suite
Penjelasan:
Contoh:
sumber
Tidak dapat dibaca ,
18301796179117711762174517361727162616061577 byteOutput dalam urutan abjad terbalik (
z
kea
) tetapi sesuai dengan aturan Anda yang tampaknya diizinkan.Penjelasan
Pertama, untuk mendapatkan kesan tentang apa yang dapat dilakukan Unreadable, berikut ini adalah operasi dasarnya:
write(x, inc(read(x)))
.Program ini menggunakan rekaman itu sebagai berikut. Nama-nama variabel akan digunakan dalam pseudocode nanti di bawah ini. Juga, ini mendokumentasikan versi pertama (yang 1830 byte); lihat pengeditan di bagian bawah untuk apa yang berubah sejak itu.
q
a
,p
,ch
hash
,v
b
,r
aa
,l
a
(96) hinggaz
(121) (kode ASCII surat itu dikurangi satu).0
= belum terlihat,-1
= terlihat sekali,-2
= terlihat dua kali,-3
= terlihat beberapa kali lebih dari 2.Algoritma pada dasarnya melanjutkan sebagai berikut:
a
danb
. Hitung nilai hash(a-2)*(a-1)+b-1
, yang unik untuk setiap kombinasi huruf a – z.*hash
). Jika itu-3
, pengguna sudah memenuhi syarat untuk penghapusan suara, jadi tambahlah*(b-1)
. Kalau tidak, pengurangan*hash
. Jika itu sekarang-3
, pengguna baru saja menjadi layak untuk penghapusan suara setelah tiga kejadian, sehingga kenaikan*(b-1)
oleh3
.z
kea
) dan keluarkan karakter yang perlu dikurangi suara. Ini membutuhkan pembagian integer manual sebesar 10 untuk menerjemahkan angka menjadi angka desimal.Dengan semua yang diklarifikasi, inilah yang tampak seperti program sebagai pseudocode:
Sunting 1, 1830 → 1796: Menyadari bahwa saya dapat menggunakan kembali nilai loop sementara di satu tempat.
Sunting 2, 1796 → 1791: Menghidupkan program sedikit lebih kecil jika, daripada menggunakan sel 6–95, saya menyimpan angka desimal dalam sel bernomor negatif (–1 dan seterusnya). Sebagai bonus tambahan, program ini tidak lagi terbatas pada 10⁹⁰ suara!
Sunting 3, 1791 → 1771: Alih-alih menetapkan hasil
*(ch = l + 95)
untukv
, sekarang saya menugaskan keq
dan kemudian memindahkan tugasv = q
ke dalam kondisi sementara, mengambil kode ke 1777 byte. Kemudian tukar lokasiq
danv
pada kaset karenaq
sekarang 1 lebih umum daripadav
.Sunting 4, 1771 → 1762: Duh. Menginisialisasi
hash
ke 1 bukannya 0 adalah 9 byte lebih pendek. Kode hash sekarang 1 lagi, yang tidak masalah.Sunting 5, 1762 → 1745: Jika saya menginisialisasi
q
danr
ke 1 alih-alih 0, saya harus memercikkan beberapa-1
di beberapa tempat untuk memperbaikinya, dan semuanya sepertinya dibatalkan - kecuali bahwawhile v { --v; [...] }
loop sekarang perlu menjalankan satu iterasi yang lebih sedikit, yang bisa saya lakukan dengan mengatakanwhile --v { [...] }
, yaitu 26 karakter lebih pendek.Sunting 6, 1745 → 1736: Alih-alih
{ r = 1; ++q }
, kita dapat menulisq = *((r = 1)+1)+1
. Ini bergantung pada fakta yangq
ada di slot variabel # 2. Jika ada di slot # 1 ini akan lebih pendek, tetapi keseluruhan program akan lebih lama secara keseluruhan.Sunting 7, 1745 → 1727: Kembalikan Sunting 6 dan alih-alih mencapai penghematan dengan menggariskan bagian terdalam sementara loop ke dalam ekspresi yang menghitung kode ASCII digit, yang juga berakhir pada 1736 byte ... tetapi kemudian menyimpan instruksi penurunan (9 byte) ) dengan mengubah
((++r) - 11) ? r :
ke(r - 10) ? ++r :
.Sunting 8, 1727 → 1626: Mengolah kembali perhitungan hash. Sekarang menggunakan satu loop sementara lebih sedikit. Lokasi sel sekarang pada kode ASCII mereka yang sebenarnya (tidak mati oleh 1 lagi). Variabel yang diacak ulang ke lokasi yang berbeda pada kaset karena sekarang terjadi dengan frekuensi yang berbeda.
Sunting 9, 1626 → 1606: Inlining lebih gila. Tubuh loop sementara pertama sekarang terlihat seperti ini:
dan tugas variabel sekarang hampir sepenuhnya berubah.
Mengedit 10, 1606 → 1577: Saya mengamati bahwa
a
dana2
keduanya dikurangi menjadi 0 sementara loop, jadi jika saya bisa memasangkanp
dengan salah satu dari mereka, tetapi tidak denganch
, saya tidak perlu menginisialisasip
ke0
(yang biaya 29 bytes). Ternyata saya bisa melakukannya dengan menukarp
danr
. Variabel assigment terbaru (dan frekuensi kemunculannya dalam kode) sekarang adalah:sumber
CJam, 23 byte
Pesta lari panjang!
atau
Jalankan semua test case
Penjelasan
Versi lain dimulai dengan membalikkan pasangan, yang menyimpan dua byte di tempat lain: a) memilih karakter pertama di setiap string hanya
:c
bukanWf=
untuk memilih yang kedua. b) Kita tidak perlu menyortir lagi sebelum RLE kedua, karena pasangan sudah diurutkan berdasarkan karakter yang tersisa.sumber
Q
di jawaban kedua Anda harusq
untuk tujuan non-test-wrapper.3
ke daftar untuk perbandingan adalah trik yang bagus. Saya menyelesaikannya hanya untuk hiburan saya sendiri, dan kehilangan satu byte di sana karena saya gunakan0=2>
. Kalau tidak, saya berakhir dengan hampir sama dengan solusi pertama Anda, kecuali untuk menggunakan::\
alih-alihWf%
untuk langkah terakhir.Bash,
95948581 byteSolusi pertama yang elegan tapi panjang untuk memulai ...
Terima kasih kepada User112638726 untuk menyimpan byte dengan
sed
, DigitalTrauma untuk menghemat 9 denganfold
, dan Rainer P. untuk menyimpan 4 lebih banyak denganawk
'ssubstr
!Untuk melihat cara kerjanya, mari kita masukan
abababcbcbcbcbbababa
.Setelah
fold -2
(bungkus garis dengan lebar 2), kita milikiSetelah
sort | uniq -c
(-c
adalah tanda yang sangat bagus untukuniq
menampilkan hitungan berapa kali setiap baris muncul di input), kita mendapatkanSekarang mari kita periksa
awk
perintah terakhir :$1>2
: Hanya menampilkan barang jika catatan 1 (alias jumlah suara yang identik) lebih besar dari 2 (yaitu, ≥ 3). Dengan kata lain, abaikan baris yang dimulai dengan angka ≤ 2.{c[substr($2,2)]+=$1}
: Jika angka lebih besar dari 2, tambahkan nomor itu kec
tabel hash, menggunakan karakter kedua dari catatan 2 (alias suara-ee) sebagai kuncinya. (Kita tidak perlu menginisialisasi semuanya menjadi nol;awk
lakukan itu untuk kita.)END{...}
: Ini hanya berarti "setelah memproses seluruh file, inilah yang harus dilakukan selanjutnya."for(x in c)printf x c[x]
: Cukup jelas. Cetak setiap kunci dan nilainya yang sesuai.sumber
&
setara dengan\0
sedsed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
bacada
, misalnya.JavaScript,
114113110Kasus uji:
Tampilkan cuplikan kode
Pada tingkat tinggi, kode ini mengisi objek dengan pasangan kunci-nilai yang memetakan penerima suara ke jumlah suara, seperti
{ b:7, a:3 }
dan kemudian menggabungkannya ke dalam sebuah string dalam satufor
lingkaran. Kode dalameval
ekspresi untuk memungkinkan penggunaanfor
dalam fungsi panah tanpa perlu menghabiskan byte{ }
dan;return r
.(Props untuk pengguna81655 untuk menghemat tiga byte!)
Penjelasan
eval
kode:sumber
Haskell, 103 byte
Contoh penggunaan:
f "jkkjjkkjjkkjljljljmlmlnmnmnm"
->"k3j6m3"
Bagaimana itu bekerja:
sumber
JavaScript (ES6),
195174169167158 byteUji
Tampilkan cuplikan kode
sumber
var
s. Siapa yang peduli tentang mencemari ruang lingkup global dalam kode golf? ;)/(\w{2})/g
bisa jadi/../g
- kita sudah tahu inputnya hanya huruf, dan mengulangi satu (atau dua) karakter lebih pendek dari{2}
. Jika Anda tertarik, Anda dapat melihat (dan mengomentari pertanyaan) jawaban JavaScript saya untuk tantangan ini. Selamat datang di PGCC!Mathematica,
11010099 bytesumber
Perl,
868483 byteItu 82 byte plus 1 untuk
-p
argumen commandline:Agak tidak terserang:
${$'}
bukan$g{$'}
. Sayangnya,$$'
tidak berhasil.sumber
Pure Bash, 151
Lebih lama dari yang saya harapkan, tapi ini dia.
Menggunakan pengindeksan array asosiatif untuk melakukan penghitungan yang diperlukan. Membutuhkan bash versi 4.0 atau lebih tinggi.
sumber
PHP 247 Karakter
(Aduh)
Dijelaskan
Apakah ini tanpa mengintip jawaban lain. Ini adalah kode golf paling sulit yang pernah saya tangani. Saya menyambut semua optimasi.
sumber
R, 221 byte
kode
ungolfed
Ada banyak ruang untuk perbaikan di sini.
sumber