Chạy dài nhất của một nhân vật trong một chuỗi


19

Thách thức của bạn: Viết một hàm mang theo một chuỗi s, một nhân vật c, và tìm thấy chiều dài của thời gian dài nhất ctrong s. Độ dài của bước chạy sẽ là l.

Quy tắc :

  • Nếu scó độ dài 0 hoặc ctrống, lnên là 0.
  • Nếu không có trường hợp nào ctrong s, lnên là 0.
  • Lỗ hổng tiêu chuẩnQuy tắc I / O tiêu chuẩn được áp dụng.
  • Không có vấn đề ở đâu trong squá trình chạy của cs, lnên giống nhau.
  • Bất kỳ ký tự ASCII có thể in nào cũng có thể xuất hiện trong sc.

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

s,c --> l
"Hello, World!",'l'  -->  2
"Foobar",'o'         -->  2
"abcdef",'e'         -->  1
"three   spaces",' ' -->  3
"xxx xxxx xx",'x'    -->  4
"xxxx xx xxx",'x'    -->  4
"",'a'               -->  0
"anything",''        -->  0

Người chiến thắng :

Như với , câu trả lời ngắn nhất trong mỗi ngôn ngữ sẽ thắng.



Bạn có thể bao gồm các trường hợp cạnh trống s và mộtc không chứa trong một strường hợp không trống trong các trường hợp thử nghiệm của bạn?
Martin Ender

Phạm vi của các ký tự có thể xuất hiện trong s/ c?
Martin Ender

6
ccó thể để trống? Trong nhiều ngôn ngữ, một ký tự chỉ là một số nguyên có ngữ nghĩa đặc biệt và bạn thực sự không thể có một số nguyên trống.
Martin Ender

14
Điều đó không thực sự có ý nghĩa với tôi. Trường hợp thử nghiệm của bạn đề nghị rằng chúng tôi phải hỗ trợ nó. Nếu chúng tôi không phải hỗ trợ nó, thì việc chỉ định đầu ra cần thiết của nó không có ý nghĩa gì, bởi vì tôi luôn có thể nói rằng nó không được hỗ trợ nếu giải pháp của tôi sẽ làm gì khác trong trường hợp đó.
Martin Ender

Câu trả lời:


12

05AB1E , 5 byte

Mã số:

SQγOM

Sử dụng mã hóa 05AB1E . Hãy thử trực tuyến!

Giải trình:

SQ      # Check for each character if it is equal to the second input
  γ     # Split the list of zeros and ones into groups
   O    # Sum each array in the arrays
    M   # Get the maximum

2
Giải pháp tốt đẹp! Tôi biết có một cách để làm điều đó như thế này, tôi không thể nghĩ về nó.
Riley

γ¢Mkhông hoạt động như tôi nghĩ, nó sẽ là 3 byte.
Bạch tuộc ma thuật Urn

8

Toán học, 35 byte

Max[Tr/@Split@Boole@Thread[#==#2]]&

Hàm thuần túy lấy danh sách các ký tự và ký tự khác làm đầu vào và trả về một số nguyên không âm. Cải thiện nỗ lực đầu tiên của tôi bằng cách sử dụng quan sát của Adnan (đi lên!) Mà người ta nên kiểm tra để cân bằng ký tự đặc biệt trước khi chia mảng.

Thread[#==#2]kiểm tra xem mỗi ký tự đầu vào trong đối số thứ nhất có bằng ký tự được cung cấp làm đối số thứ hai không. Boolechuyển đổi kết quả Trues và Falses thành 1s và 0s. Splitchia danh sách thành các phần tử liên tiếp; Tr/@tổng hợp từng danh sách con vàMax tìm ra người chiến thắng. (Vì cách thức Maxhoạt động, nếu đối số đầu tiên là danh sách trống, thì hàm này sẽ trả về -∞. Vì vậy, bạn biết đấy, đừng làm điều đó.)

đệ trình đầu tiên (51 byte)

Max[Split@#/.a:{c_String..}:>Boole[c==#2]Length@a]&

Split@#chia đầu vào thành các ký tự liên tiếp, chẳng hạn như {{"t"}, {"h"}, {"r"}, {"e", "e"}, {" ", " ", " "}, {"s"}, {"p"}, {"a"}, {"c"}, {"e"}, {"s"}}cho trường hợp thử nghiệm thứ tư. /.a:{c_String..}:>thay thế mỗi biểu thức acon là một danh sách các ký tự được lặp lại cbằng cách Length@anhân với Boole[c==#2], đó là 1nếu cbằng với ký tự đầu vào và mặt 0khác. Sau đó Maxtrích xuất câu trả lời.


7

Japt , 20 18 15 byte

fV+Vî+)ª0)n o l

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

Đã lưu 5 byte nhờ obarakon và ETHproductions


1
Tôi đã chơi xung quanh với giải pháp của riêng mình trong một thời gian và kết thúc với một giải pháp gần như của bạn, nhưng ngắn hơn. Nếu bạn sử dụng fV+Vî+)... Tôi sẽ cho phép bạn tìm ra phần còn lại :-)
ETHproductions

