I decided to have a go at generating pairs of amicable numbers using Linq. This post explains what they are, and how I went about it.

The post Finding amicable numbers with Linq appeared first on Dot Net What Not.

]]>Anyway, I was contemplating the idea of amicable numbers last night. The short explanation of these is as follows…

An “amicable pair” of numbers consists of two numbers, `p`

and `q`

where `p`

is the sum of `q`

‘s divisors, and `q`

is the sum of `p`

‘s divisors. The smallest such pair is 220 and 284. The divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110, which add up to 284, and the divisors of 284 are 1, 2, 4, 71 and 142, which add up to 220.

So, I decided to see if I could write some Linq to find pairs of amicable numbers. As usual, my interest here was in elegant code, not necessarily the most efficient algorithm.

A “perfect” number is one that is the sum of its divisors. For example, the number 6 can be divided by 1, 2 and 3 (ignoring 6 itself), and 1 + 2 + 3 = 6. There aren’t that many of these around, 6, 28, 496 and 8128 being the only ones less than 100,000, as we can see…

Finding perfect numbers was fairly easy. Note that when you look for divisors of a number `n`

, you only need to go as far as `n / 2`

, as there can’t be any divisors (other than `n`

itself) greater than that. If it’s not clear why that is, try picking some numbers and writing down their divisors. So, to find the divisors of a number `n`

, all we need to do is generate a sequence of numbers 1 to `n / 2`

, and see which numbers evenly divide into `n`

. Et voila…

Enumerable.Range(1, n / 2).Where(n1 => n % n1 == 0)

Finding all perfect numbers less that (say) 1000 is now as easy as…

Enumerable.Range(1, 1000) .Where(n => Enumerable.Range(1, n / 2).Where(n1 => n % n1 == 0).Sum() == n)

This gives the first three perfect numbers.

Note that we switch to using `p`

and `q`

instead of `n`

to make it clearer which number in the pair we mean.

To find amicable pairs, we can do the following for every number `p`

in our target range…

- Calculate the sum of
`p`

‘s divisors. This gives us a second number`q`

which is to be checked to see if it forms an amicable pair with`p`

- Calculate the sum of
`q`

‘s divisors and see it is is equal to`p`

. If so, we have an amicable pair

So, a first bash at this could look like…

Enumerable.Range(1, 1000) .Select(p => new { P = p, Q = Enumerable.Range(1, p / 2).Where(p1 => p % p1 == 0).Sum() }) .Where(data => data.P == Enumerable.Range(1, data.Q / 2).Where(q1 => data.Q % q1 == 0).Sum())

The `Select`

clause returns an anonymous type (and yes, I could just as easily have used a tuple) that contains the original number `p`

, and the sum of its divisors, ie our candidate `q`

.

The `Where`

clause then filters this list for the cases where the sum of `q`

‘s divisors equals `p`

.

This is fine, but ignores two issues. First, every perfect number forms an amicable (if somewhat anti-social) pair with itself. This is obvious, as the sum of `p`

‘s divisors obviously adds up to `p`

for a perfect number. Secondly, every amicable pair appears twice, once with the smaller number first and once with the larger number first. In other words, the above code returns the following…

P | Q |
---|---|

6 | 6 |

28 | 28 |

220 | 284 |

284 | 220 |

496 | 496 |

As you can see, this list includes 6, 28 and 496, the first three perfect numbers, but also includes the amicable pair (220, 284) twice, once like that and once as (284, 220).

Therefore, our algorithm above has to be modified to exclude these cases. I originally ~~wasted~~ spent some time handling the two cases separately, until it dawned on me that both cases could be considered by only including pairs where the first number was less than the second. This left me with the following…

Enumerable.Range(1, 5000) .Select(p => new { P = p, Q = Enumerable.Range(1, p / 2) .Where(p1 => p % p1 == 0).Sum() }) .Where(data => data.P < data.Q && data.P == Enumerable.Range(1, data.Q / 2) .Where(q1 => data.Q % q1 == 0).Sum())

Using 5000 as the upper bound, this took about a second to find the first three amicable pairs.

