some-advent-of-code: bb868ec6bdc0dd1b7d21e2acc384d60c59dbd046
1:
2: import java.awt.Point;
3: import java.io.IOException;
4: import java.nio.file.Files;
5: import java.nio.file.InvalidPathException;
6: import java.nio.file.Path;
7: import java.nio.file.Paths;
8: import java.util.ArrayList;
9: import java.util.Collection;
10: import java.util.LinkedList;
11: import java.util.List;
12: import java.util.HashSet;
13: import java.util.Map;
14: import java.util.Set;
15: import java.util.SortedSet;
16: import java.util.TreeMap;
17: import java.util.TreeSet;
18:
19: public class Exercise19031
20: {
21:
22: public static void main( String args[] )
23: {
24: final String here = Exercise19031.cl +"m ";
25: if ( args.length < 1 )
26: {
27: throw new RuntimeException( here +"add a filename argument" );
28: }
29: String userSaysFile = args[ 0 ];
30: List<String> fileLines = new LinkedList<>();
31: try
32: {
33: Path where = Paths.get( userSaysFile );
34: fileLines = Files.readAllLines( where );
35: }
36: catch ( IOException | InvalidPathException ie )
37: {
38: System.err.println( here +"couldn't read file "+ userSaysFile +" because "+ ie );
39: return;
40: }
41: /*
42: - interpretation of spec -
43: input has two csv strings, each is a wire
44: elements are cardinal vectors of operand {R D L U}
45: note the paths these take
46: note the intersections between them (but not of itself)
47: of those intersections, choose the point closest to origin
48: convert that distance to the 'manhattan'/'taxicab' distance (by making cardinal vectors to reach)
49: this is the result to provide
50:
51: potential means
52: make a set of integral points on the line of each part of the path
53: for each point of first wire, check if second wire contains point
54: if so add to intersection set
55: calculate the distance of each point in the intersection set, directly or as 'manhattan' distance
56: create a map of intersection points : 'manhattan' distance from the origin
57: choose the lowest valued point, reply with this
58:
59: split by comma
60: have an awareness of the current
61: convert instruction into a vector
62: gen the list of point pairs indicated
63: */
64: new Exercise19031( fileLines.get( 0 ), fileLines.get( 1 ) )
65: .manhattanDistanceOfClosestIntersection();
66: }
67:
68:
69: private static final String cl = "e19031.";
70: private String firstWire;
71: private String secondWire;
72:
73:
74: public Exercise19031( String first, String second )
75: {
76: firstWire = first;
77: secondWire = second;
78: }
79:
80:
81: public void manhattanDistanceOfClosestIntersection()
82: {
83: final String here = cl +"mdhoci ";
84: // System.out.println( "\t"+ here + "--- "+ firstWire );
85: Collection<Vector> convertedFirst = converted( firstWire );
86: Set<Cpoint> pointsFirst = pointsOfLine( convertedFirst );
87:
88: // System.out.println( "\t"+ here + "--- "+ secondWire );
89: Collection<Vector> convertedSecond = converted( secondWire );
90: Set<Cpoint> pointsSecond = pointsOfLine( convertedSecond );
91:
92: // render( pointsFirst, pointsSecond );
93: Set<Cpoint> crossover = intersectionsOf( pointsFirst, pointsSecond );
94: Cpoint closest = closestToOriginManhattanwise( crossover );
95: System.out.println( "\t"+ here + "closest "+ closest );
96: /*
97: make a set of integral points on the line of each part of the path
98: for each point of first wire, check if second wire contains point
99: if so add to intersection set
100: calculate the distance of each point in the intersection set, directly or as 'manhattan' distance
101: create a map of intersection points : 'manhattan' distance from the origin
102: choose the lowest valued point, reply with this
103:
104: have an awareness of the current
105: convert instruction into a vector
106: gen the list of point pairs indicated
107: */
108: // 4TESTS
109: }
110:
111:
112: private Collection<Vector> converted( String which )
113: {
114: String[] notCsv = which.split( "," );
115: Collection<Vector> converted = new ArrayList<>( notCsv.length );
116: for ( String acronym : notCsv )
117: {
118: converted.add( vectorOfAcronym( acronym ) );
119: }
120: return converted;
121: }
122:
123:
124: private Vector vectorOfAcronym( String input )
125: {
126: Vector result = new Vector();
127: result.magnitude = Integer.parseInt( input.substring( 1 ) );
128: result.direction = CardinalDirection.from( input.substring( 0, 1 ) );
129: return result;
130: }
131:
132:
133: private Set<Cpoint> pointsOfLine( Collection<Vector> instructions )
134: {
135: final String here = cl +"pol ";
136: // Set<Cpoint> allPoints = new HashSet<>( instructions.size() * 10 );
137: Set<Cpoint> allPoints = new TreeSet<>();
138: Cpoint origin = new Cpoint( 0, 0 );
139: Cpoint previous = origin;
140: Cpoint tip = origin;
141: for ( Vector arrow : instructions )
142: {
143: // System.out.println( "\t\taa "+ arrow );
144: switch ( arrow.direction )
145: {
146: case UP :
147: {
148: tip = new Cpoint( previous.x, previous.y + arrow.magnitude );
149: // System.out.println( "\t\tt "+ tip.x +" : "+ tip.y );
150: allPoints.add( tip );
151: for ( int ind = previous.y; ind < tip.y; ind++ )
152: {
153: allPoints.add( new Cpoint( previous.x, ind ) );
154: // System.out.println( "\t\t"+ previous.x +" : "+ ind );
155: }
156: break;
157: }
158: case DOWN :
159: {
160: tip = new Cpoint( previous.x, previous.y - arrow.magnitude );
161: // System.out.println( "\t\tt "+ tip.x +" : "+ tip.y );
162: allPoints.add( tip );
163: for ( int ind = tip.y; ind < previous.y; ind++ )
164: {
165: allPoints.add( new Cpoint( previous.x, ind ) );
166: // System.out.println( "\t\t"+ previous.x +" : "+ ind );
167: }
168: break;
169: }
170: case LEFT :
171: {
172: tip = new Cpoint( previous.x - arrow.magnitude, previous.y );
173: // System.out.println( "\t\tt "+ tip.x +" : "+ tip.y );
174: allPoints.add( tip );
175: for ( int ind = tip.x; ind < previous.x; ind++ )
176: {
177: allPoints.add( new Cpoint( ind, previous.y ) );
178: // System.out.println( "\t\t"+ ind +" : "+ previous.y );
179: }
180: break;
181: }
182: case RIGHT :
183: {
184: tip = new Cpoint( previous.x + arrow.magnitude, previous.y );
185: // System.out.println( "\t\tt "+ tip.x +" : "+ tip.y );
186: allPoints.add( tip );
187: for ( int ind = previous.x; ind < tip.x; ind++ )
188: {
189: allPoints.add( new Cpoint( ind, previous.y ) );
190: // System.out.println( "\t\t"+ ind +" : "+ previous.y );
191: }
192: break;
193: }
194: default :
195: {
196: break;
197: }
198: }
199: // System.out.println( "\t"+ here + tip );
200: previous.setLocation( tip );
201: }
202: /*
203: for ( Cpoint buh : allPoints )
204: {
205: System.out.println( "\t"+ here + buh );
206: }
207: */
208: return allPoints;
209: }
210:
211:
212: private void render( Set<Cpoint> toShow )
213: {
214: int minXx = 0;
215: int maxXx = 0;
216: int minYy = 0;
217: int maxYy = 0;
218: for ( Cpoint candidate : toShow )
219: {
220: if ( candidate.x < minXx )
221: minXx = candidate.x;
222: if ( candidate.x > maxXx )
223: maxXx = candidate.x;
224: if ( candidate.y < minYy )
225: minYy = candidate.y;
226: if ( candidate.y > maxYy )
227: maxYy = candidate.y;
228: }
229: Cpoint probe = new Cpoint( 0, 0 );
230: for ( int indXx = minXx; indXx <= maxXx; indXx += 1 )
231: {
232: for ( int indYy = minYy; indYy <= maxYy; indYy += 1 )
233: {
234: probe.setLocation( indXx, indYy );
235: if ( toShow.contains( probe ) )
236: System.out.print( "x " );
237: else
238: System.out.print( "- " );
239: }
240: System.out.println();
241: }
242: }
243:
244:
245: private void render( Set<Cpoint> first, Set<Cpoint> second )
246: {
247: int minXx = 0;
248: int maxXx = 0;
249: int minYy = 0;
250: int maxYy = 0;
251: for ( Cpoint candidate : first )
252: {
253: if ( candidate.x < minXx )
254: minXx = candidate.x;
255: if ( candidate.x > maxXx )
256: maxXx = candidate.x;
257: if ( candidate.y < minYy )
258: minYy = candidate.y;
259: if ( candidate.y > maxYy )
260: maxYy = candidate.y;
261: }
262: for ( Cpoint candidate : second )
263: {
264: if ( candidate.x < minXx )
265: minXx = candidate.x;
266: if ( candidate.x > maxXx )
267: maxXx = candidate.x;
268: if ( candidate.y < minYy )
269: minYy = candidate.y;
270: if ( candidate.y > maxYy )
271: maxYy = candidate.y;
272: }
273: Cpoint probe = new Cpoint( minXx, minYy );
274: for ( int indXx = minXx; indXx <= maxXx; indXx += 1 )
275: {
276: for ( int indYy = minYy; indYy <= maxYy; indYy += 1 )
277: {
278: probe.setLocation( indXx, indYy );
279: if ( first.contains( probe ) && second.contains( probe ) )
280: System.out.print( "* " );
281: else if ( first.contains( probe ) )
282: System.out.print( "x " );
283: else if ( second.contains( probe ) )
284: System.out.print( "k " );
285: else
286: System.out.print( "- " );
287: }
288: System.out.println();
289: }
290: }
291:
292:
293: private Set<Cpoint> intersectionsOf( Set<Cpoint> first, Set<Cpoint> second )
294: {
295: final String here = cl +"io ";
296: Set<Cpoint> intersections = new HashSet<>( first.size() /10 );
297: for ( Cpoint candidate : first )
298: {
299: if ( second.contains( candidate ) )
300: {
301: intersections.add( candidate );
302: // System.out.println( here + candidate );
303: }
304: }
305: return intersections;
306: }
307:
308:
309: // deprecated
310: private Cpoint closestToOrigin( Set<Cpoint> somePoints )
311: {
312: Cpoint origin = new Cpoint( 0, 0 );
313: Cpoint probe = new Cpoint( 0, 0 );
314: double minDistance = Double.MAX_VALUE, currDistance = -1;
315: for ( Cpoint candidate : somePoints )
316: {
317: if ( candidate.compareTo( origin ) == 0 )
318: continue;
319: currDistance = origin.distance( candidate );
320: if ( currDistance < minDistance )
321: {
322: probe.setLocation( candidate );
323: minDistance = currDistance;
324: }
325: }
326: System.out.println( cl +"coo "+ minDistance );
327: return probe;
328: }
329:
330:
331: private Cpoint closestToOriginManhattanwise( Set<Cpoint> somePoints )
332: {
333: Cpoint origin = new Cpoint( 0, 0 );
334: Cpoint probe = new Cpoint( 0, 0 );
335: int minDistance = Integer.MAX_VALUE, currDistance = -1;
336: for ( Cpoint candidate : somePoints )
337: {
338: if ( candidate.compareTo( origin ) == 0 )
339: continue;
340: currDistance = Math.abs( candidate.x ) + Math.abs( candidate.y );
341: if ( currDistance < minDistance )
342: {
343: probe.setLocation( candidate );
344: minDistance = currDistance;
345: }
346: }
347: System.out.println( cl +"coo "+ minDistance );
348: return probe;
349: }
350:
351:
352: private class Vector
353: {
354: int magnitude = 0;
355: CardinalDirection direction = CardinalDirection.UNKNOWN;
356:
357: @Override
358: public String toString()
359: {
360: return direction.toString() + Integer.valueOf( magnitude ).toString();
361: }
362: }
363:
364:
365: private enum CardinalDirection
366: {
367: UP( "U" ),
368: DOWN( "D" ),
369: LEFT( "L" ),
370: RIGHT( "R" ),
371: UNKNOWN( "" );
372:
373: public static CardinalDirection from( String candidate )
374: {
375: for ( CardinalDirection canon : CardinalDirection.values() )
376: {
377: if ( canon.toString().equals( candidate ) )
378: return canon;
379: }
380: return CardinalDirection.UNKNOWN; // NOTE fallback
381: }
382:
383: private String equivalent;
384:
385: private CardinalDirection( String code )
386: {
387: equivalent = code;
388: }
389:
390: @Override
391: public String toString()
392: {
393: return equivalent;
394: }
395: }
396:
397:
398: private class Cpoint extends Point implements Comparable<Cpoint>
399: {
400: public Cpoint( int xx, int yy )
401: {
402: super( xx, yy );
403: }
404:
405: @Override
406: public int compareTo( Cpoint another )
407: {
408: if ( this.x == another.x )
409: {
410: if ( this.y == another.y )
411: return 0;
412: else if ( this.y < another.y )
413: return -1;
414: else
415: return 1;
416: }
417: else if ( this.x < another.x )
418: return -1;
419: else
420: return 1;
421: }
422:
423: @Override
424: public String toString()
425: {
426: return "C"+ x +","+ y;
427: }
428: }
429:
430: }
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
Generated by git2html.