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 }