[Programmers / JAVA] Level 1 Darts Game (17682)
[Programmers / JAVA] Level 1 Darts Game (17682)
| Rank | Language Used |
|---|---|
| Level 1 | 🖼️ JAVA |
The fourth star to appear on KakaoTalk! Bored? KakaoTalk GameStar~
For its new second-half service, KakaoTalk GameStar decided to launch a darts game. In the darts game, players throw darts at a dartboard three times and compete based on the total score, making it a game anyone can easily enjoy. Muji, who just joined the company, was recognized for his coding skills and put in charge of the core part of the game: the scoring logic. The scoring logic for the darts game is as follows.
- The darts game consists of a total of 3 chances.
- Each chance can earn a score from 0 to 10 points.
- Along with the score, there are Single(S), Double(D), and Triple(T) regions, and hitting each region raises the score to the 1st, 2nd, or 3rd power (score, score, score).
- There are optional Star Bonus(*) and Oops Bonus(#) options. Hitting the Star Bonus(*) doubles both that score and the score obtained right before it. Hitting the Oops Bonus(#) makes that score negative.
- The Star Bonus(*) can also appear on the first chance. In this case, only the score of the first Star Bonus(*) is doubled. (See example 4.)
- The effect of a Star Bonus(*) can stack with the effect of another Star Bonus(*). In this case, the overlapping Star Bonus(*) score becomes 4 times. (See example 4.)
- The effect of a Star Bonus(*) can stack with the effect of an Oops Bonus(#). In this case, the overlapping Oops Bonus(#) score becomes -2 times. (See example 5.)
- Single(S), Double(D), and Triple(T) each exist once per score.
- Only one of Star Bonus(*) or Oops Bonus(#) can exist per score, and it may also be absent.
Write a function that returns the total score when given a string composed of the integers 0 ~ 10 and the characters S, D, T, *, #.
Three sets of strings composed of "score|bonus|[option]".
Example) 1S2D*3T
- The score is an integer between 0 and 10.
- The bonus is one of S, D, T.
- The option is either * or #, and may be absent.
Print the integer value corresponding to the sum of the scores obtained across the 3 chances.
Example) 37
| Example | dartResult | answer | Explanation |
|---|---|---|---|
| 1 | 1S2D*3T | 37 | 11 * 2 + 22 * 2 + 33 |
| 2 | 1D2S#10S | 9 | 12 + 21 * (-1) + 101 |
| 3 | 1D2S0T | 3 | 12 + 21 + 03 |
| 4 | 1S*2T*3S | 23 | 11 * 2 * 2 + 23 * 2 + 31 |
| 5 | 1D#2S*3S | 5 | 12 * (-1) * 2 + 21 * 2 + 31 |
| 6 | 1T2D3D# | -4 | 13 + 22 + 32 * (-1) |
| 7 | 1D2S3T* | 59 | 12 + 21 * 2 + 33 * 2 |
The approach to solving this problem is trickier than it looks.
- The order is score - bonus - option, but the option may or may not be present.
- The Star Bonus(*) affects the previous score as well.
- A Star Bonus can also appear on the very first score, in which case there is no previous score, so only that score is affected.
Because of this, we need to be able to precisely separate each score set, and since we need to touch the previous score, it seems necessary to store the scores in an array-like structure.
- Split into score sets
- Split each score set into score, bonus, and option
- Multiply the score and bonus to get the base score
- Apply the option effect to the score
Steps 1 and 2 might seem tricky, but they can be split very easily using a regular expression.
- Score-splitting regex — ([0-9]0?)([SDT])([*#]?)
- [0-9] — a single digit from 0 to 9
- 0? — a 0 may or may not be present
- [SDT] — the bonus
- [*#] — a single *, # character
- [*#]? — a *, # may or may not be present
() does not affect the regex itself, but is used in code to split the matched pattern into groups.
In JAVA, the group() method can be used to extract patterns separately by the groups delimited with (). For example, with ([0-9]0?), only 2 can be extracted from 2S*.
- group(1) — 2
- group(2) — S
- group(3) — *
Once a single score set has been extracted via the regex, the rest can be solved entirely with just that one regex — no need to separately check for the presence of */#.
Once the score splitting is done successfully, the rest is easy. Multiply what needs multiplying, apply what needs applying, and store it in an array. If a Star Bonus shows up, just call up the previous data's score and apply the effect to it.
JAVA
import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Darts Game class * * @author RWB * @since 2021.12.12 Sun 17:55:08 */ class Solution { /** * Method that returns the answer * * @param dartResult: [String] score|bonus|option string (option is optional) * * @return [int] the answer */ public int solution(String dartResult) { int answer = 0; int index = 0; Matcher matcher = Pattern.compile("([0-9]0?)([SDT])([*#]?)").matcher(dartResult); ArrayList<Integer> scores = new ArrayList<>(); while (matcher.find()) { int type = matcher.group(2).equals("T") ? 3 : matcher.group(2).equals("D") ? 2 : 1; int option = matcher.group(3).equals("*") ? 2 : matcher.group(3).equals("#") ? -1 : 1; int score = (int) Math.pow(Integer.parseInt(matcher.group(1)), type) * option; scores.add(index, score); // If the index is greater than 0 and the Star Bonus was hit if (index > 0 && option == 2) { // The previous score is also doubled by the Star Bonus effect. scores.set(index - 1, scores.get(index - 1) * option); } index++; } for (Integer score : scores) { answer += score; } return answer; } }
A problem that can be solved very easily if you have a bit of understanding of regular expressions.
If you're curious about how the regex is used, take a close look at the parts of the code where matcher.group() is used.