@ETHproductions "If s is of length 0 or c is empty, l should be 0", tôi có thể cũng đang thực hiện điều đó theo nghĩa đen
Tom

Ồ, tôi đã nhận ra rằng thất bại bất cứ khi nào skhông chứa bất kỳ trường hợp nào c.
Sản phẩm ETH

7

Python , 38 byte

f=lambda s,c:+(c in s)and-~f(s,c+c[0])

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

Dennis đã lưu 3 byte bằng cách cập nhật cthành một chuỗi các ký tự trùng lặp thay vì cập nhật đệ quy một số để nhân cvới.


1
f=lambda s,c:c in s and-~f(s,c+c[0])lưu 6 byte (3 nếu sai không được phép).
Dennis


4

Haskell, 43 39 byte

f c=maximum.scanl(\n k->sum[n+1|c==k])0

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

Chạy qua chuỗi và thay thế char hiện tại bằng một bộ đếm được tăng bất cứ khi nào nó bằng c hoặc đặt lại 0nếu không. Lấy tối đa của danh sách.

Cảm ơn @xnor cho 4 byte.


Bạn có thể làm sum[n+1|c==k].
xnor

@xnor: Đẹp quá! Tôi đã thử nghiệm *fromEnum(c==k), cả pointfree và lambda, nhưng nó luôn dài hơn 2 hoặc 3 byte.
nimi

4

C # 116 115 byte

Golf mã đầu tiên của tôi

Đã chỉnh sửa vì nội dung gửi ban đầu là một đoạn mã và thiếu không gian tên bắt buộc cho regex

Chỉnh sửa viết lại hoàn chỉnh # 2 để hỗ trợ các ký tự có ý nghĩa regex đặc biệt

sử dụng System.Linq; s => c => System.Text.RegularExpressions.Regex.Replace (s, "[^" + c + "]", ++ c + ""). Split (c) .Max (x => x. Chiều dài);

using System.Linq;s=>c=>{var r=(char)(c-1);return string.Join("",s.Select(x=>x==c?c:r)).Split(r).Max(x=>x.Length)};

3
Tôi không biết C # nhưng có vẻ như mã của bạn mong đợi các biến csđược xác định trước. Chúng tôi gọi đây là "đoạn mã" và nó không được phép. Bạn có thể có thể cấu trúc lại mã của mình dưới dạng một hàm ẩn danh hoặc để đặt các biến đó thành đầu vào. Cả hai đều được cho phép.
Phù thủy lúa mì

Nó có hoạt động không? (Xem chỉnh sửa ở trên)
Chổi

1
Một lần nữa tôi không biết C #, nhưng có vẻ như nó làm. Bạn có thể muốn kiểm tra các mẹo chơi golf của chúng tôi trong C # tại đây để được tư vấn nhiều kinh nghiệm hơn về C #.
Phù thủy lúa mì

Cảm ơn các liên kết! Tôi chắc chắn sẽ xem qua các mẹo C #
Chổi

3
Xin chào, chỉ một số nhận xét chung cho việc chơi gôn trong C #, bạn có thể xác định chức năng của mình là (s,c)=>. Bạn phải sử dụng System.Text.RegularExpressions.Regexhoặc thêm một câu lệnh sử dụng ngay trước chức năng của mình.
LiefdeWen

