I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Coprime triplets

Coprime triplets is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Find and show the smallest number which is coprime to the last two predecessors and has not yet appeared; a(1)=1, a(2)=2.
p and q are coprimes if they have no common factors other than 1.
Let p, q < 50

## ALGOL 68

`BEGIN # find members of the coprime triplets sequence: starting from 1, 2 the #      # subsequent members are the lowest number coprime to the previous two  #      # that haven't appeared in the sequence yet                             #    # iterative Greatest Common Divisor routine, returns the gcd of m and n   #    PROC gcd = ( INT m, n )INT:         IF m = 0 THEN            n         ELSE            INT a := ABS m, b := ABS n;            WHILE b /= 0 DO                INT new a = b;                b        := a MOD b;                a        := new a            OD;            a         FI # gcd # ;    # returns an array of the coprime triplets up to n                        #    OP   COPRIMETRIPLETS = ( INT n )[]INT:         BEGIN            [ 1 : n ]INT result;            IF n > 0 THEN                result[ 1 ] := 1;                IF n > 1 THEN                    [ 1 : n ]BOOL used;                    used[ 1 ] := used[ 2 ] := TRUE;                    FOR i FROM 3 TO n DO used[ i ] := FALSE; result[ i ] := 0 OD;                    result[ 2 ] := 2;                    FOR i FROM 3 TO n DO                        INT p1 = result[ i - 1 ];                        INT p2 = result[ i - 2 ];                        BOOL found := FALSE;                        FOR j TO n WHILE NOT found DO                            IF NOT used[ j ] THEN                                found := gcd( p1, j ) = 1 AND gcd( p2, j ) = 1;                                IF found THEN                                    used[   j ] := TRUE;                                    result[ i ] := j                                FI                            FI                        OD                    OD                FI            FI;            result         END # COPRIMETRIPLETS # ;    []INT cps = COPRIMETRIPLETS 49;    INT printed := 0;    FOR i TO UPB cps DO        IF cps[ i ] /= 0 THEN            print( ( whole( cps[ i ], -3 ) ) );            printed +:= 1;            IF printed MOD 10 = 0 THEN print( ( newline ) ) FI        FI    OD;    print( ( newline, "Found ", whole( printed, 0 ), " coprime triplets up to ", whole( UPB cps, 0 ), newline ) )END`
Output:
```  1  2  3  5  4  7  9  8 11 13
6 17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45
Found 36 coprime triplets up to 49
```

## AppleScript

`on hcf(a, b)    repeat until (b = 0)        set x to a        set a to b        set b to x mod b    end repeat     if (a < 0) then return -a    return aend hcf on coprimeTriplets(max)    if (max < 3) then return {}    script o        property candidates : {}        property output : {1, 2}    end script     -- When repeatedly searching for lowest unused numbers, it's faster in    -- AppleScript to take numbers from a preset list of candidates which    -- grows shorter from at or near the low end as used numbers are removed    -- than it is to test increasing numbers of previous numbers each time    -- against a list that's growing longer with them.    -- Generate the list of candidates here.    repeat with i from 3 to max        set end of o's candidates to i    end repeat    set candidateCount to max - 2    set {p1, p2} to o's output    set ok to true    repeat while (ok) -- While suitable coprimes found and candidates left.        repeat with i from 1 to candidateCount            set q to item i of o's candidates            set ok to ((hcf(p1, q) is 1) and (hcf(p2, q) is 1))            if (ok) then -- q is coprime with both p1 and p2.                set end of o's output to q                set p1 to p2                set p2 to q                -- Remove q from the candidate list.                set item i of o's candidates to missing value                set o's candidates to o's candidates's numbers                set candidateCount to candidateCount - 1                set ok to (candidateCount > 0)                exit repeat            end if        end repeat    end repeat     return o's outputend coprimeTriplets -- Task code:return coprimeTriplets(49)`
Output:
`{1, 2, 3, 5, 4, 7, 9, 8, 11, 13, 6, 17, 19, 10, 21, 23, 16, 15, 29, 14, 25, 27, 22, 31, 35, 12, 37, 41, 18, 43, 47, 20, 33, 49, 26, 45}`

## Factor

Works with: Factor version 0.99 2021-02-05
`USING: combinators.short-circuit.smart formatting grouping iokernel make math prettyprint sequences sets ; : coprime? ( m n -- ? ) simple-gcd 1 = ; : coprime-both? ( m n o -- ? ) '[ _ coprime? ] both? ; : triplet? ( hs m n o -- ? )    { [ coprime-both? nip ] [ 2nip swap in? not ] } && ; : next ( hs m n -- hs' m' n' )    0 [ 4dup triplet? ] [ 1 + ] until    nipd pick [ adjoin ] keepd ; : (triplets-upto) ( n -- )    [ HS{ 1 2 } clone 1 , 1 2 ] dip    '[ 2dup [ _ < ] both? ] [ dup , next ] while 3drop ; : triplets-upto ( n -- seq ) [ (triplets-upto) ] { } make ; "Coprime triplets under 50:" print50 triplets-upto[ 9 group simple-table. nl ][ length "Found %d terms.\n" printf ] bi`
Output:
```Coprime triplets under 50:
1  2  3  5  4  7  9  8  11
13 6  17 19 10 21 23 16 15
29 14 25 27 22 31 35 12 37
41 18 43 47 20 33 49 26 45

Found 36 terms.
```

## FreeBASIC

`function gcd( a as uinteger, b as uinteger ) as uinteger    if b = 0 then return a    return gcd( b, a mod b )end function function num_in_array( array() as integer, num as integer ) as boolean    for i as uinteger = 1 to ubound(array)        if array(i) = num then return true    next i    return falseend function redim as integer trips(1 to 2)trips(1) = 1 : trips(2) = 2dim as integer last do    last = ubound(trips)    for q as integer = 1 to 49        if not num_in_array( trips(), q ) _          andalso gcd(q, trips(last)) = 1 _          andalso gcd(q, trips(last-1)) = 1 then            redim preserve as integer trips( 1 to last+1 )            trips(last+1) = q            continue do         end if    next q    exit doloop print using "Found ## terms:"; ubound(trips) for i as integer = 1 to last    print trips(i);" ";next i : print`
Output:
```Found 36 terms:
1  2  3  5  4  7  9  8  11  13  6  17  19  10  21  23  16  15  29  14  25  27  22  31  35  12  37  41  18  43  47  20  33  49  26  45
```

`import Data.List (find, transpose, unfoldr)import Data.List.Split (chunksOf)import qualified Data.Set as S --------------------- COPRIME TRIPLES -------------------- coprimeTriples :: Integral a => [a]coprimeTriples =  [1, 2] <> unfoldr go (S.fromList [1, 2], (1, 2))  where    go (seen, (a, b)) =      Just        (c, (S.insert c seen, (b, c)))      where        Just c =          find            ( ((&&) . flip S.notMember seen)                <*> ((&&) . coprime a <*> coprime b)            )            [3 ..] coprime :: Integral a => a -> a -> Boolcoprime a b = 1 == gcd a b  --------------------------- TEST -------------------------main :: IO ()main =  let xs = takeWhile (< 50) coprimeTriples   in putStrLn (show (length xs) <> " terms below 50:\n")        >> putStrLn          ( spacedTable              justifyRight              (chunksOf 10 (show <\$> xs))          )  -------------------------- FORMAT ------------------------spacedTable ::  (Int -> Char -> String -> String) -> [[String]] -> StringspacedTable aligned rows =  unlines \$    unwords      . zipWith        (`aligned` ' ')        (maximum . fmap length <\$> transpose rows)      <\$> rows justifyRight :: Int -> Char -> String -> StringjustifyRight n c = (drop . length) <*> (replicate n c <>)`
Output:
```36 terms below 50:

1  2  3  5  4  7  9  8 11 13
6 17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45```

## Julia

Translation of: Phix
`function coprime_triplets(less_than = 50)    cpt = [1, 2]    while true        m = 1        while m in cpt || gcd(m, cpt[end]) != 1 || gcd(m, cpt[end - 1]) != 1            m += 1        end        m >= less_than && return cpt        push!(cpt, m)    endend trps = coprime_triplets()println("Found \$(length(trps)) coprime triplets less than 50:")foreach(p -> print(rpad(p, 3), p %10 == 0 ? "\n" : ""), enumerate(trps)) `
Output:
```
Found 36 coprime triplets less than 50:
1  2  3  5  4  7  9  8  11 13
6  17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45

```

## Perl

Library: ntheory
`use strict;use warnings;use feature <state say>;use ntheory 'gcd';use List::Util 'first';use List::Lazy 'lazy_list';use enum qw(False True);use constant Inf => 1e5; my \$ct = lazy_list {    state @c = (1, 2);    state %seen = (1 => True, 2 => True);    state \$min = 3;    my \$g = \$c[-2] * \$c[-1];    my \$n = first { !\$seen{\$_} and gcd(\$_,\$g) == 1 } \$min .. Inf;    \$seen{\$n} = True;    \$min = first { !\$seen{\$_} } \$min .. Inf;    push @c, \$n;    shift @c}; my @ct;do { push @ct, \$ct->next() } until \$ct[-1] > 50; pop @ct;say join ' ', @ct`
Output:
`1 2 3 5 4 7 9 8 11 13 6 17 19 10 21 23 16 15 29 14 25 27 22 31 35 12 37 41 18 43 47 20 33 49 26 45`

## Phix

```function coprime_triplets(integer less_than=50)
sequence cpt = {1,2}
while true do
integer m = 1
while find(m,cpt)
or gcd(m,cpt[\$])!=1
or gcd(m,cpt[\$-1])!=1 do
m += 1
end while
if m>=less_than then exit end if
cpt &= m
end while
return cpt
end function
sequence res = apply(true,sprintf,{{"%2d"},coprime_triplets()})
printf(1,"Found %d coprime triplets:\n%s\n",{length(res),join_by(res,1,10," ")})
```
Output:
```Found 36 coprime triplets:
1  2  3  5  4  7  9  8 11 13
6 17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45
```

## Raku

`my @coprime-triplets = 1, 2, {   state %seen = 1, True, 2, True;   state \$min = 3;   my \$g = \$^a * \$^b;   my \$n = (\$min .. *).first: { !%seen{\$_} && (\$_ gcd \$g == 1) }   %seen{\$n} = True;   if %seen.elems %% 100 { \$min = (\$min .. *).first: { !%seen{\$_} } }   \$n} … *; put "Coprime triplets before first > 50:\n",@coprime-triplets[^(@coprime-triplets.first: * > 50, :k)].batch(10)».fmt("%4d").join: "\n"; put "\nOr maybe, minimum Coprime triplets that encompass 1 through 50:\n",@coprime-triplets[0..(@coprime-triplets.first: * == 42, :k)].batch(10)».fmt("%4d").join: "\n"; put "\nAnd for the heck of it: 1001st through 1050th Coprime triplet:\n",@coprime-triplets[1000..1049].batch(10)».fmt("%4d").join: "\n";`
Output:
```Coprime triplets before first > 50:
1    2    3    5    4    7    9    8   11   13
6   17   19   10   21   23   16   15   29   14
25   27   22   31   35   12   37   41   18   43
47   20   33   49   26   45

Or maybe, minimum Coprime triplets that encompass 1 through 50:
1    2    3    5    4    7    9    8   11   13
6   17   19   10   21   23   16   15   29   14
25   27   22   31   35   12   37   41   18   43
47   20   33   49   26   45   53   28   39   55
32   51   59   38   61   63   34   65   57   44
67   69   40   71   73   24   77   79   30   83
89   36   85   91   46   75   97   52   81   95
56   87  101   50   93  103   58   99  107   62
105  109   64  111  113   68  115  117   74  119
121   48  125  127   42

And for the heck of it: 1001st through 1050th Coprime triplet:
682 1293 1361  680 1287 1363  686 1299 1367  688
1305 1369  692 1311 1373  694 1317 1375  698 1323
1381  704 1329 1379  706 1335 1387  716 1341 1385
712 1347 1391  700 1353 1399  710 1359 1393  718
1371 1397  722 1365 1403  724 1377 1405  728 1383```

## REXX

