Karma çarpışma: “HAYIR” “EVET” anlamına gelir


63

Bu Code Golf, Daily WTF makalesinde , True ile başa çıkamazsın ! , şöyle yazılmış bir dize karşılaştırması içerir:

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

Java'nın String.hashCodeyöntemi yeni bir şekilde uygulanıyorsa, Steve ekibinin neden olacağı sorunu hayal edin "YES".hashCode() == "NO".hashCode(). Yani, burada önerdiğim zorluk:

Bir karakter hparametresine ve tamsayı dönüş değerine h("YES")eşit değerde olabildiğince az karakterde bir karma işlevi (onu arayacağım ) yazın h("NO").

Elbette, bu def h(s): return 0, her dize için karma çarpışma yapan gibi bir işlevle ilgisiz olur. Bu meydan okumayı daha ilginç hale getirmek için aşağıdaki ek kurala uymalısınız:

Of diğer üç veya daha az büyük ASCII harf (oluşan 18 277 olası dizeleri ^[A-Z]{0,3}$), olmalıdır hiçbir karma çarpışmalar.

Açıklama (Heiko Oberdiek tarafından işaret): girdi dizesi dışındaki karakterler içerebilir A-Z, ve kod gerekir keyfi dizeleri karma edebilmek. (Ancak, giriş varsayabiliriz olan bir karakter dizesi yerine bir boş gösterici ya da başka veri türünde bir nesne.) Ancak, dönüş değeri eşleşmeyen dizeleri ne fark etmez ^[A-Z]{0,3}$sürece, bu bir tamsayı.

Ayrıca, bu işlevin amacını karıştırmak için:

Kodunuz, karakter veya string değişmezlerinin içinde 'Y', 'E', 'S', 'N' veya 'O' (büyük veya küçük harf) harflerini içermemelidir.

Tabii ki, bu kısıtlama dil anahtar için geçerli değildir, bu yüzden else, returnvb iyidir.


4
YESNOBu özel istisnayı kontrol etmek için sayısal ASCII değerlerini kullanmaya devam etmemize yardımcı olmuyor .
Joe Z.

1
Birini okumak "komik nedenlerle" komikliğini hatırlayamıyor: threewordphrase.com/pardonme.gif
Antonio Ragagnin

Yanıtlar:


7

GolfScript: 19 karakter (adlandırılmış işlev için 24 karakter)

26base.2107=59934*+

Bu işlevin gövdesidir. Bunu adlandırılmış bir işleve atamak hbeş karakter daha alır:

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

(Yığın üzerinde yatan kodun bir kopyasını bırakmayı sakıncası yoksa, son noktalı virgül atlanabilir.)

Hash fonksiyonu çekirdek 26base(26 toplam hesaplayan, N - k · bir k , k = 1 .. , n ), n, giriş karakter sayısı ve bir k ASCII kod belirtmektedir k th giriş karakteri Büyük harf ASCII harflerinden oluşan girişler için, bu çarpışma içermeyen bir karma işlevidir. Kodun geri kalanı sonucu 2107 (karma kodu NO) ile karşılaştırır ve eşitse, karma kodu 2701 + 59934 = 62041 vermek üzere 59934 ekler YES.

Örneğin çıktı için, test senaryoları ile bu çevrimiçi demoya bakın .


Bunu nasıl test ettiniz? Az önce bir sürü çarpışma buldum . Örnek: h('DXP') == h('KK') == 65884.
nneonneo

(Sen benim test amacıyla, yazdıklarından Python eşdeğeri: lambda w:sum(ord(c)*26**i for i,c in enumerate(reversed(w*9)))%102983)
nneonneo

