Skip to content

Instantly share code, notes, and snippets.

@assyrianic
Last active December 9, 2022 18:50
Show Gist options
  • Save assyrianic/f155d1ea901cc48ec2a696b4d8b0208d to your computer and use it in GitHub Desktop.
Save assyrianic/f155d1ea901cc48ec2a696b4d8b0208d to your computer and use it in GitHub Desktop.
generates boolean algebra expressions.
package main
import (
"fmt"
"math/rand"
"time"
"os"
"strings"
"strconv"
)
const (
// 'combining overline' is its name.
OVERBAR = '\u0305' // needed for doing NOTs
OR = '+'
AND = '∙'
XNOR = '⨀'
XOR = '⨁'
)
func UInt16ToBytes(num uint16, bytes int) []byte {
result := make([]byte, bytes)
for i, j := uint16(1), bytes-1; i <= num && j >= 0; i <<= 1 {
if num & i > 0 {
result[j] = byte(1)
} else {
result[j] = byte(0)
}
j--
}
return result
}
func NumOfBitsNeeded(num uint16) int {
bits_needed := 0
for i := num; i > 0; i >>= 1 {
bits_needed++
}
return bits_needed
}
// GenerateBooleanEquation
// This works from the perspective of a truth table
// where you use a SOP based array of bits.
// take two vars: `a` and `b`.
// --------------
// | # | AB | F |
// | 0 | 00 | T |
// | 1 | 01 | T |
// | 2 | 10 | T |
// | 3 | 11 | T |
// --------------
// If you supply a bit "map" of { 0, 0, 0, 1 }
// where the last `1` indicates bit #3 then you'll be given a string of `a∙b`.
// Likewise, if you supply a bit "map" of { 1, 0, 0, 0 }
// where the first `1` indicates bit #0 then you'll be given a string of `a̅∙b̅`.
func GenerateBooleanEquation(bitmap []byte, num_vars int) string {
vars := ([]rune)("abcdefghijklmnopqrstuvwxyz")
if num_vars >= len(vars) {
return ""
}
var products = make([]strings.Builder, 0, len(bitmap))
for n, v := range bitmap {
if v==byte(0) {
continue
}
/*
`fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6)`
equivalent to `fmt.Sprintf("%6.2f", 12.0)`
*/
bin_lit := fmt.Sprintf("%0[1]*b", num_vars, n)
var product strings.Builder
for i, c := range bin_lit {
switch c {
case '0':
product.WriteRune(vars[i])
product.WriteRune(OVERBAR)
case '1':
product.WriteRune(vars[i])
}
if i+1 < len(bin_lit) {
product.WriteRune(AND)
}
}
products = append(products, product)
}
var equation strings.Builder
for i := range products {
equation.WriteString(products[i].String())
if i+1 < len(products) {
equation.WriteString(" " + string(OR) + " ")
}
}
return equation.String()
}
func main() {
if len(os.Args) < 2 {
fmt.Println("{Bool Algebra Tool}: options--\n [-gen 'generates an entire truth table, capped at 4 variables.']\n number representing amount of variables required.")
return
}
var flags, arg = 0, 1
switch os.Args[arg] {
case "-gen":
flags |= 1
arg++
default:
flags |= 2
}
if flags & 1 > 0 {
if arg >= len(os.Args) {
fmt.Println("{Bool Algebra Tool}: missing number of variables required for generating truth table.")
return
}
num_vars, _ := strconv.Atoi(os.Args[arg])
total_bits := 1 << num_vars
max_value := 2 << (total_bits-1)
probs, _ := os.Create(fmt.Sprintf("boolean_algebra_truth_table_%d_vars.txt", num_vars))
defer probs.Close()
fmt.Fprintf(probs, "Max Value: %d | Total Bits: %d\n", max_value, total_bits)
for i := 0; i < max_value; i++ {
bits := UInt16ToBytes(uint16(i), total_bits)
equation := GenerateBooleanEquation(bits, num_vars)
if equation == "" {
fmt.Fprintf(probs, "𝒇 = 0\n")
continue
} else if strings.Count(string(bits), "\x01")==total_bits {
fmt.Fprintf(probs, "𝒇 = 1\n")
continue
}
fmt.Fprintf(probs, "𝒇 = %v\n", equation)
}
} else if flags & 2 > 0 {
if arg >= len(os.Args) {
fmt.Println("{Bool Algebra Tool}: missing number of variables required for random equation.")
return
}
limit, _ := strconv.Atoi(os.Args[arg])
rand.Seed(time.Now().UnixNano())
num_vars := rand.Intn(limit) + 2
total_bits := 1 << num_vars
bitmap := UInt16ToBytes(uint16(rand.Intn(0xffFF)), total_bits)
fmt.Printf("bits: %v\n 𝒇 = %v\n", bitmap, GenerateBooleanEquation(bitmap, num_vars))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment