Exercise 1

Câu hỏi 1: Viết hàm tính diện tích của một hình chữ nhật. Sử dụng hàm để tính diện tích của hình chữ nhật có hai cạnh lần lượt là 3 và 7.

dien_tich <- function(dai, rong)
{
  S = dai * rong
  return(S)
}
dien_tich(3,7)

Câu hỏi 2: Viết hàm tính độ lệch chuẩn (Standard Deviation) của một vector có dạng dữ liệu là numeric.

do_lech_chuan <- function(x)
{
  sd(x)
}
x <- c(1,2,3,4,5,55,6,3)
do_lech_chuan(x)

Exercise 2

Giải nén bộ dữ liệu stock.rar rồi cho tất cả các file dữ liệu vào một thư mục có tên stock ở, ví dụ, ổ E. Lệnh dir() để xác định đường dẫn của tất cả các file dữ liệu sẽ là như sau:

# show all data files in folder: 
library(readr)
library(dplyr)
install.packages("plyr")
library(plyr)
all_data_paths <- dir("D:/stock", full.names = TRUE)
str(all_data_paths)
getwd()
#Question 4
data1 <- read.csv("D:/stock/excel_vnm.csv")
data2 <- read.csv("D:/stock/excel_fpt.csv")
data_total <- bind_rows(data1, data2)
#Question 5
data_all <- list.files(path = "D:/stock", pattern = "*.csv", full.names = TRUE) %>% 
  lapply(read_csv) %>% 
  bind_rows()
  • Câu hỏi 1: Kiểu dữ liệu (data type) của all_data_paths là gì?

  • Trả lời: Là kiểu dữ liệu character độ dài 32 ký tự

  • Câu hỏi 2: Có tồn tại file dữ liệu nào có ba chữ cái vnm hay không?

  • Trả lời: Tồn tại file dữ liệu có ký tự vnm trong folder stock

  • Câu hỏi 3: Có bao nhiêu file dữ liệu có kí hiệu ^?

  • Trả lời: Có 2 file có ký tự ^ trong folder stock

  • Câu hỏi 4: Đọc hai files dữ liệu lần lượt có các cụm từ vnmfpt rồi sử dụng lệnh bind_rows() để join hai bộ dữ liệu này thành một data frame duy nhất.

  • Câu hỏi 5: Lặp lại công việc ở câu hỏi 4 nhưng cho tất cả các files dữ liệu có trong thư mục stock. Gợi ý: sử dụng vòng lặp for loop với chú ý rằng để tạo một data frame trống chúng ta sử dụng lệnh df_space <- data.frame().

Exercise 3

Sử dụng bộ dữ liệu coronavirus.csv rồi dùng bar plot để hình ảnh hóa 10 quốc gia có số người chết cao nhất theo kiểu dưới đây:

Exercise 4

Vẫn sử dụng bộ dữ liệu coronavirus.csv. Tỉ lệ chết tại một ngày DDR (daily death rate) có thể được định nghĩa như sau:

\[DDR = death / (confirmed - recovered)\]

Trong đó death, confirmed, recovered lần lượt là số người chết, số người nhiễm mới và số người hồi phục tại một ngày được chọn.

  • Câu hỏi 1: Lấy ra quốc gia là US rồi tính toán DDR rồi trình bày dưới dạng một data frame dạng như sau:
# Create a fake data frame about daily death rate for US: 

us_sample_ddr <- data.frame(date = c("date_ymd: 2020-01-22", "date_ymd: 2020-01-23"), 
                            ddr = c(0.08, 0.07))


# Show data form: 
library(readr)
library(dplyr)
coronavirus <- read_csv("C:/Users/Admin/Desktop/Homework/coronavirus.csv")
coronavirus %>% 
  filter(country == "US") ->ddr_US

death_US <- ddr_US %>% filter(type == "death")
confirmed_US <- ddr_US %>% filter(type == "confirmed")
recover_US <- ddr_US %>% filter(type == "recovered")

