Cool Programs from Steve O'Hara

I hope you find something interesting here. I certainly have enjoyed working on these. Feel free to copy them.

The theme of this particular set of programs is getting the computer to perform tasks that people find difficult. And solving those tasks in a way that is visible and understandable to people.

Back to Steve's Website


Quick Links on This Page

Toy Language '07 Compiler
Digit Recognition
FreeCell Player
Solve Sudoku Puzzle #1
Solve Sudoku Puzzle #2
Steve's Spreadsheet
Connect Digits with Operators
to Find Numbers
Weigh Balls to Find Which One
is Heavy or Light
Play MasterMind game
Paint Pictures from Counting Clues
Logic Puzzle Solver
Bridge Player
Calculate PI and E
to Arbitrary Precision
Symbolic Expression Evaluation
(and Derivatives)
Road Rage Simulation
Toy Struts Application
Orchronix Software
Real Time Plant Control
Other Stuff
 


Toy Language '07 Compiler

The TL07 language is based on a very small subset of the Pascal language. It provides a good basis for a simple compiler. The main components of the compiler are:

  • Parser -- convert characters to tokens like words and punctuation
  • Syntax Analyzer -- figure out what each token means
  • Semantic Analysis -- get the meaning of whole program
  • Intermediate Representation -- Three address representation for optimization
  • Code Generation -- Generate MIPS assembly code

    Here is a really simple TL07 program that reads a number and prints double that number.

    TL07 Source program:
    PROGRAM simple
        VAR x AS INT ;
    BEGIN
        x := READINT ;
        WRITEINT 2 * x ;
    END
    =>
    =>
    Syntax Tree (click to expand):
    =>
    Semantic Tree (green means Integer):
    =>
    =>
    Internal Representation:
    =>
    General MIPS Assembly Code:
        .data
    r1: .word 0
    r2: .word 0
    r3: .word 0
    r4: .word 0
    x:  .word 0
    
        .text
    block1:
        li $v0, 5            # READINT
        syscall              # code 5 = read_int
        sw $v0, r1
        lw $a0, r1           # store x
        sw $a0, x
        li $a0, 2            # 2
        sw $a0, r2
        lw $a0, x            # load x
        sw $a0, r3
        lw $a0, r2           # 2 * x
        lw $a1, r3
        mul $a2, $a0, $a1
        sw $a2, r4
        li $v0, 1            # WRITEINT
        lw $a0, r4
        syscall              # code 1 = print_int
    
        li $v0, 10           # System code for exit
        syscall              #

    Here is a robust TL07 program to calculate E = 2.71828+ to 500 digits: e.tl07
    And here is the generated MIPS code for it: e.s and it's output: e.out

    Compiler.java -- Main
    TL07Compiler.java
    TL07Parser.java
    TL07Scanner.java
    TL07Symbol.java
    TL07SymbolTable.java

    ParseAssignment.java
    ParseDeclarations.java
    ParseElseClause.java
    ParseException.java
    ParseExpression.java
    ParseExprItem.java
    ParseFactor.java
    ParseIfStatement.java
    ParseItem.java
    ParseLiteral.java
    ParseMemCell.java
    ParseProgram.java
    ParseSimpleExpression.java
    ParseStatement.java
    ParseStatementSequence.java
    ParseTerm.java
    ParseType.java
    ParseWhileStatement.java
    ParseWriteInt.java

    SyntaxAssignment.java
    SyntaxDeclaration.java
    SyntaxError.java
    SyntaxExpression.java
    SyntaxIfElse.java
    SyntaxItem.java
    SyntaxProgram.java
    SyntaxStatement.java
    SyntaxTypeChecker.java
    SyntaxWhile.java
    SyntaxWriteInt.java

    IntInstruction.java
    IntRepAssignment.java
    IntRepExpression.java
    IntRepIfElse.java
    IntRepresentation.java
    IntRepWhile.java
    IntRepWriteInt.java

    CodeGenerator.java

    Back to top

    Hand Written Digit Recognition

    
    
    
    
       ##################
       ##################
                ######
                ######
                ######
                ######
                ######
                ######
                ###
                ###
             ######
             ######
        
    
    
             #########
             #########
          ###############
          ###############
          ###         ###
          ###         ###
       ######         ###
       ######         ###
       ######         ###
       ######         ###
          ######   ###
          ######   ###
             ###
             ###
        
    lab3.c - Hand written digit recognition agent
    linearMachine.c linearMachine.h - Linear Machine Solver
    backProp.c backProp.h - Backpropagation Neural Net
    split_stdin.c split_stdin.h - Line reader
    lab3.out - Training and testing performance
    The digits to the left are 8 x 8. They originally came from the NIST dataset (http://yann.lecun.com/exdb/mnist/).

    Can you identify them as 7 and 0? I only got 87% accuracy myself. The Linear Machine method converges much more quickly than the Neural Network.

    Back to top

    Free Cell Solitaire Player

    This solver is just using various simple search techniques, mainly iterative deepening. It really knows very little about the game itself. It knows what moves are legal, and has a sense of how close it is to a solution (heuristic), but it has no concept of strategy.

    The rules of Free Cell are simple. You can move any card to any empty Free Cell. You have to move cards in the right order to the Home Cells. E.g., 8 of hearts can only go on top of the 7 of hearts. Cards can only be moved on the board to cards one higher and different color. E.g., a red 7 can only go on a black 8.
    freecell.c - Game server agent
    freecell_solver.c - Plays the game
    state.c state.h - Generates moves, etc
    split_stdin.c split_stdin.h - Line reader
    idastar.c idastar.h - Iterative Deepening Search
    rand.c rand.h - Random number generator
    freecell_user.c - Allows person to play the game
    Interact.java - Manages server and player
    freecell.bat - How to compile and run
    freecell.out - Sample detailed output
    View Cards and see how they were cropped



    Back to top

    Steve's Spreadsheet

    Gonna put Microsoft Excel out of business with this one. Give it a try! Double click on a cell to create or edit a cell. Only a couple images are available: orca.jpg oryx.jpg and opah.jpg. It runs as an applet, so please be patient.

    TRY IT!
    Click here to run the Applet.

    Sorry, I don't want to publish the source code for this. It is all java and does not use JTable! It is still a work in progress, so the Save button does not work, for example.

    Back to top


    Solve Sudoku Puzzle #1

    Sudoku puzzles can be rather difficult to solve.

    The rules are simple. Each row, each column, and each 3 x 3 block must all have the digits 1 through 9 in them, with no duplicates. For example, look at the underlined blank in the Initial state, center row all the way to the right, just below the 9. It cannot be a 1 2 3 5 or 8 because of the other values in that row. Nor can it be a 2 6 8 or 9 because of the other column values. And 1 4 5 and 9 are already in the same 3 x 3 block. So the only remaining possible value is 7, as you can see in the Final state.

    TestSudoku.java - test program
    SolveSudoku.java - solving logic
    GridSudoku.java - grid representation
    RunSudoku.out - sample output
    Sudoku.bat - run it yourself
    Sudoku.jar - compiled code
    SudokuComplexity.xls - complexity analysis
    Initial state:
         9  6  .    .  2  3    .  .  .
         1  .  7    .  8  .    .  .  6
         .  .  .    .  .  6    7  5  2
    
         .  .  .    .  .  .    4  1  9
         8  .  3    1  .  2    5  .  .
         7  .  1    6  .  4    .  .  .
    
         .  3  .    .  .  .    6  9  8
         .  1  8    2  4  .    .  .  .
         .  .  .    3  6  .    .  2  .
    
    Puzzle solved!!
    Final state:
         9  6  5    7  2  3    8  4  1
         1  2  7    4  8  5    9  3  6
         3  8  4    9  1  6    7  5  2
    
         2  5  6    8  3  7    4  1  9
         8  4  3    1  9  2    5  6  7
         7  9  1    6  5  4    2  8  3
    
         4  3  2    5  7  1    6  9  8
         6  1  8    2  4  9    3  7  5
         5  7  9    3  6  8    1  2  4
    
    Elapsed time = 16 ms.

    Back to top

    Solve Sudoku Puzzle #2

    This solver uses a totally different approach. It uses logical theorem proving. For example, the assertion "square(1,1,3)" means there is a 3 in the top left corner. And "-square(x,y,1) | -square(x,y,2)" means you cannot have a 1 and 2 in the same cell. It uses a theorem prover called "prover9" to do the logical inferencing. And it also relies on some another program to communicate with prover9 (not listed here).

    sudoku.c - 4x4 solver
    sudoku9.c - 9x9 solver
    split_stdin.c - line reader
    split_stdin.h - line reader
    Makefile - make file
    sudoku4.out - detailed 4x4 output
    sudoku9.out - brief 9x9 output
    Initial state
    (4x4): 3 . | . . . . | . 1 -----+----- 2 . | . 4 . . | . .
    Final state
    (4x4): 3 1 | 4 2 4 2 | 3 1 -----+----- 2 3 | 1 4 1 4 | 2 3

    Initial state (9x9):
     .  3  .  |  4  .  .  |  .  9  5
     .  .  4  |  .  5  2  |  .  .  .
     8  .  .  |  .  .  .  |  7  .  .
     ----------+-----------+----------
     .  .  .  |  .  1  .  |  9  4  .
     2  .  .  |  .  .  .  |  .  .  7
     .  5  3  |  .  6  .  |  .  .  .
     ----------+-----------+----------
     .  .  2  |  .  .  .  |  .  .  6
     .  .  .  |  6  3  .  |  4  .  .
     3  4  .  |  .  .  7  |  .  8  .
    
    Final state (9x9):
     6  3  1  |  4  7  8  |  2  9  5
     9  7  4  |  3  5  2  |  1  6  8
     8  2  5  |  1  9  6  |  7  3  4
     ----------+-----------+----------
     7  6  8  |  2  1  5  |  9  4  3
     2  1  9  |  8  4  3  |  6  5  7
     4  5  3  |  7  6  9  |  8  1  2
     ----------+-----------+----------
     1  9  2  |  5  8  4  |  3  7  6
     5  8  7  |  6  3  1  |  4  2  9
     3  4  6  |  9  2  7  |  5  8  1
    

    Back to top

    Connect Digits with Operators to Find Numbers

    There are many ways to connect the digits 1 - 9 - 9 - 5. For example 1 + 9 + (9 - 5) is 14.

    This program connects four digits in various combinations until it has found all the numbers from 1 to 100.

    1995.c - source file
    1995.out - Sample output
    59 = ((1 + sqrt9) ^ sqrt9) - 5
    60 = (sqrt(1 * 9) + 9) * 5
    61 = 1 + ((9 + sqrt9) * 5)
    62 = (19 * sqrt9) + 5
    63 = (-19 * sqrt9) + 5!
    64 = 19 + (9 * 5)
    

    Back to top

    Weigh Balls to Find Which One is Heavy or Light

    Suppose you have 12 balls and a balance scale. You are informed that exactly one ball is either too light or too heavy. In as few weighings as possible, find which ball is the heavy (or light) one.

    This focus of this program is on displaying the logic alternatives.

    Weigh.c - source file
    Weigh.out - Sample output
    Let  A = {1..4}  B = {5..8}  C = {9..12}
      Case 1 : A < B   ==>   {1..4} light or {5..8} heavy.
      Let  D = {1, 2, 5}  E = {3, 4, 6}  F = {7, 8}
        Case 1.1 : D < E   ==>   {1, 2} light or {6} heavy.
          Case 1.1.1 : 1 < 2   ==>   1 light.
          Case 1.1.2 : 1 = 2   ==>   6 heavy.
          Case 1.1.3 : 1 > 2   ==>   2 light.
    

    Back to top

    Play MasterMind game

    This is a reasonable attempt at playing the game of MasterMind. It tries to make optimal guesses to increase its likelihood of getting a correct answer in as few guesses as possible.

    mm.c - source file
    mm.out - Sample output
    Guess 6 ->1 7 8 5
    Green = 0  Yellow = 2
    Since lost a Yellow, eliminate 1
    Try changing #4 from 5 to 2
    
    Green count is right digit, and right spot.
    Yellow count is right digit, but wrong spot.
    
    Back to top

    Paint Pictures from Counting Clues

    Start with an empty picture with say 15 rows and 10 columns. It has 150 cells, each of which is either on or off. Now you are given clues for each row and for each column that shows how many cells are on, but it does not tell you where. You must deduce them from the clues.

    Considerable effort was spent on explaining the reasoning. Take at look at the end of the output (paint.out) and see if you recognize the picture!

    Paint.c - source file
    paint.in - Sample input file
    paint.out - Sample output
    In column 5, cell 13 is 'off'.
    In column 7, no more unknowns, so 1 is 'on'.
    A small portion of column 8 is on (from 1 to 6).
    In column 9, no more unknowns, so 1 is 'off'.
    A small portion of column 10 is on (from 8 to 15).
    A small portion of row 1 is on (from 6 to 8).
    In row 1, no more unknowns, so 5 is 'on'.
    

    Back to top

    Logic Puzzle Solver

    If you have ever tried to solve a logic puzzle, you know they can be tough. This is a fairly general rule-based solver that was able to solve several dozen puzzles from a puzzle magazine I picked up at the grocery store. I didn't waste a lot of time on the user input; it is rather tedious. The focus is on the solution path and the careful explanations of all inferences.

    Logic.c - source file #1
    Rules.c - source file #2
    Logic.h - include file
    Cats.in - Sample input file #1
    Cats.out - Sample output #1
    Einstein.in - Sample input file #2
    Einstein.out - Sample output #2
    military.in - Sample input file #3
    military.out - Sample output #3
    Vacation.in - Sample input file #4
    Vacation.out - Sample output #4
    123. Order(White) <> Second because
            Position(White) = D and Order(D) <> Second
    124. Order(White) <> Third because
            Position(White) = D and Order(D) <> Third
    125. Color(Fifth) <> Black because
            Position(Fifth) = D and Color(D) <> Black
    126. Color(Fifth) <> B&W because
            Position(Fifth) = D and Color(D) <> B&W
    127. Position(Second) <> B because
            Position(Fluff) = Position(Second) + 1 (rule 15)
    128. Name(Ginger) = Suki by elimination;
            no other Name available
    129. Color(Suki) <> Black because
            Color(Suki) = Ginger
    130. Name(White) = Fluff by elimination;
            no other Name available
    131. Color(Bella) = Black by elimination;
            no other Color available
    132. Name(Fourth) = Suki by elimination;
            no other Name available
    133. Order(Suki) <> Second because
            Order(Suki) = Fourth
    

    Back to top

    Bridge Player

    This is the start of a bridge playing program. It has zero bidding and playing intelligence though. Someday ...

    It does know how to shuffle, deal, etc. It knows what bids are legal and what plays are legal. It also knows how to count points and how to keep score.

    Bridge.c - main source file
    Bridge.h - include file
    Display.c - source file for printing hands
    Bid.c - source file for bidding
    Play.c - source file for playing
    Score.c - source file for keeping score
              North (7+2=9)
              S: T 2
              H: A T 9 2
              D: 4 2
              C: K 9 6 4 3
    
    West (4+1=5)           East (13+2=15)
    S: 6 5 4               S: K Q 9 8 3
    H: Q 8 6               H: K 4
    D: J T 7 5 3           D: K Q 9 8
    C: J 5                 C: 8 7
    
             South (16+1=17)
             S: A J 7
             H: J 7 5 3
             D: A 6
             C: A Q T 2
    

    Back to top

    Calculate PI and E to Arbitrary Precision

    Once upon a time, in a land far away, I wanted to compute pi to several thousand digits. I thought it would be trivial for computers. Not so! Hence, I wrote a Basic program to do it. I have since written it in Pascal (here) and as a Java applet (where?)

    PI.pas - main program for PI
    E.pas - main program for E
    timer.p - timer routine
    arith.p - extended precision
    PIE.out - sample output
    Pi = 3.14159 26535 89793 23846 26433
           83279 50288 41971 69399 37510
           58209 74944 59230 78164 06286
           20899 86280 34825 34211 70679
           82148 08651 32823 06647 09384
           46095 50582 23172 53594 08128
           48111 74502 84102 70193 85211
           05559 64462 29489 54930 38196
    
    Back to top

    Symbolic Expression Evaluation (and Derivatives)

    Suppose you wanted your users to be able to type in equations or expressions, much like Excel. This program provides the capability for parsing and evaluating expressions. As a bonus, it can evaluate the symbolic derivative of an expression as well!

    transform.cpp
    transform.hpp
    transform_expression.hpp
    transform_parse.cpp
    transform_eval.cpp
    transform_operators.cpp
    transform_derivative.cpp
    transform_functions.cpp
    symbols.cpp
    symbols.hpp
    datetime.cpp
    datetime.hpp
    memory.cpp
    memory.hpp
    export.hpp
    status.hpp
    test_transform.cpp
    test_derivative.cpp
    tt.out - Sample output
    Worked: 1*2 + 3*4 is 14
    Worked: 10 * (1+2+3) / $sqrt(4) is 30
    Worked: 4 + y is 204    (note: y is your variable)
    Worked: 123 - 5 is 118
    Worked: "abc" < "abd" is 1
    Worked: "ab" + "cdef" + "g" + "h" is "abcdefgh"
    Worked: 1 < 2 < 3 <= 4 = 4 < 5 > 4 >= 4 > 3 <> 2 is 1
    Worked: $len ("abc") is 3
    Worked: $month (\6/5/2000 00:00:00\) is 6
    Worked: $minute (\6/5/2000 11:53:44\) is 53
    Worked: $delta (revenue, 2) is 80
    Worked: (u+1)^(v-1) * (u*$sqrt(u)*dv+v*du) is 40
    Failed, as expected:   ( 100  +  5
    Failed, as expected:  len('a','b')
    Derivative of sin(y) is $cos(y) * d!y!
    Derivative of sin(x)*cos(y) is
            $sin(x)*-$sin(y)*d!y! + $cos(y)*$cos(x)*d!x!
    Derivative of x^3 is 3 * x^2 * d!x!
    
    No transform errors.
    No memory errors or leaks detected (calls=613).
    

    Back to top

    Road Rage Simulation

    Road Rage is becoming a major problem today. People are spending more and more time waiting in traffic and at traffic lights. This simulation allows you to simulate traffic flows at a traffic light under three different light-changing strategies. The first strategy is simply fixed at 5 seconds per direction. The second is fairly realistic, keeping a light green as long as cars are still coming, up to 30 seconds maximum. The third strategy is based on a measure of "madness". The assumption is that one driver waiting ten minutes is madder than ten drivers waiting one minute. So lights change when another direction gets "madder". Try it!

    Stop.java - source file



    Run the Simulation!

    Back to top

    Toy Struts Application

    I wrote this little Struts / JSP application as a learning exercise. It runs on my home computer using jsp, struts, tomcat and eclipse.

    Idea is that there exists a database of audio and video files. Each file has a title and has been manually transcribed. A system is needed to search those files, looking for patterns in the titles or the transcriptions.

    Source CodeDescription
    index.jspStarting point for the toy application
    Welcome.jspFirst screen, to collect user input
    Results.jspSecond screen, to display results
    struts-config.xmlStruts configuration file
    MessageResources.propertiesProperties for display
    up.batUpdate files for Tomcat
    MyForm.javaForm bean for communicating between screens
    Query.java
    Medium.java
    AudioMedium.java
    VideoMedium.java
    My business logic. This is where the query is sent
    and where the results come from


    Sample data input screen

    Sample results screen,
    including some debug information
    Back to top

    Real Time Plant Control Software

    Real time process control is a very demanding application. Life would be relatively simple if processes started and ran forever with no disturbances, maintenance, schedule changes, etc. However, the only constant is change. There are quite a few commercial products available, such as Pavilion Technologies Process Perfecter, that handle dynamic control in a fixed environment. However, they run into serious difficulties when the model has to be changed. The purpose of the Orchronix software package is to control the software that controls the plant.

    The big picture of the Orchronix software is apply Business Process Management techniques to the real time control world. See for example, BPEL for Web Services.


    Here are some screen snapshots of the Java version of Orchronix. These are intended to demonstrate a typical application of formatting some data files, preprocessing them, and running models built from them.


    Data File Formatter

    Data Preprocessor

    Run One Model

    Alternate Models

    These screen snapshots are from the .Net version of Orchronix. It shows more detail of the Formatter shown above. One would normally progress through these screens in order.


    File Editor

    Format Columns

    Format Rows

    Verify Format

    Sample output while running Orchronix application:

    Sample log file while running Orchronix application:

    Back to top


    Other Stuff

    12_Days.cTwelve Days of Christmas
    GrayScale.javaConvert an image to grayscale
    Snooper.frmSnoop through Yahoo and eBay auctions
    FromEnd.csFind fifth element from the end of a list
    MainScraper.javaScreen Scraper
    TreeCheck.javaSee if a tree is well-formed, part 1
    MyTree.javaSee if a tree is well-formed, part 2
    TreeCheckTest.javaSee if a tree is well-formed, part 3
    transform.cpp
    Back to top
    Last Updated on 11/18/07 Email: steve@oharasteve.com