diff --git a/go/ugly-number-ii.go b/go/ugly-number-ii.go new file mode 100644 index 0000000..34bd08e --- /dev/null +++ b/go/ugly-number-ii.go @@ -0,0 +1,50 @@ +package main + +import ( + "cmp" + "slices" +) + +type Factor struct { + factor int + index int + next int +} + +func MakeFactor(factor int) Factor { + return Factor{ + factor: factor, + index: 0, + next: factor, + } +} + +func (f *Factor) Update(ugly []int, last int) { + if last != f.next { + return + } + + f.index++ + f.next = f.factor * ugly[f.index] +} + +func nthUglyNumber(n int) int { + ugly := make([]int, n) + ugly[0] = 1 + + factors := []Factor{ + MakeFactor(2), MakeFactor(3), MakeFactor(5), + } + + for i := 1; i < n; i++ { + ugly[i] = slices.MinFunc(factors, func(a, b Factor) int { + return cmp.Compare(a.next, b.next) + }).next + + for j, _ := range factors { + factors[j].Update(ugly, ugly[i]) + } + } + + return ugly[n-1] +}