Last active
October 31, 2024 20:35
-
-
Save gigamonkey/f552efa33a7a7383cb63282ebdf933d4 to your computer and use it in GitHub Desktop.
Reviewer assignment algorithm. I'm not sure this actually can generate all possible legal combinations of assignments but it's pretty random and only generates legal assignments. I'm also not sure it can't. First version is mostly procedural. Second one is heavy on streams.
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
import static java.util.stream.Collectors.joining; | |
import java.io.*; | |
import java.nio.file.*; | |
import java.util.*; | |
import java.util.stream.*; | |
public record Reviewers(List<String> handles) { | |
////////////////////////////////////////////////////////////////////////////// | |
// Utility methods | |
// Return a randomly shuffled copy of a list | |
private <T> List<T> shuffled(List<T> ts) { | |
List<T> copy = new ArrayList<>(ts); | |
Collections.shuffle(copy); | |
return copy; | |
} | |
// Return a list of integers in the range [start, end) | |
private List<Integer> numbers(int start, int end) { | |
return IntStream.range(start, end).boxed().toList(); | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
// Actual reviewer assignment | |
public Map<String, List<String>> assignments(int n) { | |
var shuffled = shuffled(handles); | |
var rotations = shuffled(numbers(1, shuffled.size())).subList(0, n); | |
var assignments = new HashMap<String, List<String>>(); | |
for (var i = 0; i < shuffled.size(); i++) { | |
for (var r : rotations) { | |
assignments | |
.computeIfAbsent(shuffled.get(i), k -> new ArrayList<>()) | |
.add(shuffled.get((i + r) % shuffled.size())); | |
} | |
} | |
return assignments; | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
// Output | |
public void tsv(int n) { | |
var m = assignments(n); | |
for (var h : handles) { | |
System.out.println(h + "\t" + m.get(h).stream().collect(joining("\t"))); | |
} | |
} | |
public static void main(String[] args) throws IOException { | |
var handles = Files.lines(Path.of(args[0])).toList(); | |
var n = Integer.parseInt(args[1]); | |
new Reviewers(handles).tsv(n); | |
} | |
} |
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
import static java.util.stream.Collectors.groupingBy; | |
import static java.util.stream.Collectors.joining; | |
import static java.util.stream.Collectors.mapping; | |
import static java.util.stream.Collectors.toList; | |
import java.io.*; | |
import java.nio.file.*; | |
import java.util.*; | |
import java.util.stream.*; | |
public record Reviewers2(List<String> handles) { | |
////////////////////////////////////////////////////////////////////////////// | |
// Utility methods | |
// Return a randomly shuffled copy of a list | |
private <T> List<T> shuffled(List<T> ts) { | |
List<T> copy = new ArrayList<>(ts); | |
Collections.shuffle(copy); | |
return copy; | |
} | |
// Return a list of integers in the range [start, end) | |
private List<Integer> numbers(int start, int end) { | |
return IntStream.range(start, end).boxed().toList(); | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
// Actual reviewer assignment | |
public Map<String, List<String>> assignments(int n) { | |
var hs = shuffled(handles); | |
var rs = shuffled(numbers(1, hs.size())).subList(0, n); | |
record Pair(String author, String reviewer) {} | |
return numbers(0, hs.size()) | |
.stream() | |
.flatMap(i -> rs.stream().map(r -> new Pair(hs.get(i), hs.get((i + r) % hs.size())))) | |
.collect(groupingBy(Pair::author, mapping(Pair::reviewer, toList()))); | |
} | |
////////////////////////////////////////////////////////////////////////////// | |
// Output | |
public void tsv(int n) { | |
var m = assignments(n); | |
for (var h : handles) { | |
System.out.println(h + "\t" + m.get(h).stream().collect(joining("\t"))); | |
} | |
} | |
public static void main(String[] args) throws IOException { | |
var handles = Files.lines(Path.of(args[0])).toList(); | |
var n = Integer.parseInt(args[1]); | |
new Reviewers(handles).tsv(n); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment