<?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: Svetlana Isakova</title>
    <description>The latest articles on DEV Community by Svetlana Isakova (@sveta_isakova).</description>
    <link>https://dev.to/sveta_isakova</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%2F667606%2Fefcef061-a09d-4307-80cf-dbff5862fb39.jpg</url>
      <title>DEV Community: Svetlana Isakova</title>
      <link>https://dev.to/sveta_isakova</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sveta_isakova"/>
    <language>en</language>
    <item>
      <title>Idiomatic Kotlin: Solving Advent of Code Puzzles, Binary Boarding</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Fri, 10 Sep 2021 08:50:58 +0000</pubDate>
      <link>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-binary-boarding-513e</link>
      <guid>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-binary-boarding-513e</guid>
      <description>&lt;p&gt;Let’s continue our journey of understanding what “idiomatic Kotlin” means and solve one more puzzle from the Advent of Code challenge. The puzzles are independent of each other, so you don’t need to check any of the previous ones we’ve already covered. Simply read through the following solution or watch the video. We hope you learn something new!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XEFna3xyxeY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 5. Binary Boarding
&lt;/h2&gt;

&lt;p&gt;We’re boarding the plane! We need to analyze the list of boarding passes and find the seat with the highest seat ID. Then we need to find the one seat missing from the list, which is ours. You can find the full task description at &lt;a href="https://adventofcode.com/2020/day/5"&gt;https://adventofcode.com/2020/day/5&lt;/a&gt;.*&lt;/p&gt;

&lt;p&gt;A seat is specified as, for example, &lt;code&gt;FBFBBFFRLR&lt;/code&gt;, where &lt;code&gt;F&lt;/code&gt; means "front", &lt;code&gt;B&lt;/code&gt; means "back", &lt;code&gt;L&lt;/code&gt; means "left", and &lt;code&gt;R&lt;/code&gt; means "right". The first 7 characters are either &lt;code&gt;F&lt;/code&gt; or &lt;code&gt;B&lt;/code&gt; and they specify exactly one of the 128 rows on the plane (numbered 0 through 127). The last three characters are either &lt;code&gt;L&lt;/code&gt; or &lt;code&gt;R&lt;/code&gt;; these specify exactly one of the 8 columns of seats on the plane (numbered 0 through 7). A more detailed encoding description is given on the &lt;a href="https://adventofcode.com/2020/day/5"&gt;puzzle page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Every seat has a unique seat ID, calculated by multiplying the row by 8 and then adding the column.&lt;/p&gt;

&lt;p&gt;The puzzle input is the list of boarding passes. The first task is to find the boarding pass in this list with the highest seat ID.&lt;/p&gt;

&lt;p&gt;The second task is to find the missing boarding pass in the list. The flight is completely full, there’s only one missing boarding pass, and that’s our seat. However, some of the seats at the very front and back of the plane don't exist on this aircraft, so they are missing from the list as well.&lt;/p&gt;

&lt;p&gt;As usual, we suggest that you try to solve the task on your own before reading the solution. Here’s how you can &lt;a href="https://blog.jetbrains.com/kotlin/2021/07/advent-of-code-in-idiomatic-kotlin/#how-to-solve"&gt;set up Kotlin&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Let’s first discuss the encoding of the boarding passes. Note how it is a nicely “hidden” binary representation of natural numbers! Let’s take a closer look.&lt;/p&gt;

&lt;h3&gt;
  
  
  Boarding pass: binary representation
&lt;/h3&gt;

&lt;p&gt;First, let’s look at the rows. There are 128 rows on the plane, which are encoded with 7 “bits”. These bits are called F and B in the puzzle, but they carry the same meaning as 0 and 1 do in the binary representation. To extend the analogy, the way to identify the exact row based on the boarding pass is reminiscent of the algorithm used to convert a binary representation of the number to a decimal.&lt;/p&gt;

&lt;p&gt;Let’s consider the provided example – the first seven characters of &lt;code&gt;FBFBBFFRLR&lt;/code&gt; that decode the “row”. &lt;code&gt;F&lt;/code&gt; means to take the “front”, or the lower half, while &lt;code&gt;B&lt;/code&gt; is to take the “back”, or the upper half on each iteration. Taking the lower half is equivalent to not adding the corresponding power of two to the result (or multiplying it by zero), while taking the upper half is equivalent to adding it to the result (or multiplying it by one).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;F = 0; B = 1
FB notation  F  B  F  B  B  F  F
Bit          0  1  0  1  1  0  0
Index        6  5  4  3  2  1  0
2^Index      64 32 16 8  4  2  1

Decimal:
0 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0 =
32 + 8 + 4 = 
44
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this conversion is clear to you, you can skip the remaining explanations in this section and go directly to the Kotlin implementation. If not, please read the description of the conversion strategy on the task page and the following explanations carefully.&lt;/p&gt;

&lt;p&gt;We start by considering the whole range, rows &lt;code&gt;0&lt;/code&gt; through &lt;code&gt;127&lt;/code&gt;. The maximum value that can be decoded via 7 bits is &lt;code&gt;1111111&lt;/code&gt;, or &lt;code&gt;127&lt;/code&gt; if converted to the decimal form: &lt;code&gt;2&lt;sup&gt;7&lt;/sup&gt; - 1 = 2&lt;sup&gt;6&lt;/sup&gt; + 2&lt;sup&gt;5&lt;/sup&gt; + 2&lt;sup&gt;4&lt;/sup&gt; + 2&lt;sup&gt;3&lt;/sup&gt; + 2&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;1&lt;/sup&gt; + 2&lt;sup&gt;0&lt;/sup&gt; = 127&lt;/code&gt;. Each bit is responsible for its part of the range: if it’s &lt;code&gt;1&lt;/code&gt;, we add the corresponding power of two to the result; if it’s &lt;code&gt;0&lt;/code&gt;, we skip it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;strong&gt;Bit&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Bit index&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Description of the task&lt;/strong&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;strong&gt;Reworded in ‘binary representation’ terms&lt;/strong&gt;
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;6&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; means to take the lower half, keeping rows 0 through 63.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;6&lt;/sup&gt;=64&lt;/code&gt; to the result.
&lt;p&gt;
That keeps the result in the &lt;code&gt;0..(127-64)&lt;/code&gt; range, or &lt;code&gt;0..63&lt;/code&gt;.
   &lt;/p&gt;
&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;5&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; means to take the upper half, keeping rows 32 through 63.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;5&lt;/sup&gt;=32&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;32..63&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;4&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; means to take the lower half, keeping rows 32 through 47.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;4&lt;/sup&gt;=16&lt;/code&gt; to the result. That makes the possible range &lt;code&gt;32..(63-16)&lt;/code&gt;, or &lt;code&gt;32..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;3&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; means to take the upper half, keeping rows 40 through 47.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;3&lt;/sup&gt;=8&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;(32+8)..47&lt;/code&gt;, or &lt;code&gt;40..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;B = 1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;2&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;B&lt;/code&gt; keeps rows 44 through 47.
   &lt;/td&gt;
   &lt;td&gt;We add &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;=4&lt;/code&gt; to the result. That keeps the result in the range &lt;code&gt;(40+4)..47&lt;/code&gt;, or &lt;code&gt;44..47&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;1&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;F&lt;/code&gt; keeps rows 44 through 45.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;=2&lt;/code&gt;. That makes the possible range &lt;code&gt;44..(47-2)&lt;/code&gt;, or &lt;code&gt;44..45&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;
&lt;code&gt;F = 0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;
&lt;code&gt;0&lt;/code&gt;
   &lt;/td&gt;
   &lt;td&gt;The final &lt;code&gt;F&lt;/code&gt; keeps the lower of the two, row 44.
   &lt;/td&gt;
   &lt;td&gt;We don’t add &lt;code&gt;2&lt;sup&gt;0&lt;/sup&gt;=1&lt;/code&gt;. That makes the result &lt;code&gt;44..(45-1)&lt;/code&gt;, or simply &lt;code&gt;44&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Decoding column
&lt;/h4&gt;

&lt;p&gt;Decoding the column follows the same logic, but now &lt;code&gt;R&lt;/code&gt; takes the upper half and corresponds to bit &lt;code&gt;1&lt;/code&gt;, while &lt;code&gt;L&lt;/code&gt; takes the lower half and corresponds to bit &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's now consider the last 3 characters of &lt;code&gt;FBFBBFFRLR&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;L = 0; R = 1
RL notation  R  L  R
Bit          1  0  1
Index        2  1  0
2^Index      4  2  1

Decimal:
1 * 2^2 + 0 * 2^1 + 1 * 2^0 =
4 + 1 = 
5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The whole range represents columns 0 through 7. It’s the maximum value that can be encoded via three bits: &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt; + 2&lt;sup&gt;1&lt;/sup&gt; + 2&lt;sup&gt;0&lt;/sup&gt; = 7&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;R&lt;/code&gt; means to take the upper half, keeping columns 4 through 7. In other words, take &lt;code&gt;2&lt;sup&gt;2&lt;/sup&gt;=4&lt;/code&gt; with the multiplier &lt;code&gt;"1"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;L&lt;/code&gt; means to take the lower half, keeping columns 4 through 5. In other words, take &lt;code&gt;2&lt;sup&gt;1&lt;/sup&gt;=2&lt;/code&gt; with the multiplier &lt;code&gt;"0"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The final &lt;code&gt;R&lt;/code&gt; keeps the upper of the two, column 5. In other words, take &lt;code&gt;2&lt;sup&gt;0&lt;/sup&gt;=1&lt;/code&gt; with the multiplier &lt;code&gt;"1",&lt;/code&gt; making the result &lt;code&gt;4+1=5&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last part is converting the row and the column numbers to the seat ID by using the formula: multiply the row by 8 and then add the column. For the sample boarding pass, the row is &lt;code&gt;44&lt;/code&gt; and the column is &lt;code&gt;5&lt;/code&gt;, so this calculation gives the seat ID as &lt;code&gt;44 * 8 + 5 = 357&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Combining row and column
&lt;/h4&gt;

