A weekend farm has n plots numbered 1 to n.
Each plot has one record, which holds a crop name, the number of times it was watered, and the amount harvested.
At the start every plot has crop name -, watered 0 times, and harvested amount 0.
There are three commands.
plant k name changes the crop name of plot k to that name and resets its watering count to 0 (the harvested amount is left as it is).
water k increases the watering count of plot k by 1.
pick k g increases the harvested amount of plot k by g.
water and pick are given only for plots where a crop has been planted at least once.
The first line gives n and the number of commands q, separated by a single space, and each of the next q lines gives one command.
After processing all commands in order, print for each plot, starting from plot 1, one line with its crop name, watering count and harvested amount, separated by single spaces.
Input
1 ≤ n ≤ 100, 1 ≤ q ≤ 1,000, 1 ≤ k ≤ n, 1 ≤ g ≤ 1,000. A crop name is a string of 1 to 10 lowercase English letters
Output
n lines: for each plot, its crop name, watering count and harvested amount (digits only, no commas)
Example 1 · stdin
4 9
plant 2 carrot
water 2
water 2
pick 2 300
plant 4 corn
water 4
plant 2 bean
water 2
pick 2 50
stdout
- 0 0
bean 1 350
- 0 0
corn 1 0
main.py
Error List00F8 ↓ · ⇧F8 ↑
Input (stdin)
When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).
$ Ready
Open this on a computer to write and run code. On mobile you can read the problem and the solutions.
In other languagesShow solutions by language · 8 languages
This problem stores n records, each bundling several values, in a list. A record is a Python dict {"crop": "-", "water": 0, "total": 0}, a JS object, in TS an object whose shape is written as interface Plot, in Java and C# a class Plot, in C and C++ a struct Plot, and in Craykon it is made with Dict(). Making a separate record for every slot: Python [{...} for _ in range(n)], JS/TS Array.from({ length: n }, () => ({...})), Java and C# new Plot[n] followed by a loop that does new Plot() for each slot, C++ std::vector<Plot> plots(n), C struct Plot plots[100], and Craykon plots.Add(NewPlot()) in a loop. In C and C++ the array or vector contains the records themselves; in the other languages each list slot points to a record. Three traps: (1) If you make one record and fill n slots with it, every slot points to that same single record, so changing one plot changes them all (in the example all four lines become bean 1 350). Python [{...}] * n, JS Array(n).fill({...}), Java Arrays.fill(plots, new Plot()) and Craykon NewList(n, NewPlot()) all do this. (2) In Java, if you only write new Plot[n] and put no records in, every slot is null and the first command stops with a NullPointerException. (3) In the other direction, C and C++ structs and C# structs are copied when you take them out. With C struct Plot p = plots[k - 1];, C++ Plot plot = plots[k - 1];, or C# with Plot declared as a struct and Plot plot = plots[k - 1];, the changes go to the copy and the record in the list stays as it was (in the example all four lines become - 0 0). In C take a pointer &plots[k - 1], in C++ a reference Plot& plot, and in C# make it a class.
Pythonmain.py · 18 lines
n, q = map(int, input().split())# 밭마다 기록(사전)을 따로 하나씩 만든다. 반복할 때마다 새 사전이 생긴다plots = [{"crop": "-", "water": 0, "total": 0} for _ in range(n)]for _ in range(q): cmd = input().split() plot = plots[int(cmd[1]) - 1] # 복사가 아니라 목록 안의 그 기록을 가리킨다 if cmd[0] == "plant": plot["crop"] = cmd[2] plot["water"] = 0 elif cmd[0] == "water": plot["water"] += 1 else: plot["total"] += int(cmd[2])for plot in plots: print(plot["crop"], plot["water"], plot["total"])
JavaScriptmain.js · 20 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, q] = lines[0].trim().split(/\s+/).map(Number);// 밭마다 기록(객체)을 따로 하나씩 만든다. Array.from은 칸마다 함수를 불러 새 객체를 만든다const plots = Array.from({ length: n }, () => ({ crop: "-", water: 0, total: 0 }));for (let i = 1; i <= q; i++) { const cmd = lines[i].trim().split(/\s+/); const plot = plots[Number(cmd[1]) - 1]; // 복사가 아니라 목록 안의 그 기록을 가리킨다 if (cmd[0] === "plant") { plot.crop = cmd[2]; plot.water = 0; } else if (cmd[0] === "water") { plot.water += 1; } else { plot.total += Number(cmd[2]); }}console.log(plots.map((p) => `${p.crop} ${p.water} ${p.total}`).join("\n"));
TypeScriptmain.ts · 28 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const [n, q]: number[] = lines[0].trim().split(/\s+/).map(Number);// 기록의 모양을 타입으로 적어 둔다interface Plot { crop: string; water: number; total: number;}// 밭마다 기록(객체)을 따로 하나씩 만든다. Array.from은 칸마다 함수를 불러 새 객체를 만든다const plots: Plot[] = Array.from({ length: n }, (): Plot => ({ crop: "-", water: 0, total: 0 }));for (let i = 1; i <= q; i++) { const cmd: string[] = lines[i].trim().split(/\s+/); const plot: Plot = plots[Number(cmd[1]) - 1]; // 복사가 아니라 목록 안의 그 기록을 가리킨다 if (cmd[0] === "plant") { plot.crop = cmd[2]; plot.water = 0; } else if (cmd[0] === "water") { plot.water += 1; } else { plot.total += Number(cmd[2]); }}console.log(plots.map((p: Plot) => `${p.crop} ${p.water} ${p.total}`).join("\n"));
JavaMain.java · 42 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { // 밭 하나의 기록 static class Plot { String crop = "-"; int water = 0; int total = 0; } public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(in.readLine()); int n = Integer.parseInt(st.nextToken()); int q = Integer.parseInt(st.nextToken()); // new Plot[n]은 칸만 만든다(모두 null). 칸마다 new Plot()으로 기록을 따로 만들어 넣는다 Plot[] plots = new Plot[n]; for (int i = 0; i < n; i++) plots[i] = new Plot(); for (int i = 0; i < q; i++) { st = new StringTokenizer(in.readLine()); String cmd = st.nextToken(); Plot plot = plots[Integer.parseInt(st.nextToken()) - 1]; // 복사가 아니라 그 기록을 가리킨다 if (cmd.equals("plant")) { plot.crop = st.nextToken(); plot.water = 0; } else if (cmd.equals("water")) { plot.water++; } else { plot.total += Integer.parseInt(st.nextToken()); } } StringBuilder out = new StringBuilder(); for (Plot p : plots) out.append(p.crop).append(' ').append(p.water).append(' ').append(p.total).append('\n'); System.out.print(out); }}
C#Main.cs · 40 lines
using System;using System.Text;// 밭 하나의 기록. class이므로 변수에 담으면 복사되지 않고 같은 기록을 가리킨다class Plot{ public string Crop = "-"; public int Water = 0; public int Total = 0;}class Program{ static void Main() { string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); int n = int.Parse(first[0]), q = int.Parse(first[1]); // new Plot[n]은 칸만 만든다(모두 null). 칸마다 new Plot()으로 기록을 따로 만들어 넣는다 var plots = new Plot[n]; for (int i = 0; i < n; i++) plots[i] = new Plot(); for (int i = 0; i < q; i++) { string[] cmd = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries); Plot plot = plots[int.Parse(cmd[1]) - 1]; if (cmd[0] == "plant") { plot.Crop = cmd[2]; plot.Water = 0; } else if (cmd[0] == "water") plot.Water++; else plot.Total += int.Parse(cmd[2]); } var sb = new StringBuilder(); foreach (Plot p in plots) sb.Append($"{p.Crop} {p.Water} {p.Total}\n"); Console.Write(sb); }}
C++main.cpp · 37 lines
#include <iostream>#include <string>#include <vector>// 밭 하나의 기록struct Plot { std::string crop = "-"; int water = 0; int total = 0;};int main() { int n, q; std::cin >> n >> q; // vector<Plot>(n)은 기록 n개를 따로따로 만든다 std::vector<Plot> plots(n); for (int i = 0; i < q; i++) { std::string cmd; int k; std::cin >> cmd >> k; // &를 붙여 참조로 받아야 목록 안의 그 기록을 고친다. &가 없으면 복사본이다 Plot& plot = plots[k - 1]; if (cmd == "plant") { std::cin >> plot.crop; plot.water = 0; } else if (cmd == "water") { plot.water++; } else { int g; std::cin >> g; plot.total += g; } } for (const Plot& p : plots) std::cout << p.crop << ' ' << p.water << ' ' << p.total << '\n';}
Cmain.c · 42 lines
#include <stdio.h>#include <string.h>/* 밭 하나의 기록 */struct Plot { char crop[11]; int water; int total;};int main(void) { int n, q; /* 구조체 배열은 기록 n개가 통째로 나란히 들어 있다 */ static struct Plot plots[100]; scanf("%d %d", &n, &q); for (int i = 0; i < n; i++) { strcpy(plots[i].crop, "-"); plots[i].water = 0; plots[i].total = 0; } for (int i = 0; i < q; i++) { char cmd[8]; int k; scanf("%7s %d", cmd, &k); /* 포인터로 배열 안의 그 기록을 가리킨다. struct Plot p = plots[k - 1]; 은 복사본이다 */ struct Plot *plot = &plots[k - 1]; if (strcmp(cmd, "plant") == 0) { scanf("%10s", plot->crop); plot->water = 0; } else if (strcmp(cmd, "water") == 0) { plot->water++; } else { int g; scanf("%d", &g); plot->total += g; } } for (int i = 0; i < n; i++) printf("%s %d %d\n", plots[i].crop, plots[i].water, plots[i].total); return 0;}
Craykonmain.cray · 44 lines
// 밭 하나의 기록을 새로 만든다. 부를 때마다 새 사전이 생긴다새밭(){ p = Dict(); p["crop"] = "-"; p["water"] = 0; p["total"] = 0; return p;}첫줄 = Console.ReadNumbers();n = 첫줄[0];q = 첫줄[1];// 칸마다 기록을 따로 만들어 넣는다plots = [];for (i = 0; i < n; i++){ plots.Add(새밭());}for (i = 0; i < q; i++){ cmd = Console.ReadLine().Trim().Split(); plot = plots[cmd[1].ToNumber() - 1]; // 복사가 아니라 목록 안의 그 기록을 가리킨다 if (cmd[0] == "plant") { plot["crop"] = cmd[2]; plot["water"] = 0; } else if (cmd[0] == "water") { plot["water"] += 1; } else { plot["total"] += cmd[2].ToNumber(); }}foreach (p in plots){ Console.WriteLine(p["crop"] + " " + p["water"] + " " + p["total"]);}