Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Saturday, April 30, 2011

How I wrote [java]code to give Pencil Sketch effect to a picture

I am creating an application where I wanted to transform images to give them pencil sketch effect which can be easily obtained by photoshop as is described here.

However, I needed to automate the whole process in the code and certainly it is beyond me to look "inside" photoshop to see how it works(what are the algorithms/transformations etc and their implementations).

Anyway, from the article above it became clear that pseudocode looks like following:

s = Read-File-Into-Image("/path/to/image")
g = Convert-To-Gray-Scale(s)
i = Invert-Colors(g)
b = Apply-Gaussian-Blur(i)
result = Color-Dodge-Blend-Merge(b,g)

Now it was a matter of finding open source image-processing library that provided the operations I needed. By googling, I landed on JH Labs. They, freely, provide an image editor on which I tried to replicate the process described in photoshop article mentioned above and indeed I got the pencil sketch effect. Now, the best part is that image processing library behind JH Labs image editor is open source.

Then it was just a matter of coding the pseudocode using the JH labs library and here it is...

BufferedImage src = null;
BufferedImage target = null;
src = ImageIO.read(new File("C:\\tmp\\ss.png"));
src = ImageUtils.convertImageToARGB(src);

//transformations begin=============
//gray scale
PointFilter grayScaleFilter = new GrayscaleFilter();
BufferedImage grayScale = new BufferedImage(src.getWidth(),src.getHeight(),src.getType());
grayScaleFilter.filter(src, grayScale);

//inverted gray scale
BufferedImage inverted = new BufferedImage(src.getWidth(),src.getHeight(),src.getType());
PointFilter invertFilter = new InvertFilter();
invertFilter.filter(grayScale,inverted);

//gaussian blurr
GaussianFilter gaussianFilter = new GaussianFilter(20);
BufferedImage gaussianFiltered = new BufferedImage(src.getWidth(),src.getHeight(),src.getType());
gaussianFilter.filter(inverted, gaussianFiltered);

//color dodge
ColorDodgeComposite cdc = new ColorDodgeComposite(1.0f);
CompositeContext cc = cdc.createContext(inverted.getColorModel(), grayScale.getColorModel(), null);
Raster invertedR = gaussianFiltered.getRaster();
Raster grayScaleR = grayScale.getRaster();
BufferedImage composite = new BufferedImage(src.getWidth(),src.getHeight(),src.getType());
WritableRaster colorDodgedR = composite.getRaster();
cc.compose(invertedR, grayScaleR , colorDodgedR);

//==================================
target = composite;
File outputfile = new File("C:\\tmp\\saved.png");
ImageIO.write(target, "png", outputfile);


Here is how the image transform when I apply above code...




Notes:
- I used above code on png images. JH Labs code only works with TYPE_INT_ARGB(ref) images so you might need to transform them correctly.
- Code shown above was written to just check the concept and has no regards for performance, beauty.

Acknowledgement:
Well, to be honest, from being a alien to image-processing to getting to the code was not as linear a process as described in this post and I had to do a lot of hit n trial to get to this point. I want to thank Jerry who patiently answered my queries.

Saturday, October 16, 2010

8-puzzle in javascript

If you're just interested in the game, this is it.

Here is the longer story...

I often heard that javascript is not a toy language anymore, its object oriented in a better way than java, its dynamically typed, supports closures etc and google does wonders with just html and javascript(e.g. the google pacman game).That feature list, and that its one of the mainstream languages in the software industry with those features, was enough for me to get excited about it. So, for a long time, I have wanted to try it out.

Last weekend, I set out to build the 8-puzzle game with html and javascript with a A* search based solver. I started by following the 4 lecture series by douglas crockford(the javascript evangelist in Yahoo). Having had some experience with scheme, it helped me to understand the philosophy behind the way things are done in javascript. Well, those 4 lectures were enough for me to get started and here I present the 8-puzzle game.

Implementation of the A* based solver is fairly well understood thing already. I used Manhattan disance heuristic. After writing the solver I realized that for some randomly generated configurations of the 8-puzzle, it was running endlessly. Thankfully, today there are debuggers, profilers and REPLs available for javascript(Firebug alone gives you all that and much more) so I could analyze my code pretty easily.
And, in the end realized that not all the randomly generated instances of 8-puzzle are solvable(for those configurations my solver was just busy searching the whole state space reachable and hence was so busy). This page describes it well and gives you enough hint on how to write a function to quickly check if an instance of 8-puzzle is solvable or not(in the given link search for "if you take a state, physically lift two consecutive tiles in that state and swap their positions, then the new state will be disconnected from old state.")

Saturday, October 9, 2010

MobiMeter - measure network latency from mobile phone

Last week I was involved in doing performance tests on a mobile application that talks to some servers to pull/push data. I wanted to determine the network latency of those servers from mobile. So, I wrote a small(just 2 screens) j2me application to measure network latency of any public GET URL from your mobile phone.

Code is available on google-code.

Saturday, September 11, 2010

Facebook Engineering Puzzles

A colleague of mine pointed me to the facebook engineering puzzles page yesterday. And I tried to give a shot to first one (the liar-liar puzzle). It took a good number of my hours today but it was fun.

And, I succeeded in first submission itself :). Here is the mail from facebook that I received:

from Facebook PuzzleBot
to g.himanshu@gmail.com
date Sat, Sep 11, 2010 at 4:45 PM
subject liarliar evaluation results
mailed-by facebook.com


Dear submitter,

Thank you for your submission of a puzzle solution to Facebook! After running your solution to liarliar (received on September 11, 2010, 12:37 am), I have determined it to be correct. Your solution ran for 2508.850 ms on its longest test case. If you have not already, try installing the official Facebook Puzzles application from http://apps.facebook.com/facebookpuzzles/ and publish a story about your solution! To publish, just go to http://apps.facebook.com/facebookpuzzles/mypuzzles.php and click on the publish link.

If you are applying for a position within Facebook, the puzzle difficulty solved will be taken into account with regards to how much time you had available to solve it (remember that Hors D'oeuvres are only tests for your benefit). I have taken the liberty of alerting our recruiting team about your success. Best of luck!

Sincerely,
-The puzzle robot


sorry, but no open sourced code this time for obvious reason. :P

[Update#1] I got the 2nd one(breathalyzer) accepted also. It took multiple submissions though :( and hence more time.

[Update(May 02 - 2011)] After a long time, yesterday I worked on Gattaca puzzle and nailed it. Regarding the timing, bot says, it took 4132.647 ms on the longest test case. My first solution was O(2^n) as I thought this was NP-hard problem which got rejected. I then followed the discussions on it and realized that this was *not* NP-hard and managed to work out the code that runs in O(n^2) in the worst case.

[Update(May 08 - 2011)] dancebattle is finished too. My first submission was accepted but longest test case time was 1108.22 ms. Then I optimized it a little bit, resubmitted and then bot says, it took 263.009 ms on it's longest test case :).

[Update(May 09 - 2011)] smallworld is done. Note that trivial O(n^2) solution does not succeed. Bot says, my solution took 9928.117 ms on its longest test case.

[Update(May 16 - 2011)] Today I received acceptance email for my solution to fridgemadness (Refrigerator Madness). Hardest part in this puzzle is to really understand the problem :). Regarding the timing, puzzle bot says, it took 362.562 ms on its longest test case.

Wednesday, August 4, 2010

ignoring emacs auto buffers in (next/previous)-buffer

I am about 2 yr old emacs user now. I've been doing basic stuff with emacs for long and now trying to transition into emacs power user after getting inspiration from screencasts like this one. More such vids can be found at emacs wiki.

Anyway, The traditional commands for going to next and previous buffers in emacs are "C-x <left/right arrow>". I read a pro tip somewhere that whenever you use next/prev buffer commands, you almost never want to go to one of emacs auto buffers such as *scratch*, *Messages* etc and that unnecessarily slows you down. It sounded so true to me and I got the itch to write elisp for it that ignores those buffers and here it is(I'm sure it could be done better, but then I'm a noob :) )
(defun emacs-buffer-p (name)
(string-match-p "\\*.*\\*" name))

(defun next-non-emacs-buffer (&optional original)
"Similar to next-buffer, but ignores emacs buffer such as *scratch*, *messages* etc."
(interactive)
(let ((tmp-orig (or original (buffer-name))))
(next-buffer)
(if (and
(not (eq (buffer-name) tmp-orig))
(emacs-buffer-p (buffer-name)))
(next-non-emacs-buffer tmp-orig))))

(defun previous-non-emacs-buffer (&optional original)
"Similar to previous-buffer, but ignores emacs buffer such as *scratch*, *messages* etc."
(interactive)
(let ((tmp-orig (or original (buffer-name))))
(previous-buffer)
(if (and
(not (eq (buffer-name) tmp-orig))
(emacs-buffer-p (buffer-name)))
(previous-non-emacs-buffer tmp-orig))))

and re-mapped "C-b", "M-b"(I never used their default keybindings anyway) to them
(global-set-key (kbd "C-b") 'next-non-emacs-buffer)
(global-set-key (kbd "M-b") 'previous-non-emacs-buffer)

Now if, occasionally, I want to goto emacs auto buffers then I can still use "C-x <left/right arrow>".

Tuesday, April 6, 2010

Generic Matrix[T] impl in Scala v2.8+

This is my attempt to learn how to implement generic math libraries(generic in the sense that they can work with any "Numeric" type such as Int,Long,Double,...etc) in Scala. Similar efforts have been tried at following places..

http://stackoverflow.com/questions/485896/how-does-one-write-the-pythagoras-theorem-in-scala
http://dcsobral.blogspot.com/search/label/matrix

I got enough guidance from scala community here, and from this write-up[warn: PDF] on new array impl in scala v2.8 .

Here is the result...


//Generic Rep for m X n immutable matrix
class Matrix[T: ClassManifest] private (private val elems: Array[Array[T]])(n: Numeric[T]) {

import n.mkNumericOps

val rows = elems.size //Returns # of rows
val cols = elems(0).size //Returns # of cols

//Returns jth elem in ith row
// 0 <= i < rows And 0 <= j < cols
def apply(i: Int, j: Int): T = elems(i)(j)

//Returns ith row, 0 <= i < rows
def row(i: Int): Array[T] = elems(i).clone

//Returns ith col, 0 <= i < cols
def col(i: Int): Array[T] = elems.map(_(i))

def *(that: Matrix[T]): Matrix[T] = {
if(this.cols != that.rows)
throw new IllegalArgumentException("Can't be multiplied")
else {
val newArr = Array.ofDim[T](this.rows, that.cols)

for(i <- 0 to this.rows-1) {
for(j <- 0 to that.cols-1) {
newArr(i)(j) = this.row(i).zip(that.col(j)).map(a => a._1 * a._2).sum(n)
}
}
new Matrix(newArr)(n)
}
}

/* ------------ More Matrix Operations ----------- */
}

object Matrix {

def apply[T](elems: Array[Array[T]])(implicit n: Numeric[T],m: ClassManifest[T]): Matrix[T] =
new Matrix[T](clone(elems))(n)

private def clone[T: ClassManifest](arr: Array[Array[T]]): Array[Array[T]] = arr.map(_.clone)
}

Monday, February 22, 2010

QuickSort in Scala

Today I stumbled on this post, showing Quick-Sort impl in various languages.. and I got the itch to impl a simple version for same in scala. Here is the result..
def quickSort[A](xs: List[A])(implicit orderer:(A)=>Ordered[A]): List[A] =
xs match {
case Nil => xs
case _ :: Nil => xs
case x :: rest =>
quickSort(rest.filter(orderer(_) <= x)) ++ List(x) ++
quickSort(rest.filter(orderer(_) > x))
}
Interesting thing to note is that the size is close to same as the Haskell impl in the mentioned post.

A trial run on the Scala REPL..
Welcome to Scala version 2.7.5.final (Java HotSpot(TM) Client VM, Java 1.6.0_07).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def quickSort[A](xs: List[A])(implicit orderer:(A)=>Ordered[A]): List[A] =
xs match {
case Nil => xs
case x :: Nil => xs
case x :: rest =>
quickSort(rest.filter(orderer(_) <= x)) ++ List(x) ++ quickSort(rest.filter(orderer(_) > x))
}
| | | | | | quickSort: [A](List[A])(implicit (A) => Ordered[A])List[A]

scala> quickSort(List(2,2,2,100,-1,2,5,1,0,3,4,3))
res0: List[Int] = List(-1, 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 100)

scala> quickSort(List("himanshu","ruchi","nitin","manoj"))
res1: List[java.lang.String] = List(himanshu, manoj, nitin, ruchi)

Tuesday, January 26, 2010

An Unbeatable Tic-Tac-Toe (in Scala)

I'm reading AIMA-3e, implemented the AlphaBetaSearch from ch-5 on Adversarial Search. I thought it would be cool to create an actual game, so I wrote a TicTacToe implementation for the game and a game-loop to play it. You can find the code here. If you want to understand the implementation, you know what to read :P.
/** The *Unbeatable* Tic-Tac-Toe game implementation.
*
* Save this script in a file xyz.scala in a directory.
* Compile it with scalac: $scalac xyz.scala
* Play the game with scala: $scala Play
*
* @author Himanshu Gupta
*/

/* A Search algorithm to find the best move
* given current state of the game
*/
object AlphaBetaSearch {
def apply[S,A](state: S, game: ZeroSumGame[S,A]): A = {
val actionMinvalPairs = game.actions(state).map((a) =>
(a,MinValue(game.result(state,a),Math.MIN_DOUBLE,Math.MAX_DOUBLE,game)))
//sort the pairs in descending order of MinValue
val sorted = actionMinvalPairs.sort(_._2 > _._2)
//take the pairs with highest MinValue(they can be more than 1 also)
val bestPairs = sorted.takeWhile(sorted.head._2 == _._2)
//chose randomly one from the best
bestPairs(new scala.util.Random(new java.util.Random).nextInt(bestPairs.length))._1
}

private def MaxValue[S,A](state: S, alpha: Double,beta: Double, game: ZeroSumGame[S,A]): Double =
if (game.terminalTest(state)) game.utility(state)
else {
def loop(states: List[S], v: Double, alpha: Double): Double =
states match {
case s :: rest => {
val tmp = Math.max(v,MinValue(s,alpha,beta,game))
if(tmp >= beta) tmp
else loop(rest, tmp, Math.max(alpha,tmp))
}
case Nil => v
}

loop(game.actions(state).map(game.result(state,_)),Math.MIN_DOUBLE,alpha)
}

private def MinValue[S,A](state: S, alpha: Double, beta: Double, game: ZeroSumGame[S,A]): Double =
if (game.terminalTest(state)) game.utility(state)
else {
def loop(states: List[S], v: Double, beta: Double): Double =
states match {
case s :: rest => {
val tmp = Math.min(v,MaxValue(s,alpha,beta,game))
if(tmp <= alpha) tmp
else loop(rest, tmp, Math.min(beta,tmp))
}
case Nil => v
}

loop(game.actions(state).map(game.result(state,_)),Math.MAX_DOUBLE,beta)
}
}

//abstract game representation
abstract class Game[P,S,A] {
def initialState: S
def player(s: S): P
def actions(s: S): List[A]
def result(s: S, a: A): S
def terminalTest(s: S): Boolean
def utility(s: S, p: P): Double
}

//abstract Two-player game representation
abstract class ZeroSumGame[S,A] extends Game[String,S,A] {

//In two-player, zero-sum games, the two element vector
//can be reduced to a single value because the values
//are always opposite
// -- described in Section 5.2.2
override def utility(s: S, p: String) = utility(s)
def utility(s: S): Double
}
object ZeroSumGame {
val Min = "MIN"
val Max = "MAX"
}

//Tic-Tac-Toe implementation of Two-Player Game
class TicTacToeGame extends ZeroSumGame[(String,Array[Array[Char]]),(Int,Int)] {

type Board = Array[Array[Char]]
type State = (String,Board)
type Action = (Int,Int)

private val X = 'X'
private val O = 'O'
private val nullChar: Char = 0

def initialState = (ZeroSumGame.Max,new Array[Array[Char]](3,3))

def player(s: State) = s._1

def actions(s: State) = {
(for(x <- 0 to 2;
y <- 0 to 2;
if s._2(x)(y) == nullChar) yield (x,y)).toList
}

def result(s: State, a: Action) =
s match {
case (ZeroSumGame.Max, board) =>
if(board(a._1)(a._2) == nullChar) {
val newBoard = cloneBoard(board)
newBoard(a._1)(a._2) = X
(ZeroSumGame.Min, newBoard)
}
else throw new IllegalStateException("Box at " + a + " is already filled.")
case (ZeroSumGame.Min, board) =>
if(board(a._1)(a._2) == nullChar) {
val newBoard = cloneBoard(board)
newBoard(a._1)(a._2) = O
(ZeroSumGame.Max, newBoard)
}
else throw new IllegalStateException("Box at " + a + " is already filled.")
case _ => throw new IllegalStateException("Not a valid player " + s._1)
}

def terminalTest(s: State) =
getWinner(s._2) match {
case Some(_) => true
case None => actions(s).length == 0
}

def utility(s: State): Double =
getWinner(s._2) match {
case Some(ZeroSumGame.Max) => 1.0
case Some(ZeroSumGame.Min) => -1.0
case None if actions(s).length == 0 => 0.5
case _ => throw new IllegalStateException("Not a terminal state." + toString(s))
}

def toString(state: State) = {
val board = state._2
var result = ""
for(y <- 2.until(-1,-1); x <- 0 to 2) {
result = result + (if(board(x)(y) == nullChar) "-" else board(x)(y))
if(x == 2) result = result + "\n"
}
result
}

//Returns the winner if game has terminated without draw,
//None otherwise
private def getWinner(board: Board): Option[String] = {
(for( x <- 0 to 2; y <- 0 to 2) yield board(x)(y)).toList match {
//the for loop results in board charaters at all the
//co-ordinates in following order
//((0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2))

case X :: X :: X :: _ :: _ :: _ :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: _ :: X :: X :: X :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: _ :: _ :: _ :: _ :: X :: X :: X :: Nil => Some(ZeroSumGame.Max)
case X :: _ :: _ :: X :: _ :: _ :: X :: _ :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: X :: _ :: _ :: X :: _ :: _ :: X :: _ :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: X :: _ :: _ :: X :: _ :: _ :: X :: Nil => Some(ZeroSumGame.Max)
case X :: _ :: _ :: _ :: X :: _ :: _ :: _ :: X :: Nil => Some(ZeroSumGame.Max)
case _ :: _ :: X :: _ :: X :: _ :: X :: _ :: _ :: Nil => Some(ZeroSumGame.Max)

case O :: O :: O :: _ :: _ :: _ :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: _ :: O :: O :: O :: _ :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: _ :: _ :: _ :: _ :: O :: O :: O :: Nil => Some(ZeroSumGame.Min)
case O :: _ :: _ :: O :: _ :: _ :: O :: _ :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: O :: _ :: _ :: O :: _ :: _ :: O :: _ :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: O :: _ :: _ :: O :: _ :: _ :: O :: Nil => Some(ZeroSumGame.Min)
case O :: _ :: _ :: _ :: O :: _ :: _ :: _ :: O :: Nil => Some(ZeroSumGame.Min)
case _ :: _ :: O :: _ :: O :: _ :: O :: _ :: _ :: Nil => Some(ZeroSumGame.Min)

case _ => None
}
}

private def cloneBoard(board: Board): Board = {
val result = new Array[Array[Char]](3,3)
for(x <- 0 to 2; y <- 0 to 2) {
result(x)(y) = board(x)(y)
}
result
}
}

//The-Game-Loop
import java.io.InputStreamReader
object Play {

def main(args: Array[String]) {

println("** Welcome to the *Unbeatable* Tic-Tac-Toe **")
println("")
println("*** How To Play ***")
println("Place an O at the position chosen using its x-y coordinates")
println("0 <= x,y <= 2")
println("")
println("** Let the Game Begin, I place the X first **")

val game = new TicTacToeGame()
val initState = game.initialState
val reader = new InputStreamReader(System.in)

def loop(state: (String,Array[Array[Char]])) {
//display current state of the game
println("")
println("**************")
println(game.toString(state))
println("**************")
println("")

if(game.terminalTest(state)) {
game.utility(state) match {
case 1.0 =>
println("You LOST the game.")
case 0.5 =>
println("Its a DRAW.")
case -1.0 =>
println("You WON the game.")
}
}
else {
//get input
println("** Your turn **")
print("Type x:")
val x = Character.getNumericValue(reader.read())
reader.read() //ignore the new-line char
print("Type y:")
val y = Character.getNumericValue(reader.read())
reader.read() //ignore another new-line char

//validate input
if(x >= 0 && x <= 2 && y >= 0 && y <= 2) {
//play
val nextSt = game.result(state,(x,y))
loop(game.result(nextSt,AlphaBetaSearch(nextSt,game)))
}
else {
println("Invalid Input, Valid Input is 0 <= x,y <= 2")
loop(state)
}
}
}

loop(game.result(initState,AlphaBetaSearch(initState,game)))
}
}
How to Play:
1. Save the above code in a file, let say TicTacToe.scala in a directory.
2. Compile the code by running command $scalac TicTacToe.scala
3. Play the game by running command $scala Play

Have Fun :-)

****************************
I've played it with Scala version 2.7.6.final (Java HotSpot(TM) Server VM, Java 1.6.0_14).

Tuesday, September 15, 2009

SICP Constraint Network Impl code in Scala

I wrote the code for digital circuit simulator from SICP to contrast my scala coding style with that of Martin Odersky(he wrote same in his book "Programming in Scala"). These are the two(part-I, part-II) posts about that.

To enhance my learnings and to write some more code, Now I implemented the constraint propagation network from SICP section-3.3.5 too.

Here is the code...
//all the Constraint implementations
//extend the Constraint class
abstract class Constraint {
def informAboutValue()
def informAboutNoValue()
}

//Connector implementation
class Connector {
private var myName = "Unknown"
private var myVal:Int = _
private var informant:AnyRef = _
private var constraints:List[Constraint] = List()

def this(newName:String) {
this()
myName = newName
}

def name = myName

def hasValue() = informant != null

def value = {
if(!hasValue())
throw new RuntimeException("""|This connector
| does not have a
| value.""".stripMargin)
myVal
}

def setValue(newVal:Int, informer:AnyRef) {
Tuple(hasValue(),newVal == myVal) match {
case Tuple2(false, _) => {
myVal = newVal
informant = informer
constraints.foreach(
(c:Constraint) =>
{ if(c ne informer) c.informAboutValue()})
}
case Tuple2(true,true) => ; //ignore
case Tuple2(true,false) =>
throw new RuntimeException("Contradiction " +
newVal + " " + myVal)
}
}

def forgetValue(retractor:AnyRef) {
if(retractor eq informant) {
informant = null
constraints.foreach(
(c:Constraint) =>
{ if(c ne retractor) c.informAboutNoValue() })
}
}

def connect(c:Constraint) {
constraints = c :: constraints
}
}

//===== Constraints =====
case class Adder(a:Connector,b:Connector,
c:Connector) extends Constraint {
a.connect(this)
b.connect(this)
c.connect(this)

def informAboutValue() {
Tuple(a.hasValue(),b.hasValue(),c.hasValue())
match {
case Tuple3(true,true,false) =>
c.setValue(a.value + b.value, this)
case Tuple3(true,false,true) =>
b.setValue(c.value - a.value, this)
case Tuple3(false,true,true) =>
a.setValue(c.value - b.value, this)
case _ => ; //ignore
}
}

def informAboutNoValue() {
a.forgetValue(this)
b.forgetValue(this)
c.forgetValue(this)
informAboutValue()
}
}

case class Multiplier(a:Connector,b:Connector,
c:Connector) extends Constraint {
a.connect(this)
b.connect(this)
c.connect(this)

def informAboutValue() {
Tuple(a.hasValue(),b.hasValue(),
(a.hasValue() && a.value == 0) ||
(b.hasValue() && b.value == 0),
c.hasValue())
match {
case Tuple4(_,_,true,_) =>
c.setValue(0, this)
case Tuple4(true,true,_,false) =>
c.setValue(a.value * b.value, this)
case Tuple4(true,false,_,true) =>
b.setValue(c.value / a.value, this)
case Tuple4(false,true,_,true) =>
a.setValue(c.value / b.value, this)
case _ => ; //ignore
}
}

def informAboutNoValue() {
a.forgetValue(this)
b.forgetValue(this)
c.forgetValue(this)
informAboutValue()
}
}

case class Constant(value:Int,
c:Connector) extends Constraint {
c.connect(this)
c.setValue(value, this)

def informAboutValue() {
throw new RuntimeException("""|CONSTANT constraint,
| request not allowed
|.""".stripMargin) }
def informAboutNoValue() {
throw new RuntimeException("""|CONSTANT constraint,
| request not allowed
|.""".stripMargin) }
}

case class Probe(c:Connector) extends Constraint {
c.connect(this)

def informAboutValue() {
printProbe(c.value.toString()) }

def informAboutNoValue() {
printProbe("?") }

private def printProbe(value:String) {
println("Probe: " + c.name + " = " + value)
}
}

//====== simulation =====
def celsiusFahrenheitConverter(c:Connector,f:Connector) {
val u = new Connector()
val v = new Connector()
val w = new Connector()
val x = new Connector()
val y = new Connector()

Multiplier(c, w, u)
Multiplier(v, x, u)
Adder(v, y, f)
Constant(9, w)
Constant(5, x)
Constant(32, y)
}

val C = new Connector("Celsius Temp")
Probe(C)
val F = new Connector("Fahrenheit Temp")
Probe(F)

celsiusFahrenheitConverter(C,F)

C.setValue(25, 'user)
//Probe: Fahrenheit Temp = 77
//Probe: Celsius Temp = 25

F.setValue(212, 'user)
//java.lang.RuntimeException: Contradiction 212 77

C.forgetValue('user)
//Probe: Fahrenheit Temp = ?
//Probe: Celsius Temp = ?

F.setValue(212, 'user)
//Probe: Celsius Temp = 100
//Probe: Fahrenheit Temp = 212

Sunday, September 13, 2009

SICP digital circuit simulator in scala Part I

This is a scala port of digital circuit simulator of section 3.3.4 in SICP. Martin Odersky has done same in Chapter-18(Stateful Objects) in his book Programming in Scala. Before reading his code, I wanted to write it on my own so that I can understand where I don't think *in scala* when writing code in Scala.
Next, I'll read the same port from mentioned scala book and see what I can learn from the differences.

Here is my code(I tested it on Scala version 2.7.5.final interpreter)...

//Segment and Agenda
import scala.collection.mutable.Queue
case class Segment(val time:Int,
val queue:Queue[()=>Unit]) extends Ordered[Segment] {
require(time >= 0)

override def compare(that:Segment) = {
if(that.time == time) 0
else if(that.time < time) -1
else 1
}
}

import scala.collection.mutable.PriorityQueue
class Agenda {
private var currentTime = 0
private val timeSegments = new PriorityQueue[Segment]()

def getCurrentTime = currentTime

def addItem(time:Int, item:()=>Unit) {
getTimeSegment(time) match {
case None =>
val queue = new Queue[()=>Unit]()
queue += item
timeSegments += Segment(time, queue)
case Some(segment) => segment.queue += item
}
}

def propagate():Unit = {
if(!timeSegments.isEmpty) {
firstItem()
propagate()
}
else println("Agenda Propagation Done.")
}

//gets first agenda item and removes it
//from the agenda
private def firstItem = {
val segment = timeSegments.max
currentTime = segment.time

val item = segment.queue.dequeue
if(segment.queue.isEmpty)
timeSegments.dequeue

item
}

//get the Segment matching time from timeSegments
private def getTimeSegment(time:Int) = {
val tmp = timeSegments.filter((s:Segment)=>s.time == time)
if(tmp.isEmpty) None else Some(tmp.first)
}
}

//Wire
class Wire() {
var signal = false
private var actions:List[()=>Unit] = List()

def setSignal(b:Boolean) {
if(b != signal) {
signal = b
//execute all actions
actions.foreach((proc:()=>Unit) => proc())
}
}

def addAction(proc:()=>Unit) {
actions = proc :: actions
proc()
}
}

//Probe
def probe(name:String, wire:Wire, agenda:Agenda) {
wire.addAction(
() =>
println(name + " " + agenda.getCurrentTime
+ " ,New Value = " + wire.signal))
}

//after-delay
def afterDelay(delay:Int, proc:() => Unit, agenda:Agenda) {
require(delay >= 0)
agenda.addItem(agenda.getCurrentTime + delay, proc)
}

//====================== SIMULATION ========================

val theAgenda = new Agenda()
val inverterDelay = 2
val andGateDelay = 3
val orGateDelay = 5

//inverter
def inverter(in:Wire, out:Wire) = {
in.addAction(
() => {
val newVal = !in.signal
afterDelay(inverterDelay, () =>
(out.setSignal(newVal)),theAgenda)
})
"Ok"
}

//and gate
def andGate(in1:Wire, in2:Wire, out:Wire) = {
val action = () => {
val newVal = in1.signal && in2.signal
afterDelay(andGateDelay,
() => (out.setSignal(newVal)),
theAgenda) }
in1.addAction(action)
in2.addAction(action)
"Ok"
}

//or gate
def orGate(in1:Wire, in2:Wire, out:Wire) = {
val action = () => {
val newVal = in1.signal || in2.signal
afterDelay(orGateDelay,
() => (out.setSignal(newVal)),
theAgenda) }
in1.addAction(action)
in2.addAction(action)
"Ok"
}

//half-adder
def halfAdder(in1:Wire, in2:Wire, sum:Wire, carry:Wire) = {
val t1 = new Wire()
val t2 = new Wire()
orGate(in1, in2, t1)
andGate(in1, in2, carry)
inverter(carry, t2)
andGate(t1, t2, sum)
"Ok"
}

// == Running the simulation ==
val in1 = new Wire()
val in2 = new Wire()
val sum = new Wire()
val carry = new Wire()

probe("sum",sum,theAgenda)
//sum 0 ,New Value = false

probe("carry",carry,theAgenda)
//carry 0 ,New Value = false

halfAdder(in1,in2,sum,carry)
//Ok

in1.setSignal(true)

theAgenda.propagate()
//sum 8 ,New Value = true
//Agenda Propagation Done.

in2.setSignal(true)

theAgenda.propagate()
//carry 11 ,New Value = true
//sum 16 ,New Value = false
//Agenda Propagation Done.

Monday, March 30, 2009

make-change and make-best-change

This is one of the challenges presented on this page.
1. make-change
Find denominations of a given amount in given coins. Define your function to take the number of cents and an optional list of the available coins, largest to smallest, e.g., (make-change 72 '(25 10 1)). The default list should be (25 10 5 1).You can assume that the coins are such that the simple greedy algorithm will get the answer with the fewest coins.
Solution:
(defun make-change (amount &optional (coins '(25 10 5 1)))
(labels ((make-change-iter (amount coins result)
(cond ((null coins)
(apply #'values (nreverse result)))
((= amount 0)
(make-change-iter amount
(cdr coins) (cons 0 result)))
(t
(make-change-iter
(mod amount (car coins))
(cdr coins)
(push (floor amount (car coins)) result))))))
(make-change-iter amount coins nil)))

2. make-best-change
make-change may fail to find the best answer for certain sets of coins, where best means "uses the fewest coins." For example, if there are no nickels, then (make-change 30 '(25 10 1)) will return 1 quarter and 5 pennies, which is 6 coins, but 3 dimes would be better.
Define make-best-change to take the same arguments as make-change. make-best-change should return an answer that leaves the least amount of cents unaccounted for. If there's more than such answer, it should return a solution that uses the fewest coins.
Solution:
(defun make-best-change (amount &optional (coins '(25 10 5 1)))
(apply #'values
(butlast
(reduce #'(lambda (x y)
(cond ((< (car (last x)) (car (last y))) x)
((> (car (last x)) (car (last y))) y)
((< (sum-list (butlast x))
(sum-list (butlast y))) x)
(t y)))
(make-all-change amount coins)))))
;sum elements of a list
(defun sum-list (nums)
(reduce #'+ nums))
;this returns a list of all the possible changes with
;remaining amount appended at last of each list.
(defun make-all-change (amount coins)
(cond ((= amount 0) `(,(make-list
(1+ (length coins)) :initial-element 0)))
((null coins) `((,amount)))
((< amount (car coins))
(mapcar #'(lambda (x) (cons 0 x))
(make-all-change amount (cdr coins))))
(t (append
(mapcar
#'(lambda (x) (incf (car x)) x)
(make-all-change (- amount (car coins)) coins))
(mapcar #'(lambda (x) (cons 0 x))
(make-all-change amount (cdr coins)))))))

Wednesday, March 25, 2009

list-of macro

I stumbled on this page and started to solve the problems, Here is solution to the ex7.
list-of is a macro that simplifies collecting lists of values of expressions. Though this description is long, and the macro is powerful, it's actually quite simple and can be implemented with relatively little code.

The general syntax is

(LIST-OF exp generator-or-filter generator-or-filter ...)

It's easiest to explain by starting with simple examples.

> (list-of (1+ x) (x :in '(1 2 3)))
(2 3 4)

exp is (1+ x) and (x :in '(1 2 3)) is a generator. A generator is anything that has the form (variable :in list). This generator generates three values for x, namely 1, 2, and 3. list-of returns a list of the value of (1+ x) for those three values of x.

> (list-of (1+ x) (x :in '(1 2 3)) (oddp x))
(2 4)

The exp and generator are as before, but now I've added the filter (oddp x). A filter is any expression that doesn't look like a generator. The filter says "keep only those values of x that are odd." Hence, list-of only collects values for (1+ x) equal to 1 and 3.

That's it. Any number of generators and filters can be given. They are applied from left to right. If there are two generators, the second repeats itself for every value created by the first, e.g.,

> (setq l '(a b))
(A B)
> (list-of (list x y) (x :in l) (y :in ))
((A A) (A B) (B A) (B B))

Likewise, the filters apply in order.

> (setq l '(1 2 3 4))
(1 2 3 4)
> (list-of (list x y) (x :in l) (oddp x) (y :in l) (evenp y))
((1 2) (1 4) (3 2) (3 4))

This collects (list x y) for every x in l that is odd and every y in l that is even. Notice that

> (list-of (list x y) (x :in l) (y :in l) (oddp x) (evenp y))
((1 2) (1 4) (3 2) (3 4))

returns the same answer, but does more work. Trace oddp to see the difference.

One special case that follows naturally:

  • (list-of exp) simply returns a list of exp.

Note: It'd be more direct to write "the list of x in l that are odd" as

(list-of (x :in l) (oddp x))

rather than

(list-of x (x :in l) (oddp x))

Define list-of so that if no initial expression to collect is given, it uses the variable of the first generator.

Solution:
(defmacro list-of (&rest args)
;functions to deal with generator forms
(defun generator? (x) (and (listp x)(eq (cadr x) :in)))
(defun var-generator (x) (car x))
(defun list-generator (x) (caddr x))
;following function generates appropriate code given
;the expression and list of generators-filters
(defun generate-code (exp gfs)
(let ((code (gensym)))
(defun recurse (gfs)
(cond ((null gfs) `(push ,exp ,code))
((generator? (car gfs))
`(dolist (,(var-generator (car gfs))
,(list-generator (car gfs)))
,(recurse (cdr gfs))))
(t `(if ,(car gfs) ,(recurse (cdr gfs))))))
`(let ((,code nil))
,(recurse gfs) (nreverse ,code))))
;extracting exp and list of generators-filters; then calling
;generate-code for code generation.
(let ((exp (car args))
(generators-filters (cdr args)))
(if (generator? (car args))
(progn (setf exp (var-generator (car args)))
(setf generators-filters args)))
(generate-code exp generators-filters)))

tconc structure

I stumbled on this page and started to solve the problems, Here is solution to the ex6.

Adding elements to the end of a list is usually inefficient in Lisp:

  • (append list (list item)) is the worst possible approach, because list gets copied every time a new item is added. If you use this form to build a list N long, you'll have done N squared cons's. Imagine doing that for a simple 100-element list!
  • (nconc list (list item)) doesn't cons, but still gets very slow as the list gets long, because Lisp has to cdr all the way to the end of the list in order to find the last cons cell to modify.

A classic solution is to create a data structure called a tconc structure (for "tail concatenate"), which holds two pointers to the same list:

  • a head pointer to the whole list, and
  • a tail pointer to the last cons cell of that list.

With this data structure, you can add new elements to the end of the list with just a few quick operations, no matter how long the list is, and you can still get the whole list whenever you need it.

Therefore, your job is to:

  • Define (make-tconc [ list ]) to return a tconc structure pointing to list. If no list is given, a tconc structure for an empty list should be returned.
  • Define (tconc tconc-structure [item item ...]) to add the items, if any, to the end of the list pointed to by tconc-structure, update tconc-strcture appropriately, and return the new value of the internal list.
  • Define (tconc-list tconc-structure list ) to add the items in list to the end of the internal list.

Note that you can get the internal list at any time with (tconc tconc-structure).

> (setq tc (make-tconc))

> (tconc tc 1)
(1)
> (tconc tc 2 3)
(1 2 3)
> (tconc tc)
(1 2 3)

Each successive call to tconc should be efficient, no matter how long the internal list has grown. One test of your tconc structure is that it always obeys the following rule:
(eq (last head-pointer) tail-pointer)


Solution:
(defstruct (tconc (:constructor create-tconc))
"a tail concatenate list for easy append"
(head nil) (tail nil))
(defun make-tconc (&optional l)
(let ((tc (create-tconc)))
(apply #'tconc tc l)
tc))
(defun tconc (tconc-structure &rest items)
(unless (null items)
(if (null (tconc-head tconc-structure))
(setf (tconc-head tconc-structure) items)
(setf (cdr (tconc-tail tconc-structure)) items))
(setf (tconc-tail tconc-structure) (last items)))
(tconc-head tconc-structure))
(defun tconc-list (tconc-structure &optional l)
(apply #'tconc tconc-structure l))

collect-numbers function

I stumbled on this page and started to solve the problems, Here is solution to the ex5.

Define (collect-numbers s-exp) to return a list of all the numbers in the s-expression s-exp. s-exp may be an atom, a list, or a list of s-expressions.

> (collect-numbers 1)
(1)
> (collect-numbers 'a)
NIL
> (collect-numbers '(1 (b (2 c) ((3)))))
(1 2 3)
Solution:
(defun collect-numbers (s-exp)
(if (atom s-exp)
(if (numberp s-exp) (list s-exp) nil)
(mapcan #'collect-numbers s-exp)))

delete-car function

I stumbled on this page and started to solve the problems, Here is solution to the ex4.

Define (delete-car list) to modify and return list with the first element of list deleted.

> (setq l (list 'a 'b 'c))
(A B C)
> (delete-car l)
(B C)
> L
(B C)
Solution:
(defun delete-car (l)
(setf (car l) (cadr l))
(let ((tmp (cddr l)))
(setf (cdr l) tmp))
(if (equal l '(())) nil l))

make-balance function

I stumbled on this page and started to solve the problems, Here is solution to the ex3.
Define (make-balance initial-balance) to return a function that takes 0 or 1 arguments. If that function is called with 0 arguments, it returns the current balance. If called with 1 argument, which should be a number, it adds that number to the current balance, and returns the new balance.
> (setq bal (make-balance 100))
<>
> (funcall bal 10)
110
> (funcall bal -50)
60
> (funcall bal)
60
Solution:
(defun make-balance (bal)
(let ((balance bal))
#'(lambda (&optional (amt 0))
(setf balance (+ amt balance)))))

key-if macro

I stumbled on this page and started to solve the problems, Here is solution to the ex2.

Define the macro key-if to have the form

(KEY-IF test
:THEN exp1 exp2 ...
:ELSE exp3 exp4 ...)

This does about the same thing as:

(COND (test exp exp ...)
(T else-exp else-exp ...))

Almost everything is optional in key-if except the test. Here are some legal forms and their results:

> (key-if (> 3 1) :then 'ok)
OK
> (key-if (<> (key-if (> 3 1) :else 'oops)
NIL
> (key-if (> 3 1) :then)
NIL
> (key-if (> 3 1) :else 'oops :then 'ok)
OK
> (key-if (> 3 1) :else 'oops :then (print 'hi) 'ok)
HI
OK
Solution:
(defmacro key-if (test &rest args)
(defun extract-then-else (exp)
(defun iter (exp then-list else-list flag)
(cond
((null exp) (values (nreverse then-list) (nreverse else-list)))
((eq :then (car exp)) (iter (cdr exp)
then-list
else-list t))
((eq :else (car exp)) (iter (cdr exp)
then-list
else-list nil))
(t (if (null flag)
(iter (cdr exp) then-list (cons (car exp)
else-list) flag)
(iter (cdr exp) (cons (car exp) then-list)
else-list flag)))))
(iter exp nil nil nil))
(multiple-value-bind (then else) (extract-then-else args)
`(cond (,test ,(cons 'progn then))
(t ,(cons 'progn else)))))

has-number-p

I stumbled on this page and started to solve the problems, Here is solution to the ex1 .
Define (has-number-p s-exp) to return true if the s-expression is or contains a number.
> (has-number-p 1)
T
> (has-number-p 'a)
NIL
> (has-number-p '(a (b (c d) ((3)))))
T

Solution:
(defun has-number-p (s-exp)
(if (atom s-exp)
(if (numberp s-exp) t nil)
(some #'has-number-p s-exp)))