@ nneonneo: Açıkçası, yeterince iyi değil. Üç veya daha az girişin tam setini oluşturduğumu, hepsinin karıştığını ve karma setinin giriş setinden bir elementten daha az olduğunu kontrol ettiğimi düşündüm . Açıkçası, test takımımın bir yerde bir sorunu vardı. :-( Kısa olanı tamir edene kadar / değiştirene kadar orijinal 19-char sürümüne döneceğim.
Ilmari Karonen

54

32 bit Python 2.x (19)

hash(w*9)%537105043

RSA bir semiprime modülü kullanır ve bu onu güvenli kılar, bu yüzden hash algoritmamla birlikte kullanmak kesinlikle daha da iyi olmalı! 1

Bu saf bir matematik işlevidir, tüm karakter dizileri için çalışır (cehennem, herhangi bir Python nesnesi için işe yarar) ve herhangi bir şartlandırma veya özel muhafaza içermez! 32-bit Python tipik olarak python-32her ikisi de 2 yüklü olan çoğu sistemde olduğu gibi çağrılabilir .

Bunu test ettim ve 18,279 3 harfli veya küçük harfli dizeler için 18,278 farklı değer döndürür. Bunu bir işleve atamak 11 bayt daha alır:

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

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

64 bit Python 2.x (19)

hash(w*2)%105706823

Yukarıdakiyle aynı anlaşma.


Bu sayıları bulmak için, biraz modüler matematik kullanıldı. Ben bir işlev arıyordu fve bir modülü nböyle hash(f('YES')) % n == hash(f('NO')) % n. Bu, nbölen teste eşdeğerdir d = hash(f('YES')) - hash(f('NO')), yani sadece duygun değerleri için faktörleri kontrol etmemiz gerekir n.

İdeal nolanı, doğum günü paradoksunun çarpışma ihtimalini azaltmak için 20000 ** 2 civarında. Uygun nbulmanın biraz deneme yanılma olduğu, tüm faktörlerin d(genellikle çok fazla olmadığı) ve işlev için farklı seçeneklerle oynadığı ortaya çıkıyor f. Deneme ve yanlıma gerek duyulduğuna dikkat edin, çünkü nolabildiğince küçük yapmak istedim (golf oynamak için). Bu bir gereklilik değilse, sadece dyeterince büyük olan modülümü seçebilirdim .

Bu numarayı sadece f(s) = s(kimlik işlevi) kullanarak çözemeyeceğinizi unutmayın, çünkü dizenin en sağdaki karakterinde esas XORolarak son karma ile doğrusal bir ilişki (aslında bir ilişki) vardır (diğer karakterler çok daha doğrusal olmayan bir şekilde katkıda bulunur. ). Bu nedenle dizginin tekrarı, dizgiler arasındaki farkların sadece en sağdaki karakterin değiştirilmesinin etkisinin ortadan kaldırılması için büyütülmesini sağlar.


1 Bu patent saçma.
2 Python string hashing, ana sürüme (2 - 3) ve bitness'e (32-bit - 64-bit) bağlıdır. AFAIK platformuna bağlı değildir.


Benim oyumu aldın. : D
cjfaure

Ne yazık ki, bu yeni karma randomizasyon özelliği nedeniyle Python'un son sürümlerinde çalışmıyor.
dan04

@ dan04: Garip, bunun yalnızca Python 2.x için olduğunu belirttiğimi düşündüm. Tekrar düzenledim.
nneonneo

Bu sihirli sayıları nasıl bulduğunu bilebilir miyim? Ben bkz hash('YES'*9)sahip 34876679olurken, bir faktör olarak hash('NO'*9)sahip 34876679+537105043bir faktör olarak. Ama bunun 537105043iyi bir modül olduğunu nasıl bildin? yani başka çarpışmalar yapmadı mı?
Antonio Ragagnin

@AntonioRagagnin: Bunu cevaba ekledi.
nneonneo

38

Perl, 53 49 40 bayt

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

Ölçek:

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

Karma değerleri YESve NOaynıdır ve 18279 dizeleri vardır ^[A-Z]{0,3}$çarpışma yalnızca çarpışma dışında serbesttir, YESve NO.

Ungolfed:

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";

Eski sürüm, 49 bayt

Yeni algoritma biraz farklı olduğu için eski sürümü saklıyorum.

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

Ölçek:

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

Ungolfed:

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".
}

Düzenlemeler:

  • "\0"Dolgu baytı olarak kullanmak , 4 bayt ile karşılaştırıldığında kaydeder $".

Nerede yok 5457241ve 20047çıktı? Bu sayıları nasıl hesaplıyorsunuz? Şimdiden teşekkürler.
AL

@ n.1: YEShex cinsindendir 594553. Hex59 NOiçinde 0x594553 = 5850451 4e4f. 0x4e4f = 20047.
nneonneo

