Ci-dessous ma soluce en Java pour la partie 2. Elle met 403ms une fois Java lancé (c'est comme un bon diesel Java). Et encore, j'ai une vilaine boucle qui compte jusqu'à avant le milliard.
J'optimise en utilisant des objets mutable & un bon vieux cache basé sur un Record.
packageaoc2023;importjava.util.ArrayList;importjava.util.List;importjava.util.Scanner;publicclassAoc2023s14v2{enumType{SPHERE,ROCK;}publicstaticclassPoint{intx;inty;Typetype;publicPoint(intx,inty,Typetype){this.x=x;this.y=y;this.type=type;}}publicstaticclassWorld{intwidth;intheight;Point[][]map;List<Point>spheres=newArrayList<>();publicWorld(List<String>rows){map=newPoint[rows.size()][rows.get(0).length()];for(inty=0;y<rows.size();y++){addRow(rows.get(y),y);}this.height=rows.size();}publicvoidaddRow(Stringrow,inty){this.width=row.length();for(intx=0;x<row.length();x++){Pointp=null;if(row.charAt(x)=='O'){p=newPoint(x,y,Type.SPHERE);spheres.add(p);}elseif(row.charAt(x)=='#'){p=newPoint(x,y,Type.ROCK);}map[y][x]=p;}}publicbooleanisFree(intx,inty){if(x<0||x>=width||y<0||y>=height){returnfalse;}returnthis.map[y][x]==null;}publicPointfind(intx,inty){if(x<0||x>=width||y<0||y>=height){returnnull;}returnthis.map[y][x];}publicvoidmove(intdx,intdy){booleanchange=false;do{change=false;for(Pointp:spheres){if(isFree(p.x+dx,p.y+dy)){map[p.y][p.x]=null;p.x+=dx;p.y+=dy;map[p.y][p.x]=p;change=true;}}}while(change);}publicintcomputeWeight(){intsum=0;for(Pointsphere:spheres){sum+=(height-sphere.y);}returnsum;}publicList<String>toRows(){List<String>rows=newArrayList<>();StringBuildersb=newStringBuilder();for(inty=0;y<height;y++){sb.setLength(0);for(intx=0;x<width;x++){Pointp=find(x,y);if(p==null){sb.append('.');}elseif(p.type==Type.ROCK){sb.append('#');}else{sb.append('O');}}rows.add(sb.toString());}returnrows;}}publicstaticvoidmain(String[]args){longstartMs=System.currentTimeMillis();try(Scannerin=newScanner(Aoc2023s14v2.class.getResourceAsStream("res/t14.txt"))){List<String>rows=newArrayList<>();while(in.hasNext()){rows.add(in.nextLine());}IntegerstartCycle=null;IntegercycleCount=null;Worldworld=null;finallongLOOPS=1_000_000_000L;for(longx=0;x<LOOPS;x++){CacheKeycurrent=newCacheKey(rows);if(keys[current.cacheIndex()]!=null&&keys[current.cacheIndex()].equals(current)){if(startCycle==null){startCycle=current.cacheIndex();cycleCount=0;}elseif(startCycle==current.cacheIndex()){System.out.println("Make cycle: "+cycleCount);// Could be more elegant :)while(x<(LOOPS-cycleCount)){x+=(cycleCount+1);}}else{cycleCount++;}world=cache_worlds[current.cacheIndex()];}else{world=computeWorld(rows);keys[current.cacheIndex()]=current;cache_worlds[current.cacheIndex()]=world;System.out.println("miss "+x);startCycle=null;cycleCount=null;}rows=world.toRows();}System.out.println(world.computeWeight());}System.out.println((System.currentTimeMillis()-startMs)+"ms");}privatestaticWorldcomputeWorld(List<String>rows){Worldworld;world=newWorld(rows);world.move(0,-1);world.move(-1,0);world.move(0,1);world.move(1,0);returnworld;}publicstaticrecordCacheKey(List<String>rows){publicintcacheIndex(){returnMath.abs(this.hashCode())%CACHE_SIZE;}}publicstaticfinalintCACHE_SIZE=1_000_000;publicstaticCacheKey[]keys=newCacheKey[CACHE_SIZE];publicstaticWorld[]cache_worlds=newWorld[CACHE_SIZE];}
# Solution en Java 403ms
Posté par syj . En réponse au message Advent of Code, jour 14. Évalué à 1.
Ci-dessous ma soluce en Java pour la partie 2. Elle met 403ms une fois Java lancé (c'est comme un bon diesel Java). Et encore, j'ai une vilaine boucle qui compte jusqu'à avant le milliard.
J'optimise en utilisant des objets mutable & un bon vieux cache basé sur un Record.