# Commits

committed 096be75

problem b: bottle

• Participants
• Parent commits b676843
• Branches master

# File bottle/bottle.go

`+package prism`
`+`
`+// problem b`
`+`
`+import (`
`+	"fmt"`
`+	"math"`
`+)`
`+`
`+type Prism struct {`
`+	vector    []float64`
`+	low, high float64`
`+}`
`+`
`+func New(a []float64, x0, x1 float64) *Prism {`
`+	p := new(Prism)`
`+	p.vector = initVector(a)`
`+	p.low = x0`
`+	p.high = x1`
`+	return p`
`+}`
`+`
`+func (id *Prism) Volume() float64 {`
`+	return volume(id.vector, id.low, id.high)`
`+}`
`+`
`+func (id *Prism) Distances(v float64) ([]float64, error) {`
`+	v0 := id.Volume()`
`+	if v > v0 {`
`+		return nil, fmt.Errorf("insufficient volume")`
`+	}`
`+	n := int(v0 / v)`
`+	if n > 8 {`
`+		n = 8`
`+	}`
`+	ds := make([]float64, n)`
`+	low := id.low`
`+	for i := 0; i < n; i++ {`
`+		k := float64(0.0001)`
`+		for volume(id.vector, low, low+k) < v {`
`+			k += 0.0001`
`+		}`
`+		low += k`
`+		ds[i] = low - id.low`
`+	}`
`+	return ds, nil`
`+}`
`+`
`+func initVector(a []float64) []float64 {`
`+	m := len(a) // 0 ~ n`
`+	matrix := make([][]float64, m)`
`+	for i := 0; i < m; i++ {`
`+		matrix[i] = make([]float64, m)`
`+		for j := 0; j < m; j++ {`
`+			matrix[i][j] = a[i] * a[j]`
`+		}`
`+	}`
`+	vec := make([]float64, 2*m-1)`
`+	for i := 0; i < 2*m-1; i++ {`
`+		vec[i] = 0`
`+		k := i - m + 1`
`+		if k < 0 {`
`+			k = 0`
`+		}`
`+		j := i - k`
`+		h := j`
`+		for k <= h {`
`+			vec[i] += matrix[k][j]`
`+			k++`
`+			j--`
`+		}`
`+	}`
`+	return vec`
`+}`
`+`
`+func volume(vec []float64, x0, x1 float64) float64 {`
`+	m := len(vec) // 0 ~ 2n+1`
`+	r := float64(0)`
`+	var c float64`
`+	for i := 0; i < m; i++ {`
`+		c = float64(i + 1)`
`+		r += vec[i] * (math.Pow(x1, c) - math.Pow(x0, c)) / c`
`+	}`
`+	return r * math.Pi`
`+}`

# File bottle/bottle_test.go

`+package prism`
`+`
`+import (`
`+	"bufio"`
`+	"fmt"`
`+	"os"`
`+	"strconv"`
`+	"strings"`
`+	"testing"`
`+)`
`+`
`+var _vol_ []string`
`+var _dis_ []string`
`+`
`+func init() {`
`+	_vol_ = make([]string, 4)`
`+	_dis_ = make([]string, 4)`
`+	_vol_[0] = "263.89"`
`+	_vol_[1] = "263.89"`
`+	_vol_[2] = "50.00"`
`+	_vol_[3] = "31.42"`
`+	_dis_[0] = "0.51 1.06 1.66 2.31 3.02 3.83 4.75 5.87"`
`+	_dis_[1] = "insufficient volume"`
`+	_dis_[2] = "2.00 4.00"`
`+	_dis_[3] = "3.18 6.37 9.55"`
`+}`
`+`
`+func TestVolume(t *testing.T) {`
`+	file, err := os.Open("sample.txt")`
`+	if err != nil {`
`+		fmt.Println(err)`
`+		return`
`+	}`
`+	defer file.Close()`
`+	reader := bufio.NewReader(file)`
`+	var line, out string`
`+	var p *Prism`
`+	var a []float64`
`+	var b []string`
`+	var x0, x1, inc float64`
`+	i := 0`
`+	for {`
`+		_, err = reader.ReadString('\n')`
`+		if err != nil {`
`+			break`
`+		}`
`+		line, _ = reader.ReadString('\n')`
`+		b = strings.Fields(line)`
`+		a = make([]float64, len(b))`
`+		for i := 0; i < len(b); i++ {`
`+			a[i], _ = strconv.ParseFloat(b[i], 64)`
`+		}`
`+		line, _ = reader.ReadString('\n')`
`+		b = strings.Fields(line)`
`+		x0, _ = strconv.ParseFloat(b[0], 64)`
`+		x1, _ = strconv.ParseFloat(b[1], 64)`
`+		inc, _ = strconv.ParseFloat(b[2], 64)`
`+		p = New(a, x0, x1)`
`+		out = fmt.Sprintf("%.2f", p.Volume())`
`+		if out != _vol_[i] {`
`+			t.Errorf("Volume mismatch: got \"%v\", expected \"%v\"\n", out, _vol_[i])`
`+		}`
`+		fmt.Printf("Case %d: %s\n", i, out)`
`+		ds, err := p.Distances(inc)`
`+		if err != nil {`
`+			out = fmt.Sprintf("%s", err)`
`+		} else {`
`+			out = fmt.Sprintf("%.2f", ds)`
`+			out = out[1 : len(out)-1]`
`+		}`
`+		if out != _dis_[i] {`
`+			t.Errorf("Distance mismatch: got \"%v\", expected \"%v\"\n", out, _dis_[i])`
`+		}`
`+		fmt.Println(out)`
`+		i++`
`+	}`
`+	return`
`+}`

# File bottle/sample.txt

`+1`
`+4.0 -0.25`
`+0.0 12.0 25`
`+1`
`+4.0 -0.25`
`+0.0 12.0 300`
`+0`
`+1.7841241161782`
`+5.0 10.0 20`
`+0`
`+1.0`
`+0.0 10.0 10`