Skip to content

Instantly share code, notes, and snippets.

@j3speaks
Created May 17, 2019 20:09
Show Gist options
  • Save j3speaks/338aeb7c76607328ca86a2052bb87e51 to your computer and use it in GitHub Desktop.
Save j3speaks/338aeb7c76607328ca86a2052bb87e51 to your computer and use it in GitHub Desktop.
Bridge and Torch Logic Puzzle solved in Go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"sort"
"strings"
)
// MaxParticipants constant describes the max number of participants that will be evaluated
const MaxParticipants = 4
// Participants struct which contains an array of participants
type Participants struct {
Participants []Participant `json:"participants"`
}
// Participant struct which contains a name and the speed at which the person walks
type Participant struct {
Name string `json:"name"`
Speed int `json:"speed"`
}
// GetJSONFileStuffInStruct function retrieves the Participants data from the specified JSON file
func GetJSONFileStuffInStruct(filename string) Participants {
// Initialize our Participants array
var participants Participants
filename = strings.TrimSpace(filename)
jsonFile, err := os.Open(filename)
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
os.Exit(1)
} else {
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
// Read our opened jsonFile as a byte array
byteValue, _ := ioutil.ReadAll(jsonFile)
// Deserailize the byteArray which contains the jsonFile's content into 'participants' which we defined above
json.Unmarshal(byteValue, &participants)
}
return participants
}
// main function entry-point of the application
func main() {
// Check that the caller specific command-line arguments
if len(os.Args) != 2 {
fmt.Println("You forgot to specific the Participants JSON file.")
os.Exit(1)
}
// Initialize our Participants array
filename := strings.TrimSpace(os.Args[1])
participants := GetJSONFileStuffInStruct(filename)
// Get the number of participants in the jsonFile
numberOfParticipants := len(participants.Participants)
// Check to makesure their are 4 or more participants before proceeding
if numberOfParticipants <= 3 {
fmt.Println("This process cannot not work without having more than 3 Participants.")
os.Exit(1)
} else if numberOfParticipants > MaxParticipants {
fmt.Printf("NOTE: There are %d participants in the '%s', which are %d more than are required\n", numberOfParticipants, filename, (numberOfParticipants - MaxParticipants))
fmt.Println("for this logic puzzle. Therefore only the first four particpants will be used,")
fmt.Println("and the rest ignored.")
participants.Participants = participants.Participants[:MaxParticipants]
numberOfParticipants = MaxParticipants
}
fmt.Println("")
fmt.Printf("These are the %d participants to be evaluated:\n", numberOfParticipants)
var totalSpeed, strategyOneTotalSpeed, strategyTwoTotalSpeed int
/*
* Iterate through every participant within our participants array, and
* print out the participant name and speed
*/
for index := 0; index < numberOfParticipants; index++ {
fmt.Printf("%d. Participant %s's speed is %d %s\n", (index + 1), participants.Participants[index].Name, participants.Participants[index].Speed, showMinuteSingularOrPlural(participants.Participants[index].Speed))
totalSpeed += participants.Participants[index].Speed
}
// Sort the list of participant by speed in descending order
sort.Slice(participants.Participants, func(i, j int) bool {
return participants.Participants[i].Speed < participants.Participants[j].Speed
})
// Print out the first strategy
fmt.Println("")
fmt.Printf("1st Strategy:\n")
for index := 1; index < numberOfParticipants; index++ {
fmt.Printf("'%s' takes '%s' across in %d %s\n", participants.Participants[0].Name, participants.Participants[index].Name, participants.Participants[index].Speed, showMinuteSingularOrPlural(participants.Participants[index].Speed))
if index != (numberOfParticipants - 1) {
fmt.Printf("'%s' returns back across taking %d %s\n", participants.Participants[0].Name, participants.Participants[0].Speed, showMinuteSingularOrPlural(participants.Participants[0].Speed))
}
}
strategyOneTotalSpeed = ((totalSpeed - participants.Participants[0].Speed) + participants.Participants[0].Speed*(numberOfParticipants-1)) - 1
fmt.Printf("The total crossing will take %d minutes\n", strategyOneTotalSpeed)
// Print out the second strategy
fmt.Println("")
fmt.Printf("2nd Strategy:\n")
fmt.Printf("'%s' takes '%s' across in %d %s\n", participants.Participants[0].Name, participants.Participants[1].Name, participants.Participants[1].Speed, showMinuteSingularOrPlural(participants.Participants[1].Speed))
fmt.Printf("'%s' returns back across taking %d %s\n", participants.Participants[0].Name, participants.Participants[0].Speed, showMinuteSingularOrPlural(participants.Participants[0].Speed))
strategyTwoTotalSpeed = participants.Participants[0].Speed + participants.Participants[1].Speed
fmt.Printf("'%s' takes '%s' across in %d %s\n", participants.Participants[2].Name, participants.Participants[3].Name, participants.Participants[3].Speed, showMinuteSingularOrPlural(participants.Participants[3].Speed))
fmt.Printf("'%s' returns back across taking %d %s\n", participants.Participants[1].Name, participants.Participants[1].Speed, showMinuteSingularOrPlural(participants.Participants[1].Speed))
strategyTwoTotalSpeed += participants.Participants[1].Speed + participants.Participants[3].Speed
fmt.Printf("'%s' takes '%s' across in %d %s\n", participants.Participants[1].Name, participants.Participants[0].Name, participants.Participants[1].Speed, showMinuteSingularOrPlural(participants.Participants[1].Speed))
strategyTwoTotalSpeed += participants.Participants[1].Speed
fmt.Printf("The total crossing effort will take %d minutes\n", strategyTwoTotalSpeed)
fmt.Println("")
if strategyOneTotalSpeed == strategyTwoTotalSpeed {
fmt.Println("Either strategy is recommended, because both are equally fast!")
} else if strategyOneTotalSpeed < strategyTwoTotalSpeed {
fmt.Println("The 1st Strategy is recommended, because everyone gets across the bridge the fastest!")
} else {
fmt.Println("The 2nd Strategy is recommended, because everyone gets across the bridge the fastest!")
}
}
// showMinuteSingularOrPlural function returns the singular 'minute' if value is 1; otherwise the plural form 'minutes' is returned
func showMinuteSingularOrPlural(value int) string {
if value == 1 {
return "minute"
}
return "minutes"
}
package main
import (
"fmt"
"sort"
"testing"
)
func TestNumberOfParticipants(t *testing.T) {
// Initialize our Participants array
participants := GetJSONFileStuffInStruct("participants.json")
if len(participants.Participants) != 0 {
// Get the number of participants in the jsonFile
numberOfParticipants := len(participants.Participants)
wantValue := 4
errorWant := fmt.Sprintf("numberOfParticipants was not %d, ", wantValue)
if numberOfParticipants != wantValue {
t.Errorf(errorWant+"got: %d, want: %d.", numberOfParticipants, wantValue)
}
}
}
func TestSlowestPartcipant(t *testing.T) {
// Initialize our Participants array
participants := GetJSONFileStuffInStruct("participants.json")
if len(participants.Participants) != 0 {
// Sort the list of participant by speed in descending order
sort.Slice(participants.Participants, func(i, j int) bool {
return participants.Participants[i].Speed < participants.Participants[j].Speed
})
wantName := "Rachel"
wantValue := 8
errorWant := fmt.Sprintf("Slowest Participant is not '{%s %d}', ", wantName, wantValue)
if participants.Participants[(len(participants.Participants)-1)] != (Participant{Name: wantName, Speed: wantValue}) {
t.Errorf(errorWant+"got: %v, want: %v.", participants.Participants[(len(participants.Participants)-1)], (Participant{Name: wantName, Speed: wantValue}))
}
}
}
func TestFastestPartcipant(t *testing.T) {
// Initialize our Participants array
participants := GetJSONFileStuffInStruct("participants.json")
if len(participants.Participants) != 0 {
// Sort the list of participant by speed in descending order
sort.Slice(participants.Participants, func(i, j int) bool {
return participants.Participants[i].Speed < participants.Participants[j].Speed
})
wantName := "Pon"
wantValue := 1
errorWant := fmt.Sprintf("Fastest Participant is not '{%s %d}', ", wantName, wantValue)
if participants.Participants[0] != (Participant{Name: wantName, Speed: wantValue}) {
t.Errorf(errorWant+"got: %v, want: %v.", participants.Participants[0], (Participant{Name: wantName, Speed: wantValue}))
}
}
}
{
"participants":[
{
"name": "Shubhangi",
"speed": 5
},
{
"name": "Pon",
"speed": 1
},
{
"name": "Rachel",
"speed": 8
},
{
"name": "Naveen",
"speed": 2
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment