Хеш-зіткнення: "НІ" означає "ТАК"


63

Цей Code Golf був натхненний нещодавньою статтею Daily WTF You Can't Handle True! , який містить порівняння рядків, написане як:

String yes = "YES";
if ((delay.hashCode()) == yes.hashCode())

Уявіть собі проблеми, які могли б заподіяти команді Стіва, якби String.hashCodeметод Java просто був реалізований таким чином "YES".hashCode() == "NO".hashCode(). Отже, завдання, яке я пропоную тут:

Напишіть якомога менше символів хеш-функцію (я її зателефоную h) зі строковим параметром та цілим цільовим значенням повернення, таким, що h("YES")дорівнює h("NO").

Звичайно, це було б тривіально з функцією на зразок def h(s): return 0, яка робить хеш-зіткнення для кожної рядки. Щоб зробити цей виклик цікавішим, ви повинні дотримуватися наступного додаткового правила:

З інших 18 277 можливих рядків , що складаються з трьох або менш великих літер (ASCII ^[A-Z]{0,3}$), не повинна бути ні одного хеша зіткнення.

Уточнення (вказував Хайко Обердіек): рядок введення може містити інші символи, крім того A-Z, і ваш код повинен мати можливість хеш-довільних рядків. (Ви можете, однак, припустити, що вхід є символьним рядком, а не нульовим вказівником або об'єктом якогось іншого типу даних.) Однак, не має значення, яке значення повертається для рядків, які не відповідають ^[A-Z]{0,3}$, до тих пір, це ціле число.

Крім того, для придушення наміру цієї функції:

Ваш код не повинен містити жодної з букв "Y", "E", "S", "N" або "O" (у верхньому або нижньому регістрі) в букве символів або рядків.

Звичайно, це обмеження не поширюється на ключові слова мови, тому else, returnі т.д. все в порядку.


4
Це не допомагає, що ми все ще можемо використовувати числові значення ASCII YESNOдля перевірки цього конкретного винятку.
Джо З.

1
Читаючи статтю, не можна не згадати комікс "з причин": threewordphrase.com/pardonme.gif
Антоніо Рагагнін,

Відповіді:


7

GolfScript: 19 символів (24 символи для названої функції)

26base.2107=59934*+

Це тіло функції. Присвоєння їй іменованої функції hзаймає ще п’ять знаків:

{26base.2107=59934*+}:h;

(Остаточну крапку з комою можна пропустити, якщо ви не заперечуєте, щоб копія коду лежала на стеці.)

Ядро хеш - функції є 26base, яка обчислює суму (26 п - до · до ; до = 1 .. п ), де п є число символів у вхідних даних і до позначає ASCII код K -го вхідний символ. Для входів, що складаються з великих літер ASCII, це хеш-функція без зіткнення. Решта коду порівнює результат з 2107 (хеш-код ) і, якщо вони рівні, додає 59934, щоб отримати 2701 + 59934 = 62041, хеш-код .NOYES

Наприклад, вихід, дивіться цю онлайн-демонстрацію з тестовими кейсами.


Як ви це протестували? Я щойно знайшов купу зіткнень . Приклад: h('DXP') == h('KK') == 65884.
nneonneo

(Python еквівалент того , що ви написали, для моїх цілей тестування: lambda w:sum(ord(c)*26**i for i,c in enumerate(reversed(w*9)))%102983)
nneonneo

@nneonneo: Очевидно, недостатньо добре. Я думав, що генерував повний набір з трьох букв або менше входів, хеширував їх усі і перевіряв, що набір хешів має на один елемент менше, ніж набір входів. Ясно, що в моєму тестовому ремені було десь помилка. :-( Я повернусь до оригінальної 19-чаршової версії до / якщо не зможу виправити більш коротку.
Ільмарі Каронен

54

32-розрядний Python 2.x (19)

hash(w*9)%537105043

RSA використовує модуль напівпринципу, і це робить його безпечним, тому використання одного з моїм алгоритмом хешу, безумовно, повинно зробити його ще кращим! 1

Це чиста математична функція, працює для всіх рядків (пекло, працює для будь-якого хешируемого об'єкта Python), і не містить жодних умовних умов або спеціального кожуха! 32-розрядний Python, як правило, можна викликати як python-32у більшості систем, на яких встановлено 2 .

Я перевірив це, і він повертає 18 278 різних значень для 18 279 рядків з 3 літер або менше. Призначення цієї функції займає ще 11 байт:

h=lambda w:hash(w*9)%537105043

і h('YES') == h('NO') == 188338253.

64-розрядний Python 2.x (19)

hash(w*2)%105706823

Та сама угода, як і вище.


Щоб придумати ці цифри, було використано трохи модульної математики. Я шукав функцію fта модуль, nтакий hash(f('YES')) % n == hash(f('NO')) % n. Це еквівалентно тестуванню, яке nділиться d = hash(f('YES')) - hash(f('NO')), тобто нам потрібно лише перевірити коефіцієнти dвідповідних значень n.

Ідеал n- близько 20000 ** 2, щоб зменшити ймовірність зіткнення парадоксального дня народження. Пошук підходящого nвиявляється трохи спроб і помилок, граючи з усіма чинниками d(зазвичай їх не так багато) та різними варіантами функції f. Зауважте, що проб і помилок потрібні лише тому, що я хотів зробити nякомога менше (для гольфу). Якби це не було вимогою, я міг би просто вибрати dсвій модуль, який, як правило, досить великий.

Зауважте також, що ви не можете відключити цей трюк, використовуючи просто f(s) = s(функцію ідентичності), оскільки найправіший символ рядка має по суті лінійну залежність (фактично XORспіввідношення) з остаточним хешем (інші символи вносять значно більш нелінійний спосіб ). Таким чином, повторення рядка забезпечує посилення відмінностей між рядками для усунення ефекту зміни лише самого правого символу.


1 Це патентна нісенітниця.
2 Хешування рядків Python залежить від основної версії (2 проти 3) та бітової (32-бітної проти 64-бітної). Це не залежить від платформи AFAIK.


Ви отримали мій голос. : D
cjfaure

На жаль, це не працює в останніх версіях Python через нову функцію рандомізації хешу.
dan04,

@ dan04: Як не дивно, я думав, що я вказав, що це тільки для Python 2.x. Я знову її відредагував.
nneonneo

Чи можу я знати, як ви знайшли ці чарівні числа? Я бачу , hash('YES'*9)є 34876679як фактор, в той час як hash('NO'*9)має в 34876679+537105043якості фактора. Але як ти знав, що 537105043це гарний модуль? тобто не вчинило інших зіткнень?
Антоніо Рагагнін

@AntonioRagagnin: додав це до відповіді.
nneonneo

38

Perl, 53 49 40 байт

sub h{hex(unpack H6,pop)-20047||5830404}

Тест:

h('YES') = 5830404
h('NO')  = 5830404
Keys:   18279
Values: 18278

Значення хешу для YESі NOє однаковими, і є 18279 рядків ^[A-Z]{0,3}$, які не мають зіткнення, за винятком єдиного зіткнення для YESта NO.

Безголівки:

sub h {
    hex(unpack("H6", pop())) - 20047 || 5830404;
    # The argument is the first and only element in the argument array @_.
    # "pop" gets the argument from array @_ (from the end).
    # The first three bytes of the argument or less, if the argument
    # is shorter, are converted to a hex string, examples:
    #   "YES" -> "594553"
    #   "NO"  -> "4e4f"
    # Then the hex string is converted to a number by function "hex":
    #   0x594553 = 5850451
    #   0x4e4f   =   20047
    # The value for "NO" is subtracted, examples:
    #   case "YES": 5850451 - 20047 = 5830404
    #   case "NO":    20047 - 20047 =       0
    # If the argument is "NO", the subtraction is zero, therefore
    # 5830404 is returned, the result of "YES".
}

# Test
my %cache;
sub addcache ($) {$cache{$_[0]} = h($_[0])}

# Check entries 'YES' and 'NO'
addcache 'YES';
addcache 'NO';
print "h('YES') = $cache{'YES'}\n";
print "h('NO')  = $cache{'NO'}\n";

# Fill cache with all strings /^[A-Z]{0-3}$/
addcache '';
for my $one (A..Z) {
    addcache $one;
    for (A..Z) {
        my $two = "$one$_";
        addcache $two;
        for (A..Z) {
            my $three = "$two$_";
            addcache $three;
        }
    }
}
# Compare number of keys with number of unique values
my $keys = keys %cache;
my %hash;
@hash{values %cache} = 1 x $keys;
$values = keys %hash;
print "Keys:   $keys\n";
print "Values: $values\n";

Старіша версія, 49 байт

Оскільки новий алгоритм трохи інший, я зберігаю стару версію.

sub h{($_=unpack V,pop."\0"x4)==20302?5457241:$_}

Тест:

h('YES') = 5457241
h('NO')  = 5457241
Keys:   18279
Values: 18278

Безголівки:

sub h {
    $_ = unpack('V', pop() . ($" x 4);
        # pop():  gets the argument (we have only one).
        # $" x 4: generates the string "    " (four spaces);
        #   adding the four spaces ensures that the string is long
        #   enough for unpack's template "V".
        # unpack('V', ...): takes the first four bytes as
        #   unsigned long 32-bit integer in little-endian ("VAX") order.
    $_ == 20302 ? 5457241 : $_;
        # If the hash code would be "NO", return the value for "YES".
}

Зміни:

  • Використання "\0"як байт заповнення економить 4 байти порівняно з $".

Звідки 5457241і 20047звідки беруться? Як ви обчислюєте ці числа? Заздалегідь спасибі.
AL

@ n.1: YESу шістнадцятковій є 594553. 0x594553 = 5850451. NOв шістнадцятковій є 4e4f. 0x4e4f = 20047.
nneonneo

7

Пітон: 63

Неймовірно кульгаве рішення:

def h(s):
 try:r=int(s,36)
 except:r=0
 return(r,44596)[r==852]

Він працює, інтерпретуючи буквено-цифрові рядки як базові числа 36, і повертаючи 0 для всього іншого. Існує явний спеціальний випадок, щоб перевірити значення повернення 852 (НІ), а натомість повернути 44596 (ТАК).


3
Якщо я не розумію неправильно: це код гольфу, ви можете вважати, що введення точно. Можна викопати try:і весь третій рядок. Ви також можете зберегти кілька шматочків, встановивши кожен логічний рядок на одній фактичній лінії, розділеній крапками з комою ( def h(s):r=int(s,36);return(r,44596)[r==852])
підземний

1
@undergroundmonorail: Параметр рядка для хеш-функції не обмежений у питанні. Для певного класу рядків (до трьох великих літер) існує обмеження щодо повернених значень хеш-функції. Однак не має значення, що повертається для інших рядків, якщо значення повернення є цілим числом.
Хайко Обердік

3
Мені подобається булева індексація вашого масиву там
kratenko

6

Pure Bash, 29 байт (функціональне тіло)

h()(echo $[n=36#$1,n-852?n:44596])

Це просто розглядає вхідний рядок як базове число 36 і перетворює в десятковий, а потім займається спеціальним NOвипадком.

Вихід:

$ h A
10
$ ч Б
11
$ h CAT
15941
$ h НІ
44596
$ год ТАК
44596
$ h ZZZ
46655
$

5

Ruby, 51 байт

h=->s{d=s.unpack('C*').join;d=~/896983|^7879$/?0:d}

код тестування:

h=->s{d=s.unpack('C*').join;d=~/896983|^7879$/?0:d}

puts 'YES : '+h.call('YES').to_s # 0
puts 'NO : '+h.call('NO').to_s # 0
puts 'NOX : '+h.call('NOX').to_s # 787988
puts 'FNO : '+h.call('FNO').to_s # 707879
puts ''

values = Hash[]
n = 0
('A'..'Z').each{|c|
    values[c] = h.call(c)
    ('A'..'Z').each{|c2|
        values[c+c2] = h.call(c+c2)
        ('A'..'Z').each{|c3|
            values[c+c2+c3] = h.call(c+c2+c3)
            n += 1
        }
    }
}
puts 'tested '+n.to_s
duplicate = Hash.new()

values.each{|k, e|
    if duplicate.has_key?(e)
        puts 'duplicate : "'+k+'" = "'+duplicate[e].to_s+'" ('+e.to_s+')'
    else
        duplicate[e] = k
    end
}

вихід:

YES : 0
NO : 0
NOX : 787988
FNO : 707879

tested 17576
duplicate : "YES" = "NO" (0)

5

Javascript ( ES6 ) 54 байти

f=s=>[x.charCodeAt()for(x of s)].join('')^7879||897296
f('YES'); // 897296
f('NO'); // 897296
f('MAYBE'); // -824036582

5

Ява - 94 77

int h=new BigInteger(s.getBytes()).intValue();return Math.abs(h-(h^5835548));

Розгорнуто:

int hashCode(String s) {
    int h = new BigInteger(s.getBytes()).intValue();
    return Math.abs(h - (h ^ 5835548));
}

Оповідання - для f(s) = BigInteger(s.getBytes()):

  • f("YES") xor f("NO") = 5835548
  • Тому f("YES") xor 5835548 = f("NO")
  • Так f("YES") - (f("YES") xor 5835548) = f("NO") - (f("NO") xor 5835548)я маю рацію?

Ви не можете вбудувати BigInteger?
mafu

@mafutrct - ТАК !!! Дякую.
OldCurmudgeon

5

CJam, 15 байт

q42b_*81991617%

Працює як рішення GolfScript нижче. Спробуйте в Інтернеті.


GolfScript, 17 байт

42base.*81991617%

Цей підхід ґрунтується на відповідях nneonneo та Ільмарі Каронен .

Як це працює

42base    # Interpret the input string as a base 42 number.
          # "YES" is [ 89 69 83 ] in ASCII, so it becomes 42 * (42 * 89 + 69) + 83 = 159977.
          # "NO" is [ 78 79 ] in ASCII, so it becomes 42 * 78 + 79 = 3355.
          #
.*        # Square. "YES" becomes 25592640529, "NO" becomes 11256025.
          #
81991617% # "YES" becomes 11256025.

Вибір алгоритму

Почнемо з {b base}:h, тобто вхідний рядок вважається числом базової b. Поки b > 25, hце inyective.

Ми отримуємо зіткнення для рядків "ТАК" і "НІ", якщо ми модифікуємо hнаступним чином:, {x base n}:hде nдільник "YES" h "NO" h -.

На жаль, це означає, що ми також отримаємо зіткнення, наприклад, YETі NP. Щоб цього не допустити, ми маємо модифікувати число base-b нелінійним способом перед тим, як прийняти модуль.

Найкоротший спосіб досягти цього в GolfScript - це множення базового числа на себе (тобто, складання його на квадрат). hє зараз {base b .* n %}:h.

Залишиться лише знайти відповідні значення для bта n. Ми можемо досягти цього грубою силою:

for((b=26;b<100;b++)){
    P=($(golfscript <<< "['YES' 'NO']{$b base.*}/-" | factor | cut -d\  -f 2-))

    for n in $(for((i=0;i<2**${#P[@]};i++)){
        for((n=1,j=0;j<${#P[@]};n*=${P[j]}**((i>>j)&1),j++)){ :;};echo $n;} | sort -nu);{
            [[ $n -ge 18277 && $(echo -n '' {A..Z}{,{A..Z}{,{A..Z}}} |
                golfscript <(echo "' '/[{$b base.*$n%}/].&,")) = 18278 ]] &&
            echo $b $n && break
    }
}

Найкоротші можливі значення для b n:

37 92176978
42 81991617

Тестування

$ echo -n '' {A..Z}{,{A..Z}{,{A..Z}}} |
     golfscript <(echo '{42base.*81991617%}:h;" "/{.`"\t"+\h+puts}/') |
     sort -k 2n |
     uniq -Df 1
"NO"    11256025
"YES"   11256025

3

JavaScript (ES6) - 38 символів (33 функції функції char)

h=s=>(a=btoa(s))=="WUVT"|a=="Tk8="||+s

Випробування:

var l = console.log;
l(  h("YES")  );                // 1
l(  h("NO")  );                 // 1
l(  h("ABC")  );                // NaN     
l(  h("WIN")  );                // NaN
l(  h("YES") === h("NO")  );    // true
l(  h("ABC") === h("WIN")  );   // false
l(  h("WIN") === h("YES")  );   // false

l(  NaN === NaN  );             // false

Пояснення:

Перш за все, дозвольте познайомити вас із NaN"Не числом" - у JavaScript. Це число:

typeof NaN  // number

Так як:

typeof 42   // number

Її особливою властивістю є те, що він ніколи не дорівнює собі . Моя функція повертає , 1якщо рядок YESабо NO, і NaNдля будь-якої іншої рядка.

Таким чином, це не порушує правила, оскільки не було б зіткнення хешу для жодної іншої рядки;) ( NaN !== NaNпоказано вище у тестових випадках).

І моя мрія здійснилася: побивши Баша, Перла та Рубі в довжині коду!

Код без вогню:

h =  // h is a function 
s => // s = string argument

( ( a = btoa(s) )  ==  "WUVT" | a == "Tk8=" )
        ^-- returns some value stored in `a`

Якщо це значення "WUVT"або "Tk8=", повернення 1. Ще, повернись

+s // parseInt(s, 10)

що було б NaN.


2
NaN може бути числом, але це не "ціле число" в жодному сенсі цього слова.
Paŭlo Ebermann

2
@ PaŭloEbermann З вікі "Ціле число - це число, яке пишеться без дробової складової". Питання прямо не говорить про те, що ціле число повинно бути ^\d+$. І JS трактує NaNяк число. Ви можете помножити його на число, додати, ділити, відняти так само, як і числа. Це особлива властивість JavaScript. В його використанні немає ніякої шкоди. Ось що ми називаємо згинанням правил ;)
Gaurang Tandon

1
Я міг би використати Object.is()і стверджувати, що це все ще зіткнення…
user2428118

1
@ user2428118 Дякую за те, що ви довели до Object.is мої знання. Я ніколи цього не знав. Але я хотів би зазначити, що ОП використовує ==для порівняння оператор рівності ( ), який гарантує, що жодного рядка, крім "ТАК" або "НІ", не буде зіткнення хешу.
Gaurang Tandon

2
Чи не звертаючи уваги на той факт , що , стверджуючи , NaNне рахується , як зіткнення здається дешевим, це рішення має зіткнення з рядками NAчерез NPта YEQчерезYET
nderscore

2

Пітон 92

n=int("".join(map(str,map(ord,raw_input()))))    # hashing function
print n if 1+(n**2-904862*n)/7067329057 else-1   # input validation

Функція хешування об'єднує порядкові значення символів ASCII, оператор друку гарантує, що два бажані входи стикаються.


2

ECMAScript 6 (30 байт)

Я намагався уникати ключового слова змінної присвоєння, повернення та функціонування, і це виглядає як чудовий спосіб уникнути всієї дурниці (певним чином це також виглядає як функціональне програмування). На відміну від інших рішень, це не залежить від btoaабо atob, що не ECMAScript 6, а HTML5. 0+потрібен, щоб він міг проаналізувати довільні рядки.

a=>parseInt(0+a,36)-852||43744

1
Приємно! Я не знав, що вони додали інші бази для аналізу. Ви можете вирізати багато байт. :)a=>parseInt(0+a,36)-852||43744
nderscore

@nderscore: Дякую за пропозицію. Це дійсно значно покращило мій сценарій.
Конрад Боровський

2

Java - 45 (або 62?)

Я не маю уявлення, як справедливо оцінити, враховуючи, що потрібно для запуску програми на Java, чи потрібно включати визначення функції? Не соромтесь редагувати та коректувати міркування належним чином. Наразі я забиваю так само, як відповідь @OldCurmudgeon. Додайте 17, int h(String t){}якщо потрібно:

int h=t.hashCode();return h*h*3%1607172496;

Невикольований з тестовим джгутом:

import static org.junit.Assert.*;

import java.util.*;

import org.junit.Test;

public class YesNo {
  @Test
  public void testHashValue() {
    YesNo yesNo = new YesNo();
    Set<Integer> set = new HashSet<>();

    assertEquals(yesNo.hash("YES"), yesNo.hash("NO"));

    set.add(yesNo.hash(""));
    for(char i = 'A'; i <= 'Z'; i++) {
      set.add(yesNo.hash("" + i));
      for(char j = 'A'; j <= 'Z'; j++) {
        set.add(yesNo.hash("" + i + j));
        for(char k = 'A'; k <= 'Z'; k++) {
          set.add(yesNo.hash("" + i + j + k));
        }
      }
    }
    assertEquals(18278, set.size());
  }

  int hash(String toHash) {
    int hashValue=toHash.hashCode();
    return hashValue*hashValue*3%1607172496;
  }
}

1

І невдаха ...

Конвеєр, 145 символів

 I
>#<
 26*)2**\88
 >========*
 ^    \ \+-
 ^=====#==<
5**222P:
5======<
5***26*)*(\P\:@e25*:*)4*,F
>==============#=========
             P,F

В основному ця програма робить якусь базу на символах. Після цього він перевіряє, чи хеш дорівнює 12999 (хеш-код ТАК), і якщо так, надрукуйте 404 (хеш-код НІ), інакше він просто надрукує хеш-код.

Конвеєр - це створена мною мова, яка наразі перебуває на бета-стадіях, але перекладача разом із деякими прикладами та вихідним кодом можна знайти тут: https://github.com/loovjo/Conveyor


0

C # 4,5 (112 байт)

int h(string s){int code=s.Select((v,i)=>((int)v)<<(2*(i-1))).Sum();return(code|1073742225)|(code|-2147483569);}

Робоча (?) Версія спроби підземногомонорельса в C #. Складає байти в рядку в 32-бітове ціле число (працює лише до 4 символів), потім АБО результат проти результату для "ТАК" та "НІ" відповідно, а потім АБО разом.

Хоча в якийсь момент він може зіткнутися, це не повинно статися для жодного ^ [AZ] {2,3} $, окрім "ТАК" та "НІ".


У вас хеш-функція матиме набагато більше зіткнень. Ваша "хеш-функція" - це по суті ігнорування багатьох бітів у конкатенації. Усі пари рядків, які відрізняються лише цими бітами, матимуть однаковий хеш-код.
Paŭlo Ebermann

0

Без коментарів - 31 (зміст функції: 26)

'=|*==|,,|+|"#|[|,  |+|-%3|]*|:

Досить просте рішення. ;) Працює для будь-яких рядків UTF-8.

ПОЯСНЕННЯ: ' очевидно, це функція. По-перше, він перевіряє, чи *(його вхід) дорівнює |,,|+|"#|( |NO|). Якщо він є, він повертає |, |+|-%3|( |YES|) - інакше він просто повертається *.


2
Я ніколи не працював з No Comment, чи можна було б пояснити ваше рішення, як це часто робиться з непрозорими відповідями Golfscript, J або APL?
Kaya

@Kaya О, так, вибачте, я відредагую публікацію.
cjfaure

1
Ніяких вибачень не потрібно, мені було просто цікаво, як це працює.
Kaya

0

C 54

h(char *c){int d=*(int*)c-20302;return d*(d-5436939);}

Перетворіть рядок у ціле число - "НІ" та помножте на те саме значення + "НІ" - "ТАК", щоб отримати 0 для "НІ" та "ТАК" і ненульових для будь-якого іншого рядка у вказаному діапазоні.

Усі значення на машині Windows 7, якщо є які-небудь проблеми.



-1

CoffeeScript - 36

Потрібно повернутись 1до YESта NO, і все, що бідка дурниця, atobстворює все інше, що не є рядом base64.

h=(s)->_=atob s;_ in["`D","4"]&&1||_

Еквівалент JavaScript ( не код JS від компілятора CS):

function h( s ) {
    var _ = atob( s );

    if( _ === "`D" || _ === "4" )
        return 1;
    else
        return _;
}

3
"Функція повинна мати ціле повернене значення" - я вважаю, що ваше повертає значення, _коли вхід не "ТАК" або "НІ".
Gaurang Tandon

-1

Ось супер кульгавий. ТАК ХИМА НЕ РОБОТАЄ

Python 2.7 - 79 байт

def h(s):n=sum(100**i*ord(c)for i,c in enumerate(s));return (n-7978)*(n-836989)

Спочатку ми отримуємо суму (значення ascii кожного символу) * 100 ^ (положення цього символу в рядку). Потім ми множимо (цей результат - 7978) і (той результат - 836989), щоб отримати остаточну відповідь. 7978 і 836989 - це результати для "ТАК" і "НІ" першого біта, тому для ТА і НІ ми множимо на 0.

У цьому не повинно бути зіткнень? Я не відчуваю тестування на 18000 можливих контрприкладів, але якщо сталося ненавмисне зіткнення, я можу кинути ще на 0 100і тоді справді не повинно бути зіткнень.

Розчарований, що я не міг використовувати lambdaдля цього, але я не хотів робити два обчислення двічі, тому мені довелося зберегти його до змінної.

Будь ласка, не дозволяйте цьому виграти. Це супер кульга, і я цього не заслуговую.


Не відповідає вимозі "ніяких інших зіткнень": з 18277-рядкового набору 18277 унікальних хешів не повинно бути зіткнень.
dan04

@dan Damn, дай мені другий
undergroundmonorail

1
@dan Я не можу змусити його працювати. Можливо, в алгоритмі щось невідповідне. Я не хочу видаляти його, тому що хтось інший може знати, що не так, але я поставлю на замітку
undergroundmonorail

Це працює для мене, h = лямбда s: (хеш (и) +997192582) * (хеш (и) -480644903)
Лукас,

як визначив хеш-функцію, подібну до вашої, але з 99 ** i * int (c, 36)
Лукас,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.