LINQ Challenge #3
I'm very excited to announce that in October I'll be speaking on LINQ at Techorama Netherlands, sharing some of my best practices for becoming more effective with LINQ.
This means its time for another LINQ Challenge! These are short programming challenges, can be solved with a single LINQ expression. Of course, that might not always make for the most readable code, so feel free to solve these with or without the help of LINQ, and of course solutions in other languages are welcome. If you're using LINQ, then the MoreLINQ library often has extension methods that simplify the task.
This challenge is a little more tricky than the previous ones, so if you'd like a more gentle introduction, try some of the earlier challenges first (I've linked to the answers, but I recommend trying to solve them first before looking at the solutions)
Problem 1 - Longest Sequence
The following string contains number of sales made per day in a month:
"1,2,1,1,0,3,1,0,0,2,4,1,0,0,0,0,2,1,0,3,1,0,0,0,6,1,3,0,0,0"
How long is the longest sequence of days without a sale? (in this example it's 4)
Problem 2 - Full House
In poker a hand is a "full house" if it contains three cards of one value and two of another value. The following string defines five poker hands, separated by a semicolon:
"4♣ 5♦ 6♦ 7♠ 10♥;10♣ Q♥ 10♠ Q♠ 10♦;6♣ 6♥ 6♠ A♠ 6♦;2♣ 3♥ 3♠ 2♠ 2♦;2♣ 3♣ 4♣ 5♠ 6♠"
.
Write a LINQ expression that returns an sequence containing only the "full house" hands.
Problem 3 - Christmas Days
What day of the week is Christmas day (25th December) on for the next 10 years (starting with 2018)? The answer should be a string (or sequence of strings) starting: Tuesday,Wednesday,Friday,...
Problem 4 - Anagrams
From the following dictionary of words,
"parts,traps,arts,rats,starts,tarts,rat,art,tar,tars,stars,stray"
return all words that are an anagram of star
(no leftover letters allowed).
Problem 5 - Initial Letters
From the following list of names
"Santi Cazorla, Per Mertesacker, Alan Smith, Thierry Henry, Alex Song, Paul Merson, Alexis Sánchez, Robert Pires, Dennis Bergkamp, Sol Campbell"
find any groups of people who share the same initials as each other.
Problem 6 - Video Editing
A video is two hours long exactly, and we want to make some edits, cutting out the following time ranges (expressed in H:MM:SS):
"0:00:00-0:00:05;0:55:12-1:05:02;1:37:47-1:37:51"
.
(You can assume that the input ranges are in order and contain no overlapping portions)
We would like to turn this into a sequence of time-ranges to keep. So in this example, the output should be:
"0:00:05-0:55:12;1:05:02-1:37:47;1:37:51-2:00:00"
Share your answers
I hope you have fun solving these. Why not your solutions in GitHub Gists, and share your approach with the rest of us in the comments below. Although I've already created LINQ solutions to each of these puzzles which I'll post later, every time I do this I find I learn something from the way other people have approached the problems.
Comments
#3 seems fairly simple:
James CurranString.Join(",", Enumerable.Range(2018, 10).Select(y=>new DateTime(y, 12,25).DayOfWeek.ToString()))
(my office blocks github Gists -- but not the rest of github, from the office network)
#5 wasn't that difficult either, though this could use some tidying up, but I think I made good use of tuples in the Selects...
James Curran"Santi Cazorla, Per Mertesacker, Alan Smith, Thierry Henry, Alex Song, Paul Merson, Alexis Sánchez, Robert Pires, Dennis Bergkamp, Sol Campbell"
.Split(',')
.Select(n=>(parts:n.Trim().Split(' '), name:n))
.Select(tp=>(initial:tp.parts[0][0].ToString()+tp.parts[1][0].ToString(), tp.name))
.GroupBy(tp =>tp.initial, tp=>tp.name)
.Where(g=>g.Count() > 1)
.Select(g=> g.Key + " ==> " + String.Join(",", g));
This was fun! :)
Stuart Turnerhttps://gist.github.com/vic...
IN two of your solutions (notably, the two I'm stuck on), you make use of a method called "Segment", which I can't find any info on.
James Curranit's part of MoreLINQ - https://morelinq.github.io/
Mark Heathnice work :)
Mark Heathyes, an easier one, intended to show off the use of Enumerable.Range
Mark Heathyes, its nice that tuples are available for use in LINQ - shame that deconstruction doesn't seem to be supported in the lambda syntax yet
Mark HeathNearly all done
Mark Joneshttps://gist.github.com/ora...
nice, I like the approach to #1
Mark HeathCheers
babbelneddhttps://gist.github.com/lsc...
I feel a little stupid reading your anagram solution. clever.
babbelneddP1:
JChttps://gist.github.com/jon...
P2:
JChttps://gist.github.com/jon...
Thanks, I was pleased with that solution
Mark JonesSO, once I found MoreLinq, it became much easier...… (Actually, the most time consuming part --- trying to get the Gist page to work on Edge. The Add File button causes it to lock up)
James Curranhttps://gist.github.com/jam...
Your #5 only looks at the initial for the first name. It should be just those people with a common first & last initial. (The data masks the problem)
James CurranFixed, thanks.
Leyu SisayComing a bit late to the party, but I had fun coding the solutions.
Horia TomaHere's the gist link: https://gist.github.com/hto...
Hey. Thanks for sharing your solution.
Bianca GhiuruțanJust FYI, your solution for the full house problem is not foolproof, as it will catch pairs and three of a kind as well.
For Puzzle 6, without using MoreLinq, but same number of lines and easier to understand IMHO:
David Burstin"0:00:00-0:00:05;0:55:12-1:05:02;1:37:47-1:37:51"
.Split(';','-')
.Skip(1)
.Append("2:00:00")
.Select((s, i) => (time: s, index: i))
.GroupBy(p => p.index / 2)
.Select(g => g.Aggregate("", (agg, curr) => $"{agg}-{curr.time}").Substring(1))
.Aggregate((agg, curr) => $"{agg};{curr}")