176 lines
4.4 KiB
Go
176 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"sort"
|
|
)
|
|
|
|
var (
|
|
stringsIn = []string{
|
|
`lions, tigers, and`,
|
|
`bears, oh my!`,
|
|
`(from the "Wizard of OZ")`}
|
|
intsIn = []int{77444, -12, 0}
|
|
)
|
|
|
|
func main() {
|
|
{
|
|
// initialize three vars
|
|
x, y, z := stringsIn[0], stringsIn[1], stringsIn[2]
|
|
|
|
// I. Task suggested technique, move values to array (slice).
|
|
// It's consise and relies on library code.
|
|
s := []string{x, y, z}
|
|
sort.Strings(s)
|
|
x, y, z = s[0], s[1], s[2]
|
|
|
|
// validate
|
|
if x > y || y > z {
|
|
log.Fatal()
|
|
}
|
|
|
|
// II. Likely fastest technique, minimizing tests and data movement.
|
|
// Least consise though, hardest to understand, and most chance to make
|
|
// a coding mistake.
|
|
x, y, z = stringsIn[0], stringsIn[1], stringsIn[2] // (initialize)
|
|
if x < y {
|
|
switch {
|
|
case y < z:
|
|
case x < z:
|
|
y, z = z, y
|
|
default:
|
|
x, y, z = z, x, y
|
|
}
|
|
} else {
|
|
switch {
|
|
case x < z:
|
|
x, y = y, x
|
|
case z < y:
|
|
x, z = z, x
|
|
default:
|
|
x, y, z = y, z, x
|
|
}
|
|
}
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
|
|
// III. A little more consise than II, easier to understand, almost
|
|
// as fast.
|
|
x, y, z = stringsIn[0], stringsIn[1], stringsIn[2] // (initialize)
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
if y > z {
|
|
y, z = z, y
|
|
}
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
fmt.Println("sorted strings:")
|
|
fmt.Println(" ", x)
|
|
fmt.Println(" ", y)
|
|
fmt.Println(" ", z)
|
|
fmt.Println("original data:")
|
|
fmt.Println(" ", stringsIn[0])
|
|
fmt.Println(" ", stringsIn[1])
|
|
fmt.Println(" ", stringsIn[2])
|
|
}
|
|
// same techniques, with integer test case
|
|
{
|
|
// task suggested technique
|
|
x, y, z := intsIn[0], intsIn[1], intsIn[2] // (initialize)
|
|
s := []int{x, y, z}
|
|
sort.Ints(s)
|
|
x, y, z = s[0], s[1], s[2]
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
|
|
// minimizing data movement
|
|
x, y, z = intsIn[0], intsIn[1], intsIn[2] // (initialize)
|
|
if x < y {
|
|
switch {
|
|
case y < z:
|
|
case x < z:
|
|
y, z = z, y
|
|
default:
|
|
x, y, z = z, x, y
|
|
}
|
|
} else {
|
|
switch {
|
|
case x < z:
|
|
x, y = y, x
|
|
case z < y:
|
|
x, z = z, x
|
|
default:
|
|
x, y, z = y, z, x
|
|
}
|
|
}
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
|
|
// three swaps
|
|
x, y, z = intsIn[0], intsIn[1], intsIn[2] // (initialize)
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
if y > z {
|
|
y, z = z, y
|
|
}
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
fmt.Println("sorted ints:", x, y, z)
|
|
fmt.Println("original data:", intsIn)
|
|
}
|
|
// To put any of these techniques in a function, a function could just
|
|
// take three values and return them sorted.
|
|
{
|
|
sort3 := func(x, y, z int) (int, int, int) {
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
if y > z {
|
|
y, z = z, y
|
|
}
|
|
if x > y {
|
|
x, y = y, x
|
|
}
|
|
return x, y, z
|
|
}
|
|
x, y, z := intsIn[0], intsIn[1], intsIn[2] // (initialize)
|
|
x, y, z = sort3(x, y, z)
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
}
|
|
// Alternatively, a function could take pointers
|
|
{
|
|
sort3 := func(x, y, z *int) {
|
|
if *x > *y {
|
|
*x, *y = *y, *x
|
|
}
|
|
if *y > *z {
|
|
*y, *z = *z, *y
|
|
}
|
|
if *x > *y {
|
|
*x, *y = *y, *x
|
|
}
|
|
}
|
|
x, y, z := intsIn[0], intsIn[1], intsIn[2] // (initialize)
|
|
sort3(&x, &y, &z)
|
|
if x > y || y > z { // (validate)
|
|
log.Fatal()
|
|
}
|
|
}
|
|
}
|