1
\$\begingroup\$

This is a homework question, and I have written the code but wasn't sure if I had picked the right data structure for this job and minimised time complexity. Can anyone give me some feedback, anything about space complexity or potential bugs that can occur is appreciated as well.

Problem Description

MagicTheGathering

Aim: deal with a series of command (SUMMON, KILL, HEAL). Each SUMMON command will create a monster and each monster has a initial HP value.

Each KILL command will kill the monster with the lowest HP. And each HEAL command applies to every monster in your list.

Input: N, the number of commands. Followed by N lines of commands.

Output: Each KILL command requires you to print the HP of the monster that was killed. At the end of the series of commands, print the HP of the remaining. monsters.

Input example:

8
SUMMON 30 
SUMMON 20 
SUMMON 50 
HEAL 5 
KILL 
SUMMON 7 
KILL
HEAL 10  

Output example:

25
7
45 65

Attempt

import java.util.*;
import java.util.stream.*; 

class  Yugioh {
    public static void main(String [] args) {
        Scanner sc = new Scanner(System.in);
        int count = sc.nextInt();
        PriorityQueue<Integer> queue = new PriorityQueue(Comparator.naturalOrder());
        for (int i =0;i<count;i++) {
            String cmd = sc.next();
            if (cmd.equals("SUMMON")) {
                int health = sc.nextInt();
                queue.add(health);
            } else if (cmd.equals("HEAL")) {
                int health = sc.nextInt();
                PriorityQueue<Integer> newQueue = new PriorityQueue<>(Comparator.naturalOrder());
                List<Integer> data = queue.stream().map(x -> x + health).collect(Collectors.toList());
                newQueue.addAll(data);
                queue = newQueue;
            } else if (cmd.equals("KILL")) {
                System.out.println(queue.poll());
            }
        }
        while (!queue.isEmpty()) {
            System.out.println(queue.poll());
        }
    }
}
\$\endgroup\$
1
\$\begingroup\$

You should use an ENUM or a class for the list of commands.

E.G:

public ENUM Command
{
    private String value;

    SUMMON("Summon"),
    ATTACK("Attack"),
    HEAL("Heal")

    public Command(String value) { this.value = value; };
}

// String cmd = Commands.valueOf(sc.next());
// if (cmd == Command.HEAL) ...
// ( Or better yet, use a switch statement)

You should also be dealing with invalid input. (E.g in the default of the switch).

You've mentioned Magic the gathering, but your class name is Yugioh. As we all know, those are two very different games.

The variable 'health' is declared twice, I don't think the name makes sense for 'Summon'.

The case for 'Heal' looks overly complicated. You shouldn't need to create a 'newQueue'. Try to take away X amount of health for each item (either using a for-loop or lambdas). No need to re-order the queue.

\$\endgroup\$
0
\$\begingroup\$

HEAL doesn't change the relative order. So there is no point in rebuilding queue. Keep a sum of total HEAL so far, and remember it for each monster. Then, when HEAL happens you just do totalHealSoFar++ and to display proper score on KILL return health+(totalHealSoFar-totalHealWhenThisMonsterWasCreated).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.