WeixiangYan/CodeTransOcean huggingface dataset:
Task: Set puzzle




Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    number = [3]string{"1", "2", "3"}
    color  = [3]string{"red", "green", "purple"}
    shade  = [3]string{"solid", "open", "striped"}
    shape  = [3]string{"oval", "squiggle", "diamond"}
)

type card int

func (c card) String() string {
    return fmt.Sprintf("%s %s %s %s",
        number[c/27],
        color[c/9%3],
        shade[c/3%3],
        shape[c%3])
}

func main() {
    rand.Seed(time.Now().Unix())
    game("Basic", 9, 4)
    game("Advanced", 12, 6)
}

func game(level string, cards, sets int) {
    
    d := make([]card, 81)
    for i := range d {
        d[i] = card(i)
    }
    var found [][3]card
    for len(found) != sets {
        found = found[:0]
        
        for i := 0; i < cards; i++ {
            j := rand.Intn(81 - i)
            d[i], d[j] = d[j], d[i]
        }
        
        for i := 2; i < cards; i++ {
            c1 := d[i]
            for j := 1; j < i; j++ {
                c2 := d[j]
            l3:
                for _, c3 := range d[:j] {
                    for f := card(1); f < 81; f *= 3 {
                        if (c1/f%3 + c2/f%3 + c3/f%3) % 3 != 0 {
                            continue l3 
                        }
                    }
                    
                    found = append(found, [3]card{c1, c2, c3})
                }
            }
        }
    }
    
    fmt.Printf("%s game.  %d cards, %d sets.\n", level, cards, sets)
    fmt.Println("Cards:")
    for _, c := range d[:cards] {
        fmt.Println("  ", c)
    }
    fmt.Println("Sets:")
    for _, s := range found {
        fmt.Printf("  %s\n  %s\n  %s\n",s[0],s[1],s[2])
    }
}








Ada: package Set_Puzzle is
   
   type Three is range 1..3;
   type Card is array(1 .. 4) of Three;
   type Cards is array(Positive range <>) of Card;   
   type Set is array(Three) of Positive;
   
   procedure Deal_Cards(Dealt: out Cards);
   
   
   function To_String(C: Card) return String;
   
   generic
      with procedure Do_something(C: Cards; S: Set);
   procedure Find_Sets(Given: Cards);
   
   
end Set_Puzzle;
Task: Set puzzle







Python: 
    
from itertools import product, combinations
from random import sample
 

features = [ 'green purple red'.split(),
             'one two three'.split(),
             'oval diamond squiggle'.split(),
             'open striped solid'.split() ]
             
deck = list(product(list(range(3)), repeat=4))

dealt = 9
 

def printcard(card):
    print(' '.join('%8s' % f[i] for f,i in zip(features, card)))
 
def getdeal(dealt=dealt):
    deal = sample(deck, dealt)
    return deal
 
def getsets(deal):
    good_feature_count = set([1, 3])
    sets = [ comb for comb in combinations(deal, 3)
             if all( [(len(set(feature)) in good_feature_count)
                     for feature in zip(*comb)]
                   ) ]
    return sets
 
def printit(deal, sets):
    print('Dealt %i cards:' % len(deal))
    for card in deal: printcard(card)
    print('\nFound %i sets:' % len(sets))
    for s in sets:
        for card in s: printcard(card)
        print('')
 
if __name__ == '__main__':
    while True:
        deal = getdeal()
        sets = getsets(deal)
        if len(sets) == dealt / 2:
           break
    printit(deal, sets)





Ada: package Set_Puzzle is
   
   type Three is range 1..3;
   type Card is array(1 .. 4) of Three;
   type Cards is array(Positive range <>) of Card;   
   type Set is array(Three) of Positive;
   
   procedure Deal_Cards(Dealt: out Cards);
   
   
   function To_String(C: Card) return String;
   
   generic
      with procedure Do_something(C: Cards; S: Set);
   procedure Find_Sets(Given: Cards);
   
   
end Set_Puzzle;
Task: Set puzzle

C: #include <stdio.h>
#include <stdlib.h>

