ตรวจสอบว่าสตริงทำจากสตริงย่อยเดียวกันทั้งหมดหรือไม่


24

สิ่งนี้นำมาจากคำถามนี้ (ได้รับอนุญาตจากหลักสูตร) ฉันจะพูด:

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

ตัวอย่างบางส่วน:

'aa' //true
'aaa' //true
'abcabcabc' //true
'aba' //false
'ababa' //false
'weqweqweqweqweqw' // false

โดยเฉพาะอย่างยิ่งการตรวจสอบสตริงที่ประกอบด้วยสตริงย่อยที่ซ้ำกัน ( อัพเดต ) สามารถส่งเอาต์พุตการแสดงใด ๆ ที่เป็นจริงหรือเท็จได้ สตริงตัวอักษรผสมตัวเลขอย่างเคร่งครัด มิฉะนั้นกฎรหัสมาตรฐานกอล์ฟ นี่คือ Code Golf ดังนั้นคำตอบสั้น ๆ เป็นไบต์สำหรับแต่ละภาษาที่ชนะ


4
หืมฉันจะปิดการท้าทายนี้ในฐานะล่อลวงของอันนั้น แต่ฉันสังเกตเห็นว่าอีกอันหนึ่งให้คะแนนตามจำนวนตัวละคร ดังนั้นบางทีเราควรปิดอีกอันหนึ่ง (มันก็มีคำตอบที่ยอมรับได้) เป็นคู่หูของอันนี้แทน
Erik the Outgolfer

ขอให้เรายังคงอภิปรายนี้ในการแชท
Erik the Outgolfer

คำตอบ:


11

Brachylog , 4 3 ไบต์

ġ=Ṁ

ลองออนไลน์!

คำอธิบาย

ġ=Ṁ    Implicit input, say "abcabc"
ġ      Split into chunks of equal lengths (except maybe the last one): ["abc","abc"]
 =     Apply the constraint that all of the chunks are equal,
  Ṁ    and that there are multiple of them.

โปรแกรมจะพิมพ์true.หากข้อ จำกัด นั้นเป็นที่น่าพอใจและfalse.หากไม่เป็นเช่นนั้น


ฉันแค่พยายามดิ้นรนเพื่อให้ได้สิ่งที่ชอบ~j↙หรือ=Ṁcทำงานก่อนที่ฉันจะสังเกตเห็นว่าคุณโพสต์ข้อความนี้เมื่อชั่วโมงที่แล้ว
สตริงที่ไม่เกี่ยวข้อง

4
โอ้ใช่นี่อาจเป็นหนึ่งไบต์ที่สั้นกว่า:ġ=Ṁ
สตริงที่ไม่เกี่ยวข้อง

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

1
@ ไม่เกี่ยวข้องStringยอดเยี่ยมขอบคุณ! ฉันไม่คิดว่าจะตรวจสอบหน้าตัวแปร wiki
Zgarb

1
คำตอบที่ยอดเยี่ยมมากมายและคำตอบของ LUA มีสถานที่พิเศษในใจของฉัน คำตอบของ Arnauld นั้นอ่อนหวานเป็นพิเศษตั้งแต่คำถามดั้งเดิมที่ฉันอ้างอิงตาม (ไม่ใช่ dupe) นั้นถูกติดแท็ก Javascript จริง ๆ ส่วนใหญ่การเลือกอันนี้เพียงเพราะดูเหมือนว่าจะสั้นที่สุดโดยรวมสำหรับทุกภาษาและเป็นคำถามแรกของฉันฉันได้รับตรา
ouflak

19

JavaScript (ES6), 22 ไบต์

ส่งคืนค่าบูลีน

s=>/^(.*)\1+$/.test(s)

ลองออนไลน์!


หากไม่มีนิพจน์ทั่วไป 33  29 ไบต์

ส่งคืนnull(เท็จ) หรือวัตถุ (ความจริง)

s=>(s+s).slice(1,-1).match(s)

ลองออนไลน์!

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


9

grep, 19

