Showing posts with label mLite. Show all posts
Showing posts with label mLite. Show all posts

Wednesday, October 07, 2015

[FBSL] Decimal to Binary

Having solved the Binary Digits task in mLite, I thought I'd have a go in FBSL. Kudos to the FBSL team for a very useful and powerful Windows scripting language. Even ABAP users can leverage it!

The code below, expressed in v3.5 RC form, follows the mLite fairly closely.

#AppType Console
function Bin(byval n as integer, byval s as string = "") as string
 if n > 0 then return Bin(n \ 2, (n mod 2) & s)
 if s = "" then return "0"
 return s
end function

print Bin(5)
print Bin(50)
print Bin(9000)

pause
It was during the testing of this code that it dawned on me that the mLite wasn't handling the binary 0; appropriately. Thus those who notice such things will discover a subtle change in the mLite posting.

© Copyright Bruce M. Axtens, 2015

Tuesday, October 06, 2015

[mLite] Convert to Binary Notation

A short diversion: the Standard ML dialect called mLite is where I go for the intellectual challenge of thinking in a functional programming way. Kudos to Nils M. Holm for developing it. mLite is one of the languages I use to solve RosettaCode tasks, in this case, Binary Digits.

This turned out to be a fairly simple task and only took me a few minutes to solve. Granted, I reused some code from the logarithm calculator of a few postings ago, but that was just for the conversion of a list of numbers to their printable form.
fun binary
   (0, []) = "0"
 | (0, x) = implode ` map (fn x = if int x then chr (x + 48) else x) x
 | (n, b) = binary (n div 2, n mod 2 :: b)
 | n = binary (n, [])
; 
The gist of that is
  • pass in a number and recurse with the number and an empty list.
  • With a number that isn't zero recurse with the number divved by 2 and the list prepended with the number modded by 2.
  • Keep going until the number is zero. At that point, convert the answer's digits to string representation and implode them into a single string.
  • If the number is zero and there are no digits, return "0"
Might get back to some VB6 next. Or javascript.
© Copyright Bruce M. Axtens, 2015

Saturday, September 26, 2015

[mLite] Arbitrary Precision Integers and Logarithms

Yeah yeah, there's something 'bout you baby I like

-- Status Quo, 1981.

It's a bit worrisome when I quote musicians from last century, but I do like mLite. Granted, I don't dream about it, but it's fun to figure out how to do things in a functional way.

In this case I was wanting to solve the RosettaCode challenge
Arbitrary-precision integers (included) which has one calculate 5^4^3^2, find out how many digits there are and then display the top 20 digits and bottom 20 digits. Bignums weren't a challenge, as they are supported natively in mLite. No, the biggest challenge was figuring out how many digits. 5^4^3^2 is an extremely large number, with 183231 digits and all of my first attempts did not complete even after running for a day.

mLite's creator,
Nils M. Holm, suggested I use logarithms. However, logarithms aren't built in to mLite yet, so I had to cook up my own logarithm library. So how do you calculate logarithms by hand? I dug around a bit and found an article on Quora entitled How can we calculate the logarithms by hand without using any calculator?. Harald Overbeek's description formed the basis for the mLite code below.
fun ntol (0, x) = if len x < 1 then [0] else x
       | (n, x) = ntol (n div 10, (n mod 10) :: x)
       | n      = ntol (n, [])
;
ntol converts a number to a list.
fun powers_of_10 9 = 1000000000
               | 8 = 100000000
               | 7 = 10000000
               | 6 = 1000000
               | 5 = 100000
               | 4 = 10000
               | 3 = 1000
               | 2 = 100
               | 1 = 10
               | 0 = 1
;
powers_of_10 is a precomputation of all the powers I knew I'd encounter during the calculation. This alone sped up the code a lot.
fun size (c, 0) = c
       | (c, n > 9999999999) = size (c + 10, trunc (n / 10000000000))
       | (c, n)              = size (c +  1, trunc (n / 10))
       | n                   = size (     0, trunc (n / 10))
;
size works out the number of digits by keeping track of how many calculations it takes to divide the number by 10 until the remainder is zero.
fun makeVisible L = map (fn x = if int x then chr (x + 48) else x) L
makeVisible turns an array of digits into a string, with handling for non-numeric elements
fun log10 (n, 0, x) = ston  implode  makeVisible ` rev x
        | (n, decimals, x) =
            let val n' = n^10;
              val size_n' = size n'
            in 
              log10 (n' / powers_of_10 size_n', decimals - 1, size_n' :: x)
   end
        | (n, decimals) =
            let
              val size_n = size n
            in
              log10 (n / 10^size_n, decimals, #"." :: rev (ntol size_n) @ [])
            end
;
Then log10 ties it all together. The second parameter specifies the number of digits precision. Below I've specified 6.

Being somewhat mathematically challenged, I still had to figure out how to use the library I had made to calculate the digits. Thankfully, there's a
mathematics community on StackExchange. They helped me out a lot. Now I could work out the number of digits in the number by rounding up the result of log10(5) * 4^9 (seeing as 3^2 is 9).

Thus I ended up with
val fourThreeTwo = 4^3^2;
val fiveFourThreeTwo = 5^fourThreeTwo;

val digitCount = trunc (log10(5,6) * fourThreeTwo + 0.5);
print "Count  = "; println digitCount;

val end20 = fiveFourThreeTwo mod (10^20);
print "End 20 = "; println end20;

val top20 = fiveFourThreeTwo div (10^(digitCount - 20)); 
print "Top 20 = "; println top20;
Which, after 1 hour and 9 minutes on an AMD A6 cpu, gave
>mlite -f 5p4p3p2.m
 Count = 183231
 End 20 = 92256259918212890625
 Top 20 = 62060698786608744707 
A nice change from my day job which centres around JavaScript, Peloton, HTML, PHP and the odd bit of T-SQL. Enjoy!

© Copyright Bruce M. Axtens, 2015

Wednesday, October 29, 2014

[mLite] 99 bottles of beer

99 bottles of beer is often the first thing I try to do in a (new for me) programming language. Here is an mLite implementation (which can also be found now on RosettaCode.)
val NL = implode [#"newline"]

fun itone 1 = "it" 
        | n = "one"

fun plural (s, 0) = ("no " @ s @ "s") 
                    | (s, 1) = ("1 " @ s) 
                    | (s, n) = (ntos n @ " " @ s @ "s")

fun verse 0 = "no bottles of beer on the wall" @ NL @ 
              "no bottles of beer" @ NL @ 
              "go to the store and buy some more" @ NL @ 
              "99 bottles of beer on the wall" @ NL @ NL 
        | x = plural ("bottle",x) @ " of beer on the wall" @ NL @ 
              plural ("bottle",x) @ " of beer" @ NL @ 
              "take " @ (itone x) @ " down and pass it round" @ NL @ 
              plural ("bottle", (x-1)) @ " of beer on the wall" @ NL @ NL

fun bottles x = map (print o verse) (rev (0 :: iota (1, x)))

fun default (false, y) = y | (x, _) = x

;
bottles (ston (default (argv 0, "99")))
This code allows one to specify how many bottles on the command line (e.g.
mlite -f 99bob.m 4
), defaulting to the usual 99.

© Copyright Bruce M. Axtens, 2014

Tuesday, October 28, 2014

[mLite] Learning an ML dialect

I've tried to get my head into functional languages for some time. This time I'm having a go at mLite, which the author, Nils M Holm, describes as "a lightweight (and slightly odd) inhabitant of the ML universe ... Much like ML, but with dynamic typingguards, and a Haskell-style apply operator."

I've created a presence on RosettaCode for mLite and solved the Ackermann function challenge.

© Bruce M. Axtens, 2014.