7

Python: 63

İnanılmaz derecede topal bir çözüm:

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

Alfanümerik dizeleri base-36 sayıları olarak yorumlayarak ve her şey için 0 döndürerek çalışır. 852 (NO) dönüş değerini kontrol etmek ve bunun yerine 44596 (YES) değerini kontrol etmek için özel bir durum var.


3
Yanlış anlamadığım sürece: Bu kod golf, girişin doğru olduğunu varsaymanıza izin verilir. try:Üçüncü hattın tamamını ve hendek açabilirsiniz . Ayrıca, her bir mantıksal çizgiyi aynı gerçek satırda, noktalı virgülle ( def h(s):r=int(s,36);return(r,44596)[r==852])
undergroundmonorail

1
@ undergroundmonorail: Hash fonksiyonu için string parametresi soru ile sınırlı değil . Belirli bir dizge sınıfı için (en fazla üç büyük harf), karma işlevinin dönüş değerleriyle ilgili bir kısıtlama vardır. Bununla birlikte, eğer dönüş değeri bir tamsayıysa, diğer dizgiler için ne döndürdüğü önemli değildir.
Heiko Oberdiek


6

Saf Bash, 29 bayt (fonksiyon gövdesi)

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

Bu sadece girdi dizgesini bir baz 36 numarası olarak ele alır ve ondalık değerine dönüştürür, sonra özel NOdurumla ilgilenir .

Çıktı:

$ h A
10
$ h B
11
$ h CAT
15941
$ h NO
44596
$ h EVET
44596
$ h ZZZ
46655
$

5

Ruby, 51 bayt

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

test kodu:

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
}

çıktı :

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

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

5

Javascript ( ES6 ) 54 bayt

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

5

Java - 94 77

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

unrolled:

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

Anlatı - için f(s) = BigInteger(s.getBytes()):

  • f("YES") xor f("NO") = 5835548
  • Yani f("YES") xor 5835548 = f("NO")
  • Yani f("YES") - (f("YES") xor 5835548) = f("NO") - (f("NO") xor 5835548)haklı mıyım?

BigInteger’ın satırında olamaz mısın?
mafu

@mafutrct - EVET !!! Teşekkür ederim.
OldCurmudgeon

5

CJam, 15 bayt

q42b_*81991617%

Aşağıdaki GolfScript çözümü olarak çalışır. Çevrimiçi deneyin.


GolfScript, 17 bayt

42base.*81991617%

Bu yaklaşım, nneonneo ve Ilmari Karonen'in cevaplarına dayanıyor .

Nasıl çalışır

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.

Bir algoritma seçmek

Başlayalım {b base}:h, yani giriş dizesi bir temel b sayılır. Sürece b > 25, hinyective olduğunu.

hAşağıdaki şekilde değiştirirsek "YES" ve "NO" dizeleri için bir çarpışma elde ederiz : {x base n}:hnerede nbölen "YES" h "NO" h -.

Maalesef, bu, örneğin, YETve NP. Bunu önlemek için, baz-b sayısını, modül alınmadan önce doğrusal olmayan bir şekilde değiştirmek zorundayız.

Bunu GolfScript'te gerçekleştirmenin en kısa yolu, base-b sayısını kendisiyle çarpmaktır (yani onu kareler). hşimdi {base b .* n %}:h.

Geriye kalan tek şey bve için uygun değerler bulmak n. Bunu kaba kuvvetle başarabiliriz:

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
    }
}

Bunun için mümkün olan en kısa değerler b n:

37 92176978
42 81991617

Test yapmak

$ 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 karakter (33 karakter işlev gövdesi)

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

Test Durumları:

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

Açıklama:

Her şeyden önce, size NaNJavaScript'te - "Bir Numara Değil" - tanıtmama izin verin . Bu bir sayı:

typeof NaN  // number

Aynen gibi:

typeof 42   // number

Özel özelliği, asla kendisine eşit olmamasıdır . Benim işlevin döndürdüğü 1dize ise YESya NOve NaNdiğer herhangi bir dize.

Yani, bu kuralları çiğnemez, çünkü başka herhangi bir string için karma çarpışma olmaz;) ( NaN !== NaNyukarıda test durumlarında gösterilmiştir).

