Problem: Given an array of positive distinct integer denoting the crossing time of ‘n’ people. These ‘n’ people are standing at one side of bridge. Bridge can hold at max two people at a time. When two people cross the bridge, they must move at the slower person’s pace. Find the minimum total time in which all persons can cross the bridge.
I am not able to find the pattern as of how to scale this for 'n' people. But somehow I managed to find the case with 4 people. Can someone help me with this. I am new to Golang and I am stuck with this problem.
package main
import (
"fmt"
"io/ioutil"
"log"
"os"
"sort"
"gopkg.in/yaml.v2"
)
type conf struct {
Person []map[string]float32 `yaml:"person"`
}
func (c *conf) getConf() *conf {
filename := os.Args[1] // Taking file input
yamlFile, err := ioutil.ReadFile(filename) // Yaml parse
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}
return c
}
func main() {
var c conf // Object of struct conf
c.getConf() // calling getConf function
// Sorting the current conf map
n := map[float32][]string{} // Map to store current conf map
var a []float32 // Store values from conf map
for k, v := range c.Person {
v := float32(v)
fmt.Println(k, v)
n[v] = append(n[v], k)
}
for k := range n {
a = append(a, k)
}
// Converting float32 as float64 in order to sort the values in conf map
float32AsFloat64Values := make([]float64, len(a))
for i, val := range a {
float32AsFloat64Values[i] = float64(val)
}
sort.Float64s(float32AsFloat64Values)
for i, val := range float32AsFloat64Values {
a[i] = float32(val)
}
var time float32
fmt.Printf("
%v
", a)
for _, k := range a {
min1 := a[0]
min2 := a[1]
min3 := a[2]
for _, s := range n[k] {
//Debug:
fmt.Printf("%s, %g
", s, k)
if len(a) > 3 {
time = (3 * min2) + min1 + a[3] //Formula for minimum time in case of 4 people
} else if len(a) == 3 {
time = min1 + min2 + min3
} else {
fmt.Println("Enter valid arguments in config.yaml")
}
}
}
fmt.Printf("Minimum time taken to cross the bridge is:\t%g
", time)
}
Playground: https://play.golang.org/p/ObTVA8gk0mg
Config.yaml is:
person:
person_1: 2
person_2: 1
person_3: 5
person_4: 8
person_5: 9
One could run this as: 'go run main.go config.yaml'. My scenario is that there could be 4,5 or 'n' number of people given in this yaml. Then what would be the minimum time for them to cross the bridge given the constraints.
I think the original problem is a bit more interesting than the one stated (yes, there has to be a Torch in the "Bridge and Torch" problem!).
Based on the Wikipedia description, for example,
Four people come to a river in the night. There is a narrow bridge, but it can only hold two people at a time. They have one torch and, because it's night, the torch has to be used when crossing the bridge. Person A can cross the bridge in 1 minute, B in 2 minutes, C in 5 minutes, and D in 8 minutes. When two people cross the bridge together, they must move at the slower person's pace. The question is, can they all get across the bridge if the torch lasts only 15 minutes?
In our case, of course, there are N people instead of just four, and it takes them variable amount of time to cross the bridge, but the rest of the story is the same.
Here's the implementation:
import (
"fmt"
"sort"
)
func minCrossingTime(x []int) int {
if len(x) == 1 {
return x[0]
}
sort.Ints(x)
t := 0
a, b := x[0], x[1]
x = x[2:]
for len(x) >= 2 {
n := len(x)
c, d := x[n-2], x[n-1]
x = x[:n-2]
t1 := 2*b + a + d
t2 := d + c + 2*a
if t1 < t2 {
t += t1
} else {
t += t2
}
}
if len(x) == 1 {
c := x[0]
t += a + b + c
} else {
t += b
}
return t
}
func main() {
x1 := []int{1, 2, 5, 8}
fmt.Printf("x = %x, time = %d
", x1, minCrossingTime(x1))
x2 := []int{3, 8, 1, 6, 2, 9}
fmt.Printf("x = %x, time = %d
", x2, minCrossingTime(x2))
}
Output:
x = [1 2 5 8], time = 15
x = [1 2 3 6 8 9], time = 27
Note: the first example [1 2 5 8] is straight from the Wikipedia, so the answer is yes, they can cross in 15 minutes
Key idea:
Definitions:
Logic:
If N < 4 the problem is trivial:
If N >= 4 consider the following problem: how to make two slowest people (and only them) cross the bridge and have the torch brought back in minimal time. There are two "good" ways to do it, with times t1 = X1 + 2*X2 + XN
(+{X1,X2} -{X1} +{X[N-1],XN} -{X2}) and t2 = 2*X1 + X[N-1] + XN
(+{X1,X[N-1]} -{X1} +{X1,XN} -{X1}), so we choose the best (minimum) out of these two
Extras:
Problem: Given an array of positive distinct integer denoting the crossing time of ‘n’ people. These ‘n’ people are standing at one side of bridge. Bridge can hold at max two people at a time. When two people cross the bridge, they must move at the slower person’s pace. Find the minimum total time in which all persons can cross the bridge.
person: person_1: 2 person_2: 1 person_3: 5 person_4: 8 person_5: 9
Your algorithm looks complicated.
For example,
package main
import (
"fmt"
"sort"
)
func minCrossingTime(people []int) int {
sort.Slice(people, func(i, j int) bool {
return people[i] > people[j]
})
min := 0
for i := 0; i < len(people); i += 2 {
min += people[i]
}
return min
}
func main() {
people := []int{2, 1, 5, 8, 9}
fmt.Println(len(people), people)
crossingTime := minCrossingTime(people)
fmt.Println(len(people), people)
fmt.Println(crossingTime)
}
Playground: https://play.golang.org/p/pXdGcinwxr-
Output:
5 [2 1 5 8 9]
5 [9 8 5 2 1]
15