The post Finding amicable numbers with Linq appeared first on Dot Net What Not.

]]>The post Did I miss something here? appeared first on Dot Net What Not.

]]>I hovered over the first one (hexagon with a heart in the middle) and the following popped up…

If he isn’t sponsoring any organisations or users, then why show the badge?

The post Did I miss something here? appeared first on Dot Net What Not.

]]>The post Exporting a database from Azure and importing it into SQL Server appeared first on Dot Net What Not.

]]>We had a database in Azure that we wanted to move to non-Azure server. You would think that backing up a database to a file would be a simple task. Well it wasn’t.

Aside:Don’t be tempted to use the SSMS Import-Export wizard to do this. I did that on another database, and thought all had worked until a couple of days later when the client reported an error. After some very frustrating hours trying to work out why I was getting an exception about a null primary key (which it clearly wasn’t), I discovered that when the wizard created the new database, it had missed out some vital parts, like setting Identity on the primary keys!

After going round in circles on the portal, I discovered that there is a really quick and easy way to this using tools you probably already have on your PC.

When you install SQL Server Management Studio, it also installs Azure Data Studio (ADS). I’d never looked at this before, but now wish I had. It’s a bit like SSMS but for Azure, and makes life sooo much easier.

To backup an Azure database, you need to install an extension to ADS. Click the Extensions icon (bottom one, highlighted with a fab hand-drawn squiggle in the screenshot) and then type “SQL Server bacpac” in the search box. As you can see, I already have it installed…

After installing that, you need to connect to the Azure server that has your database. On the Home page (which might be titled Welcome) click the “Create a connection” button…

Fill in the details in the panel that pops up, and click the Connect button. This should connect you to the server, and allow you to see your database(s)…

Right-click the database you want to export and choose “Data-tier Application Wizard”…

Next, you need to choose the operation you want to perform. To export the database, choose the last option…

In the next step, set the file location (the server and database will already be populated, so you can leave those as they are) and click Next.

This gives you a summary of what you are about to do, which is pretty useless as it only reflects the three options in the immediately previous step!

Click Export, and ADS will go off and do its stuff. You’ll see the progress of the export in the Tasks panel.

I first did this on my lap top, connected via Remote Desktop, and got myself all confused when I couldn’t see the bacpac backup file when looking at File Explorer on my main PC! Duh, been a long day.

I then tried the export again from my PC, but found that ADS didn’t have the “Data-tier Application Wizard” option…

I have exactly the same version of ADS on both machines, and both are running up-to-date installations of Windows 11, so I don’t know why the main PC didn’t show the option. I didn’t investigate further, as I already had by bacpac file by then, and needed to get it imported.

Start up SSMS and connect to the server where you want to install your database.

In the Object Explorer panel, right-click Databases and choose “Import Data-tier Application”…

Click past the “*Hello, I just want to annoy you by telling you what this wizard does, even though you could figure it out for yourself*” page and choose the bacpac file you saved earlier.

In the next step change the database name to whatever you want and click Next. You can then click through until it starts the import.

And that’s it! All took very little time, especially compared to the hours I wasted trying to work out how to do all of this in the Azure portal.

The post Exporting a database from Azure and importing it into SQL Server appeared first on Dot Net What Not.

]]>The post Symbolic differentiation in C# appeared first on Dot Net What Not.

]]>One of the sections showed how to do symbolic differentiation in Lisp. For those not familiar with this, it’s a mathematical concept that, in it’s simplest understanding allows you to find the gradient of a line at any point. This is a lot more important in maths than you might think, and is a fundamental part of any course in maths. For a gentle introduction to differentiation, including an interactive differentiator, see this page.

The Lisp they wrote to differentiate expressions was quite short and elegant. You can see the sample code here. Even if you don’t understand Lisp, it’s pretty impressive how much they achieved with so little code.

Being an incurable tinkerer, I wondered how hard it would be to write such code in C#.

One of the (many) nice things about Lisp is the ease with which you can build data structures. As lists are built in, they provide a very simple way of structuring your data. The authors took advantage of this and represented expressions as nested lists, where each list represents one part of the full expression.