Ve hayalim gerçek oluyor: Bash, Perl ve Ruby'yi kod uzunluğunda dövmek!

Ungolfed Kodu:

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

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

Bu değer "WUVT"veya ise "Tk8=", geri dönün 1. Başka, dönüş

+s // parseInt(s, 10)

Bu olurdu NaN.


2
NaN bir sayı olabilir, ancak kelimenin tam anlamıyla "tamsayı" değildir.
Paŭlo Ebermann

2
@ PaŭloEbermann itibaren wiki , "Bir tamsayı bir olan sayı kesirli bileşen olmadan yazılır". Soru açıkça tamsayının olması gerektiğini söylemez ^\d+$. Ve JS NaNbir sayı gibi davranır . Sayı ile çarpabilir, toplayabilir, ayırabilir, sayılarda olduğu gibi çıkarabilirsiniz. JavaScript'in özel bir özelliğidir. Kullanmanın bir zararı yok. Buna kuralların bükülmesi diyoruz ;)
Gaurang Tandon

1
Kullanabileceğini Object.is()ve hala bir çarpışma olduğunu iddia edebilirdim …
user2428118

1
@ user2428118 Object.is'i bilgime getirdiğiniz için teşekkür ederiz. Asla bilemedim. Fakat OP'nin, eşitlik operatörünü ( ==) karşılaştırma için kullandığını not etmenizi isterim ki bu , "EVET" veya "HAYIR" dışında herhangi bir dize için hiçbir çarpışma gerçekleşmeyeceğini garanti eder.
Gaurang Tandon

2
İddia gerçeğini göz ardı edilmesi NaNçarpışma ucuz görünüyor sayılmaz, bu çözüm dizeleri ile çarpışmaları sahiptir NAiçinden NPve YEQüzerindenYET
nderscore

2

Python 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

Karma işlevi, ASCII karakterlerinin sıralı değerlerini birleştirir, print cümlesi istenen iki girişin çarpışmasını sağlar.


2

ECMAScript 6 (30 bayt)

Değişken atama, dönüş ve işlev anahtar sözcüğünden kaçınmaya çalıştım ve bu tüm saçmalıklardan kaçınmak için harika bir yol gibi görünüyor (aynı zamanda bir şekilde işlevsel programlama gibi görünüyor). Diğer çözümlerden farklı olarak ECMAScript 6 btoaya da atobHTML5'e bağlı değildir. 0+ihtiyaç duyulur, böylece keyfi dizgileri ayrıştırır.

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

1
Güzel! Ayrıştırma için başka üsler eklediklerini bilmiyordum. Yine de çok fazla bayt kesebilirsiniz. :)a=>parseInt(0+a,36)-852||43744
nderscore

@ nderscore: Öneriniz için teşekkürler. Senaryomu gerçekten çok geliştirdi.
Konrad Borowski

2

Java - 45 (veya 62?)

Java'da bir program çalıştırmak için neye ihtiyaç duyduğuna bakılırsa adil bir şekilde nasıl puan alacağımı bilmiyorum, fonksiyon tanımını dahil etmem gerekiyor mu? Puanımı uygun şekilde düzenlemek ve ayarlamaktan çekinmeyin. Şu anda @OldCurmudgeon cevap olarak aynı şekilde puan alıyorum. int h(String t){}Gerekirse 17 tane ekle :

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

Test kablo demeti ile kurtulmuş:

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

Ve gevşek olan ...

Taşıyıcı, 145 karakter

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

Temelde bu program karakterlerin üzerinde bir çeşit temel yapıyor. Bundan sonra, karma değerinin 12999'a (EVET'in karma kodu) eşit olup olmadığını kontrol eder ve eğer öyleyse 404'ü (NO'nun karma kodunu) yazdırır, aksi takdirde sadece kod kodunu yazar.

Konveyör şu anda beta aşamasında olan bir dildir ancak bazı örnekler ve kaynak kodları ile birlikte bir tercüman burada bulunabilir: https://github.com/loovjo/Conveyor


0

C # 4.5 (112 bayt)

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

Undermonmonorail girişiminin C # 'daki (?) Versiyonu. Dizideki baytları 32-bit bir tamsayıya gizler (sadece 4 karaktere kadar çalışır), ardından sonucu sırasıyla "EVET" ve "HAYIR" sonuçlarına karşı ORS, ardından OR'lar birlikte yapar.

