• About Me
  • Blog
  • Home

Eric Hokanson

~ E's little space in cyberspace

Eric Hokanson

Tag Archives: Computer science

The Value of Algorithmic Problem Solving: A Demonstration

20 Friday Mar 2015

Posted by Eric Hokanson in Algorithms, Computer Science

≈ Leave a comment

Tags

Algorithms, Computer science, magic squares, problem solving

Algorithmic problem solving is a very useful skill to develop.  Once such source you can learn and practice these skills is [1].  Allow me to illustrate with an example with puzzle #29, p. 39 from [1]:


 Magic Squares

A magic square of order 3 is a 3×3 table filled with nine distinct integers from 1 – 9 so that the sum of the numbers in each row, column, and corner-to-corner diagonals is the same.  Find all the magic squares of order 3.


 

image1According to the tutorial on p. 4 of [1], solving this problem is not difficult if we can prove that the common sum must be 15 and that 5 must be placed at the center square.  We should start with these two hints and see where that knowledge takes us.

1.  What should be the common sum?  We have nine distinct integers: 1, 2, 3, …, 9, of which, each sum is a combination of three of those distinct integers.  The sum of the digits 1 to 9, i.e. 1 + 2 + 3 + … + 9 = 45.  Since we are only using three of the digits to form our sum for each row, column, and the diagonals, we divide 45 by 3: 45/3 = 15.  Hence the common sum of any of the three squares — rows, columns, and diagonals — must be 15 because the total sum of all nine digits in the magic square will be 45.

2. Which integer should occupy the center square to get an optimal sum of 15 using the remaining integers?

image2 Start with 9: if 9 occupied the center square, then an 8 will have to occupy any one of the eight remaining boxes.  The sum of 8 + 9 = 17 and 17 > 15 so that won’t work.  The same problem occurs if 8 occupies the center square because a 9 must occupy one of the remaining boxes adjacent to the 8.

Let x, y, and z be any one of the distinct integers in the set of consecutive integers 1 through 9.  We need x + y + z = 15.  Observe that x+y = 15 – z, x+z = 15 – y, and y+z = 15 – x.  Since addition is commutative, x+y = y+x, x+z = z+x, and y+z = z+y.  Hence, x+y < 15, x+z < 15, and y+z < 15.  Since 9 cannot occupy the center, that means 9 will occupy any of the remaining squares, which means x+9 < 15* for all integers in the set of consecutive integers from 1 to 8.  The first such integer to satisfy this condition is 5, i.e. 5+9 = 14 < 15.  Hence, 5 must occupy the center square.

Given our new constraint, we know that 1+5+9 = 15:

image3

image4What about the diagonals?  Say we had the arrangement on the left.  Take the rows containing the 1: x+y+1 = 15.  The only remaining digits to satisfy the equation have to be 6 and 8, i.e. 6+8+1 = 15.  Note that the 6 or the 8 would wind up in the same row as the 9.  In either case, 8+9 = 17 > 15 and 6+9 = 15 leaving the remaining square unfillable.  Given the symmetric nature of squares, we can reason that none of the diagonal 1,5,9 combinations will work.  Given our further constraint, this reduces the possible partially filled squares to one of the four above, which I have labeled (a), (b), (c), and (d).

In the case of (a): for the row containing the 1, our only options are the digits 6 and 8 to make the 15.  These can be placed in either combination:

image5

The remaining digits can then be uniquely positioned to create our magic square.

For case (b), given the symmetric properties of squares, we can obtain our solutions by swapping the top and bottom rows from our solutions to case (a):

image6

Case (c) can be constructed in a similar fashion to case (a):

image7

And again using the symmetry of squres, we can take the case (c) solutions by swapping the first and third columns to obtain a solution for case (d):

image8

for a total of 8 magic squares of order 3!

Q.E.D


What I learned by solving the magic square puzzle:

