Skip to content

Commit

Permalink
Intersection[]
Browse files Browse the repository at this point in the history
  • Loading branch information
corywalker committed Nov 20, 2018
1 parent 901bbce commit 04496b3
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
46 changes: 46 additions & 0 deletions expreduce/builtin_list.go
Expand Up @@ -393,6 +393,52 @@ func getListDefinitions() (defs []Definition) {
return toReturn
},
})
defs = append(defs, Definition{
Name: "Intersection",
legacyEvalFn: func(this expreduceapi.ExpressionInterface, es expreduceapi.EvalStateInterface) expreduceapi.Ex {
if len(this.GetParts()) == 1 {
return this
}
var firstHead expreduceapi.Ex
intersection := map[uint64]int{}
for _, part := range this.GetParts()[1:] {
expr, isExpr := part.(expreduceapi.ExpressionInterface)
if !isExpr {
return this
}
if firstHead == nil {
firstHead = expr.GetParts()[0]
} else if !atoms.IsSameQ(firstHead, expr.GetParts()[0]) {
return this
}
theseParts := map[uint64]bool{}
for _, innerPart := range expr.GetParts()[1:] {
theseParts[hashEx(innerPart)] = true
}
for hash := range theseParts {
currVal, hasVal := intersection[hash]
if !hasVal {
intersection[hash] = 1
} else {
intersection[hash] = currVal + 1
}
}
}
toReturn := atoms.E(firstHead)
added := map[uint64]bool{}
for _, part := range this.GetParts()[1].(expreduceapi.ExpressionInterface).GetParts()[1:] {
hash := hashEx(part)
_, alreadyAdded := added[hash]
intersection := intersection[hash] == this.Len()
if intersection && !alreadyAdded {
added[hash] = true
toReturn.AppendEx(part)
}
}
sort.Sort(toReturn)
return toReturn
},
})
defs = append(defs, Definition{
Name: "PadRight",
legacyEvalFn: func(this expreduceapi.ExpressionInterface, es expreduceapi.EvalStateInterface) expreduceapi.Ex {
Expand Down
11 changes: 11 additions & 0 deletions expreduce/resources/list.m
Expand Up @@ -162,6 +162,17 @@
]
};

Intersection::usage = "`Intersection[expr1, expr2, ...]` returns a sorted intersection of the items in the expressions.";
Attributes[Intersection] = {Flat, OneIdentity, Protected, ReadProtected};
Tests`Complement = {
ESimpleExamples[
ESameTest[{a}, Intersection[{a, b}, {a}]],
ESameTest[{}, Intersection[{a, b, c}, {a}, {b}]]
], ETests[
ESameTest[foo[a], Intersection[foo[a], foo[a]]],
]
};

Range::usage = "`Range[n]` returns a `List` of integers from 1 to `n`.
`Range[m, n]` returns a `List` of integers from `m` to `n`.";
Expand Down

0 comments on commit 04496b3

Please sign in to comment.