some-advent-of-code: 1db4c49e271a145a2ad92dcdbceba136ac588a5e
1:
2: import java.io.IOException;
3: import java.nio.file.*;
4: import java.util.*;
5: import java.util.regex.*;;
6:
7: public class Exercise200702
8: {
9:
10: public static void main( String args[] )
11: {
12: final String here = "e20071.m ";
13: if ( args.length < 1 )
14: {
15: throw new RuntimeException( here +"add a filename argument" );
16: }
17: String userSaysFile = args[ 0 ];
18: List<String> fileLines = new LinkedList<>();
19: try
20: {
21: Path where = Paths.get( userSaysFile );
22: fileLines = Files.readAllLines( where );
23: }
24: catch ( IOException | InvalidPathException ie )
25: {
26: System.err.println( here +"couldn't read file "+ userSaysFile +" because "+ ie );
27: return;
28: }
29: /*
30: - interpretation of spec -
31: */
32: // gather
33: Map<String, Collection<String>> reverseAdjacency = new HashMap<>();
34: for ( String line : fileLines )
35: {
36: if ( line.isEmpty() || line.contains( "no other" ) )
37: continue;
38: int firstBagsInd = line.indexOf( "bags" );
39: String container = line.substring( 0, firstBagsInd -1 );
40: // System.out.println( here +"is "+ container );
41: Collection<String> inside = containedIn( line.substring(
42: firstBagsInd +"bags contain ".length() ) );
43: for ( String inner : inside )
44: {
45: if ( ! reverseAdjacency.containsKey( inner ) )
46: reverseAdjacency.put( inner, new HashSet<String>() );
47: reverseAdjacency.get( inner ).add( container );
48: }
49: }
50: /* everything
51: for ( String inner : reverseAdjacency.keySet() )
52: {
53: System.out.print( inner +";\t" );
54: for ( String has : reverseAdjacency.get( inner ) )
55: System.out.print( has +", " );
56: System.out.println();
57: }
58: System.out.println();
59: */
60: // trace adjacency
61: Queue<String> toCheck = new LinkedList<>();
62: int target = 0;
63: Collection<String> containsGold = reverseAdjacency.get( "shiny gold" );
64: if ( containsGold == null )
65: throw new RuntimeException( here +"gold not contained by anything" );
66: // else
67: // System.out.println( "gold in "+ containsGold.size() );
68: Set<String> outermost = new TreeSet<>();
69: outermost.addAll( containsGold );
70: toCheck.addAll( containsGold );
71: while ( ! toCheck.isEmpty() )
72: {
73: String bag = toCheck.poll();
74: if ( bag == null )
75: continue;
76: outermost.add( bag );
77: Collection<String> containedBy = reverseAdjacency.get( bag );
78: // System.out.println( "huh "+ bag +" in "+ containedBy );
79: if ( containedBy == null )
80: continue;
81:
82: /*
83: System.out.print( bag +" contained by: "+ containedBy.size() +" " );
84: for ( String inner : containedBy )
85: System.out.print( "_"+ inner );
86: System.out.println( "; left-"+ toCheck.size() );
87: */
88:
89: toCheck.addAll( containedBy );
90: }
91: System.out.println( here +"input summed to "+ outermost.size() );
92: }
93:
94:
95: /** expecting '\d+ value bag(s), ...' and not given a 'no other' line. */
96: private static Collection<String> containedIn(
97: String list
98: ) {
99: // System.out.print( "\trest is -"+ list );
100: Collection<String> inside = new LinkedList<>();
101: for (
102: int ind = 0;
103: ind < list.length() && ind >= 0;
104: ind += 1
105: ) {
106: // number
107: ind = list.indexOf( ' ', ind ) +1;
108: // color
109: int end = list.indexOf( "bag", ind );
110: String color = list.substring( ind, end -1 );
111: inside.add( color );
112: ind = list.indexOf( ", ", end ) +2;
113: //System.out.println( "color "+ color +"; pointing at "+ ind +" is_"+ list.charAt( ind ) );
114: if ( ind == 1 )
115: break; // added 2 above
116:
117: }
118: /*
119: light red bags contain 1 bright white bag, 2 muted yellow bags.
120: bright white bags contain 1 shiny gold bag.
121: muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
122: */
123: return inside;
124: }
125: }
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
Generated by git2html.