Hamming Numbers

August 30, 2011

We follow Dijkstra’s algorithm, given on page 132 of the text:

(define (hamming n)
  (let ((aq (make-vector (+ n 1) 0))
        (i2 1) (i3 1) (i5 1) (x2 2) (x3 3) (x5 5))
    (vector-set! aq 1 1)
    (do ((h 2 (+ h 1))) ((< n h) aq)
      (let ((t (min x2 x3 x5)))
        (vector-set! aq h t)
        (when (= x2 t)
          (set! i2 (+ i2 1))
          (set! x2 (* 2 (vector-ref aq i2))))
        (when (= x3 t)
          (set! i3 (+ i3 1))
          (set! x3 (* 3 (vector-ref aq i3))))
        (when (= x5 t)
          (set! i5 (+ i5 1))
          (set! x5 (* 5 (vector-ref aq i5))))))))

Or, if you only want one element of the sequence:

(define (nth-hamming n) (vector-ref (hamming n) n))

Here are some examples:

> (hamming 1000)
#(0 1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45
  48 50 54 60 64 72 75 80 81 90 96 100 108 120 125 128 135 144
  150 160 162 180 192 200 216 225 240 243 250 256 270 288 300
  320 324 360 375 384 400 405 432 450 480 486 500 512 540 576
  600 625 640 648 675 720 729 750 768 800 810 864 900 960 972
  1000 1024 1080 1125 1152 1200 1215 1250 1280 1296 1350 1440
  1458 1500 1536 1600 1620 1728 1800 1875 1920 1944 2000 2025
  2048 2160 2187 2250 2304 2400 2430 2500 2560 2592 2700 2880
  2916 3000 3072 3125 3200 3240 3375 3456 3600 3645 3750 3840
  3888 4000 4050 4096 4320 4374 4500 4608 4800 4860 5000 5120
  5184 5400 5625 5760 5832 6000 6075 6144 6250 6400 6480 6561
  6750 6912 7200 7290 7500 7680 7776 8000 8100 8192 8640 8748
  9000 9216 9375 9600 9720 10000 10125 10240 10368 10800 10935
  11250 11520 11664 12000 12150 12288 12500 12800 12960 13122
  13500 13824 14400 14580 15000 15360 15552 15625 16000 16200
  16384 16875 17280 17496 18000 18225 18432 18750 19200 19440
  19683 20000 20250 20480 20736 21600 21870 22500 23040 23328
  24000 24300 24576 25000 25600 25920 26244 27000 27648 28125
  28800 29160 30000 30375 30720 31104 31250 32000 32400 32768
  32805 33750 34560 34992 36000 36450 36864 37500 38400 38880
  39366 40000 40500 40960 41472 43200 43740 45000 46080 46656
  46875 48000 48600 49152 50000 50625 51200 51840 52488 54000
  54675 55296 56250 57600 58320 59049 60000 60750 61440 62208
  62500 64000 64800 65536 65610 67500 69120 69984 72000 72900
  73728 75000 76800 77760 78125 78732 80000 81000 81920 82944
  84375 86400 87480 90000 91125 92160 93312 93750 96000 97200
  98304 98415 100000 101250 102400 103680 104976 108000 109350
  110592 112500 115200 116640 118098 120000 121500 122880
  124416 125000 128000 129600 131072 131220 135000 138240
  139968 140625 144000 145800 147456 150000 151875 153600
  155520 156250 157464 160000 162000 163840 164025 165888
  168750 172800 174960 177147 180000 182250 184320 186624
  187500 192000 194400 196608 196830 200000 202500 204800
  207360 209952 216000 218700 221184 225000 230400 233280
  234375 236196 240000 243000 245760 248832 250000 253125
  256000 259200 262144 262440 270000 273375 276480 279936
  281250 288000 291600 294912 295245 300000 303750 307200
  311040 312500 314928 320000 324000 327680 328050 331776
  337500 345600 349920 354294 360000 364500 368640 373248
  375000 384000 388800 390625 393216 393660 400000 405000
  409600 414720 419904 421875 432000 437400 442368 450000
  455625 460800 466560 468750 472392 480000 486000 491520
  492075 497664 500000 506250 512000 518400 524288 524880
  531441 540000 546750 552960 559872 562500 576000 583200
  589824 590490 600000 607500 614400 622080 625000 629856
  640000 648000 655360 656100 663552 675000 691200 699840
  703125 708588 720000 729000 737280 746496 750000 759375
  768000 777600 781250 786432 787320 800000 810000 819200
  820125 829440 839808 843750 864000 874800 884736 885735
  900000 911250 921600 933120 937500 944784 960000 972000
  983040 984150 995328 1000000 1012500 1024000 1036800 1048576
  1049760 1062882 1080000 1093500 1105920 1119744 1125000
  1152000 1166400 1171875 1179648 1180980 1200000 1215000
  1228800 1244160 1250000 1259712 1265625 1280000 1296000
  1310720 1312200 1327104 1350000 1366875 1382400 1399680
  1406250 1417176 1440000 1458000 1474560 1476225 1492992
  1500000 1518750 1536000 1555200 1562500 1572864 1574640
  1594323 1600000 1620000 1638400 1640250 1658880 1679616
  1687500 1728000 1749600 1769472 1771470 1800000 1822500
  1843200 1866240 1875000 1889568 1920000 1944000 1953125
  1966080 1968300 1990656 2000000 2025000 2048000 2073600
  2097152 2099520 2109375 2125764 2160000 2187000 2211840
  2239488 2250000 2278125 2304000 2332800 2343750 2359296
  2361960 2400000 2430000 2457600 2460375 2488320 2500000
  2519424 2531250 2560000 2592000 2621440 2624400 2654208
  2657205 2700000 2733750 2764800 2799360 2812500 2834352
  2880000 2916000 2949120 2952450 2985984 3000000 3037500
  3072000 3110400 3125000 3145728 3149280 3188646 3200000
  3240000 3276800 3280500 3317760 3359232 3375000 3456000
  3499200 3515625 3538944 3542940 3600000 3645000 3686400
  3732480 3750000 3779136 3796875 3840000 3888000 3906250
  3932160 3936600 3981312 4000000 4050000 4096000 4100625
  4147200 4194304 4199040 4218750 4251528 4320000 4374000
  4423680 4428675 4478976 4500000 4556250 4608000 4665600
  4687500 4718592 4723920 4782969 4800000 4860000 4915200
  4920750 4976640 5000000 5038848 5062500 5120000 5184000
  5242880 5248800 5308416 5314410 5400000 5467500 5529600
  5598720 5625000 5668704 5760000 5832000 5859375 5898240
  5904900 5971968 6000000 6075000 6144000 6220800 6250000
  6291456 6298560 6328125 6377292 6400000 6480000 6553600
  6561000 6635520 6718464 6750000 6834375 6912000 6998400
  7031250 7077888 7085880 7200000 7290000 7372800 7381125
  7464960 7500000 7558272 7593750 7680000 7776000 7812500
  7864320 7873200 7962624 7971615 8000000 8100000 8192000
  8201250 8294400 8388608 8398080 8437500 8503056 8640000
  8748000 8847360 8857350 8957952 9000000 9112500 9216000
  9331200 9375000 9437184 9447840 9565938 9600000 9720000
  9765625 9830400 9841500 9953280 10000000 10077696 10125000
  10240000 10368000 10485760 10497600 10546875 10616832
  10628820 10800000 10935000 11059200 11197440 11250000
  11337408 11390625 11520000 11664000 11718750 11796480
  11809800 11943936 12000000 12150000 12288000 12301875
  12441600 12500000 12582912 12597120 12656250 12754584
  12800000 12960000 13107200 13122000 13271040 13286025
  13436928 13500000 13668750 13824000 13996800 14062500
  14155776 14171760 14348907 14400000 14580000 14745600
  14762250 14929920 15000000 15116544 15187500 15360000
  15552000 15625000 15728640 15746400 15925248 15943230
  16000000 16200000 16384000 16402500 16588800 16777216
  16796160 16875000 17006112 17280000 17496000 17578125
  17694720 17714700 17915904 18000000 18225000 18432000
  18662400 18750000 18874368 18895680 18984375 19131876
  19200000 19440000 19531250 19660800 19683000 19906560
  20000000 20155392 20250000 20480000 20503125 20736000
  20971520 20995200 21093750 21233664 21257640 21600000
  21870000 22118400 22143375 22394880 22500000 22674816
  22781250 23040000 23328000 23437500 23592960 23619600
  23887872 23914845 24000000 24300000 24576000 24603750
  24883200 25000000 25165824 25194240 25312500 25509168
  25600000 25920000 26214400 26244000 26542080 26572050
  26873856 27000000 27337500 27648000 27993600 28125000
  28311552 28343520 28697814 28800000 29160000 29296875
  29491200 29524500 29859840 30000000 30233088 30375000
  30720000 31104000 31250000 31457280 31492800 31640625
  31850496 31886460 32000000 32400000 32768000 32805000
  33177600 33554432 33592320 33750000 34012224 34171875
  34560000 34992000 35156250 35389440 35429400 35831808
  36000000 36450000 36864000 36905625 37324800 37500000
  37748736 37791360 37968750 38263752 38400000 38880000
  39062500 39321600 39366000 39813120 39858075 40000000
  40310784 40500000 40960000 41006250 41472000 41943040
  41990400 42187500 42467328 42515280 43046721 43200000
  43740000 44236800 44286750 44789760 45000000 45349632
  45562500 46080000 46656000 46875000 47185920 47239200
  47775744 47829690 48000000 48600000 48828125 49152000
  49207500 49766400 50000000 50331648 50388480 50625000
  51018336 51200000)
