複雑なサイコロのローリング式


23

バックグラウンド

友達と定期的にD&Dをしています。サイコロを転がし、ボーナスとペナルティを適用することに関して、いくつかのシステム/バージョンの複雑さについて話している間、私たちは冗談めかして、サイコロを転がす表現のいくつかの追加の複雑さを思いつきました。それらのいくつかはとてつもなく広すぎました(2d6マトリックス引数1のような単純なサイコロ式を拡張するなど)が、残りは興味深いシステムになります。

チャレンジ

複雑なサイコロ式が与えられたら、次の規則に従って評価し、結果を出力します。

基本評価ルール

  • 演算子が整数を期待しているが、オペランドのリストを受け取るたびに、そのリストの合計が使用されます
  • 演算子がリストを期待しているが、オペランドに整数を受け取ったときは常に、その整数はその整数を含む1要素のリストとして扱われます

オペレーター

すべての演算子は二項中置演算子です。説明のために、aは左のオペランド、b右のオペランドになります。リスト表記は、演算子がリストをオペランドとして取ることができる例で使用されますが、実際の式は正の整数と演算子のみで構成されます。

  • da範囲内の独立した一様ランダム整数を出力します[1, b]
    • 優先順位:3
    • 両方のオペランドは整数です
    • 例:3d4 => [1, 4, 3][1, 2]d6 => [3, 2, 6]
  • tbから最低値を取得a
    • 優先順位:2
    • aリスト、b整数です
    • の場合b > len(a)、すべての値が返されます
    • 例:[1, 5, 7]t1 => [1][5, 18, 3, 9]t2 => [3, 5]3t5 => [3]
  • Tbから最高値を取得a
    • 優先順位:2
    • aリスト、b整数です
    • の場合b > len(a)、すべての値が返されます
    • 例:[1, 5, 7]T1 => [7][5, 18, 3, 9]T2 => [18, 9]3T5 => [3]
  • r:の要素bがinのa場合、それらdを生成したステートメントを使用して、それらの要素を再ロールします
    • 優先順位:2
    • 両方のオペランドはリストです
    • 再ローリングは一度だけ行われるためb、結果にの要素を含めることができます
    • 例:3d6r1 => [1, 3, 4] => [6, 3, 4]2d4r2 => [2, 2] => [3, 2]3d8r[1,8] => [1, 8, 4] => [2, 2, 4]
  • R:inの要素bがin aである場合、それらの要素bd生成されるステートメントを使用して、要素が存在しなくなるまでそれらの要素を繰り返しリロールします
    • 優先順位:2
    • 両方のオペランドはリストです
    • 例:3d6R1 => [1, 3, 4] => [6, 3, 4]2d4R2 => [2, 2] => [3, 2] => [3, 1]3d8R[1,8] => [1, 8, 4] => [2, 2, 4]
  • +:追加aしてb一緒に
    • 優先順位:1
    • 両方のオペランドは整数です
    • 例:2+2 => 4[2]+[2] => 4[3, 1]+2 => 6
  • -bから引くa
    • 優先順位:1
    • 両方のオペランドは整数です
    • b 常により小さい a
    • 例:2-1 => 15-[2] => 3[8, 3]-1 => 10
  • .:連結aしてb一緒に
    • 優先順位:1
    • 両方のオペランドはリストです
    • 例:2.2 => [2, 2][1].[2] => [1, 2]3.[4] => [3, 4]
  • _:のaすべての要素がb削除された 出力
    • 優先順位:1
    • 両方のオペランドはリストです
    • 例:[3, 4]_[3] => [4][2, 3, 3]_3 => [2]1_2 => [1]