ddr = death_US$cases/(confirmed_US$cases- recover_US$cases)
us_dataframe_ddr <- data.frame(date = ddr_US$date %>% unique(), ddr = ddr)
us_dataframe_ddr
  • Câu hỏi 2: Thực hiện công việc ở câu hỏi 1 nhưng cho tất cả các quốc gia trong bộ dữ liệu coronavirus.csv. Các hướng gợi ý: (1) bạn có thể sử dụng vòng lặp for loop, hoặc (2) chỉ sử dụng các hàm đã được học của dplyr, hoặc (3) kết hợp cả (1) và (2) để giải quyết vấn đề.
# Create a fake data frame about daily death rate for US: 

us_sample_ddr <- data.frame(date = c("date_ymd: 2020-01-22", "date_ymd: 2020-01-23"), 
                            ddr = c(0.08, 0.07))


# Show data form: 
library(dplyr)
library(readr)
coronavirus <- read_csv("C:/Users/Admin/Desktop/Homework/coronavirus.csv")
 coronavirus %>%
   group_by(country) %>%
   count() %>%
   ungroup() %>% 
   mutate(id = country)->country_count
   
 is.data.frame(country_count)
 str(country_count)
 head(country_count)
 quoc_gia <-  country_count$id
#n <- length(country_count$id)
#attach(country_count)
 tinh_ddr <- function(quoc_gia){
 # for (i in 1:n) {
 coronavirus %>% 
  filter(country == "US") -> ddr_US

death_US <- ddr_US %>% filter(type == "death")
confirmed_US <- ddr_US %>% filter(type == "confirmed")
recover_US <- ddr_US %>% filter(type == "recovered")

ddr = death_US$cases/(confirmed_US$cases- recover_US$cases)
dataframe_ddr <- data.frame(date = ddr_US$date %>% unique(), ddr = ddr)   


#}
return(dataframe_ddr)
 }
# Ví dụ tính ddr cho China, số thứ tự 37
View(tinh_ddr(quoc_gia [37]))

Notes

  • Các bài tập (dù làm đúng hay sai) phải được hoàn thành trước ngày 06-06.

  • Hình thức gửi bài: công bố trên Rpub rồi gửi link qua email.

LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgKERheSAyKSINCmF1dGhvcjogIkF1dGhvcjogVHJhbiBRdWFuZyBRdXkiDQpzdWJ0aXRsZTogIkFuc3dlciBmb3IgaG9tZXdvcmsgZGF5IDIiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICAjIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGhpZ2hsaWdodDogemVuYnVybg0KICAgICMgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogImZsYXRseSINCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCi0tLQ0KDQpgYGB7ciBzZXR1cCxpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA2KQ0KYGBgDQoNCg0KIyBFeGVyY2lzZSAxDQoNCkPDonUgaOG7j2kgMTogVmnhur90IGjDoG0gdMOtbmggZGnhu4duIHTDrWNoIGPhu6dhIG3hu5l0IGjDrG5oIGNo4buvIG5o4bqtdC4gU+G7rSBk4bulbmcgaMOgbSDEkeG7gyB0w61uaCBkaeG7h24gdMOtY2ggY+G7p2EgaMOsbmggY2jhu68gbmjhuq10IGPDsyBoYWkgY+G6oW5oIGzhuqduIGzGsOG7o3QgbMOgIDMgdsOgIDcuIA0KYGBge3IsIGV2YWw9RkFMU0V9DQoNCg0KZGllbl90aWNoIDwtIGZ1bmN0aW9uKGRhaSwgcm9uZykNCnsNCiAgUyA9IGRhaSAqIHJvbmcNCiAgcmV0dXJuKFMpDQp9DQpkaWVuX3RpY2goMyw3KQ0KDQpgYGANCg0KQ8OidSBo4buPaSAyOiBWaeG6v3QgaMOgbSB0w61uaCDEkeG7mSBs4buHY2ggY2h14bqpbiAoU3RhbmRhcmQgRGV2aWF0aW9uKSBj4bunYSBt4buZdCB2ZWN0b3IgY8OzIGThuqFuZyBk4buvIGxp4buHdSBsw6AgbnVtZXJpYy4NCmBgYHtyLCBldmFsPUZBTFNFfQ0KDQoNCmRvX2xlY2hfY2h1YW4gPC0gZnVuY3Rpb24oeCkNCnsNCiAgc2QoeCkNCn0NCnggPC0gYygxLDIsMyw0LDUsNTUsNiwzKQ0KZG9fbGVjaF9jaHVhbih4KQ0KDQpgYGANCg0KDQoNCiMgRXhlcmNpc2UgMg0KDQpHaeG6o2kgbsOpbiBi4buZIGThu68gbGnhu4d1ICoqc3RvY2sucmFyKiogcuG7k2kgY2hvIHThuqV0IGPhuqMgY8OhYyBmaWxlIGThu68gbGnhu4d1IHbDoG8gbeG7mXQgdGjGsCBt4bulYyBjw7MgdMOqbiAqc3RvY2sqIOG7nywgdsOtIGThu6UsICDhu5UgRS4gTOG7h25oIGBkaXIoKWAgxJHhu4MgeMOhYyDEkeG7i25oIMSRxrDhu51uZyBk4bqrbiBj4bunYSB04bqldCBj4bqjIGPDoWMgZmlsZSBk4buvIGxp4buHdSBz4bq9IGzDoCBuaMawIHNhdTogDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KDQojIHNob3cgYWxsIGRhdGEgZmlsZXMgaW4gZm9sZGVyOiANCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KaW5zdGFsbC5wYWNrYWdlcygicGx5ciIpDQpsaWJyYXJ5KHBseXIpDQphbGxfZGF0YV9wYXRocyA8LSBkaXIoIkQ6L3N0b2NrIiwgZnVsbC5uYW1lcyA9IFRSVUUpDQpzdHIoYWxsX2RhdGFfcGF0aHMpDQpnZXR3ZCgpDQojUXVlc3Rpb24gNA0KZGF0YTEgPC0gcmVhZC5jc3YoIkQ6L3N0b2NrL2V4Y2VsX3ZubS5jc3YiKQ0KZGF0YTIgPC0gcmVhZC5jc3YoIkQ6L3N0b2NrL2V4Y2VsX2ZwdC5jc3YiKQ0KZGF0YV90b3RhbCA8LSBiaW5kX3Jvd3MoZGF0YTEsIGRhdGEyKQ0KI1F1ZXN0aW9uIDUNCmRhdGFfYWxsIDwtIGxpc3QuZmlsZXMocGF0aCA9ICJEOi9zdG9jayIsIHBhdHRlcm4gPSAiKi5jc3YiLCBmdWxsLm5hbWVzID0gVFJVRSkgJT4lIA0KICBsYXBwbHkocmVhZF9jc3YpICU+JSANCiAgYmluZF9yb3dzKCkNCiAgDQpgYGANCg0KDQotIEPDonUgaOG7j2kgMTogS2nhu4N1IGThu68gbGnhu4d1IChkYXRhIHR5cGUpIGPhu6dhICphbGxfZGF0YV9wYXRocyogbMOgIGfDrD8gDQorIFRy4bqjIGzhu51pOiBMw6Aga2nhu4N1IGThu68gbGnhu4d1IGNoYXJhY3RlciDEkeG7mSBkw6BpIDMyIGvDvSB04buxDQoNCi0gQ8OidSBo4buPaSAyOiBDw7MgdOG7k24gdOG6oWkgZmlsZSBk4buvIGxp4buHdSBuw6BvIGPDsyBiYSBjaOG7ryBjw6FpICoqdm5tKiogaGF5IGtow7RuZz8gDQorICBUcuG6oyBs4budaTogVOG7k24gdOG6oWkgZmlsZSBk4buvIGxp4buHdSBjw7Mga8O9IHThu7EgKip2bm0qKiB0cm9uZyBmb2xkZXIgc3RvY2sNCi0gQ8OidSBo4buPaSAzOiBDw7MgYmFvIG5oacOqdSBmaWxlIGThu68gbGnhu4d1IGPDsyBrw60gaGnhu4d1ICoqXioqPyAgDQorIFRy4bqjIGzhu51pOiBDw7MgMiBmaWxlIGPDsyBrw70gdOG7sSAqKl4qKiB0cm9uZyBmb2xkZXIgc3RvY2sNCi0gQ8OidSBo4buPaSA0OiDEkOG7jWMgaGFpIGZpbGVzIGThu68gbGnhu4d1IGzhuqduIGzGsOG7o3QgY8OzIGPDoWMgY+G7pW0gdOG7qyAqKnZubSoqIHbDoCAqKmZwdCoqIHLhu5NpIHPhu60gZOG7pW5nIGzhu4duaCBgYmluZF9yb3dzKClgIMSR4buDIGpvaW4gaGFpIGLhu5kgZOG7ryBsaeG7h3UgbsOgeSB0aMOgbmggbeG7mXQgZGF0YSBmcmFtZSBkdXkgbmjhuqV0LiANCi0gQ8OidSBo4buPaSA1OiBM4bq3cCBs4bqhaSBjw7RuZyB2aeG7h2Mg4bufIGPDonUgaOG7j2kgNCBuaMawbmcgY2hvIHThuqV0IGPhuqMgY8OhYyBmaWxlcyBk4buvIGxp4buHdSBjw7MgdHJvbmcgdGjGsCBt4bulYyBzdG9jay4gR+G7o2kgw706IHPhu60gZOG7pW5nIHbDsm5nIGzhurdwICpmb3IgbG9vcCogduG7m2kgY2jDuiDDvSBy4bqxbmcgxJHhu4MgdOG6oW8gbeG7mXQgZGF0YSBmcmFtZSB0cuG7kW5nIGNow7puZyB0YSBz4butIGThu6VuZyBs4buHbmggYGRmX3NwYWNlIDwtIGRhdGEuZnJhbWUoKWAuIA0KDQoNCiMgRXhlcmNpc2UgMw0KDQpT4butIGThu6VuZyBi4buZIGThu68gbGnhu4d1ICoqY29yb25hdmlydXMuY3N2KiogcuG7k2kgZMO5bmcgYmFyIHBsb3QgxJHhu4MgaMOsbmgg4bqjbmggaMOzYSAxMCBxdeG7kWMgZ2lhIGPDsyBz4buRIG5nxrDhu51pIGNo4bq/dCBjYW8gbmjhuqV0IHRoZW8ga2nhu4N1IGTGsOG7m2kgxJHDonk6IA0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KDQojIExvYWQgc29tZSBSIHBhY2thZ2VzOiANCg0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQoNCg0KIyBMb2FkIGRhdGE6IA0KDQpjb3JvbmF2aXJ1cyA8LSByZWFkX2NzdigiQzovVXNlcnMvQWRtaW4vRGVza3RvcC9Ib21ld29yay9jb3JvbmF2aXJ1cy5jc3YiKQ0KDQoNCiMgVG9wIDEwIGJ5IHRvdGFsIGRlYXRoOiANCg0KY29yb25hdmlydXMgJT4lIA0KICBmaWx0ZXIodHlwZSA9PSAiZGVhdGgiKSAlPiUgDQogIGdyb3VwX2J5KGNvdW50cnkpICU+JSANCiAgc3VtbWFyaXNlKHRvdGFsX2RlYXRoID0gc3VtKGNhc2VzKSkgJT4lIA0KICB1bmdyb3VwKCkgJT4lIA0KICBhcnJhbmdlKC10b3RhbF9kZWF0aCkgJT4lIA0KICBzbGljZSgxOjEwKSAtPiBkZl90b3AxMA0KDQoNCiMgUmVhcnJhbmdlIGRhdGEgZnJhbWU6IA0KDQpkZl90b3AxMCAlPiUgDQogIGFycmFuZ2UodG90YWxfZGVhdGgpICU+JSANCiAgbXV0YXRlKG5hdGlvbiA9IGZhY3Rvcihjb3VudHJ5LCBsZXZlbHMgPSBjb3VudHJ5KSkgLT4gZGZfdG9wMTANCg0KDQojIE5hdGlvbnMgd2l0aCBudW1iZXIgb2YgZGVhdGhzID4gMTAwMDA6IA0KDQpkZl90ZXh0MSA8LSBkZl90b3AxMCAlPiUgZmlsdGVyKHRvdGFsX2RlYXRoID4gMTAwMDApDQoNCm92ZXJfMTAgPC0gZGZfdGV4dDEgJT4lIHB1bGwoY291bnRyeSkNCg0KDQojIE5hdGlvbnMgd2l0aCBudW1iZXIgb2YgZGVhdGhzIDwgMTAwMDA6IA0KDQpkZl90ZXh0MiA8LSBkZl90b3AxMCAlPiUgZmlsdGVyKCFjb3VudHJ5ICVpbiUgb3Zlcl8xMCkNCg0KDQojIEJhciBwbG90OiANCg0KZGZfdG9wMTAgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBjb3VudHJ5LCB5ID0gdG90YWxfZGVhdGgpKSArIA0KICBnZW9tX2NvbCgpICsgDQogIGNvb3JkX2ZsaXAoKSArIA0KICBnZW9tX3RleHQoZGF0YSA9IGRmX3RleHQxLCBhZXMobGFiZWwgPSB0b3RhbF9kZWF0aCksIGhqdXN0ID0gMS4xLCBjb2xvciA9ICJ3aGl0ZSIpICsgDQogIGdlb21fdGV4dChkYXRhID0gZGZfdGV4dDIsIGFlcyhsYWJlbCA9IHRvdGFsX2RlYXRoKSwgaGp1c3QgPSAtMC4xLCBjb2xvciA9ICJyZWQiKQ0KDQoNCmBgYA0KDQoNCg0KIyBFeGVyY2lzZSA0DQoNClbhuqtuIHPhu60gZOG7pW5nIGLhu5kgZOG7ryBsaeG7h3UgKipjb3JvbmF2aXJ1cy5jc3YqKi4gVOG7iSBs4buHIGNo4bq/dCB04bqhaSBt4buZdCBuZ8OgeSBERFIgKGRhaWx5IGRlYXRoIHJhdGUpIGPDsyB0aOG7gyDEkcaw4bujYyDEkeG7i25oIG5naMSpYSBuaMawIHNhdTogDQoNCg0KJCRERFIgPSBkZWF0aCAvIChjb25maXJtZWQgLSByZWNvdmVyZWQpJCQNCg0KDQpUcm9uZyDEkcOzIGRlYXRoLCBjb25maXJtZWQsIHJlY292ZXJlZCBs4bqnbiBsxrDhu6N0IGzDoCBz4buRIG5nxrDhu51pIGNo4bq/dCwgc+G7kSBuZ8aw4budaSBuaGnhu4VtIG3hu5tpIHbDoCBz4buRIG5nxrDhu51pIGjhu5NpIHBo4bulYyB04bqhaSBt4buZdCBuZ8OgeSDEkcaw4bujYyBjaOG7jW4uIA0KDQoNCi0gQ8OidSBo4buPaSAxOiBM4bqleSByYSBxdeG7kWMgZ2lhIGzDoCBVUyBy4buTaSB0w61uaCB0b8OhbiBERFIgcuG7k2kgdHLDrG5oIGLDoHkgZMaw4bubaSBk4bqhbmcgbeG7mXQgZGF0YSBmcmFtZSBk4bqhbmcgbmjGsCBzYXU6IA0KDQoNCmBgYHtyLCBldmFsPUZBTFNFfQ0KDQojIENyZWF0ZSBhIGZha2UgZGF0YSBmcmFtZSBhYm91dCBkYWlseSBkZWF0aCByYXRlIGZvciBVUzogDQoNCnVzX3NhbXBsZV9kZHIgPC0gZGF0YS5mcmFtZShkYXRlID0gYygiZGF0ZV95bWQ6IDIwMjAtMDEtMjIiLCAiZGF0ZV95bWQ6IDIwMjAtMDEtMjMiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGRyID0gYygwLjA4LCAwLjA3KSkNCg0KDQojIFNob3cgZGF0YSBmb3JtOiANCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KGRwbHlyKQ0KY29yb25hdmlydXMgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL0FkbWluL0Rlc2t0b3AvSG9tZXdvcmsvY29yb25hdmlydXMuY3N2IikNCmNvcm9uYXZpcnVzICU+JSANCiAgZmlsdGVyKGNvdW50cnkgPT0gIlVTIikgLT5kZHJfVVMNCg0KZGVhdGhfVVMgPC0gZGRyX1VTICU+JSBmaWx0ZXIodHlwZSA9PSAiZGVhdGgiKQ0KY29uZmlybWVkX1VTIDwtIGRkcl9VUyAlPiUgZmlsdGVyKHR5cGUgPT0gImNvbmZpcm1lZCIpDQpyZWNvdmVyX1VTIDwtIGRkcl9VUyAlPiUgZmlsdGVyKHR5cGUgPT0gInJlY292ZXJlZCIpDQoNCmRkciA9IGRlYXRoX1VTJGNhc2VzLyhjb25maXJtZWRfVVMkY2FzZXMtIHJlY292ZXJfVVMkY2FzZXMpDQp1c19kYXRhZnJhbWVfZGRyIDwtIGRhdGEuZnJhbWUoZGF0ZSA9IGRkcl9VUyRkYXRlICU+JSB1bmlxdWUoKSwgZGRyID0gZGRyKQ0KdXNfZGF0YWZyYW1lX2Rkcg0KDQoNCg0KYGBgDQoNCg0KLSBDw6J1IGjhu49pIDI6IFRo4buxYyBoaeG7h24gY8O0bmcgdmnhu4djIOG7nyBjw6J1IGjhu49pIDEgbmjGsG5nIGNobyB04bqldCBj4bqjIGPDoWMgcXXhu5FjIGdpYSB0cm9uZyBi4buZIGThu68gbGnhu4d1IGNvcm9uYXZpcnVzLmNzdi4gQ8OhYyBoxrDhu5tuZyBn4bujaSDDvTogKDEpIGLhuqFuIGPDsyB0aOG7gyBz4butIGThu6VuZyB2w7JuZyBs4bq3cCBmb3IgbG9vcCwgaG/hurdjICgyKSBjaOG7iSBz4butIGThu6VuZyBjw6FjIGjDoG0gxJHDoyDEkcaw4bujYyBo4buNYyBj4bunYSBkcGx5ciwgaG/hurdjICgzKSBr4bq/dCBo4bujcCBj4bqjICgxKSB2w6AgKDIpIMSR4buDIGdp4bqjaSBxdXnhur90IHbhuqVuIMSR4buBLiANCg0KYGBge3IsIGV2YWw9RkFMU0V9DQoNCiMgQ3JlYXRlIGEgZmFrZSBkYXRhIGZyYW1lIGFib3V0IGRhaWx5IGRlYXRoIHJhdGUgZm9yIFVTOiANCg0KdXNfc2FtcGxlX2RkciA8LSBkYXRhLmZyYW1lKGRhdGUgPSBjKCJkYXRlX3ltZDogMjAyMC0wMS0yMiIsICJkYXRlX3ltZDogMjAyMC0wMS0yMyIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZHIgPSBjKDAuMDgsIDAuMDcpKQ0KDQoNCiMgU2hvdyBkYXRhIGZvcm06IA0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpjb3JvbmF2aXJ1cyA8LSByZWFkX2NzdigiQzovVXNlcnMvQWRtaW4vRGVza3RvcC9Ib21ld29yay9jb3JvbmF2aXJ1cy5jc3YiKQ0KIGNvcm9uYXZpcnVzICU+JQ0KICAgZ3JvdXBfYnkoY291bnRyeSkgJT4lDQogICBjb3VudCgpICU+JQ0KICAgdW5ncm91cCgpICU+JSANCiAgIG11dGF0ZShpZCA9IGNvdW50cnkpLT5jb3VudHJ5X2NvdW50DQogICANCiBpcy5kYXRhLmZyYW1lKGNvdW50cnlfY291bnQpDQogc3RyKGNvdW50cnlfY291bnQpDQogaGVhZChjb3VudHJ5X2NvdW50KQ0KIHF1b2NfZ2lhIDwtICBjb3VudHJ5X2NvdW50JGlkDQojbiA8LSBsZW5ndGgoY291bnRyeV9jb3VudCRpZCkNCiNhdHRhY2goY291bnRyeV9jb3VudCkNCiB0aW5oX2RkciA8LSBmdW5jdGlvbihxdW9jX2dpYSl7DQogIyBmb3IgKGkgaW4gMTpuKSB7DQogY29yb25hdmlydXMgJT4lIA0KICBmaWx0ZXIoY291bnRyeSA9PSAiVVMiKSAtPiBkZHJfVVMNCg0KZGVhdGhfVVMgPC0gZGRyX1VTICU+JSBmaWx0ZXIodHlwZSA9PSAiZGVhdGgiKQ0KY29uZmlybWVkX1VTIDwtIGRkcl9VUyAlPiUgZmlsdGVyKHR5cGUgPT0gImNvbmZpcm1lZCIpDQpyZWNvdmVyX1VTIDwtIGRkcl9VUyAlPiUgZmlsdGVyKHR5cGUgPT0gInJlY292ZXJlZCIpDQoNCmRkciA9IGRlYXRoX1VTJGNhc2VzLyhjb25maXJtZWRfVVMkY2FzZXMtIHJlY292ZXJfVVMkY2FzZXMpDQpkYXRhZnJhbWVfZGRyIDwtIGRhdGEuZnJhbWUoZGF0ZSA9IGRkcl9VUyRkYXRlICU+JSB1bmlxdWUoKSwgZGRyID0gZGRyKSAgIA0KDQoNCiN9DQpyZXR1cm4oZGF0YWZyYW1lX2RkcikNCiB9DQojIFbDrSBk4bulIHTDrW5oIGRkciBjaG8gQ2hpbmEsIHPhu5EgdGjhu6kgdOG7sSAzNw0KVmlldyh0aW5oX2RkcihxdW9jX2dpYSBbMzddKSkNCg0KDQpgYGANCiMgTm90ZXMNCg0KLSBDw6FjIGLDoGkgdOG6rXAgKGTDuSBsw6BtIMSRw7puZyBoYXkgc2FpKSBwaOG6o2kgxJHGsOG7o2MgaG/DoG4gdGjDoG5oIHRyxrDhu5tjIG5nw6B5IDA2LTA2LiANCg0KLSBIw6xuaCB0aOG7qWMgZ+G7rWkgYsOgaTogY8O0bmcgYuG7kSB0csOqbiBScHViIHLhu5NpIGfhu61pIGxpbmsgcXVhIGVtYWlsLiANCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=