grep -qxE '(.+)\1+'

ทดสอบ

while read; do 
  <<<"$REPLY" grep -qxE '(.+)\1+' && t="true" || t="false"
  echo "$REPLY: $t"
done < infile 

เอาท์พุท:

aa: true
aaa: true
abcabcabc: true
aba: false
ababa: false
weqweqweqweqweqw: false

9

Japtap , 6 ไบต์

²é ¤øU

บันทึกหนึ่งไบต์ด้วย @Shaggy

ลองออนไลน์!

        Implicit input, stored in variable 'U'
²       U+U, "abcabc" -> "abcabcabcabc"
 é      Rotate 1 char to the right "abcabcabcabc" -> "cabcabcabcab"
   ¤    Remove first two chars, "cabcabcabcab" -> "bcabcabcab"
    øU  Check if U is in the above

ดีมาก :) คุณสามารถแทนที่p<space>ด้วย²เพื่อบันทึกไบต์
ปุย

9

Java, 25 24 ไบต์

-1 ไบต์ขอบคุณ Olivier Grégoire!
คำตอบ regex น่าเบื่อ

s->s.matches("(.+)\\1+")

ลองออนไลน์!

มันยาวเกิน 1 python มากกว่าคำตอบหลาม aaaaaตอนนี้ฉันผูกแล้ว :)


3
คุณสามารถลบไฟล์สุดท้ายได้$เนื่องจากmatchesเมธอดนั้นเป็นการจับคู่ที่ตรงกันไม่ใช่การจับคู่สตริงย่อยตามค่าเริ่มต้น
Olivier Grégoire

ฉันลืมmatchesเพิ่มของตัวเอง$ลงใน regex ขอบคุณ!
Benjamin Urquhart

7

Excel, 26 ไบต์

=FIND(A1,A1&A1,2)<=LEN(A1)

อินพุตจาก A1 ส่งออกไปยังเซลล์ใด ๆ ที่คุณใส่สูตรนี้


คุณสามารถบันทึกได้ 4 ไบต์หากคุณกำหนดชื่อช่วงตัวอักษรเดี่ยว (เช่นA) และตั้งค่าเป็นข้อมูลของคุณ
i_saw_drones

@i_saw_drones - ฉันคิดว่าไม่ได้รับอนุญาตตามกฎ I / O มาตรฐาน: นี่คือลิงค์ไปยังคำตอบ metaที่จะใช้กับวิธีการนั้น ขณะนี้อยู่ที่ -36 คะแนน
Sophia Lechner

ขอโทษที่ฉันไม่ได้เห็นโพสต์นั้นถึงแม้ว่าจะคิดถึงมัน แต่ก็ไม่ได้A1เป็น "ตัวแปร" เนื่องจากมีค่าอินพุตอยู่หรือไม่ :)
i_saw_drones

1
ฉันจะรู้สึกอย่างนั้นถ้าฉันทำอะไรเป็นพิเศษกับความจริงที่ว่ามันเป็น A1 โดยเฉพาะเช่นถ้าฉันพึ่ง ROW (_) เป็น 1 อย่างใดอย่างหนึ่ง แต่ก็เป็นวิธีที่เป็นธรรมชาติที่สุดของการให้ฟังก์ชัน Excel ด้วย อินพุตโดยพลการ
Sophia Lechner

7

R , 28 ไบต์

grepl("(.+)\\1+$",scan(,''))

ลองออนไลน์!

รุ่น Regex ง่าย ๆ R คือ (บางครั้ง) คล้ายกับ Python ดังนั้นนี่จึงคล้ายกับคำตอบ Pex 2 regex ของ TFeld แม้ว่าจะสั้นกว่า!

คำถาม (ถ้าใครรู้คำตอบ)

ฉันยังคงสับสนว่าทำไมงานนี้เนื่องจากสตริงย่อยอาจมีความยาวเท่าใดก็ได้และจะทำงานตลอดเวลาและยังใช้ได้เมื่อฉันเพิ่มตัวอักษรที่ด้านหน้าของสตริงที่ถูกต้องเช่น "cABABABABAB" ถ้าฉันอ่าน regex เป็นการส่วนตัวฉันจะเห็น(.+)ว่ามันจับกลุ่มใดก็ได้ และจากนั้น\\1+$ซึ่งจะจับกลุ่มที่ถูกจับซ้ำหลาย ๆ ครั้งจนกระทั่งสิ้นสุด

เหตุใดจึงไม่จับเพียง "AB" และพบว่าซ้ำจนกระทั่งสิ้นสุดของสตริงโดยเฉพาะอย่างยิ่งเนื่องจากไม่มีข้อ จำกัด ที่ระบุว่าตำแหน่งย่อยสามารถเริ่มได้อย่างไร


1
น่าสนใจนี่น่าจะเป็นบั๊กในเอ็นจิ้น regex ของ R การเพิ่มตัวเลือกperl=TRUEทำให้ตรงกับ cABABAB ตามที่คุณคาดหวัง การทำงานgrep -E '(.*)\1+$'ใน bash นั้นจะตรงกับ cABABAB แม้ว่าจะgrep -Eใช้ ERE แต่ regex รส R เดียวกันก็ควรให้การสนับสนุน
Grimmy

2
ฉันเดาว่านี่เป็นการเพิ่มประสิทธิภาพที่ใช้อย่างไม่ถูกต้อง การเปลี่ยน.+ที่จุดเริ่มต้นของรูปแบบ^.+เป็นการเพิ่มประสิทธิภาพที่สำคัญ แต่ถ้า.+อยู่ภายในการจับภาพ parens มันจะหยุดใช้งานได้
Grimmy


6

เยลลี่ ,  5  4 ไบต์

ผมเห็นว่าตอนนี้วิธีที่ดีที่สุดคือการทำตามวิธีการของ XNOR !

Ḋ;Ṗw

ลิงก์ monadic ที่ยอมรับรายการของอักขระและแสดงผลเป็นจำนวนเต็ม - ความยาวที่สั้นที่สุดที่เป็นไปได้ของส่วนที่ซ้ำหรือศูนย์ถ้าไม่มี โปรดทราบว่าศูนย์เป็นเท็จในขณะที่ตัวเลขที่ไม่ใช่ศูนย์เป็นความจริงในเยลลี่

ลองออนไลน์!

อย่างไร?

Ḋ;Ṗw - Link: list of characters, S   e.g. "abcabcabc"   or "abababa"
Ḋ    - dequeue S                           "bcabcabc"       "bababa"
  Ṗ  - pop from S                         "abcabcab"       "ababab"
 ;   - concatenate                "bcabcabcabcabcab"       "bababaababab"
   w - first index of sublist     3  ^---here!             0  (not found)


4

Python 2 , 24 ไบต์

lambda s:s in(s*2)[1:-1]

ลองออนไลน์!

ขโมยอย่างไร้ยางอายจากคำตอบของ xnorต่อคำถามเดิม


รุ่นที่ใช้งานง่ายขึ้น:

Python 2 , 59 55 53 ไบต์

lambda s:s in[len(s)/i*s[:i]for i in range(1,len(s))]

ลองออนไลน์!


รุ่น regex ที่น่าเบื่อ:

Python 2 , 44 ไบต์

lambda s:re.match(r'(.+)\1+$',s)>0
import re

ลองออนไลน์!





3

PowerShell, 23 24 ไบต์

+1 ไบต์เพื่อจับคู่กฎอย่างสมบูรณ์

"$args"-match"^(.+)\1+$"

ลองออนไลน์!

ค่อนข้างน่าเบื่อ. ตามคำตอบ Regex อื่น ๆ โชคดีที่ PowerShell ไม่ได้ใช้\เป็นตัวละครในการหลบหนี!


ก็จะส่งกลับtrueสำหรับaabcabc
Mazzy

1
@ มาซี่เพิ่งแก้ไข!
Gabriel Mills

3

C # (Visual C # Interactive Compiler) , 70 ไบต์

