ถัดไปคืออะไร


15

รับรายการจำนวนเต็มคั่นด้วยช่องว่างงานของคุณคือค้นหาจำนวนเต็มถัดไปในลำดับ จำนวนเต็มในแต่ละลำดับเป็นผลมาจากการใช้การคำนวณทางคณิตศาสตร์เดียว (คน+, -, *หรือ/) เป็นจำนวนเต็มก่อนหน้านี้และแต่ละลำดับถูกสร้างขึ้นจากจำนวนตัวแปรของการดำเนินการเช่น ( แต่ไม่เกิน 10) ไม่มีลำดับใดที่จะยาวกว่าครึ่งหนึ่งของลำดับเลขจำนวนเต็มดังนั้นคุณจะมีลำดับการดำเนินการแต่ละรายการปรากฏขึ้นอย่างน้อยสองครั้งเพื่อยืนยัน
ข้อมูลที่ป้อนจะผ่าน stdin (หรือpromptสำหรับโซลูชัน JavaScript)

นี่คือตัวอย่างที่อธิบาย

การป้อนข้อมูล:

1 3 5 7 9 11

เอาท์พุท:

13

ค่อนข้างง่ายคนนี้ +2ค่าทั้งหมดเป็นค่าก่อนหน้านี้

การป้อนข้อมูล:

1 3 2 4 3 5 4 6 5 7 6

ouput:

8

ขั้นตอนที่สองในลำดับนี้แล้ว+2-1

การป้อนข้อมูล:

2 6 7 3 9 10 6 18 19 15 45 46

เอาท์พุท:

42

สามขั้นตอน *3- +1, -4,

กรณีทดสอบ

ต่อไปนี้เป็นกรณีทดสอบเพิ่มเติมเล็กน้อย:

การป้อนข้อมูล:

1024 512 256 128 64 32 16

เอาท์พุท:

8

การป้อนข้อมูล:

1 3 9 8 24 72 71 213 639

เอาท์พุท:

638

การป้อนข้อมูล:

1 2 3 4 5 2 3 4 5 6 3 4 5 6 7

เอาท์พุท:

4

การป้อนข้อมูล:

1 2 4 1 3 9 5 8 32 27 28 56 53 55 165 161 164 656 651 652 1304

เอาท์พุท:

1301

ฉันมีวิธีแก้ปัญหาสกาล่าที่ไม่ดี (42 บรรทัด) ที่ฉันจะโพสต์ในอีกสองสามวัน

นี่คือ code-golf - คำตอบที่สั้นที่สุดชนะ


รับประกันการแบ่งเป็นที่แน่นอน?
Peter Taylor

@Peter ใช่ ทุกขั้นตอนจะส่งผลเป็นจำนวนเต็ม
Gareth

แต่ถ้าขั้นตอนเป็น "/ 3" จะรับประกันได้หรือไม่ว่าส่วนที่เหลือจะเป็น 0 เสมอหรือไม่
Peter Taylor

@Peter ใช่ส่วนที่เหลือจะเป็น 0 เสมอ
Gareth

คำตอบ:


12

Golfscript, 203 138 ตัวอักษร

~]0{).2$.);[\(;]zip\/zip{.{~-}%.&({-}+\{;{.0={.~\%{.~%{;0}{~/{/}+}if}{~\/{*}+}if}{~!{;}*}if}%.&(\{;;0}/}{\;}if}%.{!}%1?)!{0}*}do\@)\,@%@=~

สิ่งนี้ใช้ifมากกว่าโปรแกรม Golfscript มาตรฐานและการดำเนินการของมันค่อนข้างลึกลับดังนั้นนี่คือความคิดเห็น (แต่ไม่ ungolfed นอกเหนือจากการเพิ่มช่องว่างและความคิดเห็น):

