Skip to content

Instantly share code, notes, and snippets.

@tpaschalis
Last active February 12, 2019 15:52
Show Gist options
  • Save tpaschalis/48147b36c0816a13999fa3283fe3b34f to your computer and use it in GitHub Desktop.
Save tpaschalis/48147b36c0816a13999fa3283fe3b34f to your computer and use it in GitHub Desktop.
A Go implementation of McCarthy's `amb` ambiguous operator
package main
import "fmt"
import "sync"
func ambString(str []string) chan []string {
c := make(chan []string)
go func() {
for _, s := range str {
c <- []string{s}
}
close(c)
}()
return c
}
func amb(str []string, chanIn chan []string) chan []string {
chanOut := make(chan []string)
go func() {
var w sync.WaitGroup
for frag := range chanIn {
w.Add(1)
go func(frag []string) {
for s := range ambString(str) {
// Constraing block start -- Check if frag matches
tmp := join(append(s, frag...))
if len(tmp) <= len(keyword) {
// Possible candidates pass on further along on `chanOut`
if tmp == keyword[len(keyword)-len(tmp):] {
fmt.Println(tmp, keyword[len(keyword)-len(tmp):], s, frag)
chanOut <- append(s, frag...)
}
}
// Constraint block end
}
w.Done()
}(frag)
}
w.Wait()
close(chanOut)
}()
return chanOut
}
const keyword = "camaroptera"
func main() {
A := []string{"bar", "foo", "cam", "kam"}
B := []string{"aropter", "ar", "ra", "baz"}
C := []string{"qux", "opter", "amar", "ra"}
D := []string{"a", "aropteraa", "ham", "optera"}
c := amb(A, amb(B, amb(C, ambString(D))))
for s := range c {
_, _ = c, s
fmt.Println("************ RESULTS ***************")
fmt.Println(join(s))
fmt.Println("A[", indexOf(s[0], A), "]\nB[", indexOf(s[1], B), "]\nC[", indexOf(s[2], C), "]\nD[", indexOf(s[3], D), "]")
}
}
func join(s []string) string {
var res string
for _, str := range s {
res += str
}
return res
}
func indexOf(element string, input []string) int {
for k, v := range input {
if element == v {
return k
}
}
return -1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment