샘의 집은 양 옆으로 사과나무와 오렌지 나무가 있어서, 과일이 풍부하다. 아래 그림에서 빨간색 영역은 집을 기리킨다. 집의 영역은 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%의 테스트케이스에서 실패했다. 버퍼가 원인이었다. 아래와 같이 버퍼를 잡은 후 모든 테스트 케이스를 통과했다.
문제
입력 형식
출력 형식
제약
입력 예제
출력 예제
설명
구현
간단 구현
package main import ( "fmt" ) type Home struct { X0 int X1 int Apple []int Orange []int } func New(a1, a2 int) *Home { h := Home{X0: a1, X1: a2} if a1 > a2 { h = Home{X0: a2, X1: a1} } h.Apple = make([]int, 2) h.Orange = make([]int, 2) return &h } func (h *Home) PrintArea() { fmt.Println(h.X0, "~", h.X1) } func (h *Home) SetApplePoint(point int) { h.Apple[0] = point } func (h *Home) SetOrangePoint(point int) { h.Orange[0] = point } func (h *Home) AppleFallen(points []int) { p := h.Apple[0] for _, point := range points { switch { case p < h.X0: if (p+point) >= h.X0 && (p+point) <= h.X1 { h.Apple[1]++ } case p > h.X1: if (p+point) >= h.X0 && (p+point) <= h.X1 { h.Apple[1]++ } } } } func (h *Home) OrangeFallen(points []int) { p := h.Orange[0] for _, point := range points { switch { case p < h.X0: if (p+point) >= h.X0 && (p+point) <= h.X1 { h.Orange[1]++ } case p > h.X1: if (p+point) >= h.X0 && (p+point) <= h.X1 { h.Orange[1]++ } } } } func (h *Home) AppleCount() { fmt.Println(h.Apple[1]) } func (h *Home) OrangeCount() { fmt.Println(h.Orange[1]) } func main() { myHome := New(5, 10) myHome.SetApplePoint(2) myHome.SetOrangePoint(16) myHome.PrintArea() myHome.AppleFallen([]int{2, 3, 5, 6, 9}) myHome.AppleCount() myHome.OrangeFallen([]int{2, -7, -10}) myHome.OrangeCount() }중복을 제거한 좀 더 나은 구현
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") }옵저버 패턴을 이용한 구현
시행착오
scanner := bufio.NewScanner(os.Stdin) buf := make([]byte, 0, 64*1024) scanner.Buffer(buf, 1024*1024) scanner.Split(bufio.ScanLines)Recent Posts
Archive Posts
Tags