追加の規則

  • 式の最終値がリストの場合、出力前に合計されます
  • 用語の評価は、正の整数または正の整数のリストのみになります-非正の整数または少なくとも1つの非正の整数を含むリストになる式では、それらの値が1sに置き換えられます
  • 括弧を使用して用語をグループ化し、評価の順序を指定できます
  • 演算子は、最高の優先順位から最低の優先順位の順に評価されます。優先順位が同順位の場合、評価は左から右に進み1d4d4ます(したがって、と評価されます(1d4)d4
  • リスト内の要素の順序は重要ではありません。リストを変更する演算子が、要素を異なる相対順序で返すように完全に許容できます
  • 評価できない、または無限ループになるような用語(1d1R1またはなど3d6R[1, 2, 3, 4, 5, 6])は無効です

テストケース

フォーマット: input => possible output

1d20 => 13
2d6 => 8
4d6T3 => 11
2d20t1 => 13
5d8r1 => 34
5d6R1 => 20
2d6d6 => 23
3d2R1d2 => 3
(3d2R1)d2 => 11
1d8+3 => 10
1d8-3 => 4
1d6-1d2 => 2
2d6.2d6 => 12
3d6_1 => 8
1d((8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3)) => 61

最後のテストケース以外はすべて、リファレンス実装で生成されました。

実施例

式: 1d((8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3))

  1. 8d20t4T2 => [19, 5, 11, 6, 19, 15, 4, 20]t4T2 => [4, 5, 6, 11]T2 => [11, 6](フル:1d(([11, 6])d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3))
  2. 6d6R1r6 => [2, 5, 1, 5, 2, 3]r1R6 => [2, 5, 3, 5, 2, 3]R6 => [2, 5, 3, 5, 2, 3]1d([11, 6]d[2, 5, 3, 5, 2, 3]-2d4+1d2).(1d(4d6_3d3))
  3. [11, 6]d[2, 5, 3, 5, 2, 3] => 17d20 => [1, 6, 11, 7, 2, 8, 15, 3, 4, 18, 11, 11, 1, 10, 8, 6, 11]1d([1, 6, 11, 7, 2, 8, 15, 3, 4, 18, 11, 11, 1, 10, 8, 6, 11]-2d4+1d2).(1d(4d6_3d3))
  4. 2d4 => 71d([1, 6, 11, 7, 2, 8, 15, 3, 4, 18, 11, 11, 1, 10, 8, 6, 11]-7+1d2).(1d(4d6_3d3))
  5. 1d2 => 21d([1, 6, 11, 7, 2, 8, 15, 3, 4, 18, 11, 11, 1, 10, 8, 6, 11]-7+2).(1d(4d6_3d3))
  6. [1, 6, 11, 7, 2, 8, 15, 3, 4, 18, 11, 11, 1, 10, 8, 6, 11]-7+2 => 133-7+2 => 1281d128).(1d(4d6_3d3))
  7. 4d6_3d3 => [1, 3, 3, 6]_[3, 2, 2] => [1, 3, 3, 6, 3, 2, 2]1d128).(1d[1, 3, 3, 6, 3, 2, 2])
  8. 1d[1, 3, 3, 6, 3, 2, 2] => 1d20 => 61d128).(6)
  9. 1d128 => 5555.6
  10. 55.6 => [55, 6][55, 6]
  11. [55, 6] => 61 (完了)

参照実装

このリファレンス実装は、0テスト可能な一貫性のある出力の各式を評価するために同じ定数シード()を使用します。各式は改行で区切られており、STDINへの入力が必要です。

#!/usr/bin/env python3

import re
from random import randint, seed
from collections import Iterable
from functools import total_ordering

def as_list(x):
    if isinstance(x, Iterable):
        return list(x)
    else:
        return [x]

def roll(num_sides):
    return Die(randint(1, num_sides), num_sides)

def roll_many(num_dice, num_sides):
    num_dice = sum(as_list(num_dice))
    num_sides = sum(as_list(num_sides))
    return [roll(num_sides) for _ in range(num_dice)]

def reroll(dice, values):
    dice, values = as_list(dice), as_list(values)
    return [die.reroll() if die in values else die for die in dice]

def reroll_all(dice, values):
    dice, values = as_list(dice), as_list(values)
    while any(die in values for die in dice):
        dice = [die.reroll() if die in values else die for die in dice]
    return dice

def take_low(dice, num_values):
    dice = as_list(dice)
    num_values = sum(as_list(num_values))
    return sorted(dice)[:num_values]

def take_high(dice, num_values):
    dice = as_list(dice)
    num_values = sum(as_list(num_values))
    return sorted(dice, reverse=True)[:num_values]

def add(a, b):
    a = sum(as_list(a))
    b = sum(as_list(b))
    return a+b

def sub(a, b):
    a = sum(as_list(a))
    b = sum(as_list(b))
    return max(a-b, 1)

def concat(a, b):
    return as_list(a)+as_list(b)

def list_diff(a, b):
    return [x for x in as_list(a) if x not in as_list(b)]

@total_ordering
class Die:
    def __init__(self, value, sides):
        self.value = value
        self.sides = sides
    def reroll(self):
        self.value = roll(self.sides).value
        return self
    def __int__(self):
        return self.value
    __index__ = __int__
    def __lt__(self, other):
        return int(self) < int(other)
    def __eq__(self, other):
        return int(self) == int(other)
    def __add__(self, other):
        return int(self) + int(other)
    def __sub__(self, other):
        return int(self) - int(other)
    __radd__ = __add__
    __rsub__ = __sub__
    def __str__(self):
        return str(int(self))
    def __repr__(self):
        return "{} ({})".format(self.value, self.sides)

class Operator:
    def __init__(self, str, precedence, func):
        self.str = str
        self.precedence = precedence
        self.func = func
    def __call__(self, *args):
        return self.func(*args)
    def __str__(self):
        return self.str
    __repr__ = __str__

ops = {
    'd': Operator('d', 3, roll_many),
    'r': Operator('r', 2, reroll),
    'R': Operator('R', 2, reroll_all),
    't': Operator('t', 2, take_low),
    'T': Operator('T', 2, take_high),
    '+': Operator('+', 1, add),
    '-': Operator('-', 1, sub),
    '.': Operator('.', 1, concat),
    '_': Operator('_', 1, list_diff),
}

def evaluate_dice(expr):
    return max(sum(as_list(evaluate_rpn(shunting_yard(tokenize(expr))))), 1)

def evaluate_rpn(expr):
    stack = []
    while expr:
        tok = expr.pop()
        if isinstance(tok, Operator):
            a, b = stack.pop(), stack.pop()
            stack.append(tok(b, a))
        else:
            stack.append(tok)
    return stack[0]

def shunting_yard(tokens):
    outqueue = []
    opstack = []
    for tok in tokens:
        if isinstance(tok, int):
            outqueue = [tok] + outqueue
        elif tok == '(':
            opstack.append(tok)
        elif tok == ')':
            while opstack[-1] != '(':
                outqueue = [opstack.pop()] + outqueue
            opstack.pop()
        else:
            while opstack and opstack[-1] != '(' and opstack[-1].precedence > tok.precedence:
                outqueue = [opstack.pop()] + outqueue
            opstack.append(tok)
    while opstack:
        outqueue = [opstack.pop()] + outqueue
    return outqueue

def tokenize(expr):
    while expr:
        tok, expr = expr[0], expr[1:]
        if tok in "0123456789":
            while expr and expr[0] in "0123456789":
                tok, expr = tok + expr[0], expr[1:]
            tok = int(tok)
        else:
            tok = ops[tok] if tok in ops else tok
        yield tok

if __name__ == '__main__':
    import sys
    while True:
        try:
            dice_str = input()
            seed(0)
            print("{} => {}".format(dice_str, evaluate_dice(dice_str)))
        except EOFError:
            exit()

[1]:adbforマトリックス引数の定義はAdX、各Xでロールすることでしたa * b、ここでA = det(a * b)。明らかに、これはこの挑戦には馬鹿げている。



上の保証と-それがbより常に低くなりますa第二の追加ルールは無意味と思われるので、私は、非正の整数を取得する方法を参照してくださいません。OTOH _は、空のリストを生成する可能性があります。これは同じ場合に便利なようですが、整数が必要な場合はどういう意味ですか?通常、私は、合計があるでしょうね0...
クリスチャンSieversの

@ChristianSievers 1)明確にするために、正でない整数に関する追加のメモを追加しました。2)空のリストの合計は0です。非陽性ルールにより、として評価されます1
Mego

わかりましたが、中間結果としては大丈夫ですか?そう[1,2]_([1]_[1])です[1,2]か?
クリスチャンシーバーズ

もたらす@ChristianSievers号[2]ので、[1]_[1] -> [] -> 0 -> 1 -> [1]
Mego

回答:


9

Python 3、803 788 753 749 744 748 745 740 700 695 682バイト

exec(r'''from random import*
import re
class k(int):
 p=0;j=Xl([d(randint(1,int(b)),b)Zrange(a)]);__mul__=Xl(sorted(Y)[:b]);__matmul__=Xl(sorted(Y)[-b:]);__truediv__=Xl([d(randint(1,int(_.i)),_.i)if _==b else _ ZY]);__sub__=Xk(max(1,int.__sub__(a,b)))
 def __mod__(a,b):
  x=[]
  while x!=Y:x=Y;a=a/b
  Wl(x)
 def V:
  if b.p:p=b.p;del b.p;Wl(Y+b.l)if~-p else l([_ZY if~-(_ in b.l)])
  Wk(int.V)
 def __neg__(a):a.p+=1;Wa
def l(x):a=k(sum(x)or 1);Y=x;Wa
def d(v,i):d=k(v);d.i=i;Wd
lambda a:eval(re.sub("(\d+)","(k(\\1))",a).translate({100:".j",116:"*",84:"@",114:"/",82:"%",46:"+--",95:"+-"}))'''.translate({90:" for _ in ",89:"a.l",88:"lambda a,b:",87:"return ",86:"__add__(a,b)"}))

Mr.Xcoderのおかげで-5バイト

NGNにより-5バイト増加

-ジョナサン・フレンチのおかげで約40バイト

なんてこったい!これは、正規表現を使用してkクラス内のすべての数値をラップし、すべての演算子をPythonが理解できる演算子に変換してから、kクラスの魔法のメソッドを使用して数学を処理することで機能します。ために最後にして、正しい優先度を維持するためのハックです。同様に、私が使用することはできませんそうすることになるだろうので日間オペレータをとして解析します。代わりに、メソッド呼び出しは演算子よりも優先順位が高いため、すべての数値を余分な括弧で囲み、d asを実行します。最後の行は、式を評価する匿名関数として評価されます。+-+--._**1d4d41d(4d4).j


def __mod__(a, b)...なぜ、間にスペースa,b
ミスターXcoder


