<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="155431" data-post-id="155431">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My answer was 7048 steps <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155431" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-155431" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155431"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="155433" data-post-id="155433">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="lud" data-post="8" data-topic="27657">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/48/14382_2.png" class="avatar"> lud:</div>
<blockquote>
<p>Could you tell me if (and how) do you avoid to compute all possible paths from key to key ?</p>
</blockquote>
</aside>
<p>I solved this via brute force (so basically computing all paths), and got it to a “reasonable” time with the following optimizations:</p>
<ol>
<li>Keep track of current best. Discard any state where more steps have been taken.</li>
<li>When considering possible next moves, prefer the keys which are closer to me. This brings me sooner to lower results, which helps optimization from 1 eliminate a bunch of combinations that would otherwise be considered fully.</li>
<li>Keep track of the seen state. If I find my self at the same point I’ve already been at, and my acquired keys are the same as, or a subset of, what I’ve already explored, and the number of steps I’ve taken is the same or larger, I stop tracking further. This one really eliminates a lot of combinations, but it’s quite tricky to do right, and I’m still not certain if I did everything properly. Also, this condition has to be expanded in part 2 to account for mutliple robots.</li>
<li>When choosing next possible moves, take only immediate points in path. For example, let’s say that I can get to keys a, b, and c, and that a is in path of c. I’ll only take the key a (unless I have it, in which case I’ll take the key c), and b. This also eliminates a bunch of redundant combinations.</li>
<li>Finally, I’ve precomputed the shortest distances between keys upfront. This is based on the assumption that the shortest path doesn’t change if some door is unlocked.</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155433" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-155433" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155433"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="155448" data-post-id="155448">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bjorng" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bjorng/120/13187_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bjorng
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Erlang Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I spent a lot of time working on my solution yesterday. My approach was a little bit unusual, in that I used <code>:digraph.get_shortest_path/1</code> to get the path from the current position to a given key. I combined that with BFS algorithm (with a priority queue based on <code>gb_sets</code>. Because <code>digraph</code> is not purely functional, I had to delete and add edges to lock and unlock doors. I got it to work on all examples, but it needed about 5 minutes for the “evil” example. Attempt at optimizations either didn’t make it faster or resulted in an incorrect result.</p>
<p>Yesterday evening I gave up and scrapped my solution.</p>
<p>Since I am here to improve my Elixir skills, I decided to rewrite <a class="mention" href="/u/ferd" rel="nofollow">@ferd</a>’s   <a href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/4" rel="nofollow">Erlang solution</a> to Elixir. I also tried to do more optimizations, but the only one that seemed to give a slight improvement was to use <code>gb_sets</code> for the priority queue instead of <code>queue</code>. I also changed the data representation to get rid of the calls to <code>atom_to_list/1</code> and <code>list_to_atom/1</code>.</p>
<p><a href="https://github.com/bjorng/advent-of-code-2019/blob/b9ee6b7b5b5f2da127364a2ac86ec32caca47932/day18/lib/day18.ex" rel="noopener nofollow ugc">My solution</a> solves both parts in about 20 seconds.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155448" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-155448" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155448"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="155460" data-post-id="155460">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ferd" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ferd/120/12731_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ferd
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Property-Based Testing with PropEr, LYSE, &amp; Erlang in Anger</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think using gb_sets might give you an optimization you haven’t used where the moment all the keys are found, you can stop the run because you’re guaranteed that what’s left in the set is going to have longer paths.</p>
<p>This isn’t always true of the queue approach where there is a kind of “scheduling” order where it’s possible that some slightly longer paths are processed before shorter ones, and the queue needs emptying.</p>
<p>I don’t know how significant it would be, but it could probably speed-up later runs when most keys are grabbed and a lot of dead-end paths are still being investigated.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="155460" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-155460" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="155460"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="156625" data-post-id="156625">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ihabunek" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ihabunek/120/17573_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ihabunek
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Late to the party, but solved this challenge recently so here it my take if anyone is interested:<br>
<a href="https://git.sr.ht/~ihabunek/aoc2019/tree/master/lib/day18.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://git.sr.ht/~ihabunek/aoc2019/tree/master/lib/day18.ex</a></p>
<p>Same algorithm works on both parts, takes under 4s for each part on my machine.</p>
<p>I’m doing a dijkstra-like search which processes only one move per iteration with the following optimizations:</p>
<ul>
<li>keep a set of visited unique vault states (a state comprises of: robot positions, remaining keys and distance traveled so far) and skip any already visited states</li>
<li>keep the best (shortest) path found so far, and skip any steps which would go over this limit</li>
<li>keep a cache of possible robot moves given current vault state so it’s not calculated every time from scratch</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="156625" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2019-day-18/27657/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-156625" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="156625"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>