ใช้อัลกอริทึมการเรียงลำดับ Thanos


93

อัลกอริทึมการเรียงลำดับมีลักษณะดังนี้:

ในขณะที่ไม่มีการเรียงลำดับรายการให้จัดครึ่งหนึ่งของรายการทั้งหมด (นำออกจากรายการ) ทำต่อไปจนกว่าจะมีการเรียงลำดับรายการหรือมีเพียงหนึ่งรายการที่เหลืออยู่ (ซึ่งเรียงลำดับตามค่าเริ่มต้น) อัลกอริทึมการเรียงลำดับนี้อาจให้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับการใช้งาน

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

รายการอินพุตสามารถมีจำนวนไอเท็มตามอำเภอใจ (ภายในเหตุผลสมมติว่ามีมากถึง 1,000 ไอเท็ม) ไม่เพียง แต่รายการที่แบ่งแยกได้อย่างสมบูรณ์แบบของรายการ 2 ^ n คุณจะต้องลบรายการ (n + 1) / 2 หรือ (n-1) / 2 หากรายการนั้นเป็นเลขคี่ฮาร์ดโค้ดหรือตัดสินใจสุ่มระหว่างรันไทม์ ตัดสินใจด้วยตัวคุณเอง: ธานอสจะทำอะไรถ้าจักรวาลมีสิ่งมีชีวิตแปลก ๆ จำนวนหนึ่ง?

รายการจะถูกจัดเรียงหากไม่มีรายการใดเล็กกว่ารายการก่อนหน้า รายการที่ซ้ำกันอาจเกิดขึ้นในอินพุตและอาจเกิดขึ้นในเอาต์พุต

โปรแกรมของคุณควรใช้อาร์เรย์ของจำนวนเต็ม (ผ่าน stdin หรือพารามิเตอร์ทั้งรายการหรือพารามิเตอร์อาร์เรย์) และส่งกลับอาร์เรย์ที่เรียงลำดับแล้ว (หรือพิมพ์ไปยัง stdout)

ตัวอย่าง:

// A sorted list remains sorted
[1, 2, 3, 4, 5] -> [1, 2, 3, 4, 5]

// A list with duplicates may keep duplicates in the result
[1, 2, 3, 4, 3] -> [1, 3, 3] // Removing every second item
[1, 2, 3, 4, 3] -> [3, 4, 3] -> [4, 3] -> [3] // Removing the first half
[1, 2, 3, 4, 3] -> [1, 2] // Removing the last half

[1, 2, 4, 3, 5] สามารถให้ผลลัพธ์ที่แตกต่าง:

// Removing every second item:
[1, 2, 4, 3, 5] -> [1, 4, 5]

หรือ:

// Removing the first half of the list
[1, 2, 4, 3, 5] -> [3, 5] // With (n+1)/2 items removed
[1, 2, 4, 3, 5] -> [4, 3, 5] -> [3, 5] // With (n-1)/2 items removed

หรือ:

// Removing the last half of the list
[1, 2, 4, 3, 5] -> [1, 2] // With (n+1)/2 items removed
[1, 2, 4, 3, 5] -> [1, 2, 4] // With (n-1)/2 items removed

หรือ:

// Taking random items away until half (in this case (n-1)/2) of the items remain
[1, 2, 4, 3, 5] -> [1, 4, 3] -> [4, 3] -> [4]

การมีกรณีทดสอบซึ่งต้องการสแนปชอตหลายอันสำหรับอัลกอริธึมการจัดเรียงที่แตกต่างกันจะมีประโยชน์มาก
สตริงที่ไม่เกี่ยวข้อง

22
เราไม่จำเป็นต้องจัดเรียงและกำจัดคำตอบครึ่งคำตอบ ...
Sumner18

4
[9, 1, 1, 1, 1]กรณีทดสอบที่แนะนำ: อัลกอริทึมของฉันเองล้มเหลวในอินพุตนี้
Conor O'Brien

คำตอบ:





12

Brachylog (v2), 6 ไบต์

≤₁|ḍt↰

ลองออนไลน์!

นี่คือการส่งฟังก์ชั่น อินพุตจากด้านซ้ายส่งออกไปทางขวาตามปกติ (ลิงก์ TIO ใช้อาร์กิวเมนต์บรรทัดคำสั่งที่ล้อมฟังก์ชันเข้ากับโปรแกรมเต็มโดยอัตโนมัติเพื่อให้คุณเห็นการทำงาน)

คำอธิบาย

≤₁|ḍt↰
≤₁       Assert that {the input} is sorted {and output it}
  |      Handler for exceptions (e.g. assertion failures):
   ḍ     Split the list into two halves (as evenly as possible)
    t    Take the last (i.e. second) half
     ↰   Recurse {and output the result of the recursion}

รอบโบนัส

≤₁|⊇ᵇlᵍḍhtṛ↰

ลองออนไลน์!

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

≤₁|⊇ᵇlᵍḍhtṛ↰
≤₁            Assert that {the input} is sorted {and output it}
  |           Handler for exceptions (e.g. assertion failures):
   ⊇ᵇ         Find all subsets of the input (preserving order)
     lᵍ       Group them by length
       ḍht    Find the group with median length:
         t      last element of
        h       first
       ḍ        half (split so that the first half is larger)
          ṛ   Pick a random subset from that group
           ↰  Recurse

นี่จะค่อนข้างสั้นกว่านี้หากเราสามารถจัดลำดับองค์ประกอบใหม่ได้ แต่ทำไมอัลกอริธึมการเรียงลำดับต้องการทำเช่นนั้น ?


12
หนึ่งไบต์ต่อหินอินฟินิตี้
djechlin

@djechlin ไบต์อินฟินิตี้คือเหตุผลที่คุณต้องไปหาหัวและโดยเฉพาะกราม
The Great Duck

10

Perl 6 , 30 ไบต์

$!={[<=]($_)??$_!!.[^*/2].&$!}

ลองออนไลน์!

ฟังก์ชันเรียกซ้ำที่ลบครึ่งหลังของรายการออกจนกว่ารายการจะถูกเรียงลำดับ

คำอธิบาย:

$!={                         }    # Assign the function to $!
    [<=]($_)??                    # If the input is sorted
              $_                  # Return the input
                !!                # Else
                  .[^*/2]         # Take the first half of the list (rounding up)
                         .&$!     # And apply the function again


8

Java 10, 106 97 ไบต์

L->{for(;;L=L.subList(0,L.size()/2)){int p=1<<31,f=1;for(int i:L)f=p>(p=i)?0:f;if(f>0)return L;}}

-9 ไบต์ขอบคุณที่@ OlivierGrégoire

ลองออนไลน์

n+12

คำอธิบาย:

L->{               // Method with Integer-list as both parameter and return-type
  for(;;           //  Loop indefinitely:
      L=L.subList(0,L.size()/2)){
                   //    After every iteration: only leave halve the numbers in the list
    int p=1<<31,   //   Previous integer, starting at -2147483648
        f=1;       //   Flag-integer, starting at 1
    for(int i:L)   //   Inner loop over the integer in the list:
      f=p>(p=i)?   //    If `a>b` in a pair of integers `a,b`:
         0         //     Set the flag to 0
        :          //    Else (`a<=b`):
         f;        //     Leave the flag the same
    if(f>0)        //   If the flag is still 1 after the loop:
      return L;}}  //    Return the list as result

n->{for(;n.reduce((1<<31)+0d,(a,b)->a==.5|b<a?.5:b)==.5;n=n.skip(n.count()/2));return n;} สั้นลงด้วยการใช้สตรีม แต่ฉันไม่สามารถหาวิธีหลีกเลี่ยงjava.lang.IllegalStateException: stream has already been operated upon or closedข้อผิดพลาดได้หลังจากส่งคืนสตรีม
ศูนย์รวมของความไม่รู้

@EmbodimentofIgnorance สิ่งนี้เกิดขึ้นเนื่องจากreduceเป็นการทำงานของเทอร์มินัลที่ปิดสตรีม คุณจะไม่สามารถโทรreduceสองครั้งบนสตรีมเดียวกัน คุณสามารถสร้างกระแสใหม่ได้
Olivier Grégoire


@ OlivierGrégoireคำสั่งนั้นดูเรียบง่ายมากตอนนี้ที่ฉันเห็นมัน .. บางครั้งมันจะมองจากอีกมุมมองหนึ่งเพื่อดูคนอื่น ๆ ที่เห็นได้ชัดในตอนแรกฉันเดาว่า :) ขอบคุณ!
Kevin Cruijssen

1
ไม่ต้องกังวลไม่ชัดเจน: ฉันทำงานเพื่อไปที่นั่น ฉันทดสอบอย่างน้อย 10 เวอร์ชันก่อนที่จะพบอันนั้น;)
Olivier Grégoire

8

ภาษา Wolfram (Mathematica)ขนาด 30 ไบต์

#//.x_/;Sort@x!=x:>x[[;;;;2]]&

ลองออนไลน์!

@Doorknob บันทึกแล้ว 12 ไบต์


1
แทนที่จะบันทึกครึ่งแรกคุณสามารถบันทึกไบต์ได้ด้วยการใช้องค์ประกอบอื่น ๆ ( x[[;;;;2]])
Doorknob

@Doorknob ใช่แน่นอน ...
J42161217

คิดว่าอาจมีการออมโดยใช้OrderedQแต่ไม่สามารถใช้งานได้
Greg Martin

@GregMartin ฉันใช้OrderedQวิธีแรกของฉัน (ดูการแก้ไข)
J42161217



6

05AB1E , 8 7 ไบต์

[Ð{Q#ιн

-1 ไบต์ขอบคุณที่@Emigna

n12

ลองใช้แบบออนไลน์หรือตรวจสอบกรณีทดสอบเพิ่มเติมอีกหลายกรณี (หรือตรวจสอบกรณีทดสอบเหล่านั้นด้วยการทำซ้ำแต่ละขั้นตอน )

7 ไบต์ทางเลือกโดย@Grimy :

ΔÐ{Ê>äн

ลบล่าสุดn2n12

ลองใช้แบบออนไลน์หรือตรวจสอบกรณีทดสอบเพิ่มเติมอีกหลายกรณี (หรือตรวจสอบกรณีทดสอบเหล่านั้นด้วยการทำซ้ำแต่ละขั้นตอน )

คำอธิบาย:

[        # Start an infinite loop:
 Ð       #  Triplicate the list (which is the implicit input-list in the first iteration)
  {Q     #  Sort a copy, and check if they are equal
    #    #   If it is: Stop the infinite loop (and output the result implicitly)
  ι      #  Uninterweave: halve the list into two parts; first containing all even-indexed
         #  items, second containing all odd-indexed items (0-indexed)
         #   i.e. [4,5,2,8,1] → [[4,2,1],[5,8]]
   н     #  And only leave the first part

Δ        # Loop until the result no longer changes:
 Ð       #  Triplicate the list (which is the implicit input-list in the first iteration)
       #  Sort a copy, and check if they are NOT equal (1 if truthy; 0 if falsey)
    >    #  Increase this by 1 (so 1 if the list is sorted; 2 if it isn't sorted)
     ä   #  Split the list in that many parts
      н  #  And only leave the first part
         # (and output the result implicitly after it no longer changes)

3
คุณสามารถใช้ιแทนหากคุณเปลี่ยนเป็นกลยุทธ์เก็บองค์ประกอบอื่น ๆ
Emigna

1
ทางเลือกที่ 7 ใช้กลยุทธ์ "ลบครึ่งสุดท้าย":ΔÐ{Ê>äн
Grimy

@Grimy นั่นเป็นวิธีที่ดีเช่นกัน ฉันจะเพิ่มมันลงในโพสต์ของฉัน (รับรองคุณแน่นอน) หรือคุณต้องการที่จะโพสต์มันเป็นคำตอบที่แยกจากกัน?
Kevin Cruijssen

รู้สึกฟรีเพื่อเพิ่ม
Grimy

6

TI-BASIC (TI-84), 47 42 45 44 ไบต์

-1 ไบต์ขอบคุณ @SolomonUcko!

Ans→L1:Ans→L2:SortA(L1:While max(L1≠Ans:iPart(.5dim(Ans→dim(L2:L2→L1:SortA(L1:End:Ans

Ansรายการอยู่ในการป้อนข้อมูล
เอาต์พุตอยู่ในAnsและพิมพ์ออกมาโดยปริยาย

คำอธิบาย:

Ans→L1                  ;store the input into two lists
Ans→L2
SortA(L1                ;sort the first list
                        ; two lists are needed because "SortA(" edits the list it sorts
While max(L1≠Ans        ;loop until both lists are strictly equal
iPart(.5dim(Ans→dim(L2  ;remove the latter half of the second list
                        ; removes (n+1)/2 elements if list has an odd length
L2→L1                   ;store the new list into the first list (updates "Ans")
SortA(L1                ;sort the first list
End
Ans                     ;implicitly output the list when the loop ends

หมายเหตุ: TI-BASIC เป็นภาษาโทเค็น จำนวนตัวอักษรไม่เท่ากับจำนวนไบต์


ฉันคิดว่าคุณสามารถแทนที่not(min(L1=Ansด้วยmax(L1≠Ansเพื่อบันทึกไบต์
โซโลมอน Ucko


3

Haskell , 57 55 ไบต์ (ขอบคุณ ASCII-only)

f x|or$zipWith(>)x$tail x=f$take(div(length x)2)x|1>0=x

ลองออนไลน์!


รหัสเดิม:

f x|or$zipWith(>)x(tail x)=f(take(div(length x)2)x)|1>0=x

ลองออนไลน์!


Ungolfed:

f xs | sorted xs = f (halve xs)
     | otherwise = xs

sorted xs = or (zipWith (>) xs (tail xs))

halve xs = take (length xs `div` 2) xs

1
ยินดีต้อนรับสู่ PPCG!
Rɪᴋᴇʀ




3

อ็อกเทฟ 49 ไบต์

l=input('');while(~issorted(l))l=l(1:2:end);end;l

ลองออนไลน์! นี่คือการเดินทางที่น่าเบื่อมากขึ้นดีกว่า สังเกตรายการที่น่าสนใจอีกสองรายการด้านล่าง:

50 ไบต์

function l=q(l)if(~issorted(l))l=q(l(1:2:end));end

ลองออนไลน์! แทนที่จะเป็นวิธีแก้ปัญหาที่ไม่น่าสนใจเราสามารถแก้ปัญหาแบบวนซ้ำได้เพียงหนึ่งไบต์เท่านั้น

53 ไบต์

f(f=@(g)@(l){l,@()g(g)(l(1:2:end))}{2-issorted(l)}())

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


2

MATL 11 ไบต์

tv`1L)ttS-a

ลองออนไลน์!

วิธีนี้ใช้ได้โดยลบทุกรายการที่สอง

คำอธิบาย

t      % Take a row vector as input (implicit). Duplicate
v      % Vertically concatenate the two copies of the row vector. When read with
       % linear indexing (down, then across), this effectively repeats each entry
`      % Do...while
  1L)  %   Keep only odd-indexed entries (1-based, linear indexing)
  t    %   Duplicate. This will leave a copy for the next iteration
  tS   %   Duplicate, sort
  -a   %   True if the two arrays differ in any entry
       % End (implicit). A new iteration starts if the top of the stack is true
       % Display (implicit). Prints the array that is left on the stack

2
เสียสำหรับรายการเรียงเริ่มต้น: [1, 2, 3, 4, 5] ควรจะยังคงอยู่ [1, 2, 3, 4, 5]
Falco

@Falco ขอบคุณ! แก้ไขแล้วตอนนี้
Luis Mendo




2

Husk , 6 5 ไบต์

บันทึก 1 ไบต์ขอบคุณ Zgarb

ΩΛ<Ċ2

ลองออนไลน์!

คำอธิบาย

ΩΛ<Ċ2
Ω         Repeat until
 Λ<         all adjacent pairs are sorted (which means the list is sorted)
   Ċ2         drop every second element from the list

นี่คือ 11 ไบต์ไม่ใช่ 6› echo -n "ΩΛ <(←½" | wc --bytes 11
Mike Holler


@MikeHoller เช่นเดียวกับภาษาอื่น ๆ ของการเล่นกอล์ฟ Husk ใช้หน้ารหัสที่กำหนดเองเพื่อให้สามารถเข้าถึงตัวละครต่าง ๆ ได้มากขึ้น: github.com/barbuz/Husk/wiki/Codepage
Leo

ขอบคุณฉันได้เรียนรู้อะไรบางอย่างในวันนี้ :)
Mike Holler

1
ใช้Ċ2แทน(←½การบันทึกไบต์
Zgarb


2

Julia 1.0 , 30 ไบต์

-x=x>sort(x) ? -x[1:2:end] : x

ลองออนไลน์!

ใช้ทุกองค์ประกอบที่สองของอาร์เรย์หากไม่ได้เรียงลำดับ


ใช้โอเปอเรเตอร์ ASCII เช่น-ขนาด 20 ไบต์ นอกจากนี้เราเกือบจะไม่นับตัวอักษร: | ดังนั้นมันจะดีถ้ามันถูกลบออกจากส่วนหัว
ASCII- เท่านั้น

เปลี่ยนแล้ว ขอบคุณสำหรับ 2 ไบต์!
niczky12

2

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

ฉันไม่สามารถแสดงความคิดเห็น แต่ฉันปรับปรุงเวอร์ชันจาก movatica โดยลดการรวมและการใช้อัตโนมัติ

-2 Bytes: ceilingcat
-2 Bytes: ASCII-only

#include<regex>
auto f(auto l){while(!std::is_sorted(l.begin(),l.end()))l.resize(l.size()/2);return l;}

ลองออนไลน์!


1
เหตุผลใดที่คุณไม่สามารถใช้l.size()/2?
ASCII เท่านั้น

ใช่มันไม่ทำงานวิธีที่ :)
peterzuger

1
คุณหมายถึงอะไร ส่งคืนรายการขนาด(n+1)/2หรือ(n-1)/2ใช้ได้ทั้งคู่ hmm ....
ASCII เท่านั้น

โอ้
โหไม่

1

VDM-SL , 99 ไบต์

f(i)==if forall x in set inds i&x=1or i(x-1)<=i(x) then i else f([i(y)|y in set inds i&y mod 2=0]) 

ไม่เคยส่งใน vdm มาก่อนจึงไม่แน่ใจในกฎเฉพาะภาษา ดังนั้นฉันจึงส่งคำจำกัดความของฟังก์ชั่นซึ่งใช้ a seq of intและส่งคืน aseq of int

โปรแกรมเต็มรูปแบบที่จะทำงานอาจมีลักษณะเช่นนี้:

functions
f:seq of int +>seq of int
f(i)==if forall x in set inds i&x=1or i(x-1)<=i(x) then i else f([i(y)|y in set inds i&y mod 2=0]) 

1

Pyth, 10 ไบต์

.W!SIHhc2Z

ลองออนไลน์ได้ที่นี่ สิ่งนี้จะลบครึ่งหลังของการวนซ้ำแต่ละครั้งปัดเศษลง จะเปลี่ยนเป็นลบในช่วงครึ่งแรกปัดเศษขึ้นให้เปลี่ยนไปhe

.W!SIHhc2ZQ   Q=eval(input())
              Trailing Q inferred
  !SIH        Condition function - input variable is H
   SIH          Is H invariant under sorting?
  !             Logical not
      hc2Z    Iteration function - input variable is Z
       c2Z      Split Z into 2 halves, breaking ties to the left
      h         Take the first half
.W        Q   With initial value Q, execute iteration function while condition function is true

องค์ประกอบอื่น ๆ ของรายการจะสั้นลง แทนที่ด้วยhc %สิ่งนี้ยังช่วยให้คุณลบตัวแปรแลมบ์ดาต่อท้ายZและให้ Pyth เติมโดยปริยายเพื่อบันทึก 2 ไบต์ทั้งหมด
hakr14

1

C ++ (gcc) , 139 137 116 ไบต์

-2 ไบต์ thanx ถึง ceilingcat, -21 ไบต์ thanx ถึง PeterZuger

#include<regex>
auto f(std::vector<int>l){while(!std::is_sorted(l.begin(),l.end()))l.resize(-~l.size()/2);return l;}

ปรับขนาดเวกเตอร์เป็นครึ่งแรกจนกว่าจะถูกจัดเรียง

ลองออนไลน์!


1
การนำเข้าจะต้องรวมอยู่ในจำนวนไบต์ดังนั้นคุณต้องเพิ่มincludes
ศูนย์รวมของความไม่รู้

ขอบคุณมากฉันจะเพิ่มพวกเขา
movatica

1

K (oK) , 22 20 ไบต์

วิธีการแก้:

{(*2 0N#x;x)x~x@<x}/

ลองออนไลน์!

ทำซ้ำการป้อนข้อมูลจนกว่าจะเรียงลำดับ ... หากไม่ได้เรียงลำดับให้ใช้รายการ n / 2 ก่อน

{(*2 0N#x;x)x~x@<x}/ / the solution
{                 }/ / lambda that iterates
                <x   / indices that sort x ascending (<)
              x@     / apply (@) these indices back to x
            x~       / matches (~) x? returns 0 or 1
 (       ; )         / 2-item list which we index into
          x          / original input (ie if list was sorted)
       #x            / reshape (#) x
   2 0N              / as 2 rows
  *                  / take the first one      

การแก้ไข:

  • -2ไบต์ขอบคุณ ngn

1
(.5*#x)#x->*2 0N#x
ngn

ฉันคิดว่าทำ2 0Nแต่คิดว่ามันจะนานกว่านี้ (โดยไม่ต้องทดสอบ) ขอบคุณ
roadster


0

เรติน่า , 38 ไบต์

\d+
*
/(_+),(?!\1)/+`,_+(,?)
$1
_+
$.&

ลองออนไลน์! ใช้ตัวเลขคั่นด้วยเครื่องหมายจุลภาค คำอธิบาย:

\d+
*

แปลงเป็นเอก

/(_+),(?!\1)/+`

ทำซ้ำขณะที่ไม่มีการเรียงลำดับรายการ ...

,_+(,?)
$1

... ลบทุกองค์ประกอบคู่

_+
$.&

แปลงเป็นทศนิยม


0

C (gcc) , 66 ไบต์

Snaps off ครึ่งหลังของรายการแต่ละการวนซ้ำ ( n/2+1องค์ประกอบถ้าความยาวเป็นเลขคี่)

ลองออนไลน์!

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

t(a,n,i)int*a;{l:for(i=0;i<n-1;)if(a[i]>a[++i]){n/=2;goto l;}a=n;}

เวอร์ชันที่ไม่ถูกปรับแต่ง:

t(a, n, i) int *a; { // take input as a pointer to an array of int, followed by its length; declare a loop variable i
  l: // jump label, will be goto'ed after each snap
  for(i = 0; i < n - 1; ) { // go through the whole array …
    if(a[i] > a[++i]) { // … if two elements are in the wrong order …
      n /= 2; // … snap off the second half …
      goto l; // … and start over
    }
  }
  a = n; // implicitly return the new length
}

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