xnor's shameless adaptation ( 46 bytes )

s=>(s+s).Substring(1,s.Length*2-2).Contains(s)

โซลูชันที่ไม่ใช่ Regex ของฉัน:

s=>s.Select((x,y)=>y).Count(z=>s.Replace(s.Substring(0,z+1),"")=="")>1

คำอธิบาย:

แทนที่สตริงย่อยที่เป็นไปได้ทั้งหมดที่เริ่มต้นที่ดัชนี 0 ด้วยสตริงว่าง ถ้าผลลัพธ์เป็นสตริงว่างสตริงนั้นจะทำจากสตริงย่อยนั้นทั้งหมด เนื่องจากสิ่งนี้รวมถึงการประเมินสตริงทั้งหมดด้วยตัวเองจำนวนผลลัพธ์ที่คาดหวังต้องมากกว่า 1

ตัวอย่าง: abcabc

สตริงย่อยที่เป็นไปได้เริ่มต้นที่ดัชนี 0:

'a', 'ab', 'abc', 'abca', 'abcab', 'abcabc'

ถ้าเราแทนที่มันด้วยสตริงว่าง

Substring          Result

'a'         =>     'bcbc'
'ab'        =>     'cc'
'abc'       =>     ''
'abca'      =>     'bc'
'abcab'     =>     'c'
'abcabc'    =>     ''

เนื่องจากมีสตริงย่อยอื่นที่ไม่ใช่ 'abcabc' ที่ส่งคืนสตริงว่างสตริงจึงทำจากสตริงย่อยอื่นทั้งหมด ('abc')

ลองออนไลน์!


3

Python 3 , 62 60 56 54 ไบต์

-4 ไบต์ thanx ถึงArBo

lambda s:s in(len(s)//l*s[:l]for l in range(1,len(s)))
  1. ทำซ้ำคำนำหน้าทั้งหมดที่เป็นไปได้ในสตริง
  2. ลองสร้างสตริงออกจากคำนำหน้า
  3. กลับมาว่าสิ่งนี้จะประสบความสำเร็จกับคำนำหน้าใด ๆ เลย

ลองออนไลน์!


1
คำตอบที่ดี! f=สามารถลดลง; ฟังก์ชั่นที่ไม่ระบุชื่อได้รับอนุญาตโดยทั่วไป นอกจากนี้การเปลี่ยนไปใช้ Python 2 และตรวจสอบความเป็นสมาชิกของรายการแทนการanyสร้างคุณสามารถรับได้ถึง55 ไบต์
ArBo

1
จับได้ดีกับสมาชิกรายการ thanx! ฉันจะไม่เปลี่ยนไปใช้ Python 2 เพราะมันเหมือนกับการเปลี่ยนภาษาซึ่งเห็นได้ชัดว่าไม่ใช่จุดที่นี่;) นอกจากนี้ยังมีวิธีที่สะดวกในการทดสอบฟังก์ชั่นที่ไม่ระบุชื่อใน TIO ทำให้นับไบต์หรือไม่
movatica

1
@movatica ในส่วนหัวให้ใส่ `f =` (\ เป็นตัวละครความต่อเนื่องของบรรทัดในไพ ธ อน)
Artemis รองรับโมนิก้า

น่ารำคาญ \ เป็นตัวละครในการหลบหนี ที่นี่โดยไม่มีการจัดรูปแบบรหัสเป็นสิ่งที่คุณควรใส่ไว้ในส่วนหัว: f = \
อาร์ทิมิสรองรับโมนิก้า

2

Japt , 10 ไบต์

ส่งกลับจำนวนบวกถ้าความจริงและ 0 ถ้าเท็จ หากคุณต้องการเอาต์พุตบูลเพียงเพิ่มแฟล็ก

å+ k@rXÃÊÉ

å+ k@rXÃÊÉ      Full program. Implicit input U.
                    e.g: U = "abcabcabc"
å+              Take all prefixes 
                         U = ["a","ab","abc","abca","abcab","abcabc","abcabca","abcabcab","abcabcabc"]
   k@           Filter U by:
     rXÃ        Values that return false (empty string)
                when replacing each prefix in U
                e.g: ["bcbcbc","ccc","","bcabc","cabc","abc","bc","c",""]
                                take ↑                             and ↑
                     U = ["abc","abcabcabc"]
         ÊÉ     Get U length and subtract 1. Then return the result

ลองออนไลน์!


2

Husk , 6 ไบต์

Ṡ€ȯhtD

ลองออนไลน์!

ฉันรู้สึกว่านี่เป็นหนึ่งไบต์ที่ดีที่สุด แต่ฉันไม่สามารถหาข้อตกลงที่ทำให้การจัดองค์ประกอบชัดเจนȯไม่จำเป็น

คำอธิบาย

Ṡ€      Find the argument in the result of applying the following function to the argument
  ȯhtD  Duplicate the argument, then remove the first and last elements.

2
€htD¹ȯหลีกเลี่ยงการ
Zgarb

มันอัศจรรย์มาก! ฉันเคยคิดเกี่ยวกับλ€htD¹แต่ฉันไม่ทราบว่าจะเพิ่ม lambdas โดยนัย
Sophia Lechner

2

Mathematica 11.x, 74 ไบต์

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&

โดยที่ตลอด#หมายถึงสตริงอินพุตและ

StringCases[#,<pattern>]

ค้นหาสตริงย่อยของอินพุตสตริงที่ตรงกับรูปแบบ

StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="") 

รูปแบบนี้ต้องใช้การจับคู่xต้องเริ่มต้นที่จุดเริ่มต้นของสตริงและต้องเป็นไปตามเงื่อนไขที่ (1) การจับคู่ไม่ใช่ทั้งสตริงและ (2) หากเราแทนที่การจับคู่ในสตริงอินพุตด้วยสตริงว่าง เราได้รับสตริงว่าง สุดท้ายเปรียบเทียบรายการที่ตรงกันกับรายการที่ว่างเปล่า

{}!=

คือTrueถ้ารายการการแข่งขันไม่ว่างเปล่าและFalseว่างเปล่าหากรายการการแข่งขันว่างเปล่า

