1. 1

      Yep and I think that explicitly partially applying using their bake is a nice API. The blog post’s API supports pipes (and redirections!) which in my opinion is nicer than what the sh library offers.

    1. 3

      Nice use of git worktree!

      1. 25

        I am going to write up my Haskell solution at some point, but I liked this:

        CREATE TABLE day_01 (v INT NOT NULL UNIQUE);
        COPY day_01 FROM 'Projects/AOC/2020/data/Day01.txt';
        
        SELECT 1 AS part, a.v * b.v AS answer
          FROM day_01 a CROSS JOIN day_01 b 
         WHERE a.v <> b.v AND a.v + b.v = 2020
         UNION
        SELECT 2 AS part, a.v *  b.v * (2020 - a.v - b.v) AS answer
          FROM day_01 a CROSS JOIN day_01 b
         WHERE a.v <> b.v
           AND 2020 - a.v - b.v > 0
           AND EXISTS (SELECT 1 FROM day_01 WHERE v = 2020 - a.v - b.v);
        

        And it’s crazy fast:

           part |  answer
         -------+----------
              1 |   800139
              2 | 59885340
        (2 rows)
        
        Time: 6.732 ms
        
        1. 7

          I love the SQL solution. If you want to use it with a version of sqlite that shipped post-2004, change COPY... to .import day01.txt day_01

          1. 2

            In part 2, what about using three join instead of the exists?

            1. 1

              That would be better, yeah. This is basically a port of my Haskell solution, though.

            2. 1

              Looks neat, and it’s also all one line of code! Woot!

              Would love to see that done for the triples in the next section.

              If everything keeps building on everything, that’s going to be a fun hunk of code to watch evolve. :)

              1. 3

                It actually does both :)

                1. 2

                  If DDL does not count as code, would it be zero lines of code if I could make a macro that reports the solution in an error? Or maybe if one used dependently typed programming where the compiler can infer the solution? If I used Datalog, would the queries count as code, but that statements not? ;)

                2. 1

                  The Haskell version I ported from:

                  solve01 :: [Int] -> Int
                  solve01 xs = head [a * b | a <- xs, let b = 2020 - a, b `elem` xs]
                  
                  solve02 :: [Int] -> Int
                  solve02 xs = 
                    head [a * b * c | a <- xs, b <- xs, a /= b, let c = 2020 - a - b, c `elem` xs]
                  

                  Tedious IO is left to the reader.

                  1. 1

                    I believe you have a bug? a.v <> b.v should be a.id <> b.id or something?

                    1. 2

                      Since the numbers are unique, they’re using that to make sure they’re not checking the number added with itself since that wouldn’t be a valid solution even if it added up to 2020.

                      1. 1

                        Right. Does the problem specify that the numbers are unique? Perhaps I missed that.

                        1. 1

                          It doesn’t, but wc -l and sort -u | wc -l gave me the same number, so.

                          1. 3

                            Plus I assume you would’ve found out pretty quickly if they weren’t all unique when you tried to import them into a column with a unique constraint.

                            1. 1

                              My first solution was in Haskell, so I had already determined that particular bit of data modelling.

                              1. 2

                                Ah, I guess it makes sense that the SQL implementation wasn’t the one you started with.

                      2. 2

                        The column in the table is named v.

                        1. 2

                          Is there just one column? I was wondering how you’d handle duplicates where the answer is a perfect square.

                          1. 1

                            Yep, just the one. I cheated :)

                            1. 2

                              Ah, the ol’ overtraining-on-single-input. Carry on :)

                    1. 1

                      Dvorak user here. I remap htns, qwerty’s jkl;, to hjkl in all applications to get spatial navigation. This also frees up d, qwerty’s h, to be used for delete in vim/kakoune/qutebrowser. However new locations for tns are needed and I’ve been using kgl for that. This leaves j free and I use that as a leader (as well as , and z).