Using Google Without a Mouse

This is part of a series of articles about how I’m trying to reform my bad keyboarding habits as a result of Repetitive Strain Injury. Other articles in this series can be found here. Other articles about demousification can be found here.


TL;DR - Navigating through Google search results with the keyboard means hitting the Tab key over and over and over again.

I just went to Google and did a search for “Repetitive Strain Injury”. To go to the first search result requires hitting the Tab key 15 times.

That clearly sucks.

Fortunately, if you use Chrome or Firefox, there’s a great extension you can get that will allow you to navigate much better. I installed it immediately.

The Google Search Navigator extension for Chrome or Firefox makes it very easy to navigate search results with the keyboard. If you’re using Edge or Internet Explorer, you have my sympathies.

The first thing it gets right is that it immediately focuses the first search result, which is almost always what I want.

Google Search Navigator results

It has lots of keyboard shortcuts, but the main ones I’ll use are:

  • Down (or J) to move to the next result
  • Up (or K) to move to the previous result
  • Enter to navigate to the result
  • Ctrl+Enter to open the result in a new window

Other keys of note:

  • Esc (or /) to go back to the search box
  • A (or S) to go to the All tab
  • I to go to the Images tab
  • V to go to the Videos tab
  • M to go to the Maps tab
  • N to go to the News tab

It’s still pretty instinctual for me to reach for the mouse once the results display, but I’m getting over it. I’m not quite ready to actually remove the mouse from my desk, but that may be what it takes for me to really reprogram my brain.

Ditching The Mouse

This is part of a series of articles about how I’m trying to reform my bad keyboarding habits as a result of Repetitive Strain Injury. Other articles in this series can be found here. Other articles about demousification can be found here.


I’m addicted to mousing. I’m not sure how I became so dependent on it, considering how fast of a keyboardist I am. But admitting the problem is the first step on the path to recovery.

As I mentioned at the beginning of this series, one of the ways that I know I’ve had a productive day is if my right shoulder feels like it’s been stabbed by an angry monkey. The act of picking my hand up from the keyboard, moving it to the mouse, using the mouse, and moving my hand back again is rapidly becoming one of the most painful things I do each day. I may be one of the least athletic people you ever meet, but I frequently suffer from tennis elbow caused by too much mouse clicking.

Thus, one of my goals for mitigating my RSI is to reduce/eliminate as many trips to the mouse as I can.

This is easier said than done; the “point-and-click” interface is so ubiquitous that it’s very difficult to get away from. I’m embarassed to admit that just 30 seconds ago I moused my way through the source control pane in VS Code to commit a new script that I created for creating blog posts.

In fact, in most cases, unless a developer has spent a significant amount of time making sure that their interface is keyboard-friendly, it may be impossible or impractical to use that software using only the keyboard, despite the fact that Microsoft and Apple design guidelines explicitly state that software should be usable using only the keyboard. Most web sites – including all the ones I’ve ever written – fail in this regard.

Adding to the frustration is the fact that in many cases, figuring out how to navigate with the keyboard is obvious, but it isn’t at all obvious how to get to where you need to be. For example, from the message list in Outlook, how do you get to the list of folders so that you can navigate to another one?

So I’ve made a list of the sites and applications that I use most often and I’m committed to learning how to keyboard my way through them. That list is:

  • Visual Studio
  • Visual Studio Code
  • JP Software’s Take Command (a command line replacement I’ve been using since the 80s)
  • Outlook
  • Excel
  • Google
  • Facebook
  • Twitter

I imagine that things like Visual Studio will require several posts. I’m not feeling that ambitious yet, so I’m going to start where I can get the most bang for my buck and do a small series of posts on the web sites I use most often, starting with Google.

Frustrations With Dvorak

This is the second in a series of articles about how I’m trying to reform my bad keyboarding habits as a result of Repetitive Strain Injury. Other articles in this series can be found here.

I’ve been coding for about a week now using the Dvorak keyboard layout.

Sometimes, I just get super frustrated with how hard things are and I switch back to QWERTY and get shit done. It’s a bit like binge eating when on a diet.

When I get my ErgoDox EZ some of these problems will go away because I can customize the layout.

The first thing I’ve noticed is this: name any key on the QWERTY keyboard and I can hit it with either index finger without looking. This seems like such a stupid skill, but it’s amazing how many times each day I’ve been doing it. I can’t do it with the Dvorak layout, and this has been a huge source of slowdown for me. This comes up a lot when I notice a single character that needs to be changed. My normal workflow in this scenario is to click on the offending character, hit backspace with my right index finger, then tap the correct key with my index finger.

I suspect this is only one of many “brain macros” I’ve been executing over and over all day that I’m going to have to reprogram.

Another source of frustration has been with array indexes. Specifically, array index 0.

On the Dvorak layout, the two bracket keys are just to the right of the zero. To type [0], my right pinkie has to do this weird little dance where it hits the [, then one left to hit 0, then two to the right to hit ]. I don’t like it. It feels weird.

When I had my tonsils out, my doctor told me that there would come a point at which the pain would subside to the point that I’d be able to say “if it feels like this for the rest of my life, I can live with it.” It took me about two weeks to get to that point with my tonsils. I wonder how long it will take with the keyboard?

Going Ergo

I’ve been programming professionally for 29 years. I’ve been typing as part of my job for 31.

As a result, I suffer from very bad Repetitive Strain Injury. I can directly measure how productive I’ve been during any given week by how badly my hands hurt on Friday evening. I’m left-handed, and my left hand suffers disproportionately. If I feel like my left hand was smashed by a hammer, I know I got a lot done.

I started learning to type long before I was given the opportunity to take a proper typing class. By the time a guidance counselor offered me a typing class in 12th grade, I could already type 120 words per minute.

But they were 120 words per minute typed the wrong way. I developed a lot of really bad habits. For one thing, I didn’t type with all my fingers. I only use three fingers on my right hand and two on my left for typing letters and numbers. I started typing on a keyboad where the function keys were on the left-hand side of the board. Because of that, and because most of the control keys I needed were also on the left-hand side, I developed the habit of contorting my left hand to type those keys. For example, to hit the keys for cut, copy, and paste, I hit the control key with my left thumb – tucking it under my hand – and hit the letter key with my left index finger. The area just below my left thumb is now almost constantly in pain, even when I’m not working.

Recently, I’ve been trying to develop better habits. But it is very difficult to work against 30+ years of muscle memory. When I’m programming “in the zone”, instinct takes over and I wind up doing all the wrong things again.

I’ve decided it’s time for a radical approach to this problem. If I’m going to work against 30 years of hard-forged neural pathways, I’m going to go all out.

Step 1: I’m going Dvorak. I have tried and failed to teach myself to type “properly” on a QWERTY keyboard. I constantly revert back to my weird self-taught style when I’m not paying attention. It’s super frustrating. So, I taught myself the Dvorak layout using all my fingers in the “proper” way. In fact, I’m typing this post in Dvorak mode. I can only type about 60 WPM this way – half my normal speed – but I feel like I’m getting better. Writing code in Visual Studio is another story: I’m constantly frustrated by needing to get things done and knowing I can go much faster.

Step 2: Ditching the mouse. I know I’ll never be able to get rid of it completely, but I need to find a way to reduce the number of times per day I reach for it. On days when I feel like my left hand has been smashed by a hammer, my right shoulder feels like it’s been stabbed by an angry monkey. This leads to…

Step 3: Learning to move around in Visual Studio with the keyboard. I like to code full screen, which means my Visual Studio window layout has most of the tool windows hidden. If I want to go to one of those, I’m always reaching for the mouse. I just learned that you can navigate between these windows by pressing Alt-F7 and Shift-Alt-F7. And I’ve learned that most of the windows I need all the time have a Ctrl-W combination that will take you there (e.g, Ctrl-W, O to go to the Output Window). Why did I never bother to learn this before? Oh, and if you’re focused in a tool window, pressing Ctrl-Tab or F7 will get you back to your code.

Step 4: I’m switching from my beloved Das Keyboard to an ErgoDox EZ keyboard. I picked this keyboard out of all of the choices available because:

  • It’s a split configuration, so I can hold my hands shoulder width apart. This reduces tension in the shoulders and keeps me from having to have my wrists bent at an angle while typing.
  • It has ortholinear keys, so my fingers don’t have to move in strange directions; they just need to go up and down.
  • Its firmware is open source. We like open source.
  • It’s completely programmable, so I can create weird keymaps that fit the way I work.
  • I can create single, easy-to-reach keys that map to the most common hand-contorting key combinations that I use. For example, I reflexively hit Shift-Ctrl-S all the time to “Save All” in Visual Studio. Given how often I hit it, I’m going to replace that with a single key press.
  • I can control the mouse with it.

Step 5: I’m going to try using Windows Speech Recognition where appropriate. I’m mostly using it in Outlook for typing e-mails. It doesn’t work so well for blog posts: I edit my blog in VSCode, and Speech Recognition isn’t quite as slick in there as it is in MS Office applications.

I still have 3 weeks to wait for the delivery of my ErgoDox EZ. I’m committed to doing most of my work using the Dvorak layout for those 3 weeks so that there’s less of a transition when it finally arrives.

I’m going to document all of the trials and tribulations of reprogramming my brain here. My goal is to be at my “normal” level of keyboarding speed within 6 months. I’ll let you know how that works out.

60 Days of Euler in F# - Problem 53

The Problem

There are exactly ten ways of selecting three from five, 12345:

123, 124, 125, 134, 135, 145, 234, 235, 245, and 345

In combinatorics, we use the notation, 5C3 = 10.

In general, equation ,where r ≤ n, n! = n×(n−1)×...×3×2×1, and 0! = 1.

It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066.

How many, not necessarily distinct, values of nCr, for 1 ≤ n ≤ 100, are greater than one-million?

The Solution

Thankfully, the problem definition has already given us the hard part of this problem. That is, figuring out the number of combinations for nCr.

The words "in general" in the problem definition made me nervous, but I couldn't think of any special cases that would apply here.

let rec fact n =
    match n with 
    | 0 -> 1I
    | 1 -> 1I
    | _ -> bigint(n) * fact (n-1)

let rec numCombos n r =
    fact n / ((fact r) * (fact (n - r)))

The numCombos function returns the number of combinations for a given n and r.

Now we can solve the problem:

seq {
    for n in 1..100 do
        for r in 1..n do
            yield (n,r)
|> (fun (n,r) -> numCombos n r)
|> Seq.filter (fun n -> n > 1000000I)
|> Seq.length

The problem definition specifies 1 ≤ n ≤ 100. Therefore 1 ≤ r ≤ n because you can't take more from n than n.

We'll start by generating a sequence of all possible n paired with the possible r values for that n.

Next, we generate the number of combinations for each (n,r) pair.

Finally we filter out the values where the number of combos is more than one million and count them. That is the answer.

60 Days of Euler in F# - Problem 52

The Problem

It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order.

Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits.

The Solution

Now that we've passed problem 50, the problems start to get harder. I'm going to skip around a bit. I've gone directly from problem 50 to 52 because I haven't (yet) made my problem 51 solution sufficiently fast. But I'm getting there.

To solve this problem, the first thing we need is a function to determine if n times m contains the same digits as as n.

let checkMultiple (n : int) (ns : string) (m : int) =
    let multiple = (n * m).ToString()
    multiple.Length = ns.Length && 
    (ns |> Seq.forall (fun d -> multiple.IndexOf(d) >= 0))

The checkMultiple function takes a number, a string representation of that number, and a multiplier as input. It multiplies n * m and converts the result to a string. If that string has the same length as ns and contains all the same characters as ns, then we've found a match.

let isAnswer n =
    let ns = n.ToString()
    seq { 2..6 }
    |> Seq.forall (fun m -> checkMultiple n ns m)

The isAnswer function examines an n. If the checkMultiple function returns true for n multiplied by 2..6, then it returns true.

Now we can find the answer.

seq { 1..System.Int32.MaxValue }
|> Seq.find isAnswer

60 Days of Euler in F# - Problem 50

The Problem

The prime 41, can be written as the sum of six consecutive primes:

41 = 2 + 3 + 5 + 7 + 11 + 13

This is the longest sum of consecutive primes that adds to a prime below one-hundred.

The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953.

Which prime, below one-million, can be written as the sum of the most consecutive primes?

The Solution

Problem 50! I think after solving this one, I earn some sort of prize. I'm hoping for a luxury vacation, but I'm not holding my breath.

The first thing we need is the list of primes below 1000000. We'll start by stealing some code from problem 35 to generate those.

let intsqrt i = int(sqrt(float i))

let isPrime i =
    if i <= 1 then false
    elif i = 2 then true
    elif (i &&& 1) = 0 then false
        let sr = intsqrt i
        seq { } |> Seq.forall (fun f -> i%f<>0)

let rec nextPrime x =
    match x with
    | x when isPrime x -> x
    | x -> nextPrime (x + 1)

let getPrimesBelow max =
    let primeGenerator candidate =
        if candidate > max then
        elif candidate = 2 then
            let next = nextPrime candidate
            if next >= max then

    Seq.unfold primeGenerator 2

let target = 1000000

let primes = getPrimesBelow target |> List.ofSeq

Now we have a list of primes. The plan of attack is to go through each and find the starting prime of the sequence that, when summed, adds up to a prime number n.

let isSumOfConsecutivePrimes n =
    let rec isSum candidates sum len =
        match candidates with
        | [] -> None
        | x::xs ->
            let newSum = sum + x
            let newLen = len + 1
            if newSum = n then Some(newLen)
            elif newSum > n then None
                isSum xs newSum newLen

    let rec findStartingPrime candidates =
        match candidates with
        | [] -> None
        | x::_ when x > n -> None
        | x::_ when x = n -> Some(n,1)
        | x::xs -> 
            match isSum xs x 1 with
            | Some l -> Some(n,l)
            | _ -> findStartingPrime xs

    findStartingPrime primes

isSumOfConsecutivePrimes starts by looping through each prime and determining if that prime is the start of the sequence we're looking for. The internal function isSum takes the list of subsequent primes, the current sum, and the length of the current sequence. If it gets to the end of the list of primes, it returns None. Otherwise, if it hits the sum we're looking for, it returns the length of the sequence that generated the sum.

This is a brute force way of solving the problem. I am certain there are other, better ways to do it. But this one works.

Full disclosure: in order to get this to run under the 1-minute time limit, I had to compile it with full code optimizations turned on. To get it to run in under a minute in FSI, I had to run it in parallel.

Here is the single-threaded code that returns the answer:

|> isSumOfConsecutivePrimes
|> Seq.choose (fun x -> x)
|> Seq.maxBy (fun (_,len) -> len)
|> fst

And here's the parallel version:

let isSumOfConsecutivePrimesAsync n = async {
    return isSumOfConsecutivePrimes n

|> isSumOfConsecutivePrimesAsync
|> Async.Parallel
|> Async.RunSynchronously
|> Seq.choose(fun x -> x)
|> Seq.maxBy (fun (_,len) -> len)
|> fst

60 Days of Euler in F# - Problem 49

The Problem

The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases by 3330, is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the 4-digit numbers are permutations of one another.

There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property, but there is one other 4-digit increasing sequence.

What 12-digit number do you form by concatenating the three terms in this sequence?

The Solution

First, let's write a function to generate a series of 3 numbers that increases by 3330.

let series n = [n; n+3330;n+3330+3330]

Next, we need a function to determine if all elements in a list contain exactly the same digits.

let haveSameDigits l =

    let first::others = 
        |> (fun x -> x.ToString())

    let containsChar (c : char) (s : string) =
        s.IndexOf(c) >= 0

    let rec haveSame (others : string list) =
        match others with
        | [] -> true
        | x::xs ->
            if (first |> Seq.forall (fun c -> containsChar c x)) then
                haveSame xs

    haveSame others

The haveSameDigits function takes a list l as input. It starts out by finding the first term in the list and separating it from all the others. Then it calls the internal haveSame function which checks all the values in others to see if each other element contains all the digits in first.

Now we need a way to determine if all the elements in a list are prime.

let intsqrt i = int(sqrt(float i))

let isPrime i =
    if i <= 1 then false
    elif i = 2 then true
    elif (i &&& 1) = 0 then false
        let sr = intsqrt i
        seq { } |> Seq.forall (fun f -> i%f<>0)

let allArePrime l = 
    l |> List.forall isPrime

The allArePrime function returns true if all the elements in the input list l are prime. The functions intsqrt and isPrime are old friends from many other Euler problems.

Now we need a function to return a sequence of primes.

let rec nextPrime x =
    match x with
    | x when isPrime x -> x
    | x -> nextPrime (x + 1)

let getPrimesBelow max =
    let primeGenerator candidate =
        if candidate > max then
        elif candidate = 2 then
            let next = nextPrime candidate
            if next >= max then

    Seq.unfold primeGenerator 2

Again, the getPrimesBelow function is familiar if you've been following this series. We're going to use it to generate a sequence of 4-digit primes since we know from the problem definition that the value we're looking for has 4 digits.

For our last helper function, we need a simple way to concatenate together a list of integers, since that's the format required for the answer.

let listToString l = 
    System.String.Join("", l |> (fun x -> x.ToString()))

Now we can solve the problem:

getPrimesBelow 10000
|> Seq.filter (fun n -> n > 1487)
|> (fun n -> series n)
|> Seq.filter allArePrime
|> Seq.filter haveSameDigits
|> listToString
|> Seq.head

We start by getting all primes below 10000 and then filtering out anything <= 1487. The problem definition gives us this starting point.

Next, we convert each element in the sequence into the series we're interested in. We filter out any of those series where not allArePrime and don't haveSameDigits.

And finally, we convert each element in the sequence to concatenated strings and return the head. That is the answer.

60 Days of Euler in F# - Problem 48

The Problem

The series, 11 + 22 + 33 + ... + 1010 = 10405071317.

Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000.

The Solution

I don't know what people working in C are doing to solve these problems that involve enormous integer values. But fortunately we're on the .NET stack and we have BigInteger. It makes solving this problem trivial.

let sum =
    Seq.unfold (fun state -> Some(state, state+1)) 1
    |> (fun n -> pown (bigint n) n)
    |> Seq.take 1000
    |> Seq.sum
let str = string sum
str.Substring(str.Length - 10)

We start out by generating natural numbers with Seq.unfold. We use to raise each element to its own power using pown. Then we take the first 1000 elements of that sequence. Then we sum those.

Next, we convert that number to a string. If you're curious, that string has 3001 characters in it. Last, we use Substring to get the last 10 digits of the string. That is our answer.

60 Days of Euler in F# - Problem 47

The Problem

The first two consecutive numbers to have two distinct prime factors are:

  • 14 = 2 × 7
  • 15 = 3 × 5

The first three consecutive numbers to have three distinct prime factors are:

  • 644 = 2² × 7 × 23
  • 645 = 3 × 5 × 43
  • 646 = 2 × 17 × 19.

Find the first four consecutive integers to have four distinct prime factors. What is the first of these numbers?

The Solution

Once again, we need primes. Lots of them. So we'll start by stealing the getSomePrimes function from yesterday.

let intsqrt i = int(sqrt(float i))

let isPrime i =
    if i <= 1 then false
    elif i = 2 then true
    elif (i &&& 1) = 0 then false
        let sr = intsqrt i
        seq { } |> Seq.forall (fun f -> i%f<>0)

let rec nextPrime i =
    match i with
    | i when isPrime i -> i
    | i -> nextPrime (i + 1)

let getSomePrimes num =
    let primeGenerator (candidate,count) =
        if count > num then
        elif candidate = 2 then
            let next = nextPrime candidate

    Seq.unfold primeGenerator (2,1)

let factors = getSomePrimes 1000 |> List.ofSeq

So how many primes do we need? As with yesterday's problem, I don't know. I'm going to pick 100 because "it sounds good" and adjust later if I need to.

Why 100? We're looking for 4 prime factors. If we generate 1000 primes and take the last 4, we get:

  • 7883
  • 7901
  • 7907
  • 7919

If you multiply those 4 numbers together you get 3,899,919,746,694,739. That's way out of 32-bit integer territory. Are we willing to bet that the answer is less than that? Yes, we are.

Now we'll write a function to get the prime factors of a number.

let f n =
    let rec getFactors (acc : Set<int>) (factors : int list) =
       match factors with
       | [] -> acc
       | x::xs -> 
            if n % (x*x) = 0 then
                getFactors (Set.add (x*x) acc) xs
            elif n % x = 0 then
                getFactors (Set.add x acc) xs
                getFactors acc xs

    getFactors Set.empty<int> factors

The function f takes a number n and returns its prime factors.

The recursive internal getFactors function simply starts with a list of factors and tests them all to see if they are factors of n. The problem definition clearly shows that squares of primes are allowed to be counted as a "distinct factor" so we account for that case.

Now we need a function to look at a number and see if it has the specified number of distinct prime factors. In fact, we need to know if several consecutive numbers have that property, so we'll take a list of numbers as input instead of just a single number. We need to verify that:

  • Each number has 4 distinct factors
  • The set of 4 numbers has 16 distinct factors

The problem definition doesn't come right out and say that "distinct prime factors" means "distinct across the 4 consecutive numbers", but you don't get the right answer without accounting for that.

let factorCount = 4

let requiredDistinct = 16

let haveDistinctPrimeFactors numbers =
    let numbersFactors = 
        |> f
        |> List.ofSeq

    let distinctCount =
        |> List.reduce (fun acc elem -> acc + elem)
        |> Set.count

    (numbersFactors |> List.forall (fun x -> (Set.count x) = factorCount)) &&
    (distinctCount = requiredDistinct)

The haveDistinctPrimeFactors function starts by computing a couple of values.

numbersFactors becomes a list of factors for each of the input numbers.

distinctCount is the count of the distinct factors across all 4 input numbers. The factors are of type Set so when we add them together, we wind up with the union of all 4 sets. Thus, the count of that union is the number of distinct factors.

If the count of distinct factors for each input is 4 and the count of distinct factors is requiredDistinct then the function returns true; otherwise, it returns false.

Now we can solve the problem:

Seq.unfold (fun state -> Some(state, state+1)) 647
|> Seq.filter (fun x -> haveDistinctPrimeFactors [x..x+3])
|> Seq.head

We start by using Seq.unfold to generate an infinite sequence of numbers starting at 647. The problem definition says that 644..646 is the first set of consecutive numbers of have 3 prime factors, so we'll start looking right after that.

Next, we filter out any values that don't have the required distinct prime factors and return the head of the resulting sequence. That is the answer.