For example, a simple expression like `2x`

could be represented as a single list `'(* 2 x)`

. Note that Lisp uses prefix notation, so the operator comes first, and the whole list is annotated with a ```

to indicate that it should not be evaluated, but treated as a literal value.

A more complex expression can be built up by inserting lists where the previous example had a symbol or value. For example, we can represent `3x + 2`

as `'(+ (* 3 x) 2)`

and so on. Once you are used to prefix notation, this is pretty easy to read, and is quite close to the mathematical representation.

I wanted to achieve the same in C# if it were possible.

For simplicity, I assume that I would only handle three types of expression…

- An integer constant
- A symbol that represents a variable, eg the “x” in (2x + 2). Note that we can have multiple symbols in an expression, but will only differentiate by one of them
- A combination of two other expressions, using a binary operator, eg (1 + 2) or (exp1 * exp2) where exp1 and exp2 are previously defined expressions

For simplicity, we are assuming all numbers involved are integers, and so only support *, + and -, as / could result in non-integers. Actually, that was later modified as I realised that I would need to support ^ as well to avoid unpleasantly complex-looking expressions.

My initial thought was to have an empty `DifExpInterface`

(`DifExp`

being short for “differentiable expression”), and define three classes that inherited from this. This would allow me to write methods that could handle any of the three sub-types, and switch on the type to handle them differently. This worked fine, but gave some really ugly looking code when I tried to construct expressions, as I needed to include the types when creating new objects.

I then switched to a single `DifExp`

class that contained a `Type`

property that specified the type. I also needed properties for the value (if it were an integer), the symbol name (for a symbol) or the three parts of the expression (first operand, operator and second operand) for an expression. This didn’t feel so elegant, but made the construction much neater (see below).

The second design decision I didn’t really like was to use hard-coded strings for operators, instead of an enum. Again, this was to enhance readability when constructing an expression.

Adding in an override for `ToString()`

, the basic class looked like this…