> (nth-hamming 1000000)
519312780448388736089589843750000000000000000000000000000000000000000000000000000000

You can run the program at http://programmingpraxis.codepad.org/kzPfcVH7.

Dijkstra’s version is purely imperative. If you like functional programming, look at SRFI-41, which gives this version of the infinite Hamming sequence in Section 5.1:

(define hamming
  (stream-cons 1
    (stream-unique =
      (stream-merge <
        (stream-map (lsec * 2) hamming)
        (stream-map (lsec * 3) hamming)
        (stream-map (lsec * 5) hamming)))))

Pages: 1 2

31 Responses to “Hamming Numbers”

  1. Graham said

    I wrote a Haskell version of Python’s test of using lazy evaluation to generate them; as it turns out, it’s the same as the SRFI-41 version.

    merge :: (Ord a) => [a] -> [a] -> [a]
    merge [] ys = ys
    merge xs [] = xs
    merge (x:xs) (y:ys) | x < y     = x : (merge xs (y:ys))
                        | x > y     = y : (merge (x:xs) ys)
                        | x == y    = y : merge xs ys
    
    
    hammingNumbers :: [Integer]
    hammingNumbers = 1 : merge hN2 (merge hN3 hN5) where
                   hN2 = map (*2) hammingNumbers
                   hN3 = map (*3) hammingNumbers
                   hN5 = map (*5) hammingNumbers
    
    
    main :: IO ()
    main = print $ take 1000 hammingNumbers
    

    Since I’m new to Haskell, I probably didn’t find the most elegant solution (and suggestions are welcome), but lazy evaluation is kind of amazing.

  2. Graham said

    Looks like I had some redundant parentheses in my definition of merge, according to hlint. Apologies.

  3. Jussi Piitulainen said

    Re the imperative version, I think it is nicer to omit the 0 that does not belong to the sequence and simply produce a 0-based sequence of n elements:

    > (aq 10)
    #(1 2 3 4 5 6 8 9 10 12)
    

    (Cut-and-paste from my editor window to be safer against silly typos. I called my translation of Dijkstra’s code aq.)

  4. programmingpraxis said

    Jussi: I tend to add a useless element to the beginning of arrays when porting code from languages that base arrays at 1 instead of 0. It’s mostly harmless, and saves a lot of x+1 and x-1 statements mapping between the two formats. I agree it’s ugly, but only a little bit. Where it actually matters, I do it right.

  5. Here’s a shortish but quite efficient lazy Clojure version:

    (defn hammings [initial-set]
    (let [v (first initial-set)
    others (rest initial-set)]
    (lazy-seq
    (cons
    v
    (hammings (into (sorted-set (* v 2) (* v 3) (* v 5)) others))))))

    (take 1000 (hammings #{1}))

    Runs in about 0.07 ms for the first 1000 hamming numbers on my machine.

  6. Here’s my clojure solution. More details at my blog.

    
    ;;Hamming Numbers
    
    (defn hamming-generator
      ([] (hamming-generator (sorted-set 1)))
      ([some-set] (let [n (first some-set)
                        s (disj some-set n)]
                    (cons n
                          (lazy-seq (hamming-generator
                                     (conj s (* n 2) (* n 3) (* n 5))))))))
    
    (def hamming-numbers (take 1000 (hamming-numbers)))
    
  7. Philipp Siegmantel said


    hemming = [1] ++ concatMap (\ x -> [x*2, x*3, x*5]) hemming
    first1k = sort . take 1000 $ hemming

    My Haskell variant

  8. Jussi Piitulainen said

    Dijkstra advocated 0-based indexing, so I think his algorithm in the chapter may actually be intended to be 0-based. It is hard to tell for sure. However, his initialization of aq to (1 1) is funny either way when only one 1 is meant to remain in the result, and the assignments to ik, xk seem to need to be either parallel or swapped when I implement it. Below is a 0-based version with parallel assignments. For example, (set*! (x y) y x) swaps x and y. (Originally I had tail-recursion instead of assignments, and I did not even notice that the second assignments in Dijkstra depend on the first ones.)

    (define-syntax set*!
      (syntax-rules ()
        ((set*! (var ...) exp ...)
         (set*! "gen" (var ...) () (var ...) exp ...))
        ((set*! "gen" (x y ...) (t ...) (var ...) exp ...)
         (set*! "gen" (y ...) (u t ...) (var ...) exp ...))
        ((set*! "gen" () (tmp ...) (var ...) exp ...)
         (set*! "map" (tmp ...) (var ...) (exp ...) ()))
        ((set*! "map" (x y ...) (t u ...) (d e ...) (w ...))
         (set*! "map" (y ...) (u ...) (e ...) ((x t d) w ...)))
        ((set*! "map" () () () ((tmp var exp) ...))
         (let ((tmp exp) ...) (set! var tmp) ...))))
    
    (define (hamming2 n)
      (let ((aq (make-vector n 1)) (i2 1) (i3 1) (i5 1) (x2 2) (x3 3) (x5 5))
        (do ((h 1 (+ h 1))) ((= h n) aq)
          (let ((t (min x2 x3 x5)))
            (vector-set! aq h t)
            (if (= x2 t) (set*! (i2 x2) (+ i2 1) (* 2 (vector-ref aq i2))))
            (if (= x3 t) (set*! (i3 x3) (+ i3 1) (* 3 (vector-ref aq i3))))
            (if (= x5 t) (set*! (i5 x5) (+ i5 1) (* 5 (vector-ref aq i5))))))))
    

    Cheers.

  9. Graham said

    @Philipp: I like the brevity of your Haskell answer, but it seems to include a lot of repeats; as a Haskell newbie, I couldn’t figure out a way to remove them easily. Any ideas?

  10. programmingpraxis said

    nub

  11. Lautaro Pecile said
    
    from itertools import product
    from bisect import insort
    
    def hamming_numbers():
        result = []
        for n in hamming_generator(10):
            insort(result, n)
        return result
    
    def hamming_generator(n=0):
        for a, b, c in product(xrange(n), repeat=3):
            yield 2**a * 3**b * 5**c
    
    
  12. Continuing to attempt to become more familiar with Haskell. Here is what I came up with.

    import qualified Data.Set as Set
    hammingNumbers = generate $ Set.fromList [1]
            where generate curr =
                           case Set.minView curr of
                                Just (min, rest) -> min :
                                                    generate (foldl (\s x -> Set.insert x s)
                                                                    rest
                                                                    (map (*min) [2,3,5]))
                                Nothing -> error "should not get here"
    
    answer = take 1000 hammingNumbers
    
  13. Adolfo said
    #lang lazy
    
    (define naturals
      (cons 1 (map add1 naturals)))
    
    (define (merge . lsts)
      (let ((ordered (sort lsts (λ (x y) (< (car x) (car y))))))
        (cons (caar ordered)
              (apply merge (cons (cdar ordered)
                                 (map (λ (x) (remove (caar ordered) x))
                                      (cdr ordered)))))))
    
    (define hamming-numbers
      (cons 1 (merge (map (λ (x) (* x 5)) hamming-numbers)
                     (map (λ (x) (* x 3)) hamming-numbers)
                     (map (λ (x) (* x 2)) hamming-numbers))))
    
  14. Adolfo said

    In case you’re curious, my solution is in Lazy Racket :-)

  15. Ended up playing with my answer some more while waiting for some other code to compile. I like how this one better.

    import qualified Data.Set as Set
    hammingNumbers = generate $ Set.fromList [1]
            where generate curr =
                           min : generate (foldl (\s x -> Set.insert (min * x) s) rest [2,3,5])
                           where (min, rest) = Set.deleteFindMin curr
    hammingAnswer = take 1000 hammingNumbers
    
  16. fa said

    HammingNumbers.java

     1 public class HammingNumbers
     2 {
     3     public static int[] hammSeq(int aLen) {
     4         int seq[] = new int[aLen];
     5         int i, i2, i3, i5, x, x2, x3, x5;
     6         
     7         seq[0] = 1; i = 0; x = 1;
     8         i2 = i3 = i5 = -1; x2 = 2; x3 = 3; x5 = 5;
     9         while (++i < aLen) {
    10             seq[i] = x = (x2 <= x3 && x2 <= x5) ? x2 : (x3 <= x5) ? x3 : x5;
    11             while (x2 <= x) x2 = 2 * seq[++i2];
    12             while (x3 <= x) x3 = 3 * seq[++i3];
    13             while (x5 <= x) x5 = 5 * seq[++i5];
    14         }
    15         return seq;
    16     }
    17     
    18     public static void main(String args[]) {
    19         for (int i : hammSeq(1000))
    20             System.out.print(" " + i);
    21         System.out.println();
    22     }
    23 }
    24 
    25 
    

    hamm.go

     1 package main
     2 import "fmt"
     3 
     4 func hamm(slen int, sfunc []func(int)int) (seq []int) {
     5     seq = make([]int, slen); seq[0] = 1 // the calculated values
     6     isf := make([]int, len(sfunc)); for i := 0; i < len(sfunc); i++ { isf[i] = -1 } // the last index for each function
     7     xsf := make([]int, len(sfunc)); for i := 0; i < len(sfunc); i++ { xsf[i] = sfunc[i](seq[0]) } // the next value of each function
     8     xmin := func()int { x := xsf[0]; for i := 1; i < len(sfunc); i++ { if xsf[i] < x { x = xsf[i] } }; return x }
     9     c := make(chan int)
    10     for is := 1; is < slen; is++ {
    11         seq[is] = xmin()
    12         for i, sf := range sfunc { // find the next value for each function, paralellize
    13             go func(sf func(int)int, isf *int, xsf *int, seq []int, is int) {
    14                 for *xsf <= seq[is] { *isf++; *xsf = sf(seq[*isf]) }
    15                 c <- 1 // next value found
    16             } (sf, &isf[i], &xsf[i], seq, is) // pass the arguments
    17         }
    18         for i := 0; i < len(sfunc); i++ { <-c } // wait for each calculation to end
    19     }
    20     return
    21 }
    22 
    23 func main() { // print the first 1000 hamming numbers calculated from the given functions
    24     sfunc := []func(int)int{ func(x int)int{ return 2*x }, func(x int)int{ return 3*x }, func(x int)int{ return 5*x } }
    25     for _, x := range hamm(1000, sfunc) { fmt.Printf("%v ", x) }; fmt.Printf("\n")
    26 }
    27 
    28 
    
  17. Graham said

    @programmingpraxis: I’ve tried throwing nub into the solution, but it either (1) comes after take 1000, in which case there are no longer 1000 entries, or (2) comes before it, and the program just hangs. I am not very adept in Haskell :-(

  18. Mike said

    Hamming number generator in Python 3.

    Follows directly from the definition. Yield 1, then yield 2*, 3* and 5* a number in the list. It’s lazy too.

    from heapq import merge
    from itertools import tee

    def hamming_numbers():
    last = 1
    yield last
    a,b,c = tee(hamming_numbers(), 3)
    for n in merge((2*i for i in a), (3*i for i in b), (5*i for i in c)):
    if n != last:
    yield n
    last = n

    x = list(islice(hamming_numbers(),1000))
    print(x[:10], x[-5:])
    # output -> [1, 2, 3, 4, 5, 6, 8, 9, 10, 12] [50331648, 50388480, 50625000, 51018336, 51200000]

  19. Mike said

    This time with proper formating:

    from heapq import merge
    from itertools import tee
    
    def hamming_numbers():
        last = 1
        yield last
    
        a,b,c = tee(hamming_numbers(), 3)
    
        for n in merge((2*i for i in a), (3*i for i in b), (5*i for i in c)):
            if n != last:
                yield n
                last = n
    
    
    #test			
    x = list(islice(hamming_numbers(),1000))
    print(x[:10],x[-5:])
    #output -> [1, 2, 3, 4, 5, 6, 8, 9, 10, 12] [50331648, 50388480, 50625000, 51018336, 51200000]
    
    
  20. Axio said

    Nothing magical here…

    merge (x:xs) (y:ys) =
      case compare x y of
        LT -> x:(merge xs (y:ys))
        EQ -> x:(merge xs ys)
        GT -> y:(merge (x:xs) ys)
    
    hn = 1: merge (map (* 2) hn)
                  (merge (map (* 3) hn)
                         (map (* 5) hn))
    run = take 1000 hn
    
  21. nbm said

    Inelegant but fast to write in Python:

    >>> from collections import defaultdict
    ... numbers = defaultdict(lambda: False)
    ... numbers[1] = False
    ... while len(numbers) < 1000:
    ...     tbd = [key for key in numbers.keys() if not numbers[key]]
    ...     tbd.sort()
    ...     me = tbd.pop(0)
    ...     numbers[me] = True
    ...     numbers[me * 2] = numbers[me * 2]
    ...     numbers[me * 3] = numbers[me * 3]
    ...     numbers[me * 5] = numbers[me * 5]
    ... hamming = numbers.keys()
    ... hamming.sort()
    
  22. CyberSpace17 said

    my C++ solution. I’m disappointed that it takes so long for my implementation to calculate the sequence. (especially since someone got it in less thana tenth of a second.)Can someone tell me where I can improve the code?
    http://codepad.org/WhHDxJAZ

  23. programmingpraxis said

    The suggested solution makes n trips through a single loop, at each iteration calculating a minimum of three integers, performing three if tests comparing two integers at each iteration, and making a single addition and a single multiplication.

    Your code has 5 for loops, two of them with if tests inside them, and 1 while loop containing an if which has a nested if inside it. And the inner loop of your code performs a modulo operation (a very expensive operation) and a compare for divisorSize × sequenceIndex iterations.

    And you forgot the 1 that starts the sequence.

    By the way, the suggested solution runs in a thousandth of a second, not a tenth of a second:

    > (define x #f)
    > (time (set! x (hamming 1000)))
    (time (set! x ...))
        no collections
        1 ms elapsed cpu time
        1 ms elapsed real time
        12048 bytes allocated
    > (vector-ref x 1000)
    51200000

    To improve your code, you should follow the suggested solution.

    I’m sorry if that’s a little bit harsh. I’ll be happy to look at your improved solution.

    Phil

  24. […] compute the first thousand terms of the Hamming sequence. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments […]

  25. […] This question is copyright of programmingpraxis.com. Click here to see the original […]

  26. CyberSpace17 said

    Thanks Phil for a review of my code. I now see how inefficient it is and was working on a revision but I don’t think I can make my algorithm as efficient as Supriya Koduri’s, to whom I want to ask “what train of thought allowed him to create such an elegant solution?”.

  27. cosmin said

    Another solution based upon Dijkstra’s paper:

    def hammingSeq(N):
    	h = [1]
    	i2, i3, i5 = 0, 0, 0
    	for i in xrange(1, N):
    		x = min(2*h[i2], 3*h[i3], 5*h[i5])
    		h.append(x)
    		if 2*h[i2] <= x: i2 += 1
    		if 3*h[i3] <= x: i3 += 1
    		if 5*h[i5] <= x: i5 += 1
    	return h
    
    print hammingSeq(1000)
    
  28. Kaos Engr said

    The results of the cosmin’s solution in Go posted by glnbrwn 12Dec2012 in Go do not match.

    Python version posted October 30, 2012 by cosmin results are:

    [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, …

    Go when executed at the link given above results in:

    [1 2 3 4 6 8 9 12 16 18 24 27 32 36 48 54 64

    Go is missing 10, 15, 20, 25, 30 when executing it. Multiples of 5 are not getting added to the result.

Leave a comment