Skip to content

Digital Companions – The Meaning Of Lionhead’s Milo Project

I recently posted an exploration of the elements of the infamous Milo demo from E3. That post primarily focused on what took place in the demo, and if all was as it was represented to be.

But let’s assume for a moment everything in the Milo demo was “real”, that it all was what it seemed to be. What’s the purpose of Milo? What’s the goal? What’s Milo meant to be?

Milo would seem to be a digital companion, a software entity that’s intended to interact, learn, and grow with the user. The software has the avatar of a human boy, which helps considerably in building the bond with the user. And the software itself seems to learn about its users and learns to interpret their moods and emotions.

Milo also seems designed to trigger nuturing responses in the user. Molyneux, Milo’s designer, has said that Milo simply won’t respond to abuse. If Milo only responds to positive behavior, will that encourage users to be positive and nuturing with him? Will it change the users? Bits such as the exchange about completing homework seem to indicate that’s the case. And don’t forget the whole drawing a fish bit is also related to helping Milo with his homework. You can easily see how this trick could be used to get kids to do their own projects, or to motivate adults with theirs (Milo: “I just can’t seem to get this pivot table right in this spreadsheet. How will I ever calculate EBITDA?”).

But beyond simple motivational tools, what can move software like Milo to be more than the latest digital pet and to something more like an actual companion? It’s not hard to imagine a next step of other special-purpose Milos, designed properly with enough affective computing tricks to address issues like social anxiety or mood issues.

The ultimate Milo, though, would be adaptive, reacting to all sorts of general-purpose needs of the users. A true digital companion would learn and grow with its users, reacting in many ways as a real-life friend would. The general outlines of such a design don’t seem too complicated. The devil, as always, will be in the details.

There are issues with this, of course. There’s potential of misuse, both by the users and by the developers. Imagine a cult leader companion, for example, preying on weaknesses and convincing users to send money somewhere (don’t think it won’t happen!). Or a companion that encouraged anti-social behavior, or one that demanded all the users time. Or even just a badly designed companion with harmful bugs.

There’s also the issue of people interacting more and more with software instead of actual people. Is that a good thing for society? Personally, I think that aspect is a bit of a moot point, since it seems inevitable. It seems to me the correct approach is to shape the interactions so that they are socially beneficial.

This can all seem pretty pie in the sky, but when you consider what exists today and what can be done with some basic tricks that obviate the need for genuine AI, it’s probably only a few years until these start to become practical questions. I’m somewhat surprised we aren’t already seeing some more sophisticated Facebook and Twitter bots playing the affective/emotional games.

Of course, it’s things like Milo’s eye contact and his vocal cues that really make the difference. Humans are simple animals on a basic emotional level, and once these basic computing interface tricks become widespread, we’re in for a whole new future.

What Excites Me About Augmented Reality

We’ve been living with a sort of Augmented Reality for a while now. But the next generation of AR, with always-on, real-time information will be a transformative technology.

The most common conceptions of AR applications thus far seem to be about data presentation. This makes sense as it’s a domain with clear value and with relatively clear implementation paths. There’s a good deal of sifting to do to find the data people want, but the how of the process is relatively straight-forward. We’ll see a lot of applications along these lines, and some may well change lives for the better.

There’s a subset of the data presentation applications that will be of particular interest, those that show and encourage social connections. Identifying who’s who and their relationships to each other has both commercial and societal value. There will be legal and ethical issues here, but demand will be high enough to make it worth working through them. Existing social networks should lead the way, if they have enough vision.

There’s also the gaming domain, and I have no doubt the game developers will charge head on into AR as quickly as they can. Transforming people’s environments into gaming arenas will have an irresistible appeal for many. There’s much promise in this area, and a great deal of fun to be had.

But what’s the flip side of that equation? It’s turning people’s games into their environments. And why stop there? Why not turn movies into people’s environments? Why not storytelling in general?

What if the characters of the story lived where you lived? If they experienced the things you experienced? How much more charged could the emotions of the story become? How much more tightly bound to the characters would you become?

One of the main purposes of creative projects is to alter the way people experience the world. What better way to do that than to alter the way people experience the world? Clever AR storytelling could shape experiences and places in ways that transformed the experiencer. New ways of seeing, new ways of knowing, new ways of being.

It’s a long road from here to there, but I do believe in the end it will be the artists who make the biggest impact with Augmented Reality tools. It’s really just a matter of time.

Project Euler, Problem 7, in Erlang

Ah, Problem 7, the one we knew was coming.

