## Comprised of

February 4th, 2015

I have just read an article about an extremely dedicated and efficient WikiGnome who has edited tens of thousands Wikipedia articles to change a single grammatical error – “is comprised of”.

My initial reaction was that the phrase was perfectly acceptable and the journalist’s dread of having published work that included the phrase was overblown.

I checked a dictionary, which list examples of the phrase:

http://dictionary.cambridge.org/dictionary/british/comprise

It is sufficiently common that it doesn’t jar.

However, the Wikipedian’s own explanation of why he opposes the phrase is logically sound:

https://en.wikipedia.org/wiki/User:Giraffedata/comprised_of

As is this note from the dictionary:

http://dictionary.cambridge.org/grammar/british-grammar/consist-comprise-or-compose

These sentences are standard English:

“Air consists of nitrogen, oxygen and other gases.”

“Air is composed of nitrogen, oxygen and other gases.”

“Air comprises nitrogen, oxygen and other gases.”

Sentences of this sort are commonly accepted but, I now accept, illogical:

“Air is comprised of nitrogen, oxygen and other gases.”

The phrase “is comprised of” merges the correct uses of consist and compose. It attempts to mean the same thing in the passive and active voice. It’s similar to “irregardless” being used to mean “regardless”: an opposite with the same meaning.

Whether we should use “is comprised of” is a contentious question, and many people feel that it’s fine. However, why do we instantly reject this sentence?

“Air is consisted of nitrogen, oxygen and other gases.”

This sentence is logically equivalent to one with “is comprised of”. Searching for the phrase “is consisted of” in the English Wikipedia turns up only 69 instances, mainly in user talk pages rather than the actual articles:

It seems likely that our acceptance of sentences as grammatical or not is based more on recognition and familiarity than on a strict logical evaluation of the words.

## Finding Reversed Words

November 23rd, 2014

Following on from coding experiments with using the decorator pattern to reverse strings in Java and with palindromes and string reversal in C#, I decided to search for the words in the English language that are the reverse of other words. The Devil lived, but Black Sabbath gave us Live Evil. To beat Sega takes ages. You’re upping the ante living near Etna.

