Task: Yellowstone sequence




Go: package main

import (
    "fmt"
    "log"
    "os/exec"
)

func gcd(x, y int) int {
    for y != 0 {
        x, y = y, x%y
    }
    return x
}

func yellowstone(n int) []int {
    m := make(map[int]bool)
    a := make([]int, n+1)
    for i := 1; i < 4; i++ {
        a[i] = i
        m[i] = true
    }
    min := 4
    for c := 4; c <= n; c++ {
        for i := min; ; i++ {
            if !m[i] && gcd(a[c-1], i) == 1 && gcd(a[c-2], i) > 1 {
                a[c] = i
                m[i] = true
                if i == min {
                    min++
                }
                break
            }
        }
    }    
    return a[1:]
}

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func main() {
    x := make([]int, 100)
    for i := 0; i < 100; i++ {
        x[i] = i + 1
    }
    y := yellowstone(100)
    fmt.Println("The first 30 Yellowstone numbers are:")
    fmt.Println(y[:30])
    g := exec.Command("gnuplot", "-persist")
    w, err := g.StdinPipe()
    check(err)
    check(g.Start())
    fmt.Fprintln(w, "unset key; plot '-'")
    for i, xi := range x {
        fmt.Fprintf(w, "%d %d\n", xi, y[i])
    }
    fmt.Fprintln(w, "e")
    w.Close()
    g.Wait()
}




Python: 

from itertools import chain, count, islice
from operator import itemgetter
from math import gcd

from matplotlib import pyplot



def yellowstone():
    
    
    def relativelyPrime(a):
        return lambda b: 1 == gcd(a, b)

    
    def nextWindow(triple):
        p2, p1, rest = triple
        [rp2, rp1] = map(relativelyPrime, [p2, p1])

        
        def match(xxs):
            x, xs = uncons(xxs)['Just']
            return (x, xs) if rp1(x) and not rp2(x) else (
                second(cons(x))(
                    match(xs)
                )
            )
        n, residue = match(rest)
        return (p1, n, residue)

    return chain(
        range(1, 3),
        map(
            itemgetter(1),
            iterate(nextWindow)(
                (2, 3, count(4))
            )
        )
    )




def main():
    

    print(showList(
        take(30)(yellowstone())
    ))
    pyplot.plot(
        take(100)(yellowstone())
    )
    pyplot.xlabel(main.__doc__)
    pyplot.show()





def Just(x):
    
    return {'type': 'Maybe', 'Nothing': False, 'Just': x}



def Nothing():
    
    return {'type': 'Maybe', 'Nothing': True}



def cons(x):
    
    return lambda xs: [x] + xs if (
        isinstance(xs, list)
    ) else x + xs if (
        isinstance(xs, str)
    ) else chain([x], xs)



def iterate(f):
    
    def go(x):
        v = x
        while True:
            yield v
            v = f(v)
    return go



def second(f):
    
    return lambda xy: (xy[0], f(xy[1]))



def showList(xs):
    
    return '[' + ','.join(repr(x) for x in xs) + ']'




def take(n):
    
    return lambda xs: (
        xs[0:n]
        if isinstance(xs, (list, tuple))
        else list(islice(xs, n))
    )



def uncons(xs):
    
    if isinstance(xs, list):
        return Just((xs[0], xs[1:])) if xs else Nothing()
    else:
        nxt = take(1)(xs)
        return Just((nxt[0], xs)) if nxt else Nothing()



if __name__ == '__main__':
    main()