~]0
# Loop over guesses L for the length of the sequence
{
    # [x0 ... xN] L-1
    ).
    # [x0 ... xN] L L
    2$.);[\(;]zip
    # [x0 ... xN] L L [[x0 x1][x1 x2]...[x{N-1} xN]]
    \/zip
    # [x0 ... xN] L [[[x0 x1][xL x{L+1}]...][[x1 x2][x{L+1} x{L+2}]...]...]
    {
        # [x0 ... xN] L [[xi x{i+1}][x{i+L} x{i+L+1}]...]
        # Is there an operation which takes the first element of each pair to the second?
        # Copy the pairs, work out each difference, and remove duplicates
        .{~-}%.&
        # Turn the first difference into an operation
        ({-}+\
        # If there was more than one unique difference, look for a multiplication
        {
            ;
            # [x0 ... xN] L [[xi x{i+1}][x{i+L} x{i+L+1}]...]
            # Do something similar, but working out multiplicative factors
            # Note that if we have [0 0] it could be multiplication by anything, so we remove it.
            # However, they can't all be [0 0] or we'd have only one unique difference
            {
                # [0     0   ] =>
                # [0     _   ] => 0     # a "false" value, because it can't possibly be multiplication
                # [a     a.b'] => {b'*}
                # [a'.b  b   ] => {a'/}
                # [_     _   ] => 0     # ditto
                # This is the obvious place to look for further improvements
                .0={.~\%{.~%{;0}{~/{/}+}if}{~\/{*}+}if}{~!{;}*}if
            }%.&
            # If we have one unique multiplication, even if it's false, keep it.
            # Otherwise discard them and replace them with false.
            (\{;;0}/
        }
        # There was only one unique difference. Discard the pairs
        {\;}if
        # operation - one of 0, {d+}, {m*}, {M/}
    }%
    # [x0 ... xN] L [op0 ... op{L-1}]
    # Is any of the operations false, indicating that we couldn't find a suitable operation?
    .{!}%1?
    # [x0 ... xN] L [op0 ... op{L-1}] idxFalse
    # If idxFalse is -1 then all the ops are ok, and we put a false to exit the loop
    # Otherwise one op failed, so we leave the array of ops, which is non-false, to be popped by the do.
    )!{0}*
}do
# [x0 ... xN] L [op0 ... op{L-1}]
\@)\,@%@=~
# op{(len(Xs)-1)%L} (Xs[-1])

การส่งต้นฉบับของฉันคือต่อไปนี้ที่ 88 ตัวอักษร:

