Find Number With Most Digits in Go
The challenge
Given a slice of positive integers, return the value with the most digits. If two or more values share the highest digit count, return the first one in the slice.
Examples:
findLongest([]int{1, 10, 100}) // → 100
findLongest([]int{9000, 8, 800}) // → 9000
findLongest([]int{8, 900, 500}) // → 900
This Codewars-style puzzle is asked in Go interviews and screens for understanding of slices, ties, and avoiding allocations.
Solution 1: count digits with integer division
The most idiomatic Go version — no strconv allocation:
package main
func digitCount(n int) int {
if n == 0 {
return 1
}
count := 0
for n > 0 {
n /= 10
count++
}
return count
}
func findLongest(nums []int) int {
longest := nums[0]
longestDigits := digitCount(nums[0])
for i := 1; i < len(nums); i++ {
d := digitCount(nums[i])
if d > longestDigits {
longest = nums[i]
longestDigits = d
}
}
return longest
}
Why this works: Each n /= 10 strips one digit. The strict > comparison preserves the first match on ties. No heap allocation, no float math.
Solution 2: strconv.Itoa shortcut
If readability beats micro-optimisation:
package main
import "strconv"
func findLongest(nums []int) int {
longest := nums[0]
longestDigits := len(strconv.Itoa(nums[0]))
for i := 1; i < len(nums); i++ {
d := len(strconv.Itoa(nums[i]))
if d > longestDigits {
longest = nums[i]
longestDigits = d
}
}
return longest
}
Trade-off: allocates a string for each element. Fine for thousands of inputs, slow for millions.
Solution 3: slices.MaxFunc with a stable wrapper (Go 1.21+)
If you want the standard-library helper but need first-match-wins behaviour:
package main
import (
"slices"
"strconv"
)
func findLongest(nums []int) int {
return slices.MaxFunc(nums, func(a, b int) int {
da, db := len(strconv.Itoa(a)), len(strconv.Itoa(b))
if db > da {
return -1 // b wins ONLY if strictly greater
}
return 1 // otherwise a wins (first occurrence stays)
})
}
Why this works: slices.MaxFunc returns the maximum according to the comparator. By returning 1 (a wins) on equal counts, we make sure the earlier element is treated as “greater” — preserving first-match semantics.
Complexity
| Solution | Time | Space |
|---|---|---|
| Integer division | O(n × d) | O(1) extra |
| strconv.Itoa | O(n × d) | O(n × d) GC |
| slices.MaxFunc | O(n × d) | O(n × d) GC |
Where n = len(nums) and d is the average digit count. For Go’s 64-bit ints d ≤ 19.
Edge cases
- Single element:
findLongest([]int{42})returns42. - Zero inside the slice:
digitCount(0)returns1, matching how humans count digits. - Empty slice: all three solutions panic on
nums[0]— addif len(nums) == 0 { return 0 }if your callers might pass empty.
Test cases
package main
import "testing"
func TestFindLongest(t *testing.T) {
cases := []struct {
in []int
want int
}{
{[]int{1, 10, 100}, 100},
{[]int{9000, 8, 800}, 9000},
{[]int{8, 900, 500}, 900},
{[]int{3, 40000, 100}, 40000},
{[]int{1, 200, 100000}, 100000},
{[]int{42}, 42},
}
for _, c := range cases {
if got := findLongest(c.in); got != c.want {
t.Errorf("findLongest(%v) = %d, want %d", c.in, got, c.want)
}
}
}
Related challenges
- Find the number with the most digits in Python — same puzzle, Python idioms.
- Find the last digit of a huge number in Go — another digit-extraction problem in Go using big.Int.
- Find the last Fibonacci digit in Go — modular arithmetic on huge integers.