class DifExp { private DifExpType Type { init; get; } private int Value { init; get; } private string Symbol { init; get; } = ""; private (DifExp E1, string Op, DifExp E2) Expression { init; get; } public DifExp(int value) { Type = DifExpType.Value; Value = value; } public DifExp(string symbol) { Type = DifExpType.Symbol; Symbol = symbol; } public DifExp(string symbol, int power) { // This ctor is used for raising a symbol to an integer power Type = DifExpType.Expresssion; Expression = (new(symbol), "^", new(power)); } public DifExp(DifExp e1, string op, DifExp e2) { if (!new[] { "+", "*", "-", "^" }.Contains(op)) { throw new ArgumentException($"Unsupported operator: {op}"); } Type = DifExpType.Expresssion; Expression = (e1, op, e2); } public override string ToString() => Type switch { DifExpType.Value => Value.ToString(), DifExpType.Symbol => Symbol, DifExpType.Expresssion => $"({Expression.E1} {Expression.Op} {Expression.E2})" }; public enum DifExpType { Value, Symbol, Expresssion } }

The astute reader may notice that adding a symbol expression requires naming the symbol, eg `new("x")`

. The reason for this is that there is no real reason why an expression has to be over a single symbol, it would be perfectly reasonable to allow the code to handle expressions over multiple symbols, such as `x`

. If so, you need to specify which symbol is to be used for the derivation. This allows for partial derivatives.^{2}y^{2} + xy

As you can see, I added constructors for each of the three basic types, value, symbol and expression, as well as the later addition of a constructor for x^{n}. To keep things simple, I only allowed a symbol to be raised to an integer power.

This allowed me to construct expressions as shown below. The comments show the result of calling `ToString()`

…

DifExp de1 = new(new(1), "*", new(2)); // (1 * 2) DifExp de2 = new(new("x"), "+", de1); // (x + (1 * 2)) DifExp de3 = new(new(2), "*", new("x")); // (2 * x) DifExp de4 = new(de3, "+", new(10)); // ((2 * x) + 10) DifExp de5 = new(new("x"), 2); // (x ^ 2)

As you can see, if you mentally remove the uses of `new`

, then all but the last line read almost like valid mathematical expressions. That benefit overrode my desire to have separate subclasses and an enum for the operators.

The first two expressions could be simplified, but that was left as an exercise for later.

This turned out to be a lot simpler than I expected. As the basic rules for differentiation aren’t actually that difficult, the code ended up being a single `switch`

…

public DifExp Differentiate(string symbol) => Type switch { DifExpType.Value => new(0), DifExpType.Symbol => symbol == Symbol ? new(1) : new(Symbol), DifExpType.Expresssion => Expression.Op switch { "+" => new(Expression.E1.Differentiate(symbol), "+", Expression.E2.Differentiate(symbol)), "-" => new(Expression.E1.Differentiate(symbol), "-", Expression.E2.Differentiate(symbol)), "*" => new(new(Expression.E1.Differentiate(symbol), "*", Expression.E2), "+", new(Expression.E1, "*", Expression.E2.Differentiate(symbol))), "^" => new(new(Expression.E2.Value), "*", new(new(symbol), "^", new(Expression.E2.Value - 1))) } };

At this stage, I had a working differentiator. There are obviously a lot of things that could be done to expand this, such as adding more derivation rules and allowing a wider variety of expressions, but given that this was only an exercise, and I had already expanded the functionality over the code shown in the book, I decided to address the one remaining niggle…

The first expression I created above was simply the sum of two integers…

DifExp de1 = new(new(1), "*", new(2));

However, this is not simplified, and is stored as `1 + 2`

. Similarly, when differentiating, expressions would often end up including terms that could be removed or simplified. For example, creating and differentiating as follows…

DifExp de2 = new(new("x"), "+", new(new(1), "*", new(2))); DifExp de2diff = de2.Differentiate("x");

…results in the differentiated expression being represented as `(1 + ((0 * 2) + (1 * 0)))`

. This can obviously be simplified to just `1`

.

The book showed a method of simplifying expressions, but as I was too lazy to get out of my chair and fetch the book from the other room, I decided to roll my own ().

I decided to simplify when the expression was created, so we were always storing the simplest possible representation. Clearly the only constructor that needed simplifying was the one that took two expression and an operator. I could see four obvious simplifications to start with…

- If both expressions are values we can combine them with the operator to produce a single value (eg
`1 = 2`

is simply`3`

) - If we are multiplying, and one expression is a value of zero, then we can simplify to a value of zero
- If we are multiplying, and one expression is a value of one, then we can simplify to the other expression
- If we are adding, and one expression is a value of zero, then we can simplify to the other expression

There are other simplifications that could be added, such as converting `x + x`

to `2 * x`

and so on. I didn’t have time to add those as well, but realised that most of them are actually redundant if you set up your original expressions in the simplest way possible. For example, if you do `new(new("x"), 2)`

instead of `new(new("x"), "*", new("x"))`

, then (as far as I can see) you’ll never end up with `x + x`

in the first place.

Coding these up wasn’t too hard, and worked fine. However, I realised that when differentiating, you sometimes needed to simplify more than once, as the first simplification could still result in expressions that could be further simplified. No problem, just make the simplify method recursive.

Ha, that’s where it all went wrong! As I was simplifying in the constructor, the simplify method got called every time I created a new expression, which led to an infinite loop when creating even the most simple expression. I won’t bore you with the sorry tale of how many hours I spent breaking my head over this, but it took longer than the rest of the project combined!

So, after much tearing of hair and gnashing of teeth, I ended up with the following…

public static DifExp Simplify(DifExp e) { if (e.Type != DifExpType.Expresssion) { return e; } return Simplify(e.Expression.E1, e.Expression.Op, e.Expression.E2); } public static DifExp Simplify(DifExp e1, string op, DifExp e2) { DifExp e1s = Simplify(e1); DifExp e2s = Simplify(e2); if (e1s.Type == DifExpType.Value && e2s.Type == DifExpType.Value) { // Both expressions are values, so combine them wth the operator specified return new(op switch { "+" => e1s.Value + e2s.Value, "*" => e1s.Value * e2s.Value, "-" => e1s.Value - e2s.Value }); } else if (op == "*" && (e1s.Type == DifExpType.Value && e1s.Value == 0) || (e2s.Type == DifExpType.Value && e2s.Value == 0)) { // We are multiplying, and one expression is a value of zero, then we are a value of zero return new(0); } else if (op == "*" && e1s.Type == DifExpType.Value && e1s.Value == 1) { // We are multiplying, and the first expression is a value of one, then we are the other expression return e2s; } else if (op == "*" && e2s.Type == DifExpType.Value && e2s.Value == 1) { // Ditto the previous comment for the second expression return e1s; } else if (op == "+" && e1s.Type == DifExpType.Value && e1s.Value == 0) { // We are adding, and the first expression is a value of zero, then we are the other expression return e2s; } else if (op == "+" && e2s.Type == DifExpType.Value && e2s.Value == 0) { // Ditto the previous comment for the second expression return e1s; } // Nothing to simplify, so return a new expression return new(e1s, op, e2s, false); }

This includes all of the cases listed above, although could probably be simplified if I had a clear enough head to think about it!

There are two overloads, as this allowed me to simplify a single previously-existing expression, or simplify one being constructed from two expressions and an operator. It’s possible that I could get away without this after I added the optional constructor parameter (see next paragraph), but I had had enough by this point. I had achieved more than I originally set out to do, and really needed to do something more productive with my time!

This was called from the constructor that took two expressions and an operator…

public DifExp(DifExp e1, string op, DifExp e2, bool simplify = true) { if (!new[] { "+", "*", "-", "^" }.Contains(op)) { throw new ArgumentException($"Unsupported operator: {op}"); } if (simplify) { DifExp exp = Simplify(e1, op, e2); Type = exp.Type; Value = exp.Value; Symbol = exp.Symbol; Expression = exp.Expression; } else { Type = DifExpType.Expresssion; Expression = (e1, op, e2); } }

As I mentioned, I had a problem with infinite loops, and needed some way of avoiding these. I ended up modifying the constructor above to take an optional parameter to specify if we were to simplify the expression. We would generally want to do this, and only want to avoid it in the penultimate line of the `Simplify()`

method.

Once I had that working, I could differentiate quite complex expressions, and get a neat representation at the end.

The full code sample with some examples can be found in this gist.

Due to the static type system in C#, the code above is more complex than the Lisp, and I feel slightly harder to read. Given that this sort of symbolic manipulation is one of the super powers of Lisp, I guess that’s not surprising.

Compare the representations of `2x`

in the two languages…^{2} + 3x + 4

// C# new(new(new(new(2), "*", new(new("x"), 2)), "+", new(new(3), "*", new("x"))), "+", new(4))

; Lisp '(+ (+ (* 2 (* x x)) (* 3 x)) 4)

Bit of a difference in clarity!

The post Symbolic differentiation in C# appeared first on Dot Net What Not.

]]>The post How to add a post-publish event to Visual Studio appeared first on Dot Net What Not.

]]>`appSettings.json`