~]:x;2.{;).(2base(;{[{--}{@*\.!+/}]=}%[x.(;2$]zip\,<{~++}%x,.@[*x\]zip<{~~}%)\x(;=!}do\;

อย่างไรก็ตามสิ่งนี้พยายามที่จะคำนวณการดำเนินการจากการเกิดขึ้นครั้งแรกของแต่ละครั้งดังนั้นหากการดำเนินการเป็นการคูณหรือการหารและการโต้แย้งรอบแรกเป็น 0 มันจะแบ่ง


1
ขอบคุณมากสำหรับการโพสต์คำอธิบาย! ฉันกำลังมองหาโปรแกรม Golfscript ที่ผ่านการตรวจสอบมาแล้วเพื่อที่ฉันจะสามารถเข้าใจได้มากขึ้น
migimaru

6

Haskell, 276 261 259 257 243 ตัวอักษร

นี่คือทางออกที่ไม่มีประสิทธิภาพของฉัน มันทำงานบนจำนวนเต็ม (และ จำกัด ) ไม่ จำกัด การแก้ปัญหานี้เกิดขึ้นในการทำงานอย่างถูกต้องกับส่วนที่ไม่แน่นอน (เช่น5 / 2 = 2)

import Control.Monad
main=interact$show.n.q read.words
f=flip
q=map
_%0=0
x%y=div x y
s b=[1..]>>=q cycle.(f replicateM$[(+),(*),(%)]>>=f q[-b..b].f)
m l x s=[y!!l|y<-[scanl(f($))(x!!0)s],x==take l y]
n x=(s(maximum$q abs x)>>=m(length x)x)!!0

มันทำงานอย่างไร: ฉันสร้างลำดับการดำเนินการ (เป็นไปได้) ที่เป็นไปได้ทั้งหมด จากนั้นฉันจะทดสอบกับลำดับของตัวเลขเพื่อดูว่าลำดับที่สร้างขึ้นจะสร้างอินพุตหรือไม่ หากเป็นเช่นนั้นให้ส่งคืนหมายเลขถัดไปตามลำดับ รหัสจะส่งคืนคำตอบที่ได้รับจากลำดับการดำเนินการที่สั้นที่สุดเสมอ สิ่งนี้เกิดขึ้นเนื่องจากมีการสร้างรายการลำดับการดำเนินการตามลำดับ มันเป็นเรื่องของการตัดสินใจระหว่างความผูกพัน ตัวอย่างเช่นผลตอบแทนรหัส6หรือสำหรับลำดับ82 4

Ungolfed:

import Control.Monad

main :: IO ()
main = print . next . map read . words =<< getLine

opSequences :: Integral a => a -> [[a -> a]]
opSequences bound = [1 ..] >>= map cycle . (`replicateM` (ops >>= (`map` args) . flip))
  where
    ops = [(+), (*), \x y -> if y == 0 then 0 else div x y]
    args = [-bound .. bound]

match :: (MonadPlus m, Integral a) => [a] -> [a -> a] -> m a
match ns opSeq = guard (ns == take len ms) >> return (ms !! len)
  where
    n0 = ns !! 0
    len = length ns
    ms = scanl (flip ($)) n0 opSeq

next :: Integral a => [a] -> a
next ns = (opSequences bound >>= match ns) !! 0
  where
    bound = maximum $ map abs ns

แนวคิดที่ดีสำหรับวิธีจัดการกับการแบ่งที่ไม่แน่นอน
ปีเตอร์เทย์เลอร์

มันเป็นผลข้างเคียงจากอุบัติเหตุ การค้นหาวิธีแก้ไขเป็นเพียงแนวคิดเริ่มต้นของฉันในการแก้ปัญหานี้สำหรับฉันฉันรู้สึกว่าเป็นงานที่ง่ายกว่าการคำนวณคำตอบ
Thomas Eding

เป็นControl.Monad -> Monadไปได้ไหม และวิธีการเกี่ยวกับinteract$show.n.q read.words
FUZxxl

6

Python, 333 366 ... 315 303 278 269 261 246 ตัวอักษร

n=map(float,raw_input().split())
y=len(n)-1
l=1
def O(f):
 p,q=n[f:y:l],n[f+1::l]
 for a,b in zip(p,q):
    for x in((b-a).__add__,(b/(a or 1)).__mul__):
     if map(x,p)==q:return x
while 1:
 if all(map(O,range(l))):print int(O(y%l)(n[y]));break
 l+=1

สร้างการทำงานด้วยตัวเลขคู่แรกและตรวจสอบกับคู่อื่น ๆ เก็บการดำเนินการทั้งหมดและหากการดำเนินการทั้งหมดสำเร็จแล้วให้ใช้การดำเนินการที่เหมาะสมในรายการองค์ประกอบสุดท้าย

แก้ไข: ผ่านการทดสอบความชั่วร้าย :-) ตอนนี้ค้นหาการดำเนินงานในทุกตำแหน่ง


ดี ผ่านการทดสอบของฉันทั้งหมด แต่ไม่ได้ปีเตอร์เทย์เลอร์เป็นความชั่วร้ายโดยเฉพาะอย่างยิ่งที่หนึ่ง:0 0 1 2 3 6 7 14
แกเร็ ธ

0 0 0 0 1 0 0 0 0 10ไม่ออก
Thomas Eding

@trinithis อินพุตนั้นไม่เป็นไปตามข้อกำหนด ลำดับของการดำเนินการต้องทำซ้ำอย่างสมบูรณ์อย่างน้อยหนึ่งครั้ง
Gareth

1
โอ้นี่คือการปรับปรุงความสนุก: ->lambda x:x+b-a (b-a).__add__น่าเสียดายที่มันมีเพียงตัวละครตัวเดียวฉันเรียนรู้เกี่ยวกับหลามอย่างมากโดยทำสิ่งเหล่านี้
Clueless

1
การทำให้lทั่วโลกโดยปริยายช่วยประหยัดได้มาก: pastie.org/2416407
Clueless

4

Python, 309 305 295 279 ตัวอักษร

จัดการกับกรณีทดสอบต้นฉบับทั้งหมดรวมถึงกรณีที่ปีเตอร์เทย์เลอร์เป็นปรกติ0 0 1 2 3 6 7 14:

l=map(int,raw_input().split())
i=v=0
while v<1:
 v=i=i+1
 for j in range(i):
    p=zip(l[j::i],l[j+1::i])
    d,r=set(q[1]-q[0]for q in p),set(q[1]*1./(q[0]or 1)for q in p if any(q))
    m,n=len(d)<2,len(r)<2
    v*=m+n
    if(len(l)-1)%i==j:s=l[-1]+d.pop()if m else int(l[-1]*r.pop())
print s

Ungolfed พร้อมเอาต์พุตการดีบัก (มีประโยชน์มากในการตรวจสอบความถูกต้อง):

nums = map(int,raw_input().split())
result = None

for i in range(1,len(nums)/2+1):
    print "-- %s --" % i
    valid = 1
    for j in range(i):
        pairs = zip(nums[j::i], nums[j+1::i])
        print pairs

        diffs = [pair[1] - pair[0] for pair in pairs]
        # this is the tough bit: (3, 6) -> 2, (0, 5) -> 5, (5, 0) -> 0, (0, 0) ignored
        ratios = [float(pair[1])/(pair[0] or 1) for pair in pairs if pair[0] != 0 or pair[1] != 0]

        if len(set(diffs))==1:
            print "  can be diff", diffs[0]
            if (len(nums) - 1) % i == j:
                result = nums[-1] + diffs.pop()
        elif len(set(ratios))==1:
            print "  can be ratio", ratios[0]
            if (len(nums) - 1) % i == j:
                result = int(nums[-1]*ratios.pop())
        else:
            print "** invalid period **"
            valid=0
    if valid and result is not None:
        break

print result

การใช้งาน:

echo 0 0 1 2 3 6 7 14 | python whatcomesnext.py

ฉัน upvoted แม้ว่าพูดอย่างเคร่งครัดอินพุตควรจะผ่าน stdin มากกว่าอาร์กิวเมนต์คำสั่ง
Gareth

ที่จริงให้ผมสั้นลงโปรแกรมโดยสี่ตัวอักษร :)
บื้

ไม่กี่ตัวอักษร i = v = 0 และในขณะที่ v == 0:
Ante

@Ante ขอบคุณฉันคิดว่าคุณไม่สามารถทำเช่นนั้นในงูหลามเพราะการมอบหมายไม่ใช่การแสดงออก แต่มันเป็นอาหารอันโอชะที่เป็นประโยชน์สำหรับการเล่นกอล์ฟ แท็บตัวอักษรเป็นการเยื้องระดับที่สองก็ช่วยได้เช่นกัน
Clueless

ฉันไม่ใช่ Pythoner แต่คุณดูเหมือนจะใช้ booleans เป็นจำนวนเต็มในการแสดงออกบางอย่างและยังไม่สามารถใช้จำนวนเต็ม v เป็นบูลีนในการทดสอบในขณะที่ นั่นถูกต้องใช่ไหม? ถ้าเป็นเช่นนั้นแน่นอนv<1ทำงานเป็นยาม
Peter Taylor

2

ทับทิม 1.9 (437) (521) (447) (477)

ใช้งานได้กับทุกกรณีทดสอบรวมถึง "ความชั่วร้าย" ฉันจะตีกอล์ฟทีหลัง

แก้ไข: ฉันรู้ว่ามีอีกกรณีที่ฉันจัดการไม่ถูกต้อง - เมื่อความต่อเนื่องต้องใช้การดำเนินการ "ลึกลับ" ลำดับ2 0 0 -2 -4 -6เริ่มต้นส่งคืน 0 แทน -12 ตอนนี้ฉันได้แก้ไขแล้ว

แก้ไข: แก้ไขกรณีขอบอีกสองสามและลดรหัสเป็น 447

แก้ไข: ฮึ มีการเพิ่มรหัสเพื่อจัดการลำดับ "ความชั่วร้าย" อื่น ๆ เช่น0 0 0 6 18 6 12

def v(c,q);t=*q[0];q.size.times{|i|f=c[z=i%k=c.size]
f=c[z]=(g=q[z+k])==0??_:((h=q[z+k+1])%g==0?"*(#{h/g})":"/(#{g/h})")if f==?_
t<<=f==?_?(a=q[i];b=q[i+1].nil?? 0:q[i+1];(a==0&&b==0)||(a!=0&&(b%a==0||a%b==0))?b:0):eval(t.last.to_s+f)}
*r,s=t
(p s;exit)if q==r
end
s=gets.split.map &:to_i
n=[[]]
((s.size-1)/2).times{|i|a,b=s[i,2]
j=["+(#{b-a})"]
j<<=?_ if a==0&&b==0
j<<="*#{b/a}"if a!=0&&b%a==0
j<<="/#{a/b}"if a*b!=0&&a%b==0
n=n.product(j).map(&:flatten)
n.map{|m|v(m*1,s)}}