To exhaustively search all possible 3×3 tables by placing a 1 in one of the possible nine locations, a 2 in any of the possible eight locations remaining, a 3 in any of the possible 7 locations left, and so on, means the total possible combinations would be:

9! = 9x8x7x…x1 = 362,880

ways to arrange the 9 numbers in a 3×3 table.  That is an undaunting task to generate all 362,880 tables checking if the result of our arrangements yields a magic square.  Considering that we just learned there are only 8 such squares of order 3, that is a lot of wasted work.

In order to improve our exhaustive search, we tried constraining our problem to help reduce the search space.  One such discovery was the invariant of the common sum of 15.  This invariant was helpful in allowing us to smartly construct magic squares that fit the constraint.

We further reduced our search space by discovering another invariant: that 5 must always occupy the center square.  Given these two invariant properties, we were able to quickly and smartly reason all the possible magic squares of order 3 without having to waste our time constructing and examining the 362,872 squares that did not fit the constraints.

Bottom line:  Invariants are incredibly useful in problem solving and programming.  Finding an invariant can reduce intractable exhaustive search problems and ensure that our solutions are correct.  The recognition of invariants is an important problem solving skill.  Possibly the most important.


* Note that 9 could be x, y, or z but the results from any of the inequality relationships will be the same.  Therefore, we will show the x+9 < 15 relationship but our “proof” will hold with any of the three inequality relationships.

References

[1] Algorithmic Puzzles, Anany Levitin, Maria Levitin, Oxford University Press, Inc., New York, NY, 2011

To Learn to Code or Not

29 Sunday Dec 2013

Posted by Eric Hokanson in Programming

≈ Leave a comment

Tags

Code, Computer science, Education, Learning, programming

There has been a lot of discussion lately on the importance of learning to code.  And I have added my two-cents.  Maybe three.

Here is an interesting opposing viewpoint: You don’t need to learn to code and other truths about future careers.  It is the only opposing view I have seen so far.  The author argues that coding is not for everybody.  If you hate coding, then forcing yourself to learn just to stay competitive in the job market, would be a miserable way to go.  And you are not likely to be successful in a job you hate.

Secondly, learning to program just to launch a career change is likely to end in frustration.  Going from no programming experience to a programming job, while not unheard of, is rare.  Many tech companies today have a grueling application process requiring you to demonstrate proficiency and that takes years to master.  Up to 10 years in some studies I have seen.

It is always good to hear the other side of an argument.  Learning to program may not be great career advice.  However, what is the harm in learning for fun?  For your own personal benefit?  Programming is not some big mysterious skill that can only be done by a few hoodie clad brainy types.  Anyone can learn to code and some languages are remarkably easy pick up.  While it may take a decade for mastery, the fundamentals can be picked up in as little as a few weeks.  And you can create some amazing things almost right away.  There is no reason not to try your hand at programming.  See if you like it.  Creating your own web-sites or apps can be fun even if no one ever sees your creations.

To actually learn how to think. I think everyone in this country should learn to program a computer. Everyone should learn a computer language because it teaches you how to think. I think of computer science as a liberal art.

Steve Jobs from the lost interviews

Speaking from personal experience, programming has sharpened my problem solving skills and it will sharpen yours too.  Becoming a better problem solver is a skill that will benefit everyone.  No matter the job market situation: if you can solve problems then you will always have a job.  The market is already flooded with people that cause problems, but we could always use a few more problem solvers.

Related articles
  • Don’t Waste Your Break! Learn Something!! (drkblog.wordpress.com)
  • Learning Code – Keep on Trekking (codemoms.wordpress.com)

The Father of Computing Pardoned!

24 Tuesday Dec 2013

Posted by Eric Hokanson in Alan Turing, Computer Science

≈ Leave a comment

Tags

Computer science, List of important publications in computer science, Turing

Alan Turing finally received an official pardon.  You can read all about it here.  It is a

The Father of Computing

long time coming, if you ask me.  I am not going to debate the whole sexual orientation thing here.  That is not my purpose today.  Lord knows we have enough debate from both sides thanks to the spate of state supreme court rulings — oh, and that duck dynasty guy.  Nope.  The Alan Turing I know was a profound thinker and ahead of his time.

I first learned of Turing as an undergrad CS major at FSU.  My interest was in cryptology and Turing made some innovative contributions to cryptanalysis during WWII.  It is a fascinating story and I recommend you check it out.  The Code Book by Simon Singh gives a good account to Turing’s thought process and how he was able to think outside the box transforming a seemingly insurmountable problem into a surmountable one.

My real appreciation of Turing’s genius was as a graduate student.  At FSU, grads are required to take an academic reading and study group.  We read seminal papers from the founding fathers of computer science and Alan Turing’s paper, “On Computable Numbers” was one of them.  I was very surprised how easy the paper was to read (well, once you wrapped your head around the Gothic Germanic notations used for set theory, but Turing explains what the notations mean in subsequent paragraphs); Turing’s paper should be on any aspiring CS major’s reading list.  Or pick up this book for a guided tour.  The author does a terrific job breaking down the paper, paragraph by paragraph, and explaining the concepts.

In the paper, Turing communicates his ideas to me as if I was a peer; not as a superior.  Although he was already an accomplished mathematician by the time of his publication and worthy of respect in academia, Turing does not come off sounding like an academic know-it-all.  I never felt like he talked down to me in his paper.  His communication style struck me as, “I have something interesting to share.  Let me tell you about it.”  Turing was able to map the concept of computing to a mathematical system — set theory in this case — and then use the laws and rules of that system to demonstrate its power and its limitations.  That’s right — computers can not solve all of our problems!  However, had it not been for Turing’s work, and the work of others, such as John Von Neumann, the computing devices you and I depend on today may never have existed.  This paper was published in 1936!  The integrated circuit wasn’t even dreamt of yet.

In 1952, Turing was convicted on indecency charges and subjected to treatments that would be considered discriminatory or unjust by today’s standards.  Socially and scientifically, Alan Turing was a man ahead of his time.  We can still learn a great deal from him.

To me, an individual’s sexual orientation or background doesn’t matter.  What matters is what you do.  Deep inside ourselves, we all have, thanks to a complicated morass of environment and upbringing, beliefs on religion, sexuality, ignorance and prejudices.  Deep down we are all flawed.  But if we can rise above our internal strife and accomplish things to improve the human condition, then that is a win.  History is full of examples of humans doing great good and inflicting great evil.  I believe it is a matter of personal choice as to which occurs.  Ironically, that is what separates us from the computer.  We can break free from our programming.

Quine Quandary

23 Monday Dec 2013

Posted by Eric Hokanson in Computer Science, Philosophy, Quine programs

≈ 1 Comment

Tags

C, Computer science, programming, Python, Quine

While at a Christmas party, I met a Computer Science undergrad currently earning his degree at UNM.  He was having trouble grappling Quine programs.  A Quine program is a computer program that takes in no input, and produces a copy of its own source code as the only output.  That is — self-replicating code.  It is not as easy to explain as one might think, and my poor crude attempts at doing so only confused this poor CS student further.  To my defense, I used examples you can find online, but many of these examples are not very intuitive to understand.  Take for example this Quine written in Python:

s='s=%r;print s%%s,';print s%s,

Fire up a Python interpreter and try it out. It simply prints that exact line you typed in.  Unless you are very familiar with Python strings and the string formatting codes, it is hard to see how this program works.  But it is essentially, defining a string s, then using that string itself to replicate.  Here is a Quine written in the old Kernigan and Ritchie C style:

main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}

I don’t believe it will compile with today’s C99 or better compilers, which don’t allow programmers to implicitly call the printf function with out using:

#include <stdio.h>

