Category talk:Wren-long: Difference between revisions
Content added Content deleted
(→Source code: Added largestPrime and prevPrime methods to ULong class.) |
(→Source code: Added support for ranges of Longs and ULongs.) |
||
Line 48: | Line 48: | ||
===Source code=== |
===Source code=== |
||
<syntaxhighlight lang="ecmascript">/* Module "long.wren" */ |
<syntaxhighlight lang="ecmascript">/* Module "long.wren" */ |
||
Line 943: | Line 944: | ||
// Returns the string representation of the current instance in base 10. |
// Returns the string representation of the current instance in base 10. |
||
toString { toBaseString_(10) } |
toString { toBaseString_(10) } |
||
// Creates and returns a range of ULongs from 'this' to 'n' with a step of 1. |
|||
// 'this' and 'n' must both be 'small' integers >= 0. 'n' can be a Num, a ULong or a Long. |
|||
..(n) { ULongs.range(this, n, 1, true) } // inclusive of 'n' |
|||
...(n) { ULongs.range(this, n, 1, false) } // exclusive of 'n' |
|||
/* Prime factorization methods. */ |
/* Prime factorization methods. */ |
||
Line 1,199: | Line 1,205: | ||
} |
} |
||
/* ULongs contains various routines applicable to lists of unsigned 64-bit integers |
/* ULongs contains various routines applicable to lists of unsigned 64-bit integers |
||
and for creating and iterating though ranges of such numbers. */ |
|||
class ULongs { |
|||
class ULongs is Sequence { |
|||
static sum(a) { a.reduce(ULong.zero) { |acc, x| acc + x } } |
static sum(a) { a.reduce(ULong.zero) { |acc, x| acc + x } } |
||
static mean(a) { sum(a)/a.count } |
static mean(a) { sum(a)/a.count } |
||
Line 1,206: | Line 1,213: | ||
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
||
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
||
// Private helper method for creating ranges. |
|||
static checkValue_(v, name) { |
|||
if (v is ULong && v.isSmall) { |
|||
return v.toSmall |
|||
} else if (v is Long && v.isSmall && !v.isNegative) { |
|||
return v.toSmall |
|||
} else if (v is Num && v.isInteger && v >= 0 && v <= Num.maxSafeInteger) { |
|||
return v |
|||
} else { |
|||
Fiber.abort("Invalid value for '%(name)'.") |
|||
} |
|||
} |
|||
// Creates a range of 'small' ULongs analogous to the Range class but allowing for steps > 1. |
|||
// Use the 'ascending' parameter to check that the range's direction is as intended. |
|||
construct range(from, to, step, inclusive, ascending) { |
|||
from = ULongs.checkValue_(from, "from") |
|||
to = ULongs.checkValue_(to, "to") |
|||
step = ULongs.checkValue_(step, "step") |
|||
if (step < 1) Fiber.abort("'step' must be a positive integer.") |
|||
if (ascending && from > to) Fiber.abort("'from' cannot exceed 'to'.") |
|||
if (!ascending && from < to) Fiber.abort("'to' cannot exceed 'from'.") |
|||
_rng = inclusive ? from..to : from...to |
|||
_step = step |
|||
} |
|||
// Convenience versions of 'range' which use default values for some parameters. |
|||
static range(from, to, step, inclusive) { range(from, to, step, inclusive, from <= to) } |
|||
static range(from, to, step) { range(from, to, step, true, from <= to) } |
|||
static range(from, to) { range(from, to, 1, true, from <= to) } |
|||
// Iterator protocol methods. |
|||
iterate(iterator) { |
|||
if (!iterator || _step == 1) { |
|||
return _rng.iterate(iterator) |
|||
} else { |
|||
var count = _step |
|||
while (count > 0 && iterator) { |
|||
iterator = _rng.iterate(iterator) |
|||
count = count - 1 |
|||
} |
|||
return iterator |
|||
} |
|||
} |
|||
iteratorValue(iterate) { ULong.fromSmall_(_rng.iteratorValue(iterate)) } |
|||
} |
} |
||
Line 1,577: | Line 1,631: | ||
// Returns the string representation of the current instance in base 10. |
// Returns the string representation of the current instance in base 10. |
||
toString { toBaseString(10) } |
toString { toBaseString(10) } |
||
// Creates and returns a range of Longs from 'this' to 'n' with a step of 1. |
|||
// 'this' and 'n' must both be 'small' integers. 'n' can be a Num, a Long or a ULong. |
|||
..(n) { Longs.range(this, n, 1, true) } // inclusive of 'n' |
|||
...(n) { Longs.range(this, n, 1, false) } // exclusive of 'n' |
|||
} |
} |
||
/* Longs contains various routines applicable to lists of signed 64-bit integers |
/* Longs contains various routines applicable to lists of signed 64-bit integers |
||
and for creating and iterating though ranges of such numbers. */ |
|||
class Longs { |
|||
class Longs is Sequence { |
|||
static sum(a) { a.reduce(Long.zero) { |acc, x| acc + x } } |
static sum(a) { a.reduce(Long.zero) { |acc, x| acc + x } } |
||
static mean(a) { sum(a)/a.count } |
static mean(a) { sum(a)/a.count } |
||
Line 1,586: | Line 1,646: | ||
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
static max(a) { a.reduce { |acc, x| (x > acc) ? x : acc } } |
||
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
static min(a) { a.reduce { |acc, x| (x < acc) ? x : acc } } |
||
// Private helper method for creating ranges. |
|||
static checkValue_(v, name) { |
|||
if ((v is Long || v is ULong) && v.isSmall) { |
|||
return v.toSmall |
|||
} else if (v is Num && v.isInteger && v.abs <= Num.maxSafeInteger) { |
|||
return v |
|||
} else { |
|||
Fiber.abort("Invalid value for '%(name)'.") |
|||
} |
|||
} |
|||
// Creates a range of 'small' Longs analogous to the Range class but allowing for steps > 1. |
|||
// Use the 'ascending' parameter to check that the range's direction is as intended. |
|||
construct range(from, to, step, inclusive, ascending) { |
|||
from = Longs.checkValue_(from, "from") |
|||
to = Longs.checkValue_(to, "to") |
|||
step = Longs.checkValue_(step, "step") |
|||
if (step < 1) Fiber.abort("'step' must be a positive integer.") |
|||
if (ascending && from > to) Fiber.abort("'from' cannot exceed 'to'.") |
|||
if (!ascending && from < to) Fiber.abort("'to' cannot exceed 'from'.") |
|||
_rng = inclusive ? from..to : from...to |
|||
_step = step |
|||
} |
|||
// Convenience versions of 'range' which use default values for some parameters. |
|||
static range(from, to, step, inclusive) { range(from, to, step, inclusive, from <= to) } |
|||
static range(from, to, step) { range(from, to, step, true, from <= to) } |
|||
static range(from, to) { range(from, to, 1, true, from <= to) } |
|||
// Iterator protocol methods. |
|||
iterate(iterator) { |
|||
if (!iterator || _step == 1) { |
|||
return _rng.iterate(iterator) |
|||
} else { |
|||
var count = _step |
|||
while (count > 0 && iterator) { |
|||
iterator = _rng.iterate(iterator) |
|||
count = count - 1 |
|||
} |
|||
return iterator |
|||
} |
|||
} |
|||
iteratorValue(iterate) { Long.fromSmall_(_rng.iteratorValue(iterate)) } |
|||
}</syntaxhighlight> |
}</syntaxhighlight> |