“What is the 10001st prime number?”

The basics are simple enough. Brute force a primality test via trial division and use the test to find 10001 prime number. So I did that, got the answer.

But it took 2:24 on my netbook, and the rule of Project Euler is that it should take less than 1:00.

So it was time to optimize! I started with the simplest optimization, limiting the upper bound of the trial division in the square root of the number being tested. If you’ve made it that far without finding a factor, you’re not going to (other than the number itself, of course), so it’s prime.

Once I added that, the time dropped to under 4 seconds, which surprised me. I didn’t expect that dramatic a drop from such a basic optimization. Lesson learned there. Sometimes it’s worth just a little more effort to make things much, much faster.

It’s also worth noting, however, that there a number of other simple optimizations I’m not adding in since I’m already well under the goal. :-)

Called by “euler7:nthprime(10001,2)” I’m seeding it with the first prime there. In most of these I could eliminate one of my seed parameters by having alternate versions of the functions for the base case, but I do it this way to simplify the code itself.

Prime Grade A Code-

 -module(euler7).
 -import(math).
 -export([nthprime/2]).

nthprime(N,Prevprime) ->
   if N >= 2 ->
        NthPrime = findprime(Prevprime+1),
        nthprime(N-1,NthPrime);
   true ->
       Prevprime
   end.     

findprime(Start) ->
   Max = math:sqrt(Start),
   Prime = isprime(Start,2,Max),
   if Prime == true ->
      Start;
   true ->
          findprime(Start+1)
   end.

isprime(N,PFactor,Max)->
   if PFactor =< Max ->
          if  N rem PFactor == 0 ->
              false;
          true ->
              isprime(N,PFactor+1,Max)
          end;
    true ->
          true
    end.

Project Euler, Problem 6, in Erlang

Problem 6 was surprisingly straight-forward.

“Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.”

Really, just a straight-forward calculation, easily implemented in Erlang recursive-speak. No real comments on this one.

-module(euler6).
 -export([difference/1]).

 difference(N) ->
    SumSquare = sumofsquares(0,N),
    Sum = squareofsum(0,N),
    SquareSum = Sum * Sum,
    io:format("Square ~w Sum ~w ~n", [SquareSum, SumSquare]),
    Difference = SquareSum - SumSquare,
    Difference.  

sumofsquares(Sum,N) ->
    if N >= 1 ->
       NewSum = (N*N) + sumofsquares(Sum,N-1);
    true ->
       NewSum = Sum
    end,
    NewSum.

squareofsum(Sum, N) ->
     if N >= 1 ->
       NewSum =  N + squareofsum(Sum, N-1);
     true ->
       NewSum = 0
      end,
     NewSum.

Project Euler, Problem 4, in Erlang

Problem 4 is an interesting one. “A palindromic number reads the same both ways. Find the largest palindrome made from the product of two 3-digit numbers.”

I thought about this for a few minutes and decided the best way to approach it would be to build candidate palindromic numbers and and then test them to see if they were the product of two 3 digit numbers.

It’s easy to see that the product of two 3 digit numbers could at most be 6 digits, so I decided that I would start building my candidate palindromes by counting down from 999 and adding the mirror of the number as a suffix. Example – take 998 and add 899 to the end for 998899. Then I would test each candidate by dividing by all possible three digit numbers and seeing if I could find a three digit cofactor for any even divisions. For example, if a candidate was evenly divisible by 123, was the cofactor also a three digit number?

So this problem was mostly centered in the approach. Once I’d settled on that, the Erlang code came easily. A little more work than I’d like building the palindromes due to single assignment, but nothing too bad. I can see how single assignment will be a pain in some situations though.

The code – - edoc ehT

 -module(euler4).
 -import(lists).
 -export([greatestpalindrome/1]).

 greatestpalindrome(N) ->
     Greatest = palindrome(N),
     io:format("Greatest is ~w", [Greatest]).

 palindrome(N) ->
    if N >= 100 ->
      Candidate = buildpalindrome(N),
      Success = testpalindrome(Candidate,999),
      if Success == true ->
         Candidate;
      true ->
         palindrome(N-1)
      end;
    true ->
      io:format("no match found~n")
    end.  

 buildpalindrome(N) ->
    Nstring = integer_to_list(N),
    ReverseN = lists:reverse(Nstring),
    Palindrome = Nstring ++ ReverseN,
    Npalindrome = list_to_integer(Palindrome),
    Npalindrome.