@ Mr.Xcoder不要なスペースを削除することでバイトを節約できると思います; __sub__。そして、おそらくまた、ここではlambda a,b: l(
ジョナサンフレッチ

1
コード全体をexec("""...""".replace("...","..."))ステートメントでラップし、頻繁に発生する文字列(などreturn )を単一の文字に置き換えることで、バイトを節約できます。しかし、私にexec-strategyは常に...ビットunelegantだ
ジョナサンFRECH

遺体__mod____add__必要としないことくらいインデント
NGN

3

APL(Dyalog Classic)、367バイト

d←{(⊢⍪⍨1+?)⍉⍪⊃⍴/⊃¨+/¨⍺⍵}⋄r←{z←⊣⌿⍺⋄((m×?n)+z×~m←z∊⊣⌿⍵)⍪n←⊢⌿⍺}⋄R←{⍬≡⊃∩/⊣⌿¨⍺⍵:⍺⋄⍵∇⍨⍺r⍵}
u←{⍺[;((⊃+/⍵)⌊≢⍉⍺)↑⍺⍺⊣⌿⍺]}⋄t←⍋u⋄T←⍒u⋄A←+/,⋄S←+/,∘-⋄C←,⋄D←{⍺/⍨~⊃∊/⊣⌿¨⍺⍵}
hv←⍬⋄o'drRtT+-._'f←{8<io⍳⊃⍵:0v⊢←(¯2v),(⍎i'drRtTASCD')/¯2v}
{⊃⍵∊⎕d:v,←⊂⍪2↑⍎⍵⋄'('=⍵:h,←⍵⋄')'=⍵:h↑⍨←i-1f¨⌽h↓⍨i←+/∨\⌽h='('⋄h,←⍵⊣h↓⍨←-i⊣f¨⌽h↑⍨-i←+/\⌽≤/(1 4 4 1/⌽⍳4)[o⍳↑⍵,¨h]}¨'\d+' '.'s'&'⊢⍞
f¨⌽h1⌈+/⊣⌿⊃v

オンラインでお試しください!

これは、に統合されたリファレンス実装からのシャンティングヤードアルゴリズムでありevaluate_dice()、不要なオブジェクト指向のナンセンスはありません。h演算子とv値の2つのスタックのみが使用されます。解析と評価はインターリーブされます。

中間結果は2×N行列として表されます。最初の行はランダムな値で、2番目の行はそれらを生成したサイコロの辺の数です。サイコロを投げる「d」演算子によって結果が生成されない場合、2行目には任意の数字が含まれます。単一のランダム値は2×1行列であるため、1要素リストと区別できません。


3

Pythonの3:723 722 714 711 707 675 653 665バイト

import re
from random import*
S=re.subn
e=eval
r=randint
s=lambda a:sum(g(e(a)))or 1
g=lambda a:next(zip(*a))
def o(m):a,o,b=m.groups();A=sorted(e(a));t=g(e(b));return str(o in"rR"and([([v,(r(1,d)*(o>"R")or choice([n+1for n in range(d)if~-(n+1in t)]))][v in t],d)for(v,d)in A])or{"t":A[:s(b)],"T":A[-s(b):],"+":[(s(a)+s(b),0)],"-":[(s(a)-s(b),0)],".":e(a)+e(b),"_":[t for t in e(a)if~-(t[0]in g(e(b)))]}[o])
def d(m):a,b=map(s,m.groups());return str([(r(1,b),b)for _ in" "*a])
p=r"(\[[^]]+\])"
def E(D):
 D,n=S(r"(\d+)",r"[(\1,0)]",D)
 while n:
  n=0
  for e in[("\(("+p+")\)",r"\1"),(p+"d"+p,d),(p+"([tTrR])"+p,o),(p+"(.)"+p,o)]:
   if n<1:D,n=S(*e,D)
 return s(D)

エントリポイントはEです。これは、正規表現を繰り返し適用します。最初に、すべての整数xをシングルトンリストtuple に置き換えます[(x,0)]。次に、最初の正規表現は、dすべて[(x,0)]d[(b,0)]をのようなタプルの配列の文字列表現で置き換えることにより、操作を実行します[(1,b),(2,b),(3,b)]。各タプルの2番目の要素は、への2番目のオペランドdです。次に、後続の正規表現が他の各演算子を実行します。完全に計算された式から括弧を削除するための特別な正規表現があります。


3

Clojure、731 720バイト

(改行が削除されるとき)

更新:のより短い実装F

(defn N[i](if(seq? i)(apply + i)i))
(defn g[i](let[L(fn[i](let[v(g i)](if(seq? v)v(list v))))R remove T take](if(seq? i)(let[[o a b :as A]i](if(some symbol? A)(case o d(repeatedly(N(g a))(fn[](inc(rand-int(N(g b))))))t(T(N(g b))(sort(g a)))T(T(N(g b))(sort-by -(g a)))r(for[i(L a)](if((set(L b))i)(nth(L a)0)i))R(T(count(L a))(R(set(L b))(for[_(range)i(L a)]i)))+(+(N(g a))(N(g b)))-(-(N(g a))(N(g b))).(into(L a)(L b))_(R(set(L b))(g a)))A))i)))
(defn F[T](if(seq? T)(if(next T)(loop[[s & S]'[_ . - + R r T t d]](let[R reverse[b a](map R(split-with(comp not #{s})(R T)))a(butlast a)](if a(cons s(map F[a b]))(recur S))))(F(first T)))T))
(defn f[i](N(g(F(read-string(clojure.string/replace(str"("i")")#"[^0-9]"" $0 "))))))

これは4つの主要な部分で構成されます。

  • N:リストを数値に強制します
  • g:抽象構文ツリーを評価します(3項目のS式)
  • F:中置ASTを接頭辞表記(S式)に変換し、オペランドの優先順位も適用します
  • fread-string文字列を数字と記号のネストされたシーケンス(中置AST)に変換し、それらをF-> g-> Nにパイプして、結果番号を返します。

私はこれを徹底的にテストする方法がわからない、おそらくリファレンス実装に対する統計テストを介して?少なくともASTとその評価は比較的簡単です。

以下のS式の例1d((8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3))

(. (d 1 (- (d (T (t (d 8 20) 4) 2)
              (R (d 6 6) (r 1 6)))
           (+ (d 2 4)
              (d 1 2))))
   (d 1 (_ (d 4 6) (d 3 3))))

中間結果とテストでゴルフが少ない:

(def f #(read-string(clojure.string/replace(str"("%")")#"[^0-9]"" $0 ")))

(defn F [T]
  (println {:T T})
  (cond
    (not(seq? T))T
    (symbol?(first T))T
    (=(count T)1)(F(first T))
    1(loop [[s & S] '[_ . - + R r T t d]]
      (let[[b a](map reverse(split-with(comp not #{s})(reverse T)))
           _ (println [s a b])
           a(butlast a)]
        (cond
          a(do(println {:s s :a a :b b})(cons s(map F[a b])))
          S(recur S))))))


(->> "3d6" f F)
(->> "3d6t2" f F)
(->> "3d2R1" f F)
(->> "1d4d4" f F)
(->> "2d6.2d6" f F)
(->> "(3d2R1)d2" f F)
(->> "1d((8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3))" f F)

(defn N[i](if(seq? i)(apply + i)i))

(defn g[i]
  (let[L(fn[i](let[v(g i)](if(seq? v)v(list v))))]
    (if(seq? i)
      (let[[o a b :as A] i]
        (println {:o o :a a :b b :all A})
        (if(every? number? A)(do(println{:A A})A)
           (case o
            d (repeatedly(N (g a))(fn[](inc(rand-int(N (g b))))))
            t (take(N (g b))(sort(g a)))
            T (take(N (g b))(sort-by -(g a)))
            r (for[i(L a)](if((set(L b))i)(nth(L a)0)i))
            R (take(count(g a))(remove(set(L b))(for[_(range)i(g a)]i)))
            + (+(N (g a))(N (g b)))
            - (-(N (g a))(N (g b)))
            . (into(L a)(L b))
            _ (remove(set(L b))(g a)))))
      (do(println {:i i})i))))


(g '(. (d 3 5) (d 4 3)))
(g '(. 1 (2 3)))
(g '(+ 1 (2 3)))
(g '(R (d 10 5) (d 1 3)))
(g '(T (d 5 20) 3))
(g '(t (d 5 20) 3))
(g '(d (d 3 4) 10))
(g '(d 4 3))
(g '(_ (d 4 6) (d 3 3)))

(->> "1d(4d6_3d3)" f F g)
(->> "1r6" f F g)
(->> "(8d20t4T2)d(6d6R1r6)" f F g)
(->> "(8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3)" f F g)
(->> "1d((8d20t4T2)d(6d6R1r6)-2d4+1d2).(1d(4d6_3d3))" f F g))

2

Python 3、695バイト

import random,tatsu
A=lambda x:sum(x)or 1
H=lambda x:[[d,D(d.s)][d in x[2]]for d in x[0]]
R=lambda x:R([H(x)]+x[1:])if{*x[0]}&{*x[2]}else x[0]
class D(int):
 def __new__(cls,s):o=super().__new__(cls,random.randint(1,s));o.s = s;return o
class S:
 o=lambda s,x:{'+':[A(x[0])+A(x[2])],'-':[A(x[0])-A(x[2])],'.':x[0]+x[2],'_':[d for d in x[0]if d not in x[2]]}[x[1]]
 f=lambda s,x:{'r':H(x),'R':R(x),'t':sorted(x[0])[:A(x[2])],'T':sorted(x[0])[-A(x[2]):]}[x[1]]
 d=lambda s,x:[D(A(x[2]))for _ in' '*A(x[0])]
 n=lambda s,x:[int(x)]
 l=lambda s,x:sum(x,[])
lambda i:tatsu.parse("s=e$;e=o|t;o=e/[-+._]/t;t=f|r;f=t/[rRtT]/r;r=d|a;d=r/d/a;a=n|l|p;n=/\d+/;l='['@:','.{n}']';p='('@:e')';",i,semantics=S())

tatsu、PEGパーサーライブラリを使用して構築されたインタープリター。への最初の引数tatsu.parser()はPEG文法です。

class D(Dieの場合)組み込みint型をサブクラス化します。値は、ロールの結果です。属性.sは、ダイスの辺の数です。

class S パーサーのセマンティックアクションを持ち、インタープリターを実装します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.