Aug 16

Learning the Dart Structured Web Language by solving the water bucket logic problem

The Water Bucket Logic Problem

You may have seen this logic problem: You have two buckets, one holds 3 gallons of water and one holds 5 gallons of water, there is also a source of water nearby. How do you measure out exactly 4 gallons?

I was recently asked to build a program that determines the solution to the problem in the least amount of steps (fills, transfers, dumps, etc…) with any given value for bucket sizes and goal fluid amount. I’ve been meaning to learn Google’s Structured web language: “Dart” so I figured I would kill two birds with one stone and see if I could solve the problem and learn Dart in the process.

Learning Dart

Over at the official dartlang website, there is a great “Tour of the Dart Language” page that does a good job describing the highlights of the language.

The Good

Since Dart has optional static types, classes, and generics and since you can compile Dart to JavaScript, it maybe a very good language to build large JavaScript projects with in the future.

One of the nice things in Dart is classes, and they have this nice syntactic sugar for assigning constructor parameters to members:

class BucketAction {
  String action;
  int fillLevelA;
  int fillLevelB;
  BucketAction(this.action, this.fillLevelA, this.fillLevelB);

You can also create class members as “final” so they cannot be modified after initialization, when you construct a class with final members you’ll need to use the “:” (colon) notation to specify final variable initialization though the initializer list:

class Bucket {
  final int capacity;
  int fillLevel;
  String id;
  Bucket(capacity, this.id) : capacity = capacity,
                     this.fillLevel = 0;

Dart also allows for declaration of generics, which makes it easy to show how you are using an array such as a list of strings (List<String>):

List<BucketAction> bucketActions = new List<BucketAction>();

Dart includes the ability to easily query the DOM like you would through jQuery, just import the html library at the top of your code and call the query method to get the appropriate HTML DOM element:


void main() {
  CanvasElement canvas = query("#canvas");
  CanvasRenderingContext2D context = canvas.context2d;
  InputElement valueA = query("#valueA");
The Bad

Dart is not quite ready for prime time, and using it with your existing projects or other js libraries will be difficult for now since you have to port those libraries over to dart. The good news is that Google is actively developing the language and the tools and they also have plans to create a standards body once the platform has matured.

The Ugly

One thing I thought was especially cumbersome while programming in Dart is string concatenation with variables, instead of just using the “+” operator like you would in JavaScript you need to use this dollar sign/curly brace syntax for interpolation:

var st = 'Step: ${animationBucketActionStep + 1}';

Now the fun stuff: The Water Bucket Logic Problem

Just choose your parameters using the sliders and click the calculate button, the code will determine the best solution, and then draw the steps out on the canvas for you:

Source Files

GraduatedCylinder.dart – The full Dart source code, or you can download all the code including the Dart editor project files in this: GraduatedCylinder-DartProject archive.

  • JBP

    Cool App, and great info about Dart. Thanks, Matt

  • mpalmerlee

    I’ve made some changes to the code for detecting invalid parameters and uploaded the new source.