Forked from lifebeyondfife/declarative programming repo problem.cs
Last active
December 29, 2016 00:08
-
-
Save rmariano/0b1bff00dde0b163a7a632823c3134cd to your computer and use it in GitHub Desktop.
Declarative Programming Repo Problem. Problem available in C#, JavaScript and Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Code below can be run directly into LINQPad - https://www.linqpad.net/ | |
Return the owner and repo name of the most starred project with more than 100 contributors, for each language | |
The declarative implementation can be solved using the Select, Where, Aggregate and GroupBy LINQ extension methods | |
*/ | |
void Main() | |
{ | |
var repos = new List<Repo> { | |
new Repo { Owner = "Alice", Name = "Swish", Stars = 611, Language = Language.CPlusPlus, Contributors = 170 }, | |
new Repo { Owner = "Bob", Name = "Thermos", Stars = 218, Language = Language.Python, Contributors = 26 }, | |
new Repo { Owner = "Charlie", Name = "Glint", Stars = 335, Language = Language.CSharp, Contributors = 53 }, | |
new Repo { Owner = "Dylan", Name = "B2", Stars = 13856, Language = Language.JavaScript, Contributors = 64 }, | |
new Repo { Owner = "Evelyn", Name = "Logang", Stars = 5834, Language = Language.Go, Contributors = 39 }, | |
new Repo { Owner = "Francis", Name = "Blocker", Stars = 10436, Language = Language.Go, Contributors = 107 }, | |
new Repo { Owner = "Geri", Name = "Curvature", Stars = 8029, Language = Language.JavaScript, Contributors = 387 }, | |
new Repo { Owner = "Harry", Name = "Proact", Stars = 7431, Language = Language.JavaScript, Contributors = 242 }, | |
new Repo { Owner = "Iona", Name = "Stereo", Stars = 9848, Language = Language.CSharp, Contributors = 153 }, | |
new Repo { Owner = "Jamie", Name = "Blueis", Stars = 4360, Language = Language.C, Contributors = 12 }, | |
new Repo { Owner = "Kerry", Name = "RightPad", Stars = 5, Language = Language.JavaScript, Contributors = 1 } | |
}; | |
Console.WriteLine(Declarative(repos)); | |
Console.WriteLine(Imperative(repos)); | |
} | |
public class Repo | |
{ | |
public string Owner { get; set; } | |
public string Name { get; set; } | |
public int Stars { get; set; } | |
public Language Language { get; set; } | |
public int Contributors { get; set; } | |
} | |
public class OwnerRepo | |
{ | |
public string Owner { get; set; } | |
public string Name { get; set; } | |
} | |
public enum Language | |
{ | |
CPlusPlus, | |
Python, | |
CSharp, | |
JavaScript, | |
Go, | |
C | |
} | |
// Return the owner and repo name of the most starred project with more than 100 contributors, for each language | |
public IList<OwnerRepo> Declarative(IList<Repo> repos) | |
{ | |
return null; | |
} | |
public IList<OwnerRepo> Imperative(IList<Repo> repos) | |
{ | |
var starredRepos = new Dictionary<Language, Repo>(); | |
foreach (var repo in repos) | |
{ | |
if (repo.Contributors <= 100) | |
continue; | |
if (!starredRepos.ContainsKey(repo.Language) || repo.Stars > starredRepos[repo.Language].Stars) | |
starredRepos[repo.Language] = repo; | |
} | |
var ownerAndRepos = new List<OwnerRepo>(); | |
foreach (var repo in starredRepos) | |
{ | |
ownerAndRepos.Add(new OwnerRepo { | |
Owner = starredRepos[repo.Value.Language].Owner, | |
Name = starredRepos[repo.Value.Language].Name | |
}); | |
} | |
return ownerAndRepos; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Return the owner and repo name of the most starred project with more than 100 contributors, for each language | |
The declarative implementation can be solved using the map, filter, reduce and groupBy from the underscore library | |
In order to chain your higher order function calls (as you would using, say, jQuery), use the _.chain() function. | |
*/ | |
const _ = require('underscore'); | |
const repos = [ | |
{ owner: 'Alice', name: 'Swish', stars: 611, language: 'C++', contributors: 170 }, | |
{ owner: 'Bob', name: 'Thermos', stars: 218, language: 'Python', contributors: 26 }, | |
{ owner: 'Charlie', name: 'Glint', stars: 335, language: 'C#', contributors: 53 }, | |
{ owner: 'Dylan', name: 'B2', stars: 13856, language: 'JavaScript', contributors: 64 }, | |
{ owner: 'Evelyn', name: 'Logang', stars: 5834, language: 'Go', contributors: 39 }, | |
{ owner: 'Francis', name: 'Blocker', stars: 10436, language: 'Go', contributors: 107 }, | |
{ owner: 'Geri', name: 'Curvature', stars: 8029, language: 'JavaScript', contributors: 387 }, | |
{ owner: 'Harry', name: 'Proact', stars: 7431, language: 'JavaScript', contributors: 242 }, | |
{ owner: 'Iona', name: 'Stereo', stars: 9848, language: 'C#', contributors: 153 }, | |
{ owner: 'Jamie', name: 'Blueis', stars: 4360, language: 'C', contributors: 12 }, | |
{ owner: 'Kerry', name: 'RightPad', stars: 5, language: 'JavaScript', contributors: 1 } | |
]; | |
// Return the owner and repo name of the most starred project with more than 100 contributors, for each language | |
const declarative = function(repos) { | |
return null; | |
}; | |
const imperative = function(repos) { | |
let mostStarredRepos = {}; | |
for (repo of repos) { | |
if (repo.contributors <= 100) { | |
continue; | |
} | |
if (!(repo.language in mostStarredRepos) || repo.stars > mostStarredRepos[repo.language].stars) { | |
mostStarredRepos[repo.language] = repo; | |
} | |
} | |
let ownerAndRepos = []; | |
for (repo in mostStarredRepos) { | |
ownerAndRepos.push({ owner: mostStarredRepos[repo].owner, name: mostStarredRepos[repo].name }); | |
} | |
return ownerAndRepos; | |
}; | |
declarative(repos); | |
imperative(repos); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' | |
Return the owner and repo name of most starred project for each language with more than 100 contributors | |
The declarative implementation can be solved using the built in map and filter functions, and the imported | |
reduce and groupby functions | |
Python doesn't chain higher order function calls like the other languages, but rather expands them outward e.g. | |
right: map(map_lambda_function, filter(filter_lambda_function, [1, 2, 3])) | |
wrong: [1, 2, 3].filter(filter_lambda_function).map(map_lambda_function) | |
''' | |
import operator | |
from itertools import groupby | |
from functools import reduce | |
repos = [ | |
{'owner': 'Alice', 'name': 'Swish', 'stars': 611, 'language': 'C++', 'contributors': 170}, | |
{'owner': 'Bob', 'name': 'Thermos', 'stars': 218, 'language': 'Python', 'contributors': 26}, | |
{'owner': 'Charlie', 'name': 'Glint', 'stars': 335, 'language': 'C#', 'contributors': 53}, | |
{'owner': 'Dylan', 'name': 'B2', 'stars': 13856, 'language': 'JavaScript', 'contributors': 64}, | |
{'owner': 'Evelyn', 'name': 'Logang', 'stars': 5834, 'language': 'Go', 'contributors': 39}, | |
{'owner': 'Francis', 'name': 'Blocker', 'stars': 10436, 'language': 'Go', 'contributors': 107}, | |
{'owner': 'Geri', 'name': 'Curvature', 'stars': 8029, 'language': 'JavaScript', 'contributors': 387}, | |
{'owner': 'Harry', 'name': 'Proact', 'stars': 7431, 'language': 'JavaScript', 'contributors': 242}, | |
{'owner': 'Iona', 'name': 'Stereo', 'stars': 9848, 'language': 'C#', 'contributors': 153}, | |
{'owner': 'Jamie', 'name': 'Blueis', 'stars': 4360, 'language': 'C', 'contributors': 12}, | |
{'owner': 'Kerry', 'name': 'RightPad', 'stars': 5, 'language': 'JavaScript', 'contributors': 1} | |
] | |
def group_by_language(repos): | |
fkey = operator.itemgetter('language') | |
return groupby(sorted(repos, key=fkey), key=fkey) | |
def repos_with_contributors(repo_group): | |
contributors = operator.itemgetter('contributors') | |
return (repo for repo in repo_group if contributors(repo) > 100) | |
def most_starred_repo(repo_sequence): | |
stars = operator.itemgetter('stars') | |
return max(repo_sequence, key=stars, default=None) | |
# Return the owner and repo name of the most starred project with more than 100 contributors, for each language | |
def declarative(repos): | |
to_show = operator.itemgetter('owner', 'name') | |
return sorted(map(to_show, filter(None, ( | |
most_starred_repo(repos_with_contributors(language_group)) | |
for _, language_group in group_by_language(repos) | |
)))) | |
def imperative(repos): | |
mostStarredRepos = {} | |
for repo in repos: | |
if repo['contributors'] <= 100: | |
continue | |
if repo['language'] not in mostStarredRepos or repo['stars'] > mostStarredRepos[repo['language']]['stars']: | |
mostStarredRepos[repo['language']] = repo | |
ownerAndRepos = [] | |
for repo in mostStarredRepos.values(): | |
ownerAndRepos.append((repo['owner'], repo['name'])) | |
return sorted(ownerAndRepos) | |
if __name__ == '__main__': | |
print(declarative(repos)) | |
print(imperative(repos)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice! Thanks for solving the problem, Mariano. Interesting to see a different approach in Python.