, but rather leave a correct one sitting on the server, and then just ignore the one created when publishing.
That works fine for manual publishing (ie to file, then manually copied to the server using FTP), as long as I remember not to copy the published one to the server! However, for automatic publishing, this won’t work.

I just discovered that you can add a command to be executed before or after publishing. I can’t find this documented anywhere on the MSDN docs, but have verified that it does work.

If you open your `.pubxml`

file, and add the following…

<Target Name="CustomActionsAfterPublish" AfterTargets="AfterPublish"> <Message Text="About to delete appSettings.json" Importance="high" /> <Exec Command='del "C:\Path\To\Published\Files\appSettings.json"' /> </Target>

…then after publishing, `appSettings.json`

will be deleted. I had to fiddle a bit with the single and double quotes to get this to work, but the way shown here is fine.

You can also run a command before publishing, using `BeforeTargets="BeforePublish"`

, but I’m not sure how useful that is.

The `<Message>`

line is documented, but far less useful.

Note that `<Exec>`

only works in VS2019+.

The post How to add a post-publish event to Visual Studio appeared first on Dot Net What Not.

]]>The post LeetCode 200 – Counting islands appeared first on Dot Net What Not.

]]>For this reason, I have tried my best to avoid LeetCode, as it’s another great place to lose yourself for a long time. However, someone posted a video of his solution to problem #200, and it got the better of me. The problem is that, given a 2D array of chars, each of which can be `0`