1

สกาล่า

นี่คือวิธีแก้ปัญหาที่ฉันได้รับ:

object Z extends App{var i=readLine.split(" ").map(_.toInt)
var s=i.size
var(o,v,f)=(new Array[Int](s),new Array[Double](s),1)
def d(p:Int,j:Array[Int]):Unit={if(p<=s/2){def t(){var a=new Array[Int](s+1)
a(0)=i(0)
for(l<-0 to s-1){o(l%(p+1))match{case 0=>a(l+1)=a(l)+v(l%(p+1)).toInt
case _=>a(l+1)=(a(l).toDouble*v(l%(p+1))).toInt}}
if(a.init.deep==i.deep&&f>0){f^=f
println(a.last)}}
o(p)=0 
v(p)=j(1)-j(0)
t
d(p+1,j.tail)
o(p)=1
v(p)=j(1).toDouble/j(0).toDouble
t
d(p+1,j.tail)}}
d(0,i)
i=i.tail
d(0,i)}

Ungolfed:

object Sequence extends App
{
    var input=readLine.split(" ").map(_.toInt)
    var s=input.size
    var (ops,vals,flag)=(new Array[Int](s),new Array[Double](s),1)
    def doSeq(place:Int,ints:Array[Int]):Unit=
    {
        if(place<=s/2) 
        {
            def trysolution()
            {
                var a=new Array[Int](s+1)
                a(0)=input(0)
                for(loop<-0 to s-1)
                {
                    ops(loop%(place+1))match
                    {
                        case 0=>a(loop+1)=a(loop)+vals(loop%(place+1)).toInt
                        case _=>a(loop+1)=(a(loop).toDouble*vals(loop%(place+1))).toInt
                    }
                }
                if(a.init.deep==input.deep&&flag>0)
                {
                    flag^=flag
                    println(a.last)
                }
            }
            ops(place)=0
            vals(place)=ints(1)-ints(0)
            trysolution
            doSeq(place+1,ints.tail)
            ops(place)=1
            vals(place)=ints(1).toDouble/ints(0).toDouble
            trysolution
            doSeq(place+1,ints.tail)
        }
    }
    doSeq(0,input)
    input=input.tail
    doSeq(0,input)
}

ฉันจะเรียกมันได้อย่างไร echo "0 0 1 2 3 6 7 14" | scala Sequenceทำให้หน้าจอเป็นสีดำ
ผู้ใช้ที่ไม่รู้จัก

@ ผู้ใช้ที่ไม่รู้จักscala Sequenceจากนั้นป้อนลำดับและกด Enter
Gareth

อาคุณเขียนความคิดเห็นในคำถามว่าคุณไม่ได้แก้ปัญหาเฉพาะนี้ - มันทำงานได้กับ echo - pipe ดังกล่าวข้างต้นสำหรับคำถามที่แก้ไขได้
ผู้ใช้ไม่รู้จัก

1

สกาล่า 936

type O=Option[(Char,Int)]
type Q=(O,O)
type L=List[Q]
val N=None
def t(a:Int,b:Int):Q=if(a>b)(Some('-',a-b),(if(b!=0&&b*(a/b)==a)Some('/',a/b)else N))else
(Some('+',b-a),(if(a!=0&&a*(b/a)==b)Some('*',b/a)else N))
def w(a:Q,b:Q)=if(a._1==b._1&&a._2==b._2)a else
if(a._1==b._1)(a._1,N)else
if(a._2==b._2)(N,a._2)else(N,N)
def n(l:L):Q=l match{case Nil=>(N,N)
case x::Nil=>x
case x::y::Nil=>w(x,y)
case x::y::xs=>n(w(x,y)::xs)} 
def z(l:L,w:Int)=for(d<-1 to w)yield
n(l.drop(d-1).sliding(1,w).flatten.toList)
def h(s:L):Boolean=s.isEmpty||(s(0)!=(N,N))&& h(s.tail)
def j(s:L,i:Int=1):Int=if(h(z(s,i).toList))i else j(s,i+1)
def k(b:Int,o:Char,p:Int)=o match{case'+'=>b+p
case'-'=>b-p
case'*'=>b*p
case _=>b/p}
val e=getLine 
val i=e.split(" ").map(_.toInt).toList
val s=i.sliding(2,1).toList.map(l=>t(l(0),l(1)))
val H=n(s.drop(s.size%j(s)).sliding(1,j(s)).flatten.toList)
val c=H._1.getOrElse(H._2.get)
println (k(i(i.size-1),c._1,c._2))

