Tìm polyphthongs của tôi!


19

Đối với mục đích của thử thách này, một polyphthong được định nghĩa là một lát liền kề của Chuỗi, chỉ chứa nguyên âm và có độ dài ít nhất là 2. Với một Chuỗi không trống làm đầu vào, nhiệm vụ của bạn là xuất ra tất cả các đa âm mà nó chứa .

Ví dụ: "abeoic"có các lát liền kề sau (được phân tách bằng dấu cách):

a b e o i c ab be eo oi ic abe beo eoi oic abeo beoi eoic abeoi beoic abeoic

Loại bỏ những thứ có chứa bất cứ thứ gì ngoài nguyên âm hoặc có độ dài nhỏ hơn 2, chúng ta sẽ có được các polyphthong mong muốn:

eo oi eoi

Nội dung gửi của bạn phải tuân thủ các quy tắc sau:

  • Bạn có thể chọn chữ thường hoặc chữ hoa cho I / O, nhưng trường hợp đầu ra phải khớp với trường hợp đầu vào.

  • Nguyên âm là aeiou(cho chữ thường) và AEIOU(cho chữ hoa). y/ Ykhông được coi là một nguyên âm.

  • Đầu vào sẽ chỉ chứa ASCII có thể in được.

  • Nếu một polyphthong xuất hiện nhiều lần, bạn có thể chọn chỉ xuất một lần hoặc xuất tất cả các lần xuất hiện của nó.

  • Bất kỳ định dạng và phương thức I / O hợp lý nào đều được cho phép (danh sách các ký tự cũng ổn, cho cả đầu vào và đầu ra).

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

Đầu vào -> Đầu ra (chữ thường)

r67 ^^ () * 6536782! 87 -> []
câu đố lập trình và mã golf -> []
aaand ... tôi đã thắng! -> ['aa', 'aa', 'aaa']
abeoic -> ['eo', 'oi', 'eoi']
yah eioo ala -> ['ei', 'io', 'oo', 'eio', 'ioo', 'eioo']
@yabeeeayio__e -> ['ee', 'ee', 'e', ​​'io', 'eee', 'eea', 'eeea']
0ioen0aaiosnjksd -> ['io', 'oe', 'aa', 'ai', 'io', 'ioe', 'aai', 'aio', 'aaio']

Lưu ý rằng đối với các trường hợp thử nghiệm 3 và 6, bạn có thể xuất ra 'aa''ee'chỉ tương ứng một lần (Xem quy tắc thứ tư).

Đây là , bài nộp ngắn nhất theo byte trong mọi ngôn ngữ sẽ thắng!


Lưu ý rằng điều này ban đầu được đăng dưới dạng CMC (Thử thách trò chuyện nhỏ) trong The Nineteenth Byte , nhưng Adám nói rằng nó phù hợp với Main , vì vậy tôi đã kết thúc việc đăng bài này.
Ông Xcoder

Tôi trường hợp thử nghiệm thứ ba của bạn, 'aa'xuất hiện hai lần. Có phải người ta phải xuất ra cùng một chuỗi nhiều lần nếu nó xuất hiện ở nhiều vị trí khác nhau hay chỉ có thể xuất ra các polyphtong duy nhất?
Jonathan Frech

@JonathanFrech Ok, tôi đoán xuất ra các polyphtong độc đáo là tốt. Sẽ chỉnh sửa.
Ông Xcoder

Liệu thứ tự của đầu ra có vấn đề?
trứng

1
@Xophmeister Với mục đích của thử thách này , một polyphthong được định nghĩa là - Tôi biết đó không phải là định nghĩa ngôn ngữ chính xác :-)
Ông Xcoder

Câu trả lời:


7

Python 2 , 102 97 byte

cảm ơn @JonathanFrech cho -5 byte

w=input();l=range(len(w)+1)
print{w[a:b]for a in l for b in l if b-a>1<set(w[a:b])<=set('aeiou')}

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

chữ thường I / O


1
Tôi nghĩ bạn không cần ...AEIOU', vì bạn chỉ được phép lấy chữ thường làm đầu vào.
Jonathan Frech


