Write a class for a game character.
A character object has a name, a maximum health m and a current health as fields. The current health starts at m.
Give the character three methods.
hit(d) lowers the health by d. The health never goes below 0; it stops at 0.
heal(h) raises the health by h. The health never goes above m; it stops at m.
A character whose health is 0 is down, so healing it changes nothing.
The status-string method turns the character into a string of the form "name health/m" (for example ann 7/10). If the health is 0, one space and the word down follow (for example ann 0/10 down).
Give the status-string method the name your language calls when it turns an object into a string (Python __str__, Java/JS/TS toString, C# ToString, C++ operator<<).
The first line gives the number of characters n and the number of commands q.
The next n lines give the name and the maximum health m of characters 1 to n, one per line.
The next q lines give one command each.
hit i d calls hit(d) on character i, and heal i h calls heal(h) on character i.
After each command, print the status string of character i on its own line.
After all commands, print on the last line the number of characters that are not down (health 1 or more).
Grading looks only at the output, so how you split the work into methods is not checked.
Input
1 ≤ n ≤ 100, 1 ≤ q ≤ 1,000, 1 ≤ m ≤ 1,000, 1 ≤ i ≤ n, 1 ≤ d ≤ 1,000, 1 ≤ h ≤ 1,000 (all integers, given as plain digits without commas). A name is 1 to 10 lowercase letters or digits, and several characters may share a name. Values on a line are separated by one space
Output
q lines, one per command, then a last line with the number of characters that are not down
Example 1 · stdin
2 6
ann 10
bo 5
hit 1 3
heal 1 5
hit 2 9
heal 2 3
hit 1 4
hit 2 1
stdout
ann 7/10
ann 10/10
bo 0/5 down
bo 0/5 down
ann 6/10
bo 0/5 down
1
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 · 6 languages
This problem takes only Python, JavaScript, TypeScript, Java, C# and C++, the languages with classes and methods (C has no methods, and Craykon cannot define classes yet). A method is a function that changes the values an object holds (hit, heal) or builds an answer from them (the status string). Each language has a fixed name for the method that turns an object into a string. In Python you write __str__, and print(hero) and str(hero) call it. In Java you write toString(), and System.out.println(hero) and "" + hero call it; in C# you write override string ToString(), and Console.WriteLine(hero) and $"{hero}" call it. In JS and TS you write toString(), and `${hero}, String(hero) and "" + hero` call it. C++ has no such method, so you write operator<< to make cout << hero work. Trap one: console.log(hero) in JS does not call toString; it shows the inside of the object, so the first line of the example becomes Hero { name: 'ann', maxHp: 10, hp: 7 }. Trap two: in C#, public string ToString() without override compiles with only a warning. But StringBuilder.Append(hero) calls the original object.ToString(), so every line is just the class name Hero. Trap three: in Java a different spelling such as tostring() is simply a new method, and the output is something like Main$Hero@55f96302. Put @Override above the method and this typo becomes a compile error. Trap four: keep the health between 0 and m inside the methods. Storing hp - d as it is turns the third line of the example into bo -4/5, and storing hp + h as it is turns the second line into ann 12/10. Use max(0, …) and min(m, …) in Python, Math.max and Math.min in JS, TS and Java, Math.Max and Math.Min in C#, std::max and std::min in C++. Trap five: heal must first ask whether the character is down. Without that check the fourth line of the example becomes bo 3/5 and a fallen character stands up again.
Pythonmain.py · 47 lines
import sysclass Hero: def __init__(self, name, max_hp): self.name = name self.max_hp = max_hp self.hp = max_hp # 체력은 가득 찬 채로 시작한다 def hit(self, d): self.hp = max(0, self.hp - d) # 0보다 작아지지 않는다 def heal(self, h): if self.hp == 0: # 쓰러진 캐릭터는 회복하지 못한다 return self.hp = min(self.max_hp, self.hp + h) def is_down(self): return self.hp == 0 # print(hero)·str(hero)·f"{hero}"가 부르는 메서드 def __str__(self): text = f"{self.name} {self.hp}/{self.max_hp}" return text + " down" if self.is_down() else textdef main(): lines = sys.stdin.read().split("\n") n, q = map(int, lines[0].split()) heroes = [] for i in range(1, n + 1): name, m = lines[i].split() heroes.append(Hero(name, int(m))) out = [] for i in range(n + 1, n + 1 + q): cmd, idx, amount = lines[i].split() hero = heroes[int(idx) - 1] if cmd == "hit": hero.hit(int(amount)) else: hero.heal(int(amount)) out.append(str(hero)) out.append(str(sum(1 for h in heroes if not h.is_down()))) print("\n".join(out))main()
JavaScriptmain.js · 44 lines
class Hero { constructor(name, maxHp) { this.name = name; this.maxHp = maxHp; this.hp = maxHp; // 체력은 가득 찬 채로 시작한다 } hit(d) { this.hp = Math.max(0, this.hp - d); // 0보다 작아지지 않는다 } heal(h) { if (this.hp === 0) return; // 쓰러진 캐릭터는 회복하지 못한다 this.hp = Math.min(this.maxHp, this.hp + h); } isDown() { return this.hp === 0; } // `${hero}`·String(hero)·"" + hero 가 부르는 메서드 toString() { const text = `${this.name} ${this.hp}/${this.maxHp}`; return this.isDown() ? text + " down" : text; }}const lines = require("fs").readFileSync(0, "utf8").split("\n");const [n, q] = lines[0].trim().split(" ").map(Number);const heroes = [];for (let i = 1; i <= n; i++) { const [name, m] = lines[i].trim().split(" "); heroes.push(new Hero(name, Number(m)));}const out = [];for (let i = n + 1; i <= n + q; i++) { const [cmd, idx, amount] = lines[i].trim().split(" "); const hero = heroes[Number(idx) - 1]; if (cmd === "hit") hero.hit(Number(amount)); else hero.heal(Number(amount)); out.push(`${hero}`); // console.log(hero)는 toString을 부르지 않는다}out.push(String(heroes.filter((h) => !h.isDown()).length));console.log(out.join("\n"));
import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.StringTokenizer;public class Main { static class Hero { private final String name; private final int maxHp; private int hp; Hero(String name, int maxHp) { this.name = name; this.maxHp = maxHp; this.hp = maxHp; // 체력은 가득 찬 채로 시작한다 } void hit(int d) { hp = Math.max(0, hp - d); // 0보다 작아지지 않는다 } void heal(int h) { if (hp == 0) return; // 쓰러진 캐릭터는 회복하지 못한다 hp = Math.min(maxHp, hp + h); } boolean isDown() { return hp == 0; } // println(hero)와 "" + hero 가 부르는 메서드. @Override가 이름 오타를 잡아 준다 @Override public String toString() { String text = name + " " + hp + "/" + maxHp; return isDown() ? text + " down" : text; } } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); int n = Integer.parseInt(st.nextToken()); int q = Integer.parseInt(st.nextToken()); Hero[] heroes = new Hero[n]; for (int i = 0; i < n; i++) { st = new StringTokenizer(br.readLine()); String name = st.nextToken(); heroes[i] = new Hero(name, Integer.parseInt(st.nextToken())); } StringBuilder sb = new StringBuilder(); for (int i = 0; i < q; i++) { st = new StringTokenizer(br.readLine()); String cmd = st.nextToken(); Hero hero = heroes[Integer.parseInt(st.nextToken()) - 1]; int amount = Integer.parseInt(st.nextToken()); if (cmd.equals("hit")) hero.hit(amount); else hero.heal(amount); sb.append(hero).append('\n'); // append(객체)가 toString을 부른다 } int up = 0; for (Hero h : heroes) if (!h.isDown()) up++; sb.append(up).append('\n'); System.out.print(sb); }}
C#Main.cs · 65 lines
using System;using System.Text;class Hero{ private readonly string name; private readonly int maxHp; private int hp; public Hero(string name, int maxHp) { this.name = name; this.maxHp = maxHp; hp = maxHp; // 체력은 가득 찬 채로 시작한다 } public void Hit(int d) { hp = Math.Max(0, hp - d); // 0보다 작아지지 않는다 } public void Heal(int h) { if (hp == 0) return; // 쓰러진 캐릭터는 회복하지 못한다 hp = Math.Min(maxHp, hp + h); } public bool IsDown => hp == 0; // Console.WriteLine(hero)와 $"{hero}"가 부르는 메서드. override를 빼면 불리지 않는다 public override string ToString() { string text = $"{name} {hp}/{maxHp}"; return IsDown ? text + " down" : text; }}class Program{ static void Main() { string[] first = Console.ReadLine()!.Trim().Split(' '); int n = int.Parse(first[0]), q = int.Parse(first[1]); var heroes = new Hero[n]; for (int i = 0; i < n; i++) { string[] p = Console.ReadLine()!.Trim().Split(' '); heroes[i] = new Hero(p[0], int.Parse(p[1])); } var sb = new StringBuilder(); for (int i = 0; i < q; i++) { string[] p = Console.ReadLine()!.Trim().Split(' '); Hero hero = heroes[int.Parse(p[1]) - 1]; int amount = int.Parse(p[2]); if (p[0] == "hit") hero.Hit(amount); else hero.Heal(amount); sb.Append(hero).Append('\n'); // Append(객체)가 ToString을 부른다 } int up = 0; foreach (Hero h in heroes) if (!h.IsDown) up++; sb.Append(up).Append('\n'); Console.Write(sb); }}
C++main.cpp · 58 lines
#include <algorithm>#include <iostream>#include <string>#include <vector>using namespace std;class Hero { string name_; int max_hp_; int hp_;public: Hero(const string& name, int max_hp) : name_(name), max_hp_(max_hp), hp_(max_hp) {} void hit(int d) { hp_ = max(0, hp_ - d); } // 0보다 작아지지 않는다 void heal(int h) { if (hp_ == 0) return; // 쓰러진 캐릭터는 회복하지 못한다 hp_ = min(max_hp_, hp_ + h); } bool is_down() const { return hp_ == 0; } // C++에는 toString이 없다. cout << hero 가 되도록 << 연산자를 만들어 준다 friend ostream& operator<<(ostream& os, const Hero& h) { os << h.name_ << ' ' << h.hp_ << '/' << h.max_hp_; if (h.is_down()) os << " down"; return os; }};int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; vector<Hero> heroes; for (int i = 0; i < n; i++) { string name; int m; cin >> name >> m; heroes.emplace_back(name, m); } for (int i = 0; i < q; i++) { string cmd; int idx, amount; cin >> cmd >> idx >> amount; Hero& hero = heroes[idx - 1]; // &가 없으면 복사본을 고치게 된다 if (cmd == "hit") hero.hit(amount); else hero.heal(amount); cout << hero << '\n'; } int up = 0; for (const Hero& h : heroes) if (!h.is_down()) up++; cout << up << '\n'; return 0;}