Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lifebeyondfife/dea196ba649993b48b940889c24b4f60 to your computer and use it in GitHub Desktop.
Save lifebeyondfife/dea196ba649993b48b940889c24b4f60 to your computer and use it in GitHub Desktop.
Declarative Programming Repo Solution. Solution available in C#, JavaScript and Python.
/*
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
}
public IList<OwnerRepo> Declarative(IList<Repo> repos)
{
return repos.
Where(r => r.Contributors > 100).
GroupBy(r => r.Language).
Select(g => g.
Aggregate((x, y) => x.Stars > y.Stars ? x : y)
).
Select(r => new OwnerRepo { Owner = r.Owner, Name = r.Name }).
ToList();
}
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;
}
/*
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 }
];
const declarative = function(repos) {
return _.chain(repos).
filter(r => r.contributors > 100).
groupBy('language').
map(g => g.
reduce((x, y) => x.stars > y.stars ? x : y)
).
map(r => { return { owner: r.owner, name: r.name }; }).
value();
};
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;
};
console.log(declarative(repos));
console.log(imperative(repos));
'''
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)
'''
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 declarative(repos):
return list(
map(
lambda r: (r['owner'], r['name']),
map(
lambda key_group: reduce(
lambda x, y: x if x['stars'] > y['stars'] else y,
key_group[1]
),
groupby(
filter(
lambda r: r['contributors'] > 100,
repos
),
key=lambda prop: prop['language']
)
)
)
)
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 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