Stack Exchange automatycznie wykrywa głosowanie seryjne (gdy jeden użytkownik głosuje lub głosuje wiele postów innego użytkownika) i odwraca go. W tym wyzwaniu zaimplementujesz bardzo prosty detektor „głosowania seryjnego”.
Wejście
Dane wejściowe to ciąg znaków reprezentujący listę głosów. Każda grupa dwóch znaków reprezentuje głos - pierwsza to głosujący, a druga głosujący użytkownik. Na przykład następujące dane wejściowe
ababbccd
może być parsowany jako ab
ab
bc
cd
i reprezentuje a
głosowanie b
dwa razy,
b
głosowanie c
raz i c
głosowanie d
raz.
Dane wejściowe będą się składać tylko z małych liter i zawsze będą miały równą długość> 0. Nie możesz także głosować na siebie (więc nie aa
lub hh
).
Wynik
Na potrzeby tego wyzwania głosowanie seryjne definiuje się jako głosowanie danego użytkownika na dowolnym innym użytkowniku trzy lub więcej razy.
Dane wyjściowe określają, ile głosów należy cofnąć dla każdego użytkownika (to znaczy, ile głosów na każdego użytkownika zostało cofniętych, a nie ile głosów oddanych zostało odwróconych), w formacie [user][votes][user2][votes2]...
. Na przykład wkład abababab
( a
głosowanie b
czterokrotnie) powinien dać wynik
b4
(cztery głosy zostały odwrócone z a
na b
).
Dane wyjściowe mogą być w dowolnej kolejności, ale dane wejściowe i wyjściowe muszą być pojedynczymi ciągami, jak opisano powyżej.
Przypadki testowe
In Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa b7a3
edfdgdhdfgfgfgih g3
jkkjjkkjjkkjljljljmlmlnmnmnm j6k3m3
opqrstuv <none>
vwvwwvwv <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz y10z3
nanananananananabatman a8
banana <none>
nanananananananabatman
przypadku testowego.Odpowiedzi:
Pyth, 22 bajty
Wypróbuj online: pakiet demonstracyjny lub testowy
Wyjaśnienie:
Przykład:
źródło
Nieczytelny ,
18301796179117711762174517361727162616061577 bajtówDane wyjściowe są w odwrotnej kolejności alfabetycznej (
z
doa
), ale zgodnie z regułami, które wydają się dozwolone.Wyjaśnienie
Po pierwsze, aby zorientować się, co może zrobić Nieczytelny, oto jego podstawowe działanie:
write(x, inc(read(x)))
.Ten program używa taśmy w następujący sposób. Nazwy zmiennych zostaną użyte w pseudokodzie później poniżej. Dokumentuje także pierwszą wersję (1830 bajtów); zobacz zmiany u dołu, które zmieniły się od tego czasu.
q
a
,p
,ch
hash
,v
b
,r
aa
,l
a
(96) doz
(121) (kod ASCII litery minus jeden).0
= jeszcze nie widział,-1
= widział raz,-2
= widział dwa razy,-3
= widział dowolną liczbę razy więcej niż 2.Algorytm zasadniczo działa w następujący sposób:
a
ib
. Oblicz wartość skrótu(a-2)*(a-1)+b-1
, która jest unikalna dla każdej kombinacji liter a – z.*hash
). Jeśli tak-3
, użytkownik jest już uprawniony do usunięcia głosu, więc zwiększaj*(b-1)
. W przeciwnym razie spadek*hash
. Jeśli jest to teraz-3
, użytkownik po prostu stać się kwalifikują się do usunięcia głosowanie po trzech zdarzeń, więc zwiększyć*(b-1)
przez3
.z
doa
) i wypisz te, które wymagają odliczenia głosów. Wymaga to ręcznego dzielenia liczb całkowitych przez 10, aby przełożyć liczbę na cyfry dziesiętne.Po tym wszystkim wyjaśniono, że tak wygląda program jako pseudokod:
Edycja 1, 1830 → 1796: Uświadomiłem sobie, że mogę ponownie użyć wartości zwracanej pętli while w jednym miejscu.
Edycja 2, 1796 → 1791: Okazuje się, że program jest nieco mniejszy, jeśli zamiast komórek 6–95 przechowuję cyfry dziesiętne w komórkach o numerach ujemnych (–1 wzwyż). Jako dodatkowy bonus program nie jest już ograniczony do 10⁹⁰ głosów!
Edycja 3, 1791 → 1771: Zamiast przypisywać wynik
*(ch = l + 95)
dov
, teraz przypisuję go do,q
a następnie przenoszę przypisaniev = q
do warunku while, przenosząc kod do 1777 bajtów. Następnie zamień lokalizacjęq
iv
na taśmie, ponieważq
jest teraz o 1 bardziej powszechna niżv
.Edytuj 4, 1771 → 1762: Duh. Inicjalizacja
hash
na 1 zamiast 0 jest krótsza o 9 bajtów. Kod skrótu jest teraz o 1 więcej, co nie ma znaczenia.Edycja 5, 1762 → 1745: Jeśli zainicjuję
q
ir
do 1 zamiast 0, muszę posypać kilka-1
s miejscami, aby wszystko było w porządku, i wydaje się, że wszystko się anuluje - poza tym, żewhile v { --v; [...] }
pętla musi teraz wykonać jedną mniejszą iterację, co mogę zrobić, mówiąc owhile --v { [...] }
26 znaków krótszych.Edycja 6, 1745 → 1736: Zamiast tego
{ r = 1; ++q }
możemy pisaćq = *((r = 1)+1)+1
. Zależy to od faktu, żeq
znajduje się w zmiennej szczelinie nr 2. Gdyby znajdował się w gnieździe nr 1, byłby jeszcze krótszy, ale cały program byłby ogólnie dłuższy.Edycja 7, 1745 → 1727: Cofnięto Edycja 6 i zamiast tego osiągnięto oszczędność poprzez wstawienie najbardziej wewnętrznej podczas pętli do wyrażenia obliczającego cyfrowy kod ASCII, który również kończy się na 1736 bajtach ... ale następnie zapisał instrukcję dekrementacji (9 bajtów ), zmieniając
((++r) - 11) ? r :
na(r - 10) ? ++r :
.Edytuj 8, 1727 → 1626: Przerobiono obliczanie wartości skrótu. Teraz używa o jedną mniej pętli while. Lokalizacje komórek mają teraz swoje rzeczywiste kody ASCII (już nie wyłączone o 1). Przetasowane zmienne w różnych miejscach na taśmie, ponieważ występują one teraz z inną częstotliwością.
Edytuj 9, 1626 → 1606: Bardziej szalone wstawianie. Ciało pierwszej pętli while wygląda teraz mniej więcej tak:
a przypisanie zmiennych zmieniło się prawie całkowicie.
Edycja 10, 1606 → 1577: Zauważyłem, że
a
ia2
są zarówno zmniejszany do 0 w podczas pętli, więc jeśli mogę powiązaćp
z żadnym z nich, ale nie zch
, nie trzeba zainicjowaćp
do0
(która kosztuje 29 bajtów). Okazuje się, że mogę to zrobić, zamieniającp
ir
. Najnowsze przypisania zmiennych (i ich częstotliwość występowania w kodzie) to teraz:źródło
CJam, 23 bajty
Długa impreza!
lub
Uruchom wszystkie przypadki testowe
Wyjaśnienie
Druga wersja zaczyna się od odwrócenia par, co pozwala zaoszczędzić dwa bajty w innym miejscu: a) wybranie pierwszego znaku w każdym ciągu jest tylko
:c
zamiastWf=
wyboru drugiego. b) Nie musimy sortować ponownie przed drugim RLE, ponieważ pary zostały już posortowane głównie według pozostałej postaci.źródło
Q
druga odpowiedź powinna byćq
dla celów bez opakowania testowego.3
listy na listę do porównania jest fajną sztuczką. Rozwiązałem to tylko dla własnej rozrywki i straciłem bajt, ponieważ użyłem0=2>
. W przeciwnym razie skończyłem z prawie tym samym, co twoje pierwsze rozwiązanie, z wyjątkiem użycia::\
zamiastWf%
do ostatniego kroku.Bash,
95948581 bajtówEleganckie, ale długie pierwsze rozwiązanie na początek ...
Dzięki User112638726 do zapisywania bajt z
sed
, DigitalTrauma do zapisywania 9 Wfold
, a Rainer P. za uratowanie 4 więcej zawk
„ssubstr
!Aby zobaczyć, jak to działa, weźmy wkład
abababcbcbcbcbbababa
.Po
fold -2
(zawiń linię do szerokości 2) mamyPo
sort | uniq -c
(-c
jest bardzo fajną flagą,uniq
która wyświetla liczbę, ile razy każda linia pojawia się na wejściu), otrzymujemyTeraz sprawdźmy ostatnie
awk
polecenie:$1>2
: Przesyłaj rzeczy tylko wtedy, gdy rekord 1 (czyli liczba identycznych głosów) jest większy niż 2 (to znaczy ≥ 3). Innymi słowy, zignoruj dowolny wiersz zaczynający się od liczby ≤ 2.{c[substr($2,2)]+=$1}
: Jeśli liczba jest większa niż 2, dodaj tę liczbę doc
tabeli mieszającej, używając drugiego znaku rekordu 2 (aka głosowanie-ee) jako klucza. (Nie musimy inicjować wszystkiego do zera;awk
robi to za nas).END{...}
: Oznacza to po prostu „po przetworzeniu całego pliku, oto co dalej.”for(x in c)printf x c[x]
: Dość oczywiste. Wydrukuj każdy klucz i odpowiadającą mu wartość.źródło
&
jest równoważne z\0
in sedsed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
bacada
na przykład dla danych wejściowych .JavaScript,
114113110Przypadki testowe:
Pokaż fragment kodu
Na wysokim poziomie ten kod zapełnia obiekt parami klucz-wartość, które mapują odbiorców głosów na liczbę głosów, na przykład,
{ b:7, a:3 }
a następnie łączą je w ciąg wfor
pętli. Kod jesteval
wyrażeniem umożliwiającym użyciefor
funkcji strzałki bez konieczności wydawania bajtów na{ }
i;return r
.( Proponuje użytkownikowi 81655 zapisanie trzech bajtów!)
Objaśnienie
eval
kodu:źródło
Haskell, 103 bajty
Przykład użycia:
f "jkkjjkkjjkkjljljljmlmlnmnmnm"
->"k3j6m3"
Jak to działa:
źródło
JavaScript (ES6),
195174169167158 bajtówTest
Pokaż fragment kodu
źródło
var
s. Kogo obchodzi zanieczyszczenie globalnego zasięgu w golfie kodowym? ;)/(\w{2})/g
można po prostu być/../g
- już wiemy, wejście jest tylko litery i powtarzając jeden (lub dwa) znaków jest krótszy niż{2}
. Jeśli jesteś zainteresowany, możesz przejrzeć (i skomentować pytania) moją odpowiedź JavaScript na to wyzwanie. Witamy w PGCC!Mathematica,
11010099 bajtówźródło
Perl,
868483 bajtówTo 82 bajty plus 1 dla
-p
argumentu wiersza poleceń:Nieco golfisty:
${$'}
zamiast$g{$'}
. Niestety$$'
nie działaźródło
Pure Bash, 151
Dłużej niż się spodziewałem, ale oto jest.
Używa asocjacyjnego indeksowania tablic, aby wykonać niezbędne zliczanie. Wymaga wersji bash 4.0 lub nowszej.
źródło
PHP 247 znaków
(ouch)
Wyjaśniono
Zrobił to bez zerkania na inne odpowiedzi. To najtrudniejszy golf golfowy, z jakim się zmierzyłem. Z zadowoleniem przyjmuję wszystkie optymalizacje.
źródło
R, 221 bajtów
kod
bez golfa
Jest tu dużo miejsca na ulepszenia.
źródło