protype shuffling version -- unreachable
This commit is contained in:
parent
d611085b73
commit
41d2b32689
@ -6,15 +6,18 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// handwritten merge sort because it minimizes comparisons, which are
|
// handwritten merge sort because it minimizes comparisons, which are
|
||||||
// the expensive part when asking a human for every comparison.
|
// the expensive part when asking a human for every comparison.
|
||||||
// quicksort's "in-place" behavior isn't necessary.
|
// quicksort's "in-place" behavior isn't necessary.
|
||||||
func merge(a, b []string) []string {
|
func merge(a, b []string, less func(string, string) bool) []string {
|
||||||
if len(a) == 0 {
|
if len(a) == 0 {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@ -23,7 +26,7 @@ func merge(a, b []string) []string {
|
|||||||
}
|
}
|
||||||
ret := make([]string, 0, len(a)+len(b))
|
ret := make([]string, 0, len(a)+len(b))
|
||||||
for len(a) > 0 && len(b) > 0 {
|
for len(a) > 0 && len(b) > 0 {
|
||||||
if better(a[0], b[0]) {
|
if less(a[0], b[0]) {
|
||||||
ret = append(ret, a[0])
|
ret = append(ret, a[0])
|
||||||
a = a[1:]
|
a = a[1:]
|
||||||
} else {
|
} else {
|
||||||
@ -50,6 +53,48 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Question struct {
|
||||||
|
First string
|
||||||
|
Second string
|
||||||
|
Reply chan<- bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Question) Ask() {
|
||||||
|
q.Reply <- better(q.First, q.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Question) Push(qc chan<- *Question) bool {
|
||||||
|
c := make(chan bool, 1)
|
||||||
|
q.Reply = c
|
||||||
|
qc <- q
|
||||||
|
return <-c
|
||||||
|
}
|
||||||
|
|
||||||
|
func betterLoop(qq <-chan *Question) {
|
||||||
|
var pool []*Question
|
||||||
|
drain := time.After(100 * time.Millisecond)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case q, ok := <-qq:
|
||||||
|
if !ok {
|
||||||
|
qq = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pool = append(pool, q)
|
||||||
|
case <-drain:
|
||||||
|
rand.Shuffle(len(pool), func(i, j int) { pool[i], pool[j] = pool[j], pool[i] })
|
||||||
|
for _, q := range pool {
|
||||||
|
q.Ask()
|
||||||
|
}
|
||||||
|
pool = pool[:0]
|
||||||
|
if qq == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
drain = time.After(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func better(first, second string) bool {
|
func better(first, second string) bool {
|
||||||
for {
|
for {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
@ -74,12 +119,42 @@ func better(first, second string) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parallelBetter(first, second string, qq chan<- *Question) bool {
|
||||||
|
q := Question{
|
||||||
|
First: first,
|
||||||
|
Second: second,
|
||||||
|
}
|
||||||
|
return q.Push(qq)
|
||||||
|
}
|
||||||
|
|
||||||
func mergeSort(items []string) []string {
|
func mergeSort(items []string) []string {
|
||||||
if len(items) <= 1 {
|
if len(items) <= 1 {
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
midpoint := len(items) / 2
|
midpoint := len(items) / 2
|
||||||
return merge(mergeSort(items[:midpoint]), mergeSort(items[midpoint:]))
|
return merge(mergeSort(items[:midpoint]), mergeSort(items[midpoint:]), better)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parallelMergeSort(questions chan<- *Question, items []string) []string {
|
||||||
|
if len(items) <= 1 {
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
midpoint := len(items) / 2
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(2)
|
||||||
|
var r1, r2 []string
|
||||||
|
go func() {
|
||||||
|
r1 = parallelMergeSort(questions, items[:midpoint])
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
r2 = parallelMergeSort(questions, (items[midpoint:]))
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
return merge(r1, r2, func(a, b string) bool {
|
||||||
|
return parallelBetter(a, b, questions)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -107,6 +182,9 @@ func main() {
|
|||||||
log.Fatalf("can't read %q: %v", os.Args[1], err)
|
log.Fatalf("can't read %q: %v", os.Args[1], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rand.Shuffle(len(items), func(i, j int) {
|
||||||
|
items[i], items[j] = items[j], items[i]
|
||||||
|
})
|
||||||
sorted := mergeSort(items)
|
sorted := mergeSort(items)
|
||||||
fmt.Println("Sorted. Saving...")
|
fmt.Println("Sorted. Saving...")
|
||||||
obuf := bufio.NewWriter(ofile)
|
obuf := bufio.NewWriter(ofile)
|
||||||
|
Loading…
Reference in New Issue
Block a user