ハッシュ衝突:「NO」は「YES」を意味します


63

このコードゴルフは、最近のDaily WTFの記事「You Ca n't Can the True!」に触発されました、次のように記述された文字列比較を備えています。

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

JavaのString.hashCodeメソッドがたまたまJavaのメソッドが次のように実装された場合、Steveのチームに生じたトラブルを想像してください"YES".hashCode() == "NO".hashCode()。したがって、ここで提案する課題は次のとおりです。

(私はそれを呼び出すよ、できるだけ少ない文字数で、ハッシュ関数を書く hように、文字列パラメータと整数戻り値で) h("YES")に等しいですh("NO")

もちろん、これはdef h(s): return 0すべての文字列に対してハッシュ衝突を発生させるのような関数で行うのは簡単です。この課題をさらに面白くするには、次の追加規則を順守する必要があります。

3つ以下の大文字のASCII文字()で構成される他の 18 277の可能な文字列のうち、ハッシュの衝突が発生して^[A-Z]{0,3}$はなりません

明確化(Heiko Oberdiekが指摘):入力文字列には以外の文字が含まれている場合がA-Zあり、コード任意の文字列をハッシュできる必要があります。(ただし、入力がいることを仮定してもよいです文字列ではなくNULLポインタまたは他のいくつかのデータ型のオブジェクト。)しかし、戻り値が一致しない文字列を何のためにあるのかは重要ではありません^[A-Z]{0,3}$限り、整数です。

さらに、この関数の意図をわかりにくくするには:

コードには、文字または文字列リテラル内に文字「Y」、「E」、「S」、「N」、または「O」(大文字または小文字)を含めないでください。

もちろん、この制限は、言語のキーワードには適用されませんのでelsereturnなど細かいです。


4
YESNOこの特定の例外をチェックするためにASCIIの数値を使用できることは、何の役にも立ちません。
ジョーZ. 14

1
:記事1を読むこと「の理由で」漫画覚えていないことはできませんthreewordphrase.com/pardonme.gif
アントニオRagagnin

回答:


7

GolfScript:19文字(名前付き関数の場合は24文字)

26base.2107=59934*+

これは関数の本体です。名前付き関数に割り当てるには、hさらに5つの文字が必要です。

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

(コードのコピーをスタック上に残してもかまわない場合は、最後のセミコロンを省略できます。)

ハッシュ関数のコアは、26basesum(26 nka k ; k = 1 .. n)を計算します。ここで、nは入力の文字数で、a kk番目のASCIIコードを示します入力文字。大文字のASCII文字で構成される入力の場合、これは衝突のないハッシュ関数です。残りのコードは、結果を2107(のハッシュコードNO)と比較し、等しい場合は、59934を加算して、のハッシュコードである2701 + 59934 = 62041を生成しますYES

出力例については、このオンラインデモとテストケースをご覧ください


これをどのようにテストしましたか?私はちょうど衝突の束を発見しました。例: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-char型のバージョンに戻します。
イルマリKaronen

54

32ビットPython 2.x(19)

hash(w*9)%537105043

RSAはセミプライムモジュラスを使用しており、これにより安全性が向上します。したがって、私のハッシュアルゴリズムでRSAを使用すると、さらに改善されるはずです。1

これは純粋な数学関数であり、すべての文字列に対して機能し(地獄、ハッシュ可能なPythonオブジェクトに対して機能します)、条件や特殊なケースは含まれていません!通常、32ビットPythonは、python-32両方がインストールされているほとんどのシステムで呼び出すことができます2

これをテストしましたが、3文字以下の大文字の文字列18,279に対して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最終ハッシュと線形関係(実際には関係)を持っているため(他の文字ははるかに非線形の方法で寄与するため)だけ(アイデンティティ関数)を使用してこのトリックを実行できないことに注意してください)。したがって、文字列の繰り返しにより、文字列間の違いが増幅され、右端の文字のみを変更する効果がなくなります。


1これはパテントナンセンスです。
2 Python文字列ハッシュは、メジャーバージョン(2対3)およびビット数(32ビット対64ビット)に依存します。プラットフォームAFAIKに依存しません。


あなたは私の票を持っています。:D
cjfaure 14

残念ながら、新しいハッシュランダム化機能により、これは最近のバージョンのPythonでは機能しません。
dan04 14

@ dan04:奇数、私はこれがPython 2.x専用であると指定したと思った。もう一度編集しました。
nneonneo

これらの魔法の数字をどのように見つけたか知っていますか?私は見hash('YES'*9)てい34876679ながら、要因としてhash('NO'*9)持っている34876679+537105043要因として。しかし、それ537105043が良いモジュラスであることをどのように知りました か?すなわち、それは他の衝突をしなかった?
アントニオラガグニン14

@AntonioRagagnin:それを答えに追加しました。
nneonneo 14

38

Perl、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"as fill byte を使用すると、と比較して4バイト節約され$"ます。

どこか545724120047から来るの?これらの数値をどのように計算しますか?前もって感謝します。
AL

@ n.1:YES16進数は594553です。0x594553 =5850451。16 NO進数は4e4fです。0x4e4f = 20047
nneonneo

7

Python: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:3行目全体を捨てることができます。また、セミコロン(で区切って、同じ実際のライン上のすべての論理行を持つことによって、いくつか刺されを保存することができますdef h(s):r=int(s,36);return(r,44596)[r==852]
undergroundmonorail

1
@undergroundmonorail:ハッシュ関数の文字列パラメーターは質問で制限されていません。特定のクラスの文字列(最大3文字の大文字)については、ハッシュ関数の戻り値に関する制限があります。ただし、戻り値が整数である場合、他の文字列に対して何が返されるかは問題ではありません。
ヘイコOberdiek 14

3
私はそこにあなたの配列のブール・インデックスが好き
kratenko

6

Pure Bash、29バイト(関数本体)

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

これは、入力文字列を基数36として扱い、10進数に変換してから、特殊なNOケースを処理します。

出力:

$ h A
10
$ h B
11
$ h CAT
15941
$ hいいえ
44596
$ hはい
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

Java- 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をインライン化できませんか?
マフ14

@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 > 25hinyectiveです。

h次のように変更すると、文字列「YES」と「NO」の衝突が発生します:{x base n}:hnはの約数です"YES" h "NO" h -

残念ながら、これは、我々はまた、例えば、のための衝突を取得します意味、YETNP。これを防ぐには、モジュラスを取得する前に、base-bの数値を非線形に変更する必要があります。

GolfScriptでこれを実現する最短の方法は、base-bの数値をそれ自体で乗算することです(つまり、2乗します)。h{base b .* n %}:hです。

行うに残っているのは、適した値を見つけることであるbn。総当たりでこれを達成できます。

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

説明:

まずNaN、JavaScriptで「Not A Number」を紹介します。それは数字です:

typeof NaN  // number

と同じように:

typeof 42   // number

その特別な特性は、決してそれ自体に等しくないことです1文字列がYESまたはの場合NO、およびNaN他の文字列の場合、私の関数は戻ります。

したがって、他の文字列にはハッシュ衝突がないため、これはルールを破りません;)(NaN !== NaNテストケースで上に示されています)。

そして、私の夢は実現します。Bash、Perl、Rubyをコード長で打ち負かすことです!

未ゴルフコード:

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は数字の場合もありますが、言葉の意味では「整数」ではありません。
パエロエベルマン14

2
@からPaŭloEbermann ウィキ、「整数である端数部品なしで書かれています」。質問は整数がそうである必要があると明確に言いません^\d+$。また、JSはNaN数値として扱います。数値で乗算、加算、除算、減算を数値と同様に行うことができます。これはJavaScriptの特別なプロパティです。それを使用しても害はありません。それは我々が呼んだルールの曲げ ;)
Gaurang Tandon

1
私は使用することができますObject.is()...そして、それはまだ衝突の主張
user2428118

1
@ user2428118 Object.isを知ってくれてありがとう。知らなかった。しかし、OPは==比較に等値演算子()を使用することに注意してください。これにより、「YES」または「NO」以外の文字列に対してハッシュ衝突が発生しないことが保証されます。
ゴーランタンドン14