กรณีทดสอบ:

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aa"]
(*  True  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aaa"]
(*  True  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["abcabc"]
(*  True  *)

และ

{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["aba"]
(*  False  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["ababa"]
(*  False  *)
{}!=StringCases[#,StartOfString~~x__/;(x!=#&&StringReplace[#,x->""]=="")]&["weqweqweqweqweqw"]
(*  False  *)

2

Python 3, 84 ไบต์

import textwrap
lambda s:any(len(set(textwrap.wrap(s,l)))<2 for l in range(1,len(s)))

ใช้textwrap.wrap(ขอบคุณคำตอบนี้ ) เพื่อแยกสตริงเป็นชิ้นส่วนของความยาวnเพื่อทดสอบความยาวที่เป็นไปได้ของการทำซ้ำสตริงย่อย ชิ้นส่วนที่ถูกแยกจะถูกนำมาเปรียบเทียบกันโดยการเพิ่มลงในชุด หากชิ้นส่วนทั้งหมดเท่ากันและชุดมีความยาว 1 ดังนั้นสตริงต้องเป็นสตริงซ้ำ ฉันใช้<2แทน==1เพราะมันช่วยประหยัดไบต์และความยาวของสตริงอินพุตนั้นรับประกันว่ามากกว่าศูนย์

หากไม่มีnความยาวของสตริงย่อยที่ทำซ้ำรวมnกันเป็นสตริงทั้งหมดให้ส่งคืนค่าเท็จสำหรับฟังก์ชันทั้งหมด


2

05AB1E , 5 ไบต์

วิธีการของ xnorจากคำถามก่อนหน้านี้ดูเหมือนจะดีที่สุดใน 05AB1E เช่นกัน

«¦¨så

ลองออนไลน์! หรือเป็นชุดทดสอบ

คำอธิบาย

«       # append input to input
 ¦¨     # remove the first and last character of the resulting string
   så   # check if the input is in this string

1
แน่นอน .. ฉันกำลังจะได้รับคำตอบ 05AB1E เมื่อฉันไม่เห็นว่ามีใครอยู่ เพื่อนร่วมงานถามคำถามและพูดคุยเกี่ยวกับวันหยุดของเขา ฉันมองกลับไปที่หน้าจอ: คำตอบใหม่ ธาดาเอาชนะ XD อีกครั้ง
Kevin Cruijssen

@KevinCruijssen: นั่นเป็นเรื่องปกติ เกิดขึ้นกับฉันหลายครั้งเช่นกัน;)
Emigna

2

ทำความสะอาด 73 ไบต์

ไม่ใช้ regex

import StdEnv,Data.List
$s=or[isPrefixOf s(cycle t)\\t<-tl(tails s)|t>[]]

ลองออนไลน์!

$ :: [Char] -> Boolกำหนด
ตรวจสอบว่าสตริงที่กำหนดเป็นคำนำหน้าของการทำซ้ำของสตริงย่อยใด ๆ ที่นำมาจากจุดสิ้นสุด


2

C ++ (gcc) , 36 ไบต์

#define f(x)(x+x).find(x,1)<x.size()

ลองออนไลน์!

โซลูชันอื่นของ xnor ใช้แมโครเพื่อขยายอาร์กิวเมนต์ไปยังนิพจน์ std::stringอาร์กิวเมนต์จะถือว่าเป็นประเภท


1

ตัวแปร QlikView ขนาด 27 ไบต์

สิ่งนี้ควรถูกกำหนดเป็นตัวแปรซึ่งอนุญาตให้คุณส่งพารามิเตอร์เช่น$1ค่าอินพุตของคุณ

มันจะส่งกลับ0หรือ-1(เทียบเท่ากับTRUE()ฟังก์ชั่นของ QlikView )

=substringcount($1&$1,$1)>2

1

Swift, 196 ไบต์

func r(s:String)->Bool{guard let k=s.dropFirst().firstIndex(where:{$0==s.first}) else{return false};let v=s[...k].dropLast();var w=v;while s.hasPrefix(w) && s.count>=(w+v).count{w+=v};return s==w}

ลองออนไลน์!


ฉันไม่ได้ใช้ Swift แต่ฉันแน่ใจว่าสามารถลบช่องว่างพิเศษออกได้
Benjamin Urquhart


@ArtemisFowl หรือแม้แต่123 ไบต์
Roman Podymov




1

T-SQL, 47 ไบต์

ใช้วิธีการของ @ Xnor :

DECLARE @ varchar(max)='ababab'

PRINT sign(charindex(@,left(@+@,len(@)*2-1),2))

การรักษาคำตอบเก่าไว้เพราะมันมีการตีกอล์ฟที่ดี (67 ไบต์):

DECLARE @y varchar(max)='abababa'

,@ INT=0WHILE
replace(@y,left(@y,@),'')>''SET
@+=1PRINT @/len(@y)^1

คำอธิบาย:สคริปต์นี้พยายามแทนที่อินพุต '@y' ซ้ำด้วยอักขระ '@' แรกของอินพุต '@y' โดยไม่มีอะไรเลยขณะที่เพิ่ม '@'

หากคุณแทนที่ 'ab' ใน 'ababab' ด้วยสิ่งใดก็ตามคุณจะต้องมีสตริงว่าง

ในที่สุดผลลัพธ์จะว่างเปล่า หากสิ่งนี้เกิดขึ้นเมื่อตัวแปรลูปเท่ากับความยาวของ varchar เกณฑ์เป็นเท็จ / 0 เพราะ '@' = len (@y) (ไม่มี varchar ซ้ำ)

iif(@=len(@y),0,1)

สามารถเล่นกอล์ฟได้

@/len(@y)^1

เนื่องจากความยาวของ '@y' ไม่สามารถเป็น 0 และ '@' จะไม่เกินความยาว @y

ลองออนไลน์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.