4

JavaScript (ES6), 54 53 51 byte

-2 byte nhờ @Neil
-1 byte nhờ @apsillers

s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j

Đưa đầu vào theo cú pháp currying : f("foobar")("o").

Kiểm tra đoạn trích

f=
s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j
String: <input id=I> Letter: <input id=J maxlength=1 size=1> <button onclick='O.innerHTML+=`f("${I.value}")("${J.value}") = ${f(I.value)(J.value)}\n`'>Run</button><pre id="O"></pre>

Một tùy chọn khác sử dụng evalfor(54 byte)

s=>c=>eval("i=j=0;for(x of s)i=x==c&&i+1,i>j?j=i:0;j")

Trả lời cũ bằng Regex (85 byte)

s=>c=>c?Math.max(...s.match(eval(`/${/\w/.test(c)?c:"\\"+c}*/g`)).map(x=>x.length)):0

1
Tôi nghĩ x==c?i++:i=0chỉ có thể là i=x==c&&i+1do một falsekết quả x==cso sánh sẽ được coi là 0so sánh số và gia số (và sẽ không bao giờ là giá trị trả về, vì bất kỳ số nào, bao gồm 0, jsẽ luôn được ưu tiên hơn so với số không falsetrong i)
apsillers

@apsillers Cảm ơn, đã cập nhật, nhưng ý bạn là gì về việc nó không bao giờ là giá trị trả về?
Justin Mariner

Xin lỗi vì sự nhầm lẫn; Tôi chỉ giải thích rằng sự thay đổi sẽ không bao giờ khiến chương trình của bạn quay trở lại false(vì thử thách luôn đòi hỏi phải trả lại số)
apsillers

1
s=>c=>[...s].map(x=>j=(x!=c?i=0:++i)>j?i:j,i=j=0)&&jdường như để tiết kiệm một vài byte.
Neil

1
Xin lỗi, tôi đã đăng sai mã, ý tôi là đăng f=s=>c=>[...s].map(x=>j=(i=x==c&&i+1)>j?i:j,i=j=0)&&j, đó là một byte ngắn hơn.
Neil

4

JavaScript (Firefox 30-57), 75 72 byte

(s,c)=>Math.max(0,...(for(s of s.split(/((.)\2*)/))if(s[0]==c)s.length))

Đoạn mã tương thích ES6:

f=
(s,c)=>Math.max(0,...s.split(/((.)\2*)/).filter(s=>s[0]==c).map(s=>s.length))
<div oninput=o.textContent=f(s.value,c.value)><input id=s><input id=c maxlength=1 size=1><pre id=o>0

split trả về một chuỗi các chuỗi rỗng và các ký tự đơn cũng như các lần chạy nhưng điều này không ảnh hưởng đến kết quả.


3

Micro , 112 byte