char *names[4][3] = {
	{ "red", "green", "purple" },
	{ "oval", "squiggle", "diamond" },
	{ "one", "two", "three" },
	{ "solid", "open", "striped" }
};

int set[81][81];

void init_sets(void)
{
	int i, j, t, a, b;
	for (i = 0; i < 81; i++) {
		for (j = 0; j < 81; j++) {
			for (t = 27; t; t /= 3) {
				a = (i / t) % 3;
				b = (j / t) % 3;
				set[i][j] += t * (a == b ? a : 3 - a - b);
			}
		}
	}
}

void deal(int *out, int n)
{
	int i, j, t, c[81];
	for (i = 0; i < 81; i++) c[i] = i;
	for (i = 0; i < n; i++) {
		j = i + (rand() % (81 - i));
		t = c[i], c[i] = out[i] = c[j], c[j] = t;
	}
}

int get_sets(int *cards, int n, int sets[][3])
{
	int i, j, k, s = 0;
	for (i = 0; i < n; i++) {
		for (j = i + 1; j < n; j++) {
			for (k = j + 1; k < n; k++) {
				if (set[cards[i]][cards[j]] == cards[k])
					sets[s][0] = i,
					sets[s][1] = j,
					sets[s][2] = k,
					s++;
			}
		}
	}

	return s;
}

void show_card(int c)
{
	int i, t;
	for (i = 0, t = 27; t; i++, t /= 3)
		printf("%9s", names[i][(c/t)%3]);
	putchar('\n');
}

void deal_sets(int ncard, int nset)
{
	int c[81];
	int csets[81][3]; 
	int i, j, s;

	do deal(c, ncard); while ((s = get_sets(c, ncard, csets)) != nset);

	printf("dealt %d cards\n", ncard);
	for (i = 0; i < ncard; i++) {
		printf("%2d:", i);
		show_card(c[i]);
	}
	printf("\nsets:\n");

	for (i = 0; i < s; i++) {
		for (j = 0; j < 3; j++) {
			printf("%2d:", csets[i][j]);
			show_card(c[csets[i][j]]);
		}
		putchar('\n');
	}
}

int main(void)
{
	init_sets();
	deal_sets(9, 4);

	while (1) deal_sets(12, 6);

	return 0;
}
Task: Set puzzle







Python: 
    
from itertools import product, combinations
from random import sample
 

features = [ 'green purple red'.split(),
             'one two three'.split(),
             'oval diamond squiggle'.split(),
             'open striped solid'.split() ]
             
deck = list(product(list(range(3)), repeat=4))

dealt = 9
 

def printcard(card):
    print(' '.join('%8s' % f[i] for f,i in zip(features, card)))
 
def getdeal(dealt=dealt):
    deal = sample(deck, dealt)
    return deal
 
def getsets(deal):
    good_feature_count = set([1, 3])
    sets = [ comb for comb in combinations(deal, 3)
             if all( [(len(set(feature)) in good_feature_count)
                     for feature in zip(*comb)]
                   ) ]
    return sets
 
def printit(deal, sets):
    print('Dealt %i cards:' % len(deal))
    for card in deal: printcard(card)
    print('\nFound %i sets:' % len(sets))
    for s in sets:
        for card in s: printcard(card)
        print('')
 
if __name__ == '__main__':
    while True:
        deal = getdeal()
        sets = getsets(deal)
        if len(sets) == dealt / 2:
           break
    printit(deal, sets)
Task: Set puzzle




Go: package main

import (
    "fmt"
    "math/rand"
    "time"
)

const (
    number = [3]string{"1", "2", "3"}
    color  = [3]string{"red", "green", "purple"}
    shade  = [3]string{"solid", "open", "striped"}
    shape  = [3]string{"oval", "squiggle", "diamond"}
)

type card int

func (c card) String() string {
    return fmt.Sprintf("%s %s %s %s",
        number[c/27],
        color[c/9%3],
        shade[c/3%3],
        shape[c%3])
}

func main() {
    rand.Seed(time.Now().Unix())
    game("Basic", 9, 4)
    game("Advanced", 12, 6)
}

func game(level string, cards, sets int) {
    
    d := make([]card, 81)
    for i := range d {
        d[i] = card(i)
    }
    var found [][3]card
    for len(found) != sets {
        found = found[:0]
        
        for i := 0; i < cards; i++ {
            j := rand.Intn(81 - i)
            d[i], d[j] = d[j], d[i]
        }
        
        for i := 2; i < cards; i++ {
            c1 := d[i]
            for j := 1; j < i; j++ {
                c2 := d[j]
            l3:
                for _, c3 := range d[:j] {
                    for f := card(1); f < 81; f *= 3 {
                        if (c1/f%3 + c2/f%3 + c3/f%3) % 3 != 0 {
                            continue l3 
                        }
                    }
                    
                    found = append(found, [3]card{c1, c2, c3})
                }
            }
        }
    }
    
    fmt.Printf("%s game.  %d cards, %d sets.\n", level, cards, sets)
    fmt.Println("Cards:")
    for _, c := range d[:cards] {
        fmt.Println("  ", c)
    }
    fmt.Println("Sets:")
    for _, s := range found {
        fmt.Printf("  %s\n  %s\n  %s\n",s[0],s[1],s[2])
    }
}
Task: Averages_Simple moving average



C#: using System;
using System.Collections.Generic;
using System.Linq;

namespace SMA {
    class Program {
        static void Main(string[] args) {
            var nums = Enumerable.Range(1, 5).Select(n => (double)n);
            nums = nums.Concat(nums.Reverse());

            var sma3 = SMA(3);
            var sma5 = SMA(5);

            foreach (var n in nums) {
                Console.WriteLine("{0}    (sma3) {1,-16} (sma5) {2,-16}", n, sma3(n), sma5(n));
            }
        }

        static Func<double, double> SMA(int p) {
            Queue<double> s = new Queue<double>(p);
            return (x) => {
                if (s.Count >= p) {
                    s.Dequeue();
                }
                s.Enqueue(x);
                return s.Average();
            };
        }
    }
}









Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average

C: #include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

typedef struct sma_obj {
  double sma;
  double sum;
  int period;
  double *values;
  int lv;
} sma_obj_t;

typedef union sma_result {
  sma_obj_t *handle;
  double sma;
  double *values;
} sma_result_t;

enum Action { SMA_NEW, SMA_FREE, SMA_VALUES, SMA_ADD, SMA_MEAN };
sma_result_t sma(enum Action action, ...)
{
  va_list vl;
  sma_result_t r;
  sma_obj_t *o;
  double v;

  va_start(vl, action);
  switch(action) {
  case SMA_NEW: 
    r.handle = malloc(sizeof(sma_obj_t));
    r.handle->sma = 0.0;
    r.handle->period = va_arg(vl, int);
    r.handle->values = malloc(r.handle->period * sizeof(double));
    r.handle->lv = 0;
    r.handle->sum = 0.0;
    break;
  case SMA_FREE: 
    r.handle = va_arg(vl, sma_obj_t *);
    free(r.handle->values);
    free(r.handle);
    r.handle = NULL;
    break;
  case SMA_VALUES: 
    o = va_arg(vl, sma_obj_t *);
    r.values = o->values;
    break;
  case SMA_MEAN: 
    o = va_arg(vl, sma_obj_t *);
    r.sma = o->sma;
    break;
  case SMA_ADD: 
    o = va_arg(vl, sma_obj_t *);
    v = va_arg(vl, double);
    if ( o->lv < o->period ) {
      o->values[o->lv++] = v;
      o->sum += v;
      o->sma = o->sum / o->lv;
    } else {
      o->sum -= o->values[ o->lv % o->period];
      o->sum += v;
      o->sma = o->sum / o->period;
      o->values[ o->lv % o->period ] = v; o->lv++;
    }
    r.sma = o->sma;
    break;
  }
  va_end(vl);
  return r;
}











Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average


C++: #include <iostream>
#include <stddef.h>
#include <assert.h>

using std::cout;
using std::endl;

