샘의 집은 양 옆으로 사과나무와 오렌지 나무가 있어서, 과일이 풍부하다. 아래 그림에서 빨간색 영역은 집을 기리킨다. 집의 영역은 s에서 부터 t 까지다. 사과나무는 집 왼쪽에 있고, 오렌지 나무는 오른쪽에 있다. 사과나무의 위치는 a 오랜제나무의 위치는 b라고 가정하자.
땅을 x축이라고 할 때, 과일이 땅에 떨어지면 x축의 위치에 값을 가질 것이다. 이때 과일이 떨어졌던 나무와의 거리 d를 계산 할 수 있을 것이다. 그림에서 사과의 경우 오른쪽방향으로 떨어졌으므로 양의 정수 값을 가진다.
땅에 떨어진 m개의 사과와 n개의 오렌지 가 있으며, 나무로 부터 떨어진 거리 d를 알고 있다면, 얼마나 많은 과일들이 샘의 집([s,t]) 에 떨어졌는지를 계산 할 수 있을 것이다. 샘의 집에 떨어진 사과와 오렌지의 갯수를 출력하라.
package main
import (
"fmt"
)
type Home struct {
X0 int
X1 int
FruitTree map[string][]int
}
func New(a1, a2 int) *Home {
h := Home{X0: a1, X1: a2}
h.FruitTree = make(map[string][]int)
if a1 > a2 {
h = Home{X0: a2, X1: a1}
}
return &h
}
func (h *Home) PrintArea() {
fmt.Println(h.X0, "~", h.X1)
}
func (h *Home) SetFruitTree(name string, point int) {
h.FruitTree[name] = []int{point, 0}
}
func (h *Home) FruitFallen(name string, points []int) {
p := h.FruitTree[name][0]
for _, point := range points {
switch {
case p < h.X0:
if (p+point) >= h.X0 && (p+point) <= h.X1 {
h.FruitTree[name][1]++
}
case p > h.X1:
if (p+point) >= h.X0 && (p+point) <= h.X1 {
h.FruitTree[name][1]++
}
}
}
}
func (h *Home) FruitCount(name string) {
fmt.Println(h.FruitTree[name][1])
}
func main() {
myHome := New(5, 10)
myHome.PrintArea()
myHome.SetFruitTree("apple", 2)
myHome.SetFruitTree("orange", 16)
myHome.FruitFallen("apple", []int{2, 3, 5, 6, 9})
myHome.FruitFallen("orange", []int{2, -7, -10})
myHome.FruitCount("apple")
myHome.FruitCount("orange")
}
쓸데없는 중복을 제거했다. 개선해보자.
옵저버 패턴을 이용한 구현
집 영역을 관찰하다가 과일이 떨어지면 계수하는 서비스에 맞는 구조인 것 같다.
시행착오
해커랭크는 표준입력으로 코드를 테스트 한다. 실제 제출하는 코드는 bufio.NewScanner(os.Stdin)으로 표준입력을 받아서 공백문자로 Split 한후 문자열을 Int 형으로 변환하는 등의 과정이 필요하다.
처음에는 아래와 같이 코드를 만들었다.
이렇게 해서 돌렸더니, 약 70%의 테스트케이스에서 실패했다. 버퍼가 원인이었다. 아래와 같이 버퍼를 잡은 후 모든 테스트 케이스를 통과했다.
문제
입력 형식
출력 형식
제약
입력 예제
출력 예제
설명
구현
간단 구현
중복을 제거한 좀 더 나은 구현
옵저버 패턴을 이용한 구현
시행착오
Recent Posts
Archive Posts
Tags