# This script implements a circular queue and # it's relative tests! fun newCircularQueue(T: Type = int, max: int = 3) { if T == None: error("Invalid type"); if max <= 0: error("Maximum queue size must be positive"); list = []; i = 0; while i < max: { list[i] = none; i = i+1; } return { max: max, head: 0, tail: 0, list: list, type: T }; } fun getSize(queue: Map) { size = none; if queue.tail == queue.head: { if queue.list[queue.tail] == none: { size = 0; } else { size = queue.max; } } else if queue.tail < queue.head: { size = queue.head - queue.tail; } else { size = queue.head + queue.max - queue.tail; } return size; } fun append(queue: Map, value) { if type(value) != queue.type: error("Invalid type"); size = getSize(queue); queue.list[queue.head] = value; if size == queue.max: { queue.tail = queue.tail+1; if queue.tail == queue.max: queue.tail = 0; } queue.head = queue.head+1; if queue.head == queue.max: queue.head = 0; } fun pop(queue: Map) { if getSize(queue) == 0: return none; value = queue.list[queue.tail]; queue.list[queue.tail] = none; queue.tail = queue.tail+1; if queue.tail == queue.max: queue.tail = 0; return value; } { utils = import("../utils.noja"); queue = newCircularQueue(int, 3); assert(getSize(queue) == 0); assert(queue.head == 0); assert(queue.tail == 0); append(queue, 1); assert(queue.head == 1); assert(queue.tail == 0); assert(getSize(queue) == 1); assert(utils.compareAny(queue.list, [1, none, none])); append(queue, 2); assert(queue.head == 2); assert(queue.tail == 0); assert(getSize(queue) == 2); assert(utils.compareAny(queue.list, [1, 2, none])); append(queue, 3); assert(queue.head == 0); assert(queue.tail == 0); assert(getSize(queue) == 3); assert(utils.compareAny(queue.list, [1, 2, 3])); append(queue, 4); assert(queue.head == 1); assert(queue.tail == 1); assert(getSize(queue) == 3); assert(utils.compareAny(queue.list, [4, 2, 3])); v = pop(queue); assert(v == 2); assert(queue.head == 1); assert(queue.tail == 2); assert(getSize(queue) == 2); assert(utils.compareAny(queue.list, [4, none, 3])); v = pop(queue); assert(v == 3); assert(queue.head == 1); assert(queue.tail == 0); assert(getSize(queue) == 1); assert(utils.compareAny(queue.list, [4, none, none])); v = pop(queue); assert(v == 4); assert(queue.head == 1); assert(queue.tail == 1); assert(getSize(queue) == 0); assert(utils.compareAny(queue.list, [none, none, none])); v = pop(queue); assert(v == none); assert(queue.head == 1); assert(queue.tail == 1); assert(getSize(queue) == 0); assert(utils.compareAny(queue.list, [none, none, none])); }