@JonathanFrech print([w[a:b]for a in l for b in l[a+2:]if{*w[a:b]}<={*'aeiou'}])hoạt động cho 93.
Lynn

@Lynn Và giải pháp của bạn tạo ra 96 Python 2 byte .
Jonathan Frech

6

JavaScript (ES6), 77 75 byte

Mong đợi đầu vào bằng chữ thường. Đầu ra polyphthong độc đáo mà không lặp lại.

w=>(r=[],g=s=>w.match(s)&&[...'aeiou'].map(c=>g(s+c),s[1]&&r.push(s)))``&&r

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

Làm sao?

Chúng tôi xây dựng đệ quy cây của tất cả các polyphthong có thể, cắt tỉa các nhánh ngay khi nút hiện tại không còn trong đầu vào nữa và lưu tất cả các nút phù hợp với ít nhất 2 ký tự.

w => (                      // given the input w
  r = [],                   // r = array of results
  g = s =>                  // g = recursive function taking s
    w.match(s) &&           // if w contains s:
    [...'aeiou'].map(c =>   //   for each vowel c:
      g(s + c),             //     do a recursive call with s + c
      s[1] &&               //     if s is at least 2-character long:
      r.push(s)             //       push it into r
    )                       //   end of map()
)``                         // initial call to g() with s = ''
&& r                        // return r

6

Võng mạc , 23 20 byte

M!&`[aeiou]+
r!&`..+

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

Điều này in tất cả các lần xuất hiện của một polyphthong.

Giải trình

Retina có một cách để có được tất cả các trận đấu chồng chéo , nhưng điều này thực sự có nghĩa là nó sẽ tìm kiếm một trận đấu từ mỗi vị trí. Vì vậy, nếu có nhiều trận đấu từ cùng một vị trí, điều này sẽ chỉ trả lại một trong số chúng. Cách duy nhất để thực sự có được tất cả các trận đấu chồng chéo là sử dụng tính năng này hai lần, một lần khớp từ trái sang phải và một lần từ phải sang trái (để trước tiên chúng tôi có được trận đấu dài nhất có thể từ mỗi vị trí bắt đầu có thể, và sau đó chúng tôi cũng nhận được tất cả các trận đấu cho các vị trí kết thúc có thể).

Vì vậy, chương trình thực tế:

M!&`[aeiou]+

Nhận tất cả các nguyên âm chồng chéo. Điều này thực sự có nghĩa là để có được tất cả các hậu tố của tất cả các nguyên âm chạy.

r!&`..+

Bây giờ, nhận tất cả các tiền tố có độ dài ít nhất là 2, bằng cách khớp từ phải sang trái. Điều Mnày được ngầm định ở đây, bởi vì đó là dòng cuối cùng của chương trình.


Bạn có thể giải thích mã?
Adám

