해시 충돌 : "아니오"는 "예"를 의미합니다.


63

이 코드 골프는 최근 일일 WTF 기사 인 You ca n't handle the true! 에서 영감을 얻었습니다 . 다음과 같이 작성된 문자열 비교 기능이 있습니다.

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

Java의 String.hashCode메소드가 방금 구현 된 방식으로 스티브의 팀에게 야기 된 문제를 상상해보십시오 "YES".hashCode() == "NO".hashCode(). 그래서 여기서 제안하는 과제는 다음과 같습니다.

h문자열 매개 변수와 정수 반환 값을 사용하여 가능한 한 적은 수의 문자로 해시 함수 h("YES")를 작성 h("NO")합니다.

물론 이것은 모든 문자열에 def h(s): return 0해시 충돌을 일으키는 같은 함수와 관련이 있습니다. 이 도전을 더 재미있게하려면 다음 추가 규칙을 따라야합니다.

다른 세 이하의 대문자 ASCII 문자 (구성된 18 277 가능한 문자열 ^[A-Z]{0,3}$)이 없어야합니다 해시 충돌.

설명 (Heiko Oberdiek에서 지적) : 입력 문자열에 이외의 문자가 포함될 수 있으며 A-Z코드에서 임의의 문자열을 해시 할 수 있어야합니다 . (당신은, 그러나, 입력이 있다고 가정 할 수 있습니다 문자열이 아닌 널 포인터 또는 다른 데이터 형식의 목적은.) 그러나,이 반환 값이 일치하지 않는 문자열이 무엇인지는 중요하지 않습니다 ^[A-Z]{0,3}$만큼, 정수입니다.

또한이 기능의 의도를 혼란스럽게하려면 :

코드는 문자 또는 문자열 리터럴 내에 'Y', 'E', 'S', 'N'또는 'O'(대문자 또는 소문자)를 포함해서는 안됩니다.

물론,이 제한은 언어 키워드에 적용되지 않으므로 else, return등 정상입니다.


4
YESNO이 특정 예외를 확인하기 위해 숫자 ASCII 값을 계속 사용할 수는 없습니다 .
Joe Z.

1
기사를 읽는 사람은 "이유"만화를 기억할 수 없습니다 : threewordphrase.com/pardonme.gif
Antonio Ragagnin

답변:


7

GolfScript : 19 자 (명명 된 기능의 경우 24 자)

26base.2107=59934*+

이것이 함수의 본문입니다. 이름이 지정된 함수에 지정하면 h5 개의 문자가 더 필요합니다.

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

스택에 코드 사본을 남겨 두지 않아도되는 경우 마지막 세미콜론을 생략 할 수 있습니다.

해시 함수의 핵심은 26base, sum (26 n - k · a k ; k = 1 .. n )을 계산합니다. 여기서 n 은 입력의 문자 수이고 , kk 번째 ASCII 코드입니다. 입력 문자. 대문자 ASCII 문자로 구성된 입력의 경우 충돌이없는 해시 함수입니다. 나머지 코드는 결과를 2107 (의 해시 코드 NO)과 비교 하고 같으면 59934를 추가하여의 해시 코드 인 2701 + 59934 = 62041을 생성합니다 YES.

출력 예 는 테스트 사례가있는온라인 데모를 참조하십시오 .


이것을 어떻게 테스트 했습니까? 방금 충돌을 발견했습니다 . 예 : h('DXP') == h('KK') == 65884.
nneonneo

(당신이 내 테스트 목적으로, 쓴 파이썬에 해당 : lambda w:sum(ord(c)*26**i for i,c in enumerate(reversed(w*9)))%102983)
nneonneo

