Menu
CoddyTech

Tổng kết theo tháng

Thuộc phần Logic và luồng điều khiển trong hành trình R của Coddy. Bài học 61 trên 64.

challenge icon

Thử thách

Trung bình

Thêm lệnh (command) MONTH. Giữ cho mọi lệnh từ các bước trước vẫn hoạt động chính xác như trước.

  • MONTH <YYYY-MM>: chỉ xét các khoản chi có ngày bắt đầu bằng tháng đó. Trả lời 2024-05: count 3, total 520.50, biggest rent kèm số khoản chi, tổng tiền với hai chữ số thập phân và danh mục của khoản chi lớn nhất trong tháng (chọn khoản đầu tiên nếu có nhiều khoản bằng nhau). Nếu không có khoản nào, trả lời 2024-05: no expenses.

Code được cung cấp truyền từng dòng đầu vào cho tracker() dưới dạng một lệnh và in mỗi câu trả lời được trả về trên một dòng riêng. Ngày được ghi theo định dạng YYYY-MM-DD, danh mục là các từ viết thường, và đầu vào chỉ chứa những lệnh đã mô tả đến lúc này.

Tự làm thử

tracker <- function(commands) {
  expenses <- data.frame(date = character(0), category = character(0), amount = numeric(0))
  replies <- c()
  for (cmd in commands) {
    parts <- strsplit(cmd, " ")[[1]]
    if (parts[1] == "ADD") {
      amount <- suppressWarnings(as.numeric(parts[4]))
      if (length(parts) != 4 || is.na(amount) || amount <= 0) {
        replies <- c(replies, paste("invalid:", cmd))
      } else {
        expenses <- rbind(expenses, data.frame(date = parts[2], category = parts[3], amount = amount))
        replies <- c(replies, sprintf("added %s %.2f", parts[3], amount))
      }
    } else if (parts[1] == "TOTAL") {
      replies <- c(replies, sprintf("total: %.2f, count: %d", sum(expenses$amount), nrow(expenses)))
    } else if (parts[1] == "CATEGORY") {
      if (nrow(expenses) == 0) {
        replies <- c(replies, "no expenses")
      } else {
        totals <- tapply(expenses$amount, expenses$category, sum)
        replies <- c(replies, sprintf("%s: %.2f", names(totals), totals))
      }
    } else if (parts[1] == "TOP") {
      n <- as.numeric(parts[2])
      ranked <- expenses[order(-expenses$amount, expenses$date), ]
      top <- head(ranked, n)
      if (nrow(top) == 0) {
        replies <- c(replies, "no expenses")
      } else {
        replies <- c(replies, sprintf("%s %s %.2f", top$date, top$category, top$amount))
      }
    }
  }
  replies
}

# Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
cat(tracker(input), sep = "\n")

Tất cả bài học trong Logic và luồng điều khiển

Tự luyện tập: Trình biên dịch R online