!&`[aeiou]{2,}rất gần để chính xác , có cách nào để làm cho nó tham lam hơn để nó phù hợp với io?
admBorkBork

1
@ Adám Đã thêm một lời giải thích.
Martin Ender

@AdmBorkBork Loại giải thích của tôi bao gồm lý do tại sao điều đó không thể làm việc. Retina không thích thú với công cụ regex thực tế, vì vậy, &điều cần làm nhất là thử một trận đấu từ mỗi vị trí, do đó bạn không thể có nhiều trận đấu có độ dài khác nhau từ cùng một vị trí. Đó là lý do tại sao tôi cần một giai đoạn thứ hai.
Martin Ender

Giải thích tốt đẹp, cảm ơn.
admBorkBork

5

QuadS , 20 + 1 = 21 byte

⊃,/⍵
[aeiou]+
1↓,\⍵M

với ocờ

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

Theo thứ tự những điều xảy ra:

[aeiou]+ trên mỗi trận đấu của PCRE này

,\⍵M tiền tố của trận đấu

1↓ bỏ cái đầu tiên (trong đó có một nguyên âm)

,/⍵ nối tất cả các danh sách các tiền tố

 tiết lộ (vì giảm /kèm theo)


Điều này tương đương với chức năng ngầm của Dyalog APL:

{⊃,/⍵}'[aeiou]+'S{1↓,\⍵.Match}⍠'OM'1

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



4

Java (OpenJDK 8) , 138 135 134 byte

s->{String e,x="";for(int i=0,j,y=s.length();i<=y;i++)for(j=y;j>i;x+=e.matches("[aeiou]{2,}")?e+" ":"")e=s.substring(i,j--);return x;}

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


i<y-1có thể i<=yString#matchesngầm kiểm tra toàn bộ Chuỗi, vì vậy bạn không cần ^$. +1 để đánh bại tôi với nó, mặc dù. Chỉ là để gửi câu trả lời 138 byte của riêng tôi (nhưng với những thay đổi này, tôi đề xuất của bạn ngắn hơn). :)
Kevin Cruijssen


3

Thạch , 9 byte

ẆḟÐḟØcḊÐf

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

Giải trình

ẆḟÐḟØcḊÐf  Main Link
Ẇ          Get all (contiguous) sublists
  Ðḟ       Filter; remove all elements where the result is truthy:
 ḟ  Øc     Filter; remove all vowels; if it's truthy, then it contains non-vowels
       Ðf  Filter; keep elements where the result is truthy:
      Ḋ    Dequeue; return all but the first element (truthy if the length was at least 2)

-4 byte nhờ ông Xcoder


11 byte bằng cách thay thế L>1$$bằng L’$.
Ông Xcoder

Trên thực tế bạn có thể thay thế L’$bằng cho 9 byte . Một tương đương sẽ là ẆṫLḊḟÐḟØc.
Ông Xcoder

3

C (gcc) , 104 byte (99 byte chỉ có chữ thường hoặc chỉ chữ hoa)

Vâng, nó bị rò rỉ - vậy thì sao?

#include<string.h>
a;f(char*s){*s&&f(s+1);for(a=strspn(s=strdup(s),"AEIOUaeiou");a>1;)s[a--]=0,puts(s);}

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


3
Có vẻ như hoạt động mà không có#include , và bạn chỉ cần xử lý một trường hợp chữ cái, vì vậy bạn có thể rút ngắn nó xuống còn 80 byte.
Steadybox


3

R , 137 byte

bị đánh bại bởi Mark !

function(S)(x=unlist(sapply((s=el(strsplit(S,"[^aeiou]")))[nchar(s)>1],function(x)substring(x,1:(n=nchar(x)),rep(n:1,e=n)))))[nchar(x)>1]

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

function(S){
 s <- el(strsplit(S,"[^aeiou]"))            # split on non-vowels
 s <- s[nchar(s)>1]                         # vowel groups of length at least 2
 p <- function(x){                          # generates all substrings of inputs
  n <- nchar(x)
  start <- 1:n
  stop <- rep(n:1, n)                       # this will generate dups
  substring(x, start, stop)
} q <- unlist(sapply(s, p)) # all substrings q <- q[nchar(q)>1] # all length-2 or more substrings }


Bạn không cần unique.
Ông Xcoder

"Bất kỳ định dạng và phương thức I / O hợp lý nào đều được cho phép (danh sách các ký tự cũng ổn, cho cả đầu vào và đầu ra)." Tôi đã không thử nó, nhưng tôi nghi ngờ điều này có thể ngắn hơn khá nhiều nếu bạn sử dụng danh sách nhân vật từ đầu.
dùng2390246

@ user2390246 có lẽ. Tôi không tin rằng nó sẽ giúp ích cho tất cả, nhưng điều đó có lẽ chỉ vì cách tiếp cận cách ly nguyên âm sẽ khá khác biệt và tôi không thể quấn đầu xung quanh nó ngay bây giờ.
Giuseppe


2

PowerShell , 93 88 byte

param($a)0..($b=$a.count-1)|%{($i=$_)..$b|%{-join$a[$i..$_]}}|?{$_-match'^[aeiou]{2,}$'}

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

Sử dụng I / O chữ thường hoặc chữ hoa (hoặc kết hợp!).

Mượn mã từ câu trả lời của tôi trên Substrings đã nổ để có được tất cả các chuỗi con, sau đó rút ra những thứ mà regex -matchchống lại ^[aeiou]{2,}$- tức là những cái có ít nhất hai nguyên âm dài và chỉ có nguyên âm. Các chuỗi được để lại trên đường ống và đầu ra là ẩn.


2

Haskell , 148 137 130 123 118 byte

Cảm ơn @Laikoni cho -11 byte, hơn -7 byte bằng cách chỉ cho tôi các mẹo chơi gôn, -7 byte khác và -5 byte khác, với tổng số -30 byte.

Điều này có vẻ phù hợp với Haskell nhưng kết quả dường như không đồng ý. Tôi đoán rằng Haskell là một lựa chọn OK-ish sau tất cả. Tôi vẫn khó chịu bởi cách subsequenceslàm việc mặc dù.

import Data.List
v=(`elem`"aeiou")
p s=nub$do x<-groupBy((.v).(&&).v)s;[y|y@(c:_:_)<-subsequences x,v c,y`isInfixOf`x]

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


1
Chào mừng bạn đến với golf Haskell! Bạn có thể quan tâm đến bộ sưu tập các mẹo chơi gôn của chúng tôi , hướng dẫn về các quy tắc chơi golfOf Monads and Men , phòng trò chuyện Haskell của chúng tôi.
Laikoni

1
Một số lưu ý về câu trả lời của bạn: Dòng mới có cùng số byte như ;, nhưng tăng khả năng đọc mã. Bạn luôn luôn sử dụng ecùng với v, vì vậy bạn có thể trực tiếp khai báo e=(elem "aeiou"). y!!0ngắn hơn head y. Có concatMapthay vì concat.map, nhưng thậm chí ngắn hơn là (=<<)từ danh sách đơn nguyên có tác dụng tương tự.
Laikoni

1
Bạn có thể nhập Data.Liststhay vì Data.List. Cái trước có tất cả các chức năng của cái sau, nhưng cũng có những thứ bổ sung như powerslice, nó đưa ra một danh sách tất cả các chuỗi liên tục.
nimi

1
Trong danh sách hiểu, bạn có thể kết hợp trên y@(h:_:_)để thả length y>1và rút ngắn v(y!!0)tới v h.
Laikoni

1
Tôi có thêm hai cú át tay áo: (1) (\x y->v x&&v y)có thể rút ngắn bằng cách chuyển đổi sang không có điểm, bằng tay sử dụng mẹo này hoặc bằng cách sử dụng pointfree.io . (2) Danh sách đơn nguyên cũng có thể được sử dụng với doký hiệu, đó là do x<-l;[...]giống như l>>=(\x->[...]). Btw, trên TIO, bạn có thể đặt bạn mainvào trường đầu trang hoặc chân trang để có số byte phù hợp với trình thực tế.
Laikoni

2

Perl, 45 byte

local $,=" ";print $_=~/(?=([AEIOU]{2,}))/ig;

Chào mừng đến với PPCG! Bài đăng đầu tiên rất hay!
Rɪᴋᴇʀ

1
Trong trường hợp bạn đang tự hỏi về downvote, tài khoản bot Cộng đồng sẽ tự động được đặt vì bài đăng của bạn đã được chỉnh sửa. Xin lỗi, không có gì chúng tôi thực sự có thể làm về nó, đó là hành vi ngu ngốc. Hy vọng rằng các upvote sẽ kích hoạt rút lại downvote tự động.
HyperNeutrino

2

R , 120 byte 110 byte

function(x){k=nchar(x);i=k:1;e=expand.grid(i,i[-1]);grep("^[aeiou]+$",mapply(substr,x,e[,2],e[,2]+e[,1]),v=T)}

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

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

function(x){                  #initalize the anonymous function where input is stored in x
  k=nchar(x)                  #set k to the number of characters in x
  i=k:1                       #create vector of integers from k to 1
  e=expand.grid(i,i[-1])      #create matrix of full outer join on i 
                              #except in the second column, limit i to being less than k
  grep("^[aeiou]+$",          #search for strings made of only vowels
       mapply(substr,         #map the substring function
              x,              #with x as the string to subset
              e[,2],          #start at the second column of the outer join
              e[,2]+e[,1]     #end at the sum of the sum of the first and second columns
       ),
       v=T                    #if a match is found, return it's value
  )
}                             #by default, R returns the last line of a function

Cách tiếp cận tuyệt vời 105 byte , tôi sẽ thêm một nhận xét vào giải pháp của tôi và lưu ý rằng bạn đã vượt qua tôi :)
Giuseppe

Tôi sẽ thành thật, tôi rất hài lòng rằng tôi đã có thể đưa ra một giải pháp thay thế cho bạn :) Thông thường bạn đã đi trước tôi nhiều năm hoặc tìm ra tất cả các mã tôi để lại trên bàn.
Đánh dấu


1

JavaScript (ES6), 105 byte

s=>eval('a=[];l=i=s.length;while(i--){j=l;while(j--)if(/^[aeiou]{2,}$/.test(t=s.slice(i,j)))a.push(t)}a')

Có lẽ có rất nhiều golf còn lại để làm.

let f=
s=>eval('a=[];l=i=s.length;while(i--){j=l;while(j--)if(/^[aeiou]{2,}$/.test(t=s.slice(i,j)))a.push(t)}a')
console.log(JSON.stringify(f('r67^^()*6536782!87')))
console.log(JSON.stringify(f('programming puzzles and code golf')))
console.log(JSON.stringify(f('aaand... i won!')))
console.log(JSON.stringify(f('abeoic')))
console.log(JSON.stringify(f('yah eioo ala')))
console.log(JSON.stringify(f('@yabeeeayio__e')))
console.log(JSON.stringify(f('0ioen0aaiosnjksd')))



1

05AB1E , 10 byte

Œʒg≠}ʒžMм_

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

Giải thích:

Œʒg≠}ʒžMм_  
Œ            Push all substrings (abeoic => a, b, e, ..., eoi, eoc, ... abeioc)
 ʒ  }        Filter elements for which result is 1
  g≠            Push 1 if length is != 1, 0 otherwise
     ʒ       Filter elements for which result is 1
      žMм       Remove all occurences of 'aeiou' from element
         _      Negative bool: push 1 if length == 0, 0 otherwise

Câu trả lời tốt đẹp! Tôi đã cóŒʒžMм_}ʒg≠
Ông Xcoder

@ Mr.Xcoder Cảm ơn. Tôi cũng đã có ŒD1ùKʒžMм_10 byte. Tôi đang cố gắng tìm cách để đánh golf xuống
scottinet

1

C, 105 75 byte

Một hàm chấp nhận một con trỏ để nhập chữ thường và tạo các chuỗi được phân tách bằng dấu cách trên đầu ra tiêu chuẩn:

i;f(char*p){for(i=strspn(p,"aeiou");i>1;)printf("%.*s ",i--,p);*p&&f(p+1);}

Chương trình kiểm tra

#include <stdio.h>

int main(int argc, char **argv)
{
    for (int i = 1;  i < argc;  ++i) {
        char *in = argv[i];
        printf("'%s' -> [ ", in);
        f(in);
        puts("]");
    }
}

Bản giới thiệu

'r67^^()*6536782!87' -> [ ]
'programming puzzles and code golf' -> [ ]
'aaand... i won!' -> [ aaa aa aa ]
'abeoic' -> [ eoi eo oi ]
'yah eioo ala' -> [ eioo eio ei ioo io oo ]
'@yabeeeayio__e' -> [ eeea eee ee eea ee ea io ]
'0ioen0aaiosnjksd' -> [ ioe io oe aaio aai aa aio ai io ]

Giải trình

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

void find_polyphthongs(char *p)
{
    /* from longest polyphthong substring down to 2 */
    for (int i = strspn(p,"aeiou");  i >= 2;  --i) {
        /* print exactly [p .. p+i] */
        printf("%.*s ", i, p);
    }

    /* tail-recurse to next char */
    if (*p) {
        find_polyphthongs(p+1);
    }
}

Sử dụng GCC trên Debian Linux, tôi dường như thoát khỏi các khai báo ngầm không tương thích của strchr()printf(). Các nền tảng khác có thể yêu cầu <stdio.h><string.h> được bao gồm.

Hãy thử trực tuyến (yêu cầu Javascript).


Không thể f(p)char*p;được f(char*p)?
Jonathan Frech

Hoàn toàn đúng - Ban đầu tôi có đầu ra cho bộ nhớ được cấp phát của người gọi : f(s,d)char*s,*d.
Toby Speight


1

APL (Dyalog) , 53 byte

Đây là một Dfn( d irect f unstio n ). Cách sử dụng là p '<argument>'. Cảnh báo công bằng: điều này không hiệu quả và hết thời gian cho input > 8 charactersTIO, nhưng hoạt động bình thường khi có đủ thời gian.

p←{(G∊⊃,/⌽,\∘⌽¨,\⌽⍵)/G←⊃,/{(,v∘.,⊢)⍣⍵⊢v'aeiou'}¨⍳≢1↓⍵}

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

Cảm ơn @ Adám cho 16 byte!

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

Điều này dễ hiểu hơn nếu chúng ta phá mã theo các phần nhỏ hơn:

  • Phần 1 - G←⊃,/{(,v∘.,⊢)⍣⍵⊢v←'aeiou'}¨⍳≢1↓⍵: Phần này của hàm lấy độ dài của đối số (phải) và trộn vectơ aeiouvới chính nó nhiều lần, mang lại mọi kết hợp có thể có của[2, length(right arg)] nguyên âm .
  • Phần 2 - (G∊⊃,/⌽,\∘⌽¨,\⌽⍵)/: Phần này kiểm tra (các) phần tử nào của G là thành viên của chuỗi con của đầu vào. Điều này trả về một vectơ boolean, với 1các chỉ số của các kết hợp nguyên âm có trong đầu vào và 0trong trường hợp không có. Vectơ kết quả sau đó được ánh xạ ( /) qua G, trả về các phần tử tương ứng với các giá trị trung thực.

Toàn bộ điều sau đó được giao cho p. p←không được bao gồm trong số byte bởi vì nó không cần thiết , nó chỉ làm cho việc sử dụng chức năng dễ dàng hơn.


Chơi gôn thêm. Ngoài ra, bạn không nên sử dụng để lọc. Sử dụng /.
Adám


1

Ruby 2.4, 100 byte

(2..(b=(a=gets).size-1)).to_a.flat_map{|i|(0..(b-i)).to_a.map{|j|a[j,i]}}.select{|k|k=~/^[aeiou]+$/}

Đây là nỗ lực đầu tiên của tôi khi chơi golf và tôi chắc chắn có rất nhiều cách để rút ngắn mã này.




0

T-SQL (SQL Server 2014), 281 byte

;with s as(select substring(@,1,1)C,stuff(@,1,1,'')D,1 R union all select substring(D,1,1),stuff(D,1,1,''),R+1from s where len(D)>0),c as(select R i,C w from s where C LIKE'[aeiou]'union all select R,w+C from c join s ON i+1=R where s.C LIKE'[aeiou]')select w from c where len(w)>1

Đầu vào cho bởi

declare @ varchar(max) = 'abeoic'

Sử dụng một biểu thức bảng chung sđể thổi đầu vào thành các chữ cái riêng lẻ được sắp xếp và sau đó một biểu thức bảng chung thứ hai cđể tạo ra tất cả các kết hợp có thứ tự, loại bỏ các nguyên âm không.

Câu đố SQL


0

PHP, 139 byte

function y($s){$p=[];$l=strlen($s);for($i=2;$i<=$l;$i++)for($j=0;$j<=$l-$i;$j++)strspn($a=substr($s,$j,$i),'aeiou')==$i&&$p[]=$a;return$p;}

Bản demo trực tuyến

function yreadable($s)
{
    $p = [];
    $l = strlen($s);
    for($i=2; $i<=$l; $i++)
        for($j=0; $j<=$l-$i; $j++)
            strspn($a=substr($s,$j,$i),'aeiou')==$i
            && $p[] = $a;
    return $p;
}

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

Chọn các chuỗi con (bắt đầu bằng độ dài 2) bao gồm các ký tự liền kề và di chuyển dọc theo chuỗi. Thu thập bất kỳ chuỗi con chỉ chứa nguyên âm. Lặp lại với các chuỗi con dài hơn.

Đối với chuỗi 'abcdef', đây là các chuỗi con được tạo và kiểm tra:

'ab','bc','cd','de','ef'
'abc','bcd','cde','def'
'abcd','bcde','cdef'
'abcde','bcdef',
'abcdef'
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.