Organize code, remove problematic files
This commit is contained in:
parent
107b8c6397
commit
15de5e8283
25 changed files with 279 additions and 174 deletions
|
@ -1,4 +1,4 @@
|
|||
import RegexUtil, only: [scan_index_with_binary: 2]
|
||||
import AoC.Util.Regex, only: [scan_index_with_binary: 2]
|
||||
|
||||
defmodule Mix.Tasks.Day3 do
|
||||
use Mix.Task
|
||||
|
|
|
@ -19,7 +19,7 @@ defmodule Mix.Tasks.Day5 do
|
|||
def parse_line(line) when line != "" do
|
||||
make_range = fn line ->
|
||||
[dest_start, source_start, len] = line |> split_int_list(" ")
|
||||
{:range, {RangeUtil.from_start(dest_start, len), RangeUtil.from_start(source_start, len)}}
|
||||
{:range, {AoC.Util.Range.from_start(dest_start, len), AoC.Util.Range.from_start(source_start, len)}}
|
||||
end
|
||||
|
||||
cap = Regex.run(~r/(\w+)-to-(\w+) map:/, line)
|
||||
|
@ -46,7 +46,7 @@ defmodule Mix.Tasks.Day5 do
|
|||
|> Map.put(type, data)
|
||||
|> Map.put(
|
||||
:ranges,
|
||||
ranges |> Stream.map(fn [start, len] -> RangeUtil.from_start(start, len) end)
|
||||
ranges |> Stream.map(fn [start, len] -> AoC.Util.Range.from_start(start, len) end)
|
||||
)
|
||||
|
||||
:map_key ->
|
||||
|
@ -89,7 +89,7 @@ defmodule Mix.Tasks.Day5 do
|
|||
transpose =
|
||||
case ranges
|
||||
|> Enum.find(fn {_, start} -> n in start end) do
|
||||
{dest_range, source_range} -> RangeUtil.transpose(n, source_range, dest_range)
|
||||
{dest_range, source_range} -> AoC.Util.Range.transpose(n, source_range, dest_range)
|
||||
nil -> n
|
||||
end
|
||||
|
||||
|
@ -103,16 +103,16 @@ defmodule Mix.Tasks.Day5 do
|
|||
for {dest_range, source_range} <- ranges,
|
||||
reduce: {[], [range]} do
|
||||
{transposed_ranges, leftover} ->
|
||||
intersection = RangeUtil.intersection(range, source_range)
|
||||
intersection = AoC.Util.Range.intersection(range, source_range)
|
||||
|
||||
offset = intersection.first - source_range.first
|
||||
transpose_start = dest_range.first + offset
|
||||
transposed = RangeUtil.from_start(transpose_start, intersection |> Range.size())
|
||||
transposed = AoC.Util.Range.from_start(transpose_start, intersection |> Range.size())
|
||||
|
||||
{
|
||||
[transposed | transposed_ranges],
|
||||
leftover
|
||||
|> Enum.flat_map(fn r -> RangeUtil.difference(r, intersection) end)
|
||||
|> Enum.flat_map(fn r -> AoC.Util.Range.difference(r, intersection) end)
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{_, puzzle_input} = File.read("./input/2023_11.txt")
|
||||
IO.puts("part 1 #{Galaxy.solve_pt_1(puzzle_input)}")
|
||||
IO.puts("part 2 #{Galaxy.shortest_paths_expansion_adjusted(puzzle_input, 10**6)}")
|
||||
#{_, puzzle_input} = File.read("./input/2023_11.txt")
|
||||
#IO.puts("part 1 #{Galaxy.solve_pt_1(puzzle_input)}")
|
||||
#IO.puts("part 2 #{Galaxy.shortest_paths_expansion_adjusted(puzzle_input, 10**6)}")
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
{_, content} = File.read("./input/2023_12.txt")
|
||||
SprintParseWorker.solve_in_parallel(content) |> IO.puts()
|
||||
# {_, content} = File.read("./input/2023_12.txt")
|
||||
#SprintParseWorker.solve_in_parallel(content) |> IO.puts()
|
||||
|
|
|
@ -35,12 +35,12 @@ defmodule RollingRocks do
|
|||
end
|
||||
|
||||
def solve_1(input) do
|
||||
StringUtil.transpose(input)
|
||||
AoC.Util.String.transpose(input)
|
||||
|> String.split("\n")
|
||||
|> Enum.with_index()
|
||||
|> Enum.map(&line_to_tile_map(&1))
|
||||
|> Enum.map(&roll_rocks(&1, :north))
|
||||
|> EnumUtil.transpose()
|
||||
|> AoC.Util.Enum.transpose()
|
||||
|> Enum.map(fn tilemap ->
|
||||
tilemap
|
||||
|> Enum.map(fn tile -> Map.get(tile, :tile) end)
|
||||
|
@ -84,16 +84,16 @@ defmodule RollingRocks do
|
|||
end
|
||||
|
||||
def cycle(grid) do
|
||||
StringUtil.transpose(grid)
|
||||
AoC.Util.String.transpose(grid)
|
||||
|> String.split("\n")
|
||||
|> Enum.with_index()
|
||||
|> Enum.map(&line_to_tile_map(&1))
|
||||
|> Enum.map(&roll_rocks(&1, :north))
|
||||
|> EnumUtil.transpose()
|
||||
|> AoC.Util.Enum.transpose()
|
||||
|> Enum.map(&roll_rocks(&1, :west))
|
||||
|> EnumUtil.transpose()
|
||||
|> AoC.Util.Enum.transpose()
|
||||
|> Enum.map(&roll_rocks(&1, :south))
|
||||
|> EnumUtil.transpose()
|
||||
|> AoC.Util.Enum.transpose()
|
||||
|> Enum.map(&roll_rocks(&1, :east))
|
||||
|> Enum.map(fn tilemap ->
|
||||
tilemap
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{_, content} = File.read("./input/2023_14.txt")
|
||||
#{_, content} = File.read("./input/2023_14.txt")
|
||||
|
||||
RollingRocks.solve_2(content) |> IO.puts()
|
||||
#RollingRocks.solve_2(content) |> IO.puts()
|
||||
|
|
|
@ -162,7 +162,7 @@ defmodule Lightbeam do
|
|||
|> Enum.map(fn dir ->
|
||||
|
||||
{
|
||||
TupleUtil.pairwise_sum(current_position, @direction_tuple[dir]),
|
||||
AoC.Util.Tuple.pairwise_sum(current_position, @direction_tuple[dir]),
|
||||
dir
|
||||
}
|
||||
end)
|
||||
|
|
|
@ -2,9 +2,9 @@ defmodule Mix.Tasks.Day19 do
|
|||
def run(args) do
|
||||
[part | _] = args
|
||||
{_, puzzle_input} = File.read("./input/2023_19.txt")
|
||||
part = if part == "1", do: :part1, else: :part2
|
||||
part = if part == "1", do: :part1, else: :part2
|
||||
|
||||
{commands, toys} = parse(puzzle_input, case part do
|
||||
{commands, toys} = parse(puzzle_input, case part do
|
||||
:part1 -> &build_comparator/1
|
||||
:part2 -> &build_range_comparator/1
|
||||
end)
|
||||
|
@ -52,7 +52,7 @@ defmodule Mix.Tasks.Day19 do
|
|||
fn toy ->
|
||||
toy
|
||||
|> Map.get(facet)
|
||||
|> RangeUtil.split_at(thresh, if(comp == ">", do: :lb, else: :ub))
|
||||
|> AoC.Util.Range.split_at(thresh, if(comp == ">", do: :lb, else: :ub))
|
||||
|> Enum.map(fn new_range ->
|
||||
if comp == ">" and new_range.first > thresh do
|
||||
{new_range, target}
|
||||
|
|
|
@ -24,7 +24,7 @@ defmodule Mix.Tasks.Day8 do
|
|||
|
||||
true ->
|
||||
receive do
|
||||
n -> loop_receive(max_len, MathUtil.lcm(acc, n), count + 1)
|
||||
n -> loop_receive(max_len, AoC.Util.Math.lcm(acc, n), count + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
defmodule EnumUtil do
|
||||
def transpose(enum) do
|
||||
col_count = enum |> Enum.at(0) |> Enum.count()
|
||||
|
||||
for col <- 0..(col_count - 1) do
|
||||
enum |> Enum.map(&Enum.at(&1, col))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,23 +1,9 @@
|
|||
defmodule Mix.Tasks.GetInput do
|
||||
defp get_session() do
|
||||
{_, content} = File.read("./.session")
|
||||
content |> String.trim()
|
||||
end
|
||||
|
||||
defp get_request_headers() do
|
||||
[Cookie: "session=#{get_session()}"]
|
||||
end
|
||||
|
||||
def run(args) do
|
||||
[year, day] = args
|
||||
write_file = &File.write("./input/#{year}_#{day}.txt", &1)
|
||||
HTTPoison.start()
|
||||
|
||||
HTTPoison.get!(
|
||||
"https://adventofcode.com/#{year}/day/#{day}/input",
|
||||
get_request_headers()
|
||||
)
|
||||
|> Map.get(:body)
|
||||
AoC.Input.fetch_input!(year, day)
|
||||
|> then(fn i ->
|
||||
IO.puts(i)
|
||||
i
|
||||
|
|
15
lib/input.ex
Normal file
15
lib/input.ex
Normal file
|
@ -0,0 +1,15 @@
|
|||
defmodule AoC.Input do
|
||||
defp get_session!(), do: File.read!("./.session") |> String.trim()
|
||||
defp get_request_headers!(), do: [Cookie: "session=#{get_session!()}"]
|
||||
defp get_url(year, day), do: "https://adventofcode.com/#{year}/day/#{day}/input"
|
||||
|
||||
def fetch_input!(year, day) do
|
||||
HTTPoison.start()
|
||||
|
||||
get_url(year, day)
|
||||
|> HTTPoison.get!(
|
||||
get_request_headers!()
|
||||
)
|
||||
|> Map.get(:body)
|
||||
end
|
||||
end
|
|
@ -1,78 +0,0 @@
|
|||
defmodule RangeUtil do
|
||||
@spec from_start(integer(), integer()) :: Range.t()
|
||||
def from_start(start, len) do
|
||||
if len == 0 do
|
||||
..
|
||||
else
|
||||
start..(start + len - 1)
|
||||
end
|
||||
end
|
||||
|
||||
def transpose(value, source, dest) do
|
||||
offset = value - (source |> Enum.at(0))
|
||||
(dest |> Enum.at(0)) + offset
|
||||
end
|
||||
|
||||
@spec contains?(Range.t(), Range.t()) :: boolean
|
||||
def contains?(r1, r2) do
|
||||
r2.first >= r1.first and r2.last <= r1.last
|
||||
end
|
||||
|
||||
@spec difference(Range.t(), Range.t()) :: [Range.t()]
|
||||
def difference(r1, r2) do
|
||||
cond do
|
||||
Range.disjoint?(r1, r2) ->
|
||||
[r1]
|
||||
|
||||
RangeUtil.contains?(r2, r1) ->
|
||||
[]
|
||||
|
||||
RangeUtil.contains?(r1, r2) ->
|
||||
s1_len = r2.first - r1.first
|
||||
s2_len = r1.last - r2.last
|
||||
|
||||
[
|
||||
RangeUtil.from_start(r1.first, s1_len),
|
||||
RangeUtil.from_start(r2.last + 1, s2_len)
|
||||
]
|
||||
|> Enum.reject(fn r -> r == .. end)
|
||||
|
||||
r2.first <= r1.first and r2.last <= r1.last ->
|
||||
s1_len = r1.last - r2.last
|
||||
[RangeUtil.from_start(r2.last + 1, s1_len)]
|
||||
|
||||
r2.first >= r1.first and r2.last >= r1.last ->
|
||||
s1_len = r2.first - r1.first
|
||||
[RangeUtil.from_start(r1.first, s1_len)]
|
||||
end
|
||||
end
|
||||
|
||||
@spec intersection(Range.t(), Range.t()) :: Range.t()
|
||||
def intersection(r1, r2) do
|
||||
cond do
|
||||
Range.disjoint?(r1, r2) -> ..
|
||||
RangeUtil.contains?(r2, r1) -> r1
|
||||
RangeUtil.contains?(r1, r2) -> r2
|
||||
r2.first <= r1.first and r2.last <= r1.last -> Range.new(r1.first, r2.last)
|
||||
r2.first >= r1.first and r2.last >= r1.last -> Range.new(r2.first, r1.last)
|
||||
end
|
||||
end
|
||||
|
||||
@spec split_at(range :: Range.t(), value :: integer(), bound :: :lb | :ub) :: [Range.t()]
|
||||
def split_at(range, value, bound) do
|
||||
if value <= range.first or value >= range.last do
|
||||
[range]
|
||||
else
|
||||
ls = min(range.first, value - 1)
|
||||
le = min(range.last, value - 1)
|
||||
rs = max(range.first, value + 1)
|
||||
re = max(range.last, value + 1)
|
||||
|
||||
if bound == :lb do
|
||||
[ls..value, rs..re]
|
||||
else
|
||||
[ls..le, value..re]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
defmodule StringUtil do
|
||||
def transpose(str) do
|
||||
EnumUtil.transpose(
|
||||
str
|
||||
|> String.split("\n")
|
||||
|> Enum.map(&String.graphemes(&1))
|
||||
|
||||
)|> Enum.map(&Enum.join(&1,"")) |> Enum.join("\n")
|
||||
end
|
||||
end
|
17
lib/util/enum.ex
Normal file
17
lib/util/enum.ex
Normal file
|
@ -0,0 +1,17 @@
|
|||
defmodule AoC.Util.Enum do
|
||||
@doc """
|
||||
Transposes (in the sense of matrices) a collection of nested enums.
|
||||
|
||||
iex> AoC.Util.Enum.transpose(
|
||||
iex> [[1,2,3], [4,5,6], [7,8,9]]
|
||||
iex> )
|
||||
[[1,4,7],[2,5,8],[3,6,9]]
|
||||
"""
|
||||
def transpose(enum) do
|
||||
col_count = enum |> Enum.at(0) |> Enum.count()
|
||||
|
||||
for col <- 0..(col_count - 1) do
|
||||
enum |> Enum.map(&Enum.at(&1, col))
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,11 @@
|
|||
defmodule MathUtil do
|
||||
defmodule AoC.Util.Math do
|
||||
@moduledoc """
|
||||
Math utility methods.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Returns the greatest common divisor of integers a and b.
|
||||
"""
|
||||
@spec gcd(integer(), integer()) :: integer()
|
||||
def gcd(0, 0) do
|
||||
0
|
||||
|
@ -19,6 +26,9 @@ defmodule MathUtil do
|
|||
gcd(a, b - a)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the least common multiple of integers a and b.
|
||||
"""
|
||||
@spec lcm(integer(), integer()) :: integer()
|
||||
def lcm(a, b) do
|
||||
div(a * b, gcd(a, b))
|
141
lib/util/range.ex
Normal file
141
lib/util/range.ex
Normal file
|
@ -0,0 +1,141 @@
|
|||
defmodule AoC.Util.Range do
|
||||
@doc """
|
||||
Given a `start` and a `length`, returns a Range of
|
||||
start..(start+len-1).
|
||||
|
||||
Returns the empty range if `len` is 0.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> AoC.Util.Range.from_start(10, 2)
|
||||
10..11
|
||||
|
||||
iex> AoC.Util.Range.from_start(10, 0)
|
||||
..
|
||||
|
||||
iex> AoC.Util.Range.from_start(10, 10)
|
||||
10..19
|
||||
"""
|
||||
@spec from_start(integer(), integer()) :: Range.t()
|
||||
def from_start(start, len) do
|
||||
if len == 0 do
|
||||
..
|
||||
else
|
||||
start..(start + len - 1)
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Given a `value`, z, and a range (x,y) containing that value.
|
||||
Return the `value`'s "place" in the `dest` range (s,t),
|
||||
given by s + (z - x). Note that this does not check that
|
||||
`source` and `dest` are the same size so it is possible the
|
||||
returned value is not contained within `dest`.
|
||||
|
||||
iex> AoC.Util.Range.transpose(5, 1..10, 30..50)
|
||||
34
|
||||
"""
|
||||
def transpose(value, source, dest) do
|
||||
offset = value - (source |> Enum.at(0))
|
||||
(dest |> Enum.at(0)) + offset
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns true iff r2 is completely contained within r1.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> AoC.Util.Range.contains?(1..10, 2..8)
|
||||
true
|
||||
"""
|
||||
@spec contains?(Range.t(), Range.t()) :: boolean
|
||||
def contains?(r1, r2) do
|
||||
r2.first >= r1.first and r2.last <= r1.last
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the set difference r1 \\ r2.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> AoC.Util.Range.difference(1..10, 11..20)
|
||||
[1..10]
|
||||
|
||||
iex> AoC.Util.Range.difference(1..10, 2..5)
|
||||
[1..1, 6..10]
|
||||
|
||||
iex> AoC.Util.Range.difference(1..10, -1..3)
|
||||
[4..10]
|
||||
"""
|
||||
@spec difference(Range.t(), Range.t()) :: [Range.t()]
|
||||
def difference(r1, r2) do
|
||||
cond do
|
||||
Range.disjoint?(r1, r2) ->
|
||||
[r1]
|
||||
|
||||
AoC.Util.Range.contains?(r2, r1) ->
|
||||
[]
|
||||
|
||||
AoC.Util.Range.contains?(r1, r2) ->
|
||||
s1_len = r2.first - r1.first
|
||||
s2_len = r1.last - r2.last
|
||||
|
||||
[
|
||||
AoC.Util.Range.from_start(r1.first, s1_len),
|
||||
AoC.Util.Range.from_start(r2.last + 1, s2_len)
|
||||
]
|
||||
|> Enum.reject(fn r -> r == .. end)
|
||||
|
||||
r2.first <= r1.first and r2.last <= r1.last ->
|
||||
s1_len = r1.last - r2.last
|
||||
[AoC.Util.Range.from_start(r2.last + 1, s1_len)]
|
||||
|
||||
r2.first >= r1.first and r2.last >= r1.last ->
|
||||
s1_len = r2.first - r1.first
|
||||
[AoC.Util.Range.from_start(r1.first, s1_len)]
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the set intersection of r1 and r2.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> AoC.Util.Range.intersection(1..10, 1..3)
|
||||
1..3
|
||||
|
||||
iex> AoC.Util.Range.intersection(1..10, -1..3)
|
||||
1..3
|
||||
|
||||
iex> AoC.Util.Range.intersection(-1..10, 1..3)
|
||||
1..3
|
||||
"""
|
||||
@spec intersection(Range.t(), Range.t()) :: Range.t()
|
||||
def intersection(r1, r2) do
|
||||
cond do
|
||||
Range.disjoint?(r1, r2) -> ..
|
||||
AoC.Util.Range.contains?(r2, r1) -> r1
|
||||
AoC.Util.Range.contains?(r1, r2) -> r2
|
||||
r2.first <= r1.first and r2.last <= r1.last -> Range.new(r1.first, r2.last)
|
||||
r2.first >= r1.first and r2.last >= r1.last -> Range.new(r2.first, r1.last)
|
||||
end
|
||||
end
|
||||
|
||||
@spec split_at(range :: Range.t(), value :: integer(), bound :: :lb | :ub) :: [Range.t()]
|
||||
def split_at(range, value, bound) do
|
||||
if value <= range.first or value >= range.last do
|
||||
[range]
|
||||
else
|
||||
ls = min(range.first, value - 1)
|
||||
le = min(range.last, value - 1)
|
||||
rs = max(range.first, value + 1)
|
||||
re = max(range.last, value + 1)
|
||||
|
||||
if bound == :lb do
|
||||
[ls..value, rs..re]
|
||||
else
|
||||
[ls..le, value..re]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
defmodule RegexUtil do
|
||||
defmodule AoC.Util.Regex do
|
||||
@spec scan_index_with_binary(Regex.t(), binary()) :: list()
|
||||
def scan_index_with_binary(regex, binary) do
|
||||
Regex.scan(regex, binary, return: :index)
|
24
lib/util/string.ex
Normal file
24
lib/util/string.ex
Normal file
|
@ -0,0 +1,24 @@
|
|||
defmodule AoC.Util.String do
|
||||
@doc """
|
||||
Transposes the string when it represents
|
||||
a grid of newline separated rows where each
|
||||
character is a new column.
|
||||
|
||||
iex> AoC.Util.String.transpose(
|
||||
iex> ~s(abc
|
||||
iex>def
|
||||
iex>ghi)
|
||||
iex>)
|
||||
~s(adg
|
||||
beh
|
||||
cfi)
|
||||
"""
|
||||
def transpose(str) do
|
||||
AoC.Util.Enum.transpose(
|
||||
str
|
||||
|> String.split("\n")
|
||||
|> Enum.map(&String.graphemes(&1))
|
||||
|
||||
)|> Enum.map(&Enum.join(&1,"")) |> Enum.join("\n")
|
||||
end
|
||||
end
|
|
@ -1,4 +1,4 @@
|
|||
defmodule TupleUtil do
|
||||
defmodule AoC.Util.Tuple do
|
||||
def pairwise_sum(t1, t2) do
|
||||
Tuple.to_list(t1)
|
||||
|> Stream.zip(Tuple.to_list(t2))
|
|
@ -14,11 +14,11 @@ defmodule Day5Tests do
|
|||
end
|
||||
|
||||
test "range util does not lie" do
|
||||
assert RangeUtil.from_start(120, 300) |> Enum.count() === 300
|
||||
assert AoC.Util.Range.from_start(120, 300) |> Enum.count() === 300
|
||||
end
|
||||
|
||||
test "range util transpose does not lie" do
|
||||
assert RangeUtil.transpose(98, 98..99, 50..51) === 50
|
||||
assert AoC.Util.Range.transpose(98, 98..99, 50..51) === 50
|
||||
end
|
||||
|
||||
test "parse works" do
|
||||
|
@ -28,7 +28,7 @@ seed-to-soil map:
|
|||
50 98 2
|
||||
52 50 48"
|
||||
# assert Mix.Tasks.Day5.parse(ex |> String.split("\n")) == %{
|
||||
# :seeds => [79, 14, 55, 13],
|
||||
# :seeds => [79, 14, 55, 13],
|
||||
# :maps => %{:seed => {:soil, [{52..99, 50..97}, {50..51, 98..99}]}},
|
||||
# :last_map_key => :seed
|
||||
# }
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
defmodule RangeUtilTest do
|
||||
use ExUnit.Case
|
||||
|
||||
test "RangeUtil.difference should work with disjoint ranges" do
|
||||
assert RangeUtil.difference(1..10, 11..20) == [1..10]
|
||||
end
|
||||
|
||||
test "RangeUtil.difference should work with contained ranges" do
|
||||
assert RangeUtil.difference(1..10, 2..5) == [1..1, 6..10]
|
||||
assert RangeUtil.difference(1..10, 1..10) == []
|
||||
assert RangeUtil.difference(1..10, 2..10) == [1..1]
|
||||
assert RangeUtil.difference(1..10, -1..11) == []
|
||||
assert RangeUtil.difference(1..10, 1..12) == []
|
||||
assert RangeUtil.difference(1..10, 2..2) == [1..1, 3..10]
|
||||
end
|
||||
|
||||
test "RangeUtil.difference should work with partially overlapped ranges" do
|
||||
assert RangeUtil.difference(1..10, -1..3) == [4..10]
|
||||
assert RangeUtil.difference(1..10, 1..1) == [2..10]
|
||||
assert RangeUtil.difference(1..10, 8..12) == [1..7]
|
||||
assert RangeUtil.difference(1..10, 2..12) == [1..1]
|
||||
end
|
||||
|
||||
test "RangeUtil.intersection should work with contained ranges" do
|
||||
assert RangeUtil.intersection(1..10, 1..3) == 1..3
|
||||
assert RangeUtil.intersection(1..10, -1..3) == 1..3
|
||||
assert RangeUtil.intersection(-1..10, 1..3) == 1..3
|
||||
assert RangeUtil.intersection(-1..10, -100..300) == -1..10
|
||||
assert RangeUtil.intersection(-1..10, 11..300) == (..)
|
||||
end
|
||||
end
|
4
test/util/enum_test.exs
Normal file
4
test/util/enum_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule AoC.Util.EnumTest do
|
||||
use ExUnit.Case
|
||||
doctest AoC.Util.Enum
|
||||
end
|
32
test/util/range_test.exs
Normal file
32
test/util/range_test.exs
Normal file
|
@ -0,0 +1,32 @@
|
|||
defmodule AoC.Util.RangeTest do
|
||||
use ExUnit.Case
|
||||
doctest AoC.Util.Range
|
||||
|
||||
test "AoC.Util.Range.difference should work with disjoint ranges" do
|
||||
assert AoC.Util.Range.difference(1..10, 11..20) == [1..10]
|
||||
end
|
||||
|
||||
test "AoC.Util.Range.difference should work with contained ranges" do
|
||||
assert AoC.Util.Range.difference(1..10, 2..5) == [1..1, 6..10]
|
||||
assert AoC.Util.Range.difference(1..10, 1..10) == []
|
||||
assert AoC.Util.Range.difference(1..10, 2..10) == [1..1]
|
||||
assert AoC.Util.Range.difference(1..10, -1..11) == []
|
||||
assert AoC.Util.Range.difference(1..10, 1..12) == []
|
||||
assert AoC.Util.Range.difference(1..10, 2..2) == [1..1, 3..10]
|
||||
end
|
||||
|
||||
test "AoC.Util.Range.difference should work with partially overlapped ranges" do
|
||||
assert AoC.Util.Range.difference(1..10, -1..3) == [4..10]
|
||||
assert AoC.Util.Range.difference(1..10, 1..1) == [2..10]
|
||||
assert AoC.Util.Range.difference(1..10, 8..12) == [1..7]
|
||||
assert AoC.Util.Range.difference(1..10, 2..12) == [1..1]
|
||||
end
|
||||
|
||||
test "AoC.Util.Range.intersection should work with contained ranges" do
|
||||
assert AoC.Util.Range.intersection(1..10, 1..3) == 1..3
|
||||
assert AoC.Util.Range.intersection(1..10, -1..3) == 1..3
|
||||
assert AoC.Util.Range.intersection(-1..10, 1..3) == 1..3
|
||||
assert AoC.Util.Range.intersection(-1..10, -100..300) == -1..10
|
||||
assert AoC.Util.Range.intersection(-1..10, 11..300) == (..)
|
||||
end
|
||||
end
|
4
test/util/string_test.exs
Normal file
4
test/util/string_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule AoC.Util.StringTest do
|
||||
use ExUnit.Case
|
||||
doctest AoC.Util.String
|
||||
end
|
Loading…
Add table
Reference in a new issue