@nneonneo : 분명히 충분하지 않습니다. 나는 생각 나는 세 글자 또는없는 입력의 전체 세트를 생성 그들 모두를 해시 및 해시 세트는 입력의 설정보다 하나 개의 요소를 가지고 있음을 확인. 분명히, 내 테스트 장치에는 어딘가에 버그가있었습니다. :-( 때까지이 짧은 하나를 해결할 수 없다면 나는 / 원래 19 문자의 버전으로 되돌릴 수 있습니다.
Ilmari 카로 넨

54

32 비트 Python 2.x (19)

hash(w*9)%537105043

RSA는 semiprime modulus를 사용하므로 보안이 강화되므로 해시 알고리즘과 함께 사용하면 확실히 향상됩니다! 1

이것은 순수한 수학 함수이며 모든 문자열 (지옥, 해시 가능한 Python 객체에서 작동)에 적용되며 조건부 또는 특수 대소 문자를 포함하지 않습니다! 32 비트 Python은 일반적으로 2python-32 가 모두 설치된 대부분의 시스템에서 와 같이 호출 될 수 있습니다 .

나는 이것을 테스트했으며 18,279 개의 3 자 대문자 문자열에 대해 18,278 개의 다른 값을 반환합니다. 이것을 함수에 할당하면 11 바이트가 더 필요합니다.

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

그리고 h('YES') == h('NO') == 188338253.

64 비트 Python 2.x (19)

hash(w*2)%105706823

위와 같은 거래.


이 숫자를 생각해 내기 위해 약간의 모듈 식 수학이 사용되었습니다. 나는 그런 함수 f와 모듈러스를 찾고 있었다 . 이는 나누는 테스트와 동일합니다 . 즉, 적합한 값에 대한 요인 만 확인하면됩니다 .nhash(f('YES')) % n == hash(f('NO')) % nnd = hash(f('YES')) - hash(f('NO'))dn

n생일 역설 충돌의 가능성을 줄이기 위해 20000 ** 2 부근에 이상적 입니다. 적합한 n것을 찾는 것은 약간의 시행 착오로 판명되며 d(보통 많지는 않지만) 모든 요소 와 기능에 대한 다른 선택을 가지고 노는 것입니다 f. 시행 착오는 n골프를 위해 가능한 한 작게 만들고 싶기 때문에 필요합니다 . 그것이 요구 사항이 아닌 경우, 나는 d보통 충분히 큰 내 계수로 선택할 수 있습니다 .

f(s) = s문자열의 가장 오른쪽 문자가 본질적으로 XOR최종 해시와 선형 관계 (실제 관계)를 갖기 때문에 (다른 문자는 훨씬 비선형 방식으로 기여 하기 때문에) 단지 (ID 함수)를 사용 하여이 트릭을 풀 수 없다는 점에 유의하십시오 ). 따라서 문자열을 반복하면 문자열 간의 차이가 증폭되어 가장 오른쪽 문자 만 변경하는 효과가 제거됩니다.


1 이것은 말도 안되는 특허입니다.
2 파이썬 문자열 해싱은 메이저 버전 (2 대 3)과 비트 (32 비트 대 64 비트)에 따라 다릅니다. 플랫폼 AFAIK에 의존하지 않습니다.


당신은 내 투표를했습니다. : D
cjfaure

불행히도 새로운 해시 무작위 화 기능으로 인해 최신 버전의 Python에서는 작동하지 않습니다.
dan04

@ dan04 : 홀수, 이것이 Python 2.x 전용이라고 지정했다고 생각했습니다. 다시 편집했습니다.
nneonneo

이 마법의 숫자를 어떻게 찾았는지 알 수 있을까요? 나는 참조 hash('YES'*9)34876679있는 동안, 요인으로 hash('NO'*9)34876679+537105043요인으로. 그러나 이것이 537105043좋은 계수 임을 어떻게 알 수 있습니까? 즉, 다른 충돌을 일으키지 않았습니까?
Antonio Ragagnin

@AntonioRagagnin : 답변에 추가했습니다.
nneonneo

38

펄, 53 49 40 바이트

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

테스트:

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

해시 값 YESNO동일하고 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 바이트가 절약됩니다 $".

어디 않습니다 545724120047에서 온? 이 숫자를 어떻게 계산합니까? 미리 감사드립니다.
AL

@ n.1 : YES16 진수입니다 594553. 0x594553 = 5850451 NO은 16 진수입니다 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 (NO)의 반환 값을 확인하고 44596 (YES)을 반환하는 명시적인 특수한 경우가 있습니다.


3
내가 오해하지 않는 한 : 그것은 코드 골프이며, 입력이 정확하다고 가정 할 수 있습니다. 당신은 도랑 try:과 전체 세 번째 라인을 할 수 있습니다 . 세미콜론 ( def h(s):r=int(s,36);return(r,44596)[r==852]) 으로 구분 된 동일한 실제 줄에 모든 논리 줄을 가짐으로써 약간의 물기를 절약 할 수도 있습니다
지하

1
@undergroundmonorail : 해시 함수의 문자열 매개 변수 는 질문에 제한 되지 않습니다 . 특정 클래스의 문자열 (최대 3 개의 대문자)의 경우 해시 함수의 반환 값과 관련하여 제한이 있습니다. 그러나 반환 값이 정수이면 다른 문자열에 대해 반환되는 것은 중요하지 않습니다.
Heiko Oberdiek

3
나는 배열의 부울 인덱스를 좋아한다
kratenko

6

순수 배시, 29 바이트 (기능 본문)

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

이것은 단순히 입력 문자열을 기본 36 숫자로 취급하고 십진수로 변환 한 다음 특별한 NO경우를 처리합니다.

산출:

$ 시간 A
10
B 시간
11
$ h 고양이
15941
$ 시간 NO
44596
$ h 예
44596
$ h ZZZ
46655
$

5

루비, 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

자바 스크립트 ( 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%

이 접근법은 nneonneoIlmari Karonen 의 답변을 기반으로합니다 .

작동 원리

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, hinyective입니다.

우리가 수정할 경우 우리는 문자열에 대한 충돌을 얻을 "YES"와 "NO" h다음과 같은 방법으로 : {x base n}:h여기서 n의 제수입니다 "YES" h "NO" h -.

불행히도 이것은 예를 들어 YET및에 충돌을 일으킨다는 것을 의미 NP합니다. 이를 방지하기 위해 모듈러스를 취하기 전에 비선형 방식으로 base-b 숫자를 수정해야합니다.

GolfScript에서이 작업을 수행하는 가장 짧은 방법은 base-b 숫자에 자체를 곱하는 것입니다 (즉, 제곱). h지금 {base b .* n %}:h입니다.

해야 할 일은 band에 적합한 값을 찾는 것입니다 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 자 함수 본문)

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

설명:

우선, NaNJavaScript에서 "Not A Number" 를 소개하겠습니다 . 숫자입니다 :

typeof NaN  // number

처럼:

typeof 42   // number

그것의 특별한 속성은 결코 자신과 같지 않다는 것 입니다. 내 함수는 1문자열이 YES또는 NONaN경우 다른 문자열에 대해 반환 합니다.

따라서 다른 문자열에 해시 충돌이 없기 때문에 규칙을 위반하지 않습니다 NaN !== NaN.

그리고 내 꿈은 실현됩니다 : 코드 길이에서 Bash, Perl 및 Ruby를 때리는 것!

Ungolfed Code :

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를 제 지식으로 가져 주셔서 감사합니다. 나는 그것을 몰랐다. 그러나 OP는 ==비교에 등호 연산자 ( )를 사용하여 "YES"또는 "NO"이외의 문자열에 대해 해시 충돌이 발생하지 않도록합니다.
Gaurang Tandon

2
주장 NaN이 비용이 NANPYEQYET
적게 든다고

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 문자의 서수 값을 연결하고 print 문은 두 개의 원하는 입력이 충돌하는지 확인합니다.


2

ECMAScript 6 (30 바이트)

변수 할당, 반환 및 함수 키워드를 피하려고 시도했지만 이것은 말도 안되는 모든 것을 피할 수있는 좋은 방법으로 보입니다 (기능 프로그래밍처럼 보입니다). 다른 솔루션과 달리, 그것은에 의존하지 않는다 btoa또는 atobECMAScript를 6 만 HTML5하지 않은. 0+필요하므로 임의의 문자열을 구문 분석 할 수 있습니다.

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

1
좋은! 나는 그들이 parseInt에 대한 다른 기초를 추가했는지 몰랐다. 그래도 많은 바이트를 줄일 수 있습니다. :)a=>parseInt(0+a,36)-852||43744
nderscore

@nderscore : 제안 해 주셔서 감사합니다. 스크립트가 많이 향상되었습니다.
Konrad Borowski

2

자바-45 (또는 62?)

Java로 프로그램을 실행하는 데 필요한 점수를 어떻게 얻습니까? 함수 정의를 포함시켜야합니까? 점수를 적절히 수정하고 조정하십시오. 현재 @OldCurmudgeon 답변과 같은 방식으로 점수를 매 깁니다. int h(String t){}필요한 경우 17을 추가하십시오 .

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

