Last active
September 23, 2020 17:57
-
-
Save boukeversteegh/000ff368df58b18627652d5c6dc2cfc3 to your computer and use it in GitHub Desktop.
Luck or hard work?
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
// run this script in your browser on: | |
// | |
// https://dartpad.dev/000ff368df58b18627652d5c6dc2cfc3 | |
import 'dart:math'; | |
// number of participants: | |
const n_participants = 18300; | |
// that will receive a skill between: | |
const minimum_skill = 0; | |
const maximum_skill = 100; | |
// and some luck between: | |
const minimum_luck = 0; | |
const maximum_luck = 100; | |
// that will participate in a contest with n winners: | |
const n_winners = 11; | |
// where winners are picked by score, which is a combination of skill and luck. | |
const skill_factor = 0.95; // percent | |
const luck_factor = 0.05; // percent | |
// and where the skill distribution is | |
// 1 = even (just as likely to be bad as good) | |
// 2 = skewed (more likely to be bad than good) | |
const skill_skewedness = 1.0; | |
// we will show the lowest skilled winner out of n contests | |
const n_contests = 100; | |
final random = Random(); | |
void main() { | |
print('Random contest:'); | |
final contest = Contest(); | |
contest.winners.forEach(print); | |
print(''); | |
print('Worst winner in $n_contests contests:'); | |
final worstWinner = worstWinnerEver(contests: n_contests); | |
print(worstWinner); | |
} | |
Participant worstWinnerEver({int contests}) { | |
Participant worstWinnerEver; | |
for (var i = 0; i < contests; i++) { | |
var worstWinner = Contest().worstWinner; | |
if (worstWinnerEver == null || worstWinner.skill < worstWinnerEver.skill) { | |
worstWinnerEver = worstWinner; | |
} | |
} | |
return worstWinnerEver; | |
} | |
class Contest { | |
List<Participant> participants; | |
Contest() { | |
participants = Iterable<int>.generate(n_participants).map((element) { | |
return Participant( | |
skill: minimum_skill + | |
pow(random.nextDouble(), skill_skewedness) * | |
(maximum_skill - minimum_skill), | |
luck: minimum_luck + (random.nextDouble() * (maximum_luck-minimum_luck)), | |
); | |
}).toList(); | |
participants.sort((p1, p2) => p2.score.compareTo(p1.score)); | |
} | |
Iterable<Participant> get winners => participants.getRange(0, n_winners); | |
Participant get worstWinner { | |
var winners = this.winners.toList(); | |
winners.sort((w1, w2) => w1.skill.compareTo(w2.skill)); | |
return winners.first; | |
} | |
} | |
class Participant { | |
final num score; | |
final num skill; | |
final num luck; | |
Participant({this.luck, this.skill}) | |
: score = luck * luck_factor + skill * skill_factor; | |
@override | |
String toString() { | |
return 'Participant{score: ${format(score)}, skill: ${format(skill)}, luck: ${format(luck)}}'; | |
} | |
} | |
String format(num n) => n.toStringAsFixed(1).padLeft(5); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment