Skip to content

Instantly share code, notes, and snippets.

@kipcole9
Last active June 27, 2021 22:21
Show Gist options
  • Save kipcole9/4c4b21949a2769f755f3291bb238aef6 to your computer and use it in GitHub Desktop.
Save kipcole9/4c4b21949a2769f755f3291bb238aef6 to your computer and use it in GitHub Desktop.
defmodule Channel do
@input [{0, 190}, {1, 0}, {2, 0}, {3, 0}, {6, 220}, {9, 90}]
@doc """
Map a list of {index, value} pairs
into a binary, filling in any gaps in
the index sequence with <<0>> as
the list is built.
"""
def to_binary(input \\ @input) do
input
|> reduce_input()
|> :erlang.list_to_binary()
end
# Only one element, return its value
def reduce_input([{_i1, v1}]) do
[v1]
end
# This element and the next are in
# sequence so no filler is required
def reduce_input([{i1, v1}, {i2, _v2} = next | tail]) when i2 == i1 + 1 do
[v1 | reduce_input([next | tail])]
end
# This element and the next are not in sequence
# so we need to insert some filler <<0>>'s
def reduce_input([{i1, v1}, {i2, _v2} = next | tail]) do
[v1 | Enum.reduce(1..i2 - i1 - 1, reduce_input([next | tail]), fn _i, acc -> [0 | acc] end)]
end
@doc """
This version composes the binary directly
It is 17% slower than the list version
since combining binaries is not as fast
as list insertion.
"""
def to_binary2(input \\ @input) do
input
|> reduce_input2()
end
# Only one element, return its value
def reduce_input2([{_i1, v1}]) do
<<v1>>
end
# This element and the next are in
# sequence so no filler is required
def reduce_input2([{i1, v1}, {i2, _v2} = next | tail]) when i2 == i1 + 1 do
<<v1>> <> reduce_input2([next | tail])
end
# This element and the next are not in sequence
# so we need to insert some filler <<0>>'s
def reduce_input2([{i1, v1}, {i2, _v2} = next | tail]) do
<<v1>> <> Enum.reduce(1..i2 - i1 - 1, reduce_input2([next | tail]), fn _i, acc -> <<0>> <> acc end)
end
end
@kipcole9
Copy link
Author

kipcole9 commented Jun 27, 2021

iex> Channel.to_binary 
<<190, 0, 0, 0, 0, 0, 220, 0, 0, 90>>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment