1. 문제

www.codewars.com/kata/55b3425df71c1201a800009c

 

Codewars: Achieve mastery through challenge

Codewars is where developers achieve code mastery through challenge. Train on kata in the dojo and reach your highest potential.

www.codewars.com

문제 설명

You are the "computer expert" of a local Athletic Association (C.A.A.). Many teams of runners come to compete. Each time you get a string of all race results of every team who has run. For example here is a string showing the individual results of a team of 5 runners:

"01|15|59, 1|47|6, 01|17|20, 1|32|34, 2|3|17"

Each part of the string is of the form:h|m|swhere h, m, s (h for hour, m for minutes, s for seconds) are positive or null integer (represented as strings) with one or two digits. There are no traps in this format.

To compare the results of the teams you are asked for giving three statistics;range, average and median.

Range: difference between the lowest and highest values. In {4, 6, 9, 3, 7} the lowest value is 3, and the highest is 9, so the range is 9 − 3 = 6.

Mean or Average: To calculate mean, add together all of the numbers in a set and then divide the sum by the total count of numbers.

Median: In statistics, the median is the number separating the higher half of a data sample from the lower half. The median of a finite list of numbers can be found by arranging all the observations from lowest value to highest value and picking the middle one (e.g., the median of {3, 3, 5, 9, 11} is 5) when there is an odd number of observations. If there is an even number of observations, then there is no single middle value; the median is then defined to be the mean of the two middle values (the median of {3, 5, 6, 9} is (5 + 6) / 2 = 5.5).

the form:

"Range: hh|mm|ss Average: hh|mm|ss Median: hh|mm|ss"

where hh, mm, ss are integers (represented by strings) witheach 2 digits.

제한 사항

Remarks:

  1. if a result in seconds is ab.xy... it will be giventruncatedas ab.

  2. if the given string is "" you will return ""

입출력 예

input - "01|15|59, 1|47|6, 01|17|20, 1|32|34, 2|3|17"

result - "Range: hh|mm|ss Average: hh|mm|ss Median: hh|mm|ss"


2. 어떻게 풀까?

  1. input으로 들어온 time 문자열을 쪼갠다.
  2. 각 time 문자열을 시간, 분, 초를 계산해서, 혹은 LocalTime을 이용해서 List에 저장 후 정렬한다.
    • 전에 Time 패키지 공부 한 것을 써먹기 위해 LocalTime을 사용해서 해결
  3. List를 통해 Range, Average, Median을 구하고 String으로 표현한다.

3. 코드

테스트 코드

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;

import org.junit.Test;

public class StatTest {

  @Test
  public void testWhenInputIsEmptyString() {
    String expected = "";
    String input = "";
    assertThat(Stat.stat(input), is(expected));
  }

  @Test
  public void testWhenInputSizeIs1() {
    String expected = "Range: 00|00|00 Average: 00|15|00 Median: 00|15|00";
    String input = "0|15|0";
    assertThat(Stat.stat(input), is(expected));
  }

  @Test
  public void testWhenInputSizeIsOdd() {
    String expected = "Range: 01|01|18 Average: 01|38|05 Median: 01|32|34";
    String input = "01|15|59, 1|47|16, 01|17|20, 1|32|34, 2|17|17";
    assertThat(Stat.stat(input), is(expected));
  }

  @Test
  public void testWhenInputSizeIsEven() {
    String expected = "Range: 00|31|17 Average: 02|25|24 Median: 02|19|40";
    String input = "02|15|59, 2|47|16, 02|17|20, 2|32|34, 2|17|17, 2|22|00";
    assertThat(Stat.stat(input), is(expected));
  }

}

실제 코드


import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class Stat {

  public static String stat(String strg) {
    if (strg.isEmpty()) {
      return "";
    }
    List<LocalTime> list = getSortedTimeList(strg);

    LocalTime range = getRange(list);
    LocalTime average = getAverage(list);
    LocalTime median = getMedian(list);

    return getResultString(range, average, median);
  }

  private static List<LocalTime> getSortedTimeList(String strg) {
    List<LocalTime> list = new ArrayList<>();
    String[] split = strg.split(", ");
    for (int i = 0; i < split.length; i++) {
      LocalTime temp = LocalTime.parse(split[i], DateTimeFormatter.ofPattern("H|mm|s"));
      list.add(temp);
    }
    list.sort(Comparator.naturalOrder());
    return list;
  }

  private static LocalTime getRange(List<LocalTime> list) {
    LocalTime min = list.get(0);
    LocalTime max = list.get(list.size() - 1);
    long seconds = min.until(max, ChronoUnit.SECONDS);

    return LocalTime.ofSecondOfDay(seconds);
  }

  private static LocalTime getAverage(List<LocalTime> list) {
    long seconds = 0;
    for (int i = 0; i < list.size(); i++) {
      seconds += list.get(i).toSecondOfDay();
    }
    return LocalTime.ofSecondOfDay(seconds / list.size());
  }

  private static LocalTime getMedian(List<LocalTime> list) {
    long seconds = 0;
    if (list.size() % 2 == 1) {
      seconds = list.get(list.size() / 2).toSecondOfDay();
    } else {
      seconds += list.get(list.size() / 2).toSecondOfDay();
      seconds += list.get(list.size() / 2 - 1).toSecondOfDay();
      seconds /= 2;
    }
    return LocalTime.ofSecondOfDay(seconds);
  }

  private static String getResultString(LocalTime range, LocalTime average, LocalTime median) {
    return String.format("Range: %s Average: %s Median: %s",
        range.format(DateTimeFormatter.ofPattern("HH|mm|ss")),
        average.format(DateTimeFormatter.ofPattern("HH|mm|ss")),
        median.format(DateTimeFormatter.ofPattern("HH|mm|ss")));
  }
}
  • getSortedTimeList() 에서 input 문자열을 ", "로 쪼갠 뒤 List에 저장 후 정렬했다.
  • getRange(), getAverage(), getMedian()에서 List에 저장한 LocalTime들을 계산했다.

4. 느낀 점

  • 문제를 처음 보고 '|'의 index를 통해 시, 분, 초를 구하고 그것들을 초로 바꾸어 List에 저장해서 정렬 후, range/average/medain을 계산하려 했는데, 전에 공부했던 Time 패키지의 LocalTime을 이용하면 쉽게 해결 할 수 있겠다고 생각해서 사용해 보았다.
  • List<LocalTime>을 정렬하면 정렬이 안될줄 알았는데 아주 잘 되서 신기했다.
  • LocalTime을 이용할 때, 전에 포스팅한 Time 패키지를 참고했다. 정리 해놓길 잘했다는 생각이 든다.
 

[Java] Time 패키지 (LocalTime, LocalDate, LocalDateTime)

1. Date, Calendar 클래스 이전 포스팅을 보자 jino-dev-diary.tistory.com/entry/Java-Date-Calendar-%ED%81%B4%EB%9E%98%EC%8A%A4?category=941695 요약하자면, Date 클래스와 Calendar 클래스는 문제점이 많아..

jino-dev-diary.tistory.com

 

+ Recent posts