Java Algorithm: Pascal’s Triangle

Pascal’s Triangle

Pascal’s triangle is a problem where you want to print a triangle of a certain height where each element is the sum of the 2 elements above it.  The first row is 1, the second row is 2 1’s, and then the pattern builds from there with 1 on the ends and the other elements being the sum of their parents.

For Example:

        1
       1 1
      1 2 1
     1 3 3 1
    1 4 6 4 1

Generalized Solution

It’s always good to (first) try to solve algorithms yourself without looking at other peoples’ solutions so that you truly learn how to work them out yourself in real scenarios.

So, there may be a more efficient solution than this; but here was my approach:

  • Set a list to hold the previous row (initially empty).
  • Loop up to the required depth from 1 to D inclusively.
    • Loop for each item that should be in that level (level 1 has 1 number, level N has N numbers).
    • If it’s an end-number add “1” to the new row, otherwise add the sum of parents.
  • Print the new row.
  • Store the new row as the previous row so it can be used for the next depth level’s parent calculations.

I’m sure you can do this without storing the previous row as well mathematically, but this is pretty elegant and will only take extra space equal to the sizeof(int) * level-number which is really nothing.

Java Solution

package john.humphreys;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class PascalsTriangle {

    public static void main(String[] args) {
        printToDepth(20);
    }

    private static void printToDepth(int d) {

        //Row 1 has value 1, anything less is invalid.
        if (d < 1) return;

        //Keep track of the previous row.
        List<Integer> previousRow = new ArrayList<>();

        //Loop from 1 to target depth inclusively.
        for (int i = 1; i <= d; ++i) {

            //Create a new row to populate with our solution.
            List<Integer> newRow = new ArrayList<>();

            //If this is a row-end (0 or max in row) add 0, otherwise add the parents' sum.
            for (int ri = 0; ri < i; ++ri) {
                newRow.add(ri == 0 || ri == i - 1 ? 1 : previousRow.get(ri - 1) + previousRow.get(ri));
            }

            //Print out the space-separated row.
            System.out.println(newRow.stream().map(Object::toString).collect(Collectors.joining(" ")));

            //Store this as the previous row.
            previousRow = newRow;
        }
    }
}

If we take out comments, gratuitous spacing, and imports, it’s quite lean:

public class PascalsTriangle {

    public static void main(String[] args) {
        printToDepth(20);
    }

    private static void printToDepth(int d) {
        if (d < 1) return;
        List<Integer> previousRow = new ArrayList<>();

        for (int i = 1; i <= d; ++i) {
            List<Integer> newRow = new ArrayList<>();
            for (int ri = 0; ri < i; ++ri) {
                newRow.add(ri == 0 || ri == i - 1 ? 1 : previousRow.get(ri - 1) + previousRow.get(ri));
            }
            System.out.println(newRow.stream().map(Object::toString).collect(Collectors.joining(" ")));
            previousRow = newRow;
        }
    }
}

Java Regex Capture/Extract Multiple Values

Use Case

When you’re trying to parse complex log lines or extract data from complex strings, regular expression capture groups are about the most useful tool you could possibly ask for.

This example is taken from work where I had to parse and analyze some logs for loading data to a database. A log sample would look like this:

/data/SXF_SX_4906_2019-04-13.01.43.24.143.log:2019-04-13 01:43:28,320 INFO com.x.dc.db.schemagen.batch.listener.JobResultListener [tx.id=IF-TX-ID-a23c195c-673a-47ab-ab0c-7b8591821169] [main] Inside sendEmailNotification method: subject is prod alert:DB copy job STARTED for the dataset:4906

The Code

The relevant part of the code is here:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

private static final String capturePattern =
"^/.*/SXF_SX_(\\d+)_(\\d{4}-\\d{2}-\\d{2}.\\d{2}.\\d{2}.\\d{2}.\\d{3}).log:(.*) INFO.*" +
"copy job (.*) for the dataset:.*"

//Leaving out rest of class, this is just the regex parsing portion.
//isValid, fulLLogEntry, dataSetId, fileTimestamp, logTimestamp, status are all
//member variables in a class where this function is a member.
public DbLoadLog(String line) {

    isValid = true;

    Pattern r = Pattern.compile(capturePattern);
    Matcher m = r.matcher(line);

    //If you wanted to run over a multi-line-string/file, you could put
    //m.find() in a while loop and keep going; but I'm just analyzing specific lines.
    if (m.find()) {
        fullLogEntry = line;
        dataSetId = Integer.valueOf(m.group(1));
        fileTimestamp = m.group(2);
        logTimestamp = m.group(3);
        status = m.group(4);
    }
    else {
        isValid = false;
    }
}

 

Does Spring JdbcTemplate Close Connections? … Not Always.

Common Advice – Correct?

Decent developers usually know that they have to try/catch/finally to ensure they clean up connections, file handles, or any number of things.  But then, for Java, you hear “just use JdbcTemplate! it does all this boilerplate for you!”.

Uncommon Scenario

Normally when you’re writing an average app, you generally want lots of queries to be able to run in parallel, efficiently, using the same user and password.  In this case, you can easily just use a connection pool and “not worry about it”.  Spring JdbcTemplates will just grab connections from your data source and pool them appropriately based on the data source.  You don’t have to worry about if they are opened, closed, or whatever.

I ran into a scenario today where that was not true though.  I have an app where each user connects to each back-end data-source using their own personal account which is managed by the application itself.  So, each user needs his or her own connection.  So… pooling would not make much sense unless each user had to do parallel operations (which they don’t).

What Happens to the Connections?

So, here’s the fun part.  I had, for the longest time, assumed that JdbcTemplates would clean up connections in addition to results sets.  In fact, you’ll see this online a lot.  But be careful!  This does not appear to be the case, or if it is, it is at least data source dependent… and that actually makes sense if you think about their purose.

Here is how I verified this. I created a JdbcTemplate which is based on a new data source each time (which is needed as the user/password change).

private NamedParameterJdbcTemplate getJdbcTemplate(String email, String password) {
    SimpleDriverDataSource ds = new SimpleDriverDataSource();
    ds.setDriverClass(HiveDriver.class);
    ds.setUrl(url);
    ds.setUsername(email);
    ds.setPassword(password);
    return new NamedParameterJdbcTemplate(ds);
}

Then I used the template for a number of queries in a normal manner (like this):

getDirectHiveJdbcTemplate(email, catalog)
.queryForList("describe extended `mytable`.`mytable`",
new MapSqlParameterSource())

Then I took a heap dump of the process with this command (run it from your command line in your JDK bin folder in Program Files or the Linux install location with minor changes):

jmap.exe -F -dump:format=b,file=C:\temp\dump.bin your-pid

You can get the PID easily by looking at your running process from JVisualVM (which is also in the bin directory).

Once the dump is complete, load the file into JVisualVM (you need to use the 3rd option of file type to make it go in, I think its pattern is . or something.

Finally, go to the classes tab, go to the very bottom of the screen, and search for the class of interest (in my case HiveConnection). I can see as many instances as I have run queries as each query made a new connection from a new data source. They are definitely not being cleaned up.

This surprised me because even though creating a new template/data-source each time is not normal, I expected them to clean up the connections when they were garbage collected or as part of normal operations.  After thinking about it more, I realize operations in my case would not me “normal”, but the lack of clean up when out of scope still definitely is a surprise to me.

 

Interleaving Iterator

Creating an interleaving iterator is a popular interview question in the Java world.

What is an Interleaving Iterator?

An interleaving iterator is an iterator of iterators. An iterator is a class that implements the following methods (others exist but are not mandatory).

boolean hasNext();
T next();

Iterators are designed to “iterate” (cycle through) a sequence of elements of unknown length. You don’t know how many elements there are; you just know that hasNext() returns true so more elements exist (or it returns false and you’re done with the iterator).

So, an iterator of iterators is an iterator that iterates over iterators which iterate over sequences of elements of another type.

Iterators can even be potentially infinite; they may never end!

Solution Details

There are quite a few different solutions for this… but the easiest one I’ve seen leverages a queue. The basic approach is:

  • Create a member variable in the class that is a Queue.
  • On construction, populate the queue with all of the provided iterators.
  • Create a utility method (getNext() in the solution below).
    • This method is designed to get the next element if it hasn’t already been found.
    • It stores it in a member variable of the class so that we know if it has already been found.
    • The methods next() and hasNext() both defer to this method to test if there is a next element and/or retrieve the next element.
    • This is important as when using the iterator, callers will call hasNext() to see if there is a next element (which must clearly get the next element to know if it exists). We want to return that already-found element when next is called instead of accidentally skipping ahead to yet-another element.
    • Also, if I (badly) made an iterator of iterators that I knew I put 10 elements in overall, I should technically be able to just call next() 10 times without calling hasNext(), even though it is bad practice.
    • IMPORTANT – the method must basically consist of:
    • while next element isn’t found and some iterators remain in the queue:
      • Take next iterator.
      • See if it has more elements.
      • If it does, take the next element and put it back in the queue if it has more.
      • If it doesn’t have more elements, add it back to the queue.
  • The next() method just gets the next element using the utility method and returns it, or throws a NoSuchElementException if there wasn’t one.
  • The hasNext() method just returns whether or not the utility method says there are more elements.

Implementation (Java)

import java.util.*;

public class InterleavingIterator<T> implements Iterator<T> {

    private Queue<Iterator<T>> iteratorQueue;
    private T next;

    public InterleavingIterator(Iterator<Iterator<T>> masterIterator) {
        if (masterIterator == null) {
            throw new IllegalArgumentException("Iterator cannot be null.");
        }
        iteratorQueue = new ArrayDeque<>();
        masterIterator.forEachRemaining(iteratorQueue::add);
    }

    private T getNext() {
        while (next == null && !iteratorQueue.isEmpty()) {
            Iterator<T> iterator = iteratorQueue.poll();
            if (iterator.hasNext()) {
                next = iterator.next();
                if (iterator.hasNext()) {
                    iteratorQueue.add(iterator);
                }
                return next;
            }
        }
        return next;
    }

    @Override
    public boolean hasNext() {
        return getNext() != null;
    }

    @Override
    public T next() {
        T n = getNext();
        next = null;
        if (n == null) throw new NoSuchElementException();
        return n;
    }

    //Test it out!
    public static void main(String[] args) {

        //Create 4 lists with a range of test cases.
        List<String> a = Arrays.asList("a", "d", "f");
        List<String> b = Arrays.asList("b", "e", "g", "h");
        List<String> c = Collections.singletonList("c");
        List<String> d = Collections.emptyList();

        Iterator<Iterator<String>> masterIterator = Arrays.asList(
                a.iterator(),
                b.iterator(),
                c.iterator(),
                d.iterator()).iterator();

        InterleavingIterator<String> interleaving =
                new InterleavingIterator<>(masterIterator);

        while (interleaving.hasNext()) {
            System.out.println(interleaving.next());
        }
    }
}

Output

a
b
c
d
e
f
g
h