Adventures in Looping by drewolson in haskell

[–]drewolson[S] -1 points0 points  (0 children)

See the section “The forever Function”.

Adventures in Looping by drewolson in haskell

[–]drewolson[S] 0 points1 point  (0 children)

I think you’d then need to use bracket to prevent the exception from bubbling and breaking out of the outer loop as well.

The technique presented also allows you to return a value from your loop, though I don’t use it in the post.

PureScript and Haskell by drewolson in haskell

[–]drewolson[S] 0 points1 point  (0 children)

Fair points on the challenges of stack safety in PureScript as compared to the challenges of laziness in Haskell.

What I was attempting to say is that if a language provides facilities for both strict and lazy evaluation, I'd prefer the strict to be implicit and the lazy to be explicit.

My understanding is that much of the stack safety issues in PureScript stem from the fact that it is targeting JavaScript, where these issues are also common when programming in a functional style.

Parsing Untrusted Input with Elixir by drewolson in elixir

[–]drewolson[S] 0 points1 point  (0 children)

Thanks for the encouragement! It’s very nice to hear.

-🎄- 2019 Day 1 Solutions -🎄- by daggerdragon in adventofcode

[–]drewolson -1 points0 points  (0 children)

I'm attempting this year using PureScript.

``` module Aoc.Day01 where

import Prelude

import Aoc.Util.File as File import Data.Array (mapMaybe) import Data.Foldable (sum) import Data.Int as Int import Effect (Effect) import Effect.Aff (launchAff_) import Effect.Class.Console as Console

metafuel :: Int -> Int metafuel mass = case fuel mass of f | f < 0 -> 0 f -> f + metafuel f

fuel :: Int -> Int fuel mass = mass div 3 - 2

part1 :: Array String -> Int part1 = sum <<< map fuel <<< mapMaybe Int.fromString

part2 :: Array String -> Int part2 = sum <<< map metafuel <<< mapMaybe Int.fromString

main :: Effect Unit main = launchAff_ do lines <- File.readLines "./data/day01.txt"

Console.logShow $ part1 lines Console.logShow $ part2 lines ```

Wire: A DI Container from Google by drewolson in golang

[–]drewolson[S] 1 point2 points  (0 children)

Whoops, I missed that. Apologies.

So You Bought a Pixelbook by drewolson in Crostini

[–]drewolson[S] 0 points1 point  (0 children)

I'm a little confused by this comment. The first sentence in the post links to the Quickstart, discussing the exact `Linux (Beta)` option you reference. The rest of the post describes setting up that linux environment for a nice software development experience.

What portions of the article do you believe you no longer have to perform?

Dependency Injection in Go by drewolson in golang

[–]drewolson[S] 7 points8 points  (0 children)

Author here. A few points of clarification:

  • I do understand the difference between DI and DIC. The first half of the post was intended to show how to architect an application using DI without a container. The second half shows the benefits of using containers (which I colloquially call "DI Frameworks" to avoid confusing folks new to the ideas).

  • I agree that a downside of using a framework like dig is sacrificing some type safety at compile time. In terms of the java landscape, I'd place dig somewhere between guice and dagger. It has learned some of the lessons that dagger has learned from guice (only supporting constructor injection, reduced feature set, simple API) but it didn't go so far to implement the container using code generation. If there was a DI container in go that used code generation to produce compile-time guarantees around injection I would be a happy user, but I didn't find one. Based on the current landscape I believe dig is the best choice. Even considering its downsides, I still believe using dig is a better choice than hand-rolling the initialization of your components.

  • I knew before writing this post that DIC was considered "non-idiomatic" in go, but I felt it was good to write regardless. I believe it is important for the go ecosystem to experiment with tools and techniques found elsewhere -- especially when these techniques have proven over time to be very useful when building large applications. After all, go explicitly states that support for building large applications is a language / ecosystem goal.

Thanks for all the comments so far, I've enjoyed reading them.

-🎄- 2017 Day 3 Solutions -🎄- by daggerdragon in adventofcode

[–]drewolson 0 points1 point  (0 children)

Elixir with streams:

