Lambda Functions
One day, a friend of mine called me up asking for help with his CS assignment. It was about lambda functions in scheme. Lambda functions had always been something confusing both in theory and practice for me. Why do you need them? Before I explain what they are, I'll start with a simple probably justifying why they are.
All code in this post is going to be in python, but most of it can be applied to other high level languages. I've only used lambda functions in python and scheme, but I'm sure the functionality exists in many, many other languages.
Sorting
Sorting in python is very straight forward. If I have a list of strings in python and want to sort them, I do this:
1 2 3 4 | a = ["banana","apple","pear","elephant","zebra","mango"] a.sort() print a # OUT: ['apple', 'banana', 'elephant', 'mango', 'pear', 'zebra'] |
But what happens when you try to sort a list of words containing capital letters?
1 2 3 4 | a = ["pear","Police","apple","Airplane","banana","Bear"] a.sort() print a # OUT: ['Airplane', 'Bear', 'Police', 'apple', 'banana', 'pear'] |
The sorting is done purely based on the byte values of the characters. Since 'P' (ASCII 80) < 'a' (ASCII 97), "Police" is placed before "apple" in the list of words. Normally when you're trying to sort a list of words, you want to do it alphabetically. So how do you fix this? You make a comparator function. Here's python's definition of the sort function.
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*; cmp(x, y) -> -1, 0, 1
For those of you who have used qsort in the standard C library, this isn't such an arcane concept. In python however, it is much easier (no void* madness).
1 2 3 4 5 6 7 | def alphacmp(x,y): return cmp(x.lower(),y.lower()) a = ["pear","Police","apple","Airplane","banana","Bear"] a.sort(alphacmp) print a # OUT: ['Airplane', 'apple', 'banana', 'Bear', 'pear', 'Police'] |
Okay, great! We now have our list sorted in the intuitive way. The lower() function will ensure that the lowercase version of the strings are being compared, removing the issues of the byte comparisons. But this code seems a little longer than it could be. Normally, you wouldn't create a function for task you do only once if it was just as readable within the code body. But the sort function needs a comparator function. So how can you give sort a comparator function without having to actually declare a function? The answer is lambda functions.
Lambda Functions
Lambda functions are anonymous functions. What does that mean? They're functions without a declared name. Let's look at an example so you can see what I mean. In the above example, we can sort alphabetically without defining the alphacmp function like so:
1 2 3 4 | a = ["pear","Police","apple","Airplane","banana","Bear"] a.sort(lambda x,y: cmp(x.lower(),y.lower())) print a # OUT: ['Airplane', 'apple', 'banana', 'Bear', 'pear', 'Police'] |
So what does lambda x,y: cmp(x.lower(),y.lower()) mean? "lambda" says that the statements following define an anonymous function. "x,y:" defines the parameter list accepted by the anonymous function. "cmp(x.lower(),y.lower())" defines the return value for the lambda function. If you're still a little bit confused, read on for many many more examples. At some point, it will likely click and you'll see how valuable lambda really is.
Another sorting example: what if I want to sort by length of the strings instead of alphabetically? Easily done with lambda.
1 2 3 4 | a = ["pencil","pen","cap","zebra","Blizzard","0xB4DC0DE","!"] a.sort(lambda x,y: len(x) - len(y)) print a # OUT: ['!', 'pen', 'cap', 'zebra', 'pencil', 'Blizzard', '0xB4DC0DE'] |
The use of lambda functions makes the use of many higher level functions much nicer. I'll be outlining a few of them here.
map
map(function, sequence[, sequence, ...]) -> list Return a list of the results of applying the function to the items of the argument sequence(s). If more than one sequence is given, the function is called with an argument list consisting of the corresponding item of each sequence, substituting None for missing values when not all sequences have the same length. If the function is None, return a list of the items of the sequence (or a list of tuples if more than one sequence).
More or less, what map does is apply a function on every element of an array then return an array of the corresponding return values.
A very simple use for map would be making every word in a list upper case.
1 2 3 4 | a = ["abc","cattle","not even if there's a FIRE","Jeymi!?"] b = map(lambda x: x.upper(),a) print b # OUT: ['ABC', 'CATTLE', "NOT EVEN IF THERE'S A FIRE", 'JEYMI!?'] |
A more useful example involves printing out grids. Say I have a matrix of numbers, represented as a list of lists in python. The default output formatting for this in python is extremely difficult to look at.
1 2 3 4 5 6 7 | a = [ [1,212,-13], [41,5,614], [7,8,91] ] print a # OUT: [[1, 212, -13], [41, 5, 614], [7, 8, 91]] |
What would be better is to output one row per line.
1 2 3 4 5 6 7 8 9 10 | a = [ [1,212,-13], [41,5,614], [7,8,91] ] print "\n".join(map(lambda x: str(x), a)) #OUT: # [1, 212, -13] # [41, 5, 614] # [7, 8, 91] |
The join function concatenates a list of string, separating the elements with the separator character - in this case: "\n"
Much better! But what would be even better would be to print out the numbers in columns that line up nicely too.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | a = [ [1,212,-13], [41,5,614], [7,8,91] ] print "\n".join( map( lambda row: " ".join(map( lambda y: "%4d" % y, row )), a ) ) # OUT: # 1 212 -13 # 41 5 614 # 7 8 91 |
"%4d" % y is applying the formatting string %4d to y, much the same way that printf in C and php do
Now, using a lambda function inside of a lambda function is less than readable, so I'll write out what this function does first without the maps and lambdas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | a = [ [1,212,-13], [41,5,614], [7,8,91] ] def rowformat(row): formatted_cells = [] for element in row: formatted_cells.append("%4d" % element) return " ".join(formatted_cells) formatted_rows = [] for row in a: formatted_rows.append(rowformat(row)) print "\n".join(formatted_rows) # OUT: # 1 212 -13 # 41 5 614 # 7 8 91 |
In this case, "rowformat(row)" plays the exact same roles as "lambda row:".
filter
filter(function or None, sequence) -> list, tuple, or string Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list.
The filter function does just what it's name suggests: filters out items that don't meet certain requirements. Specifically, any element which does not evaluate to true when passed to the provided function will be discarded. Note that this is not in place - it returns the filtered list.
Example: remove all odd numbers from a list of numbers
1 2 3 4 | a = [1,2,5,0,-15,100,1400,-1337,135] a = filter(lambda x: x % 2 == 0, a) print a #OUT: [2, 0, 100, 1400] |
Example: remove all vowels from a string
1 2 3 4 | a = "Hello there! My name is Jamie, not to be confused with Jeymi." a = "".join(filter(lambda x: "aeiou".find(x) == -1, list(a))) print a # OUT: Hll thr! My nm s Jm, nt t b cnfsd wth Jym. |
Example: build a list of all prime numbers between 0 and 100 inclusive
1 2 3 4 5 6 7 8 9 10 11 12 13 | # NOTE: This prime test is inefficient - used for readability) def isprime(x): if (x < 2): return False for i in range(2,x): if (x % i == 0): return False return True print filter(isprime,range(101)) # OUT (placed on multiple lines for readability) # [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, # 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] |
reduce
reduce(function, sequence[, initial]) -> value Apply a function of two arguments cumulatively to the items of a sequence, from left to right, so as to reduce the sequence to a single value. For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates ((((1+2)+3)+4)+5). If initial is present, it is placed before the items of the sequence in the calculation, and serves as a default when the sequence is empty.
Example: Calculate 30 factorial without using local variables
1 2 3 | # Note that range(2,n) -> [2,3,...,n-1] print reduce(lambda x,y: x*y, range(2,31)) # OUT: 265252859812191058636308480000000 |
Example: Find the longest word in a list of words
1 2 3 | a = ["pencil","pen","cap","zebra","Blizzard","0xB4DC0DE","!"] print reduce(lambda x,y: y if len(y) > len(x) else x, a) # OUT: 0xB4DC0DE |
And that's all for now. If you're in SE 2014 reading this and don't think you need to know how to use lambda functions - have fun with scheme.
Game of Life
For my latest project, I'm implementing Conway's Game of Life in python into animated GIFs.
Before I even explain what Conway's Game of Life is, be amused by the below, generated animation:

As always, the code I'm using here is open source: Game Of Life @ Github. In addition to the source code, there's also a few animation demos such as the one above.
Conway's Game of Life is a cellular automaton following very simple rules, as outlined in the Wikipedia article.It is a zero player game played on a 2 dimensional grid of squares, each holding either a state of dead or alive. The state of any cell is dependent on the state of the 8 cells neighbouring it in the previous generation. There are only 4 rules.
From the Wikipedia article Conway's Game of Life:
1. Any live cell with fewer than two live neighbours dies, as if caused by underpopulation. 2. Any live cell with more than three live neighbours dies, as if by overcrowding. 3. Any live cell with two or three live neighbours lives on to the next generation. 4. Any dead cell with exactly three live neighbours becomes a live cell.
The colours you see in the above animation represent the alive status of each cell and also how many neighbours that cell has if it's alive.
This project is my first time making use of two utilities: optparse in python, and gifsicle.
optparse is a python library designed to make the creation of command line application much simpler. Specifically it's targeted towards making application with many possible flags easy to maintain. lifeImage.py falls into this category. From the commandline, you can control the source of input, the colour scheme, the number of generations to output, the scaling of the image and various other things to produce the exact animation or image you want.
You can take a look at optparse here: optparse @ docs.python.org. The tutorial included there was enough for me to create this application.
gifsicle is a command line application for the creation and modification of animated gifs. It can create gifs out of a sequence of images, convert an image into a sequence of images, or even modify replace a single frame of an animated gif with an external image.
You can see and download gifsicle here: Official Gifsicle Page
Why did I use gifsicle instead of the much more universal convert in ImageMagick? Simply put: gifsicle is faster. If someone would like to do a benchmark to (dis)prove this, I'd be happy to post the results, but from simple experimentation, it seemed obvious to me that gifsicle took less time to make the animation.
What's Next? Now that I have a working command line utility, my next goal is to make an AJAX powered web interface for the thing. This might explain why I have ProcMonitor in the github for Game of Life. The web interface was another key motivator behind using gifs for the output medium. People may want to use these things for avatar, and they're simply easier to share and move around than a java applet, or a flash swf, or some database stored simulation. It also helps that gifs are designed for palette based images, which works out nicely for optimizing the file size of these animations. The first 1000 generations of acorn is 2.5 MB as it is.
Another thing I want to do is make lifeImage.py read the .cells format from the Life Lexicon. This would save me a lot of time having to code all the states myself. This will be a very straightforward process, as the .cells files are simply plaintext with 2 lines of header.
Suggestions/bug fixes for my implementation of Game of Life are welcomed.
I'm almost 100% sure that some combination of the command line flags of lifeImage.py don't work nicely together, and would like to know what they are.
SPOJ Problem 2: Prime Generator (PRIME1)
Problem: Prime Generator
Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!
Concept The idea behind every solution here (with some variation) is to generate all the prime numbers that could be factors of numbers up to the maximum endpoint 1 billion. That square root happens to be around 32000. Using this array, do a bounded Sieve of Eratosthenes only in the range requested. In languages like php and python, it turns out that it's more efficient to build an associative array and check if the index is set than it is to generate a huge boolean array.
Code
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | /// PRIME1 - C++ (g++) // AC Time: 2.52s // NOTE: I am aware that the use of vector and set actually // makes this code run _slower_ // I used vector and set simply as a way of practicing STL #include <iostream> #include <cmath> #include <vector> #include <set> using namespace std; int main() { vector<int> primes; primes.push_back(2); for (int i = 3; i < = 32000; i+=2) { bool isprime = true; int cap = sqrt(i) + 1; vector<int>::iterator p; for (p = primes.begin(); p != primes.end(); p++) { if (*p >= cap) break; if (i % *p == 0) { isprime = false; break; } } if (isprime) primes.push_back(i); } int T,N,M; cin >> T; for (int t = 0; t < T; t++) { if (t) cout << endl; cin >> M >> N; if (M < 2) M = 2; int cap = sqrt(N) + 1; set<int> notprime; notprime.clear(); vector</int><int>::iterator p; for (p = primes.begin(); p != primes.end(); p++) { if (*p >= cap) break; int start; if (*p >= M) start = (*p)*2; else start = M + ((*p - M % *p) % *p); for (int j = start; j < = N; j += *p) { notprime.insert(j); } } for (int i = M; i <= N; i++) { if (notprime.count(i) == 0) { cout << i << endl; } } } return 0; } |
SPOJ Problem 1
When I saw that Thor had done solutions to the first few problems of Project Euler in many many languages, I thought "Hey! That's a good idea!" but didn't want to copy exactly.
So instead I'm doing solutions to some problems on SPOJ. SPOJ is an online judge system full of algorithmic problems. This is one of the things that Hanson Wang did to get as good as he is. The solutions I'll be providing here are going to be very simple problems, so don't expect any magic. The beautiful thing about SPOJ is the sheer number of languages it will judge. I figured this was the perfect playground to make sure my code worked in all the languages I try.
Problem: Life, the Universe, and Everything
Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.
Solutions - In order of frequency that I use the language
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 | //TEST AC - CPP (g++) #include <iostream> using namespace std; int main() { int n; while(1) { cin >> n; if (n == 42) break; cout << n << endl; } return 0; } |
C99
1 2 3 4 5 6 7 8 9 10 11 | //TEST AC - (gcc C99) #include <stdio.h> int main() { int n; while(1) { scanf("%d",&n); if (n == 42) break; printf("%d\n",n); } return 0; } |
php
1 2 3 4 5 6 7 8 | <? //TEST AC - PHP while(1) { fscanf(STDIN,"%d",$n); if ($n == 42) break; print "$n\n"; } ?> |
Python
1 2 3 4 5 6 | #TEST AC - Python while 1: num = input() if (num == 42): break print num |
Bash
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash # TEST AC - BASH while true; do read n if [ $n -eq 42 ]; then break fi echo "$n" done |
Ruby
1 2 3 4 5 6 7 8 | #TEST AC - Ruby while 1 n = gets.to_i if n == 42 break end puts n end |
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | //TEST AC - Java import java.io.*; import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while(true) { int n = in.nextInt(); if (n == 42) break; System.out.println(n); } } } |
Perl
1 2 3 4 5 6 7 8 9 | #TEST AC - Perl while (1) { $n = <STDIN>; if ($n == 42) { last; } print $n } |
C#
1 2 3 4 5 6 7 8 9 10 11 12 | //TEST AC - C# (gmcs + Mono) using System; class WelcomeCSS { static void Main() { while(true) { int n; n = int.Parse(Console.ReadLine()); if (n == 42) break; Console.WriteLine(n); } } } |
GNU Pascal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | {TEST AC - GPC Pascal} program TEST; var n:integer; begin while true do begin readln(n); if n = 42 then begin break; end; writeln(n); end; end. |
You can see Thor's Project Euler solutions here: Derek Thurn's Website - Project Euler