<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Christopher Kruse</title>
    <description>The latest articles on DEV Community by Christopher Kruse (@ballpointcarrot).</description>
    <link>https://dev.to/ballpointcarrot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F44062%2F92d7dc02-0ef7-4cd5-b93c-02b7b25fc4c2.jpg</url>
      <title>DEV Community: Christopher Kruse</title>
      <link>https://dev.to/ballpointcarrot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ballpointcarrot"/>
    <language>en</language>
    <item>
      <title>Running Rust on AWS Lambda on ARM64</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Wed, 06 Oct 2021 23:31:14 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/running-rust-on-aws-lambda-on-arm64-4h28</link>
      <guid>https://dev.to/ballpointcarrot/running-rust-on-aws-lambda-on-arm64-4h28</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;TL;DR: Rust on ARM64 Lambda: check out &lt;a href="https://github.com/ballpointcarrot/lambda-rust-arm64" rel="noopener noreferrer"&gt;my example repo&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've been a hobbyist Rust developer for a while now, playing with random tools and mostly having false starts on projects that I'd like to build, but then the energy to do so wanes before I can complete them. Because of that, I always look for new applications for Rust to fit somewhere in my day-to-day, so that I can give myself some practice.&lt;/p&gt;

&lt;p&gt;I also work very closely with AWS Serverless tooling in my daily work at &lt;a href="https://stedi.com" rel="noopener noreferrer"&gt;Stedi&lt;/a&gt;. Recently, AWS posted an update to the Lambda service that they were providing &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/09/better-price-performance-aws-lambda-functions-aws-graviton2-processor/" rel="noopener noreferrer"&gt;Graviton2-based Lambda functions&lt;/a&gt; as part of the service, and I immediately thought to myself, "How would I do a Rust lambda that way?"&lt;/p&gt;

&lt;p&gt;Lambda gives you the ability to create a &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html" rel="noopener noreferrer"&gt;"Custom" runtime&lt;/a&gt; - all you need to do is provide a executable that acts as a bootstrap for running the function (aptly named "bootstrap" in the runtime code). By building that as a rust binary with the correct architecture, we can run Rust code natively on the Lambda!&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;I started with a vanilla cargo project, and added the following into the cargo.toml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[[bin]]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bootstrap"&lt;/span&gt;
&lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"src/main.rs"&lt;/span&gt;

&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;lambda_runtime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^0.4"&lt;/span&gt;
&lt;span class="py"&gt;tokio&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^1"&lt;/span&gt;
&lt;span class="py"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"derive"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;serde_json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"^1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;[[bin]]&lt;/code&gt; section allows us to specify the binary filename for what's built (and saves us renaming the file after compilation). The dependencies are all references and dependencies of &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime" rel="noopener noreferrer"&gt;the AWS Rust runtime crates&lt;/a&gt; - that's where the code for the function we'll be using is pulled from.&lt;/p&gt;

&lt;p&gt;we just have one file in the source directory, at &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;lambda_runtime&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;handler_fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;funct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;handler_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;lambda_runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;funct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;json!&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, {}!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;)}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those less savvy with Rust code, this defines the 'bootstrap' runtime under &lt;code&gt;main()&lt;/code&gt;, and calls the async function &lt;code&gt;func()&lt;/code&gt; to act as the lambda function body. Our function responds with a message of "Hello, World!" in a JSON response by default, or can respond with a specific greeting when passed a "firstName" JSON value as part of its input.&lt;/p&gt;

&lt;p&gt;Now, you could build this locally, but because of the way that the lambda function is called, local runs will panic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;± cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.39s
     Running `target/debug/bootstrap`
thread 'main' panicked at 'Missing AWS_LAMBDA_RUNTIME_API env var: NotPresent', /home/ckruse/.asdf/installs/rust/stable/registry/src/github.com-1ecc6299db9ec823/lambda_runtime-0.4.1/src/lib.rs:57:58
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The immediate goal here is to run it in lambda, and not locally, so we'll save testing it out on our own for a later time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross-Compiling
&lt;/h2&gt;

&lt;p&gt;The example that is provided in the AWS Rust runtime repository shows them using a &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime#aws-cli" rel="noopener noreferrer"&gt;custom linker and rustup target&lt;/a&gt; in order to cross-compile for x86-based lambdas. I attempted to dive into how to get a arm64-based linker, but in the process of trying to figure out how to get that linker installed locally (no convenient packages for Ubuntu, sorry), I stumbled across a project that provides cross-compilation tooling for various platforms via Docker. That made my life a lot easier - Using the &lt;a href="https://github.com/messense/rust-musl-cross" rel="noopener noreferrer"&gt;rust-musl-cross&lt;/a&gt; Docker container, all I have to do is wrap the call to &lt;code&gt;cargo build&lt;/code&gt;, and it builds for the proper architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="nv"&gt;build_arch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aarch64-musl

docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/home/rust/src messense/rust-musl-cross:&lt;span class="nv"&gt;$build_arch&lt;/span&gt; &lt;span class="nv"&gt;$@&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Armed with that (pardon the pun), I can now call &lt;code&gt;./musl-build cargo build --release&lt;/code&gt;, and I get a resulting binary at &lt;code&gt;target/aarch64-unknown-linux-musl/release/bootstrap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The final step, as called out in the AWS Rust runtime docs, is to bundle that executable up in a Zip file, so that the Lambda service can construct what it needs to on its side. I've made the &lt;code&gt;package.sh&lt;/code&gt; file in the repo to handle that and act as a basic build script (I'll probably convert this to a Makefile later when feeling energetic):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; dist

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; target/aarch64-unknown-linux-musl &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
  ./musl-build cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# TODO: use vars for arch folder and binary name&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;target/aarch64-unknown-linux-musl/release/bootstrap dist/
&lt;span class="nb"&gt;cd &lt;/span&gt;dist &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; zip package.zip bootstrap &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, after running that command, I can grab the file at &lt;code&gt;dist/package.zip&lt;/code&gt; and go take that to AWS Lambda to run:&lt;/p&gt;

&lt;p&gt;With no arguments provided:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Frust-arm-lambdas%2Frust-arm-lambda-default.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Frust-arm-lambdas%2Frust-arm-lambda-default.png" alt="Rust Lambda without name"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With a name provided:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Christopher"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Frust-arm-lambdas%2Frust-arm-lambda-name.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Frust-arm-lambdas%2Frust-arm-lambda-name.png" alt="Rust Lambda with firstName"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope you can use this to make a running start building out lambda function code on the new Graviton2-based Lambda runners. Let me know if this helped you out!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>aws</category>
      <category>rust</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Share your favorite reads!</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Tue, 25 Jun 2019 23:25:49 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/share-your-favorite-reads-2980</link>
      <guid>https://dev.to/ballpointcarrot/share-your-favorite-reads-2980</guid>
      <description>&lt;p&gt;As we go through time, learning and growing our software craft, there are often pieces that catch and become indelibly marked in our minds as pivotal. I hesitate to use the word "game-changer", but the effect is the same - after reading it, you are forever altered in your way of thinking.&lt;/p&gt;

&lt;p&gt;I'd love to share a couple of mine that I've encountered, and reference and re-reference to friends and colleagues frequently. These are blog posts that I hope never see removed from the Internet:&lt;/p&gt;




&lt;h2&gt;
  
  
  _why's Poignant Guide to Ruby:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://poignant.guide/"&gt;https://poignant.guide/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I caught this when it was more-or-less originally published, and it sparked my love of programming in a way that was literate. Putting focus on understanding how to write code in a way that made sense to humans, but could also be parsed my machines, was the jump I needed to realize I could do this as a lifetime pursuit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Execution in the Kingdom of Nouns:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html"&gt;https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I played around with looking at other ways of writing code outside of OOP (Scala, Lisps, Haskell), but it never really clicked until seeing it presented as Steve presents it here. Obviously it demonizes OOP a little bit, but in the effort to show that there's a better way that exists.&lt;/p&gt;




&lt;h2&gt;
  
  
  Learn ViM for the last time:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://danielmiessler.com/study/vim/"&gt;https://danielmiessler.com/study/vim/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apparently I understand things better when you give me examples in terms of 'verbs' and 'nouns'. :)&lt;/p&gt;

&lt;p&gt;Daniel's vim tutorial helped me to finally get out of a spiral of "try to learn vim, put it down, come back in &lt;em&gt;x&lt;/em&gt; months, repeat". Once I had the understanding of the commands I entered into the editor were speaking a language that was actively interpreted by vim, it made my familiarity with the editor skyrocket, and made me feel much more comfortable in vim as well.&lt;/p&gt;

&lt;p&gt;Even though I no longer use vim directly (I keep my vim config up to date at times, but I've moved to Emacs with the evil package), I'll always send someone learning vim to this page, to help enlighten them.&lt;/p&gt;




&lt;h2&gt;
  
  
  New Programming Jargon (from StackOverflow):
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.codinghorror.com/new-programming-jargon/"&gt;https://blog.codinghorror.com/new-programming-jargon/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've had tons of times where I've used one of these terms, and have been met with a look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/tu54GM19sqJOw/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/tu54GM19sqJOw/giphy.gif" alt="wtf" width="320" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then promptly send them to this post, laughs are had, and all is made clear. I'm sure I'll use "Yoda conditions", "Pokemon Exception Handling", and "Smurf naming" for the forseeable future. :)&lt;/p&gt;




&lt;h2&gt;
  
  
  Clojure for the Brave and True:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.braveclojure.com/clojure-for-the-brave-and-true/"&gt;https://www.braveclojure.com/clojure-for-the-brave-and-true/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Daniel's introductory book on Clojure bridged a lot of gaps for me when trying to learn the language. The humor reminded me a lot of _why's Poignant Guide, and put the 'fun' in thinking 'functionally'.&lt;/p&gt;




&lt;p&gt;Please share some of your blog posts or vignettes that have changed your way of thinking around programming! Looking forward to adding more to my list. :D&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
    </item>
    <item>
      <title>Finding my Loaf of Bread</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Tue, 07 May 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/finding-my-loaf-of-bread-2da6</link>
      <guid>https://dev.to/ballpointcarrot/finding-my-loaf-of-bread-2da6</guid>
      <description>&lt;p&gt;I made my first loaf of bread last Saturday.&lt;/p&gt;

&lt;p&gt;I've been watching a lot of &lt;a href="https://thegreatbritishbakeoff.co.uk/"&gt;"The Great British Bakeoff"&lt;/a&gt; (or "Baking Show" if you're in the US, because of &lt;a href="http://www.pbs.org/publiceditor/blogs/pbs-public-editor/whats-in-a-name/"&gt;trademark reasons&lt;/a&gt;). Watching people on your television make intricate, creative, and most importantly &lt;em&gt;delicious-looking&lt;/em&gt; baked goods, the desire to try it yourself becomes irresistable. Both my wife and I have tried some things we've seen on the show, to decent result. However, I've never really been a "Baker" - I've generally avoided the big hot box that sits underneath the stove, and would tell people that me and that box didn't really get along well.&lt;/p&gt;

&lt;p&gt;Despite this, the drive to try it out was too much to handle. I made use of the fact that my wife was out of town this past weekend to give me some buffer time: if things turned out well, I'd have a nice surprise for her when she returned; if I screwed up things or made a complete mess of the kitchen, I'd have time to destroy the evidence. :D&lt;/p&gt;

&lt;p&gt;My project took about 3 hours from start to finish; I began later than I really should have (around 8pm), but since I wasn't disturbing anyone by my late-night "breadscapade", I kept at it. I won't go into too much of the process, as photos can provide more insight here:&lt;/p&gt;

&lt;p&gt;The dough sat for about an hour to rise:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ThPVbbnO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_210312.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ThPVbbnO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_210312.jpg" alt="pre-rise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fsWf7wGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_220141.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fsWf7wGD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_220141.jpg" alt="post-rise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After rising, the recipe I was following directed me to braid 3 strands of the loaf together:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H5f1GDS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_221614.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H5f1GDS0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_221614.jpg" alt="braided, but unbaked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, after an egg wash, it was in the oven for a half-hour. The end result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sh4rF_i1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_225522.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sh4rF_i1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.ballpointcarrot.net/posts/finding-my-loaf-of-bread/IMG_20190504_225522.jpg" alt="glorious looking bread"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Needless to say, I'm happy with how everything turned out.&lt;/p&gt;

&lt;p&gt;Now, this is being posted on &lt;a href="https://dev.to/"&gt;dev.to&lt;/a&gt;, so what does &lt;em&gt;any&lt;/em&gt; of this have to do with programming?&lt;/p&gt;

&lt;p&gt;Reflecting on the process I had doing the above: the timeframe it took, the level of familiarity, determining what I could take away from the experience for next time - I began to wonder what my programming "Loaf of bread" is. Reviewing the criteria I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;took about 3 hours start-to-finish&lt;/li&gt;
&lt;li&gt;dealt with something unfamiliar&lt;/li&gt;
&lt;li&gt;a safe way to clean up the mess in case it failed&lt;/li&gt;
&lt;li&gt;the ability to &lt;a href="https://twitter.com/ballpointcarrot/status/1124895392288477184"&gt;chronicle the process&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I can share it with others if it turns out well&lt;/li&gt;
&lt;li&gt;I should have fun doing it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, the hardest thing in converting this metaphor to programming is the time slot. Learning something new in the programming world (new language/framework/technique/etc.) takes a signifigantly longer amount of time, and I'm generally the type to read through and find tutorials and materials to get a sufficient level of understanding before trying to crank something out on my own. Taking only a 3h timeslot and trying to do learn something meaningful in a new language seems impossible to fit. Maybe I need to expand the time. I could reduce the scope on what I'm learning, but then I feel like I don't capture enough to make what I've learned meaningful with just a tiny piece. This is my normal problem with katas - I can figure out how to solve the problem, but it feels external to how you would deal with a "real problem" in that language.&lt;/p&gt;