Again, the C program is not any more intuitive to understand than the Python example.  So today, my goal is to write a Quine program in C that is easier for me to explain by example.  Instead of using printf format strings, I am going to leverage the power of a computer’s ability to represent C source code as data.  The goal is to take the data representation of the source code and print it, then translate the data into the ASCII high-level source code and print that.  After some trial and error, here is what I came up with:

#include <stdio.h>

int
main (void)
{
    unsigned int i;

    printf("const unsigned char data[] = {");
    for (i = 0; i<sizeof(data); i++)
    {
        if (i%8 == 0)
            printf("\n");
        printf("%0#4x,", data[i]);    
    }
    printf("\n};\n\n");
    for (i = 0; i<sizeof(data); i++)
        putchar(data[i]);
    return 0;
}

The above is my partial program so far.  There are two for-loops.  The first loop will iterate through a byte array called data, which I have not defined yet because this data array will contain the hexadecimal representation of this ASCII code (i.e. everything from the #include to the last right curly-brace at the bottom).

The second for-loop takes that same data array and uses the C library putchar that will translate the hexadecimal representation into an ASCII character, which will give us all that C code from the #include to the last right curly-brace at the bottom.  In other words: this source code will print an exact copy of the data array and our source code when executed.

Next, we need to translate our C code into the byte array data and place it at the top of our program (before the #include statement in the source above).  It should look like this:

const unsigned char data[] = {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x74,0x64,0x69,0x6f,0x2e,
0x68,0x3e,0x0a,0x0a,0x69,0x6e,0x74,0x0a,
0x6d,0x61,0x69,0x6e,0x20,0x28,0x76,0x6f,
0x69,0x64,0x29,0x0a,0x7b,0x0a,0x20,0x20,
0x20,0x20,0x75,0x6e,0x73,0x69,0x67,0x6e,
0x65,0x64,0x20,0x69,0x6e,0x74,0x20,0x69,
0x3b,0x0a,0x20,0x20,0x20,0x20,0x0a,0x20,
0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,
0x66,0x28,0x22,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,
0x64,0x20,0x63,0x68,0x61,0x72,0x20,0x64,
0x61,0x74,0x61,0x5b,0x5d,0x20,0x3d,0x20,
0x7b,0x22,0x29,0x3b,0x0a,0x20,0x20,0x20,
0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x20,
0x3d,0x20,0x30,0x3b,0x20,0x69,0x3c,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x64,0x61,
0x74,0x61,0x29,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x69,0x66,0x20,0x28,0x69,0x25,0x38,0x20,
0x3d,0x3d,0x20,0x30,0x29,0x0a,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x66,
0x28,0x22,0x5c,0x6e,0x22,0x29,0x3b,0x0a,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x70,0x72,0x69,0x6e,0x74,0x66,0x28,0x22,
0x25,0x30,0x23,0x34,0x78,0x2c,0x22,0x20,
0x64,0x61,0x74,0x61,0x5b,0x69,0x5d,0x29,
0x3b,0x20,0x20,0x20,0x20,0x0a,0x20,0x20,
0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,
0x70,0x72,0x69,0x6e,0x74,0x66,0x28,0x22,
0x5c,0x6e,0x22,0x7d,0x3b,0x5c,0x6e,0x5c,
0x6e,0x22,0x29,0x3b,0x0a,0x20,0x20,0x20,
0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x20,
0x3d,0x20,0x30,0x3b,0x20,0x69,0x3c,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x64,0x61,
0x74,0x61,0x29,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x70,0x75,0x74,0x63,0x68,0x61,
0x72,0x28,0x64,0x61,0x74,0x61,0x5b,0x69,
0x5d,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,
0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,
0x3b,0x0a,0x7d,0x0a,
};

Now, how did I get the above?  Well, we can use an ASCII table and transcribe our C source above by hand… # = 0x23, i = 0x69, n = 0x6E, c = 0x63, l = 0x6C, u = 0x75, d = 0x64, e = 0x65, spaces = 0x20, newlines = 0x0A, etc.  That is a lot of work.  Being a lazy computer scientist, I wrote the following python script to do it for me:

import sys

f = open(sys.argv[1], 'r')

s = ''
for line in f:
    for l in line:
        s += '0x%02x' % ord(l)
        s += ','

s += '0x0a,'
step = 40
for i in range(0, len(s), step):
    line = s[i:i+step]
    print line

In the above, you pass in the C file of our first code listing above, and it prints to the screen:

0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x74,0x64,0x69,0x6f,0x2e,
0x68,0x3e,0x0a,0x0a,0x69,0x6e,0x74,0x0a,
0x6d,0x61,0x69,0x6e,0x20,0x28,0x76,0x6f,
0x69,0x64,0x29,0x0a,0x7b,0x0a,0x20,0x20,
0x20,0x20,0x75,0x6e,0x73,0x69,0x67,0x6e,
0x65,0x64,0x20,0x69,0x6e,0x74,0x20,0x69,
0x3b,0x0a,0x20,0x20,0x20,0x20,0x0a,0x20,

<-------snipped----------------------->

0x28,0x64,0x61,0x74,0x61,0x29,0x3b,0x20,
0x69,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x70,0x75,0x74,
0x63,0x68,0x61,0x72,0x28,0x64,0x61,0x74,
0x61,0x5b,0x69,0x5d,0x29,0x3b,0x0a,0x20,
0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,
0x6e,0x20,0x30,0x3b,0x0a,0x7d,0x0a,

You can copy and paste that into your

const unsigned char data[] = {

},

block and put that above the #include of the first code listing above.  I used Eclipse-C++ to code and run my program.  Upon execution the program should print to the console:

const unsigned char data[] = {
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
0x20,0x3c,0x73,0x74,0x64,0x69,0x6f,0x2e,
0x68,0x3e,0x0a,0x0a,0x69,0x6e,0x74,0x0a,
0x6d,0x61,0x69,0x6e,0x20,0x28,0x76,0x6f,
0x69,0x64,0x29,0x0a,0x7b,0x0a,0x20,0x20,
0x20,0x20,0x75,0x6e,0x73,0x69,0x67,0x6e,
0x65,0x64,0x20,0x69,0x6e,0x74,0x20,0x69,
0x3b,0x0a,0x20,0x20,0x20,0x20,0x0a,0x20,
0x20,0x20,0x20,0x70,0x72,0x69,0x6e,0x74,
0x66,0x28,0x22,0x63,0x6f,0x6e,0x73,0x74,
0x20,0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,
0x64,0x20,0x63,0x68,0x61,0x72,0x20,0x64,
0x61,0x74,0x61,0x5b,0x5d,0x20,0x3d,0x20,
0x7b,0x22,0x29,0x3b,0x0a,0x20,0x20,0x20,
0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x20,
0x3d,0x20,0x30,0x3b,0x20,0x69,0x3c,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x64,0x61,
0x74,0x61,0x29,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x69,0x66,0x20,0x28,0x69,0x25,0x38,0x20,
0x3d,0x3d,0x20,0x30,0x29,0x0a,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x70,0x72,0x69,0x6e,0x74,0x66,
0x28,0x22,0x5c,0x6e,0x22,0x29,0x3b,0x0a,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x70,0x72,0x69,0x6e,0x74,0x66,0x28,0x22,
0x25,0x30,0x23,0x34,0x78,0x2c,0x22,0x20,
0x64,0x61,0x74,0x61,0x5b,0x69,0x5d,0x29,
0x3b,0x20,0x20,0x20,0x20,0x0a,0x20,0x20,
0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,
0x70,0x72,0x69,0x6e,0x74,0x66,0x28,0x22,
0x5c,0x6e,0x22,0x7d,0x3b,0x5c,0x6e,0x5c,
0x6e,0x22,0x29,0x3b,0x0a,0x20,0x20,0x20,
0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x20,
0x3d,0x20,0x30,0x3b,0x20,0x69,0x3c,0x73,
0x69,0x7a,0x65,0x6f,0x66,0x28,0x64,0x61,
0x74,0x61,0x29,0x3b,0x20,0x69,0x2b,0x2b,
0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x70,0x75,0x74,0x63,0x68,0x61,
0x72,0x28,0x64,0x61,0x74,0x61,0x5b,0x69,
0x5d,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,
0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x30,
0x3b,0x0a,0x7d,0x0a,
};

#include 

int
main (void)
{
unsigned int i;printf("const unsigned char data[] = {");
for (i = 0; i<sizeof(data); i++)
    {
        if (i%8 == 0)
            printf("\n");
        printf("%0#4x," data[i]);    
    }
    printf("\n"};\n\n");
    for (i = 0; i<sizeof(data); i++)
        putchar(data[i]);
    return 0;
}

You should be able to copy and paste the print out into an IDE, compile and run it.  Quines are pretty neat.  I enjoyed this little exercise.  It made me think about levels of meaning; about values and their representations.  Computers and programs can’t differentiate between data and code.  It is the context that determines when data is meant to be interpreted as code instead of data, and when code is meant to be data (e.g. when downloading a binary file from the Internet).  This is an important concept in computer security.  It is the fact that we can use data as code that makes shellcode exploits possible.

“Yields falsehood when preceded by its quotation” yields falsehood when preceded by its quotation.

–Quine’s paradox

Computer Science Education Week December 9 – 15

07 Saturday Dec 2013

Posted by Eric Hokanson in Computer Science, Learning, Programming

≈ 1 Comment

Tags

Computer science, Newton's method, programming, Python, Square root

Teaching students programming and computer science one hour of code at a time.  Here is the official site where you can learn how to become involved.   I thought I would take an opportunity here to make my contribution.  In this lesson, I will use as my guide, a great introductory to Computer Science (CS) text, often referred to as the “purple” book, or the “wizard” book.

What is Computer Science?

Computer science is really a misnomer.  It is not a science.  We don’t study a system, observe phenomena, and run experiments to validate a hypothesis.  Computer science is not a study of computers anymore than biology is the study of microscopes.  A computer is simply a tool.  And computational devices come in many different forms.  There are the silicon-based binary gadgets that you use everyday, like laptops, tablets, and smart phones.  But they are poor imitations of the most powerful computing device ever created: the human being.  We are a bio-mechanical machine, performing our computations in base 10.  And of course, we are capable of much, much more.

Declarative and Imperative Knowledge

Computer science is not a science; it is more of an art — an engineering practice.  Computer science is really about knowledge.  The knowledge of how to do something: solve a problem, perform a task in a methodical, mechanical process.  This process is called imperative knowledge.  It is the knowledge of how to do something.  Declarative knowledge, on the other hand, deals with the facts.  Let me illustrate with an example found in the purple book.

Example: Square Roots by Newton’s Method

An example of declarative knowledge:

The above is a fact about square roots.  You can find it in any basic math text.  In words: the square root of any number x, is a number y, where y is a positive number, and if I multiply y by itself.  I get x.  For example: let x be 4, then y must be 2 because 2 times 2 equals 4.  You can reason the same for 16, or even 625.  Larger numbers are harder.  You may have to make some educated guesses before you stumble upon the correct answer.
Well, that is all fine and dandy.  But what if you were given: \sqrt{2} ?  How can we use the above declarative knowledge to figure that out?  And that is the problem of declarative knowledge.  It doesn’t tell you how to calculate the square root of 2 — or how to find the square root of any number.  The declarative statement can only tell you how to recognize a square root if you saw one.

Newton’s Method

To solve the square root of any number, we will use a very old algorithm called Newton’s method.  Ironically, the method starts with a wild-ass guess (a WAG, we call it in the scientific and engineering community).  Then we refine our guess with successive approximations until we get to an answer that is good enough for government work.  Let’s construct our algorithm based on Newton’s method:

To find the approximation of the square root of x:

  1. Make a guess G
  2. Improve guess G by averaging G and x/G
  3. Keep improving until the guess is good enough.

Simple, right?  Don’t take my word for it.  Try it out.

table

Compare the 1.4142 with your calculator’s square root button.  You should see the 1.4142 plus a bunch of other numbers.  We solved out to four decimal places (to the 10-thousandths place), and that is good enough for us.

Now let us write this out as a recipe of instructions:

Square Root X:

  1. Make a guess G
  2. Is it good enough?:  absolute_value(G*G – X) < 0.0001 then G is the answer and we can stop; otherwise go to next step
  3. Improve guess G: G = (G + X/G)/2
  4. Repeat step 2.

So let’s step through our recipe.  First make a Scientific Wild-ass Guess.

Next we test our guess by, first squaring our guess and subtracting that guess with X.  We take the absolute value because your guess may be less than the square.  For example, in the square root of 2, our first guess was 1.  1 – 2 = -1 and we don’t want a negative number because we are measuring the distance between our guess and the perfect square X.  And since negative distances don’t make sense, we take the absolute value, which means we first remove the negative sign, and then see if the answer is within some threshold of tolerance.  In this case, less than one-ten-thousandths.  Or put another way, we will keep refining our guesses until we calculate the square root to four decimal places.  If our guess is less than our threshold, then we stop and G is our answer.  If not, we go to step three to improve our guess and repeat the process.

Try our recipe above out with a piece of paper and a calculator and see if you get the same results as in the table above, if you let X = 2.

If you made it this far, my dear reader, I want to congratulate you.  Together we wrote a computer program.  Our program is not in a traditional computer language like C, or C++, or even Python.  But it is in the language of English and math.  Any reasonably intelligent human computer, with some knowledge of middle school, or high school math should be able to follow our recipe (algorithm) and effectively become the square root button on a calculator.

I hope the above example gives you an idea of what programming and computer science is about.  Now, if you really want to learn a programming language, first pick a language and a site you can learn from.  I recommend code academy and the language of Python.  Python is very easy to learn.  Once you get the basics and the syntax down, see if you can take our little recipe above and translate it into your new language, and get a computer to do all this hard math stuff for us.

Related articles
  • Bubble Name Animation (devguy.co)

What Every Computer Scientist Should Know

26 Tuesday Nov 2013

Posted by Eric Hokanson in Computer Science

≈ 2 Comments

Tags

Computer science, Discrete mathematics, Joel Spolsky, Sandia National Laboratories

I have the pleasure of being a part of Sandia National Laboratories (SNL) College Cyber Defenders (CCD) program.  I have been conducting some of the phone interviews for next summer’s program already.  During the interview, I give each prospective student a chance to ask me any question they want.  “This is your phone interview”, I tell them.

Lately, in addition to the usual questions you would expect, several have asked: “What should a CS student know to be successful at Sandia?”  This is a good question to ask — and not just for the labs but for any research position or job in academia, government, and private industry.

I began wondering: “is my advice too narrow?  I know what is useful in my current research interests and duties, but what about generally?”  What is a good core set of skills that a graduating, eager CS degreed individual entering the work force can build upon in order to have an awesome career before real life crushes their aspirations like an empty beer can?

Using my favorite research tool, I began googling to see what others felt about the subject.  Naturally, everyone has their two cents: what computer science concepts should I know?  However, I stumbled upon this from Joel Spolsky.  Here is another from an academic.  The latter’s list is pretty long; I would focus on the top of the list; the further down, the more specialized the skills become.  Besides, trying to master all of them may take you longer than you have life left.

the lyf so short, the craft so long to lerne.

Chaucer (1340-1400)

Spolsky’s advice is more succinct and do-able.  Learning to write is a great skill for CS and non-CS alike.  If you can not describe, in a page or paragraph, to a reasonably thinking human being what your program is supposed to do, then how do you possibly hope to tell a machine how to do it?  In fact, you don’t need to learn a programming language to learn how to program.  English will work just nicely.  Let another human being be the “compiler/interpreter” and see if they perform the task(s) you described.  If they seg-fault and core dump, they can explain in plain English your error far better than some of the cryptic compiler errors you will encounter.

I would add one more skill to the list: don’t blow off discrete mathematics because its hard.  Discrete math is often called, “math for computer scientists.” for a reason. Time and again you will use the core concepts, combining them, building upon them to design algorithms to solve some of today’s most challenging and interesting problems.  If you want to get in on the Big Data craze everyone is raving about, you will need discrete math.

Of course, dispensing advice is easy so I am going to put my money where my mouth is.  Here’s my story: two years ago, I was at a cross-roads in my career.  I was looking for ways to improve my technical skills.  I thought long and about it.  My time is limited and I am a pretty lazy.  I can’t improve every skill at once, but if I could improve one technical skill that would have the most positive impact in my CS career, what would that be?  I chose to re-study discrete mathematics and I am glad I did.

By the way, if your discrete math (DM) class is not using this text, run — don’t walk — run to your nearest book store and get yourself a copy.  Its worth the heady sticker price and it is pretty verbose, but verboseness is good in this case.  The author does an excellent job of explaining the concepts and not pulling any of that “proof is up to the reader” crap so many other DM texts employ.  I used this text in the course of my personal re-study.  It took me about 9 months to get through it cover-to-cover and it was the best thing I ever did for myself.  The text has plenty of exercises; do them and you will walk away understanding the concepts.

I don’t know what’s the matter with people: they don’t learn by understanding, they learn by some other way — by rote or something. Their knowledge is so fragile!

Richard P Feynman (1918 – 1988)

The most profound lesson I discovered is that DM is learning how to communicate in the language of mathematics.  It is a lot like English composition, except the syntax and statements involve logic and mathematical thought, you learn how to write by writing essays.  Lots of essays.  In DM you write proofs.  Lots of proofs.  I found that doing proofs was similar to writing programs — especially inductive proofs.  It is not a coincidence that programming languages are modeled after mathematical statements, structures, and objects.  I know my study of DM has made me a better software developer.

So study your discrete mathematics, kids, and who knows what you will be able accomplish.  Check out what some supposed CS  people did with their discrete math knowledge below.  I leave the proof up to you, my dear reader 😉

Related articles
  • Computer Scientists Prove God Exists (canadasblog.wordpress.com)
  • Computer Scientists “Prove” God Exists (downtrend.com)

Subscribe

  • Entries (RSS)
  • Comments (RSS)

Archives

  • May 2016
  • May 2015
  • April 2015
  • March 2015
  • September 2014
  • August 2014
  • June 2014
  • May 2014
  • April 2014
  • March 2014
  • February 2014
  • January 2014
  • December 2013
  • November 2013

Categories

  • Alan Turing
  • Algorithms
  • Apollo 17
  • C Programming
  • Christmas
  • Computer Programming
  • Computer Science
  • Computer Security
  • Current Events
  • Cyber Security Research
  • Education
  • Freedom of choice
  • Freewill
  • Hacking
  • Holidaze
  • Learning
  • Malware RE
  • Math
  • NASA
  • Pen-testing
  • Philosophy
  • Pi Day
  • procrastination
  • Programming
  • Python
  • Quine programs
  • Quotes
  • Random Stuff
  • Research
  • Reverse Engineering
  • Shopping
  • Smithsonian National Air and Space Museum
  • Software Development
  • Star Wars
  • Success
  • Uncategorized

Meta

  • Register
  • Log in

Blog at WordPress.com.

  • Follow Following
    • Eric Hokanson
    • Join 44 other followers
    • Already have a WordPress.com account? Log in now.
    • Eric Hokanson
    • Customize
    • Follow Following
    • Sign up
    • Log in
    • Report this content
    • View site in Reader
    • Manage subscriptions
    • Collapse this bar
 

Loading Comments...