-
-
Notifications
You must be signed in to change notification settings - Fork 401
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New practice exercise variable-length-quantity
#798
New practice exercise variable-length-quantity
#798
Conversation
Thank you for contributing to Based on the files changed in this PR, it would be good to pay attention to the following details when reviewing the PR:
Automated comment created by PR Commenter 🤖. |
What if we changed this exercise a bit, rather than working with a list of integers, what if we use bitstrings? So the exercise would be converting integers to VLQ encoded binaries, and VLQ encoded binaries to integers. I don't think we have anything like this in our practice list, might be super interesting to promote a binary-based pattern matching exercise. To encode the integer you can do something like this: integer = 78
<<encoded::7>> = <<integer::7>>
remainder = integer - encoded
if remainder == 0 do
<<0::1, encoded::7, following::binary>>
else
encode(remainder, <<1::1, encoded::7, following::binary>>)
end |
I'm with @neenjaw, bitstrings are the perfect choice for this exercise. We definitely need more practice exercises for bitstrings! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just adding a request for changes based on: #798 (comment)
Excellent suggestion. It also made my code more readable :) Also CI with 1.8 is failing, I'm not sure why. Any idea? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice solution, looks awesome. <<_::8>>
is equivalent to the binary
type since a binary
is always divisible by 8 bits. bitstrings
can be any number of bits.
That's an interesting error. I wonder if there has been a regression somewhere in older versions because I thought that would have worked. Anyway, this seems to solve it with use Bitwise
then using the infix operators:
defmodule VariableLengthQuantity do
use Bitwise
@doc """
Encode integers into a bitstring of VLQ encoded bytes
"""
@spec encode(integers :: [integer]) :: <<_::8>>
def encode(integers) when is_list(integers) do
integers
|> Enum.map(&encode/1)
|> Enum.map(&String.reverse/1)
|> Enum.join(<<>>)
end
def encode(0), do: <<0>>
def encode(int, leading \\ 0)
def encode(0, _), do: <<>>
def encode(int, leading) do
rest = int >>> 7
<<leading::1, int::7, encode(rest, 1)::binary>>
end
@doc """
Decode a bitstring of VLQ encoded bytes into a series of integers
"""
@spec decode(bytes :: <<_::8>>) :: {:ok, [integer]} | {:error, String.t()}
def decode(bytes, _status \\ :complete, acc \\ 0)
def decode(<<>>, :complete, _), do: {:ok, []}
def decode(<<>>, :incomplete, _), do: {:error, "incomplete sequence"}
def decode(<<lead::1, byte::7, bytes::binary>>, _status, acc) do
acc = (acc <<< 7) + byte
if lead == 1 do
decode(bytes, :incomplete, acc)
else
with {:ok, result} <- decode(bytes, :complete),
do: {:ok, [acc | result]}
end
end
end
exercises/practice/variable-length-quantity/lib/variable_length_quantity.ex
Outdated
Show resolved
Hide resolved
exercises/practice/variable-length-quantity/lib/variable_length_quantity.ex
Outdated
Show resolved
Hide resolved
Co-authored-by: Tim Austin <tim@neenjaw.com>
Nice, the inline operator looks better anyway :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect 🥳 I'm so happy we finally have a bitstrings practice exercise
New one.
Nothing too special, except that bit manipulation code is alway hard to read (or at least I can't make it legible).