&lt;p&gt;I also struggle with a aversion to failure - that's why I had to make sure I had time alone to try the bread, and have sufficient time in case of disaster. I struggle with wanting to do cool things, but not wanting to mess up things in the process. Even though I consciously know that no software project ever works this way, I subconsiously want the thing I build to have a well-thought-out design, and be more-or-less right the first time. Software has the remarkable ability to evolve; I just need to learn to embrace it. With the bread, if I screwed it up I could toss it out, and nobody would know.&lt;/p&gt;

&lt;p&gt;I'm working on ways to handle tracking progress when building something new. I'm usually willing to post in-progress things up on Twitter or the Fediverse, and used some free time on the weekend to set up everything I needed to run livecoding sessions on Twitch. However, there's a big jump between preparing to do that, and actually pulling the trigger.&lt;/p&gt;

&lt;p&gt;An example: I've got a project that I've had for a year that I have started a number of times, but never actually created anything meaningful on. In the latest incantation, I was working on it using Elixir (my language to learn for the year, which I'm doing a bad job of considering it's almost half-over). Once I had my livestream stuff set up, I became terribly nervous - I don't know this language, so the majority of the stream is just going to be me reading through docs, which won't be terribly interesting. I over-indexed on this, and then ended up deciding to just move on to the next household project instead of working on it.&lt;/p&gt;

&lt;p&gt;I'm inside my head a lot here - In my case, I wouldn't have anyone watching to begin with, so streaming out to the void and reading docs may have been okay. And hey, maybe someone jumping in could assist.&lt;/p&gt;

&lt;p&gt;I'd be interested to hear any of your coding "loaves of bread". What kind of projects do you use for trying things out? Is it worth doing a bigger-scope, longer-term thing to build up knowledge? Should I alter my scope of what I consider a "real problem" for a language, so that I can just do?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>help</category>
      <category>discuss</category>
      <category>personalnews</category>
    </item>
    <item>
      <title>Making the Shell Less Scary - Starting out</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Sun, 31 Mar 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/making-the-shell-less-scary-starting-out-4i99</link>
      <guid>https://dev.to/ballpointcarrot/making-the-shell-less-scary-starting-out-4i99</guid>
      <description>&lt;p&gt;I will fully admit that I grew up comfortable working on a computer without a GUI. From my early days, I had an old computer that I mainly used to play games (some things never change, but current ones don't come on 5 1/4" floppies); in order to get those games to run, I learned from my Mom how to access the correct drive, and the commands to run in order to start up the game.&lt;/p&gt;

&lt;p&gt;Today, even though we have fancy GUI apps to do a lot of the work that we need to get done on a daily basis, I still find that it's easier for me to quickly open a terminal window, enter a few commands, and complete whatever task I was doing. Not everything benefits from this approach (imagine doing image editing with a text editor!), but tasks involving finding files, moving files around the system, and working on remote systems works are things that I would much prefer a terminal for.&lt;/p&gt;

&lt;p&gt;Today I'm going to dive into a few of the commands that do just the things that I was talking about. These are some of the commands that you would end up using on  a day-to-day basis in a terminal window; hopefully I can shine some light on some corners of them that you don't expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Directories and Files
&lt;/h3&gt;

&lt;p&gt;Let's say you're an avid photographer - you'll have a lot of photos collected. In order to make sense of your collection, you're going to want to organize those photos. If they were physical photos, you'd want to collect them by the event that you took them at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tim's birthday party&lt;/li&gt;
&lt;li&gt;Joe's wedding&lt;/li&gt;
&lt;li&gt;Vacation photos from Las Vegas&lt;/li&gt;
&lt;li&gt;random photos of food&lt;/li&gt;
&lt;li&gt;far too many cat pictures&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, let's say these photos happened over the course of a few years.&lt;/p&gt;

&lt;p&gt;Borrowing from the physical realm, we can place these photos into different folders, or &lt;em&gt;directories&lt;/em&gt;, in order to keep them organized. Let's lay them out like so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2018

&lt;ul&gt;
&lt;li&gt;Joe's Wedding&lt;/li&gt;
&lt;li&gt;I &amp;lt;3 Food&lt;/li&gt;
&lt;li&gt;My Cat&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;2019

&lt;ul&gt;
&lt;li&gt;Tim's Bday Bash&lt;/li&gt;
&lt;li&gt;Vegas trip&lt;/li&gt;
&lt;li&gt;My Cat&lt;/li&gt;
&lt;li&gt;I &amp;lt;3 Food&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You'll notice there are duplicate names here - that's okay, because they're nested within two different folders.&lt;/p&gt;

&lt;p&gt;Now, all of these folder names are legit as they stand, but they'll be a little harder to deal with when on the command line with some of the special characters and spaces. It's a standard convention to replace spaces and special characters in names to make it easy to deal with, while retaining most of the meaning that was present in the original names; most of the replacements are things like dashes or underscores. This would be my likely replacement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2018

&lt;ul&gt;
&lt;li&gt;joe-wedding&lt;/li&gt;
&lt;li&gt;i-heart-food&lt;/li&gt;
&lt;li&gt;my-cat&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;2019

&lt;ul&gt;
&lt;li&gt;tim-bday-bash&lt;/li&gt;
&lt;li&gt;vegas-trip&lt;/li&gt;
&lt;li&gt;my-cat&lt;/li&gt;
&lt;li&gt;i-heart-food&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Syntactically very similar, and much easier to deal with while typing.&lt;/p&gt;

&lt;p&gt;So rather than pulling up a file manager window, let's make this structure out of commands at a terminal.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;mkdir&lt;/code&gt; makes the dirs
&lt;/h4&gt;

&lt;p&gt;the &lt;code&gt;mkdir&lt;/code&gt; command is used to make a directory. The basic invocation is very straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir &amp;lt;folder-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will create a new directory with the given name based on the directory you're currently in (referred to as your 'Current Working Directory' or 'Present Working Directory'). Sometimes the terminal you're using will tell you where you are as part of the prompt; even if not, you can find out by running the command &lt;code&gt;pwd&lt;/code&gt; to give you that directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pwd
/home/ballpointcarrot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So let's make our photo collection structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir 2018

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait... Nothing came back. Did it do anything?&lt;/p&gt;

&lt;h4&gt;
  
  
  add &lt;code&gt;ls&lt;/code&gt; to the list
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;ls&lt;/code&gt; is a versatile command - it gives you a listing of your PWD. This becomes handy when you're looking around you filesystem, and generally know where something is located. If we do an &lt;code&gt;ls&lt;/code&gt; where we are now, you'll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls
2018/   Desktop/        Downloads/      Notes/          Videos/
Books/  Documents/      Music/          Photos/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oops... that 2018 isn't in the right spot. Let's move it with &lt;code&gt;mv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mv 2018 Photos

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we get no output signifying anything. However, on the next &lt;code&gt;ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls
Books/          Documents/      Music/  Photos/
Desktop/        Downloads/      Notes/  Videos/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can see that the 2018 folder is no longer here. We want to make sure that it's in the Photos directory though, so we'll check there, too:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: this shows that the &lt;code&gt;ls&lt;/code&gt; command can be used on folders - meaning you don't have to be &lt;em&gt;in&lt;/em&gt; the folder to use &lt;code&gt;ls&lt;/code&gt;. That gets handy when you're searching a lot of subfolders.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls Photos
10262018_0001.JPG  10262018_0035.JPG  10262018_0069.JPG  10262018_0103.JPG  10262018_0137.JPG  10262018_0171.JPG  10262018_0205.JPG  10262018_0239.JPG  10262018_0273.JPG  10262018_0307.JPG
10262018_0002.JPG  10262018_0036.JPG  10262018_0070.JPG  10262018_0104.JPG  10262018_0138.JPG  10262018_0172.JPG  10262018_0206.JPG  10262018_0240.JPG  10262018_0274.JPG  10262018_0308.JPG
10262018_0003.JPG  10262018_0037.JPG  10262018_0071.JPG  10262018_0105.JPG  10262018_0139.JPG  10262018_0173.JPG  10262018_0207.JPG  10262018_0241.JPG  10262018_0275.JPG  10262018_0309.JPG
10262018_0004.JPG  10262018_0038.JPG  10262018_0072.JPG  10262018_0106.JPG  10262018_0140.JPG  10262018_0174.JPG  10262018_0208.JPG  10262018_0242.JPG  10262018_0276.JPG  10262018_0310.JPG
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whoa! Where's the 2018 folder? These are all just JPG files (the photos that I've been dumping without organizing into the Photos folder). Fortunately, I can filter out the type of object returned from &lt;code&gt;ls&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls -d */
2018//
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's our folder. Now let's explain that command: the &lt;code&gt;-d&lt;/code&gt; within the command tells &lt;code&gt;ls&lt;/code&gt; that we just want directories, and not files. However, &lt;code&gt;ls&lt;/code&gt; isn't smart enough on its own to just grab the directories on its own; we have to explicitly say grab "all directories", which is where &lt;code&gt;*/&lt;/code&gt; comes in - it signifies "anything in the current directory" with the asterisk (also called a star or wildcard), and the forward slash is for anything designated a folder.&lt;/p&gt;

