Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rmariano/0b1bff00dde0b163a7a632823c3134cd to your computer and use it in GitHub Desktop.
Save rmariano/0b1bff00dde0b163a7a632823c3134cd to your computer and use it in GitHub Desktop.
Declarative Programming Repo Problem. Problem 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
}
// 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;
}
/*
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);
'''
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))
@lifebeyondfife
Copy link

Nice! Thanks for solving the problem, Mariano. Interesting to see a different approach in Python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment