Mở rộng khung!


36

Thách thức của bạn là mở rộng một số dấu ngoặc trong đầu vào của chương trình như được hiển thị:

  1. Tìm một chuỗi s giữa hai dấu ngoặc phù hợp [], với một chữ số n sau dấu ngoặc đóng.
  2. Xóa dấu ngoặc.
  3. Thay s bằng chính nó lặp đi lặp lại n lần. (Nếu n bằng 0, chỉ cần xóa s .)
  4. Chuyển đến bước 1 cho đến khi không còn dấu ngoặc phù hợp nào trong đầu vào.

Các quy tắc bổ sung và làm rõ:

  • Bạn sẽ nhận đầu vào và cung cấp đầu ra thông qua bất kỳ phương tiện được phép.
  • Một dòng mới trong đầu ra được cho phép.
  • Bạn chỉ cần xử lý ASCII có thể in trong đầu vào.
  • Bạn có thể cho rằng tất cả các dấu ngoặc trùng khớp, tức là bạn sẽ không bao giờ nhận được đầu vào []]]]hoặc [[[[].
  • Bạn có thể giả sử rằng mỗi khung đóng ]có một chữ số sau nó.

Các trường hợp thử nghiệm:

Input                -> Output
[Foo[Bar]3]2         -> FooBarBarBarFooBarBarBar
[one]1[two]2[three]3 -> onetwotwothreethreethree
[three[two[one]1]2]3 -> threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
[!@#[$%^[&*(]2]2]2   -> !@#$%^&*(&*($%^&*(&*(!@#$%^&*(&*($%^&*(&*(
[[foo bar baz]1]1    -> foo bar baz
[only once]12        -> only once2
[only twice]23456789 -> only twiceonly twice3456789
[remove me!]0        -> 
before [in ]2after   -> before in in after

Vì đây là , câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng. Chúc may mắn!



13
Bạn nên đăng một thử thách khác để nén một chuỗi trở lại định dạng ngắn nhất của nó
Jo King

Có đáng nói rõ rằng chuỗi của bạn skhông bao giờ nên chứa các dấu ngoặc khác không? Ví dụ: cố gắng giải quyết [Foo[Bar]3]2bằng cách mở rộng chuỗi Foo[Bar3 lần sẽ dẫn đến trạng thái không hợp lệFoo[BarFoo[BarFoo[Bar]2
BradC

@BradC tất cả phụ thuộc vào cách bạn chọn để thực hiện nhiệm vụ.
MD XF

Điều đó có nghĩa là có hai câu trả lời hợp lệ [a[b]2c[d]2e]2? Bạn nhận được abbcddeabbcddebằng cách mở rộng bdđầu tiên, nhưng ababcdbcdedbabcdbcdedebằng cách mở rộng a[bd]2eđầu tiên.
BradC

Câu trả lời:


13

Gema , 17 ký tự

[#]?=@repeat{?;#}

Chạy mẫu:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone

Wow, nói về việc tìm ngôn ngữ phù hợp cho công việc!
MD XF

Hoặc công việc phù hợp với ngôn ngữ. Nhiều thách thức đã phải bỏ qua vì lập luận đệ quy không đủ linh hoạt.
thao tác

Chấp nhận điều này ngay bây giờ vì tôi không thấy bất kỳ cách nào nó bị đánh bại, nhưng nó sẽ không được chấp nhận trong trường hợp không thể xảy ra.
MD XF


7

Haskell , 101 96 byte

fst.(""%)
infix 4%
s%']':d:r=(['1'..d]>>s,r)
s%'[':r|(t,q)<-""%r=s++t%q
s%x:r=s++[x]%r
s%e=(s,e)

Hãy thử trực tuyến! Thay vì sử dụng biểu thức chính quy như hầu hết các câu trả lời khác, điều này thực hiện một trình phân tích cú pháp đệ quy.

-5 byte nhờ BMO !


4
Một khai báo cố định (%)giúp bạn tiết kiệm 1 byte và ['1'..d]giúp bạn tiết kiệm thêm 4 byte , hãy xem điều này .
ბიმო

3
@BMO Rất vui, tôi không mong đợi một tuyên bố cố định sẽ hữu ích cho việc chơi golf mã. Tôi nghĩ bạn nên thêm nó vào câu hỏi mẹo.
Laikoni

7

Perl 5 , 34 33 29 + 1 ( -p) = 30 byte

s/.([^[]*?)](.)/$1x$2/e&&redo

Hãy thử trực tuyến!

Cắt giảm nó với một số trợ giúp từ @Shaggy và @TonH rửa.


3
Tôi không biết ngọc trai nhưng làm lại có vẻ tuyệt đẹp!
chính thức tuyên bố

Tôi nghĩ bạn sẽ có thể lưu một byte bằng cách không thoát ].
Xù xì

1
Tôi không biết Perl nhưng điều này dường như hoạt động với 30 + 1 byte.
Xù xì

2
29 + 1 này cũng hoạt động: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'perl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Aidel

5

Japt v2 , 21 20 19 byte

Đã lưu 2 byte nhờ @Shaggy

e/.([^[]*?)](./@YpZ

Kiểm tra nó trực tuyến!

elà thay thế đệ quy, làm cho một thay thế tại một thời điểm cho đến khi không còn trận đấu nữa. Trong trường hợp này, các kết quả khớp của biểu thức chính /\[([^[]*?)](\d)/gđược thay thế bằng <văn bản bên trong> lặp lại <chữ số> lần cho đến khi không còn kết quả khớp nào nữa.

Theo những gì tôi đã lên kế hoạch ( ở đây ), regex này cuối cùng sẽ ngắn hơn ít nhất 3 2 byte:

‹[“⁽[»₋”]“.›

2
Vì chúng tôi " có thể giả định rằng mỗi khung đóng ]có một chữ số sau nó " nên bạn có thể thay thế (\dbằng (..
Xù xì

Bạn cũng có thể thay thế \[bằng.
Shaggy

@Shaggy Đẹp, cảm ơn!
Sản phẩm ETH

4

JavaScript, 71 67 66 byte

Tôi đã có một giải pháp 54 byte nhưng nó đã bị hỏng bởi trường hợp thử nghiệm thứ hai! :

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x

Các trường hợp thử nghiệm

f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x
o.innerText=`[Foo[Bar]3]2
[one]1[two]2[three]3
[three[two[one]1]2]3
[!@#[$%^[&*(]2]2]2
[[foo bar baz]1]1
[only once]12
[only twice]23456789
[remove me!]0
before [in ]2after`.split`\n`.map(x=>x.padEnd(22)+`:  `+f(x)).join`\n`
<pre id=o></pre>


4

Python 3 , 110 93 92 byte

import re
f=lambda s:f(re.sub(r'\[([^][]+)\](.)',lambda m:m[1]*int(m[2]),s))if'['in s else s

Hãy thử trực tuyến!

-17 byte nhờ pizzapants184 -1 byte nhờ Kevin Cruijssen


1
-17 byte trong Python 3 với việc lập chỉ mục re.match và kiểm tra chuỗi con bằng cách sử dụng in.
pizzapants184

1
-1 byte bằng cách thay đổi (\d)thành (.), bởi vì chúng ta biết một khung khối ]luôn được theo sau bởi một chữ số.
Kevin Cruijssen

4

Scala , 173 byte

l.foreach{x=>def r(c:String):String={val t="""\[([^\[\]]*)\](.)""".r.unanchored;c match{case t(g,h)=>r(c.replaceAllLiterally(s"[$g]$h",g*h.toInt));case _=>c}};println(r(x))}

Hãy thử trực tuyến!

Mở rộng:

l.foreach { x =>
  def remove(current: String): String = {
    val test ="""\[([^\[\]]*)\](.)""".r.unanchored
    current match {
      case test(g, h) => remove(current.replaceAllLiterally(s"[$g]$h", g * h.toInt))
      case _ => current
    }
  }

  println(remove(x))
}

Giải pháp cũ

Scala , 219 215 213 212 199 byte

l.foreach{x=>def r(c:String):String={"""\[([^\[\]]*)\](.)""".r.findFirstMatchIn(c).map{x=>val g=x.group(1);val h=x.group(2).toInt;r(c.replaceAllLiterally(s"[$g]$h",g*h))}.getOrElse(c)};println(r(x))}

Hãy thử trực tuyến!

Mở rộng:

l.foreach { x =>
  def remove(current: String): String = {
    """\[([^\[\]]*)\](.)""".r.findFirstMatchIn(current).map { x =>
      val g = x.group(1)
      val h = x.group(2).toInt
      remove(current.replaceAllLiterally(s"[$g]$h", g * h))
    }.getOrElse(current)
  }
  println(remove(x))
}

Trong đó l là danh sách các chuỗi mà chúng ta sẽ xử lý.

Cảm ơn Kevin Cruijssen cho -1 byte

Đã đi từ 212 đến 199 bằng cách xóa tham số không sử dụng, không chú ý.


4
Chào mừng đến với PPCG! Hãy thử trình thông dịch scala của tio tại tio.run/#scala và xem liệu bạn có thể gửi một liên kết cho câu trả lời, để những người khác có thể thử trực tuyến. :)
chính thức

2
Cảm ơn bạn! Tôi chỉnh sửa câu trả lời để bao gồm các liên kết. Hy vọng rằng ok, tiêu đề, mã và chân trang được khai báo như thế nào để được gửi đúng.
Shik Khẩu

1
Xin chào, chào mừng đến với PPCG! Câu trả lời đầu tiên tuyệt vời, +1 từ tôi. Tôi nghĩ rằng bạn có thể tiết kiệm 1 byte bằng cách thay đổi (\d)thành (.), bởi vì chúng tôi biết một khung khối ]luôn được theo sau bởi một chữ số.
Kevin Cruijssen

3

Xếp chồng lên nhau , 39 38 byte

Đã lưu 1 byte nhờ Shaggy, đánh gôn regex!

['\[([^[\]]+)](.)'{.y x:x#~y*}recrepl]

Hãy thử trực tuyến!

Đơn giản chỉ cần đệ quy thay thế một '\[([^[\]]+)](.)'biểu thức chính quy bằng quy tắc lặp lại.


Tôi nghĩ bạn có thể lưu một byte bằng cách không thoát cuối cùng ].
Xù xì

3

Python 3, 155 148 101 97 byte

def f(x):
 a=x.rfind('[')
 if~a:b=x.find(']',a);x=f(x[:a]+x[a+1:b]*int(x[b+1])+x[b+2:])
 return x

Dùng thử trực tuyến

Cảm ơn HyperNeutrino và Mego cho -47 byte và user202729 cho -4 byte.


Biến nó thành một lớp lót để tiết kiệm một vài byte:def f(x):a=x.rfind('[');b=x.find(']',a);return f(x[:a]+x[a+1:b]*int(x[b+1])+x[b+2:])if~a else x
mathmandan

3

JavaScript - 77 75 72 byte

f=a=>a.replace(/(.*)\[([^[]*?)](.)(.*)/,(a,b,c,d,e)=>f(b+c.repeat(d)+e))

Chỉnh sửa: regex cập nhật với khuyến nghị của Shaggy

Đoạn trích:


2
Chào mừng đến với PPCG! Bạn có thể giảm xuống 70 byte bằng cách điều chỉnh RegEx.
Xù xì

Vâng, 72 byte, rõ ràng, xin lỗi; Tôi đã quên đếm f=!
Shaggy

2

QuadR với đối số, 30 28 byte

\[[^[]+?].
∊(⍎⊃⌽⍵M)⍴⊂1↓¯2↓⍵M

Hãy thử trực tuyến!

\[[^[]+?]. thay thế " nhân vật [không phải [thứ ]" bằng

¯2↓⍵M thả hai ký tự cuối cùng của M atch ( " ]chữ số ')
1↓ thả các ký tự đầu tiên (' [")
 kèm theo được đối xử như một toàn thể
(... )⍴r eshape theo chiều dài:
⌽⍵M đảo ngược M atch
 chọn đầu tiên (chữ số)
 đánh giá
ε nlist ( làm phẳng)

 lặp lại cho đến khi không có nhiều thay đổi xảy ra


Hàm APL Dyalog tương đương là 47 byte:

'\[[^[]+?].'R{∊(⍎⊃⌽⍵.Match)⍴⊂1↓¯2↓⍵.Match}⍣≡

Hãy thử trực tuyến!


2

Java 8, 250 249 241 239 byte

s->{for(;s.contains("[");)for(int i=0,j,k;i<s.length();)if(s.charAt(i++)==93){String t="",r=t;for(j=k=s.charAt(i)-48;j-->0;)t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");s=k<1?t:s.replaceFirst(r,"$1$3").replace("",t);}return s;}

-2 byte nhờ @JonathanFrech (mã hiện có hai ký tự ASCII không thể in được, có thể nhìn thấy trong liên kết TIO bên dưới).

Thở dài ... Java với regex rất hạn chế .. Tôi sẽ chỉ trích dẫn bản thân mình từ một câu trả lời khác ở đây:

Việc thay thế WWWWbằng 222WJava rất dễ dàng, nhưng 4Wkhông phải .. Nếu chỉ Java có cách sử dụng nhóm bắt regex cho một thứ gì đó .. Lấy độ dài bằng "$1".length(), thay thế chính nó bằng "$1".replace(...), chuyển đổi khớp với một số nguyên bằng new Integer("$1")hoặc sử dụng một cái gì đó tương tự như Retina (tức là s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))hoặc JavaScript (nghĩa là s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) sẽ là điều số 1 của tôi mà tôi muốn thấy trong Java trong tương lai để mang lại lợi ích cho việc mã hóa ..>.> Tôi nghĩ rằng đây là lần thứ 10 tôi ghét Java không thể làm được bất cứ điều gì với trận đấu nhóm bắt giữ ..
Trích dẫn từ đây.

Giải trình:

Hãy thử trực tuyến.

s->{                           // Method with String as both parameter and return-type
  for(;s.contains("[");)       //  Loop as long as the String contains a block-bracket
    for(int i=0,j,k;i<s.length();)
                               //   Inner loop over the characters of the String
      if(s.charAt(i++)==93){   //    If the current character is a closing block-bracket:
        String t="",r=t;       //     Create two temp-Strings, starting empty
        for(j=k=s.charAt(i)-48;//     Take the digit after the closing bracket
            j-->0;)            //     Loop that many times:
          t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");
                               //      Append `t` with the word inside the block brackets
        s=k<1?                 //     If the digit was 0:
           t                   //      Replace the input with an empty String as well
          :                    //     Else:
           s.replaceFirst(r,"$1$3").replace("",t);}
                               //      Replace the word between brackets by `t`,
                               //      and remove the digit
  return s;}                   //  Return the modified input-String as result

1
Tôi nghĩ rằng bạn có thể sử dụng một ASCII thực sự mặc dù ký tự không thể in được để lưu hai byte . (Giải pháp của bạn thực sự cần tới 240 byte, 239 ký tự.)
Jonathan Frech

@JonathanFrech Cảm ơn! Đã tìm kiếm một ký tự 1 byte bên ngoài phạm vi ASCII có thể in được. Không nghĩ đến việc sử dụng một thứ không thể in được ..
Kevin Cruijssen


2

C, 407 368 byte

Cảm ơn Jonathan Frech đã lưu byte.

đánh gôn (tập tin ngoặc.c):

i,j,k,l,n;char*f(a,m)char*a;{for(i=0;a[i];++i){a[i]==91&&(j=i+1);if(a[i]==93){k=a[i+1]-48;if(!k){for(l=i+2;l<m;)a[++l-i+j-4]=a[l];a=realloc(a,m-3);return f(a,m-3);}for(l=j;l<i;)a[~-l++]=a[l];for(l=i+2;l<m;)a[++l-4]=a[l];m-=3;n=m+~-k*(i---j--);a=realloc(a,n);for(l=i;l<m;)a[l+++~-k*(i-j)]=a[l];for(m=0;m<k;++m)for(l=j;l<i;)a[l+++m*(i-j)]=a[l];return f(a,n);}}return a;}

vô dụng với chương trình:

#include <stdlib.h>
#include <stdio.h>

// '[' = 133
// ']' = 135
// '0' = 48

i, j, k, l, n;

char* f(a,m) char*a;
{
  for (i=0; a[i]; ++i) {
    a[i]==91&&(j=i+1);

    if (a[i]==93) {
      k=a[i+1]-48;

      if (!k) {
        for (l=i+2; l<m; )
          a[++l-i+j-4] = a[l];

        a = realloc(a,m-3);
        return f(a,m-3);
      }
      for (l=j;l<i;)
        a[~-l++] = a[l];
      for (l=i+2; l<m; )
        a[++l-4] = a[l];
      m -= 3;
      n = m+~-k*(i---j--);
      a = realloc(a,n);

      for (l=i; l<m; )
        a[l+++~-k*(i-j)] = a[l];
      for (m=0; m<k; ++m)
        for (l=j; l<i;)
          a[l+++m*(i-j)] = a[l];

      return f(a,n);
    }
  }
  return a;
}

int main()
{
  char c[]="[Foo[Bar]3]2";
  char *b;

  char cc[]="[remove me!]0";
  char *bb;

  char ccc[]="[only once]12";
  char *bbb;

  b=malloc(13);
  bb=malloc(14);
  bbb=malloc(14);

  for (i=0; i<13; ++i)
    b[i] = c[i];

  for (i=0; i<14; ++i)
    bb[i] = cc[i];

  for (i=0; i<14; ++i)
    bbb[i]=ccc[i];

  printf("%s\n", f(b, 13));
  printf("%s\n", f(bb, 14));
  printf("%s\n", f(bbb, 14));

  return 0;
}

Được biên dịch với gcc 5.4.1, gcc bracket.c



387 với sự cần thiết bao gồm (đối với realloc). Tôi sẽ làm một bản cập nhật sạch (với phiên bản không được chỉnh sửa) sau. Cảm ơn
Tsathoggua

Nếu bạn sử dụng GCC, tôi nghĩ trình biên dịch sẽ cố gắng đoán định nghĩa của cả hai mallocrealloc, bao gồm cả stdlib.hchính nó.
Jonathan Frech

Tôi không biết điều đó. Tính năng đẹp cho chơi golf mã. Cảm ơn.
Tsathoggua

2

Màu đỏ , 147 byte

f: func[t][a: charset[not"[]"]while[parse t[any a some[remove["["copy h any a"]"copy d a](insert/dup v: copy""h to-integer d)insert v | skip]]][]t]

Ung dung:

f: func [t][
    a: charset [not "[]"]                          ; all chars except [ and ]
    while [ parse t [                              ; repeat while parse is returning true
        any a                                      ; 0 or more chars other than [ and ]
        some [                                     ; one or more block:
            remove ["[" copy h any a "]" copy d a] ; remove the entire block, store the
                                                   ; substring between the [] in h,
                                                   ; the digit into d
            (insert/dup v: copy "" h to-integer d) ; makes d copies of h 
            insert v                               ; and inserts them in place 
            | skip ]                               ; skip if no match
        ]                                       
    ][]                                            ; empty block for 'while'
    t                                              ; return the modified string
]

Tôi đã bắt đầu học phương ngữ Parse của Red chỉ ngày hôm qua, vì vậy tôi chắc chắn rằng mã của tôi có thể được cải thiện hơn nữa. Parse hoàn toàn dài dòng hơn regex, nhưng rất rõ ràng, linh hoạt và dễ đọc và có thể được trộn lẫn tự do với phần còn lại của ngôn ngữ Đỏ.

Hãy thử trực tuyến!


1

Thạch , 30 byte

œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®
Çċ”]$¡

Hãy thử trực tuyến!


Giải trình.


œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®    Helper link 1, expand once.
                           Assume input = "ab[cd]2ef".

œṡ      Split at first occurence of
  ”]      character "]".
    µ   Start new monadic chain. Value = "ab[cd","2ef".

Ḣ       ead. "ab[cd"
 U      Upend. "dc[ba"
  œṡ”[  Split at first occurence of "[". | "dc","ba".

ẋ€        Repeat ...
  1¦        the element at index 1...
          by ...
    Ṫ Ḣ$    the ead of the ail of ...
          the input list ("ab[cd","2ef") (that is, 2)

          The command  also pop the head '2'. The remaining
            part of the tail is "ef".
     ©    Meanwhile, store the tail ("ef") to the register.

          Current value: "dcdc","ba"
FṚ        Flatten and everse. | "abcdcd"
  ;®      Concatenate with the value of the register. "abcdcdef"

Çċ”]$¡    Main link.

 ċ”]$     Count number of "]" in the input.
     ¡    Repeatedly apply...
Ç           the last link...
            that many times.

1

C, 381 byte

Phiên bản nhỏ gọn:

while(1){int t=strlen(i);int a,c=-1;char*w;char*s;char*f;while(c++<t){if(i[c]==']'){int k=c-a;w=calloc((k--),1);memcpy(w,&i[a+1],k);s=calloc((t-c-1),1);memcpy(s,&i[c+2],t-c-2);i[a]=0;int r=i[c+1]-48;if(r==0){f=calloc(t,1);sprintf(f,"%s%s",i,s);}else{f=calloc((t+k),1);sprintf(f,"%s%s[%s]%d%s",i,w,w,r-1,s);}free(i);i=f;break;}else if(i[c]=='[')a=c;}free(w);free(s);if(c>=t)break;}

Phiên bản đầy đủ:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void proceed(char* input)
{
  while(1)
  {
    int t=strlen(input);
    int start,cursor=-1;
    char* word;
    char* suffix;
    char* final;
    while(cursor++<t)
    {
      if(input[cursor]==']')
      {
        int wordlength = cursor-start;
        word=calloc((wordlength--),sizeof(char));
        memcpy(word, &input[start+1], wordlength );
        suffix=calloc((t-cursor-1),sizeof(char));
        memcpy( suffix, &input[cursor+2], t-cursor-2 );
        input[start]='\0';
        int rep=input[cursor+1]-'0';
        if(rep==0)
        {
          final=calloc(t,sizeof(char));
          sprintf(final,"%s%s",input,suffix);
        }
        else
        {
          final=calloc((t+wordlength+5),sizeof(char));
          sprintf(final,"%s%s[%s]%d%s",input,word,word,rep-1,suffix);
        }
        free(input);
        input=final;
        break;
      }
      else if(input[cursor]=='[')
        start=cursor;
    }
    free(word);
    free(suffix);

    if(cursor>=t)break;
  }
}

int main()
{
  char* input=calloc(256,sizeof(char));
  sprintf(input,"a[[toto]2b]2[ana]3");
  printf("in : %s\n",input);
  proceed(input);
  printf("out: %s\n",input);
  return 0;
}

3
Chào mừng đến với PPCG!
Xù xì

1
Chào mừng đến với trang web! Lưu ý rằng bài nộp C cần phải là chương trình hoặc chức năng đầy đủ, không chỉ là đoạn trích.
MD XF

1

Python, 80 byte

import re
b=re.sub
s=lambda x:eval(b(r"\](.)",r"')*\1+'",b(r"\[","'+('","%r"%x)))

Hãy thử trực tuyến!

s("[Foo[Bar]3]2")Chuyển đổi [Foo[Bar]3]2sang''+('Foo'+('Bar')*3+'')*2+'' , và đánh giá lại.

Thất bại cho đầu vào với dấu ngoặc kép trong ngoặc (ví dụ [']3)


Tôi đã đánh giá thấp câu trả lời này vì câu hỏi yêu cầu xử lý bất kỳ ASCII có thể in nào trong đầu vào và câu trả lời này không. Thông báo cho tôi nếu bạn sửa nó và tôi sẽ vui vẻ rút lại phiếu bầu của mình.
caird coinheringaahing
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.