기본적 으로이 프로그램은 문자에 대한 기본 26 가지 작업을 수행합니다. 그런 다음 해시가 12999 (해시 코드 YES)인지 확인하고 404 (해시 코드 NO)를 인쇄하면 해시 코드 만 인쇄합니다.

Conveyor는 현재 베타 단계에있는 언어이지만, 일부 예제 및 소스 코드와 함께 인터프리터는 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 #에서 undergroundmonorail 시도의 작동 (?) 버전. 문자열의 바이트를 32 비트 정수로 연결 한 다음 (최대 4 자까지만 작동) 결과를 각각 "YES"및 "NO"에 대한 결과와 OR 한 다음 OR로 묶습니다.

어느 시점에서 충돌 할 수 있지만 "YES"및 "NO"이외의 ^ [AZ] {2,3} $에 대해서는 발생하지 않아야합니다.


해시 함수에는 더 많은 충돌이 있습니다. "해시 함수"는 기본적으로 연결에서 많은 비트를 무시합니다. 해당 비트 만 다른 모든 문자열 쌍은 동일한 해시 코드를 갖습니다.
Paŭlo Ebermann

0

코멘트 없음-31 (기능 내용 : 26)

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

아주 간단한 해결책. ;) 모든 UTF-8 문자열에서 작동합니다.

설명 : ' 분명히 기능입니다. 먼저 *(입력)이 |,,|+|"#|( |NO|) 인지 확인합니다 . 그렇다면 |, |+|-%3|( |YES|)을 반환합니다 *. 그렇지 않으면 그냥 반환합니다 .


2
나는 논평 없음으로 일한 적이 없었습니다. 불투명 한 Golfscript, J 또는 APL 답변으로 종종 수행되는 것처럼 솔루션을 설명 할 수 있습니까?
Kaya

@Kaya 아, 죄송합니다. 글을 수정하겠습니다.
cjfaure

1
사과가 필요하지 않습니다. 어떻게 작동했는지 궁금했습니다.
Kaya

0

C 54

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

문자열을 정수- "NO"로 변환하고 동일한 값 + "NO"- "YES"를 곱하여 "NO"및 "YES"에 대해 0을, 지정된 범위에있는 다른 문자열에 대해 0이 아닌 값을 얻습니다.

엔디안 문제가있는 경우 Windows 7 시스템의 모든 값



-1

CoffeeScript-36

1for YES및을 반환해야 하며 base64 문자열이 아닌 다른 모든 항목에 대해 NO왜곡 된 넌센스가 atob생성하는 모든 항목을 반환해야 합니다.

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

자바 스크립트 상당 ( 하지 연사 컴파일러에서 JS 코드) :

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

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

3
"함수는 정수 반환 값을 가져야합니다."- _입력이 "YES"또는 "NO"가 아닌 경우를 반환한다고 가정합니다 .
Gaurang Tandon

-1

여기는 매우 절름발이입니다. 너무 작동하지 않아서 작동하지 않습니다

파이썬 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는 첫 번째 비트의 "YES"및 "NO"에 대한 결과이므로 YES 및 NO에 0을 곱합니다.

충돌이 없어야합니까? 18000 개의 가능한 반례에 대해 테스트하고 싶지는 않지만 의도하지 않은 충돌이 있으면 다른 0을 던질 수 100있으며 실제로 충돌 없어야합니다.

나는 lambda이것을 사용할 수 없다고 실망 했지만 전체 계산을 두 번하고 싶지 않았으므로 변수에 저장해야했습니다.

이기지 말아주세요 그것은 매우 절름발이이며 나는 그것을받을 자격이 없습니다.


"다른 충돌 없음"요구 사항을 충족하지 않음 : 18277 문자열 집합에는 충돌이 없어야하는 고유 한 해시가 18012 개뿐입니다.
dan04

@ dan 젠장, 잠깐만
undergroundmonorail

1
@ dan 나는 그것을 작동시킬 수 없다. 알고리즘에 본질적으로 문제가있을 수 있습니다. 나는 다른 사람이 잘못 알고 수 있기 때문에 그것을 삭제하지 않습니다,하지만 난 메모를 놓을 게요
undergroundmonorail

이것은 나를 위해 작동합니다. h = lams s : (hash (s) +997192582) * (hash (s) -480644903)
Lucas

당신과 비슷하지만 99 ** i * int (c, 36)로 해시 함수를 정의한 것처럼
Lucas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.