to represent water or `1`

to represent land, find out how many islands there are, where cells are only considered to be connected horizontally or vertically, not diagonally.

His solution used Python, and implemented a breadth-first algorithm. Without looking too closely at his code, I decided to give it a go in C#.

My first attempt (which didn’t work properly, but was abandoned due to my Linq epiphany, see below) was to walk the dry land cells in each row in turn, checking the cells above and to the left (which have already been visited) to see if they are dry land. If so, the current cell can be put in the same island. The code looked something like this…

char[,] islands = { {'1','1','1','0','0'}, {'1','1','0','0','0'}, {'1','1','0','0','0'}, {'0','0','0','1','1'}, }; int rows = islands.GetLength(0); int cols = islands.GetLength(1); int[,] results = new int[rows, cols]; int maxIslands = 0; // Go through and check each cell for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { if (IsLand(islands, row - 1, col)) { results[row, col] = results[row - 1, col]; } else if (IsLand(islands, row, col - 1)) { results[row, col] = results[row, col - 1]; } else if (IsLand(islands, row, col)) { results[row, col] = ++maxIslands; } } } Console.WriteLine($"Total islands: {maxIslands}"); static bool IsLand(char[,] islands, int row, int col) { try { return islands[row, col] == '1'; } catch { return false; } }

After setting up a sample set of cells, lines 8 and 9 get the number of rows and columns. We then create an array that will contain the island number for each cell (or 0 if it’s water).

The main work is done in the nested `for`

loop on lines 13 to 23. This uses the utility method `IsLand`

to make the code cleaner. We check all dry cells to see if the cell above is land, and if so, set the current cell to be in the same island. If the cell above were water, then we check the cell to the left. If neither are dry, then we have reached a new island, so we add increase the counter and set the current cell to the new island number.

This worked moderately well, although not completely. I had to stop in the middle, so didn’t get chance to work out what needed tweaking before I realised that the algorithm wouldn’t work in all cases. If we had a set of cells like this…

0 1 1 1

…then the top-right cell would get put in a new island #1. The bottom-left cell would also be put in a new island #2, as it isn’t touching any previously-checked dry land. This meant that when we checked the bottom-right cell, we would assign it to the island above (ie #1, the number of the top-right cell). However, it is also touching the bottom-left cell, which is in island #2.

In order to get around this, I would have to check for this situation and merge the two islands. I had an idea how this could be done, when something started niggling in the back of my mind.

I love Linq. I can’t imagine coding without it, and tend to look at every problem as a potential candidate for Linq. Whilst contemplating this puzzle, I realised that what we are doing is the sort of set operation that Linq excels at. However, unlike the regular set operation that are solved with methods like `Select`

, `Where`

that operate on a single element at a time, this one required knowledge of the rest of the problem data as well. How was I going to handle this.

At this stage, I thought of `Aggregate`

, which is one of those Linq methods that I don’t use very often, but find incredibly powerful when I do.

In simple terms, `Aggregate`

is a bit like `Select`

, in that it iterates over every element in the input, but unlike `Select`

, you get access to a running accumulated value as well. Although the accumulator is normally used to keep something like a running total of what’s gone on before, I could use it to keep the current state of the solution, meaning that whilst processing a single element, I knew what had happened to previously processed elements.

With a little fiddling, I came up with the following code…

