-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAoC072019.java
69 lines (59 loc) · 2.27 KB
/
AoC072019.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.adventofcode.aoc2019;
import static com.adventofcode.utils.Utils.getFirstString;
import static com.adventofcode.utils.Utils.toLongList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Stream;
import com.adventofcode.Solution;
import com.adventofcode.utils.Computer2019;
import com.adventofcode.utils.Utils;
import com.google.common.collect.Collections2;
class AoC072019 implements Solution {
public String solveFirstPart( final Stream<String> input ) {
return solve( input, Set.of( 0, 1, 2, 3, 4 ) );
}
public String solveSecondPart( final Stream<String> input ) {
return solve( input, Set.of( 5, 6, 7, 8, 9 ) );
}
private String solve( final Stream<String> input, final Collection<Integer> availablePhases ) {
final List<Long> program = toLongList( getFirstString( input ) );
return Collections2.permutations( availablePhases )
.stream()
.map( settings -> runComputers( program, settings.iterator() ) )
.max( Long::compareTo )
.map( Utils::itoa )
.orElseThrow();
}
private long runComputers( final List<Long> program, final Iterator<Integer> settings ) {
BlockingQueue<Long> firstConnection = new LinkedBlockingQueue<>();
BlockingQueue<Long> previousConnection = firstConnection;
final Set<Future<?>> computers = new HashSet<>();
while ( settings.hasNext() ) {
//configure phase settings
previousConnection.add( settings.next().longValue() );
//connect computers to each other. loop back last computer into first
final BlockingQueue<Long> nextConnection = settings.hasNext() ? new LinkedBlockingQueue<>() : firstConnection;
computers.add(
Computer2019.runComputer( program, previousConnection, nextConnection, true ) );
previousConnection = nextConnection;
}
try {
//start computing
firstConnection.add( 0L );
for ( final var computer : computers ) {
//wait for completion
computer.get();
}
return previousConnection.remove();
} catch ( InterruptedException | ExecutionException e ) {
throw new RuntimeException( e );
}
}
}