# Simple algorithm to order a list

There was once a program, back in Mac Classic days, called Do It All! Calendar. It was a wonderful task manager and scheduler in the late 90s. It is no longer supported, and I’ve seen nothing quite like it since. There was something special about the scheduling aspect that I can’t quite remember, but the feature that really helped me was the prioritizing algorithm. The program would present all your outstanding tasks in pairs and ask which was more important. As you selected from each pair you would eventually end up with a prioritized list. It would take a few minutes, but it wouldn’t compare every task to every other task. I remember looking at the resultant list and really feeling like I could just take that list from the top and chew away at it, not worried that I was going to leave something important undone, missed far down the list.

Well. My work life is so busy, and my task list (OmniFocus at this time.) fills up so quickly that I eventually glaze over when trying prioritize, and I do worry that I’m missing something important.

My thought was to apply a “simple” pairing and sorting algorithm to order my tasks. So my question is: has anyone tried applying anything like such an algorithm using Keyboard Maestro?

That's a curious algorithm. But I can see how it probably wouldn't be overwhelmingly popular so it has gone extinct.

There's probably some interesting math that can be implemented to get this to work effectively. Or one could simply pull up random comparisons which wouldn't be quite as effective but may end up with similar results eventually. I'm not sure I could come up with the real math behind that algorithm, so I'd probably just implement random comparisons.

The new KM v9 has some new string manipulation capabilities with its JSON functions. That might be the way to go. Or maybe not, as each string is clearly representable by a number in simple set of lines in a text variable. All we really have to do is refer to the string by a one dimensional array of numbers which are indices to the strings they represent.

At the moment, here's what I'm pondering as the pseudo code:

For LoopValue = 1 to 30
Pick two random strings from the list
Ask user to decide which one is more important
If they aren't currently in the right order, swap them
End Loop

Hmm, I can see why my algorithm isn't efficient. It's not keeping track of the previous answers and ensuring that the previous answers are always enforced. I think I'm starting to envision the real math behind how that old application probably worked. Let me ponder that a bit more, because I like puzzles, and this is definitely a puzzle.

Of course, it's also possible that the user provides bogus answers. He could say A>B, B>C, C>A. I'm not sure how any algorithm should deal with false data.

Ok I've drafted a KM macro skeleton program that tackles this. It's not quite finished, and in this code it's up to the user to manually map the numbers 1 to 6 to six different tasks. Just 6. Exactly 6. Yes I know that's not desirable but at least I have a template working. It's just a proof of concept to get me thinking about this curious mathematical puzzle. If you want to contribute to the solution, by improving my code where it's weak, that would be great.

One problem is that I haven't figured out how to list all the combinations of numbers from 1 to 6. Normally that's done with recursion. KM isn't very good at recursion since it doesn't allow parameters, and it would have a limit of 25 recursions because that's the limit of how many macros can run simultaneously. My simulated recursion is very inefficient. This should be easy to fix by someone who knows how to use the Execute Swift action, for example, which I don't know how to use.

The first step is to collect all the task names. In my case I just used the numbers 1 to 6 as the task names. Mapping these to actual strings is a trivial thing that I'll save for the end. So there isn't even any code here, it's just an abstraction at this point.

The second step is to collect the comparisons from the user. For testing purposes all I did was create a variable that stores some sample comparisons, as follows:

The next step was to zeroize a results variable. All possible valid results will be assembled in this variable. In all likelihood there will be dozens of legal results that we can give to the user:

Then we have to create a list of all combinations of the digits from 1 to 6. This is where my programming skills are currently a bit lacking. I did succeed, but it's very inefficient. I created six nested loops. The first one looks like this:

and the last one looks like this:

All this does is collect all the permutations of the numbers from 1 to 6.

Then for the functional meat of the job:

There's one key condition that's blank in this code. It's the condition that checks that the candidate results matches (each) condition that the user prepared for us. That's tricky to write but not that tricky.

All valid results are just displayed briefly, which probably is not how you want the user to see the results.

This code is incomplete. It's inefficient. In many ways it's bad code. But for a first draft, it's interesting mental fodder. If this code worked efficiently and neatly for the user, would this be the actual problem you are trying to solve, or am I barking up the wrong tree?

If my code is solving the right problem, let me know. If not, also let me know.

There are probably more comprehensive explanations of a simple sorting algorithm, but I ran across this Youtube video that explains the basics of how such an algorithm functions in practice. Not a coding explanation but a conceptual one. What stick out to me about it is how, according to the function of the algorithm, it isn't necessary to compare all pairs. There's a tracking, or logging, function to the algorithm that limits the need to compare all pairs.

I can imagine a variable that contains the index of a task, a variable with the task, and a variable that tracks comparisons.

A quicker sort of a pile of things might be:

• Take any item from the pile,
• divide all that remains into two heaps: things that are less important than the task in hand, and things that are more important,
• recursively repeat the whole procedure with each smaller heap that emerges.

(But if it isn't obvious what to do next, the fastest progress may come from discarding it all and moving on.)

1 Like

Searching more about algorithms, I came across this thread at StackOverflow. It has some of the clearest coding explanations I could find of sorting a list by preference. The entry beginning "Make is simple:" seemed the most clear, accessible and relevant to me:

After running the code snippet within StackOverlow many times, here is what I believe I understand about how this algorithm functions practically:

• Take all the elements of the list and assign each element a score of zero (0).

• Take the next two elements in the list (initially, the first two).

• IF the pair of elements are marked "done" (They won't be initially.) move on to the next two elements.

• IF the 2nd element has a lower score than the first element,

• mark them "done"

• move on to the next two elements in the list.

• IF the 2nd element does NOT have a lower score (if the 2nd element has a higher score than the first or if they are tied), the compare them (get user preference).

• Raise the score of the preferred item by +1 and sort the pair by score (or you could sort the whole list by their score).

• mark them "done"

• move on to the next two elements in the list.

• Take the next two elements in the list...continue with the functions above, until the end of the list is reached, then go back to the top of the list and run these functions again.

• Keep going back through the list until all pairs are marked done.

• Then, remove the "done" mark from all elements.

• skip the first element, then

• take the next two elements

• run the functions above.

• When all pairs are marked "done."

• Go back to beginning with the first element.

When all elements are separated by a score of 1, then they are ordered by definition.

I realize I'm speaking partly in "functions" and partly in concepts so I hope what I'm writing makes some sense.

I think I just got quite a bit closer (but not there yet) about how the sorting algorithm might work in Keyboard Maestro.

I'm sure this algorithm would not be the most efficient (require the fewest user responses) but it seems the most accessible to me for "coding" in Keyboard Maestro.

Although my proposed solution is currently inefficient and incomplete, I would like to note that it is designed to provide every single possible solution that meets the requirements. Some of the solutions I'm reading in this thread focus on finding one solution. Using the algorithm I drafted up, if there are 10 items it will find all 3628800 ways to permute them, and it will reduce that number in accordance with the priority rules. So for example if you indicated that item #3 has to precede item #5, my algorithm would generate all 1812400 results.

It sounds like you're describing a Heap Sort of a list ranked using pair comparison analysis.

IMO, all of the above is making something simple way more complex than it needs to be. LOL
Has anyone shown that any of these complex methods actually result in a better sorted list of to-dos?

What's wrong with the old A-B-C method that I've used my entire working life:

• Just go quickly down the list assigning each item an A, B, or C, where A is highest priority, needs to get done soonest.
• Don't think about it -- just quickly assign your gut reaction.
• Sort by A-B-C when done.

The trick is not in the assigning of priority, but in the daily discipline to execute the list, especially items that you really don't want to do/face.

Not perfect, I'm sure, but has worked well for me.

YMMV.

I think this is, generally speaking, a poor method of prioritisation for the majority of people. Humans aren't naturally well-suited to considering a list of many items and comparing them en masse.

[ Edit: Although you actually go on to say that, for you, ordering a list is not about priority, and more about doing it. In which case, A-B-C is most likely just fine, but will only be fine for certain people in certain situations. ]

Yes. Some form of priority queuing is used throughout businesses, professionals, students, down to the everyday folk. Personally, I do not, but I am considering it now, as I think I suffer from being inefficient.

We actually implement this sort of process naturally in our heads, but on a smaller scale, such as when deciding what to eat in a restaurant from their menu.

That's probably why your method is not suitable for most people. It's often, particularly in a professional context, less about being motivated or able to execute the list, but doing it in the order that means, in the event the list does not get completed for whatever reason, the uncompleted tasks are much less likely to impact on anything else.

I think the focus in the responses so far has been on the nature of the sorting algorithm, whereas the key process is the pair comparison analysis. Once one has performed the pairwise comparisons, the method used to sort them isn't especially important.

From the OP:

So, I would NOT consider my personal list of tasks, AKA "To-Do List", to be of "many items". I'm thinking around 10 or so. Now if your list is > 100, then that is a whole different problem to solve.

So you seem to contridict yourself with this:

So if we could do it in our head, why not on paper (make that Mac or iPhone) wouldn't my A-B-C method work?

If the task list is longer, or more complicated, then I would be moving to something like the Getting Things Done (GTD) method.

Sorry, but I still think you guys are over-thinking, over complicating this easy task.
Maybe you should make a list, write an algorithm, implement and test it, and get back to me with the results.

The term many is really referring to anything more than about three or four items: humans don't process data in working memory with anything more than this, which is what makes a pairwise comparison process ideal for figuring out priority.

I misspoke before and didn't mean to say that it wouldn't work. In fact, I didn't fully grasp initially what you were doing with your A-B-C method, however, assuming that the resulting list is one organised by priority, then clear it would work. But your brain will be doing what iis being discussed in this thread, whether or not you're aware of it doing so: it performs the same (similar) set of discrete data comparisons and then sorts the data using the comparison results, doing this on a subconscious level that creates the illusion of a "gut reaction". It starts doing this from the moment you scan through the list, and despite how it may seem that one is able to manifest a sorted priority list without doing very much, the brain certainly won't be taking 10 items and performing any sort of manipulation with all ten in unit time.

If, as you possibly implied before, that the resulting list isn't necessarily one that's ordered by priority (or one that's only roughly ordered by priority, but also by other significant factors), then the objectives here are different and your A-B-C method would not be appropriate.

Whether such a list that approximates priority order to a less stringent degree is or is not suitable for OP's situation is something he can debate with himself internally. There are many instances in which a more rigorous method of prioritisation is much preferred/necessary, but to know with certainty that the two methods would yield the same result, we'd need to know what is happening at a lower level in the brain during a gut reaction, and I don't think most people have access to this degree of awareness.

I suppose the answer to your question is actually the answer to whether a particular method when used in practice allows an given task list to be traversed to a satisfactory outcome by the end of each day. If so, then, yes, the A-B-C scheme is demonstrably suited.

This is more an approach to the psychology of organising a task list more than the process of organising it, which still ends up needing to be done after the pre-planning stage outlined by the GTD method. By itself, it won't result in a prioritised list.

That said, I think considering how one approach's a task list psychologically is a very important factor that is often overlooked, and certainly not something we've touched upon in this thread. But that can be for the OP to consider if they wish to. What I like about this (and similar) approach(es) is that it factors in—to a small degree—how long a task takes to complete, and not simply how important the task is. GTD has a simple 2-minute cut off rule, whereby if a task takes under two minutes to perform, then, essentially, one can stop processing the task list and perform that task in the immediate present. There are more advanced algorithms for this too, but I've not read into them in detail.

That's fine. It does sound like this degree of more rigorous prioritisation isn't something you want or need. From what I'm discerning given the OP's description in his original post, it actually doesn't sound that complicated at all. Of course, the OP may not be well versed in sorting algorithms, so, as with anything with which one is unfamiliar, it will have an initial learning curve, as does GTD. Being autistic, I would find the A-B-C method possibly insurmountably difficult to learn, as I lack any sort of "gut reaction", so don't really understand what people are referring to when they say this, i.e. I can't conceptualise the feeling of a gut reaction or how it then leads to a decision being made, but I am aware that the processes which I perform consciously are typically performed much faster by those doing them subconsciously, though would be expected to produce more-or-less the same result (± EQ factors).

My point is that it's not always possible to apply a one-size-fits-all method to things, even when a problem seems "easy" to someone.

Yes, that is what the OP was looking to do, hence why we were chiming in with the sorts of analyses and algorithms that could point him in the right direction. If I remember rightly, you did a computer science degree, so I would imagine that making a list, writing, say, a heap sort (or any sorter, really), and running it would be something you could do in about ten minutes...

...and the benefit there being that you would only need to do it once, as subsequent lists will get spit out automatically by the Keyboard Maestro macro the OP ends up creating, or whatever program they might end up finding to replace the old one.

In contrast, if one chooses to prioritise/sort their list mentally, this has to be done with each new task list. Of course, there's nothing wrong with this, and one would expect that it becomes habitually familiar once done frequently enough that it can seemingly be done without thinking about it.

1 Like