@@ -90,38 +90,56 @@ func getKeyword(position int) (keyword string, err error) {
9090}
9191
9292// The function intended to convert any sized positive integer numbers into words
93- func convertIntPart (strArg string ) string {
93+ func convertIntPart (strArg string ) ( string , error ) {
9494 str := removeSignMarkIfExists (strArg )
95+ length := len (str )
9596
96- //used to indicate level 10^3, 10^6
97- pos := 1
98- wordBuilder := make ([] string , 0 )
97+ if length == 0 {
98+ return "" , nil
99+ }
99100
100- //starting from right hand side, pick up triples and start process it
101- for i := len (str ); i >= 0 ; i = i - 3 {
101+ // Calculate how many triples will be processed
102+ tripleCount := (length + 2 ) / 3
103+ words := make ([]string , tripleCount * 2 ) // Worst case: each triple + a keyword
104+ wordIndex := tripleCount * 2 - 1 // Fill from the end to avoid reversing
105+
106+ pos := 1
107+ for i := length ; i > 0 ; i -= 3 {
102108 key , _ := getKeyword (pos )
103109 pos ++
104110
105- var leftPointer int = i - 3
111+ leftPointer : = i - 3
106112 if leftPointer < 0 {
107113 leftPointer = 0
108114 }
109- var rightPointer int = i
110115
111- tripleAsWords , _ := tripleToWord (str [leftPointer :rightPointer ])
116+ tripleAsWords , err := tripleToWord (str [leftPointer :i ])
117+ if err != nil {
118+ return "" , err
119+ }
112120
113- //insert triple `tripleAsWords` in the front of result
114- if len (tripleAsWords ) != 0 {
115- if len (key ) != 0 {
116- wordBuilder = append ([]string {tripleAsWords , key }, wordBuilder ... )
117- } else {
118- wordBuilder = append ([]string {tripleAsWords }, wordBuilder ... )
121+ if tripleAsWords != "" {
122+ if key != "" {
123+ words [wordIndex ] = key
124+ wordIndex --
119125 }
126+ words [wordIndex ] = tripleAsWords
127+ wordIndex --
120128 }
129+ }
121130
131+ // Construct the final string using strings.Builder
132+ var builder strings.Builder
133+ for i := wordIndex + 1 ; i < len (words ); i ++ {
134+ if words [i ] != "" {
135+ if builder .Len () > 0 {
136+ builder .WriteByte (' ' )
137+ }
138+ builder .WriteString (words [i ])
139+ }
122140 }
123141
124- return strings . Join ( wordBuilder , " " )
142+ return builder . String (), nil
125143}
126144
127145// convertOneDigitIntoWord("0") -> "sıfır"
@@ -145,38 +163,28 @@ func convertTwoDigitsIntoWord(twoDigitsWord string) (string, error) {
145163 return "" , ErrInvalidArgument
146164 }
147165
148- var textBuilder []string
149- var idxAt1 int
150- if i , err := strconv .Atoi (twoDigitsWord [1 :]); err != nil {
151- return "" , err
152- } else {
153- idxAt1 = i
154- }
155- var wordForIdxAt1 string
156- if idxAt1 == 0 {
157- wordForIdxAt1 = ""
158- } else {
159- wordForIdxAt1 = digits [idxAt1 ]
160- }
161-
162- if len (wordForIdxAt1 ) != 0 {
163- textBuilder = append ([]string {wordForIdxAt1 }, textBuilder ... )
164- }
166+ var builder strings.Builder
167+ first := true // To manage spacing between words
165168
166- var idxAt0 int
167- if i , err := strconv .Atoi (twoDigitsWord [0 :1 ]); err != nil {
169+ // Process tens place (index 0)
170+ if val , err := strconv .Atoi (twoDigitsWord [0 :1 ]); err != nil {
168171 return "" , err
169- } else {
170- idxAt0 = i
172+ } else if val != 0 {
173+ builder .WriteString (tens [val ])
174+ first = false
171175 }
172176
173- wordForIdxAt0 := tens [idxAt0 ]
174-
175- if len (wordForIdxAt0 ) != 0 {
176- textBuilder = append ([]string {wordForIdxAt0 }, textBuilder ... )
177+ // Process ones place (index 1)
178+ if val , err := strconv .Atoi (twoDigitsWord [1 :]); err != nil {
179+ return "" , err
180+ } else if val != 0 {
181+ if ! first {
182+ builder .WriteString (" " )
183+ }
184+ builder .WriteString (digits [val ])
177185 }
178186
179- return strings . Join ( textBuilder , " " ), nil
187+ return builder . String ( ), nil
180188}
181189
182190// convertThreeDigitsIntoWord("390") -> "üç yüz doxsan"
@@ -186,65 +194,42 @@ func convertThreeDigitsIntoWord(threeDigitsWord string) (string, error) {
186194 return "" , ErrInvalidArgument
187195 }
188196
189- var textBuilder []string
190- for i := len (threeDigitsWord ) - 1 ; i >= 0 ; i -- {
191-
192- var word string
193- switch i {
194- case 2 :
195- var ValAtIdx2 int
196- if i , err := strconv .Atoi (threeDigitsWord [2 :]); err != nil {
197- return "" , err
198- } else {
199- ValAtIdx2 = i
200- }
201- if ValAtIdx2 != 0 {
202- word = digits [ValAtIdx2 ]
203- }
204-
205- case 1 :
206- var ValAtIdx1 int
207- if i , err := strconv .Atoi (threeDigitsWord [1 :2 ]); err != nil {
208- return "" , err
209- } else {
210- ValAtIdx1 = i
211- }
212- if ValAtIdx1 != 0 {
213- word = tens [ValAtIdx1 ]
214- } else {
215- word = ""
216- }
217- case 0 :
218- var ValAtIdx0 int
219- if i , err := strconv .Atoi (threeDigitsWord [0 :1 ]); err != nil {
220- return "" , err
221- } else {
222- ValAtIdx0 = i
223- }
224- isNonZero := ValAtIdx0 != 0
197+ // Use a strings.Builder to avoid heap allocations during string construction
198+ var builder strings.Builder
199+ first := true // To manage spacing between words
225200
226- var prefix string
227- if isNonZero {
228- prefix = digits [ValAtIdx0 ]
229- } else {
230- prefix = ""
231- }
201+ // Process hundreds place
202+ if val , err := strconv .Atoi (threeDigitsWord [0 :1 ]); err != nil {
203+ return "" , err
204+ } else if val != 0 {
205+ builder .WriteString (digits [val ])
206+ builder .WriteString (" " )
207+ builder .WriteString (HundredAsString )
208+ first = false
209+ }
232210
233- if len (prefix ) > 0 {
234- word = prefix + " " + HundredAsString
235- } else {
236- word = ""
237- }
238- default :
239- return "" , ErrUnexpectedBehaviour
211+ // Process tens place
212+ if val , err := strconv .Atoi (threeDigitsWord [1 :2 ]); err != nil {
213+ return "" , err
214+ } else if val != 0 {
215+ if ! first {
216+ builder .WriteString (" " )
240217 }
218+ builder .WriteString (tens [val ])
219+ first = false
220+ }
241221
242- if len (word ) != 0 {
243- textBuilder = append ([]string {word }, textBuilder ... )
222+ // Process ones place
223+ if val , err := strconv .Atoi (threeDigitsWord [2 :]); err != nil {
224+ return "" , err
225+ } else if val != 0 {
226+ if ! first {
227+ builder .WriteString (" " )
244228 }
229+ builder .WriteString (digits [val ])
245230 }
246231
247- return strings . Join ( textBuilder , " " ), nil
232+ return builder . String ( ), nil
248233}
249234
250235// The function intended to convert triples("1", "12", "123") into words' representation
0 commit comments