1. 문제
www.codewars.com/kata/56a32dd6e4f4748cc3000006
문제 설명
data and data1 are two strings with rainfall records of a few cities for months from January to December. The records of towns are separated by\n
. The name of each town is followed by:
data
and towns
can be seen in "Your Test Cases:".
Task:
- function:
mean(town, strng)
should return the average of rainfall for the citytown
and thestrng
data
ordata1
(In R and Julia this function is calledavg
). - function:
variance(town, strng)
should return the variance of rainfall for the citytown
and thestrng
data
ordata1
.
제한 사항
-
if functions
mean
orvariance
have as parametertown
a city which has no records return-1
or-1.0
(depending on the language) -
Don't truncate or round: the tests will pass if
abs(your\_result - test\_result) <= 1e-2
orabs((your\_result - test\_result) / test\_result) <= 1e-6
depending on the language. -
Shell tests only variance
-
A ref:http://www.mathsisfun.com/data/standard-deviation.html
-
data
anddata1
(can be named0
andd1
depending on the language; see "Sample Tests:") are adapted from:http://www.worldclimate.com
입출력 예
mean("London", data), 51.19(9999999999996)
variance("London", data), 57.42(833333333374)
2. 어떻게 풀까?
- 우선
data
가\n
으로 도시들이 구분되어 있고, 도시와 월별 rainfall은:
로 구분되어있다고 하니data
를 통해 각 도시와 rainfall을 split 하는 게 중요해 보인다. - 그 이후에는 각 rainfall들을 더해서 12로 나누어 평균값(mean)을 구하고, mean을 이용해서 variance도 구하면 되겠다.
- mean은 평균값인게 이해가 갔는데 variance는 뭔지 몰랐다. 근데 참고 링크를 보니까 딱 알겠더라.
- 제한 사항을 보니 입력의
town
이data
ordata1
에 존재하지 않으면 -1을 리턴하라고 한다.- 처음에는 입력으로 주어진 town에 대한 결과값만 리턴하면 되겠다. 생각했는데, 이 제한사항 때문에 Map을 이용해야겠다고 생각했다.
3. 코드
테스트 코드
package codeWars.kyu6.rainFall_20201117;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Test;
public class RainfallTest {
public static String data =
"Rome:Jan 81.2,Feb 63.2,Mar 70.3,Apr 55.7,May 53.0,Jun 36.4,Jul 17.5,Aug 27.5,Sep 60.9,Oct 117.7,Nov 111.0,Dec 97.9"
+
"\n" +
"London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9"
+
"\n" +
"Paris:Jan 182.3,Feb 120.6,Mar 158.1,Apr 204.9,May 323.1,Jun 300.5,Jul 236.8,Aug 192.9,Sep 66.3,Oct 63.3,Nov 83.2,Dec 154.7"
+
"\n" +
"NY:Jan 108.7,Feb 101.8,Mar 131.9,Apr 93.5,May 98.8,Jun 93.6,Jul 102.2,Aug 131.8,Sep 92.0,Oct 82.3,Nov 107.8,Dec 94.2"
+
"\n" +
"Vancouver:Jan 145.7,Feb 121.4,Mar 102.3,Apr 69.2,May 55.8,Jun 47.1,Jul 31.3,Aug 37.0,Sep 59.6,Oct 116.3,Nov 154.6,Dec 171.5"
+
"\n" +
"Sydney:Jan 103.4,Feb 111.0,Mar 131.3,Apr 129.7,May 123.0,Jun 129.2,Jul 102.8,Aug 80.3,Sep 69.3,Oct 82.6,Nov 81.4,Dec 78.2"
+
"\n" +
"Bangkok:Jan 10.6,Feb 28.2,Mar 30.7,Apr 71.8,May 189.4,Jun 151.7,Jul 158.2,Aug 187.0,Sep 319.9,Oct 230.8,Nov 57.3,Dec 9.4"
+
"\n" +
"Tokyo:Jan 49.9,Feb 71.5,Mar 106.4,Apr 129.2,May 144.0,Jun 176.0,Jul 135.6,Aug 148.5,Sep 216.4,Oct 194.1,Nov 95.6,Dec 54.4"
+
"\n" +
"Beijing:Jan 3.9,Feb 4.7,Mar 8.2,Apr 18.4,May 33.0,Jun 78.1,Jul 224.3,Aug 170.0,Sep 58.4,Oct 18.0,Nov 9.3,Dec 2.7"
+
"\n" +
"Lima:Jan 1.2,Feb 0.9,Mar 0.7,Apr 0.4,May 0.6,Jun 1.8,Jul 4.4,Aug 3.1,Sep 3.3,Oct 1.7,Nov 0.5,Dec 0.7";
public static String data1 =
"Rome:Jan 90.2,Feb 73.2,Mar 80.3,Apr 55.7,May 53.0,Jun 36.4,Jul 17.5,Aug 27.5,Sep 60.9,Oct 147.7,Nov 121.0,Dec 97.9"
+
"\n" +
"London:Jan 58.0,Feb 38.9,Mar 49.9,Apr 42.2,May 67.3,Jun 52.1,Jul 59.5,Aug 77.2,Sep 55.4,Oct 62.0,Nov 69.0,Dec 52.9"
+
"\n" +
"Paris:Jan 182.3,Feb 120.6,Mar 188.1,Apr 204.9,May 323.1,Jun 350.5,Jul 336.8,Aug 192.9,Sep 66.3,Oct 63.3,Nov 83.2,Dec 154.7"
+
"\n" +
"NY:Jan 128.7,Feb 121.8,Mar 151.9,Apr 93.5,May 98.8,Jun 93.6,Jul 142.2,Aug 131.8,Sep 92.0,Oct 82.3,Nov 107.8,Dec 94.2"
+
"\n" +
"Vancouver:Jan 155.7,Feb 121.4,Mar 132.3,Apr 69.2,May 85.8,Jun 47.1,Jul 31.3,Aug 37.0,Sep 69.6,Oct 116.3,Nov 154.6,Dec 171.5"
+
"\n" +
"Sydney:Jan 123.4,Feb 111.0,Mar 151.3,Apr 129.7,May 123.0,Jun 159.2,Jul 102.8,Aug 90.3,Sep 69.3,Oct 82.6,Nov 81.4,Dec 78.2"
+
"\n" +
"Bangkok:Jan 20.6,Feb 28.2,Mar 40.7,Apr 81.8,May 189.4,Jun 151.7,Jul 198.2,Aug 197.0,Sep 319.9,Oct 230.8,Nov 57.3,Dec 9.4"
+
"\n" +
"Tokyo:Jan 59.9,Feb 81.5,Mar 106.4,Apr 139.2,May 144.0,Jun 186.0,Jul 155.6,Aug 148.5,Sep 216.4,Oct 194.1,Nov 95.6,Dec 54.4"
+
"\n" +
"Beijing:Jan 13.9,Feb 14.7,Mar 18.2,Apr 18.4,May 43.0,Jun 88.1,Jul 224.3,Aug 170.0,Sep 58.4,Oct 38.0,Nov 19.3,Dec 2.7"
+
"\n" +
"Lima:Jan 11.2,Feb 10.9,Mar 10.7,Apr 10.4,May 10.6,Jun 11.8,Jul 14.4,Aug 13.1,Sep 23.3,Oct 1.7,Nov 0.5,Dec 10.7";
@Test
public void meanTest() {
assertThat(Rainfall.mean("London", data), is(51.199999999999996));
assertThat(Rainfall.mean("Beijing", data), is(52.416666666666664));
}
@Test
public void varianceTest() {
assertThat(Rainfall.variance("London", data), is(57.42833333333374));
assertThat(Rainfall.variance("Beijing", data), is(4808.37138888889));
}
@Test
public void whenDataHasNotTownTest() {
assertThat(Rainfall.mean("Lon", data), is(-1.0));
assertThat(Rainfall.variance("Lon", data), is(-1.0));
}
}
실제 코드
package codeWars.kyu6.rainFall_20201117;
import java.util.HashMap;
import java.util.Map;
public class Rainfall {
public static double mean(String town, String strng) {
Map<String, Double> townRainfallMeanMap = buildTownRainfallMeanMap(strng);
return townRainfallMeanMap.getOrDefault(town, -1.0);
}
private static Map<String, Double> buildTownRainfallMeanMap(String strng) {
Map<String, Double> townRainfallMeanMap = new HashMap<>();
String[] townAndMonthRainfalls = strng.split("\n");
for (String townAndMonthRainfall : townAndMonthRainfalls) {
String targetTown = townAndMonthRainfall.split(":")[0];
String[] monthRainfalls = townAndMonthRainfall.split(":")[1].split(",");
double sumOfRecords = 0;
for (String monthRainfall : monthRainfalls) {
sumOfRecords += Double.parseDouble(monthRainfall.split(" ")[1]);
}
townRainfallMeanMap.put(targetTown, sumOfRecords / 12);
}
return townRainfallMeanMap;
}
public static double variance(String town, String strng) {
Map<String, Double> townRainfallVarianceMap = buildTownRainfallVarianceMap(town, strng);
return townRainfallVarianceMap.getOrDefault(town, -1.0);
}
private static Map<String, Double> buildTownRainfallVarianceMap(String town, String strng) {
Map<String, Double> townRainfallVarianceMap = new HashMap<>();
double mean = mean(town, strng);
String[] townAndMonthRainfalls = strng.split("\n");
for (String townAndMonthRainfall : townAndMonthRainfalls) {
String targetTown = townAndMonthRainfall.split(":")[0];
String[] monthRainfalls = townAndMonthRainfall.split(":")[1].split(",");
double sumOfRecords = 0;
for (String monthRainfall : monthRainfalls) {
double rainfall = Double.parseDouble(monthRainfall.split(" ")[1]);
sumOfRecords += Math.pow((rainfall - mean), 2);
}
townRainfallVarianceMap.put(targetTown, sumOfRecords / 12);
}
return townRainfallVarianceMap;
}
}
mean()
과 variance()
둘 다 비슷하게 구현했다. data로 주어진 strng
을 \n
으로 쪼개 town별로 분리하고, 분리한 town String 배열에서 :
으로 쪼개 도시와 월별 rainfall로 분리했다. 그리고 rainfall끼리 전부 더해서 12로 나누어준 값을 map에 저장했다. varinace()
에서는 mean()
을 이용하여 variance를 구했다.
4. 느낀점
- 어렵지 않은 문제였다. String을 어떻게 잘 쪼개냐가 관건인 것 같다.
'Coding Test > Codewars' 카테고리의 다른 글
[Codewars] 6Kyu, Simple Frequency Sort (Java, Python) (0) | 2022.01.17 |
---|---|
코드워즈 - Square Matrix Multiplication (01/21) (java) (0) | 2021.01.21 |
코드워즈 - Statistics for an Athletic Association (12/14) (java) (0) | 2020.12.14 |
코드워즈 - Large Factorials (10/31) (java) (0) | 2020.10.31 |