List<List<(int, int)>> islands = cells.Cast<char>() .Select((val, n) => (val, n)) .Where(c => c.val == '1') .Select(c => (c.n / cells.GetLength(1), c.n % cells.GetLength(1))) .Aggregate(new List<List<(int, int)>>(), (List<List<(int, int)>> acc, (int row, int col) cell) => { List<(int, int)>? above = acc.FirstOrDefault(i => i.Contains((cell.row - 1, cell.col))); List<(int, int)>? left = acc.FirstOrDefault(i => i.Contains((cell.row, cell.col - 1))); if (above != null && left != null) { if (above == left) { above.Add(cell); } else { above.AddRange(left); above.Add(cell); acc.Remove(left); } } else if (above != null) { above.Add(cell); } else if (left != null) { left.Add(cell); } else { acc.Add(new List<(int, int)> { cell }); } return acc; });

This isn’t actually as complex as it looks at first!

Lines 1 to 4 just mould the data into a more usable form. We take the whole 2D array as a 1D array of `char`

s, then select the cell value along with its index (0, 1, 2, …). Line 3 filters out the water, as that doesn’t interest us at all, and line 4 converts the index of the 1D array to a pair of co-ordinates that correspond to the dry cells in the 2D array. Dumping the output of those few lines would give…

(0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (2, 0) (2, 1) (3, 3) (3, 4)

If you compare that with the original 2D array, you see it’s just the co-ordinates of the dry cells.

Then we call `Aggregate`

, passing an empty list of lists as the initial value. The idea is that each individual list will be a collection of cells that make up an island.

The code inside the lambda checks both the cells above and to left of the current one, to see if they are already in an island. We do this by looking for an island that contains each of these two cells. We then act as follows…

1) If both islands are non-null (meaning that both the above and left cells are in islands), then we check if the two islands are the same. If so, we just add the current cell to one of them (doesn’t matter which as they are the same). If they are different, then we have hit the problem mentioned above, so we add the cells in the island containing the left cell to the island containing the right cell, then remove the left island.

2) The next two clauses (lines 16 to 19) are for when exactly one of the two neighbouring cells is non-null. We just add the current cell to that island.

3) Line 21 is for the only other option, that this is a new island

Once we have iterated over all cells, we are left with a collection of lists, where each list represents one island. We can dump these out very easily…

Console.WriteLine($"Islands: {islands.Count}"); islands.ForEach(l => Console.WriteLine($"{string.Join(", ", l.Select(c => $"({c.Item1}, {c.Item2})"))}"));

This gives the expected output…

Islands: 2 (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (2, 0), (2, 1) (3, 3), (3, 4)

Took me a little while to get this one working, but it was an excellent exercise in reminding myself how to use `Aggregate`

.

My code also ended up quite a bit shorter than the Python solution I saw.

The post LeetCode 200 – Counting islands appeared first on Dot Net What Not.

]]>Sometimes it tells you a little bit more than that...

The post When developers write documentation appeared first on Dot Net What Not.

]]>Sometimes it tells you a little bit more than that…

I guess you’ve don’t really have any excuses with documentation like that!

The post When developers write documentation appeared first on Dot Net What Not.

]]>The post Thunderbird has an interesting idea of what a PHP file is! appeared first on Dot Net What Not.

]]>Someone sent me a .php file today. Being a .NET developer, and not a great fan of PHP (ducks to avoid fling bricks from any passing PHP fans), I don’t have a default application for opening .php files.

No problem, Thunderbird is intelligent enough to ask me what it should use…

Erm, well maybe it’s not that intelligent after all!

In fairness, I’m not sure where it picks up the suggestions, so it may be that Windows is to blame. Maybe not. Either way, at least two out of those three were pretty dumb!

The post Thunderbird has an interesting idea of what a PHP file is! appeared first on Dot Net What Not.

]]>The post Visual Studio IntelliCode is always quite as intelligent as it might be appeared first on Dot Net What Not.

]]>I must admit to being seriously impressed at how well it works, until someone showed me the following…

OK, so perhaps it’s not quite as intelligent as we thought!

The post Visual Studio IntelliCode is always quite as intelligent as it might be appeared first on Dot Net What Not.

]]>The post Amazon don’t HTML-encode their product descriptions appeared first on Dot Net What Not.

]]>Not that I would ever do anything like that!

Ahem.

The post Amazon don’t HTML-encode their product descriptions appeared first on Dot Net What Not.

]]>