Created basic data structures and methods for dealing with a collection of surreal...
[surreal-numbers] / chapter-1-experiments / ch1-breeding-numbers.go
// (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
// See LICENSE.txt file for copyright and license details.
package main
import (
"flag"
"fmt"
"log"
)
// =============================================================================
type surrealUniverse struct {
// TODO: Note that the elements of this array are maintained in order
// w.r.t. Axiom 2.
numbers []surrealNumber
nextUniqueID int
}
func (u *surrealUniverse) exists(num surrealNumber) bool {
// TODO: After I implement a LEQ comparison function, the fact that
// u.numbers[] is ordered by that comparison will allow me to greatly
// shorten the search.
for i := 0; i < len(u.numbers); i++ {
if num.number == u.numbers[i].number {
return true
}
}
return false
}
func (u *surrealUniverse) cardinality() int {
return len(u.numbers)
}
func (u *surrealUniverse) insert(num surrealNumber) {
if !u.exists(num) {
num.metadata.identifier = u.nextUniqueID
u.nextUniqueID++
// TODO: Need a LEQ function before I can insert in the correct order.
// For now, just append to the end.
u.numbers = append(u.numbers, num)
}
}
func (u *surrealUniverse) remove(num surrealNumber) {
for i := 0; i < len(u.numbers); i++ {
if num.number == u.numbers[i].number {
u.numbers = append(u.numbers[:i], u.numbers[i+1:]...)
}
}
}
// =============================================================================
type surrealNumber struct {
number surrealValue
metadata surrealMetadata
}
// TODO: Note that this is split from the metadata so we can do direct
// comparisons when numbers are in reduced form.
type surrealValue struct {
leftSet *surrealSet
rightSet *surrealSet
}
type surrealMetadata struct {
identifier int
generation int
}
// =============================================================================
type surrealSet struct {
members []surrealNumber
}
func (s *surrealSet) isMember(num surrealNumber) bool {
for i := 0; i < len(s.members); i++ {
if num.number == s.members[i].number {
return true
}
}
return false
}
func (s *surrealSet) cardinality() int {
return len(s.members)
}
func (s *surrealSet) insert(num surrealNumber) {
if !s.isMember(num) {
s.members = append(s.members, num)
}
}
func (s *surrealSet) remove(num surrealNumber) {
for i := 0; i < len(s.members); i++ {
if num.number == s.members[i].number {
s.members[i] = s.members[len(s.members)-1]
s.members = s.members[:len(s.members)-1]
}
}
}
// =============================================================================
func main() {
// Obtain termination conditions from user.
remainingGenerations := flag.Int("generations", 2, "Number of generations of surreal numbers to breed.")
flag.Parse()
if *remainingGenerations < 1 {
log.Fatal("ERROR: The argument to '-generations' must be greater than zero.")
}
// Build a universe to contain all the surreal numbers we breed.
// Seed it by hand with the number zero as generation-0.
var universe surrealUniverse
universe.insert(surrealNumber{surrealValue{nil, nil}, surrealMetadata{0, 0}})
// TODO: Describe the basic algorithm.
for generation := 1; generation <= *remainingGenerations; generation++ {
// TODO: Continue here next time.
// Rough Plan:
// allSymbols := buildAllSymbolCombinations(generation)
// validNumbers := pruneInvalidSymbolCombinations(allSymbols)
// addNumbersToUniverse(validNumbers)
}
// TODO: These are just for checking progress. How do I want to render the
// final generations vs magnitude chart?
fmt.Println("Total Numbers:", len(universe.numbers))
fmt.Println(universe.numbers)
}
// =============================================================================