{T l m 1+:Q # T Q T l~:r}:Z{T[0]+}:X
{i s m:n
n p = if(Z,X)
i L=if(,a)}:a
0\\:C:s:i"":p"":n[0]:T
s l:L
a
T l m:\


2

Perl 6 ,  45 43  42 byte

->$_,$c {$c&&$_??.comb(/$c+/)».chars.max!!0}

Kiểm tra nó

->$_,$c {$c&&$_??.comb(/$c+/).max.chars!!0}

Kiểm tra nó

->$_,$c {$c&$_??.comb(/$c+/).max.chars!!0}

Kiểm tra nó

Mở rộng:

-> $_, $c {       # pointy block lambda

    $c & $_       # AND junction of $c and $_
                  #   empty $c would run forever
                  #   empty $_ would return 4 ( "-Inf".chars )

  ??              # if True (neither are empty)

    .comb(/$c+/)  # find all the substrings
    .max          # find the max
    .chars        # get the length

  !!              # if False (either is empty)

    0             # return 0
}

2

JavaScript, ES6, 52

Giải pháp đệ quy coi đầu vào chuỗi là một mảng (lưu ý: đầu vào ban đầu vẫn là một chuỗi) và tiêu thụ từ trái sang phải trong ký tự C:

f=([C,...s],c,t=0,T=0)=>C?f(s,c,C==c&&++t,t>T?t:T):T

Theo dõi chạy hiện tại tvà tốt nhất toàn cầu trongT .

Giải trình:

f=            // function is stored in `f` (for recursion)
  ([C,...s],  // turn input string in first-char `C` and the rest in `s`
   c,         // argument `c` to search for
   t=0,T=0)   // current total `t`, best total `T`
     =>
        C?             // if there is still any char left in the string
          f(s,c,       // recursively call `f`
            C==c&&++t, // increment `t` if char is match, or set `t` to `false`
            t>T?t:T)   // set global `T` to max of `t` and `T`
          :T           // when string is depleted, return `T`

Cài đặt tthành falsekhông khớp hoạt động bởi vì bất cứ khi nào tđược tăng lên, falseđược coi là 0(nghĩa false + 11) và falsesẽ không bao giờ so sánh vắt hơn bất kỳ giá trị nào trong toàn cầu-max T.


1
Giải pháp hay, tôi không quen với [C,...s]cú pháp. Sẽ giúp tôi slice()tắt byte từ bài viết của riêng tôi.
Rick Hitchcock

2

Thạch , 5 byte

=ŒgṀS

Đây là một liên kết / hàm dyadic có một chuỗi và một ký tự. Lưu ý rằng nó không thể hoạt động như một chương trình đầy đủ, vì đầu vào từ các đối số dòng lệnh sử dụng cú pháp Python và Python - không giống như Jelly - không phân biệt các chuỗi singleton với các ký tự.

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

Làm thế nào nó hoạt động

=ŒgṀS  Main link. Left argument: s (string). Right argument: c (character)

=      Compare all characters in s with c, yielding 1 for c and 0 otherwise.
 Œg    Group adjacent, equal Booleans in the resulting array.
   Ṁ   Take the maximum. Note that any array of 1's will be greater than any array
       of 0's, while two arrays of the same Booleans are compared by length.
    S  Take the sum, yielding the length for an array of 1's and 0 otherwise.


2

APL (Dyalog) , 18 11 byte

Yêu cầu hoán đổi với Phiên bản 16.0 hoặc có ⎕ML←3(mặc định trên nhiều hệ thống).

⌈/0,≢¨⊂⍨⎕=⎕

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

⎕=⎕ Boolean cho sự bình đẳng giữa hai đầu vào

⊂⍨ tự phân vùng (bắt đầu phân vùng trong đó phần tử khác không lớn hơn phần trước của nó)

≢¨ kiểm đếm từng

0, trả trước một số không (cho các trường hợp đầu vào trống)

⌈/ tối đa trong số đó


Giải pháp cũ

Nhắc trước cho s , sau đó cho c

⌈/0,(⎕,¨'+')⎕S 1⊢⎕

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

 nhắc nhở cho s

 cho rằng

(... )⎕S 1PCRE S earch cho độ dài của lần xuất hiện của

'+' một biểu tượng dấu cộng (có nghĩa là một hoặc nhiều)

 gắn vào từng yếu tố của

 nhắc nhở cho c

0, trả trước một số không (cho các trường hợp đầu vào trống)

⌈/ tối đa trong số đó

c phải được đưa ra dưới dạng vectơ 1 phần tử của một chuỗi kèm theo nếu nó cần thoát.


2

PHP, 70 67 byte

ba phiên bản:

while(~$c=$argv[1][$i++])$x=max($x,$n=($c==$argv[2])*++$n);echo+$x;
while(~$c=$argv[1][$i++])$x=max($x,$n=$c==$argv[2]?++$n:0);echo+$x;
for(;++$n&&~$c=$argv[1][$i++];)$x=max($x,$n*=$c==$argv[2]);echo+$x;

lấy đầu vào từ các đối số dòng lệnh; chạy với -rhoặc kiểm tra chúng trực tuyến .


2

PHP , 70 byte

for(;~$c=$argv[1][$i++];)$r[]=$argv[2]==$c?++$n:$n=0;echo$r?max($r):0;

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

PHP , 75 byte

for(;~$s=substr($argv[1],$i++);)$r[]=strspn($s,$argv[2]);echo max($r?:[0]);

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

PHP , 83 byte

<?=@preg_match_all("<".preg_quote($argv[2])."+>",$argv[1],$t)?strlen(max($t[0])):0;

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

+8 byte để tránh @

<?=($a=$argv[2])&&preg_match_all("<".preg_quote($a)."+>",$argv[1],$t)?strlen(max($t[0])):0;

Phiên bản 67 byte sẽ thất bại đối với bất kỳ char đặc biệt regex nào (và #tất nhiên).
Tít

... và ~có thể thất bại cho chr(207).
Tít

@Titus Xong và Nhập chỉ có thể là các ký tự Ascii
Jörg Hülsermann

mắt tốt cho ++$n! Bạn có nghĩa là ascii có thể in. ;)
Tít

1
echo$r?max($r):0;tiết kiệm một byte
Titus

2

JavaScript (ES6), 47 40 38 byte

(Đã lưu 7 byte nhờ @Neil và 2 byte nhờ @HermanLauenstein.)

s=>g=c=>c&&s.includes(c)?1+g(c+c[0]):0

Giải trình:

Tìm kiếm đệ quy cho một lần chạy dài hơn cho đến khi không tìm thấy.

Đoạn trích:


1
Quá dễ! Rực rỡ!
apsillers

Bạn có thể không làm f=(s,c)=>c&&s.includes(c)&&1+f(s,c+c[0])?
Neil

Hoặc tốt hơn vẫn là, cà ri nó để s=>g=c=>c&&s.includes(c)&&1+g(c+c[0]).
Neil

Điều đó gần như hoạt động, nhưng nó trả về "false" và một chuỗi null cho hai trường hợp cuối cùng. Điều đó đã được sửa bằng cách nối thêm ||0, nó vẫn ngắn hơn giải pháp của tôi.
Rick Hitchcock

Đây f=không phải là một phần của phiên bản curried, bởi vì chỉ có chức năng bên trong là đệ quy.
Neil

2

Thạch, 10 9 byte

f⁴L
ŒgÇ€Ṁ

Giải trình:

f⁴L
f⁴      -Filter by the character argument.
  L     -Return Length of filtered String.

ŒgÇ€»/
Œg      -Group string by runs of characters.
  ǀ    -Run above function on each group.
    Ṁ   -Return the largest in the list.

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


Bạn có thể lưu một vài byte với Œgf€L€Ṁ.
Dennis


1

Haskell , 66 byte

import Data.List
((maximum.(0:).map length).).(.group).filter.elem

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

Một phiên bản dễ đọc hơn một chút - không phải là pointfree:

f c s = maximum (0:(map length (filter (elem c) (group s))))

Nhóm chuỗi theo chữ cái, sau đó lọc theo các nhóm có chứa ký tự phù hợp, sau đó tìm độ dài, nối 0 vào danh sách độ dài trong trường hợp nó không xuất hiện và cuối cùng tìm thấy giá trị tối đa.


1

Toán học, 109 byte

(s=Differences[First/@StringPosition[#,#2]];k=t=0;Table[If[s[[i]]==1,t++;If[k<t,k=t],t=0],{i,Length@s}];k+1)&


đầu vào

["xxx xxxx xx", "x"]



1

CJam , 20 19 18 16 byte

0q~e`f{~@=*}$+W=

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

Giải trình

0                 e# Push 0. We'll need it later.
 q~               e# Read and eval input. Pushes c and s to the stack.
   e`             e# Run-length encode s: turns it into an array of [length, char] pairs.
     f{           e# Map over these pairs using c an extra parameter:
       ~          e#  Dump the pair to the stack.
        @=        e#  Bring c to the top, check equality with the char, pushing 0 or 1.
          *       e#  Multiply the length by the result.
           }      e# (end map)
            $     e# Sort the resulting list in ascending order.
             +    e# Prepend the 0 from before, in case it's empty.
              W=  e# Get the last element.

1

Excel, 56 byte

{=MAX(IFERROR(FIND(REPT(A2,ROW(A:A)),A1)^0*ROW(A:A),0))}

snên được nhập vào A1.
cnên được nhập vào A2.
Công thức phải là một công thức mảng ( Ctrl+ Shift+ Enter) có thêm dấu ngoặc nhọn{ } .

Về mặt kỹ thuật, điều này chỉ có thể xử lý ở nơi chạy lâu nhất dưới 1.048.576 (tức là 2 ^ 20) vì đó là cách các hàng Excel hiện tại sẽ cho phép bạn có trong một bảng tính. Vì nó tải hàng triệu giá trị + vào bộ nhớ mỗi khi tính toán lại, đây không phải là một công thức nhanh .


1

MATL , 15 byte

0i0v=dfd1L)0hX>

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

Thuật toán cơ bản rất đơn giản (không sử dụng phân tách!), Nhưng tôi đã phải ném vào 0i0v0hđể cho phép các trường hợp cạnh. Tuy nhiên, tôi nghĩ rằng cách tiếp cận này rất hay và có lẽ tôi vẫn có thể tìm ra một kỹ thuật khác để xử lý các trường hợp cạnh: thuật toán tìm ra bước chạy dài nhất ở giữa một chuỗi chỉ tốt, nhưng không phải cho các ký tự đơn hoặc chuỗi rỗng; Tôi vẫn đang thử nghiệm nếu tôi có thể 'đệm' các biến ở những nơi tốt hơn để có kết quả tốt hơn.

0i0v % Prepends and appends a zero to the (implicit) input.
   = % Element-wise equality with the desired char (implicit input)
   d % Pairwise difference. Results in a 1 at the start of a run, and -1 at the end.
   f % Get indices of 1's and -1's.
   d % Difference to get length of the runs (as well as length of non-runs)
 1L) % Only select runs, throw out non-runs. We now have an array of all run lengths.
  0h % 'Find' (`f`) returns empty if no run is found, so append a zero to the previous array.
  X> % Maximum value.

Không làm việc trên sản phẩm nào c. Sau đó, một lần nữa, tôi cho rằng mỗi chuỗi chứa một chuỗi vô hạn các chuỗi trống giữa mỗi ký tự :)


1

R , 66 58 byte

-8 byte nhờ BLT và MickyT

function(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)

trả về một hàm ẩn danh. TIO có chênh lệch 1 byte vìel không hoạt động ở đó vì những lý do không thể giải thích được.

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


Lưu một byte vớir=rle(el(strsplit(s,'')))
BLT

1
Bỏ qua bình luận trước đây của tôi nếu bạn nhìn thấy nó. Có một cái tốt hơn cho bạnfunction(s,c)max((r=rle(el(strsplit(s,''))))$l*(r$v==c),0)
MickyT

@BLT elkhông hoạt động trên TIO (không biết tại sao) và tôi chỉ sao chép và dán nó từ mã làm việc ở đó vì vậy tôi sẽ phải nhớ đưa nó trở lại vào @MickyT rất thông minh! Cảm ơn!
Giuseppe

1

Java 8, 67 65 byte

s->c->{int t=0,m=0;for(char x:s)m=m>(t=x==c?t+1:0)?m:t;return m;}

-2 byte nhờ @ OlivierGrégoire

Đưa đầu vào slà một char[], và cnhư mộtchar

Giải trình:

Hãy thử nó ở đây.

s->c->{          // Method with char[] and char parameters and int return-type
  int t=0,       //  Temp counter-integer
      m=0;       //  Max integer
  for(char a:s)  //  Loop over the characters of the input
    m=m>(
     t=x==c?     //   If the current character equals the input-character:
      t+1        //    Raise `t` by 1
      :          //   Else:
       0)        //    Reset `t` to 0
    ?m:t;        //   If `t` is now larger than `m`, put `t` as new max into `m`
                 //  End of loop (implicit / single-line body)
  return m;      //  Return the resulting max
}                // End of method

1
m=m>(t=x==c?t+1:0)?m:t;ngắn hơn {t=x==c?t+1:0;m=m>t?m:t;}.
Olivier Grégoire

Mặc dù nó dài hơn, tôi thích suy nghĩ đầu tiên của tôi : s->c->java.util.Arrays.stream(s.split("[^"+c+"]")).mapToInt(z->z.length()).max().orElse(0);)
Olivier Grégoire

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.