protype shuffling version -- unreachable
This commit is contained in:
parent
d611085b73
commit
41d2b32689
@ -6,15 +6,18 @@ import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// handwritten merge sort because it minimizes comparisons, which are
|
||||
// the expensive part when asking a human for every comparison.
|
||||
// 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 {
|
||||
return b
|
||||
}
|
||||
@ -23,7 +26,7 @@ func merge(a, b []string) []string {
|
||||
}
|
||||
ret := make([]string, 0, len(a)+len(b))
|
||||
for len(a) > 0 && len(b) > 0 {
|
||||
if better(a[0], b[0]) {
|
||||
if less(a[0], b[0]) {
|
||||
ret = append(ret, a[0])
|
||||
a = a[1:]
|
||||
} 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 {
|
||||
for {
|
||||
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 {
|
||||
if len(items) <= 1 {
|
||||
return items
|
||||
}
|
||||
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() {
|
||||
@ -107,6 +182,9 @@ func main() {
|
||||
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)
|
||||
fmt.Println("Sorted. Saving...")
|
||||
obuf := bufio.NewWriter(ofile)
|
||||
|
Loading…
Reference in New Issue
Block a user