ActionScript Puzzlers

Joshua Bloch is well known for his work on several Java APIs and the excellent book Effective Java. He is also co-author of Java Puzzlers, a catalogue of the less well traveled quirks and corner cases of the language. This is invaluable reading for enthusiastic Java specification pedants, and sadistic job interviewers. If you are not caught out by at least a handful of these puzzlers, you no doubt design JVMs in your spare time.

In homage to this book, I’ve collected a small collection of oddities specific to Actionscript 3 (AS3). ActionScript has its roots in ECMAScript, but moved away from prototypal inheritance with AS3 favouring strong typing and class-based inheritance. I have the good fortune of being able to draw on three sources for my collection of puzzlers:

  1. JavaScript – There is no shortage of verbiage on the interwebs on the shortcomings of JavaScript. With its shared roots, ActionScript inherits both the good and also some, but not all, of the bad parts.
  2. Java – A number of the Java Puzzlers are directly applicable to AS3. Rather than repeating these here, I’ve listed the puzzlers that also apply to AS3 and suggest you get the book and try them out yourself, if you’re interested (see footnote).
  3. ActionScript – A few puzzlers exist due to features unique to ActionScript.

Without further ado, let’s get to the puzzlers.

Puzzle 1: Looping

What does a call to loopy() return?

private function loopy() : String {
  var names : Array = [ null, "bee", "bop", null, "boo" ];
  var result : Array = [];

  for each (var name : String in names) {
    var caps : String;

    if (name != null) {
      caps = name.toUpperCase();
    }
    if (caps != null) {
      result.push(caps);
    }
  }
  return result.join(',');
}

Puzzle 2: Sorted

What does a call to sorted() return?

private function sorted() : String {
	var values : Array = [ 22, 33, 71, 1, 4, -5, -22, 1 ];
	var sorted : Array = values.sort();
	return arrayToString( sorted );
}

public static function arrayToString( a : Array ) : String {
	return StringUtil.substitute(
		"[ {0} ] (length={1})",
		a.join(', '), a.length);
}

Puzzle 3: Delimiters

What does a call to delimiters() return?

private function delimiters() : String {
	var result : String = "";
	result += arrayToString( [ 1, 2, 3 ] ) + '\n';
	result += arrayToString( [ 1, 2, 3, ] ) + '\n';
	result += arrayToString( [ 1, 2, 3, , ] ) + '\n';
	result += arrayToString( [ , 1, 2, 3, ] ) + '\n';
	result += arrayToString( [ , ,1, 2, 3, , ] ) + '\n';
	return result;
}

public static function arrayToString( a : Array ) : String {
	return StringUtil.substitute(
		"[ {0} ] (length={1})",
		a.join(', '), a.length);
}

Puzzle 4: Indecisive

What does a call to responseOrError(indecisive) return?

private function responseOrError( myFunction : Function ) : String {
	var response : String;
	try {
		response = myFunction();
	} catch ( e : Error ) {
		response = e.message;
	}
	return response;
}

private function indecisive() : String {
	try {
		throw new Error("try wins");
	} catch (e : Error ) {
		throw new Error("catch wins");
	} finally {
		return "finally wins";
	}
}

Puzzle 5: Illusive dates

What does a call to dates() return?

private function dates() : String {
	var formatter : DateFormatter = new DateFormatter();
	formatter.formatString = "YYYY MM DD";

	var date : Date = new Date(2009, 7, 31);
	var result : String = "start=" + formatter.format(date);

	date.fullYear = 2010;
	date.month = 1;
	date.date = 15;
	result += " finish=" + formatter.format(date);

	return result;
}

Puzzle 6: Sparsity

What does a call to sparse() return?

private function sparse() : String {
	var values : Array = [ 1, 2 ];
	var valuesAC : ArrayCollection;
	var valuesVector : Vector.<int>;
	var count : int = 0;
	var value : int;
	var result : String = '';
	values[ 100 ] = 3;
	for each (value in values) {
		count++;
	}
	result = StringUtil.substitute("Array: length={0} count={1} ",
		values.length, count );

	valuesVector = Vector.<int>(values);
	count = 0;
	for each (value in valuesVector) {
		count++;
	}
	result += StringUtil.substitute("Vector: length={0} count={1} ",
		valuesVector.length, count );

	valuesAC = new ArrayCollection(values);
	count = 0;
	for each (value in valuesAC) {
		count++;
	}
	result += StringUtil.substitute("ArrayCollection: length={0} count={1}",
		valuesAC.length, count );

	return result;
}

Puzzle 7: Mixed up

What does a call to mixedUp() return?

private function objectLiteral() : * {
	return
	{
		a : 123
		b : "888"
	};
}

private function mixedUp() : String {
	var lit : * = objectLiteral();
	return lit.a + lit.b;
}

Puzzle 8: Unicoder

What does a call to escaped() return?

private function escaped() : int {
	return "a\u0022.length + \u0022b".length;
}

Puzzle 9: Constantly confused

Demonstrate a const having two different values within the same function call.

Puzzle 10: Extended Array

The Array class includes a number of methods that encourage functional style programming. For instance, the following line takes a list of tweets, filters down to those created today, extracts the body them adds these to a blotter.

allTweets.filter(createdToday).map(body).forEach(appendToBlotter);

This syntax is very readable, avoids out-by-one errors and encourages you to break up your code into short well defined methods. Since Array is a dynamic class, you can extend it to add your own methods, however this would limit its usefulness since it would only work on instances of your subclass, and not regular Arrays. Although prototypal inheritance is generally discouraged, it comes in very handy in this circumstance. By adding methods to the Array prototype, they will become available to all Array instances.

Here’s an example of using prototype inheritance on the Array class. What does a call to arrayMax()return?

private function arrayMax() : String {
	Array.prototype.max = function() : Number {
		var array : Array = this;
		var result : Number = Number.MIN_VALUE;
		for each ( var item : Number in array ) {
			result = Math.max( result, item );
		}
		return result;
	};

	var numbers : Array = [1, 2, 10];
	return StringUtil.substitute('len={0} max={1}',
		numbers.length, numbers.max());
}

Answers are now available here.

Java Puzzlers that apply to ActionScript

  • Puzzle 1: Oddity
  • Puzzle 2: Time for a Change
  • Puzzle 7: Swap Meat
  • Puzzle 13: Animal Farm (if you substitute === for ==)
  • Puzzle 22: Dupe of URL
  • Puzzle 25: Inclement Increment
  • Puzzle 26: In the loop
  • Puzzle 27: Shifty i’s
  • Puzzle 28: Looper
  • Puzzle 29: Bride of Looper
  • Puzzle 30: Son of Looper
  • Puzzle 36: Indecision
  • Puzzle 40: The Reluctant Constructor
Advertisement

One thought on “ActionScript Puzzlers

  1. Pingback: ActionScript Puzzlers Answers « Technical Tidbits

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s