Tuesday, December 15, 2015

Scratchpad Tools

Whenever I want to test out some small C# code I use the excellent LINQPad. It's great as a quick scratchpad for everything from a couple of lines of code to a small program. You can reference your own class libraries so it's great for performance testing. I also use it a lot to transform files. The free version is nice but if you can swing it, Pro is worth it just for the auto-completion.

For JavaScript testing and debugging it's hard to beat JSFiddle. I use it often and like the ability to save and share snippets of JS. I was interested when I found .NET Fiddle online. Could it offer the same versatility of LINQPad and the online sharing of JSFiddle.

I took the code from my last blog post and pasted it in .NET Fiddle. Interestingly by default code is evaluated and run as you enter it (you can turn this option off by setting Auto Run to 'No'). The first thing that occurred was that I got this error message:

Fatal Error: Memory usage limit was exceeded

Apparently the number of iterations in my test loop was too many. Once I dialed that back to 100,000 the code ran fine. This code is pretty basic and not creating a lot of large objects so this limit seems low. Also looks like no GC is running so this limit my hinder other tests.

It does have a 'Share' link that gives you either a direct link to the fiddle or a widget that you can embed directly in a blog post. Here is the widget for this post:


Definitely a nice tool for sharing code but think I will stick with LINQPad for most of my scratchpad needs.

Monday, December 7, 2015

All Your Base Are Belong To Us

I wanted to encode a number in Base 36. A simple enough task, but as these things sometimes do, this took me down the rabbit hole of wanting to create a generic routine. I needed a set of methods, one that would take an integer and convert it to an arbitrary base and another to convert it back to a Base 10 number. There are a bunch of examples floating around the web but I wanted to create my own (combining some of the best elements from the code I found). It's a relatively easy problem to solve but along the way I found some interesting tricks to speed up the process.

So here is my C# take on this old problem:

// Chars to use in Base conversion
private const string BASE_DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
/// <summary>
/// Convert a base 10 number to a different base.
/// </summary>
/// <param name="number">Number to convert</param>
/// <param name="radix">Base to convert the number into (2-62)</param>
/// <returns>String</returns>
public static string NumberToBase(long number, int radix) {
 
  if (number == 0) return "0";
  if (radix < 2 || radix > BASE_DIGITS.Length)
    throw new ArgumentOutOfRangeException("radix", radix, "The Radix/Base must be between 2 and " + BASE_DIGITS.Length);
 
  var baseChars = BASE_DIGITS.ToCharArray();
  var charStack = new Stack<char>();
  var num = Math.Abs(number);
 
  while (num != 0) {
    charStack.Push(baseChars[num % radix]);
    num /= radix;
  }
  var result = new string(charStack.ToArray());
  return number < 0 ? "-" + result : result;
}
 
/// <summary>
/// Convert a string in a different base to a base 10 number
/// </summary>
/// <param name="number">Number to convert</param>
/// <param name="radix">Base to convert from</param>
/// <returns>Int64</returns>
public static long NumberFromBase(string number, int radix) {
  if (radix < 2 || radix > BASE_DIGITS.Length)
    throw new ArgumentOutOfRangeException("radix", radix, "The Radix/Base must be between 2 and " + BASE_DIGITS.Length);
 
  long result = 0;
  long multiplier = 1;
 
  for(var i = number.Length - 1; i >= 0; i--) {
    var c = number[i];
    // This is the negative sign symbol
    if (i == 0 && c == '-') {
      result = -result;
      break;
    }
 
    result += BASE_DIGITS.IndexOf(c) * multiplier;
    multiplier *= radix;
  }
  return result;
}

I used LINQPad to create a quick program to test it out.

void Main() {
  Random r = new Random();
  for (int i = -1000; i < 1000000; i++) {
    var basex = r.Next(2, 62);
    var encoded = NumberToBase(i, basex);
    var decoded = NumberFromBase(encoded, basex);
     
    if (i != decoded) {
      Console.WriteLine("i: {0} enc: {1} dec: {2}", i, encoded, decoded);
    }
  }
}