class SMA {
public:
	SMA(unsigned int period) :
		period(period), window(new double[period]), head(NULL), tail(NULL),
				total(0) {
		assert(period >= 1);
	}
	~SMA() {
		delete[] window;
	}

	
	void add(double val) {
		
		if (head == NULL) {
			head = window;
			*head = val;
			tail = head;
			inc(tail);
			total = val;
			return;
		}

		
		if (head == tail) {
			
			total -= *head;
			
			inc(head);
		}

		
		*tail = val;
		inc(tail);

		
		total += val;
	}

	
	
	double avg() const {
		ptrdiff_t size = this->size();
		if (size == 0) {
			return 0; 
		}
		return total / (double) size; 
	}

private:
	unsigned int period;
	double * window; 

	
	double * head; 
	double * tail; 

	double total; 

	
	
	void inc(double * & p) {
		if (++p >= window + period) {
			p = window;
		}
	}

	
	ptrdiff_t size() const {
		if (head == NULL)
			return 0;
		if (head == tail)
			return period;
		return (period + tail - head) % period;
	}
};

int main(int argc, char * * argv) {
	SMA foo(3);
	SMA bar(5);

	int data[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
	for (int * itr = data; itr < data + 10; itr++) {
		foo.add(*itr);
		cout << "Added " << *itr << " avg: " << foo.avg() << endl;
	}
	cout << endl;
	for (int * itr = data; itr < data + 10; itr++) {
		bar.add(*itr);
		cout << "Added " << *itr << " avg: " << bar.avg() << endl;
	}

	return 0;
}










Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average




Go: package main

import "fmt"

func sma(period int) func(float64) float64 {
    var i int
    var sum float64
    var storage = make([]float64, 0, period)

    return func(input float64) (avrg float64) {
        if len(storage) < period {
            sum += input
            storage = append(storage, input)
        }

	sum += input - storage[i]
        storage[i], i = input, (i+1)%period
	avrg = sum / float64(len(storage))

	return
    }
}

func main() {
    sma3 := sma(3)
    sma5 := sma(5)
    fmt.Println("x       sma3   sma5")
    for _, x := range []float64{1, 2, 3, 4, 5, 5, 4, 3, 2, 1} {
        fmt.Printf("%5.3f  %5.3f  %5.3f\n", x, sma3(x), sma5(x))
    }
}








Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average





Java: import java.util.LinkedList;
import java.util.Queue;

public class MovingAverage {
    private final Queue<Double> window = new LinkedList<Double>();
    private final int period;
    private double sum;

    public MovingAverage(int period) {
        assert period > 0 : "Period must be a positive integer";
        this.period = period;
    }

    public void newNum(double num) {
        sum += num;
        window.add(num);
        if (window.size() > period) {
            sum -= window.remove();
        }
    }

    public double getAvg() {
        if (window.isEmpty()) return 0.0; 
        return sum / window.size();
    }

    public static void main(String[] args) {
        double[] testData = {1, 2, 3, 4, 5, 5, 4, 3, 2, 1};
        int[] windowSizes = {3, 5};
        for (int windSize : windowSizes) {
            MovingAverage ma = new MovingAverage(windSize);
            for (double x : testData) {
                ma.newNum(x);
                System.out.println("Next number = " + x + ", SMA = " + ma.getAvg());
            }
            System.out.println();
        }
    }
}







Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average







Python: from collections import deque

def simplemovingaverage(period):
    assert period == int(period) and period > 0, "Period must be an integer >0"
    
    summ = n = 0.0
    values = deque([0.0] * period)     

    def sma(x):
        nonlocal summ, n
        
        values.append(x)
        summ += x - values.popleft()
        n = min(n+1, period)
        return summ / n

    return sma





Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average








VB: Class sma

Private n As Integer 
Private arr() As Double 
Private index As Integer 
Private oldsma As Double

Public Sub init(size As Integer)
    n = size
    ReDim arr(n - 1)
    index = 0
End Sub

Public Function sma(number As Double) As Double
    sma = oldsma + (-arr(index) + number) / n
    oldsma = sma
    arr(index) = number
    index = (index + 1) Mod n
End Function

Normal module
Public Sub main()
    s = [{1,2,3,4,5,5,4,3,2,1}]
    Dim sma3 As New sma
    Dim sma5 As New sma
    sma3.init 3
    sma5.init 5
    For i = 1 To UBound(s)
        Debug.Print i, Format(sma3.sma(CDbl(s(i))), "0.00000"),
        Debug.Print Format(sma5.sma(CDbl(s(i))), "0.00000")
    Next i
End Sub




Ada: generic
   Max_Elements : Positive;
   type Number is digits <>;
package Moving is
   procedure Add_Number (N : Number);
   function Moving_Average (N : Number) return Number;
   function Get_Average return Number;
end Moving;
Task: Averages_Simple moving average

C: #include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

typedef struct sma_obj {
  double sma;
  double sum;
  int period;
  double *values;
  int lv;
} sma_obj_t;

typedef union sma_result {
  sma_obj_t *handle;
  double sma;
  double *values;
} sma_result_t;

enum Action { SMA_NEW, SMA_FREE, SMA_VALUES, SMA_ADD, SMA_MEAN };
sma_result_t sma(enum Action action, ...)
{
  va_list vl;
  sma_result_t r;
  sma_obj_t *o;
  double v;

  va_start(vl, action);
  switch(action) {
  case SMA_NEW: 
    r.handle = malloc(sizeof(sma_obj_t));
    r.handle->sma = 0.0;
    r.handle->period = va_arg(vl, int);
    r.handle->values = malloc(r.handle->period * sizeof(double));
    r.handle->lv = 0;
    r.handle->sum = 0.0;
    break;
  case SMA_FREE: 
    r.handle = va_arg(vl, sma_obj_t *);
    free(r.handle->values);
    free(r.handle);
    r.handle = NULL;
    break;
  case SMA_VALUES: 
    o = va_arg(vl, sma_obj_t *);
    r.values = o->values;
    break;
  case SMA_MEAN: 
    o = va_arg(vl, sma_obj_t *);
    r.sma = o->sma;
    break;
  case SMA_ADD: 
    o = va_arg(vl, sma_obj_t *);
    v = va_arg(vl, double);
    if ( o->lv < o->period ) {
      o->values[o->lv++] = v;
      o->sum += v;
      o->sma = o->sum / o->lv;
    } else {
      o->sum -= o->values[ o->lv % o->period];
      o->sum += v;
      o->sma = o->sum / o->period;
      o->values[ o->lv % o->period ] = v; o->lv++;
    }
    r.sma = o->sma;
    break;
  }
  va_end(vl);
  return r;
}
Task: Averages_Simple moving average



C#: using System;
using System.Collections.Generic;
using System.Linq;

namespace SMA {
    class Program {
        static void Main(string[] args) {
            var nums = Enumerable.Range(1, 5).Select(n => (double)n);
            nums = nums.Concat(nums.Reverse());

            var sma3 = SMA(3);
            var sma5 = SMA(5);

            foreach (var n in nums) {
                Console.WriteLine("{0}    (sma3) {1,-16} (sma5) {2,-16}", n, sma3(n), sma5(n));
            }
        }

        static Func<double, double> SMA(int p) {
            Queue<double> s = new Queue<double>(p);
            return (x) => {
                if (s.Count >= p) {
                    s.Dequeue();
                }
                s.Enqueue(x);
                return s.Average();
            };
        }
    }
}
Task: Averages_Simple moving average


C++: #include <iostream>
#include <stddef.h>
#include <assert.h>

using std::cout;
using std::endl;

class SMA {
public:
	SMA(unsigned int period) :
		period(period), window(new double[period]), head(NULL), tail(NULL),
				total(0) {
		assert(period >= 1);
	}
	~SMA() {
		delete[] window;
	}

	
	void add(double val) {
		
		if (head == NULL) {
			head = window;
			*head = val;
			tail = head;
			inc(tail);
			total = val;
			return;
		}

		
		if (head == tail) {
			
			total -= *head;
			
			inc(head);
		}

		
		*tail = val;
		inc(tail);

		
		total += val;
	}

	
	
	double avg() const {
		ptrdiff_t size = this->size();
		if (size == 0) {
			return 0; 
		}
		return total / (double) size; 
	}

private:
	unsigned int period;
	double * window; 

	
	double * head; 
	double * tail; 

	double total; 

	
	
	void inc(double * & p) {
		if (++p >= window + period) {
			p = window;
		}
	}

	
	ptrdiff_t size() const {
		if (head == NULL)
			return 0;
		if (head == tail)
			return period;
		return (period + tail - head) % period;
	}
};

int main(int argc, char * * argv) {
	SMA foo(3);
	SMA bar(5);

	int data[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
	for (int * itr = data; itr < data + 10; itr++) {
		foo.add(*itr);
		cout << "Added " << *itr << " avg: " << foo.avg() << endl;
	}
	cout << endl;
	for (int * itr = data; itr < data + 10; itr++) {
		bar.add(*itr);
		cout << "Added " << *itr << " avg: " << bar.avg() << endl;
	}

	return 0;
}
Task: Averages_Simple moving average





Java: import java.util.LinkedList;
import java.util.Queue;

public class MovingAverage {
    private final Queue<Double> window = new LinkedList<Double>();
    private final int period;
    private double sum;

    public MovingAverage(int period) {
        assert period > 0 : "Period must be a positive integer";
        this.period = period;
    }

    public void newNum(double num) {
        sum += num;
        window.add(num);
        if (window.size() > period) {
            sum -= window.remove();
        }
    }

    public double getAvg() {
        if (window.isEmpty()) return 0.0; 
        return sum / window.size();
    }

    public static void main(String[] args) {
        double[] testData = {1, 2, 3, 4, 5, 5, 4, 3, 2, 1};
        int[] windowSizes = {3, 5};
        for (int windSize : windowSizes) {
            MovingAverage ma = new MovingAverage(windSize);
            for (double x : testData) {
                ma.newNum(x);
                System.out.println("Next number = " + x + ", SMA = " + ma.getAvg());
            }
            System.out.println();
        }
    }
}
Task: Averages_Simple moving average







Python: from collections import deque

def simplemovingaverage(period):
    assert period == int(period) and period > 0, "Period must be an integer >0"
    
    summ = n = 0.0
    values = deque([0.0] * period)     

    def sma(x):
        nonlocal summ, n
        
        values.append(x)
        summ += x - values.popleft()
        n = min(n+1, period)
        return summ / n

    return sma
Task: Averages_Simple moving average








VB: Class sma

Private n As Integer 
Private arr() As Double 
Private index As Integer 
Private oldsma As Double

Public Sub init(size As Integer)
    n = size
    ReDim arr(n - 1)
    index = 0
End Sub

Public Function sma(number As Double) As Double
    sma = oldsma + (-arr(index) + number) / n
    oldsma = sma
    arr(index) = number
    index = (index + 1) Mod n
End Function

Normal module
Public Sub main()
    s = [{1,2,3,4,5,5,4,3,2,1}]
    Dim sma3 As New sma
    Dim sma5 As New sma
    sma3.init 3
    sma5.init 5
    For i = 1 To UBound(s)
        Debug.Print i, Format(sma3.sma(CDbl(s(i))), "0.00000"),
        Debug.Print Format(sma5.sma(CDbl(s(i))), "0.00000")
    Next i
End Sub
Task: Averages_Simple moving average




Go: package main

import "fmt"

func sma(period int) func(float64) float64 {
    var i int
    var sum float64
    var storage = make([]float64, 0, period)

    return func(input float64) (avrg float64) {
        if len(storage) < period {
            sum += input
            storage = append(storage, input)
        }

	sum += input - storage[i]
        storage[i], i = input, (i+1)%period
	avrg = sum / float64(len(storage))

	return
    }
}

func main() {
    sma3 := sma(3)
    sma5 := sma(5)
    fmt.Println("x       sma3   sma5")
    for _, x := range []float64{1, 2, 3, 4, 5, 5, 4, 3, 2, 1} {
        fmt.Printf("%5.3f  %5.3f  %5.3f\n", x, sma3(x), sma5(x))
    }
}