2
主張しているという事実を無視しNaN、衝突が安いようだとしてカウントされませんが、この解決策は、文字列との衝突を持っNANPしてYEQ通過YET
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

ハッシュ関数はASCII文字の序数値を連結し、printステートメントは2つの入力が衝突することを保証します。


2

ECMAScript 6(30バイト)

変数の割り当て、戻り値、および関数のキーワードを回避しようとしましたが、これはすべてのナンセンスを回避するための素晴らしい方法のように見えます(ある意味、関数型プログラミングのようにも見えます)。他のソリューションとは異なり、ECMAScript 6ではなくHTML5であるbtoaor atobに依存しません。0+が必要なので、任意の文字列を解析できます。

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

1
いいね!parseIntに他のベースを追加したことは知りませんでした。ただし、多くのバイトを削減できます。:)a=>parseInt(0+a,36)-852||43744
nderscore 14

@nderscore:提案をありがとう。それは私のスクリプトを本当に改善しました。
コンラッドボロスキー14

2

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

基本的に、このプログラムは、charsに対して何らかのベース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#での、地下モノレールの試みの作業(?)バージョン。文字列内のバイトを32ビット整数(最大4文字のみ)に連結し、結果をそれぞれ「YES」および「NO」の結果とOR演算し、次にそれらをOR演算します。

ある時点で衝突する可能性がありますが、「はい」と「いいえ」以外の^ [AZ] {2,3} $に対しては発生しません。


ハッシュ関数にはさらに多くの衝突があります。あなたの「ハッシュ関数」は本質的に連結の多くの部分を無視しています。これらのビットのみが異なるすべての文字列ペアは、同じハッシュコードを持ちます。
パエロエベルマン14

0

コメントなし-31(機能内容:26)

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

非常にシンプルなソリューション。;)すべてのUTF-8文字列で機能します。

説明: '明らかに、機能です。まず、*(入力である)が|,,|+|"#||NO|)と等しいかどうかをチェックします。存在する場合は|, |+|-%3||YES|)を返します*。存在しない場合は単にを返します。


2
私はコメントなしで作業したことはありませんが、不透明なGolfscript、J、またはAPLの回答でよく行われるように、あなたのソリューションを説明することは可能ですか?
カヤ14

@Kayaああ、はい、すみません、投稿を編集します。
cjfaure 14

1
謝罪する必要はありません。どのように機能するのか興味がありました。
カヤ14

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

andを返す必要1YESありNOatobbase64文字列ではない他のすべての文字化けしたナンセンスが生成されます。

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

同等のJavaScript(CSコンパイラのJSコードではありません):

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

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

3
「関数には整数の戻り値が必要です」- _入力が「YES」でも「NO」でもないときに、あなたの関数が返すと思います。
ゴーランタンドン14

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

まず、(各文字のアスキー値)* 100 ^(文字列内のその文字の位置)の合計を取得します。次に、(その結果-7978)と(その結果-836989)を乗算して、最終的な答えを取得します。7978と836989は、最初のビットの「YES」と「NO」の結果であるため、YESとNOの場合、0を乗算します。

これに衝突はありませんか?18000の反例に対してテストする気はありませんが、意図しない衝突があった場合、その上に別の0を投げることができ100実際には衝突はありません。

lambdaこのためにa を使用できなかったことに失望しましたが、計算全体を2回実行したくなかったため、変数に保存する必要がありました。

これを勝たせないでください。それは非常に不自由であり、私はそれに値しません。


「他の衝突なし」の要件を満たしていません。衝突しないはずの18277文字列セットには18012個の一意のハッシュしかありません。
dan04 14

@ダンダム、ちょっと待ってください
地下

1
@ダン私はそれを動作させることができません。アルゴリズムに本質的に問題があるのか​​もしれません。他の誰かが何が悪いのか知っているかもしれないので、私はそれを削除したくありません、しかし、私はメモを書きます
地下

これは私の場合、h = lambda s:(hash(s)+997192582)*(hash(s)-480644903)
ルーカス

あなたのものと似ているが、99 ** i * int(c、36)でハッシュ関数を定義したように
ルーカス14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.