github.com/LanderTome/numerologyCalculator@v1.0.2/numerology/utils.go (about)

     1  // Copyright 2021 Robert D. Wukmir
     2  // This file is subject to the terms and conditions defined in
     3  // the LICENSE file, which is part of this source code package.
     4  //
     5  // Unless required by applicable law or agreed to in writing,
     6  // software distributed under the License is distributed on an
     7  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
     8  // either express or implied. See the License for the specific
     9  // language governing permissions and limitations under the
    10  // License.
    11  
    12  package numerology
    13  
    14  import (
    15  	"errors"
    16  	mapset "github.com/deckarep/golang-set"
    17  	"github.com/mozillazg/go-unidecode"
    18  	"regexp"
    19  	"strconv"
    20  	"strings"
    21  	"unicode"
    22  )
    23  
    24  var duplicateSpaces = regexp.MustCompile("\\s+")
    25  var removeNewLines = regexp.MustCompile("[\r\n\t]")
    26  
    27  func removeDuplicateSpaces(s string) string {
    28  	return duplicateSpaces.ReplaceAllString(s, " ")
    29  }
    30  
    31  // ToAscii transliterates a unicode string to ascii string and removes extraneous
    32  // newline chars and whitespace. This conversion is not 100% due to complexities
    33  // of language. See this article by Sean M. Burke for more information.
    34  // https://interglacial.com/~sburke/tpj/as_html/tpj22.html
    35  func ToAscii(s string) string {
    36  	ascii := unidecode.Unidecode(s)
    37  	noNewLines := removeNewLines.ReplaceAllString(ascii, "")
    38  	noDupWhiteSpace := duplicateSpaces.ReplaceAllString(noNewLines, " ")
    39  	return strings.TrimSpace(noDupWhiteSpace)
    40  }
    41  
    42  func numberOfQuestionMarks(s string) int {
    43  	return strings.Count(s, "?")
    44  }
    45  
    46  func isMasterNumber(v int, masterNumbers []int) bool {
    47  	for _, n := range masterNumbers {
    48  		if v == n {
    49  			return true
    50  		}
    51  	}
    52  	return false
    53  }
    54  
    55  func inIntSlice(v int, slice []int) bool {
    56  	for _, n := range slice {
    57  		if v == n {
    58  			return true
    59  		}
    60  	}
    61  	return false
    62  }
    63  
    64  // Convert a number into a slice of numbers. 1234 -> [1,2,3,4]
    65  func splitNumber(i uint64) []int {
    66  	listNumbers := []int{}
    67  	convertedToString := strconv.FormatUint(i, 10)
    68  	// Borrows from standard library for strings.Atoi. Figured we could make it faster by skipping some of
    69  	// their checks because we know that the number is guaranteed to be between 0 and 9.
    70  	for _, ch := range []byte(convertedToString) {
    71  		ch -= '0'
    72  		listNumbers = append(listNumbers, int(ch))
    73  	}
    74  	return listNumbers
    75  }
    76  
    77  // countNumerologicalNumbers converts the letters of a name into the corresponding numerological values based on the given
    78  // numberSystem argument. Those numbers are then compiled into a map that counts the occurrences of each number.
    79  func countNumerologicalNumbers(name string, numberSystem NumberSystem) (counts map[int32]int, maxCount int, unknownChars unknownCharacters) {
    80  	counts = map[int32]int{}
    81  	unknownChars = unknownCharacters{mapset.NewSet()}
    82  	// Initialize map with all valid numbers.
    83  	for _, i := range numberSystem.ValidNumbers {
    84  		counts[int32(i)] = 0
    85  	}
    86  
    87  	for _, n := range name {
    88  		num := int32(numberSystem.NumberMapping[unicode.ToLower(n)])
    89  		// Increment the counts of the numerological numbers.
    90  		if c, ok := counts[num]; ok {
    91  			newCount := c + 1
    92  			counts[num] = newCount
    93  			if newCount > maxCount {
    94  				maxCount = newCount
    95  			}
    96  		} else {
    97  			// If a number isn't valid then skip it. Generally this would be a '0'.
    98  			unknownChars = unknownChars.Add(n)
    99  			continue
   100  		}
   101  	}
   102  	return counts, maxCount, unknownChars
   103  }
   104  
   105  // GetNumberSystem returns the appropriate NumberSystem type from the number systems name. (Pythagorean, Chaldean).
   106  func GetNumberSystem(s string) (NumberSystem, error) {
   107  	switch strings.ToLower(s) {
   108  	case "pythagorean":
   109  		return Pythagorean, nil
   110  	case "chaldean":
   111  		return Chaldean, nil
   112  	default:
   113  		return NumberSystem{}, errors.New("unknown number system: " + s)
   114  	}
   115  }