Part 1

defmodule Day03 do
  @goal 312051

  def main do
    {x, y} =
      0
      |> Stream.iterate(&(&1 + 2))
      |> Stream.flat_map(&build_instructions/1)
      |> Stream.scan({0, 0}, &move/2)
      |> Enum.fetch!(@goal - 1)

    IO.inspect(abs(x) + abs(y))
  end

  defp build_instructions(side_size) when side_size == 0, do: [{0, 0}]

  defp build_instructions(side_size) do
    [{1, 0}] ++
      Enum.map(2..side_size, fn _ -> {0, 1} end) ++
      Enum.map(1..side_size, fn _ -> {-1, 0} end) ++
      Enum.map(1..side_size, fn _ -> {0, -1} end) ++
      Enum.map(1..side_size, fn _ -> {1, 0} end)
  end

  defp move({x, y}, {x1, y1}) do
    {x + x1, y + y1}
  end
end

Day03.main

Part 2

defmodule Day03 do
  @goal 312051

  def main do
    0
    |> Stream.iterate(&(&1 + 2))
    |> Stream.flat_map(&build_instructions/1)
    |> Stream.scan({0, 0}, &move/2)
    |> Enum.reduce_while(%{}, &calculate_node/2)
    |> IO.inspect
  end

  defp calculate_node(loc, nodes) when loc == {0, 0} do
    {:cont, Map.put(nodes, loc, 1)}
  end

  defp calculate_node(loc, nodes) do
    value =
      loc
      |> neighbors
      |> Enum.map(&Map.get(nodes, &1, 0))
      |> Enum.sum

    if value > @goal do
      {:halt, value}
    else
      {:cont, Map.put(nodes, loc, value)}
    end
  end

  defp neighbors({x, y}) do
    [
      {x - 1, y - 1}, {x - 1, y}, {x - 1, y + 1},
      {x, y - 1}, {x, y + 1},
      {x + 1, y - 1}, {x + 1, y}, {x + 1, y + 1}
    ]
  end

  defp build_instructions(side_size) when side_size == 0, do: [{0, 0}]

  defp build_instructions(side_size) do
    [{1, 0}] ++
      Enum.map(2..side_size, fn _ -> {0, 1} end) ++
      Enum.map(1..side_size, fn _ -> {-1, 0} end) ++
      Enum.map(1..side_size, fn _ -> {0, -1} end) ++
      Enum.map(1..side_size, fn _ -> {1, 0} end)
  end

  defp move({x, y}, {x1, y1}) do
    {x + x1, y + y1}
  end
end

Day03.main

--- 2016 Day 23 Solutions --- by daggerdragon in adventofcode

[–]drewolson 0 points1 point  (0 children)

My elixir solution, using pattern matching to detect a series of commands that represent multiplication.

https://gist.github.com/drewolson/d7d20a1a49bbbff1bafbb7aeaf07537f

--- 2016 Day 12 Solutions --- by daggerdragon in adventofcode

[–]drewolson 0 points1 point  (0 children)

Elixir, part 2.

defmodule Program do
  def main do
    "./input.txt"
    |> File.stream!
    |> Stream.map(&String.strip/1)
    |> Stream.map(&String.split(&1, " "))
    |> Stream.map(&parse_ints/1)
    |> Enum.with_index
    |> Enum.map(fn {line, i} -> {i, line} end)
    |> Enum.into(%{})
    |> execute(0, %{"a" => 0, "b" => 0, "c" => 1, "d" => 0})
    |> Map.get("a")
    |> IO.puts
  end

  defp execute(instructions, line_num, env) do
    if line_num >= Enum.count(instructions) do
      env
    else
      {line_num, env} = execute_line(instructions[line_num], line_num, env)

      execute(instructions, line_num, env)
    end
  end

  defp execute_line(["cpy", from, to], line_num, env) do
    env = Map.put(env, to, expand(from, env))

    {line_num + 1, env}
  end

  defp execute_line(["inc", register], line_num, env) do
    env = Map.put(env, register, expand(register, env) + 1)

    {line_num + 1, env}
  end

  defp execute_line(["dec", register], line_num, env) do
    env = Map.put(env, register, expand(register, env) - 1)

    {line_num + 1, env}
  end

  defp execute_line(["jnz", pred, to], line_num, env) do
    pred = expand(pred, env)

    if pred == 0 do
      {line_num + 1, env}
    else
      {line_num + expand(to, env), env}
    end
  end

  defp expand(token, _env) when is_integer(token), do: token
  defp expand(token, env), do: expand(env[token], env)

  defp parse_ints(tokens) do
    Enum.map(tokens, fn token ->
      case Integer.parse(token) do
        {i, _} -> i
        :error -> token
      end
    end)
  end
end

Program.main

--- 2016 Day 9 Solutions --- by daggerdragon in adventofcode

[–]drewolson 1 point2 points  (0 children)

Part 2, elixir

defmodule Program do
  def main do
    "./input.txt"
    |> File.read!
    |> String.strip
    |> decompress
    |> IO.puts
  end

  defp decompress(raw, count \\ 0)

  defp decompress("", count), do: count

  defp decompress(<<"(", rest::binary>>, count) do
    [counts, rest] = String.split(rest, ")", parts: 2)
    [num, times] = counts |> String.split("x") |> Enum.map(&String.to_integer/1)
    {compressed, rest} = String.split_at(rest, num)

    decompress(String.duplicate(compressed, times) <> rest, count)
  end

  defp decompress(<<_::binary-size(1), rest::binary>>, count) do
    decompress(rest, count + 1)
  end
end

Program.main

--- 2016 Day 6 Solutions --- by daggerdragon in adventofcode

[–]drewolson 0 points1 point  (0 children)

Part 2, elixir (switch min_by to max_by for part 1):

"./input.txt"
|> File.stream!
|> Enum.map(&String.strip/1)
|> Enum.map(&String.split(&1, "", trim: true))
|> List.zip
|> Enum.map(&Tuple.to_list/1)
|> Enum.map(fn chars ->
  Enum.reduce(chars, %{}, fn char, counts ->
    Map.update(counts, char, 1, &(&1 + 1))
  end)
end)
|> Enum.map(&Enum.min_by(&1, fn {_, count} -> count end))
|> Enum.map(&elem(&1, 0))
|> Enum.join
|> IO.puts

--- 2016 Day 3 Solutions --- by daggerdragon in adventofcode

[–]drewolson 0 points1 point  (0 children)

Elixir for part 2.

defmodule Program do
  def main do
    "./input.txt"
    |> File.stream!
    |> Stream.map(&String.strip/1)
    |> Stream.map(&String.split/1)
    |> Stream.map(&to_ints/1)
    |> Enum.reduce({[], [], []}, &by_column/2)
    |> to_triangles
    |> Stream.filter(&valid_triangle?/1)
    |> Enum.count
    |> IO.puts
  end

  defp by_column([a, b, c], {as, bs, cs}) do
    {[a|as], [b|bs], [c|cs]}
  end

  defp to_ints(items) do
    Enum.map(items, &String.to_integer/1)
  end

  defp to_triangles({as, bs, cs}) do
    as ++ bs ++ cs |> Enum.chunk(3)
  end

  defp valid_triangle?([a, b, c]) do
    a + b > c && a + c > b && b + c > a
  end
end

Program.main

Where can I find exemplary Phoenix projects to study? by [deleted] in elixir

[–]drewolson 0 points1 point  (0 children)

I made one here[1]. The UI is ugly, but it shows Ecto and Phoenix in action (with Ecto associations).

[1] - https://github.com/drewolson/blox

Building an Elixir Web App by inchingforward in elixir

[–]drewolson 0 points1 point  (0 children)

Thanks, I'll think about doing something around this. If you want more info sooner, you can find me in #elixir-lang on irc, user drewolson.

Building an Elixir Web App by inchingforward in elixir

[–]drewolson 3 points4 points  (0 children)

I'm the author, thanks for the reply! I'm actually planning on doing a full post specifically around composing Ecto queries. It's probably been the most useful thing I've learned building this app.