&lt;p&gt;But if we look closer at this formula, we’ll notice that we don’t need to find the row and column separately! We can simply add all the row bits with indexes increased by three to the result (note that &lt;code&gt;8 = 2&lt;sup&gt;3&lt;/sup&gt;&lt;/code&gt;). This bit operation is formally called “left-shift”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FBRL notation  F  B  F  B  B  F  F  R  L  R
Bit            0  1  0  1  1  0  0  1  0  1
Index          9  8  7  6  5  4  3  2  1  0

Decimal:
[0 * 2^9 + 1 * 2^8 + 0 * 2^7 + 1 * 2^6 + 1 * 2^5 + 0 * 2^4 + 0 * 2^3] + [1 * 2^2 + 0 * 2^1 + 1 * 2^0] =
2^3 * [0 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 0 * 2^0] + [1 * 2^2 + 0 * 2^1 + 1 * 2^0] =
8 * 44 + 5 = 
357
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a little bit of math, a Kotlin solution can almost fit on a single line! Let’s see how.&lt;/p&gt;

&lt;h3&gt;
  
  
  Converting boarding pass to seat ID
&lt;/h3&gt;

&lt;p&gt;We only need to replace &lt;code&gt;B/F&lt;/code&gt; and &lt;code&gt;R/L&lt;/code&gt; with &lt;code&gt;1/0&lt;/code&gt; notation, and then convert the resulting binary representation to an integer. Each of these operations is one function call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'B'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'F'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'R'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'L'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;radix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0101100101"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;radix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 357&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"FBFBBFFRLR"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;       &lt;span class="c1"&gt;// 357&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;String.replace(oldChar: Char, newChar: Char)&lt;/code&gt; function replaces all occurrences of the old character with the new character. There are two more similar functions. If you need to replace each substring with a new string, pass the strings as arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oldValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to replace each substring that matches the given regular expression, use another function taking &lt;code&gt;Regex&lt;/code&gt; as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;String.toInt(radix: Int)&lt;/code&gt; function parses the string receiver as an integer in the specified radix. In our case, we specify that the radix is two, so it parses the binary representation of the number.&lt;/p&gt;

&lt;p&gt;There’s no need to reimplement the conversion algorithm from scratch when you can use the library functions – unless you specifically want to practice that, of course, but that’s not the goal of this puzzle.&lt;/p&gt;

&lt;p&gt;We’ve got the seat ID from the boarding pass now and we can continue with the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the maximum seat ID
&lt;/h3&gt;

&lt;p&gt;As usual, we need to read the input first. After implementing the conversion function, it’s quite straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day05/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seatIDs list is a list of integers, and the only thing left is finding the maximum in this list. There’s no need to implement it from scratch; we simply use the &lt;code&gt;maxOrNull()&lt;/code&gt; library function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;maxID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Max seat ID: $maxID"&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;We’ve found the seat with the maximum seat ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finding the vacant seat ID
&lt;/h3&gt;

&lt;p&gt;The second part of the task is finding the vacant seat that is missing from the list. There’s guaranteed to be only one. However, we remember that some of the seats at the very front and back of the plane don't exist on this aircraft, so they are missing as well. And so, we can’t simply iterate through the range from &lt;code&gt;1&lt;/code&gt; to &lt;code&gt;maxID&lt;/code&gt; and check for missing seats, as we would also “find” those at the very front and back.&lt;/p&gt;

&lt;p&gt;Note, however, that our required vacant seat is not on the edge. This means it’s the only missing seat whose neighbors are both present in the list. So, we can check for this condition: that the seat itself must be missing (in other words, not occupied), but both its neighbors must be occupied.&lt;/p&gt;

&lt;p&gt;First, to make our code more expressive, let’s add a function that checks whether a given seat is occupied. It checks that the given seat index belongs to the list of seat IDs provided as the input for our challenge. To make this check quickly, we convert the given list to a set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;occupiedSeatsSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seat&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;occupiedSeatsSet&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kotlin allows us to create local functions, that is, functions inside other functions. That’s really convenient for the kind of short and simple function we need to write here: the &lt;code&gt;isOccupied()&lt;/code&gt; function will capture the outer variable, &lt;code&gt;occupiedSeatsSet&lt;/code&gt;, and we don’t need to pass it explicitly as a parameter.&lt;/p&gt;

&lt;p&gt;Now the only thing left to do is find the desired seat index, when the seat is not occupied but the neighboring seats (with indices &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;+1&lt;/code&gt;) are both occupied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mySeat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;maxID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My seat ID: $mySeat"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! &lt;/p&gt;

&lt;p&gt;The whole main function that solves both parts of the task looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;seatIDs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day05/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toSeatID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;maxID&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;maxOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Max seat ID: $maxID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;occupiedSeatsSet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seatIDs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seat&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;occupiedSeatsSet&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mySeat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;maxID&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;isOccupied&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My seat ID: $mySeat"&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;Note that in order to use &lt;code&gt;maxID&lt;/code&gt; as the upper bound of the range, we call &lt;code&gt;!!&lt;/code&gt;, since the &lt;code&gt;maxOrNull()&lt;/code&gt; function returns a nullable value. Specifically, it returns &lt;code&gt;null&lt;/code&gt; if the list is empty. &lt;/p&gt;

&lt;p&gt;Following the Kotlin philosophy, you might expect to find the &lt;code&gt;max()&lt;/code&gt; function, throwing an exception if the list is empty. And you’d be right! However, in Kotlin 1.5 the &lt;code&gt;max()&lt;/code&gt; function is deprecated, and in future versions it will be totally removed and replaced with a function throwing an exception. The &lt;code&gt;max()&lt;/code&gt; function was present in the standard library starting with Kotlin 1.0 but returned a nullable value, and now the Kotlin team is slowly fixing this small discrepancy. Until the &lt;code&gt;max()&lt;/code&gt; function reappears in the standard library, it’s fine to write &lt;code&gt;maxOrNull()!!&lt;/code&gt; to explicitly highlight that you need the non-null value as a result, and you prefer an exception if the list is empty. Alternatively, to avoid using &lt;code&gt;!!&lt;/code&gt;, you can use &lt;code&gt;maxOf { it }&lt;/code&gt; for now.&lt;/p&gt;

&lt;p&gt;That’s it! We outlined the strategy for solving the puzzle, recognized the binary encoding for the numbers, discussed how it works, and presented the solution in Kotlin, which is quite simple thanks to the Kotlin standard library functions.&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;). &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Idiomatic Kotlin: Solving Advent of Code Puzzles, Day 2</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Wed, 21 Jul 2021 16:25:30 +0000</pubDate>
      <link>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-day-2-pe2</link>
      <guid>https://dev.to/kotlin/idiomatic-kotlin-solving-advent-of-code-puzzles-day-2-pe2</guid>
      <description>&lt;h2&gt;
  
  
  Idiomatic Kotlin: Solving Advent of Code Puzzles, Day 2
&lt;/h2&gt;

&lt;p&gt;Let’s &lt;a href="https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62"&gt;continue&lt;/a&gt; learning how to write idiomatic Kotlin code by solving the &lt;a href="https://adventofcode.com/"&gt;AdventOfCode&lt;/a&gt; tasks! Today, we’re discussing the solution for the day 2 task.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/MyvJ7G6aErQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 2. Password philosophy
&lt;/h2&gt;

&lt;p&gt;We need to confirm that passwords meet the corporate policy. Find the full task description at &lt;a href="https://adventofcode.com/2020/day/2"&gt;https://adventofcode.com/2020/day/2&lt;/a&gt;*.&lt;/p&gt;

&lt;p&gt;First, we need to read the input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1-3 a: abcde
1-3 b: cdefg
2-9 c: ccccccccc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each line contains the password policy and the password. Our task is to check that the password is valid and conforms to the given policy. The policies are different in the first and the second parts of the task.&lt;/p&gt;

&lt;p&gt;In the first part, the password policy indicates the lowest and highest number of times a given letter must appear for the password to be valid. For example, &lt;code&gt;1-3 a&lt;/code&gt; means that the password must contain &lt;code&gt;a&lt;/code&gt; at least once and at most 3 times. In the example, two passwords, the first and the third ones, are valid. The first contains one &lt;code&gt;a&lt;/code&gt;, and the third contains nine &lt;code&gt;c&lt;/code&gt;s, both within the limits of their respective policies. The second password, &lt;code&gt;cdefg&lt;/code&gt;, is invalid, as it contains no instances of &lt;code&gt;b&lt;/code&gt; but needs at least 1.&lt;/p&gt;

&lt;p&gt;In the second part, the policy describes two positions in the password, where 1 means the first character, 2 means the second character, and so on (indexing starts at 1, not 0). Exactly one of these positions must contain the given letter. Other occurrences of the letter are irrelevant. Given the same example list from above:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;1-3 a: abcde&lt;/code&gt; is valid: position 1 contains &lt;code&gt;a&lt;/code&gt; and position 3 does not.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1-3 b: cdefg&lt;/code&gt; is invalid: neither position 1 nor position 3 contains &lt;code&gt;b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2-9 c: ccccccccc&lt;/code&gt; is invalid: both positions 2 and position 9 contain &lt;code&gt;c&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We should count the number of passwords from the given input that are valid according to the interpretations of the policies.&lt;/p&gt;

&lt;p&gt;As usual, if you haven’t done it, please solve the task yourself first. Here’s how you can &lt;a href="https://blog.jetbrains.com/kotlin/2021/07/advent-of-code-in-idiomatic-kotlin/#how-to-solve"&gt;set up Kotlin&lt;/a&gt; for this purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;First, we should read and parse the input. Let’s create a &lt;code&gt;data&lt;/code&gt; class for storing a given password together with its policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IntRange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Char&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each policy specifies an integer range and a letter that we store in the &lt;code&gt;IntRange&lt;/code&gt; and &lt;code&gt;Char&lt;/code&gt; types, accordingly. The modifier &lt;code&gt;data&lt;/code&gt; instructs the compiler to generate some useful methods for this class, including the constructor, &lt;code&gt;equals&lt;/code&gt;, &lt;code&gt;hashCode&lt;/code&gt;, and &lt;code&gt;toString&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing input
&lt;/h3&gt;

&lt;p&gt;Let’s write a function that parses one input line into this class. Since it’s a function that creates an instance, let’s put it into a companion object in our data class. Then we can call it by the class name: &lt;code&gt;PasswordWithPolicy.parse()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;companion&lt;/span&gt; &lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
           &lt;span class="nc"&gt;TODO&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;}&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;While developing, you can put the &lt;code&gt;TODO()&lt;/code&gt; call that throws the &lt;code&gt;NotImplementedError&lt;/code&gt;exception. Because it returns the &lt;code&gt;Nothing&lt;/code&gt; type, which is a subtype of any other type, the compiler won’t complain. The function is supposed to return &lt;code&gt;PasswordWithPolicy&lt;/code&gt;, but throwing an exception inside is totally valid from the compiler’s point of view.&lt;/p&gt;

&lt;p&gt;There are two ways to parse the input: by using utility functions on Strings or by using regular expressions. Let’s discuss both of these ways.&lt;/p&gt;

&lt;p&gt;The Kotlin standard library contains many useful functions on &lt;code&gt;String&lt;/code&gt;s, including &lt;code&gt;substringAfter()&lt;/code&gt; and &lt;code&gt;substringBefore()&lt;/code&gt; which perfectly solve the task in our case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1-3 a: abcde&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;": "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;substringBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;single&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
   &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substringBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="py"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&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;We provide the parameter names explicitly while calling the &lt;code&gt;PasswordWithPolicy&lt;/code&gt; constructor. The input format convention requires that: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;password&lt;/code&gt; be the string that goes right after the colon&lt;/li&gt;
&lt;li&gt;the letter go between the whitespace and the colon, and&lt;/li&gt;
&lt;li&gt;the range go before the whitespace and consist of two numbers split by “-”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build a range, we first take the substring before the whitespace and split it with the “-” delimiter. We then use only the first two parts (&lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;), and build a range using the “..” operator converting both lines to &lt;code&gt;Int&lt;/code&gt;s. We use &lt;code&gt;let&lt;/code&gt; to convert the result of &lt;code&gt;substringBefore()&lt;/code&gt; to the desired range.&lt;/p&gt;

&lt;p&gt;In this code, we assume that all the input lines follow the rules. In a real-world scenario, we should check that the input is correct. &lt;code&gt;substringAfter()&lt;/code&gt; and similar functions take a second argument default to the string itself that should be returned in the event the given delimiter is not found. &lt;code&gt;toInt()&lt;/code&gt; and &lt;code&gt;single()&lt;/code&gt; have &lt;code&gt;toIntOrNull()&lt;/code&gt; and &lt;code&gt;singleOrNull()&lt;/code&gt; counterparts returning &lt;code&gt;null&lt;/code&gt; if the string can’t be converted to an integer number or consists of more than one character.&lt;/p&gt;

&lt;p&gt;Let’s now implement the same logic using regular expressions. Here is a regular expression describing the input format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(\d+)-(\d+) ([a-z]): ([a-z]+)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First are two numbers split by -, then a letter and a password.&lt;/p&gt;

&lt;p&gt;Our new &lt;code&gt;parse&lt;/code&gt; function matches the line against a regular expression and then builds &lt;code&gt;PasswordWithPolicy&lt;/code&gt; on the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;regex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Regex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"""(\d+)-(\d+) ([a-z]): ([a-z]+)"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;parseUsingRegex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchEntire&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;destructured&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
           &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toInt&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;single&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;In Kotlin, you use the &lt;code&gt;Regex&lt;/code&gt; class to define a regular expression. Note how we put it inside a triple-quoted string, so you don’t need to escape “&lt;code&gt;\&lt;/code&gt;”. For regular strings, escaping is done in the conventional way, with a backslash, so if you need a backslash character in the string, you repeat it: &lt;code&gt;"(\\d+)-(\\d+)".&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We assume that our input is correct, which is why we use “&lt;code&gt;!!&lt;/code&gt;” to throw an NPE if the input doesn’t correspond to the regular expression. An alternative is to use the safe access “&lt;code&gt;?.&lt;/code&gt;” here and return &lt;code&gt;null&lt;/code&gt; as the result.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;destructured&lt;/code&gt; property provides components for a destructuring assignment for groups defined in the regular expression. We use its result together with &lt;code&gt;let&lt;/code&gt; and destruct it inside the lambda expression, defining &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;letter&lt;/code&gt;, and &lt;code&gt;password&lt;/code&gt; as parameters. As before, we need to convert strings to &lt;code&gt;Int&lt;/code&gt;s and &lt;code&gt;Char&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password validation
&lt;/h3&gt;

&lt;p&gt;After we read the input, we need to validate whether the passwords comply with the given policy.&lt;/p&gt;

&lt;p&gt;In the first part, we need to ensure that the number of occurrences of a given letter is in a range. It’s one line in Kotlin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;IntRange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Char&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validatePartOne&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;
       &lt;span class="o"&gt;..&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;We count the occurrences of &lt;code&gt;letter&lt;/code&gt; in the &lt;code&gt;password&lt;/code&gt; string, and check that the result is in &lt;code&gt;range&lt;/code&gt;. &lt;code&gt;in&lt;/code&gt; checks that the given element belongs to a range. For numbers and other comparable elements, &lt;code&gt;x in range&lt;/code&gt; is the same as writing explicitly &lt;code&gt;range.first &amp;amp;lt;= x &amp;amp;&amp;amp; x &amp;amp;lt;= range.last&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second part isn’t difficult. We need to check that exactly one of the positions (stored in the range) contains the given letter. We use the boolean &lt;code&gt;xor&lt;/code&gt; operator for that, which returns &lt;code&gt;true&lt;/code&gt; if the operands are different. That’s exactly what we need here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;validatePartTwo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;xor&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to subtract 1 from &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;last&lt;/code&gt; because they imply indexing from one, but string indexation starts from zero.&lt;/p&gt;

&lt;p&gt;Added all together, this gives us our &lt;code&gt;main&lt;/code&gt; function that finds the result for both parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;passwords&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day2/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PasswordWithPolicy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validatePartOne&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
   &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validatePartTwo&lt;/span&gt;&lt;span class="p"&gt;()&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;Note how we pass a member reference &lt;code&gt;PasswordWithPolicy::parse&lt;/code&gt; to the &lt;code&gt;map&lt;/code&gt; function to convert the strings to passwords.&lt;/p&gt;

&lt;p&gt;That’s it! We discussed how to solve this problem, and along the way, looked at string utility functions, regular expressions, operations on collections, and how &lt;code&gt;let&lt;/code&gt; helps transform the expression nicely to the form you need.&lt;/p&gt;

&lt;p&gt;Please let us know if you find this format useful and would like us to provide solutions for more difficult tasks!&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;). &lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Solving Advent of Code Puzzles in Idiomatic Kotlin</title>
      <dc:creator>Svetlana Isakova</dc:creator>
      <pubDate>Thu, 15 Jul 2021 12:41:37 +0000</pubDate>
      <link>https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62</link>
      <guid>https://dev.to/kotlin/solving-advent-of-code-puzzles-in-idiomatic-kotlin-1m62</guid>
      <description>&lt;p&gt;What’s the best way to learn a language other than writing some code with it? Solving fun and short tasks like the ones from &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; might be a great opportunity to practice your language skills, and you can learn a lot if you compare your solutions with how others have solved the same problem.&lt;/p&gt;

&lt;p&gt;Lots of developers from around the world, including some from the Kotlin team, take part in the Advent of Code challenges created by &lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;. Advent of Code is a series of tasks published every December, which you solve and compete with others. Many would agree that it’s the best advent calendar to celebrate Christmas and New Year!&lt;/p&gt;

&lt;p&gt;To help the community learn idiomatic Kotlin, and motivate more developers to solve Advent of Code tasks in Kotlin in the future, we decided to prepare solutions for the tasks from Advent of Code 2020. It doesn’t matter if you solved it back in December, you’re ready to solve it now, or you just want to check the solutions – we hope you’ll find something useful in these materials. Of course, it works best if you try to solve the same task first yourself!&lt;/p&gt;

&lt;p&gt;Below is the solution and video for the first task. If you find this format useful and want us to cover more tasks in a similar fashion, please share in the comments!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/o4emra1xm88"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Day 1. Report Repair
&lt;/h2&gt;

&lt;p&gt;We’re fixing an expense report! Find the full task description at &lt;a href="https://adventofcode.com/2020/day/1"&gt;https://adventofcode.com/2020/day/1&lt;/a&gt;*.&lt;/p&gt;

&lt;p&gt;You need to find the two (and in the second part, three) entries from the list of numbers that sum to 2020 and then multiply those two (or three) numbers together.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to solve the task
&lt;/h3&gt;

&lt;p&gt;Register at &lt;a href="https://adventofcode.com/"&gt;https://adventofcode.com/&lt;/a&gt;, open the task at &lt;a href="https://adventofcode.com/2020/day/1"&gt;https://adventofcode.com/2020/day/1&lt;/a&gt;, write your solution in Kotlin, and check the result on the site. You can either write Kotlin code &lt;a href="https://play.kotlinlang.org/"&gt;online&lt;/a&gt; or using an IDE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download the  free Community Edition of &lt;a href="https://www.jetbrains.com/idea/download/"&gt;IntelliJ IDEA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;create &lt;a href="https://kotlinlang.org/docs/jvm-get-started.html"&gt;a Kotlin project&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;write your solution there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, compare your solution with the solution below.&lt;/p&gt;

&lt;p&gt;We &lt;a href="https://github.com/svtk/advent-of-code-2020/blob/master/build.gradle.kts"&gt;marked&lt;/a&gt; the &lt;code&gt;src&lt;/code&gt; folder as a source set to put the code directly there. We copied input files, like &lt;code&gt;src/day1/input.txt&lt;/code&gt;,  to the source folder for convenience. You can find the solutions in &lt;a href="https://github.com/Kotlin-hands-on/advent-of-code-2020"&gt;this project&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Here’s the sample input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1721
979
366
299
675
1456
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we need to read and parse the input. We can use the Kotlin &lt;code&gt;readLines()&lt;/code&gt; function for reading a list of lines from a given file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day1/input.txt"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;readLines()&lt;/code&gt; returns a list of Strings, and we convert it to a list of numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.File&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"src/day1/input.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readLines&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;toInt&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;You put this code inside the &lt;code&gt;main&lt;/code&gt; function, the entry point for your program. When you start typing, IntelliJ IDEA imports the &lt;code&gt;java.io.File&lt;/code&gt; automatically.&lt;/p&gt;

&lt;p&gt;Now we can simply iterate through the list, and then for each number repeat the iteration and check the sum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
           &lt;span class="k"&gt;return&lt;/span&gt;
       &lt;span class="p"&gt;}&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;You put this code inside &lt;code&gt;main&lt;/code&gt;, so &lt;code&gt;return&lt;/code&gt; returns from &lt;code&gt;main&lt;/code&gt; when the required numbers are found.&lt;/p&gt;

&lt;p&gt;In a similar way, you check the sum of three numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;third&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
               &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;third&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
               &lt;span class="k"&gt;return&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;}&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;You can run it and get the result for a given input. That’s it! The first task is really a simple one.&lt;/p&gt;

&lt;p&gt;However, we iterate over the same list again and again for each of the elements. Having two nested loops for finding two numbers makes it N&lt;sup&gt;2&lt;/sup&gt; operations, where N is the number of elements. When we need to find three numbers, that’s three nested loops, and N&lt;sup&gt;3&lt;/sup&gt; operations. If the list of numbers is large, that’s not the most efficient way to solve this type of problem. Surely there is a better way, right?&lt;/p&gt;

&lt;p&gt;There definitely is and the Kotlin standard library can help us express that concisely. As often happens, we can replace the long calculation with some kind of smart storage used to find the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving the task for two numbers
&lt;/h3&gt;

&lt;p&gt;First, let’s build a map for number “complements” – numbers that together with the given number sum up to 2020:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complements&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associateBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the Kotlin &lt;code&gt;associateBy&lt;/code&gt; function to build the map. Its lambda argument returns a key in this map, by which the list element is getting stored. For the sample input it’ll be the following map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;complements&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1041&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1654&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1345&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;564&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this procedure, you can clearly see the answer! The very first number &lt;code&gt;1721&lt;/code&gt; from the list is present in the &lt;code&gt;complements&lt;/code&gt; map as a key: &lt;code&gt;1721=299&lt;/code&gt;, which means it’s the complement for the number &lt;code&gt;299&lt;/code&gt;, and they sum to &lt;code&gt;2020&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Having stored this information in a map, we can check if any number from the list has a complement in this map. The following code finds the first number with an existing complement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pair&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mapNotNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;complements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;firstOrNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We transform each number into a pair consisting of the number and its complement (if the complement exists) and then find the first non-null result.&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;mapNotNull&lt;/code&gt;, which transforms each element in a list and filters out all the resulting &lt;code&gt;null&lt;/code&gt;s. It’s shorthand for calling first &lt;code&gt;map&lt;/code&gt;, and then &lt;code&gt;filterNotNull&lt;/code&gt; on the result.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;firstOrNull&lt;/code&gt; returns the first element in the list or &lt;code&gt;null&lt;/code&gt; if the list is empty. Kotlin standard library often uses the &lt;code&gt;OrNull&lt;/code&gt; suffix to mark functions returning &lt;code&gt;null&lt;/code&gt; on failure rather than throwing an exception (like &lt;code&gt;elementAtOrNull&lt;/code&gt;, &lt;code&gt;singleOrNull&lt;/code&gt;, or &lt;code&gt;maxOrNull&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Starting with Kotlin 1.5.0, you can also replace the two consequent operations &lt;code&gt;mapNotNull&lt;/code&gt; and &lt;code&gt;first(OrNull)&lt;/code&gt; with one function call: &lt;code&gt;firstNotNullOf(OrNull)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After building the auxiliary structure, we managed to find the resulting two numbers in N operations, not in N&lt;sup&gt;2&lt;/sup&gt; as before!&lt;/p&gt;

&lt;p&gt;We need a multiplication of these numbers, so here’s the last step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;pair&lt;/code&gt; variable contains a nullable &lt;code&gt;Pair&lt;/code&gt; of two numbers and is &lt;code&gt;null&lt;/code&gt; if the initial list contains no numbers that sum up to 2020. We use safe access &lt;code&gt;?.&lt;/code&gt; together with the &lt;code&gt;let&lt;/code&gt; function and destructuring in a lambda syntax to display the result in case &lt;code&gt;pair&lt;/code&gt; is not &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solving the task for three numbers
&lt;/h3&gt;

&lt;p&gt;The next step is solving this problem for three numbers. Let’s reuse what we’ve done so far and extract the logic of finding a pair of numbers summing up to a given number into a separate function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Map: sum - x -&amp;gt; x&lt;/span&gt;
   &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complements&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;associateBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;firstNotNullOfOrNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;complements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;null&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;We also used the &lt;code&gt;firstNotNullOfOrNull&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Now, we use &lt;code&gt;findPairOfSum&lt;/code&gt; to build a helper map that stores the complement &lt;em&gt;pair of values&lt;/em&gt; for each number which together with this number sums up to 2020:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Map: x -&amp;gt; (y, z) where y + z = 2020 - x&lt;/span&gt;
&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;complementPairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Pair&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;associateWith&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;it&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 the same initial input, here’s the complement pairs map:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="n"&gt;pairs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1721&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;299&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;675&lt;/span&gt;&lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="mi"&gt;979&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1456&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As before, you already can see the answer! It’s the number that corresponds to a non-null pair in a map.&lt;/p&gt;

&lt;p&gt;However, we don’t really need to build the whole map — we only need to find the first number that corresponds to a non-null pair! Let’s find it using the already familiar &lt;code&gt;firstNotNullOfOrNull&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;findTripleOfSum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;Triple&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
   &lt;span class="nf"&gt;firstNotNullOfOrNull&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
       &lt;span class="nf"&gt;findPairOfSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
           &lt;span class="nc"&gt;Triple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pair&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;second&lt;/span&gt;&lt;span class="p"&gt;)&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;Note Kotlin’s concise syntax – the function can return an expression directly.&lt;/p&gt;

&lt;p&gt;The final step is to find the multiplication if the resulting triple is non-null, similar to how we did it before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triple&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;z&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;That’s all!&lt;/p&gt;

&lt;p&gt;In the next part, we’ll discuss how to solve the second task. Please let us know if you find this content useful and would like us to provide solutions for more tasks!&lt;/p&gt;




&lt;p&gt;*Used with the permission of &lt;a href="https://adventofcode.com/"&gt;Advent of Code&lt;/a&gt; (&lt;a href="https://twitter.com/ericwastl"&gt;Eric Wastl&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>adventofcode</category>
      <category>codenewbie</category>
      <category>100daysofcode</category>
    </item>
  </channel>
</rss>
