aboutsummaryrefslogtreecommitdiff
path: root/challenge-084/jeongoon/go/ch-2.go
blob: 0316bee075c77aaea3bfffea93c0d7e09bb51869 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package main

import (
	"os"
	"bufio"
	"fmt"
	"strings"
)

func usage() {
	fmt.Println( "Usage: echo [1101][1100][0111][1011]' | go run ch-2.go" )
}

// this function will ignore any other information but "0","1","]"
func getPointsFromMatrixLines (raw string) [][]int {
	var rowsOut [][]int
	// remove new lines separated by []
	lines  := strings.Split(raw, "\n")
	joined := strings.Join(lines,  "")
	matrixlines := strings.Split(joined, "]")

	for ln, line := range matrixlines {
		x := 0
		var points []int
		// cqollect useful data only
		for _, singleStr := range line {
			switch string(singleStr) {
			case "1":
				points = append( points, x )
				x++
			case "0":
				x++
			case "[": // okay but not used
			case " ":
			default:
				fmt.Fprintf( os.Stderr,
					"Wrong character(%s) at row: %d\n",
					singleStr, ln )

			}
		}
		if len(points) > 0 {
			rowsOut = append( rowsOut, points )
		}
	}
	return rowsOut
}

func combiIndex2 (counts int) [][]int {
	combis := [][]int {}
	if counts < 1 {
		return combis
	}

	for fst := 0; fst < (counts -1); fst++ {
		for snd := (fst +1); snd < counts; snd++ {
			combis = append( combis, []int{fst, snd} )
		}
	}
	return combis
}

type HLine struct {
	points []int
	row    int
}

func abs(n int) int {
	if n < 0 {
		return -n
	}
	return n
}

func min(a int, b int) int{
	if a < b {
		return a
	}
	return b
}

func (hl HLine) length() int {
	return abs(hl.points[0] - hl.points[1])
}

func (hl HLine) startingPoint() int {
	return min(hl.points[0], hl.points[1])
}

func getHorizLinesFromPoints ( pointsAtRows [][]int ) []HLine{
	var hlinesAtRows []HLine
	for r, pts := range pointsAtRows {
		for _, ids := range combiIndex2( len(pts) ) {
			hlinesAtRows = append( hlinesAtRows,
				HLine {
					[]int{pts[ids[0]], pts[ids[1]]}, r } )
		}
	}
	return hlinesAtRows
}

type Square struct {
	top     HLine
	bottom  HLine
}

// find some way to make length from points and beginning point
// nicely in golang
func findSquares ( hlines []HLine ) []Square {
	var squares []Square
	for _, ids := range combiIndex2( len(hlines) ) {
		tl, bl := hlines[ids[0]], hlines[ids[1]]
		tlLen := tl.length()
		if tl.startingPoint() == bl.startingPoint() &&
			tlLen == bl.length() {
			if tlLen == abs(tl.row - bl.row) {
				squares = append(squares, Square{ tl, bl })
			}
		}
	}
	return squares
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	matrixString, _ := reader.ReadString('')
	pointsAtRows := getPointsFromMatrixLines( matrixString )


	if len(pointsAtRows) < 2 {
		fmt.Fprintln( os.Stderr,
			"Number of rows is less than two. ",
			": unable to make any squares." )
		os.Exit(1)
	}

	hlines  := getHorizLinesFromPoints( pointsAtRows )
	squares := findSquares( hlines )
	fmt.Fprint(   os.Stderr, "Found Squares are: ")
	fmt.Println( len(squares), "\n" )
	// FIXME: better print out
	fmt.Fprintln( os.Stderr, squares )
	fmt.Fprintln( os.Stderr, "\nFrom Horizontal lines: ")
	fmt.Fprintln( os.Stderr, hlines )
	fmt.Fprintln( os.Stderr, "\nFound Points: ")
	fmt.Fprintln( os.Stderr, pointsAtRows )
	os.Exit(0)
}