Stack Exchange автоматически обнаруживает последовательное голосование (когда один пользователь повышает или понижает количество постов другого пользователя) и отменяет его. В этом задании вы реализуете очень, очень простой детектор «серийного голосования».
вход
Входные данные представляют собой строку, представляющую список голосов. Каждая группа из двух символов представляет собой голос - первый - это избиратель, а второй - пользователь, за которого проголосовали. Например, следующий вход
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>
nanananananananabatman
теста.Ответы:
Pyth, 22 байта
Попробуйте онлайн: демонстрация или тестовый набор
Объяснение:
Пример:
источник
Не читается ,
18301796179117711762174517361727162616061577 байтВывод в обратном алфавитном порядке (
z
доa
), но в соответствии с вашими правилами, что представляется допустимым.объяснение
Во-первых, чтобы получить представление о том, что может сделать Unreadable, вот его основная операция:
write(x, inc(read(x)))
.Эта программа использует ленту следующим образом. Имена переменных будут использованы в псевдокоде ниже. Кроме того, это документирует первую версию (которая была 1830 байтов); см. правки внизу, чтобы узнать, что изменилось с тех пор.
q
a
,p
,ch
hash
,v
b
,r
aa
,l
a
(96) -z
(121) (код ASCII буквы минус один).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, чтобы перевести число в десятичные цифры.После того, как все прояснилось, программа выглядит как псевдокод:
Изменить 1, 1830 → 1796: понял, что я могу повторно использовать возвращаемое значение цикла while в одном месте.
Edit 2, 1796 → 1791: Оказывается, программа немного меньше, если вместо использования ячеек 6–95 я сохраню десятичные цифры в ячейках с отрицательным номером (–1 и далее). В качестве дополнительного бонуса программа больше не ограничена 10⁹⁰ голосами!
Редактировать 3, 1791 → 1771: вместо присвоения результата
*(ch = l + 95)
дляv
я теперь присваиваю его,q
а затем перемещаю присвоениеv = q
в условие while, переводя код в 1777 байт. Затем поменяйте местами расположениеq
иv
на ленте, потому чтоq
теперь это на 1 чаще, чемv
.Изменить 4, 1771 → 1762: Дух. Инициализация
hash
до 1 вместо 0 на 9 байт короче. Хеш-код теперь на 1 больше, что не имеет значения.Редактировать 5, 1762 → 1745: если я инициализирую
q
и равнымr
1 вместо 0, мне придется посыпать некоторые-1
s местами, чтобы все было правильно, и все это, похоже, отменяется - за исключением того, чтоwhile v { --v; [...] }
цикл теперь должен выполнить на одну меньшую итерацию, что я могу сделать, сказавwhile --v { [...] }
, что на 26 символов короче.Изменить 6, 1745 → 1736: Вместо этого
{ r = 1; ++q }
мы можем написатьq = *((r = 1)+1)+1
. Это зависит от того, чтоq
находится в переменной слот № 2. Если бы это было в слоте № 1, это было бы еще короче, но тогда вся программа была бы длиннее в целом.Правка 7, 1745 → 1727: отменил правку 6 и вместо этого добился сохранения, вставив самый внутренний цикл while в выражение, которое вычисляет цифровой код ASCII, который также заканчивается 1736 байтами ... но затем сохранил инструкцию уменьшения (9 байтов). ), изменив
((++r) - 11) ? r :
на(r - 10) ? ++r :
.Изменить 8, 1727 → 1626: переработан расчет хеша. Теперь он использует один цикл while. Местоположения ячеек теперь имеют свои действительные коды ASCII (больше не на 1). Перестановки переменных в разных местах на ленте, потому что они теперь происходят с различной частотой.
Изменить 9, 1626 → 1606: более сумасшедшее встраивание. Тело первого цикла while теперь выглядит примерно так:
и назначение переменных теперь почти полностью изменилось.
Edit 10, 1606 → 1577: Я заметил , что
a
иa2
оба декрементируется 0 в то время как петли, так что, если я мог бы паруp
ни с одним из тех , кто, но не сch
, я не должен был бы инициализироватьp
до0
(который стоит 29 байт). Оказывается, я могу сделать это путем обменаp
иr
. Новейшие назначения переменных (и их частота появления в коде) теперь:источник
CJam, 23 байта
Вечеринка!
или же
Запустите все тестовые случаи
объяснение
Другая версия начинается с обращения пар, что позволяет сохранить два байта в другом месте: а) выбор первого символа в каждой строке только
:c
вместоWf=
выбора второго. b) Нам не нужно снова сортировать перед вторым RLE, потому что пары уже отсортированы в основном по оставшемуся символу.источник
Q
в вашем втором ответе должен бытьq
для целей не тест-обертка.3
список для сравнения - хороший трюк. Я решил это только для собственного развлечения и потерял там байт, потому что использовал0=2>
. В противном случае я получил почти то же самое, что и ваше первое решение, за исключением использования::\
вместоWf%
последнего шага.Баш,
95948581 байтЭлегантное, но длинное первое решение, чтобы начать ...
Благодаря User112638726 для сохранения байт с
sed
, DigitalTrauma для сохранения 9 сfold
, и Райнер П. для сохранения 4 больше сawk
«сsubstr
!Чтобы увидеть, как это работает, давайте посмотрим
abababcbcbcbcbbababa
.После
fold -2
(обернуть строку на ширину 2), мы имеемПосле того, как
sort | uniq -c
(-c
очень изящный флагuniq
, показывающий, сколько раз каждая строка появляется на входе), мы получаемТеперь давайте рассмотрим последнюю
awk
команду:$1>2
: Выводить данные только в том случае, если запись 1 (то есть число идентичных голосов) больше 2 (то есть ≥ 3). Другими словами, игнорируйте любую строку, которая начинается с числа ≤ 2.{c[substr($2,2)]+=$1}
: Если число больше 2, добавьте это число вc
хеш-таблицу, используя в качестве ключа второй символ записи 2 (он же голос-е). (Нам не нужно инициализировать все до нуля; этоawk
делается для нас.)END{...}
Это означает, что «после обработки всего файла, вот что делать дальше».for(x in c)printf x c[x]
: Довольно понятно Напечатайте каждый ключ и его соответствующее значение.источник
&
равноэквивалентно\0
вsed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
bacada
, например.JavaScript,
114113110Тестовые случаи:
Показать фрагмент кода
На высоком уровне этот код заполняет объект парами ключ-значение, которые сопоставляют получателей голосов с количеством голосов, например,
{ b:7, a:3 }
и затем соединяют их в строку вfor
цикле. Код находится вeval
выражении, позволяющем использоватьfor
функцию внутри стрелки без необходимости тратить байты на{ }
и;return r
.( Попросите пользователя 81655 для сохранения трех байтов!)
Объяснение
eval
кода:источник
Haskell, 103 байта
Пример использования:
f "jkkjjkkjjkkjljljljmlmlnmnmnm"
->"k3j6m3"
Как это устроено:
источник
JavaScript (ES6),
195174169167158 байтКонтрольная работа
Показать фрагмент кода
источник
var
с. Кто заботится о загрязнении глобального масштаба в коде гольф? ;)/(\w{2})/g
может быть просто/../g
- мы уже знаем, что ввод - это только буквы, а повторение одного (или двух) символов короче, чем{2}
. Если вам интересно, вы можете посмотреть (и прокомментировать) мой ответ JavaScript на этот вопрос. Добро пожаловать в PGCC!Mathematica,
11010099 байтисточник
Perl
868483 байтаЭто 82 байта плюс 1 для
-p
аргумента командной строки:Несколько не одураченный
${$'}
вместо$g{$'}
. К сожалению,$$'
не работает.источник
Чистый Баш, 151
Дольше, чем я надеялся, но вот оно.
Использует ассоциативное индексирование массива для необходимого подсчета. Требуется bash версии 4.0 или выше.
источник
247 символов PHP
(Ой)
Разъяснения
Сделал это, не заглядывая в другие ответы. Это самый сложный кодовый гольф, с которым я когда-либо сталкивался. Я приветствую все оптимизации.
источник
R, 221 байт
код
ungolfed
Здесь есть много возможностей для улучшения.
источник