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"
|
||||
)
|
||||
|
||||
var _ json.Marshaler = (*Set[int])(nil)
|
||||
const minSetSize = 16
|
||||
|
||||
var _ json.Marshaler = (*SampleableSet[int])(nil)
|
||||
|
||||
// SampleableSet is a set of elements that supports sampling.
|
||||
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
|
||||
|
||||
import (
|
||||
"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.
|
||||
// Set represents a set of unique elements
|
||||
type Set[T comparable] map[T]struct{}
|
||||
|
||||
// Of returns a Set initialized with [elts]
|
||||
func Of[T comparable](elts ...T) Set[T] {
|
||||
s := NewSet[T](len(elts))
|
||||
s.Add(elts...)
|
||||
return s
|
||||
// Of creates a new set with the given elements
|
||||
func Of[T comparable](elements ...T) Set[T] {
|
||||
s := make(Set[T], len(elements))
|
||||
for _, e := range elements {
|
||||
s[e] = struct{}{}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Return a new set with initial capacity [size].
|
||||
// More or less than [size] elements can be added to this set.
|
||||
// Using NewSet() rather than Set[T]{} is just an optimization that can
|
||||
// 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)
|
||||
// Add adds an element to the set
|
||||
func (s Set[T]) Add(element T) {
|
||||
s[element] = struct{}{}
|
||||
}
|
||||
|
||||
func (s *Set[T]) resize(size int) {
|
||||
if *s == nil {
|
||||
if minSetSize > size {
|
||||
size = minSetSize
|
||||
}
|
||||
*s = make(map[T]struct{}, size)
|
||||
}
|
||||
// Contains checks if an element is in the set
|
||||
func (s Set[T]) Contains(element T) bool {
|
||||
_, exists := s[element]
|
||||
return exists
|
||||
}
|
||||
|
||||
// Add all the elements to this set.
|
||||
// If the element is already in the set, nothing happens.
|
||||
func (s *Set[T]) Add(elts ...T) {
|
||||
s.resize(2 * len(elts))
|
||||
for _, elt := range elts {
|
||||
(*s)[elt] = struct{}{}
|
||||
}
|
||||
// Remove removes an element from the set
|
||||
func (s Set[T]) Remove(element T) {
|
||||
delete(s, element)
|
||||
}
|
||||
|
||||
// Union adds all the elements from the provided set to this set.
|
||||
func (s *Set[T]) Union(set Set[T]) {
|
||||
s.resize(2 * set.Len())
|
||||
for elt := range set {
|
||||
(*s)[elt] = struct{}{}
|
||||
}
|
||||
// Len returns the number of elements in the set
|
||||
func (s Set[T]) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
// Difference removes all the elements in [set] from [s].
|
||||
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
|
||||
// List returns a slice of all elements in the set
|
||||
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 {
|
||||
return maps.Equal(s, other)
|
||||
}
|
||||
|
||||
// Removes and returns an element.
|
||||
// If the set is empty, does nothing and returns false.
|
||||
func (s *Set[T]) Pop() (T, bool) {
|
||||
for elt := range *s {
|
||||
delete(*s, elt)
|
||||
return elt, 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
|
||||
if len(s) != len(other) {
|
||||
return false
|
||||
}
|
||||
for k := range s {
|
||||
if !other.Contains(k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user