testpalindrome(N,Testfactor) ->
    if Testfactor >= 100 ->
       if N rem Testfactor == 0 ->
          Cofactor = round(N / Testfactor),
            if Cofactor >= 100, Cofactor =< 999 ->
                true;
            true ->
                false
            end;
       true ->
            testpalindrome(N,Testfactor - 1)
       end;
     true ->
       false
    end.

Project Euler, Problem 5, in dirty dirty Erlang

I did complete Problem 4 already, but the write up will take a bit of time. So I went ahead and did Problem 5, in a very quick and dirty way.

Problem 5 – “What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?”

The total elapsed time from reading the problem to having the answer was less than 10 minutes. The first instinct is to just brute force the thing, and that’s what I did.

I did make some small optimizations, things that occurred to me in the couple of minutes I spent thinking about it.

1 – There’s no point in testing divisibility by numbers 1-10, since anything that’s divisible by 11-20 will of necessity by divisible by 1-10. (ie each of the numbers 1-10 are factors of at least one of the numbers 11-20).

2- There’s no point in testing divisibility by 20, since we’re starting with 20 and incrementing by 20. All candidates will be divisible by 20.

I have no doubt that this can be optimized considerably. It takes 22 seconds to complete on my netbook, an eternity! But this code makes me laugh, so here it is.

Called by euler5:lowest(20).

Brutish code -

 -module(euler5).
 -export([lowest/1]).

  lowest(N) ->
     if
	N rem 19 == 0,
 	N rem 18 == 0,
 	N rem 17 == 0,
 	N rem 16 == 0,
 	N rem 15 == 0,
 	N rem 14 == 0,
 	N rem 13 == 0,
 	N rem 12 == 0,
 	N rem 11 == 0 ->
              N;
      true ->
          lowest(N+20)
      end.

Project Euler, Problem 3, in Erlang

When I first read Problem 3 I thought it was going to be more involved than it turned out to be.

“What is the largest prime factor of the number 600851475143 ?”

And I started thinking I’ll need to list the factors and test them for primality, or find primes first and test only those for being factors, etc.

But after thinking about how to actually factor the number, I remembered factor trees and how they’d lead me to prime factors by default. And as an added bonus, factor trees are inherently recursive! This wasn’t going to be so bad after all.

For some reason I got hooked on the idea that I needed to build a list of the factors, and then at the end I would find the largest of them. Eventually I realized I just needed to track the largest so far; I think I just wanted to fiddle with lists in Erlang.

The Erlang came pretty easy to me this time. I’m adjusting to the structures imposed by Single Assignment, which was conceptually a challenge at first. The idea of immutable variables just seemed so wrong! But I’ve read more and understand why that’s the case and I’m getting a feel for how to deal with them.

The only real Erlang catch came from the line that finds the co-factor of the most recently found factor – “Cofactor = round(N / Factor)”. You’ll notice the “round” function there. The division returned a floating point number, when what I wanted was an integer. Casting variable types turns out to be a bit clunky in Erlang, mostly done by BIFs (Built In Functions) with unwieldy names like “integer_to_list” and so on. But there is no “float_to_integer” BIF! So it had to be the “round()” function. While fine in this case, I’m not sure this will always do what I need it to do.

A couple of other notes- This isn’t very optimized, I’m intentionally not optimizing in this initial pass. I do plan to revisit and refactor down the road, once I have a better idea what I’m doing. I did sneak in an optimization in the factor search, limiting the upper end to the square root of the number we’re looking for factors of. That’s a very simple trick which does save some iterations (if you haven’t found a factor by the time you reach the square root of a number, you’re not going to). I could have further limited the search range by limiting the lower end to being equal to or greater than the previously found factors, but that would add parameters to the functions so I skipped it for now.

One last thing, the program doesn’t seem to work properly on very large numbers (giving me a factor of “2″ on numbers that aren’t even, for example), I’m not sure why. Probably some sort of overflow condition.

My code of codes-

 -module(euler3).
  -import(math).
  -export([greatestprimefactor/1]).

  greatestprimefactor(N) ->
     Greatest = factor(1,N),
     io:format("GPF is ~w~n", [Greatest]).

  factor(Greatestsofar,N) ->
    Max=math:sqrt(N),
    Factor = nextfactor(Max,2,N),
    if
      Factor > Greatestsofar ->
            Newgreatest = Factor;
      true ->
            Newgreatest = Greatestsofar
    end,
    Cofactor = round(N / Factor),
    io:format("Factor ~w~n",[Factor]),
    if
      Cofactor == 1 ->
           Newgreatest;
      true->
           factor(Newgreatest,Cofactor)
    end.

 nextfactor(Max,X,N)->
      if
       N rem X == 0 ->
 	    X;
       X =< Max ->
            nextfactor(Max,X+1,N);
       true ->
            N
       end.

