This is a solution to the
rotate-for-a-max kata.
I needed to add support for `shared array` since somehow I overlooked that before. It's not an ideal implementation yet, as it does a double allocation rather than just store the array bits directly in the shared object. There looks to be a bit of cleanup required of the basic memory management stuff -- too many functions and oddities involved.
import std
import math
defn rot_max = ( n : integer ) -> {
n < 0 then fail string_tag( "negative-not-supported" )
n == 0 then return n
var mx = n
//convert into array of digits
var maxDigits = num_decimal_digits(n)
var digits = type「shared array「integer」」(maxDigits)
var digitCount = 0
loop n > 0 ? {
digits#digitCount = mod(n, 10)
n /= 10
digitCount+=1
}
for i in std.range(digitCount, 0) {
rotate( digits, 0, i )
var s = add(digits, digitCount)
mx = max( mx, s )
}
return mx
}
defn add = ( digits : shared array「integer」, digitCount : integer ) -> {
var r : integer = 0
for i in std.incl_range(digitCount-1,0) {
r *= 10
r += digits#i
}
return r
}
defn rotate = ( digits : shared array「integer」, start : integer, end : integer ) -> {
end <= start then return
var t = digits#(end-1)
for i in std.range(end-1, start) {
digits#i = digits#(i-1)
}
digits#start = t
}
defn max = ( a, b ) -> {
return a > b ? a | b
}
defn num_decimal_digits = ( x : integer ) -> ( : integer ) {
var l = math.log10(lossy(x))
return lossy(l+1)
}
var main = -> {
dotest(38458215, 85821534);
dotest(195881031, 988103115);
dotest(896219342, 962193428);
dotest(69418307, 94183076);
dotest(257117280, 571172802);
dotest(240522578, 452782025);
dotest(561656824, 666824515);
dotest(672963486, 796348662);
dotest(48192242, 89242412);
dotest(25053359, 55392035);
dotest(785727925, 877925752);
dotest(275076894, 750768942);
dotest(507992495, 507992495);
dotest(461358517, 638517415);
dotest(563692037, 669203753);
dotest(159043701, 590437011);
dotest(896304934, 963049348);
dotest(273293210, 732932102);
dotest(451496516, 549651641);
dotest(1, 1);
dotest(16130873362142, 63873362142110);
dotest(84005278654009, 84005278654009);
dotest(51564279810300, 51564279810300);
dotest(12364484492416, 26484492416134);
dotest(63026816035764, 63026816035764);
dotest(77910393341241, 79103933412417);
dotest(88700243816673, 88700243816673);
dotest(65879065959482, 65879065959482);
dotest(88361793184682, 88361793184682);
dotest(91556298303742, 91556298303742);
}
defn dotest = ( n : integer, mx : integer ) -> {
var r = rot_max( n )
r != mx then {
std.print([ n, ": Actual(", r, ") Expect(", mx, ")\n"])
}
}