`/*REXX program finds and display  coprime triplets  below a specified limit  (limit=50).*/parse arg n cols .                               /*obtain optional arguments from the CL*/if    n=='' |    n==","  then    n= 50           /*Not specified?  Then use the default.*/if cols=='' | cols==","  then cols= 10           /* "      "         "   "   "     "    */w= max(3, length( commas(n) ) )                  /*width of a number in any column.     */                                     @copt= ' coprime triplets  where  N  < '    commas(n)if cols>0  then say ' index │'center(@copt, 1 + cols*(w+1)     )if cols>0  then say '───────┼'center(""   , 1 + cols*(W+1), '─')!.= 0;                   @.= !.;   idx= 1;    \$= /*initialize some variables.           */       do #=1          do j=1;     if @.j  then iterate       /*J in list of coprime triplets?  Skip.*/          if #<3  then leave                     /*First two entries not defined? Use it*/                      a= # - 1;    b= # - 2      /*get the last two indices of sequence.*/          if gcd(j, !.a)\==1  then iterate       /*J not coprime with    last    number?*/          if gcd(j, !.b)\==1  then iterate       /*"  "     "      "  penultimate   "   */          leave                                  /*OK, we've found a new coprime triplet*/          end   /*j*/       if j>=n  then leave                       /*Have we exceeded the limit? Then quit*/       @.j= 1;              !.#= j               /*flag a coprime triplet (two methods).*/       if cols==0  then iterate                  /*Not showing the numbers? Keep looking*/       \$= \$  right( commas(j), w)                /*append coprime triplet to output list*/       if #//cols\==0  then iterate              /*Is output line full? No, keep looking*/       say center(idx, 7)'│' substr(\$, 2);    \$= /*show output line of coprime triplets.*/       idx= idx + cols                           /*bump the index for the output line.  */       end   /*forever*/ if \$\==''  then say center(idx, 7)'│'  substr(\$, 2)   /*show any residual output numbers*/if cols>0 then say '───────┴'center(""    , 1 + cols*(w+1), '─')saysay 'Found '     commas(#-1)      @coptexit 0                                           /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/commas: parse arg ?;  do jc=length(?)-3  to 1  by -3; ?=insert(',', ?, jc); end;  return ?gcd:    procedure; parse arg x,y;  do until _==0;  _= x//y;  x= y;  y= _;   end;  return x`
output   when using the default inputs:
``` index │    coprime triplets  where  N  <  50
───────┼─────────────────────────────────────────
1   │   1   2   3   5   4   7   9   8  11  13
11   │   6  17  19  10  21  23  16  15  29  14
21   │  25  27  22  31  35  12  37  41  18  43
31   │  47  20  33  49  26  45
───────┴─────────────────────────────────────────

Found  36  coprime triplets  where  N  <  50
```

## Ring

` see "working..." + nlrow = 2numbers = 1:50first = 1second = 2see "Coprime triplets are:" + nlsee "" + first + " " + second + " "      for n = 3 to len(numbers)         flag1 = 1         flag2 = 1         if first < numbers[n]            min = first         else            min = numbers[n]         ok         for m = 2 to min             if first%m = 0 and numbers[n]%m = 0                flag1 = 0                exit             ok         next         if second < numbers[n]            min = second         else            min = numbers[n]         ok         for m = 2 to min             if second%m = 0 and numbers[n]%m = 0                 flag2 = 0                exit             ok         next         if flag1 = 1 and flag2 = 1            see "" + numbers[n] + " "            first = second             second = numbers[n]             del(numbers,n)            row = row+1            if row%10 = 0               see nl            ok            n = 2         ok    next     see nl + "Found " + row + " coprime triplets" + nl    see "done..." + nl `
Output:
```working...
Coprime triplets are:
1 2 3 5 4 7 9 8 11 13
6 17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45
Found 36 coprime triplets
done...
```

## Wren

Translation of: Phix
Library: Wren-math
Library: Wren-seq
Library: Wren-fmt
`import "/math" for Intimport "/seq" for Lstimport "/fmt" for Fmt var limit = 50var cpt = [1, 2] while (true) {    var m = 1    while (cpt.contains(m) || Int.gcd(m, cpt[-1]) != 1 || Int.gcd(m, cpt[-2]) != 1) {        m = m + 1    }    if (m >= limit) break    cpt.add(m)}System.print("Coprime triplets under %(limit):")for (chunk in Lst.chunks(cpt, 10)) Fmt.print("\$2d", chunk)System.print("\nFound %(cpt.count) such numbers.")`
Output:
```Coprime triplets under 50:
1  2  3  5  4  7  9  8 11 13
6 17 19 10 21 23 16 15 29 14
25 27 22 31 35 12 37 41 18 43
47 20 33 49 26 45

Found 36 such numbers.
```