Technology, and poor parenting is making people soft

After more than three decades dealing with technology, it is more apparent than ever that technology is likely the leading cause of stupidity in the world today. I mean it all seemed like a good idea – we should have known it wouldn’t be the utopia many thought it would. Many of the things people said it would do just haven’t panned out to be that good. It would honestly be better if it were more of a sidelined technology, but it has reached far too deeply into our lives, and honestly created a lot of junk along the way. Oh, it was done with good intention… I guess. Sure we can access a lot of information on the net, and buy things from anywhere in the world. But that’s not really any form of utopia. Technology has made things more efficient, and allows us to carry a computer and camera in our pocket… but many days I wonder if it was all worth it. Lot’s of benefits, many limitations.

The limitations are ones which are starting to effect the psyche of younger generations. Too much screen time, too little ability to think without a machine, an inability to read, and no aptitude for the simplest math. Problem solving? forget it. Children should be outdoors, building tree houses, and doing the things that we did as Gen-Xers. You were out there in nature all day long, doing whatever was to be done – building things, or just goofing around. When you went camping you usually carried a knife of some sort and the skills to start a fire if needed. You taught yourself things, and drank water from outside taps. You applied your own first-aid if you just happened to rip all the skin off your knee when you came off your bike. There was no technology, I guess unless you were lucky enough to have one of the first “game” machines, which few people did. Technology was a Meccano set, or Lego. Playgrounds were made of steel, which burned a damn sight more than the elvish rope that burned Gollum – and we still played on them. With no internet you spent time indoors reading – I mean what were you going to watch on four TV stations (hint, the original or just about every remake now).

Sure, times were different, but we also didn’t have many kids with allergies, or so many people with mental health issues, or anxiety. If Gen-X-ers have anxiety now, it’s likely because of society around us. Look, life would likely be simpler if we got rid of most of the garbage on social media, and limited children’s access to all the nonsense. Kids don’t really need to be online. Kids also don’t need to be gaming. Game addiction is a disease which I first saw as an undergrad in the 1980s… only in those days I watched kids get addicted to stupid games like Larn and Rogue. Too many kids these days, especially boys spend their lives playing games in basements… and then their parents wonder why they can’t cope with the outside world. Of course schooling hasn’t helped any either – few if any kids get low grades in any subject in school anymore. If you never fail anything, you tend to grow up thinking you are good at everything – but the reality of course is quite different.

Technology has made people too soft. Too soft to work, too soft to do assignments, too soft to deal with the notion of failure in any form. We have spent far too long giving out prizes to everyone, and never even considering the consequences. There is only one winner in a 100m race. Of course this is made worse by these aloof parents, call them what you want – snowplow, helicopter, bulldozer, lawnmower parents – it doesn’t matter, it all means the same thing – a parenting style that seeks to remove all obstacles from a child’s path so they don’t experience pain, failure, or discomfort. Nice. Let’s hope there are some portion of kids that are actually brought up in some sort of reality.

Computer versus natural language

How many people think about how programming languages differ from natural ones? Natural languages work very well for human to human communication, however there are very few programming languages that are truly natural language based.

There are three main differences between natural languages and programming languages:

Complexity

The English language is complex. The Oxford English Dictionary contains over 600,000 words – the average person is lucky to have a knowledge base of 40,000.

Ambiguity

Many words have different meanings. For example below the word saw means “a hand tool to cut wood”, “the act of using a saw”, and to discern or perceive”.

He saw the man in the park with a telescope.

Did the man have the telescope, or did the park have the telescope? Or did he use the telescope to see the man in the park? Ambiguity in the context of natural languages is resolved through the context of the dialogue. Programming languages should have the trait of non-ambiguity.

Context freeness

But words put together into sentences can be even more ambiguous.

He put the book on the table.
She used a table of logarithms.

There are two meanings of the word table. It depends on the context of table, i.e. its neighbouring words. Programming languages should be context-free.

Semantic interpretation

When learning a natural language, one understands that they are used for communication with other human beings. Learning the language is enough, e.g. maison is French for house. In German, the word for carrot is Karotte. In Swiss-German, the word is Rüebli. Learning a programming languages requires an understanding of the machine.

Sorry, image processing is NOT a sub-field of AI

One thing I really don’t like is when AI people classify image processing as a subcategory of AI. Here’s the thing, it isn’t. Sure, it could be used as an applications realms for AI, but they are not sub-fields of AI. Image processing is just processing images using algorithms. Image processing is the manipulation of a digitized image, often to improve its quality (and is different to image analysis). Image processing evolved from the work done on processing images from NASA’s 1960’s lunar probes, and is ultimately derived from signal processing. No AI involved.

Image processing algorithms can be brute-force, or AI, it doesn’t really matter – all AI does is use vast quantities of data to shape an algorithm. If anything image processing is more of an interdisciplinary field. It is possible to use AI algorithms in image processing, but image processing is a mature stand-alone field. The human visual system (HVS) makes scene interpretation seem easy. We can easily look out a window and trivially decipher a very complex scene. This task is still very difficult for a machine, so there are certainly applications for AI, in both image processing and computer vision. But algorithms tend to lack the intuition of the HVS, and the brains ability to interpret the aesthetic qualities of an image.

A human can look at an image, and visualize how an algorithm has affected the images aesthetic appeal. No machine can do that because regardless of the AI, it does not really have the ability to interpret a visual scene in the same way a human does. AI might be able to tell you what the main focus of a scene is, but it won’t be able to decipher its intricacies – because no matter how good AI is, it is not the human eye.

The Eight Queens Puzzle (iii) – recursion

8-Queens, or indeed N-Queens is a puzzle which is solved in a simple manner using recursion, indeed many would argue it is the optimal solution. Backtracking by non-recursive means is possible but involves a data structure of some sort, and brute force is by no means efficient. Here is the classic algorithm by Niklaus Wirth [1] rewritten in Fortran. This version produces 92 distinct solutions – and does not recognize rotations or reflections.

Instead of using a 2D model to represent the moves of the queen, Wirth decided to use a representation which makes checking as simple as possible. He uses a series of arrays which represent, not the position of the queens, but rather whether or not a queen has already been placed along each row and diagonals. The arrays are x, a, b, and c:

  • x(i) denotes the position of the queen in the ith column.
  • a(j) means no queen lies in the jth row.
  • b(k) means no queen occupies the kth ↙︎ diagonal.
  • c(k) means no queen occupies the kth ↘︎ diagonal.

The first is an integer array, and the remainder are all Boolean arrays. Arrays a, b, and c are set to true. Here are examples of how they are used:

  • a (row array elements 1 to 8) : A queen in row n sets row array element n to false.
  • b (column+row elements are numbered 2 to 16, corresponding to the sum of column and row) : A queen placed in column 1, row 1 sets array element 2 to false. A queen placed in column 3, row 5 sets array element 8 to false.
  • c (column−row elements are numbered -7 to 7, corresponding to difference between column and row) : A queen at column 1, row 1 sets array element 0 to false. A queen at column 1, row 8 sets array element -7 to false.

The interested reader is referred to the description in Algorithms + Data Structures = Programs.

program eightQueens

   integer :: x(1:8)
   logical :: a(1:8), b(2:16), c(-7:7)
   integer :: i
   logical :: q

   a = .true.
   b = .true.
   c = .true.

   call try(1)

contains

subroutine print()
   do i = 1,8
      write (*,"(I2)",advance="no") x(i)
   end do
   write (*,*)
end subroutine print

recursive subroutine try(i)
   integer, intent(in) :: i
   integer :: j

   do j = 1,8
      if (a(j) .and. b(i+j) .and. c(i-j)) then
         x(i) = j;
         a(j) = .false.
         b(i+j) = .false.
         c(i-j) = .false.
         if (i < 8) then
            call try(i+1)
         else
            call print()
         end if
         a(j) = .true.
         b(i+j) = .true.
         c(i-j) = .true.
      end if
   end do

end subroutine try

end program eightQueens

Further reading:

  1. Wirth, Niklaus, Algorithms + Data Structures = Programs, Prentice-Hall (1976)

The Eight Queens Puzzle (ii) – brute force

The simplest solution to the 8-Queens puzzle is to use a brute-force search algorithm, which considers all 648 = 281,474,976,710,656 possible blind placements of eight queens, and then removing all placements that place two queens, either on the same space, or in mutually attacking positions. This algorithm will produce the same results in various permutations, at the expense of performing the same computations over and over again. A more constrained brute-force algorithm places a single queen on each row, leading to only 88 = 16,777,216 blind placements.

The following Fortran program solves the 8-Queens problem by brute force. The algorithm involves populating the array col with thecolumn positions for every possible combination of queens. This gives a total of 88 or 16,777,216 checks (hence the eight nested loops). After each combination is populated, it is tested for validity using the function isValid().

program eightqueensBF
   integer :: n=8
   integer, dimension(1:8) :: col

   integer :: i, j, k, l, w, x, y, z
   integer :: count=0

   do i = 1,n
      do j = 1,n
         do k = 1,n
            do l = 1,n
               do w = 1,n
                  do x = 1,n
                     do y = 1,n
                        do z = 1,n
                           col(1) = i; col(2) = j; col(3) = k; col(4) = l
                           col(5) = w; col(6) = x; col(7) = y; col(8) = z
                           if (isValid(col) == 1) then
                              count = count + 1
                              call printQueens(col)
                           end if
                        end do
                     end do
                  end do
               end do
            end do
         end do
      end do
   end do

contains

integer function isValid(c)
   integer, dimension(1:8), intent(in) :: c
   integer :: i, k, sw
   sw = 1
   i = 1

   do while (i <= n .and. sw == 1)
      k = 1
      do while ((k < i) .and. sw == 1)
         if ((c(i) == c(k)) .or. (iabs(c(i)-c(k)) == i-k)) then
            sw = 0
         end if
         k = k + 1
      end do
      i = i + 1
   end do
   isValid = sw

end function isValid

subroutine printQueens(c)
   integer, dimension(1:8), intent(in) :: c
   integer :: i

   write(*, '(a5,i2,a4)',advance='no') "Soln ", count, " -> "
   do i = 1,n
      write(*, '(i1,x)',advance='no') c(i)
   end do
   write(*,*)
end subroutine printQueens

end program eightqueensBF

The function isValid() checks whether there are conflicts in the set of queen positions submitted. The array col[1] in the main program contains the column position of the queen in the 1st row. The algorithm checks whether two queens are in the same column or diagonal. If c[i] is the column where the queen in the ith row is located, then a check is made as to whether the queen in the kth row is in the same column (Line 42). For a queen threatening from the diagonal, the difference in the columns is the same as the difference in the rows, such that if the queen in the kth row threatens the queen in the ith row along one of its diagonals (also Line 42). Here is a sample of the output (from the 92 solution):

Soln 39 -> 4 6 8 3 1 7 5 2
Soln 40 -> 4 7 1 8 5 2 6 3
Soln 41 -> 4 7 3 8 2 5 1 6
Soln 42 -> 4 7 5 2 6 1 3 8
Soln 43 -> 4 7 5 3 1 6 8 2
Soln 44 -> 4 8 1 3 6 2 7 5
Soln 45 -> 4 8 1 5 7 2 6 3
Soln 46 -> 4 8 5 3 1 7 2 6
Soln 47 -> 5 1 4 6 8 2 7 3
Soln 48 -> 5 1 8 4 2 7 3 6

Obviously in the early years of computing such as brute force technique involving over 16 million loop iterations would have been prohibitively slow. Nowadays though, it takes less than half a second.

The Eight Queens Puzzle (i) – background

The eight-Queens puzzle, a classic computer science conundrum, was first proposed in 1848 by the German chess player Max Bezzel (1824-1871), and published in the German chess newspaper Berliner Schachzeitung [3]. The first to discover a solution was Franz Nauck in 1850, published in Leipziger Illustrierte Zeitung [2]. His solution incorporated the 12 fundamental patterns, excluding rotations for 90°, 180° and 270°, and mirror images. That these 12 patterns exhaust all the possibilities was proved in Philosophical Magazine in 1874 by English mathematician JWL Glaisher (1848-1928) [1]. Carl Friedrich Gauss (1777-1855), also took a passing interest, but did not completely solve it. What seems like a somewhat trivial problem is actually one which may be best solved using a combination of trial-and-error and brute force. The problem is stated as follows:

Place eight Queens on a chess board in such a way that no queen checks against any other queen.

The 8-Queens problem has the following characteristics:

  • A queen can attack in any of the compass directions N, NE, E, SE, S, SW, W, NW.
  • A queen can attack at any distance as long as it’s in a valid direction.
  • There are 4,426,165,368 possible arrangements.
An example of an eight-Queens solution.

The solutions to the puzzle can be formulated into distinct and unique solutions. For example the 8-Queens puzzle has 92 distinct solutions and 12 unique solutions. The unique solutions are derived by rotating and flipping the chessboard. So given one unique solution, a number of others can be found by applying the following series of transformation:

  1. A rotation of 90˚ counterclockwise.
  2. A rotation of 180˚ counterclockwise.
  3. A rotation of 270˚ counterclockwise.
  4. Flipping about the vertical axis.
  5. Flipping about the horizontal axis.
  6. Flipping about the diagonal axis passing through the cells aij, (i≠j)

The N-Queens puzzle is an extension of 8-Queens to place N Queens on an N×N chessboard.

NNo. of solutionsUnique solutionsNNo. of solutionsUnique solutions
111935246
2001072492
300112,680341
4211214,2001,787
51021373,7329,233
64114365,59645,752
7406152,279,184285,053
892121614,772,5121,846,955

Further reading:

  1. Glaisher, J.W.L., “On the problem of the eight queens”, Edinburgh Philosophical Magazine, Vol.4(48), pp.457-467 (1874)
  2. Nauck, F., “First complete solution of eight queens problem”, Leipziger Illustrierte Zeitung, Vol.361, pp.352 (1850)
  3. Bezzel, F.W.M., “Eight Queens problem”, Berliner Schachzeitung, Vol.3, pp.636 (1848)
  4. Wirth, Niklaus, Algorithms + Data Structures = Programs, Prentice-Hall (1976)
  5. Wirth, N., “Program development by stepwise refinement”, Communications of the ACM, Vol.14(4), pp.221-227 (1971)
  6. Dahl, O.J., Dijkstra, E.W., Hoare, C.A.R., Structured Programming, Academic Press (1972) -see pp 72-82 for Dijkstra’s solution of the 8 Queens problem.

Students and the art of spoon-feeding

There is nothing I find more tiresome than students who email with a question whose answer is clearly outlined in the course material. They are just too lazy to read the material, and it has been getting progressively worse over the past few years. Typical reasons for these questions include:

  • A failure to read course material.
  • A failure to read course material properly.
  • A failure to read course emails.
  • A failure to read the extensive course FAQ.
  • An inability to do an internet search.
  • A belief in what someone else told them, without verifying it.
  • An inability to start an assignment until the last possible minute.

Sometimes they even dare to lie, saying “I read through the material, and just can’t understand X”. Problem is that most profs can see online (within the context of learning platforms) whether they have actually looked at the material, and they often haven’t. They just want to be spoon fed the information. The other issue is interpreting things as they see fit. If an assignment says “don’t do X”, some students will do it anyway and then say “Oh, I just thought I would do it, that’s okay right?”. Sorry no it isn’t “okay” – because you couldn’t be bothered following the instructions – they exist for a reason. Another example is when an assignment says “write a 500 word article”, yet some people decide that this means copy-and-paste someone’s work from somewhere else. Like are you kidding me?

I honestly don’t have any time, nor any sympathy for people who can’t be bothered to do any work and instead need to be spoon-fed. It’s okay to email a prof if you have a question that you really can’t understand, and have tried to solve it yourself – but it’s not okay to just email every time you have an issue because you are too lazy to do the leg-work yourself. What it says about these people is that they will struggle to find good jobs, because when you get paid to do a job, you actually have to do the job.

Why am I even mentioning this? Well, it’s just another thing in the pile of things that is producing some graduates with few if any skills. The Conference Board of Canada says that 55% of Canadian adults have inadequate numeracy, literacy and problem-solving skills. This means that 55% of graduating higher-ed students lack these basic skills. It’s no wonder they like to be spoon-fed. When they graduate they are not literate, or numerate, or knowledgeable enough to perform the work they have been studying for. That’s food for thought, and a little scary.

It’s almost like, because they have paid for a product (their degree), they feel they are owed it. But that’s not how education works. Of course the interested reader will ask how these incapable students graduate. Well, it’s really all about bums-in-seats, and $, which is intrinsically linked to the idea of the university as a business. Asking universities to stop making it easy for students to graduate is like asking Apple to stop designing new iPhones. Capitalism rules I guess. Look I don’t completely blame students. Society is partially to blame, social media, helicopter parents, school teachers with an inability to teach… the list is so long.

Spoon-feeding? Don’t make me laugh. This is a force-feeding frenzy, with students haplessly sitting around while academics assist them is opening their mouths so the blended food can be poured in. We keep questioning why the last decade has produced so many anxious people. They are anxious because nobody lets them do anything by themselves. Helicopter parents drop in anytime there is an issue, snow-plow parents push away any obstacles in their children’s progress. Nobody let’s them fail. They never get to understand their limits, because they can “be whatever they want”. The reality is quite different.

Look, as a teacher it’s okay to say no. It’s okay to tell a student to explore the answer themselves. It’s okay to let them fail, because it’s their work – they have to put the effort in. It’s even better to push them beyond their perceived limits, but they have to want to push beyond their perceived limits.

Programming inefficiencies and redundant computations

Very few programmers these days consider the idea of algorithm efficiency. In the early days of computing this was of course important, because memory was quite constrained. Nowadays there is too much memory, which in many cases does lead to some sloppy coding. One of the more common issues is redundant computation, where unnecessary computations and storage are used. This often manifests itself in loops, where there is a repeated calculation of an expression that essentially remains constant throughout the lifetime of the loop. Here is an example (in Fortran_:

x = 0
do i = 1,n
   x = x + 0.01
   y = (a * a * a + c) * x * x + b * b * x;
   print*, x, y
end do

This loop ends up doing twice the number of multiplications needed to complete the computation. The unnecessary computations can be removed from the loop, pre-calculating them before.

aaac = a * a * a + c
b2 = b * b
x = 0
do i = 1,n
   x = x + 0.01
   y = aaac * x * x + b2 * x;
   print*, x, y
end do

You may say that it doesn’t matter, because on modern machines, there is minimal differences between these time these pieces of code take to run. But that’s also the reason why there is so much bloated software out there. If there were better adherence to some basic principles of writing better code, I imagine we would have much more elegant, streamlined software.