Archive for September, 2011

Calorie Count @ NYTM

This is already a few weeks old, but someone finally uploaded a good video of the presentation that I was a part of at the September New York Tech Meetup.

Igor showed off the awesome new voice logging feature that we recently added to the iPhone version of the app (coming soon to the Android version). Then I manned the keyboard to show off a little hack that we put together that same day. We provisioned a Twilio phone number, and let the user record a little 10 second clip of what they want to log (ie. “one banana, two cups of coffee”). We then took that clip and sent it to iSpeech who transcribed it. And finally we ran the transcribed text through our own API to log it.

Igor asked the crowd to call in the phone number, which they did, and it worked! It was a great experience, and a fun day. Many thanks to Hal Rotholz as well as he was instrumental in getting this hack up and running, in addition to monitoring the server while we were up there :-P

Comments

Conway’s Game of Life in C#

I wrote this for fun on the train a while ago, and just came across it again recently. So I figured I may as well post it. The code implements a simple game of life simulation, but the interesting bit is that it parallelizes the process using the TPL. I uploaded it to github as a gist, so please feel free to check it out, and see if you can do anything interesting with it :-)

using System;
using System.Threading.Tasks;

namespace Life
{
    public class LifeSimulation
    {
        private bool[,] world;
        private bool[,] nextGeneration;
        private Task processTask;

        public LifeSimulation(int size)
        {
            if (size < 0) throw new ArgumentOutOfRangeException("Size must be greater than zero");
            this.Size = size;
            world = new bool[size, size];
            nextGeneration = new bool[size, size];
        }

        public int Size { get; private set; }
        public int Generation { get; private set; }

        public Action<bool[,]> NextGenerationCompleted;

        public bool this[int x, int y]
        {
            get { return this.world[x, y]; }
            set { this.world[x, y] = value; }
        }

        public bool ToggleCell(int x, int y)
        {
            bool currentValue = this.world[x, y];
            return this.world[x, y] = !currentValue;
        }

        public void Update()
        {
            if (this.processTask != null && this.processTask.IsCompleted)
            {
                // when a generation has completed
                // now flip the back buffer so we can start processing on the next generation
                var flip = this.nextGeneration;
                this.nextGeneration = this.world;
                this.world = flip;
                Generation++;

                // begin the next generation's processing asynchronously
                this.processTask = this.ProcessGeneration();

                if (NextGenerationCompleted != null) NextGenerationCompleted(this.world);
            }
        }

        public void BeginGeneration()
        {
            if (this.processTask == null || (this.processTask != null && this.processTask.IsCompleted))
            {
                // only begin the generation if the previous process was completed
                this.processTask = this.ProcessGeneration();
            }
        }

        public void Wait()
        {
            if (this.processTask != null)
            {
                this.processTask.Wait();
            }
        }

        private Task ProcessGeneration()
        {
            return Task.Factory.StartNew(() =>
            {
                Parallel.For(0, Size, x =>
                {
                    Parallel.For(0, Size, y =>
                    {
                        int numberOfNeighbors = IsNeighborAlive(world, Size, x, y, -1, 0)
                            + IsNeighborAlive(world, Size, x, y, -1, 1)
                            + IsNeighborAlive(world, Size, x, y, 0, 1)
                            + IsNeighborAlive(world, Size, x, y, 1, 1)
                            + IsNeighborAlive(world, Size, x, y, 1, 0)
                            + IsNeighborAlive(world, Size, x, y, 1, -1)
                            + IsNeighborAlive(world, Size, x, y, 0, -1)
                            + IsNeighborAlive(world, Size, x, y, -1, -1);

                        bool shouldLive = false;
                        bool isAlive = world[x, y];

                        if (isAlive && (numberOfNeighbors == 2 || numberOfNeighbors == 3))
                        {
                            shouldLive = true;
                        }
                        else if (!isAlive && numberOfNeighbors == 3) // zombification
                        {
                            shouldLive = true;
                        }

                        nextGeneration[x, y] = shouldLive;

                    });
                });
            });
        }

        private static int IsNeighborAlive(bool[,] world, int size, int x, int y, int offsetx, int offsety)
        {
            int result = 0;

            int proposedOffsetX = x + offsetx;
            int proposedOffsetY = y + offsety;
            bool outOfBounds = proposedOffsetX < 0 || proposedOffsetX >= size | proposedOffsetY < 0 || proposedOffsetY >= size;
            if (!outOfBounds)
            {
                result = world[x + offsetx, y + offsety] ? 1 : 0;
            }
            return result;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            LifeSimulation sim = new LifeSimulation(10);

            // initialize with a blinker
            sim.ToggleCell(5, 5);
            sim.ToggleCell(5, 6);
            sim.ToggleCell(5, 7);

            sim.BeginGeneration();
            sim.Wait();
            OutputBoard(sim);

            sim.Update();
            sim.Wait();
            OutputBoard(sim);

            sim.Update();
            sim.Wait();
            OutputBoard(sim);

            Console.ReadKey();
        }

        private static void OutputBoard(LifeSimulation sim)
        {
            var line = new String('-', sim.Size);
            Console.WriteLine(line);

            for (int y = 0; y < sim.Size; y++)
            {
                for (int x = 0; x < sim.Size; x++)
                {
                    Console.Write(sim[x, y] ? "1" : "0");
                }

                Console.WriteLine();
            }
        }
    }
}
,
view raw GameOfLife.cs This Gist brought to you by GitHub.

The included sample program that uses the ‘LifeSimulation’ class initializes the a simple blinker, and then generates and outputs 3 generations.

Comments (1)