Ulam numbers

From Rosetta Code
Revision as of 12:20, 1 December 2020 by PureFox (talk | contribs) (→‎{{header|Go}}: Minor improvement.)

With the following initial conditions:

      u1 = 1 
      u2 = 2 

we define the n-th Ulam number un as the number such that is greater than un-1 and uniquely written as a sum of two different Ulam numbers ui (<n) and uj (<n).

Task

Write a function to generate the n-th Ulam number.

References

Go

Translation of: Wren

<lang go>package main

import "fmt"

func ulam(n int) int {

   ulams := []int{1, 2}
   set := map[int]bool{1: true, 2: true}
   i := 3
   for {
       count := 0
       for j := 0; j < len(ulams); j++ {
           _, ok := set[i-ulams[j]]
           if ok && ulams[j] != (i-ulams[j]) {
               count++
               if count > 2 {
                   break
               }
           }
       }
       if count == 2 {
           ulams = append(ulams, i)
           set[i] = true
           if len(ulams) == n {
               break
           }
       }
       i++
   }
   return ulams[n-1]

}

func main() {

   for n := 10; n <= 10000; n *= 10 {
       fmt.Println("The", n, "\bth Ulam number is", ulam(n))
   }

}</lang>

Output:
The 10th Ulam number is 18
The 100th Ulam number is 690
The 1000th Ulam number is 12294
The 10000th Ulam number is 132788

Haskell

Lazy List

<lang haskell>ulam

 :: Integral i =>
    Int -> i

ulam 1 = 1 ulam 2 = 2 ulam n

 | n > 2 = ulams !! (n-1)

ulams

 :: Integral n =>
    [n]

ulams = 1:2:(nexts [2,1]) nexts us = u: (nexts (u:us))

 where
   n = length us
   [u] = head . filter isSingleton . group . sort  $ 
           [v | i <- [0 .. n-2], j <- [i+1 .. n-1] 
              , let s = us !! i
              , let t = us !! j
              , let v = s+t
              , v > head us
              ]

isSingleton :: [a] -> Bool isSingleton as

 | length as == 1 = True
 | otherwise      = False</lang>

Wren

Library: Wren-set

<lang ecmascript>import "/set" for Set

var ulam = Fn.new() { |n|

   var ulams = [1, 2]
   var set = Set.new(ulams)
   var i = 3
   while (true) {
       var count = 0
       for (j in 0...ulams.count) {
           if (set.contains(i - ulams[j]) && ulams[j] != (i - ulams[j])) {
               count = count + 1
               if (count > 2) break
           }
       }
       if (count == 2) {
           ulams.add(i)
           set.add(i)
           if (ulams.count == n) break
       }
       i = i + 1
   }
   return ulams[-1]

}

var n = 1 while (true) {

   n = n * 10
   System.print("The %(n)th Ulam number is %(ulam.call(n))")
   if (n == 10000) break

}</lang>

Output:
The 10th Ulam number is 18
The 100th Ulam number is 690
The 1000th Ulam number is 12294
The 10000th Ulam number is 132788