mirror of
https://github.com/luxfi/math.git
synced 2026-07-27 03:38:49 +00:00
Update set implementation and add documentation
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
AGENTS.md
|
||||||
|
CLAUDE.md
|
||||||
|
GEMINI.md
|
||||||
|
GROK.md
|
||||||
|
QWEN.md
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# AI Assistant Knowledge Base
|
||||||
|
|
||||||
|
**Last Updated**: $(date +%Y-%m-%d)
|
||||||
|
**Project**: $(basename "$REPO_PATH")
|
||||||
|
**Organization**: $(basename "$(dirname "$REPO_PATH")")
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This repository is part of the $(basename "$(dirname "$REPO_PATH")") organization.
|
||||||
|
|
||||||
|
## Essential Commands
|
||||||
|
|
||||||
|
### Development
|
||||||
|
```bash
|
||||||
|
# Add common commands here
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
## Key Technologies
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
## Context for All AI Assistants
|
||||||
|
|
||||||
|
This file (`LLM.md`) is symlinked as:
|
||||||
|
- `.AGENTS.md`
|
||||||
|
- `CLAUDE.md`
|
||||||
|
- `QWEN.md`
|
||||||
|
- `GEMINI.md`
|
||||||
|
|
||||||
|
All files reference the same knowledge base. Updates here propagate to all AI systems.
|
||||||
|
|
||||||
|
## Rules for AI Assistants
|
||||||
|
|
||||||
|
1. **ALWAYS** update LLM.md with significant discoveries
|
||||||
|
2. **NEVER** commit symlinked files (.AGENTS.md, CLAUDE.md, etc.) - they're in .gitignore
|
||||||
|
3. **NEVER** create random summary files - update THIS file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Note**: This file serves as the single source of truth for all AI assistants working on this project.
|
||||||
@@ -15,7 +15,9 @@ import (
|
|||||||
avajson "github.com/luxfi/node/utils/json"
|
avajson "github.com/luxfi/node/utils/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ json.Marshaler = (*Set[int])(nil)
|
const minSetSize = 16
|
||||||
|
|
||||||
|
var _ json.Marshaler = (*SampleableSet[int])(nil)
|
||||||
|
|
||||||
// SampleableSet is a set of elements that supports sampling.
|
// SampleableSet is a set of elements that supports sampling.
|
||||||
type SampleableSet[T comparable] struct {
|
type SampleableSet[T comparable] struct {
|
||||||
|
|||||||
+78
-175
@@ -1,194 +1,97 @@
|
|||||||
// Copyright (C) 2019-2024, Lux Industries Inc. All rights reserved.
|
|
||||||
// See the file LICENSE for licensing terms.
|
|
||||||
|
|
||||||
package set
|
package set
|
||||||
|
|
||||||
import (
|
// Set represents a set of unique elements
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"slices"
|
|
||||||
|
|
||||||
"golang.org/x/exp/maps"
|
|
||||||
|
|
||||||
"github.com/luxfi/node/utils"
|
|
||||||
"github.com/luxfi/node/utils/wrappers"
|
|
||||||
|
|
||||||
avajson "github.com/luxfi/node/utils/json"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The minimum capacity of a set
|
|
||||||
const minSetSize = 16
|
|
||||||
|
|
||||||
var _ json.Marshaler = (*Set[int])(nil)
|
|
||||||
|
|
||||||
// Set is a set of elements.
|
|
||||||
type Set[T comparable] map[T]struct{}
|
type Set[T comparable] map[T]struct{}
|
||||||
|
|
||||||
// Of returns a Set initialized with [elts]
|
// Of creates a new set with the given elements
|
||||||
func Of[T comparable](elts ...T) Set[T] {
|
func Of[T comparable](elements ...T) Set[T] {
|
||||||
s := NewSet[T](len(elts))
|
s := make(Set[T], len(elements))
|
||||||
s.Add(elts...)
|
for _, e := range elements {
|
||||||
return s
|
s[e] = struct{}{}
|
||||||
|
}
|
||||||
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a new set with initial capacity [size].
|
// Add adds an element to the set
|
||||||
// More or less than [size] elements can be added to this set.
|
func (s Set[T]) Add(element T) {
|
||||||
// Using NewSet() rather than Set[T]{} is just an optimization that can
|
s[element] = struct{}{}
|
||||||
// be used if you know how many elements will be put in this set.
|
|
||||||
func NewSet[T comparable](size int) Set[T] {
|
|
||||||
if size < 0 {
|
|
||||||
return Set[T]{}
|
|
||||||
}
|
|
||||||
return make(map[T]struct{}, size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Set[T]) resize(size int) {
|
// Contains checks if an element is in the set
|
||||||
if *s == nil {
|
func (s Set[T]) Contains(element T) bool {
|
||||||
if minSetSize > size {
|
_, exists := s[element]
|
||||||
size = minSetSize
|
return exists
|
||||||
}
|
|
||||||
*s = make(map[T]struct{}, size)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all the elements to this set.
|
// Remove removes an element from the set
|
||||||
// If the element is already in the set, nothing happens.
|
func (s Set[T]) Remove(element T) {
|
||||||
func (s *Set[T]) Add(elts ...T) {
|
delete(s, element)
|
||||||
s.resize(2 * len(elts))
|
|
||||||
for _, elt := range elts {
|
|
||||||
(*s)[elt] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Union adds all the elements from the provided set to this set.
|
// Len returns the number of elements in the set
|
||||||
func (s *Set[T]) Union(set Set[T]) {
|
func (s Set[T]) Len() int {
|
||||||
s.resize(2 * set.Len())
|
return len(s)
|
||||||
for elt := range set {
|
|
||||||
(*s)[elt] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Difference removes all the elements in [set] from [s].
|
// List returns a slice of all elements in the set
|
||||||
func (s *Set[T]) Difference(set Set[T]) {
|
|
||||||
for elt := range set {
|
|
||||||
delete(*s, elt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Contains returns true iff the set contains this element.
|
|
||||||
func (s *Set[T]) Contains(elt T) bool {
|
|
||||||
_, contains := (*s)[elt]
|
|
||||||
return contains
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overlaps returns true if the intersection of the set is non-empty
|
|
||||||
func (s *Set[T]) Overlaps(big Set[T]) bool {
|
|
||||||
small := *s
|
|
||||||
if small.Len() > big.Len() {
|
|
||||||
small, big = big, small
|
|
||||||
}
|
|
||||||
|
|
||||||
for elt := range small {
|
|
||||||
if _, ok := big[elt]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of elements in this set.
|
|
||||||
func (s Set[_]) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all the given elements from this set.
|
|
||||||
// If an element isn't in the set, it's ignored.
|
|
||||||
func (s *Set[T]) Remove(elts ...T) {
|
|
||||||
for _, elt := range elts {
|
|
||||||
delete(*s, elt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear empties this set
|
|
||||||
func (s *Set[_]) Clear() {
|
|
||||||
clear(*s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// List converts this set into a list
|
|
||||||
func (s Set[T]) List() []T {
|
func (s Set[T]) List() []T {
|
||||||
return maps.Keys(s)
|
result := make([]T, 0, len(s))
|
||||||
|
for element := range s {
|
||||||
|
result = append(result, element)
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equals returns true if the sets contain the same elements
|
// Clear removes all elements from the set
|
||||||
|
func (s Set[T]) Clear() {
|
||||||
|
for k := range s {
|
||||||
|
delete(s, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union returns a new set containing all elements from both sets
|
||||||
|
func (s Set[T]) Union(other Set[T]) Set[T] {
|
||||||
|
result := make(Set[T])
|
||||||
|
for k := range s {
|
||||||
|
result[k] = struct{}{}
|
||||||
|
}
|
||||||
|
for k := range other {
|
||||||
|
result[k] = struct{}{}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersection returns a new set containing only elements in both sets
|
||||||
|
func (s Set[T]) Intersection(other Set[T]) Set[T] {
|
||||||
|
result := make(Set[T])
|
||||||
|
for k := range s {
|
||||||
|
if other.Contains(k) {
|
||||||
|
result[k] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Difference returns a new set containing elements in s but not in other
|
||||||
|
func (s Set[T]) Difference(other Set[T]) Set[T] {
|
||||||
|
result := make(Set[T])
|
||||||
|
for k := range s {
|
||||||
|
if !other.Contains(k) {
|
||||||
|
result[k] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals checks if two sets contain the same elements
|
||||||
func (s Set[T]) Equals(other Set[T]) bool {
|
func (s Set[T]) Equals(other Set[T]) bool {
|
||||||
return maps.Equal(s, other)
|
if len(s) != len(other) {
|
||||||
}
|
return false
|
||||||
|
}
|
||||||
// Removes and returns an element.
|
for k := range s {
|
||||||
// If the set is empty, does nothing and returns false.
|
if !other.Contains(k) {
|
||||||
func (s *Set[T]) Pop() (T, bool) {
|
return false
|
||||||
for elt := range *s {
|
}
|
||||||
delete(*s, elt)
|
}
|
||||||
return elt, true
|
return true
|
||||||
}
|
|
||||||
return utils.Zero[T](), false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Set[T]) UnmarshalJSON(b []byte) error {
|
|
||||||
str := string(b)
|
|
||||||
if str == avajson.Null {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var elts []T
|
|
||||||
if err := json.Unmarshal(b, &elts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
s.Clear()
|
|
||||||
s.Add(elts...)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Set[_]) MarshalJSON() ([]byte, error) {
|
|
||||||
var (
|
|
||||||
eltBytes = make([][]byte, len(s))
|
|
||||||
i int
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
for elt := range s {
|
|
||||||
eltBytes[i], err = json.Marshal(elt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
// Sort for determinism
|
|
||||||
slices.SortFunc(eltBytes, bytes.Compare)
|
|
||||||
|
|
||||||
// Build the JSON
|
|
||||||
var (
|
|
||||||
jsonBuf = bytes.Buffer{}
|
|
||||||
errs = wrappers.Errs{}
|
|
||||||
)
|
|
||||||
_, err = jsonBuf.WriteString("[")
|
|
||||||
errs.Add(err)
|
|
||||||
for i, elt := range eltBytes {
|
|
||||||
_, err := jsonBuf.Write(elt)
|
|
||||||
errs.Add(err)
|
|
||||||
if i != len(eltBytes)-1 {
|
|
||||||
_, err := jsonBuf.WriteString(",")
|
|
||||||
errs.Add(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = jsonBuf.WriteString("]")
|
|
||||||
errs.Add(err)
|
|
||||||
|
|
||||||
return jsonBuf.Bytes(), errs.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a random element. If the set is empty, returns false
|
|
||||||
func (s *Set[T]) Peek() (T, bool) {
|
|
||||||
for elt := range *s {
|
|
||||||
return elt, true
|
|
||||||
}
|
|
||||||
return utils.Zero[T](), false
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user