Bir noktada çarpışmasına rağmen, "EVET" ve "HAYIR" dışında herhangi bir ^ [AZ] {2,3} $ 'da olmamalıdır.


Hash fonksiyonunun daha fazla çarpışması olacak. Senin "hash" fonksiyonu esas olarak birleştirme işleminde birçok bit görmezden geliyor. Yalnızca bu bitlerde farklılık gösteren tüm dize çiftleri aynı karma koda sahip olacaktır.
Paŭlo Ebermann

0

Yorum Yok - 31 (fonksiyon içeriği: 26)

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

Oldukça basit bir çözüm. ;) Herhangi bir ve tüm UTF-8 dizeleri için çalışır.

AÇIKLAMA: ' Açıkçası, işlevdir. İlk önce, *(giriş) in |,,|+|"#|( |NO|) e eşit olup olmadığını kontrol eder . Öyleyse, döndürür |, |+|-%3|( |YES|) - aksi takdirde, yalnızca döndürür *.


2
Yorum Yok ile hiç çalışmadım, sık sık opak Golfscript, J veya APL cevapları ile yapıldığı gibi çözümünüzü açıklamanız mümkün mü?
Kaya

@Kaya Oh, evet, üzgünüm, yazıyı düzenleyeceğim.
cjfaure

1
Özür gerek yok, sadece nasıl çalıştığını merak ediyordum.
Kaya

0

C 54

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

Dizgiyi tamsayıya - "HAYIR" a dönüştürün ve "NO" ve "YES" için 0 almak ve belirtilen aralıktaki diğer herhangi bir dize için sıfır olmayan değeri aynı değerde + "NO" - "YES" ile çarpın.

Endian kaygıları varsa, Windows 7 makinedeki tüm değerler.



-1

CoffeeScript - 36

Dönmelidir 1için YESve NOve bozuk saçma olursa olsun atobher şey için üretiyor base64 dize değil.

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

JavaScript eşdeğeri ( CS derleyiciden JS kodu değil ):

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

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

3
"Fonksiyonun bir tamsayı dönüş değeri olması gerekir" - Sanırım _giriş "EVET" veya "HAYIR" değilken sizinkini verir.
Gaurang Tandon,

-1

İşte süper bir topal olanı. SO LAME, ÇALIŞMAYAN ÇALIŞIYOR

Python 2.7 - 79 bayt

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

İlk önce (her karakterin ascii değeri) * 100 ^ 'nin (karakterin dizideki konumu) toplamını alırız. Sonra son cevabımızı almak için çarptık (bu sonuç - 7978) ve (bu sonuç - 836989). 7978 ve 836989, ilk bitin "YES" ve "NO" sonuçlarıdır, dolayısıyla YES ve NO için 0 ile çarpıyoruz.

Bunun herhangi bir çarpışması olmamalı mı? Ben 18000 olası counterexamples karşı test gibi hissetmiyorum, ama istenmeyen bir çarpışma olsaydı bu konuda başka 0 atabilir 100ve sonra orada gerçekten herhangi çarpışmalara olmamalıdır.

Bunun lambdaiçin kullanamayacağımı hayal kırıklığına uğrattım , ancak tüm hesaplamayı iki kez yapmak istemedim, bu yüzden onu bir değişkene kaydetmek zorunda kaldım.

Lütfen bunun kazanmasına izin verme. Süper topal ve bunu haketmiyorum.


"Başka çarpışma yok" şartını yerine getirmiyor: 18277 telli setten çarpışma olmaması gereken sadece 18012 benzersiz karma var.
dan04

Kahretsin, bana bir saniye ver
undergroundmonorail

1
@ dan Çalışamıyorum. Belki de algoritmada kendine özgü bir yanlışlık var. Silmek istemiyorum çünkü başkaları neyin yanlış olduğunu biliyor olabilir, ancak bir not
undergroundmonorail

Bu benim için çalışıyor, h = lambda s: (karma (s) +997192582) * (karma (s) -480644903)
Lucas

sizinkilere benzer ancak bir hash işlevinin tanımlanması gibi 99 ** i * int (c, 36)
Lucas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.