September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,44 +0,0 @@
I = (P) ->
# The cryptic name "I" follows the problem description;
# it returns a function that computes a moving average
# of successive values over the period P, using closure
# variables to maintain state.
cq = circular_queue(P)
num_elems = 0
sum = 0
SMA = (n) ->
sum += n
if num_elems < P
cq.add(n)
num_elems += 1
sum / num_elems
else
old = cq.replace(n)
sum -= old
sum / P
circular_queue = (n) ->
# queue that only ever stores up to n values;
# Caller shouldn't call replace until n values
# have been added.
i = 0
arr = []
add: (elem) ->
arr.push elem
replace: (elem) ->
# return value whose age is "n"
old_val = arr[i]
arr[i] = elem
i = (i + 1) % n
old_val
# The output of the code below should convince you that
# calling I multiple times returns functions with independent
# state.
sma3 = I(3)
sma7 = I(7)
sma11 = I(11)
for i in [1..10]
console.log i, sma3(i), sma7(i), sma11(i)

View file

@ -1,11 +0,0 @@
> coffee moving_average.coffee
1 1 1 1
2 1.5 1.5 1.5
3 2 2 2
4 3 2.5 2.5
5 4 3 3
6 5 3.5 3.5
7 6 4 4
8 7 5 4.5
9 8 6 5
10 9 7 5.5

View file

@ -1,55 +1,56 @@
#define system.
#define system'routines.
#define system'collections.
#define extensions.
import system'routines.
import system'collections.
import extensions.
#class SMA
class SMA
{
#field thePeriod.
#field theList.
object thePeriod.
object theList.
#constructor new : aPeriod
constructor new : aPeriod
[
thePeriod := aPeriod.
theList := List new.
]
#method append : aNumber
append : aNumber
[
theList += aNumber.
theList append:aNumber.
#var aCount := theList length.
^ aCount =>
0 ? [ 0.0r ]
var aCount := theList length.
aCount =>
0 [ ^0.0r ];
! [
(aCount > thePeriod)?
if (aCount > thePeriod)
[
theList remove &index:0.
theList remove at:0.
aCount := thePeriod.
aCount := thePeriod
].
#var aSum := theList summarize:(Real new &int:0).
var aSum := theList summarize(Real new int:0).
^ aSum / aCount.
].
^ aSum / aCount
]
]
}
#symbol program =
program =
[
#var SMA3 := SMA new:3.
#var SMA5 := SMA new:5.
var SMA3 := SMA new:3.
var SMA5 := SMA new:5.
1 to:5 &doEach: (:i)
1 to:5 do(:i)
[
console write:"sma3 + " :i :" = ": (SMA3 += i) &paddingRight:30 &with:#32.
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
console printPaddingRight(30, "sma3 + ", i, " = ", SMA3 append:i).
console printLine("sma5 + ", i, " = ", SMA5 append:i)
].
5 to:1 &doEach: (:i)
5 to:1 do(:i)
[
console write:"sma3 + " :i :" = ": (SMA3 += i) &paddingRight:30 &with:#32.
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
console printPaddingRight(30, "sma3 + ", i, " = ", SMA3 append:i).
console printLine("sma5 + ", i, " = ", SMA5 append:i)
].
console readChar.
].

View file

@ -1,5 +1,6 @@
import java.util.LinkedList;
import java.util.Queue;
public class MovingAverage {
private final Queue<Double> window = new LinkedList<Double>();
private final int period;
@ -19,13 +20,13 @@ public class MovingAverage {
}
public double getAvg() {
if (window.isEmpty()) return 0; // technically the average is undefined
if (window.isEmpty()) return 0.0; // technically the average is undefined
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};
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) {

View file

@ -0,0 +1,19 @@
// version 1.0.6
fun initMovingAverage(p: Int): (Double) -> Double {
if (p < 1) throw IllegalArgumentException("Period must be a positive integer")
val list = mutableListOf<Double>()
return {
list.add(it)
if (list.size > p) list.removeAt(0)
list.average()
}
}
fun main(args: Array<String>) {
val sma4 = initMovingAverage(4)
val sma5 = initMovingAverage(5)
val numbers = listOf(1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0)
println("num\tsma4\tsma5\n")
for (number in numbers) println("${number}\t${sma4(number)}\t${sma5(number)}")
}

View file

@ -1,83 +0,0 @@
#import <Foundation/Foundation.h>
@interface MovingAverage : NSObject {
unsigned int period;
NSMutableArray *window;
double sum;
}
@end
@implementation MovingAverage
// init with default period
- (id)init {
self = [super init];
if(self) {
period = 10;
window = [[NSMutableArray alloc] init];
sum = 0.0;
}
return self;
}
// init with specified period
- (id)initWithPeriod:(unsigned int)thePeriod {
self = [super init];
if(self) {
period = thePeriod;
window = [[NSMutableArray alloc] init];
sum = 0.0;
}
return self;
}
// clear
- (void)dealloc {
[window release];
[super dealloc];
}
// add a new number to the window
- (void)add:(double)val {
sum += val;
[window addObject:[NSNumber numberWithDouble:val]];
if([window count] > period) {
NSNumber *n = [window objectAtIndex:0];
sum -= [n doubleValue];
[window removeObjectAtIndex:0];
}
}
// get the average value
- (double)avg {
if([window count] == 0) {
return 0; // technically the average is undefined
}
return sum / [window count];
}
// set the period, resizes current window
- (void)setPeriod:(unsigned int)thePeriod {
// make smaller?
if(thePeriod < [window count]) {
for(int i = 0; i < thePeriod; ++i) {
NSNumber *n = [window objectAtIndex:0];
sum -= [n doubleValue];
[window removeObjectAtIndex:0];
}
}
period = thePeriod;
}
// get the period (window size)
- (unsigned int)period {
return period;
}
// clear the window and current sum
- (void)clear {
[window removeAllObjects];
sum = 0;
}
@end

View file

@ -1,11 +0,0 @@
double testData[10] = {1,2,3,4,5,5,4,3,2,1};
int periods[2] = {3,5};
for(int i = 0; i < 2; ++i) {
MovingAverage *ma = [[MovingAverage alloc] initWithPeriod:periods[i]];
for(int j = 0; j < 10; ++j) {
[ma add:testData[j]];
NSLog(@"Next number = %f, SMA = %f", testData[j], [ma avg]);
}
[ma release];
NSLog(@"\n");
}

View file

@ -0,0 +1,42 @@
testdata = .array~of(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)
-- run with different period sizes
loop period over .array~of(3, 5)
say "Period size =" period
say
movingaverage = .movingaverage~new(period)
loop number over testdata
average = movingaverage~addnumber(number)
say " Next number =" number", moving average =" average
end
say
end
::class movingaverage
::method init
expose period queue sum
use strict arg period
sum = 0
-- the circular queue makes this easy
queue = .circularqueue~new(period)
-- add a number to the average set
::method addNumber
expose queue sum
use strict arg number
sum += number
-- add this to the queue
old = queue~queue(number)
-- if we pushed an element off the end of the queue,
-- subtract this from our sum
if old \= .nil then sum -= old
-- and return the current item
return sum / queue~items
-- extra method to retrieve current average
::method average
expose queue sum
-- undefined really, but just return 0
if queue~isempty then return 0
-- return current queue
return sum / queue~items

View file

@ -0,0 +1,19 @@
data 1,2,3,4,5,5,4,3,2,1
dim sd(10) ' series data
global sd ' make it global so we all see it
for i = 1 to 10:read sd(i): next i
x = sma(3) ' simple moving average for 3 periods
x = sma(5) ' simple moving average for 5 periods
function sma(p) ' the simple moving average function
print "----- SMA:";p;" -----"
for i = 1 to 10
sumSd = 0
for j = max((i - p) + 1,1) to i
sumSd = sumSd + sd(j) ' sum series data for the period
next j
if p > i then p1 = i else p1 = p
print sd(i);" sma:";p;" ";sumSd / p1
next i
end function

View file

@ -13,10 +13,10 @@ func simple_moving_average(period) {
}
}
var ma3 = simple_moving_average(3);
var ma5 = simple_moving_average(5);
var ma3 = simple_moving_average(3)
var ma5 = simple_moving_average(5)
[1 ..^ 6, 6 ^.. 1].map{@|_} -> each {|num|
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
for num (1..5, flip(1..5)) {
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
num, ma3.call(num), ma5.call(num))
}

View file

@ -13,7 +13,7 @@ class sma_generator(period, list=[], sum=0) {
var ma3 = sma_generator(3)
var ma5 = sma_generator(5)
for num in [@|(1..5), @|(1..5 -> flip)] {
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
for num (1..5, flip(1..5)) {
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
num, ma3.SMA(num), ma5.SMA(num))
}

View file

@ -0,0 +1,8 @@
fcn SMA(P){
fcn(n,ns,P){
sz:=ns.append(n.toFloat()).len();
if(P>sz) return(0.0);
if(P<sz) ns.del(0);
ns.sum(0.0)/P;
}.fp1(List.createLong(P+1),P) // pre-allocate a list of length P+1
}

View file

@ -0,0 +1,2 @@
T(1,2,3,4,5,5,4,3,2,1).apply(SMA(3)).println();
T(1,2,3,4,5,5,4,3,2,1).apply(SMA(5)).println();