I had a copy of a dictionary file from Ubuntu on my hard drive. To make life a little simpler, I used some PowerShell magic to remove the many words that end in “‘s” (there are no words that start “s'”) and to make the list all lower case:

PS M:data> Get-Content .\british-english.csv | ?{ $_ -NotMatch "'s$" } | %{ $_.ToLower() } | Sort-Object | Get-Unique | Set-Content british-english-without-apostrophe-s.txt The simplest algorithm for finding words that are the reverse of other words is to simply go through the whole list and then check whether any of the other words are the reverse of that word. To do this, we need a method to test if two strings are a reversed pair. Pushing the characters of the first string onto a stack and then popping them off as you check them against each character of the second string can achieve this: public bool AreReversedPair(string firstString, string secondString) { if (firstString.Length != secondString.Length) { return false; } var firstStringStack = new Stack<char>(); foreach (var c in firstString) { firstStringStack.Push(c); } foreach (var currentCharFromSecond in secondString) { var currentCharFromFirst = firstStringStack.Pop(); if (currentCharFromFirst != currentCharFromSecond) { return false; } } return true; } Next, the code for finding the pairs: public IEnumerable<ReversedWordPair> FindReversedWords(IQueryable<string> allWords) { var reversedWords = new LinkedList<ReversedWordPair>(); var reversedStringChecker = new StackReversedStringChecker(); foreach (var firstWord in allWords) { foreach (var secondWord in allWords) { if (reversedStringChecker.AreReversedPair(firstWord, secondWord)) { reversedWords.AddLast(new ReversedWordPair(firstWord, secondWord)); } } } return reversedWords; } This code is very straightforward, but not fast at all. The time complexity of the algorithm is O(n^2) because for each word, we need to check every other word. For a list with almost 73,000 words, this takes a long time. In spite of this, it does finish. I left the program running, went to dinner and found a list waiting for me when I came back. reversed-word-pairs.txt As the list of words is not going to change very often and I only need to run the algorithm once, I could just leave the program as it is. However, it would be nice to reduce the time complexity of the algorithm. The simplest way to do this would be to reverse each word and then check whether the list of all the words contains the reversed word (readers who are familiar with .Net may have noticed that I passed the list of words as an IQueryable  rather than an IEnumerable for the list of words). Depending on the data structure, checking whether the reversed string is a member of the set of words should be less than O(n). For example, retrieval from a Trie takes O(m) where m is the length of the string. This would leave us with O(nm) time. As with all optimisations, you’ve got to time the code to see whether you get a boost or not. My next task is to come up with a meaningful sentence with all words the reverse of the corresponding word at the other end of the sentence, with a palindrome at the centre. There must be something that can be made of Dennis, who sinned in the straw, only to get warts to stun his nuts. See if you can make a mirror sentence of your own. The complete code, along with some tests, can be found at: https://github.com/robert-impey/CodingExperiments/tree/master/C-Sharp/FindReversedWords ## Fizz Buzz with Functional Programming October 11th, 2014 Fizz Buzz is a counting game where players count upwards saying either the number, “Fizz!” if the number is a multiple of 3, “Buzz!” if a multiple of 5, or “Fizz! Buzz!” if the a multiple of 3 and 5. It’s also a simple programming problem that can be solved in a number of ways. In C#, the solution could be as simple as: var max = 30; Console.WriteLine("With a for loop:"); for (var i = 1; i <= max; i++) { Console.Write(i + ": "); if (i % 3 == 0) { Console.Write("Fizz! "); } if (i % 5 == 0) { Console.Write("Bang!"); } Console.WriteLine(); } href=”https://github.com/robert-impey/CodingExperiments/blob/master/C-Sharp/FizzBang/FizzBang/Program.cs I’m going to show a way of solving this problem using F#. This is not the simplest way to solve this problem. However, the F# solution below does demonstrate the use of higher order functions, an important concept in functional programming. F# is a strongly typed language. This means that the compiler checks that the values that we bind and pass to and return from functions conform to its expectations. This catches a huge number of programmer errors almost as soon as they are made. It also allow the programmer to state his or her intentions by defining types. In this program, we are dealing with checking numbers that may or may not have the special property of causing us to say a message. We are going to need a function that can check numbers, so we define a type that describes such functions: type NumberChecker = int -> string option An example of such a function is let isEven x = if x % 2 = 0 then Some "That number's even!" else None This takes x and checks whether the remainder after dividing by 2 is 0. If so, it returns something (the message). Otherwise, it returns nothing. We can test this function using a match statement. We call isEven with a number. If the function returns a message (the case where there is Some message) we can print it. If the function returned None, then we’ll just print the number. let number = 4 match isEven number with | Some message -> printfn "%s" message | None -> printfn "%d" number This code is fine if we only want to check one number with one number checker. We want to be able to check numbers with different checker functions. For example, we might also define: let isOdd x = if x % 2 = 1 then Some "That number's odd!" else None To test this, we could duplicate our code: match isOdd number with | Some message -> printfn "%s" message | None -> printfn "%d" number Nobody likes duplicated effort. The only difference between these lines of code and the isEven printing code is the checker function. This is where a higher order functions come in. A higher order function takes a function as an input or returns a function as the output. let numberCheckerPrinter (numberChecker : NumberChecker) number = match numberChecker number with | Some message -> printfn "%s" message | None -> printfn "%d" number The first argument to this function is annotated as a NumberChecker, which we defined at the top of our program. We can pass into this function any number checker function we like and it will either print the message (if one is returned) or the number on its own. numberCheckerPrinter isEven 2 numberCheckerPrinter isEven 3 numberCheckerPrinter isOdd 2 numberCheckerPrinter isOdd 3 This has this output: That number's even! 3 2 That number's odd!  Note that the first argument (which happens to be a function) is passed to the function in the same way as the second argument (which happens to be an integer). We could go on defining number functions in the way, but we’re already beginning to repeat ourselves. The definition of the higher order function was a function that took a function as an input or returned a function. It would nice if the programming language could some of the work for us and make number checkers. All that stays the same from number checker to number checker is that they all must accept an integer and return either a message or nothing. We might have a number of number checkers that vary only in that they check a different divisor and have a different message. let divisorNumberChecker (divisor, message) number = if number % divisor = 0 then Some message else None Note that this function does not conform to the NumberChecker type that is defined at the top as it takes two arguments: a tuple of the divisor and the message and the number. We can use this function to make new number checkers by fixing the first input with partial function application. let fizz = divisorNumberChecker (3, "Fizz!") Even though divisorNumberChecker takes two arguments, we only supplied the first. This causes F# to return a new function which accepts the remaining argument and has fixed the first argument. Running this in F# interactive gives the type of fizz, which matches NumberChecker. > val fizz : (int -> string option)  Making the “Buzz!” checker is simply: let buzz = divisorNumberChecker (5, "Buzz!") We have functions for the “Fizz!” and the “Buzz!” part of the game, we now need to deal with the case when the number is divisible by 3 and 5. We could define a function to do this, but this a duplicated effort that we want to avoid. After all we have fizz and buzz, we want to reuse them. let andNumberChecker (f : NumberChecker, g : NumberChecker) x = match f x, g x with | Some messageF, Some messageG -> messageF + " " + messageG |> Some | _ -> None The andNumberChecker lets us combine two number checker functions into one. If both functions return a message for the given number, then it joins the messages together and returns them. Otherwise, it returns None. Again, I’ve use partial function application to fix the fizz and buzz functions to make fizzBuzz. let fizzBuzz = andNumberChecker (fizz, buzz) So far, I’ve been passing single functions as arguments to other functions. Functions can be treated as other objects in F#. Therefore, we can put them into a list and pass that list to a function. This way we can keep checking the same number with different checkers and use the message from the first one that returns something rather than nothing: let doManyChecks (numberCheckers : NumberChecker list) number = let message = List.fold (fun message numberChecker -> match message with | Some _ -> message | None -> numberChecker number ) None numberCheckers match message with | Some message' -> printfn "%s" message' | None -> printfn "%d" number let doFizzBuzzChecks = doManyChecks [ fizzBuzz; fizz; buzz ] We can use this to play the game: doFizzBuzzChecks 3 doFizzBuzzChecks 4 doFizzBuzzChecks 5 doFizzBuzzChecks 15 In FSI: Fizz! 4 Buzz! Fizz! Buzz!  Or to play the game with many numbers: [ 1 .. 30 ] |> List.iter doFizzBuzzChecks The complete code for this can be found here: https://github.com/robert-impey/CodingExperiments/blob/master/F-Sharp/Loose/FizzBuzz.fsx Functional programming has been described as a non-solution to a non-problem. Compared to the for loop in C#, this looks like a lot of work. If you have a problem as simple as Fizz! Buzz!, then it’s best to stick to the simplest solution. However, many interesting problems are much more complicated. Higher order functions allow for abstracting away the details and generalising code. We might add a rule of saying “Boom!” for primes. The code such a checker might be complicated and require extensive testing. The code that makes use of the checkers does not need to change in order to use this new checker, we simply add the function to the list of checkers. We can also combine it with other checkers, enabling code reuse. Functional programming is getting increasing attention because it allows programmers to closely focus their attention on just their problem and decouple that code from the part of the program that will make use of it. ## People don’t sit on Park Benches at Random March 16th, 2014 As I was approaching Berkeley Square at lunchtime on Thursday, I noticed a pattern in the way that the people were sitting on the park benches. Even though it was a sunny day, the square was not very full, and there were about twice as many bench seats as there were people. Nobody wanted to sit too close to another stranger (this is London, after all), so they sat the maximum distance apart that they could. This resulted in evenly distributed people – Empty, Person, Empty, Person, and so on. The sequence cannot be called random because the people are actively deciding where to sit. I decided to look at a simple random sequence in F#. To start off with, I decided to define a type for my program. This might not sound like a promising starting point for a program, but in F# it’s so painless that it is a good way to begin thinking about the domain and what states make sense in your domain. For more on this, see Scott Wlaschin’s slides on Domain Driven Design in F#. My domain is coin tossing. Therefore, I created the following discriminated union in F# interactive: > type CoinToss = Tails | Heads;; type CoinToss = | Tails | Heads This allows a coin toss to be either heads or tails but not both or neither. Static typing allows the program to make definite statements about the world. I also needed a random number generator: > let r = System.Random();; val r : System.Random F# allows you to define infinite sequences that can be evaluated lazily. The following is a potentially infinite sequence of random coin tosses. > let coins = Seq.initInfinite (fun _ -> if r.Next(2) = 0 then Heads else Tails);; val coins : seq<CoinToss> r.Next(2) means the next random integer less than 2 but greater than or equal to 0, that is a random 0 or 1. If the idea of an infinite sequence of coin tosses sounds weird and unruly, here’s how we can make use of them. The take function allows us to tame infinity. Or at least take a little bit of it. The following says “Take 10 of the randomly generated coins and pass them along (|>) to a function that iterates through them one at a time and prints them out” > Seq.take 10 coins |> Seq.iter (printfn "%A");; Heads Heads Tails Heads Heads Tails Tails Heads Tails Tails val it : unit = () That sequence is not very dissimilar from the lunchers on the park benches in the photo above. There are no long clusters of one thing (person, heads, etc.) or another (empty seat, tails, etc.). However, this isn’t always the case: > Seq.take 10 coins |> Seq.iter (printfn "%A");; Tails Tails Heads Heads Heads Tails Heads Tails Heads Heads val it : unit = () or even: > Seq.take 10 coins |> Seq.iter (printfn "%A");; Tails Tails Tails Tails Tails Heads Heads Heads Heads Heads val it : unit = () Five tails followed by five heads looks completely fixed. In a casino, you might start to get worried. But it happened. Trust me. One way to check if the coin is being tossed fairly, is to count how many times each face lands. This function does that: > let rec countCoins coins (heads, tails) = match coins with | [] -> heads, tails | hd :: tl -> let newCounts = match hd with | Heads -> heads + 1, tails | Tails -> heads, tails + 1 countCoins tl newCounts;; val countCoins : coins:CoinToss list -> heads:int * tails:int -> int * int The way to read this function is as follows. If the argument coins matches an empty list, return the counts for heads and tails as they are. Otherwise, coins must be a list with a first element (hd) and the remaining part of the part of the list (tl), which might be an empty list. We need to find the new counts of heads or tails by adding 1 to either count. Finally, we call the countCoins function again with the remainder of the list (tl). This will continue until we have stripped all the first elements from the list and tl is an empty list. The function then terminates as we have satisfied the first condition above. For convenience, I defined a function that gets a number of coin tosses and puts them into a list to be counted: > let getCoins numberOfCoins = Seq.take numberOfCoins coins |> Seq.toList;; val getCoins : numberOfCoins:int -> CoinToss list For a short list, the counts for each face might not be equal: > countCoins (getCoins 10) (0, 0);; val it : int * int = (6, 4) Note that the counts for heads and tails start off as zeroes. However, with a larger number of coins (in this case, pown 10 7 or 10 to the power of 7 or 10 million), the counts should both approach half the number of tosses: > countCoins (getCoins (pown 10 7)) (0, 0);; val it : int * int = (4997646, 5002354) ## Walking on Hampstead Heath March 16th, 2014 Living in London certainly makes one appreciate the few sunny days that we do get. Half of London seemed to be on Hampstead Heath this afternoon. It’s unseasonably warm at the moment. It is certainly very strange to see Londoners dressed in flip flops and shorts when the leaves haven’t even come on on the trees yet. I just hope that the good weather lasts! ## Using F# to minimise a function August 22nd, 2013 Finding the minimum of functions is at the heart of optimisation. Mathematicians, engineers and programmers have come up with a large number of approaches to solving this problem, including differentiation, genetic algorithms and even exhaustive search. Consider a quadratic function such that could be written in F# as let f x = (x ** 2.0) - (2.0 * x) + 1.0 Finding the minimum means finding the input value for the function that returns to lowest value. If we plot the curve, then the minimum is the lowest point of the curve. One way to find this is find the derivative of the function: (2.0 * x) - 2.0 and solve the equation where the derivative is equal to 0, which is when x is 1. This probably the best way to solve this problem in practice. However, not all functions have derivatives that are easy to find. Therefore, an alternative way to minimise a function is an exhaustive search of the inputs in some range. This is not an elegant or generally efficient solution, but it works. In F#, we might proceed as follows. We define the range that we want to search and the step between candidate inputs: let min = 0.0 let max = 10.0 let step = 0.01 We know where to start searching- with the lowest candidate input: let firstCandidate = f min, min This creates a tuple of two floats, the first being the output and the second being the lowest candidate input. We also want a sequence of tuples of two floats that are the remaining candidate solutions: let remainingCandidates = seq { for c in min + step .. step .. max do yield f c, c } Note that at this point the sequence has not been enumerated and the function has not been run with each of the candidate inputs. Because sequences are evaluated lazily, the function will not be run for each of the candidate inputs until it is asked for. We are trying to minimise the function, therefore we need a function that can compare the first elements of two candidate solutions: let findMin currentMinSln candidateSln = match fst currentMinSln < fst candidateSln with | true -> currentMinSln | false -> candidateSln Running this code in fsi shows its type to be: val findMin : 'a * 'b -> 'a * 'b -> 'a * 'b when 'a : comparison The F# compiler can infer that the function takes in two tuples, each with two elements. The tuples must be of the same type and the first element of each tuple must be comparable. Way to go, type inference! Everything has been set up at this point. We just need to run the code: let minSln = Seq.fold findMin firstCandidate remainingCandidates The fold function is to reduce a sequence to a single value, starting with a given accumulator. In this case, the first candidate solution that we created earlier is our starting point. The output of the function for each candidate input is compared to that accumulator. Running the code finds the same answer (1) that we found with calculus. This code runs pretty quickly, but this approach is generally slow. Our range is only 10 wide and the step is 0.01, so there are only 1000 candidate inputs. Increasing the size of the range or decreasing the step would increase the number of inputs. More worryingly, the size of the search space increases exponentially as the number of inputs to the function increases. So a function that took two inputs for the same range for each input would have a million candidate inputs, three inputs would take a billion and so on. However, it is also quite straightforward to parallelise this approach. The sequence of candidate solutions could be split up into partitions and each partition could be sent off to a different computer. Each batch would find a local minimum for the range it was given. Finding the minimum for the whole of our range of inputs is simply a matter of find the minimum in the returned list. The complete code for this can be found here: https://github.com/robert-impey/CodingExperiments/blob/master/F%23/Loose/MinimiseQuadratic.fs ## Project Euler 1 in F# using Sequences August 21st, 2013 I have written previously about solving the first problem on the Project Euler website using F# and Haskell. The problem is to find the sum of the natural numbers that are divisible by 3 or 5 that are less than 1000. To solve this in F#, my first solution looked like this: [0..999] |> List.filter (fun x -> x % 3 = 0 || x % 5 = 0) |> List.sum This works. However, it was pointed out to me that using lists to generate the numbers below 1000 in my F# solution was memory hungry as the list will be created and stored in memory then piped to the filter and so on. The list is evaluated eagerly. This isn’t a problem with a small list like this, but it could create issues with more elements. I took a look at sequences in F#, which are evaluated lazily. To get an idea of what this means, consider the sequence of natural numbers: let countingNumbers = seq { for i in 1 .. System.Int32.MaxValue do printfn "Yielding: %d" i yield i } If you are unfamiliar with lazy evaluation, it might look like this will create all the natural numbers up to System.Int32.MaxValue (2147483647) and print each number as it goes. However, if you run this with F# Interactive (aka fsi), it creates a seq<int> without printing anything out. At this point, the sequence is yet to be enumerated. The ingenious thing about sequences is that we can work with them without enumerating them. Consider these lines: let max = 999 let firstUpToMax = Seq.take max countingNumbers The Seq.take function allows us to take the first elements in a sequence. However, running these lines in fsi does not cause the for loop in the sequence above to be run. The print and yield statements are not run. F#’s ability to delay enumeration is not limited to sequences. Queries also allow us to describe a sequence of numbers without enumerating them. I define the following function that will be used to filter the sequence: let isDivisibleBy3Or5 x = x % 3 = 0 || x % 5 = 0 and then create this query: let divisibleBy3Or5 = query { for countingNumber in firstUpToMax do where (isDivisibleBy3Or5 countingNumber) select countingNumber } Programmers who are familiar with SQL or LINQ should have no problem understanding this query. In plain English, we might say “we will go through the sequence and find the values that match the given criterion.” Note the use of the future tense. Running this code in fsi does not result in enumeration of our sequence and the printing of the “Yielding…” lines. I could find the sum of the numbers matching our criteria using a built in function like this: let seqSum = Seq.sum divisibleBy3Or5 This will cause the sequence to be enumerated and finds the same sum as the list method above. However, by defining the following function: let noisySum total next = printfn "Adding %d to %d" next total total + next I will be able to see the order in which the sequence is enumerated and when the values are pumped down the pipeline to be folded into the sum. let seqFoldSum = divisibleBy3Or5 |> Seq.fold noisySum 0 At this point we get the following out put at fsi: Yielding: 1 Yielding: 2 Yielding: 3 Adding 3 to 0 Yielding: 4 Yielding: 5 Adding 5 to 3 Yielding: 6 ... Yielding: 996 Adding 996 to 231173 Yielding: 997 Yielding: 998 Yielding: 999 Adding 999 to 232169 val seqFoldSum : int = 233168 Which clearly demonstrates the order of execution and that only the numbers that are divisible by 3 or 5 are added to the sum. Does this make much difference to the memory usage? For this problem, this is not the bottle neck. The integers storing the sum of the numbers overflow before the input lists become large enough to use a lot of memory. However, passing values down the pipeline as they are yielded is somehow more pleasing to this programmer. Also, lazy evaluation means that enumerating the numbers and performing the mathematics do not take place until the result is actually needed. By creating a sequence and query, the programmer can create the code and pass it around the program without doing any heavy computation or using up much memory. The complete listing of this code can be found at GitHub: https://github.com/robert-impey/CodingExperiments/blob/master/F%23/Loose/Euler1.fs ## Finding the Nearest Tube Station with LINQ August 20th, 2013 I recently wrote a little command line program in C# that can tell you the name of the nearest tube station. I’ve put the program on GitHub in my Coding Experiments repository: https://github.com/robert-impey/CodingExperiments/tree/master/C%23/NearestTube The interface is very simple- this more of an experiment than something that I intend for mass consumption! You enter a location via the command line as the latitude and longitude: The starting point of the program was to calculate the distances between points. To do this I adapted some JavaScript code that John D. Cook wrote: http://www.johndcook.com/lat_long_distance.html Mathematical code looks very similar in many languages, and the translation from JavaScript to C# was trivially simple as the languages are very similar in this case. This code is part of the Point class:  /// <summary> /// Porting JavaScript code from /// http://www.johndcook.com/lat_long_distance.html /// </summary> /// <param name="that"></param> /// <returns></returns> public double Distance(Point that) { // Compute spherical coordinates double rho = 6373; // convert latitude and longitude to spherical coordinates in radians // phi = 90 - latitude double phi1 = (90.0 - this.Latitude) * Math.PI / 180.0; double phi2 = (90.0 - that.Latitude) * Math.PI / 180.0; // theta = longitude double theta1 = this.Longitude * Math.PI / 180.0; double theta2 = that.Longitude * Math.PI / 180.0; // compute spherical distance from spherical coordinates // arc length = \arccos(\sin\phi\sin\phi'\cos(\theta-\theta') + \cos\phi\cos\phi') // distance = rho times arc length return rho * Math.Acos( Math.Sin(phi1) * Math.Sin(phi2) * Math.Cos(theta1 - theta2) + Math.Cos(phi1) * Math.Cos(phi2)) * 1000; } Once I was able to calculate the distances between points on the map, I needed to be able to sort the tube stations of London by distance from the given point. This is the sort of code that LINQ to objects handles very naturally. In the SequentialTubeStationFinder class, I have the following method:  public TubeStation FindNearestTubeStation(Point point) { return (from tubeStation in tubeStations orderby tubeStation.Point.Distance(point) select tubeStation).First(); } tubeStations is a generic list of TubeStation objects. Each has a Point property that is used to sort the tube stations and find the nearest one to our location. The declarative style of programming that LINQ uses is much easier to read (and therefore maintain) than the equivalent code written with a for loop. ## Trying F# March 18th, 2013 As part of my ongoing interest in functional programming languages, I have decided to try F#. I have been looking at the Try F# page: http://www.tryfsharp.org/ This provides an online REPL environment for exploring the language. I have a number of students at school who are exploring JavaScript and Python as first languages through Code Academy. I thought it would be a useful experiment to try this sort of educational activity with an unfamiliar language myself. At first glance, I quite like the learning experience of reading through explanations and running some code, although it’s not as much fun as trying to make something yourself. In order to consolidate my learning, I tried to solve the first of the problems in Project Euler, which is to find the sum of the natural numbers less than 1000 that are multiples of 3 or 4. (I have already done this in Haskell). I came up with this: [0..999] |> List.filter (fun x -> x % 3 = 0 || x % 5 = 0) |> List.sum ## One liner to show logs without Rotated Backup files May 25th, 2012 I’ve been looking at the Apache log files on a web server this morning. There are many virtual hosts on the machine and the log rotation scripts have created many numbered backup files of the logs. To make the directory listing more readable, I have been using the following one-liner: ls -l /var/log/apache2 | grep -Ev -e '[[:digit:]]+(\.gz)?$'

This will only display the current log files, assuming that /var/log/apache2 is the directory in which you store your Apache logs and that you do not store any other files there.

I hope it helps.