-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAoC102016.java
121 lines (108 loc) Β· 3.98 KB
/
AoC102016.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package com.adventofcode.aoc2016;
import static com.adventofcode.utils.Utils.SPACE;
import static com.adventofcode.utils.Utils.atoi;
import static com.adventofcode.utils.Utils.itoa;
import com.adventofcode.Solution;
import com.adventofcode.utils.Pair;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.IntStream;
import java.util.stream.Stream;
class AoC102016 implements Solution {
private static final String BOT = "bot ";
private static final String OUTPUT = "output ";
@Override
public String solveFirstPart( final Stream<String> input ) {
return solve( input, true );
}
@Override
public String solveSecondPart( final Stream<String> input ) {
return solve( input, false );
}
private String solve( final Stream<String> input, final boolean first ) {
final var inputList = input.toList();
final Map<String, Set<Integer>> bots = new HashMap<>();
final Map<String, Integer> outputs = new HashMap<>();
final Map<String, Pair<String, String>> botGives = new HashMap<>();
final Set<String> complete = new HashSet<>();
for ( final var line : inputList ) {
complete.addAll( initialize( line, bots, outputs, botGives ) );
}
while ( complete.size() < bots.size() ) {
final Set<String> lastComplete = new HashSet<>();
for ( final var bot : complete ) {
lastComplete.addAll( giveValue( bot, bots, outputs, botGives ) );
}
complete.addAll( lastComplete );
}
if ( first ) {
final int a = inputList.size() < 10 ? 3 : 61;
final int b = inputList.size() < 10 ? 5 : 17;
return bots.entrySet()
.stream()
.filter( bot -> bot.getValue().contains( a ) && bot.getValue().contains( b ) )
.map( bot -> bot.getKey().substring( BOT.length() ) )
.findFirst()
.orElseThrow();
} else {
return itoa( IntStream.rangeClosed( 0, 2 )
.mapToObj( i -> ( OUTPUT + i ) )
.mapToInt( outputs::get )
.reduce( 1, ( a, b ) -> a * b ) );
}
}
private Set<String> giveValue( final String bot, final Map<String, Set<Integer>> bots,
final Map<String, Integer> outputs, final Map<String, Pair<String, String>> botGives ) {
final Set<String> complete = new HashSet<>();
final var out = botGives.get( bot );
if ( out != null ) {
final var chips = bots.get( bot );
complete.addAll(
putValue( out.getFirst(), Collections.min( chips ), bots, botGives, outputs ) );
complete.addAll( putValue( out.getSecond(), Collections.max( chips ), bots, botGives,
outputs ) );
}
return complete;
}
private Set<String> putValue( final String out, final int value,
final Map<String, Set<Integer>> bots, final Map<String, Pair<String, String>> botGives,
final Map<String, Integer> outputs ) {
if ( out.startsWith( BOT ) ) {
return addChip( out, value, bots, outputs, botGives );
} else {
outputs.put( out, value );
return new HashSet<>();
}
}
private Set<String> addChip( final String bot, final int value,
final Map<String, Set<Integer>> bots, final Map<String, Integer> outputs,
final Map<String, Pair<String, String>> botGives ) {
final Set<String> complete = new HashSet<>();
final var chips = bots.computeIfAbsent( bot, k -> new HashSet<>() );
if ( chips.size() < 2 ) {
chips.add( value );
if ( chips.size() == 2 ) {
complete.add( bot );
complete.addAll( giveValue( bot, bots, outputs, botGives ) );
}
}
return complete;
}
private Set<String> initialize( final String line, final Map<String, Set<Integer>> bots,
final Map<String, Integer> outputs, final Map<String, Pair<String, String>> botGives ) {
final var words = line.split( " " );
if ( line.startsWith( BOT ) ) {
final String bot = words[0] + SPACE + words[1];
bots.putIfAbsent( bot, new HashSet<>() );
botGives.put( bot,
new Pair<>( words[5] + SPACE + words[6], words[10] + SPACE + words[11] ) );
return new HashSet<>();
} else {
return addChip( words[4] + SPACE + words[5], atoi( words[1] ), bots, outputs,
botGives );
}
}
}