&lt;p&gt;Let's get to work on the rest of those folders. First, let's put ourselves in the right place.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;code&gt;cd&lt;/code&gt; - not just for music
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;cd&lt;/code&gt; command changes our current working directory. By changing directories, it gives us the ability to change context with what we're doing on the filesystem. In our case, we'll change to the Photos directory, because we're working in the context of organizing our Photos. Makes sense.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd Photos

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, the command has now output, but we can do a &lt;code&gt;pwd&lt;/code&gt; and see that we've changed places:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pwd
/home/ballpointcarrot/Photos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's finish up our 2018 folders. Me, being lazy, want to do everything in one shot - fortunately, &lt;code&gt;mkdir&lt;/code&gt; lets us do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir 2018/joe-wedding 2018/i-heart-food 2018/my-cat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates three folders, all nested neatly under the 2018 folder. "Great!", we say, and we go to do 2019:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir 2019/tim-bday-bash 2019/vegas-trip 2019/my-cat 2019/i-heart-food
mkdir: cannot create directory ‘2019/tim-bday-bash’: No such file or directory
mkdir: cannot create directory ‘2019/vegas-trip’: No such file or directory
mkdir: cannot create directory ‘2019/my-cat’: No such file or directory
mkdir: cannot create directory ‘2019/i-heart-food’: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uh oh... because we never created the parent 2019 folder, it's not allowing us to build the rest of the directories. We can outwit it though; &lt;code&gt;mkdir&lt;/code&gt; has a parameter option &lt;code&gt;-p&lt;/code&gt;, which gives us the ability to make parent directories within the same call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir -p 2019/tim-bday-bash 2019/vegas-trip 2019/my-cat 2019/i-heart-food

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All good. Just to double-check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls 2019
tim-bday-bash/  vegas-trip/     my-cat/         i-heart-food/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Moving the files in
&lt;/h3&gt;

&lt;p&gt;So now we've got our directory structure in the Photos directory, with a boatload of random JPG files. How are we going to get them organized? It looks like a lot of them are around the same dates (look at all the 10262018_xxxx files we have up there). Let's take a look at one or two of them to get a sample, to make sure it's the right event. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: This step will be different depending on the platform you're on, so I'll give both.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# OSX example&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;open 10262018_0001.JPG

&lt;span class="c"&gt;# Linux example&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;xdg-open 10262018_0001.JPG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both of these commands do the same thing - they ask the current environment to figure out who the best person to open a JPG file is, and then executes that program. Ideally, you'll see a window with your picture loaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fimages%2Fmiles.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fimages%2Fmiles.jpg" alt="miles"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh look, it's a cat photo. We know where those are supposed to go. I'm going to assume the 300+ photos around this time period are all cat photos (don't judge). We're going go go back to using the &lt;code&gt;mv&lt;/code&gt; command. However, instead of individually moving the files one-by-one (which would take &lt;em&gt;forever&lt;/em&gt;), we'll make use of our friend the wildcard, and make all of the files move on their own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mv 10262018_* 2018/my-cat

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we get nothing back as output, so let's double-check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ls 2018/my-cat
10262018_0001.JPG  10262018_0035.JPG  10262018_0069.JPG  10262018_0103.JPG  10262018_0137.JPG  10262018_0171.JPG  10262018_0205.JPG  10262018_0239.JPG  10262018_0273.JPG  10262018_0307.JPG
10262018_0002.JPG  10262018_0036.JPG  10262018_0070.JPG  10262018_0104.JPG  10262018_0138.JPG  10262018_0172.JPG  10262018_0206.JPG  10262018_0240.JPG  10262018_0274.JPG  10262018_0308.JPG
10262018_0003.JPG  10262018_0037.JPG  10262018_0071.JPG  10262018_0105.JPG  10262018_0139.JPG  10262018_0173.JPG  10262018_0207.JPG  10262018_0241.JPG  10262018_0275.JPG  10262018_0309.JPG
10262018_0004.JPG  10262018_0038.JPG  10262018_0072.JPG  10262018_0106.JPG  10262018_0140.JPG  10262018_0174.JPG  10262018_0208.JPG  10262018_0242.JPG  10262018_0276.JPG  10262018_0310.JPG
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great - all our cat photos are now pleasantly sorted.&lt;/p&gt;

&lt;p&gt;I'll leave us here for now. I want to make this a continuing series of posts, so please let me know if there's a command that you're interested in. I know that this one may be a little too basic for a lot of dev-types, but hey - everyone has to start somewhere, right? As long as someone makes use of it, I'm happy.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cli</category>
    </item>
    <item>
      <title>Maintaining Motivation</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Tue, 19 Feb 2019 17:08:57 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/maintaining-motivation-h7g</link>
      <guid>https://dev.to/ballpointcarrot/maintaining-motivation-h7g</guid>
      <description>&lt;p&gt;I've been facing an uphill battle to keep motivation and interest in my day-to-day. My office project has been a bit of a slog to get launched, and by the end of the day, I don't have the drive to come home and try to play with things at home.&lt;/p&gt;

&lt;p&gt;How are people combating scenarios like this, and what things do you do to keep excited / refreshed about the things you're working on?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
    </item>
    <item>
      <title>Advent of Code 2018 - Day 3</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Mon, 03 Dec 2018 00:00:00 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/advent-of-code-2018---day-3-3f0f</link>
      <guid>https://dev.to/ballpointcarrot/advent-of-code-2018---day-3-3f0f</guid>
      <description>&lt;p&gt;Solving these problems has been more difficult than I originally imagined - these aren't your FizzBuzz-level problems; they're asking for a little bit more (especially the second halves). I got a little bit of a head start on day three, as I'm three hours behind the release of the problems, and that means I get to have some time before bed to think about them. This proved bad, as I was laying in bed thinking about solving things (which makes sleeping nigh impossible :D).&lt;/p&gt;

&lt;p&gt;On this particular night/day, I had some issues with work (and I was on-call for my team at the time), so I got a second chance to look at them early in the morning (3am-ish local time). But, once I was up, I was up, so once the work problem subsided, I took a crack at getting the rest of the problem solved.&lt;/p&gt;

&lt;p&gt;This is my first of these writeups to take place after-the-fact, so let me know if there's any issues with how it was covered here vs. the previous days.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 3, Part 1
&lt;/h3&gt;

&lt;p&gt;After we saved the cloth from the previous problem, it's now up to the Elves to figure out how to cut it optimally. The problem statement makes the first assertion that the fabric is a square of 1000x1000 square inches. This proved useful to my method of solving the problem, as you'll see below.&lt;/p&gt;

&lt;p&gt;Each elf makes a claim on the fabric to designate a rectangle they want to cut. The claims have the following format:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#12 @ 3,4: 5x6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which is to be interpreted as "Claim number &lt;code&gt;12&lt;/code&gt;, with the top corner location of &lt;code&gt;(x,y) = (3,4)&lt;/code&gt;, has a width of &lt;code&gt;5&lt;/code&gt; and a height of &lt;code&gt;6&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;To make sense of this, I used a &lt;a href="https://www.regular-expressions.info/quickstart.html" rel="noopener noreferrer"&gt;regular expression&lt;/a&gt; to isolate the various numerical terms (while &lt;a href="https://xkcd.com/208/" rel="noopener noreferrer"&gt;regex is a superpower&lt;/a&gt;, it is also a bit of a rabbit-hole, and I won't cover its general concepts here). Unfortunately, while Java 7+ has support for a regex feature called &lt;a href="https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html#group%28java.lang.String%29" rel="noopener noreferrer"&gt;named capture groups&lt;/a&gt;, Clojure does not have that support out of the box. However, the regex with the named groups still functions, but I can only get positional arguments. I built out a function that took an input claim, and built out a rather interesting set of responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;defrecord&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;claim-number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;convert-to-grid&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"Converts a claim into a sequence of 'taken' squares."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-width&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;;; Named groups would be great here, but Clojure doesn't support this natively.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;matcher&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="s"&gt;"#(?&amp;lt;claim&amp;gt;\d+)\s@\s(?&amp;lt;x&amp;gt;\d+),(?&amp;lt;y&amp;gt;\d+):\s(?&amp;lt;width&amp;gt;\d+)x(?&amp;lt;height&amp;gt;\d+)$"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;re-find&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;matcher&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;horiz&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;horiz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;take&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;iterate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-width&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Claim.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's walk through this example a little.&lt;/p&gt;

&lt;p&gt;The first thing we see is the definition of a clojure &lt;a href="https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/defrecord" rel="noopener noreferrer"&gt;record&lt;/a&gt; (similar to a struct). Because Clojure lives on the JVM, this builds out effectively a Java class and allows you to instantiate objects of that type. The problem above could have been solved with a simple map, but I wanted to give readers of the codebase an easier way to have a mental model of the transformed claim. Additionally, this helps us keep track of the claim number, which is not important in Part 1, but makes a re-appearance in Part 2.&lt;/p&gt;

&lt;p&gt;Because we know the width of the field we'll be working with in units, I made a choice to build out the "rectangle" that a claim represented by identifying the cells that the rectangle makes up. For example, in a 5x5 grid, with a claim of &lt;code&gt;#1 @ 2,0: 3x3&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Fadvent-of-code-2018-3%2Fgrid-set-example.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.ballpointcarrot.net%2Fposts%2Fadvent-of-code-2018-3%2Fgrid-set-example.png" alt="5x5-grid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This leaves us with a set of squares: &lt;code&gt;#{2 3 4 7 8 9 12 13 14}&lt;/code&gt;. The practical upshot here is now we can use set logic (difference, intersection, union) to manipulate the rectangles and calculate our details for overlaps. And that's just what I did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;get-overlap&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"returns the amount of overlap based on calculated inputs.
   Answer provided in square units matching the units entered
   (for the case of the problem, square inches)."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="c1"&gt;;; Perform intersection to find any matches, then union to combine; repeat through the list.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mapped-area&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;convert-to-grid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="n"&gt;shared-fabric&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="n"&gt;intersections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{}]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapped-area&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;intersections&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;intersect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set/intersection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shared-fabric&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:squares&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapped-area&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nb"&gt;union&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set/union&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;shared-fabric&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:squares&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapped-area&lt;/span&gt;&lt;span class="p"&gt;)))]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;mapped-area&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;union&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set/union&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intersections&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;intersect&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again we see our friends &lt;code&gt;loop&lt;/code&gt; and &lt;code&gt;recur&lt;/code&gt; from Day 2. This section highlights one of my favorite things about Clojure - maniuplating data in bulk. We pass into this a vector of claim strings, that are parsed in the function above it. In just one &lt;code&gt;map&lt;/code&gt; call, however, we were able to convert each of those strings into a grid area 1000x1000 wide. Once we have objects we can compute easily against, we go about calculating. :)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;set/intersection&lt;/code&gt; notation is new to these examples, because &lt;code&gt;clojure.set&lt;/code&gt; is outside of Clojure's "Core" namespace - up until now we've been using functions packaged in &lt;code&gt;clojure.core&lt;/code&gt;, which is loaded by default for a Clojure runtime. Since &lt;code&gt;clojure.set&lt;/code&gt; isn't, we have to import it into the namespace (and in our case, provide it a nice short name to use when calling):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aoc.aoc3&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;clojure.set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to call &lt;a href="http://clojuredocs.org/clojure.set" rel="noopener noreferrer"&gt;functions in &lt;code&gt;clojure.set&lt;/code&gt;&lt;/a&gt; by using &lt;code&gt;set/fn-name&lt;/code&gt;. For each iteration of the loop, we do three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We check against the "shared fabric". This is done by doing a set intersection between the current rectangle (defined by &lt;code&gt;(first mapped-area)&lt;/code&gt;) and all of the rectangles that came before it.&lt;/li&gt;
&lt;li&gt;We define the "shared fabric" by adding the current rectangle to the rectangles that have already been added by a set union.&lt;/li&gt;
&lt;li&gt;When we cut back into the next iteration, we take the union of all found intersections in previous iterations, and the intersections we've found in this run. &lt;strong&gt;This&lt;/strong&gt; piece is what gives us our total overlap at the end, as we're constantly accumulating more overlap; because it's a set, however, we're not recounting the same values, we're just including them as "overlapped" already.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once this was done, I was able to solve Part 1 quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 3, Part 2 (Sports Team: 0)
&lt;/h3&gt;

&lt;p&gt;Now that we've found the overlapping area, our challenge is to find the rectangle which does &lt;em&gt;not&lt;/em&gt; have any overlapping area within the list of claims. This is where keeping that claim number comes in handy.&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;wanted&lt;/em&gt; to come up with a clever way of using the set notation used above to make a lightning-quick function for processing the list of rectangles to find one with no overlap, but nothing came to mind. (If anyone finds one, let me know and I'll owe you a coffee.) Instead, I used a little more of a brute force method: compare each grid to the list of grids, and cut out when you find no set intersections. This was a little more computationally intensive (&lt;code&gt;O(n^2)&lt;/code&gt;), but given the count limit in the sample input, it wasn't too bad to sit for a few seconds while the laptop pounded it out.&lt;/p&gt;

&lt;p&gt;I had one hiccup as I was putting this together - how do I managed the list of claims so that I don't run an intersection with myself? That would cause even the "no overlap" rectangle to match (as it's matching itself). What I ended up doing was breaking out the function that handled the overlapping calculation to have a check at the top that said "if you're the same rectangle by claim number, then return &lt;code&gt;nil&lt;/code&gt;" - this allows you to pass the full list and not worry about matching yourself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;overlapping-claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cond&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:claim-number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:claim-number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;nil&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;not-empty&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;set/intersection&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:squares&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:squares&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find-no-overlap&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"given a set of input claims, find the claim that has no overlap
  with any other claims."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;grid-claims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;convert-to-grid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ignores&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{}]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;contains?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:claim-id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-claims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ignores&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;if-let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;overlap&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;overlapping-claim&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-claims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-claims&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;conj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ignores&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:claim-number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;overlap&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:claim-number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;nth&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;grid-claims&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ignores&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool Clojure-y things to point out here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;cond&lt;/code&gt;. Think of &lt;a href="http://clojuredocs.org/clojure.core/cond" rel="noopener noreferrer"&gt;&lt;code&gt;cond&lt;/code&gt;&lt;/a&gt; as a bit of a &lt;code&gt;if/else&lt;/code&gt; on steroids. It allows you to pass a pair of items: test expression, and success expression. If the test expression passes (ie, returns &lt;code&gt;true&lt;/code&gt;), then the success expression is evaluated and returned (immediately - it does not fall through to other condition pairs). This means I don't have to nest &lt;code&gt;if&lt;/code&gt; calls, which makes it easier to read (IMO).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;if-let&lt;/code&gt;. This is basically a conditional binding (think variable) assignment: if the binding value is not &lt;code&gt;nil&lt;/code&gt;, then assign the value that binding for the scope of the &lt;code&gt;if-let&lt;/code&gt;. It saves you from the all-too-common pattern of:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ruby&lt;/span&gt;
&lt;span class="n"&gt;my_var&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doThingPossibly&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;my_var&lt;/span&gt;
  &lt;span class="c1"&gt;# do other things&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# python
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;doExpensiveThing&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;repeatItForVariable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;doExpensiveThing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="c1"&gt;# do other things
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And again, my code is available in a &lt;a href="https://gist.github.com/ballpointcarrot/aa5aa68f616811381499519b74a6cca9" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt;. Until tomorrow!&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>adventofcode</category>
      <category>challenges</category>
    </item>
    <item>
      <title>Advent of Code 2018 - Day 2</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Sun, 02 Dec 2018 04:55:32 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/advent-of-code-2018---day-2-1a3p</link>
      <guid>https://dev.to/ballpointcarrot/advent-of-code-2018---day-2-1a3p</guid>
      <description>&lt;p&gt;Welcome back! Today, we're continuing the &lt;a href="https://ladventofcode.com" rel="noopener noreferrer"&gt;Advent of Code&lt;/a&gt; challenges. I found these challenges through the awesome people I've found at the &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt; community, which has been embracing these challenges, providing discussion boards, and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 2, Problem the First
&lt;/h3&gt;

&lt;p&gt;The long-and-short of the second day's problem is thus:&lt;/p&gt;

&lt;p&gt;You are given a list of box IDs, which are series of letters. In order to verify the contents of the boxes in total, you count the number of IDs with "exactly two of any letter", and separately count "exactly three of any letter" to make a checksum of the values. Using the example from the problem statement:&lt;/p&gt;

&lt;p&gt;For example, if you see the following box IDs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;abcdef&lt;/code&gt; contains no letters that appear exactly two or three times.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bababc&lt;/code&gt; contains two a and three b, so it counts for both.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;abbcde&lt;/code&gt; contains two b, but no letter appears exactly three times.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;abcccd&lt;/code&gt; contains three c, but no letter appears exactly two times.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aabcdd&lt;/code&gt; contains two a and two d, but it only counts once.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;abcdee&lt;/code&gt; contains two e.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ababab&lt;/code&gt; contains three a and three b, but it only counts once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As a result, we have four IDs which contain exactly two repeated letters (2, 3, 5, and 6), and three IDs which contain three repeats (2, 4, 7). If you multiply these values together &lt;code&gt;4 x 3 = 12&lt;/code&gt;, so 12 is your checksum value. You are now asked to calculate the checksum value of the test input.&lt;/p&gt;

&lt;p&gt;Not to be bitten by the trouble yesterday, I wanted to set up a full project (with the ability to test). This took a fair bit longer than I had intended, because I rabbit-holed into "how do I get this to provide test results automatically?" (where I spent about 20m), and "Why the hell isn't this test executing correctly?" (which took substantially longer).&lt;/p&gt;

&lt;p&gt;Once I finally had my environment up and running correctly, I went about putting some test cases down:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aoc.aoc2-test&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:require&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;aoc.aoc2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sut&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;clojure.test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:refer&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;deftest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="p"&gt;]]))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;deftest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aoc2-part1&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;testing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"the example statement"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"abcdef"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"bababc"&lt;/span&gt;&lt;span class="w"&gt;
                 &lt;/span&gt;&lt;span class="s"&gt;"abbcde"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"abcccd"&lt;/span&gt;&lt;span class="w"&gt;
                 &lt;/span&gt;&lt;span class="s"&gt;"aabcdd"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"abcdee"&lt;/span&gt;&lt;span class="w"&gt;
                 &lt;/span&gt;&lt;span class="s"&gt;"ababab"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sut/checksum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;testing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"a simple second example"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"abab"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"abaa"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"aab"&lt;/span&gt;&lt;span class="w"&gt;
                 &lt;/span&gt;&lt;span class="s"&gt;"aac"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"aaa"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sut/checksum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses the example scenario given in the problem, as well as a small example I cooked up myself. Armed with tests that executed on file save, I was ready to build out the solution.&lt;/p&gt;

&lt;p&gt;Once again, this problem lends well to the &lt;a href="https://clojuredocs.org/clojure.core/frequencies" rel="noopener noreferrer"&gt;&lt;code&gt;frequencies&lt;/code&gt;&lt;/a&gt; function provided by Clojure - it will automatically group the values within the string by how frequent they show up. Since we only care about twos and threes, however, we need to search those results for those values. The &lt;a href="https://clojuredocs.org/clojure.core/reduce" rel="noopener noreferrer"&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/a&gt; function (of "map/reduce" fame) is where we want to be - it gives us an easy way to take a list of things and make a scalar value out of it. In our case, we want to reduce each map to its existence of twos and threes; ideally, {:a 3 :b 1 :c 2} would result in {:threes 1 :twos 1}.&lt;/p&gt;

&lt;p&gt;Building out a complicated &lt;code&gt;reduce&lt;/code&gt; function generally is painful; because the inner function to a reduce is exactly that (a function), I defined it outside the logic. Because clojure values are generally immutable, I needed an easy way to maintain the state during the loop - &lt;code&gt;transient&lt;/code&gt; helped out here, because I treat the map as temporarily mutable, but only within the bounds of the function and the lifetime of the transient binding.&lt;/p&gt;

&lt;p&gt;Here's what I ended up with for the part 1 solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;aoc.aoc2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reduce-twos-threes&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"check the given frequency map n for twos or threes matches, and update
   the memo map to indicate if the string has a match. Used for a reducer."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;memo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;transient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;assoc!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:twos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:twos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;some&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;assoc!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;persistent!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t-memo&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;checksum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sum-maps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;frequencies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;twos-threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reduce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reduce-twos-threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="no"&gt;:twos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;:threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sum-maps&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:twos&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;twos-threes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;:threes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;twos-threes&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the &lt;code&gt;checksum&lt;/code&gt; function read really straightforward: find the frequencies of each input value, find the numbers of twos and threes (stored in a map), then finally multiply the twos and threes values together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 2 Problem 2 (Electric Boogaloo)
&lt;/h3&gt;

&lt;p&gt;Distilling the problem statement again:&lt;/p&gt;

&lt;p&gt;Given your list of IDs, the particular IDs you're searching for differ by just one character; for example, "text" and "tent" fit this requirement, because you only need to replace the "x" and "n" characters. The example given in the problem is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;abcde&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fghij&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;klmno&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pqrst&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fguij&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;axcye&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wvxyz&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;where &lt;code&gt;fghij&lt;/code&gt; and &lt;code&gt;fguij&lt;/code&gt; are "adjacent" boxes.&lt;br&gt;
Any problem where you're comparing closeness of matching strings &lt;strong&gt;screams&lt;/strong&gt; &lt;a href="https://people.cs.pitt.edu/~kirk/cs1501/Pruhs/Spring2006/assignments/editdistance/Levenshtein%20Distance.htm" rel="noopener noreferrer"&gt;Levenshtein Distance&lt;/a&gt;. The Levenshtein distance of two strings is a measure of the minimum number of changes required to turn one string into another - this is generally counting insertion, deletion, and substitution, but our needs solely require substitution (better known as Hamming Distance - two separate mathematicians studying the same area of string differences. This is done by comparing values in each string, and adding 1 to each difference you encounter - a pretty simple comparison function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hamming&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s"&gt;"Compute the Hamming Distance between two equal length
   strings."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;str1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;IllegalArgumentException.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"Strings must be equal size."&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str1&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;str2&lt;/span&gt;&lt;span class="w"&gt;
         &lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
             &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uses Clojure's tail-recursive optimizing functions &lt;code&gt;loop&lt;/code&gt; and &lt;code&gt;recur&lt;/code&gt; to compare the strings one-by-one, and calculate their Hamming distance (we've got a check in there to make sure they're the same length, and throw an error if not).&lt;/p&gt;

&lt;p&gt;Once that was complete, I built out a way to sift through the list of boxes to find just the ones with a Hamming distance of 1. This returns a two-item sequence, one for each swap of matching (there's probably an optimization there to not go through the entire list):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;find-christmas-boxes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;keep&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;identity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base-str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target-box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hamming&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;base-str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
                          &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target-box&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;base-str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target-box&lt;/span&gt;&lt;span class="p"&gt;)])))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a couple of cool things to point out here. First, the base &lt;code&gt;map&lt;/code&gt; function will return a lot of &lt;code&gt;nil&lt;/code&gt; (Clojure's &lt;code&gt;null&lt;/code&gt; value). In order to get rid of those, we use the &lt;code&gt;identity&lt;/code&gt; function (which basically says "return true if truthy"; it's effectively a cleaner &lt;code&gt;(not (nil? thing))&lt;/code&gt;). Another thing to point out for non-Clojurists is that shorthand function declaration used in the &lt;code&gt;filter&lt;/code&gt; call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; These two are equivalent:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; 

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the AoC puzzle asks for the common characters between the two strings. This is close to the Hamming Distance function above, but we just need to drop a character if it doesn't match. This got reduced to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remove-uncommon-letter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;keep-indexed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;;; To execute everything:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;; (apply remove-uncommon-letter (first find-christmas-boxes input))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="c1"&gt;;; where input is the raw input string from the project.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;apply&lt;/code&gt; is the cool bit here - using &lt;code&gt;apply&lt;/code&gt; allows you to use vector (read: array) entries as arguments to a function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;numbers-to-add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;apply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;numbers-to-add&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And hey - no borrowing from anyone else today, and right before day 3 releases. I'm saving that for tomorrow, though. :D The Github Gist for today's problems is &lt;a href="https://gist.github.com/ballpointcarrot/8bec8ebd2bfe8b3a0739eba824eeed1b" rel="noopener noreferrer"&gt;right here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>challenges</category>
      <category>adventofcode</category>
    </item>
    <item>
      <title>Advent of Code 2018 - Day 1</title>
      <dc:creator>Christopher Kruse</dc:creator>
      <pubDate>Sat, 01 Dec 2018 00:00:00 +0000</pubDate>
      <link>https://dev.to/ballpointcarrot/advent-of-code-2018---day-1-2fko</link>
      <guid>https://dev.to/ballpointcarrot/advent-of-code-2018---day-1-2fko</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted at &lt;a href="https://www.ballpointcarrot.net/posts/advent-of-code-2018-1/" rel="noopener noreferrer"&gt;https://www.ballpointcarrot.net/posts/advent-of-code-2018-1/&lt;/a&gt; - Also, obligatory "first post" points for being my first dev.to post :D&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Spurred on by&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a lack of posting in this space,&lt;/li&gt;
&lt;li&gt; the chance to show off the new backend/theme to my blog (I did work
on this while nobody was looking, and started building an RSS feeed!), and&lt;/li&gt;
&lt;li&gt; after finding &lt;a href="https://twitter.com/ASpittel/status/1068869815333527557?s=20" rel="noopener noreferrer"&gt;this Tweet&lt;/a&gt; by &lt;a href="https://www.alispit.tel/#/" rel="noopener noreferrer"&gt;Ali Spittel&lt;/a&gt;,&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I decided that doing this &lt;a href="https://adventofcode.com/" rel="noopener noreferrer"&gt;"Advent of Code"&lt;/a&gt; was something to do. First, it gives me a nice thing to practice on. Second, it gives me a reason to make some frequent posts on here (which, given the year+ lack of content, may not be a bad idea). Finally, it helps me build out some public code, which I've been bad at doing - even if they're solutions to set problems. I'll be using GitHub gists for posting my solutions, and embedding them here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem the First
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://adventofcode.com/2018/day/1" rel="noopener noreferrer"&gt;first problem&lt;/a&gt; is summarized as follows: you're an Elf travelling back in time to fix anomalies in history, in order to "save Christmas". However, in order to get the time travel device working correctly, it first needs calibrated.&lt;/p&gt;

&lt;p&gt;Given a series of "frequency changes", like &lt;code&gt;+1 -2 +3 -1&lt;/code&gt;, the following changes would occur:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current frequency  &lt;code&gt;0&lt;/code&gt;, change of &lt;code&gt;+1&lt;/code&gt;; resulting frequency  &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Current frequency  &lt;code&gt;1&lt;/code&gt;, change of &lt;code&gt;-2&lt;/code&gt;; resulting frequency &lt;code&gt;-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Current frequency &lt;code&gt;-1&lt;/code&gt;, change of &lt;code&gt;+3&lt;/code&gt;; resulting frequency  &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Current frequency  &lt;code&gt;2&lt;/code&gt;, change of &lt;code&gt;+1&lt;/code&gt;; resulting frequency  &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This provies a resulting frequency of &lt;code&gt;3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With those rules in place, the Advent of Code site has you log in (thanks, Login with Github) and get a link for sample input. The input file was larger than I expected, but the rules simple enough to come up with this small Clojure snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calibrate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;input-file&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;raw-input&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;slurp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input-file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Integer.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;%&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;clojure.string/split-lines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;raw-input&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reduce&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above reads the file into a string (using &lt;code&gt;slurp&lt;/code&gt;), then converts each individual number (separated with a newline character) into a Java Integer. Finally, everything is summed up via &lt;code&gt;reduce&lt;/code&gt; to get the full set of adjustments for a final frequency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem the Second
&lt;/h3&gt;

&lt;p&gt;Within your input, you now need to keep track of the active value, and look for the first time you encounter the same value twice. Additionally, this means that your list can loop; for example, take the input &lt;code&gt;+3, +3, +4, -2, -4&lt;/code&gt;. As you run through this the first time, you generate intermediate values of &lt;code&gt;3, 6, 10, 8 4&lt;/code&gt;, and there are no matches within that set. So, you take the last &lt;code&gt;4&lt;/code&gt; offset, and start the original list over again, returning &lt;code&gt;7, 10, ...&lt;/code&gt;. When you've reached &lt;code&gt;10&lt;/code&gt; again, you have found your "twice match", and return that value. Now, using the same test input, we get to find the first value we hit twice.&lt;/p&gt;

&lt;p&gt;Clojure gets to harness the power of lazy infinite sequences here. Using the clojure &lt;a href="https://clojuredocs.org/clojure.core/cycle" rel="noopener noreferrer"&gt;&lt;code&gt;cycle&lt;/code&gt;&lt;/a&gt; function, the list of frequencies gets to be repeated indefinitely. Obviously, we can't eager load a list of infinite values - there's not&lt;br&gt;
enough memory space to do that; what we &lt;em&gt;can&lt;/em&gt; do, however, is let that list populate as needed, only providing the next&lt;br&gt;
number until we need it.&lt;/p&gt;

&lt;p&gt;I built a function that generates a list of the intermediate points, and loops to find a solution::&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;frequency-adjustments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;reductions&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cycle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calibrate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;take&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;frequency-adjustments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;step-counts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;frequencies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="n"&gt;repeats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;step-counts&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;if-not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;repeats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;keys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;repeats&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;inc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I was happy with how things looked. I went to a REPL and tested the logic with some of the samples, which seemed to get&lt;br&gt;
the answer I was looking for. &lt;code&gt;frequency-adjustments&lt;/code&gt; was nice, actually, because you could see effectively a new list&lt;br&gt;
of how each step processes, which was great for visual analysis. I then fired it off with the test data.&lt;/p&gt;

&lt;p&gt;And waited. Quite a while in fact.&lt;/p&gt;

&lt;p&gt;Turns out that, when you have a high enough input, trying to build the list over and over again is somewhat taxing on&lt;br&gt;
the system doing that calculation. Obviously, this wasn't the solution I was looking for. At this point, I did a little&lt;br&gt;
bit of cheating (hey, it's the Internet, and I'm not proud) and checked &lt;a href="https://www.reddit.com/r/adventofcode/comments/a20646/2018_day_1_solutions/" rel="noopener noreferrer"&gt;the reddit post&lt;/a&gt; where people were posting solutions, and came across a separate Clojure&lt;br&gt;
solution by &lt;a href="https://www.reddit.com/r/adventofcode/comments/a20646/2018_day_1_solutions/eau9gjm/" rel="noopener noreferrer"&gt;zqvt&lt;/a&gt; (slightly&lt;br&gt;
modified to fit my input parameters below):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight clojure"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;defn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;calibrate2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cycle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;contains?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;recur&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;rest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;conj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;&lt;span class="c1"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a set of values we've come across, as well as keeps a running total of where we're at while we're&lt;br&gt;
generating. The key here that I didn't even think about (let alone thought possible) was the use of &lt;code&gt;rest&lt;/code&gt; to generate&lt;br&gt;
further sequences while not including the items processed. That was clever, and this solution very quickly provided a&lt;br&gt;
response.&lt;/p&gt;

&lt;p&gt;Lessons learned:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;My initial thought was to build a set of values that I'd seen going through the list calculated with
&lt;code&gt;reductions&lt;/code&gt;, but I really wanted to try something that I could do without maintaining state outside of the loop. That
led me down the path of regenerating the list each time, which made it impossible to run effectively. I probably
should've gone with that easier thought process, as it would've worked faster (and I would've spent less time on the
solution).&lt;/li&gt;
&lt;li&gt;Good to be posting stuff again, and practice always helps.&lt;/li&gt;
&lt;li&gt;Honesty - it hurt to come clean about looking for solutions, but sometimes you have to suck it up. Also, I felt really
dumb after seeing the painful performance of my implementation vs. the one that I found. But I wanted to highlight a
successful implementation, both to show that there are good ways to do it, and to give myself something to look
forward to improving upon. I'm hoping to not need the crutch next time.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>clojure</category>
      <category>challenges</category>
      <category>adventofcode</category>
    </item>
  </channel>
</rss>
