protype shuffling version -- unreachable

This commit is contained in:
Kistaro Windrider 2024-03-09 22:23:43 -08:00
parent d611085b73
commit 41d2b32689
Signed by: kistaro
SSH Key Fingerprint: SHA256:TBE2ynfmJqsAf0CP6gsflA0q5X5wD5fVKWPsZ7eVUg8

View File

@ -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)