В этом вызове кода вы напишите хеш-функцию в 140 байтах 1 или менее исходного кода. Хеш-функция должна принимать строку ASCII в качестве входных данных и возвращать 24-разрядное целое число без знака ([0, 2 24 -1]) в качестве выходных данных.
Ваша хеш-функция будет оцениваться для каждого слова в этом большом британско-английском словаре 2 . Ваша оценка - это количество слов, которые разделяют значение хэша с другим словом (столкновение).
Побеждает наименьшая оценка, разрывается связь с первым постером.
Прецедент
Перед отправкой, пожалуйста, проверьте ваш сценарий оценки на следующем входе:
duplicate
duplicate
duplicate
duplicate
Если он дает любой результат, кроме 4, он глючит.
Уточняющие правила:
- Ваша хеш-функция должна выполняться в одной строке, а не во всем массиве. Кроме того, ваша хеш-функция может не выполнять какой-либо другой ввод-вывод, кроме входной строки и выходного целого числа.
- Встроенные хеш-функции или аналогичные функции (например, шифрование в байты шифрования) запрещены.
- Ваша хеш-функция должна быть детерминированной.
- В отличие от большинства других конкурсов, оптимизация специально для подсчета очков разрешена.
1 Я знаю, что Twitter ограничивает символы вместо байтов, но для простоты мы будем использовать байты в качестве ограничения для этой задачи.
2 Изменено из wbritish-огромного Debian , удаляя любые слова, не входящие в ASCII.
Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch's
? Что за...?D=340275
словами иR=2^24
выходами хэша случайный хеш имеет ожидаемыеD^2/(2*R) = 3450
сталкивающиеся пары, некоторые из которых перекрываются. Есть ожидаемыеD^3/(6*R^2) = 23
сталкивающиеся тройки и незначительное число более крупных столкновений, что означает, что эти тройки, вероятно, не пересекаются. Это дает ожидаемые6829
слова, которые имеют общее значение хеша, ~70
в тройках, а остальные в парах. Стандартное отклонение оценивается в118
, так что получение<6200
со случайным хешем - это примерно 5 сигма событий.Ответы:
Хорошо, я пойду изучать язык игры в гольф.
CJam, 140 байтов, 3314 встречных слов
Определяет блок (анонимная функция). Для теста, можно добавить ,
qN%%N*N
чтобы взять новую строку списка разделенных слов на стандартном ввод и запись новой строки списка разделенных хэш на стандартном выводе. Эквивалентный код Python:Pyth, 140 байтов,
35353396 встречных словОпределяет функцию с именем
y
. Чтобы проверить, вы можете добавить,jmyd.z
чтобы взять список слов, разделенных символом новой строки, в stdin и написать список хэшей, разделенных символом новой строки, в stdout. Эквивалентный код Python:Теоретические пределы
Насколько хорошо мы можем ожидать сделать? Здесь представлен график зависимости x от числа сталкивающихся слов и y от энтропии в байтах, необходимой для получения не более x встречных слов. Например, точка (2835, 140) говорит нам, что случайная функция получает не более 2835 сталкивающихся слов с вероятностью 1/256 ** 140, поэтому крайне маловероятно, что мы когда-либо сможем добиться гораздо большего успеха, чем при 140 байты кода.
источник
Python,
53334991Я считаю, что это первый претендент, который выиграл значительно лучше, чем случайный оракул.
источник
def H(s):n=int(s.encode('hex'),16);return n%...
сохраняет 5 байтов, в случае, если вы можете использовать их как-то ...2**24 == 8**8
.Python 2, 140 байт, 4266 встречных слов
Я действительно не хотел начинать с непечатных байтов, учитывая их непонятную гибкость, но я не начал. :-П
Python 2, 140 байт для печати,
466244714362 встречных словаВдохновленный формой решения Касперда, очевидно, но с важным добавлением аффинного преобразования в пространстве модулей и совершенно других параметров.
источник
n%(8**8-ord('…'[n%70]))
без других изменений параметров мне удалось добраться только до 4995, так что, похоже, ваш новый оптимизатор догнал мой. Теперь это становится интереснее!CJam,
4125393737913677Этот подход делит домен и кодомен на 110 непересекающихся множеств и определяет несколько отличную хеш-функцию для каждой пары.
Оценка / Проверка
Следующий порт для Python можно использовать с официальным фрагментом скоринга:
источник
h
этот порт Python встроенному CJam?b
(базовая конверсия).Python,
64466372Это решение достигает меньшего количества коллизий, чем все предыдущие записи, и ему требуется только 44 из 140 байтов, разрешенных для кода:
источник
%(2**24-1)
, так что я думаю, что было бы хорошо попросить разъяснений[0, 2**24-1]
чем слов в английском языке, было бы математически невозможно создать хеш, в котором было бы возможно каждое отдельное значение в этом диапазоне.CJam, 6273
XOR каждого символа с 49 , уменьшить полученную строку с помощью x, y 5 245x + y и взять остаток по модулю 16 777 213 (наибольшее 24-битное простое число).
счет
источник
JavaScript (ES6), 6389
Хеш-функция (105 байт):
Функция оценки (NodeJS) (170 байт):
Вызовите как
node hash.js dictionary.txt
, гдеhash.js
находится скрипт,dictionary.txt
это текстовый файл словаря (без последней новой строки), иF
он определен как функция хеширования.Спасибо Нейлу за то, что он убрал 9 байтов из функции хеширования!
источник
((...)>>>0)%(1<<24)
вас, вероятно, можно использовать(...)<<8>>>8
.i
.Mathematica, 6473
Следующий шаг вверх ... вместо суммирования кодов символов мы рассматриваем их как цифры числа base-151, а затем принимаем их по модулю 2 24 .
Вот короткий скрипт для определения количества столкновений:
Я только что систематически пробовал все базы
1
, и до сих пор база 151 дала наименьшее количество столкновений. Я постараюсь еще немного понизить счет, но тестирование немного медленное.источник
Javascript (ES5), 6765
Это CRC24, уменьшенный до 140 байт. Мог бы играть в гольф больше, но хотел получить мой ответ :)
Валидатор в node.js:
источник
Python, 340053
Ужасная оценка от ужасного алгоритма, этот ответ существует больше, чтобы дать небольшой скрипт на Python, который отображает выигрыш.
Набрать:
источник
Python,
639063766359Можно считать тривиальной модификацией ответа Мартина Бюттнера .
источник
[0, 2**24-1]
. Единственное, что не разрешено, это вывод любого числа, не входящего в этот диапазон, например,-1
или2**24
.Питон, 9310
Да, не самый лучший, но, по крайней мере, это что-то. Как мы говорим в крипто, никогда не пишите свою собственную хеш-функцию .
Это также ровно 140 байтов.
источник
Matlab,
3082886206848Он создает хэш, присваивая простое число каждому комбинированному символу / позиции ascii и вычисляя их произведение для каждого слова по модулю наибольшего простого числа, меньшего, чем 2 ^ 24. Обратите внимание, что для тестирования я переместил вызов простых чисел в тестер непосредственно перед циклом while и передал его в хэш-функцию, поскольку он ускорился примерно в 1000 раз, но эта версия работает и является автономной. Может произойти сбой со словами длиной более 40 символов.
Tester:
источник
double
явно преобразовывать свой символ . Также вы можете использовать,numel
а неlength
. Не уверен, что вы будете делать со всеми этими дополнительными байтами!Рубин, 9309 столкновений, 107 байт
Не очень хороший соперник, но я хотел изучить идею, отличную от других.
Присвойте первые n простых чисел первым n позициям строки, затем сложите все простые числа [i] ** (ascii-код строки [i]), затем mod 2 ** 24-1.
источник
Java 8,
7054,6467Это вдохновлено (но не скопировано) встроенной функцией java.lang.String.hashCode, поэтому не стесняйтесь запрещать в соответствии с правилом № 2.
Набрать:
источник
hashes
с ,Map<Integer, Integer> hashes = new HashMap<>()
а затем подсчитать количество слов для каждого хэша, вы можете объяснить их правильно.Python,
699568626732Просто простая функция RSA. Довольно хромает, но бьет некоторые ответы.
источник
C ++:
711266946483647964126339 коллизий, 90 байтЯ реализовал наивный генетический алгоритм для моего массива коэффициентов. Я обновлю этот код, так как он находит лучшие. :)
Тестовая функция:
источник
C #, 6251
6335Константы 533 и 733,
889 и 155дают лучший результат из всех, которые я искал до сих пор.источник
TCL
88 байтов, 6448/3233 столкновений
Я вижу, что люди подсчитывают либо количество сталкивающихся слов, либо количество слов, помещенных в непустые ведра. Я даю оба счета - первый соответствует спецификации проблемы, а второй - о чем сообщают другие авторы.
источник
proc H w {incr h;lmap c [split $w {}] {set h [expr (2551*$h+[scan $c %c])%2**24]};set h}
... верно?Python 3, 89 байтов, 6534 коллизий хешей
Все большие магические числа, которые вы видите здесь, являются константами выдумки.
источник
JavaScript, 121 байт,
3268325032446354 (3185) коллизийПараметры (13, 7809064, 380886, 2, 266324) являются методом проб и ошибок.
Я думаю, что все еще можно оптимизировать, и есть место для добавления дополнительных параметров, работающих для дальнейшей оптимизации ...
верификация
3268> 3250 - изменен третий параметр с 380713 на 380560.
3250> 3244 - изменен 3-й параметр с 380560 на 380886.
3244> 6354 - изменил 2-й параметр с 7809143 на 7809064 и обнаружил, что я использовал неправильный метод расчета; P
источник
Вот несколько аналогичных конструкций, которые являются вполне «начальными» и делают возможной оптимизацию дополнительных параметров. Чёрт, сложно получить ниже 6к! Предполагая, что средний балл равен 6829, а средний - 118, я также рассчитал вероятность случайного получения таких низких баллов.
Clojure A, 6019, Pr = 1: 299,5e9
Clojure B, 6021, Pr = 1: 266.0e9
Clojure C, 6148, Pr = 1: 254.0e6
Clojure, 6431, Pr = 1: 2.69e3 (что-то другое)
Это была моя оригинальная специальная хеш-функция, она имеет четыре настраиваемых параметра.
источник
r
фиксированного множителя ). Но все же мой алгоритм поиска по сути является грубой силой, и я не уверен,r
важен ли первоначальный выбор множителя или нет.f(n) % (8^8 - g(n))
.Ruby, 6473 столкновения, 129 байтов
Переменная @p заполнена всеми простыми числами ниже 999.
Это преобразует значения ascii в простые числа и принимает их произведение по модулю большого простого числа. Коэффициент выдумки 179 связан с тем фактом, что оригинальный алгоритм использовался для поиска анаграмм, где все слова, которые являются перестановками одних и тех же букв, получают одинаковый хэш. Добавляя фактор в цикл, он дает анаграммам разные коды.
Я мог бы удалить ** 0,5 (тест sqrt для простого) за счет более низкой производительности, чтобы сократить код. Я мог бы даже выполнить поиск простых чисел в цикле, чтобы удалить еще девять символов, оставив 115 байтов.
Чтобы проверить, следующее пытается найти лучшее значение для коэффициента выдумки в диапазоне от 1 до 300. Предполагается, что файл слова находится в каталоге / tmp:
источник
TCL
# 91 байт, 6508 столкновений91 байт, 6502 столкновения
Компьютер все еще выполняет поиск, чтобы оценить, есть ли значение, которое вызывает меньше коллизий, чем база
147875, которая по-прежнему является рекордсменом.источник