Skip to content

Instantly share code, notes, and snippets.

@david-beckman
Created March 25, 2020 18:47
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 david-beckman/98556bc508a305cf1d9df16234889b81 to your computer and use it in GitHub Desktop.
Save david-beckman/98556bc508a305cf1d9df16234889b81 to your computer and use it in GitHub Desktop.
Israeli Parliamentary Coalitions
// https://ayende.com/blog/190275-C/giving-a-job-candidate-a-hard-problem
static var parliment = new Dictionary<string, (int Seats, int Index)>
{
["Likud"] = (36, 0),
["KahulLaval"] = (33, 1),
["JointList"] = (15, 2),
["Shas"] = (9, 3),
["YahadutHatora"] = (7, 4),
["IsrealBeitenu"] = (7, 5),
["AvodaGesherMeretz"] = (7, 6),
["Yemina"] = (6, 7)
};
static var likes = new[,]
{
// likud, kahul, joint, shas, yahdut, beitenu, avoda, yemina
{ 1.0, -0.5, -1.0, 0.95, 0.95, -0.2, -0.8, 0.95}, // likud
{ -0.9, 1.0, -0.6, -0.5, -0.5, 0.5, 0.8, -0.2}, // kahul
{ -0.9, -0.3, 1.0, -0.6, -0.6, -1.0, -0.2, -1.0}, // joint
{ 0.96, -0.7, -0.6, 1.0, 0.9, -1.0, -0.7, 0.8}, // shas
{ 0.97, -0.6, -0.6, 0.92, 1.0, -1.0, -0.6, 0.7}, // yahadut
{ -0.4, -0.1, -1.0, -0.99, -0.99, 1.0, -0.6, 0.1}, // beitenu
{ -0.95, 0.98, 0.3, -0.89, -0.89, -0.01, 1.0, -0.75}, // avoda
{ 0.999, -0.92, -1.0, 0.86, 0.85, -0.3, -0.4, 1.0}, // yemina
};
static var target = Math.Ceiling((parliment.Sum(party => party.Value.Seats) + 1) / 2.0); // 61
Coalition.GetAllCoalitions()
.Where(coalition => coalition.IsSufficient && coalition.IsLikely)
.OrderByDescending(coalition => coalition.Likelyhood)
.Select(coalition => coalition.ToString())
.Dump();
public class Coalition
{
public Coalition(IReadOnlyCollection<KeyValuePair<string, (int Seats, int Index)>> members)
{
this.Members = members ?? throw new ArgumentNullException(nameof(members));
if (this.Members.Count == 0)
{
throw new ArgumentOutOfRangeException(nameof(members), "There must be at least 1 member of a coalition.");
}
}
private IReadOnlyCollection<KeyValuePair<string, (int Seats, int Index)>> Members { get; }
public IReadOnlyCollection<string> MemberNames => this.Members.Select(party => party.Key).ToArray();
public int Seats => this.Members.Sum(party => party.Value.Seats);
public bool IsSufficient => Seats >= target;
private double DenormalizedLikelyhood => this.Members.SelectMany(party1 => this.Members.Select(party2 => new {party1, party2}))
.Sum(relationship => likes[relationship.party1.Value.Index, relationship.party2.Value.Index]);
public double Likelyhood => this.Members.Count == 1
? DenormalizedLikelyhood
: 2 * (DenormalizedLikelyhood - this.Members.Count) / (this.Members.Count * (this.Members.Count - 1));
public bool IsLikely => this.Likelyhood > 0.0;
public override string ToString()
{
return string.Format("Seats: {0} Likelyhood: {1:0.0000} Members: {2}", this.Seats, this.Likelyhood, string.Join(", ", this.MemberNames));
}
public static IEnumerable<Coalition> GetAllCoalitions()
{
var combo = new bool[parliment.Count];
// Ignore all false...
while (GetNextCombo(ref combo, combo.Length - 1))
{
yield return new Coalition(parliment.Where(party => combo[party.Value.Index]).ToArray());
}
}
private static bool GetNextCombo(ref bool[] combo, int index)
{
if (index < 0) return false;
if (!combo[index])
{
return combo[index] = true;
}
combo[index] = false;
return GetNextCombo(ref combo, index - 1);
}
}
/*
Seats: 65 Likelyhood: 0.6029 Members: Likud, Shas, YahadutHatora, IsrealBeitenu, Yemina
Seats: 91 Likelyhood: 0.5989 Members: Likud, KahulLaval, Shas, YahadutHatora, Yemina
Seats: 65 Likelyhood: 0.4829 Members: Likud, Shas, YahadutHatora, AvodaGesherMeretz, Yemina
Seats: 73 Likelyhood: 0.4509 Members: Likud, JointList, Shas, YahadutHatora, Yemina
Seats: 85 Likelyhood: 0.3250 Members: Likud, KahulLaval, Shas, YahadutHatora
Seats: 82 Likelyhood: 0.2998 Members: Likud, KahulLaval, YahadutHatora, Yemina
Seats: 84 Likelyhood: 0.2998 Members: Likud, KahulLaval, Shas, Yemina
Seats: 67 Likelyhood: 0.2250 Members: Likud, JointList, Shas, YahadutHatora
Seats: 98 Likelyhood: 0.1193 Members: Likud, KahulLaval, Shas, YahadutHatora, AvodaGesherMeretz, Yemina
Seats: 98 Likelyhood: 0.1073 Members: Likud, KahulLaval, Shas, YahadutHatora, IsrealBeitenu, Yemina
Seats: 66 Likelyhood: 0.0698 Members: Likud, JointList, Shas, Yemina
Seats: 64 Likelyhood: 0.0532 Members: Likud, JointList, YahadutHatora, Yemina
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment