Category talk:Wren-long: Difference between revisions

m
→‎Source code: Now uses Wren S/H lexer.
(→‎Source code: Removed some redundant lines.)
m (→‎Source code: Now uses Wren S/H lexer.)
 
(4 intermediate revisions by the same user not shown)
Line 48:
 
===Source code===
 
<syntaxhighlight lang="ecmascript">/* Module "long.wren" */
<syntaxhighlight lang="wren">/* Module "long.wren" */
 
import "./trait" for Comparable
Line 78 ⟶ 79:
// Returns the largest ULong = 2^64-1 = 18446744073709551615
static largest { lohi_(4294967295, 4294967295) }
 
// Returns the largest prime less than 2^64.
static largestPrime { ULong.new("18446744073709551557") }
 
// Returns the smallest ULong = 0
Line 486 ⟶ 490:
if (n.isPrime) return n
n = n + ULong.two
}
}
 
// Returns the previous prime number less than the current instance or null if there isn't one.
prevPrime {
if (this < ULong.three) return null
if (this == ULong.three) return ULong.two
var n = isEven ? this - ULong.one : this - ULong.two
while (true) {
if (n.isPrime) return n
n = n - ULong.two
}
}
Line 929 ⟶ 944:
// Returns the string representation of the current instance in base 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'
 
// Return a list of the current instance's base 10 digits
digits { toString.map { |d| Num.fromString(d) }.toList }
 
// Returns the sum of the current instance's base 10 digits.
digitSum {
var sum = 0
for (d in toString.bytes) sum = sum + d - 48
return sum
}
 
/* Prime factorization methods. */
Line 1,185 ⟶ 1,215:
}
 
/* 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 mean(a) { sum(a)/a.count }
Line 1,192 ⟶ 1,223:
static max(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) }
 
// Self-explanatory read only properties.
from { _rng.from }
to { _rng.to }
step { _step }
min { from.min(to) }
max { from.max(to) }
isInclusive { _rng.isInclusive }
isAscending { 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,563 ⟶ 1,650:
// Returns the string representation of the current instance in base 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. */
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 mean(a) { sum(a)/a.count }
Line 1,572 ⟶ 1,665:
static max(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) }
 
// Self-explanatory read only properties.
from { _rng.from }
to { _rng.to }
step { _step }
min { from.min(to) }
max { from.max(to) }
isInclusive { _rng.isInclusive }
isAscending { 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>
9,476

edits