Project Euler in Erlang, Problem 2

Problem 2 is again stated simply- “Find the sum of all the even-valued terms in the (Fibonacci) sequence which do not exceed four million.”

The Fibonacci Sequence is the sequence which runs 1, 2, 3, 5, 8, 13, 21 etc. in which each term is the sum of the previous two terms.

Again, conceptually easy. Just run the terms until one exceeds 4,000,000 and sum those which are divisible by 2.

In a procedural language, this is another problem that I can solve as fast as I can type. It’s very straight-forward in approach.

But I’ve quickly learned that recursion is the default thought-process for the functional language Erlang, so I immediately set about trying to think of the problem recursively. I admit to heading down a couple of dead end paths at first, really just approaching it from the wrong end. I kept worrying about building the terms when what I really wanted to do was focus on accumulating the sum. Once I realized that, everything fell into place quickly. The end result is a little messy, having to call the function with seed values – sumofevenfib(1,1,0) and having the cutoff value of 4,000,000 hardcoded. But it works.

Only a couple of problems into the euler series, but I’m getting the effects I wanted. Spending a lot more time studying up on Erlang, reading about why it’s designed the way it is, and understanding what the syntax is really saying and so on. Also learning to move from the procedural-by-reflex mindset I’ve developed over years and years of coding to a more functional approach. There’s definitely a switch I need to flip over in my head about that kind of thing.

Le code -


-module(euler2).
-export([sumofevenfib/3]).

sumofevenfib(Prev,Cur,Sum) ->
   Next = Prev + Cur,
   if
      Next =< 4000000 ->
       if
         Next rem 2 == 0 ->
           sumofevenfib(Cur,Next,Sum+Next);
         true ->
           sumofevenfib(Cur,Next,Sum)
       end;
      true -> Sum
    end.

Project Euler, Problem 1

Getting started with my quest via my first attempt at a solution in Erlang to Project Euler’s problem number 1.

The problem itself is simply stated : “Find the sum of all the multiples of 3 or 5 below 1000.”

A naive algorithm is immediately apparent- cycle through each number between below 1000 and sum those that are evenly divisible by 5 or 3. While hardly sophisticated or efficient, it’s an algorithm that will work.

In thinking about how to do this in a functional language like Erlang, it seems the obvious approach is recursion. A function that takes a number N as an input and calls itself for N-1, adding N to the result of the recursive call if N is evenly divisible by 3 or 5. I also decided to make the determination if N was a 3 or 5 multiple its own function.

So conceptually, the answer and the approach came pretty quickly. I stumbled a bit on implementation mostly due to not understanding Erlang’s if-statement at all. Once I sussed out the oddities there (including not being able to call a function in a guard expression- this puzzles me, but I also get the feeling that understanding why this is true is important to my grokking Erlang. I must explore further), the functions fell into place and I had a tiny understanding of how to start thinking about this sort of thing.

It’s been too long for me. Tiny little baby steps needed. I could have written this in a C-like language as fast as I can type. This took a bit longer. :-)

My magnificent code for Problem 1.

-module(euler1).
-export([sumof3and5multiples/1]).

sumof3and5multiples(0)->
	0;
sumof3and5multiples(N) ->
	Multiple = ismultipleof3or5(N),
	if
          Multiple == true ->
	    N + sumof3and5multiples(N-1);
          true ->
	    sumof3and5multiples(N-1)
	end.   	

ismultipleof3or5(X) ->
	if
	   X rem 3 == 0 ->
	     true;
	   X rem 5 == 0 ->
	     true;
	   true ->
	     false
	end.

Learning Erlang Via Euler

I’ve been doodling with Erlang of late, attempting to make up for what I missed by not diving into functional programming long ago. I’ve slacked off in my progress, lacking any coherent project to apply it to.

But in the last few days I stumbled across Project Euler, a site that presents a number of mathematical problems of increasing difficulty. It’s meant to serve as a structure for learning more about certain computer science and math concepts, which, oddly enough, is something I’m looking to do. It’s also a nice structure to learn to start applying some functional programming concepts. So I’ll have a series of posts about my approaches and solutions to the various problems, starting with problem 1.

Hey, everyone needs a hobby!