ungolfed:

type O = Option[(Char, Int)]

def stepalize (a: Int, b: Int): (O, O) = (a > b) match {
   case true => (Some('-', a-b), (if (b!=0 && b * (a/b) == a) Some ('/', a/b) else None)) 
   case false=> (Some('+', b-a), (if (a!=0 && a * (b/a) == b) Some ('*', b/a) else None)) }

def same (a: (O, O), b: (O, O)) = {
  if (a._1 == b._1 && a._2 == b._2) a else
  if (a._1 == b._1) (a._1, None) else 
  if (a._2 == b._2) (None, a._2) else 
  (None, None)}

def intersection (lc: List[(O, O)]): (O, O) = lc match {
  case Nil => (None, None)
  case x :: Nil => x
  case x :: y :: Nil => same (x, y)
  case x :: y :: xs  => intersection (same (x, y) :: xs)} 

def seriallen (lc: List[(O, O)], w: Int= 1) =
  for (d <- 1 to w) yield 
    intersection (lc.drop (d-1).sliding (1, w).flatten.toList)

def hit (s: List[(O, O)]) : Boolean = s match {
  case Nil => true 
  case x :: xs => (x != (None, None)) && hit (xs)}

def idxHit (s: List[(O, O)], idx: Int = 1) : Int =
  if (hit (seriallen (s, idx).toList)) idx else 
    idxHit (s, idx+1)

def calc (base: Int, op: Char, param: Int) = op match {
  case '+' => base + param
  case '-' => base - param
  case '*' => base * param
  case _   => base / param}

def getOp (e: String) = {
  val i = e.split (" ").map (_.toInt).toList
  val s = i.sliding (2, 1).toList.map (l => stepalize (l(0), l(1)))
  val w = idxHit (s)
  val hit = intersection (s.drop (s.size % w).sliding (1, w).flatten.toList)
  val ci = hit._1.getOrElse (hit._2.get)
  val base = i(i.size - 1)
  println ("i: " + i + " w: " + w + " ci:" + ci + " " + calc (base, ci._1, ci._2))
}

val a="1 3 5 7 9 11"
val b="1 3 2 4 3 5 4 6 5 7 6"
val c="2 6 7 3 9 10 6 18 19 15 45 46"
val d="1024 512 256 128 64 32 16"
val e="1 3 9 8 24 72 71 213 639"
val f="1 2 3 4 5 2 3 4 5 6 3 4 5 6 7"
val g="1 2 4 1 3 9 5 8 32 27 28 56 53 55 165 161 164 656 651 652 1304"
val h="0 0 1 2 3 6 7 14"
val i="0 0 0 0 1 0 0 0 0 1 0"

List (a, b, c, d, e, f, g, h, i).map (getOp)

ล้มเหลวอย่างน่าสังเวชของ Peter Taylor hแต่ฉันไม่เห็นความเป็นไปได้ในการรักษาโปรแกรมในระยะเวลาที่เหมาะสม


มันจะช่วยการหดถ้าคุณได้รับการปฏิบัติ-เป็นกรณีพิเศษ+และ/เป็นกรณีพิเศษของ*? วิธีที่ฉันส่งผ่านอินพุต (และที่คล้ายกัน) ของปีเตอร์เทย์เลอร์คือตัดหมายเลขแรกในลำดับแล้วลองอีกครั้ง ฉันไม่ได้มีเวลาดูว่าโปรแกรมของคุณทำงานยังไม่รู้ว่าจะช่วยให้คุณ
Gareth

ฉันเดาว่ามันจะช่วยได้ แต่สำหรับกรณีพิเศษนั้นเท่านั้น ซีรีส์ที่มีการคูณด้วยโมฆะในภายหลังเช่น-1, 0, 0, 1, 2, 3, 6, 7, 14จะต้องมีการรักษาที่แตกต่างกัน
ผู้ใช้ไม่รู้จัก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.