From cb33a29f8446096f85ee4aea81480b0bb19a99a7 Mon Sep 17 00:00:00 2001 From: Angelika Cathor Date: Tue, 21 Oct 2025 17:32:53 +0200 Subject: [PATCH 1/5] Update to Elixir 1.19 --- .github/workflows/ci.yml | 8 ++++---- README.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ef315260..5bedb85bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,8 +17,8 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - elixir: [1.18.1] - otp: [27.2] + elixir: [1.19.0] + otp: [28.1] steps: - name: Checkout code @@ -76,8 +76,6 @@ jobs: strategy: matrix: include: - - elixir: '1.14.0' - otp: '25.0' - elixir: '1.15.0' otp: '26.0' - elixir: '1.16.0' @@ -86,6 +84,8 @@ jobs: otp: '27.0' - elixir: '1.18.1' otp: '27.2' + - elixir: '1.19.0' + otp: '28.1' steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 diff --git a/README.md b/README.md index 4ca00df87..57ae0c072 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Setup -The exercises currently target Elixir versions from 1.14 to 1.18 and Erlang/OTP versions from 25 to 27. Detailed installation instructions can be found at +The exercises currently target Elixir versions from 1.15 to 1.19 and Erlang/OTP versions from 25 to 27. Detailed installation instructions can be found at [https://elixir-lang.org/install.html](https://elixir-lang.org/install.html). We recommend using the [asdf version manager](https://github.com/asdf-vm/asdf) to manage multiple Elixir versions. ## Testing From 41adb97ee3e65731c99d16b7f41f9cb2c94ff842 Mon Sep 17 00:00:00 2001 From: Angelika Cathor Date: Tue, 21 Oct 2025 17:41:26 +0200 Subject: [PATCH 2/5] Upgrade doctest_formatter --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 4bf1921a3..be9a19346 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,7 @@ defmodule ExercismTestRunner.Mixfile do [ {:dialyxir, "~> 1.3.0", runtime: false}, {:markdown_code_block_formatter, "~> 0.1.0", runtime: false}, - {:doctest_formatter, "~> 0.2.0", runtime: false} + {:doctest_formatter, "~> 0.4.0", runtime: false} ] end end diff --git a/mix.lock b/mix.lock index 2829d1b1e..bc96803ff 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, - "doctest_formatter": {:hex, :doctest_formatter, "0.2.0", "fe6198e8d81d833269314696b5bb55c0db0e16f609de53cdcafe1758f53ecf6c", [:mix], [], "hexpm", "34fb0da7cbb704d5caf477e77268fcf7ee9c87e13d94a04ea1865afb9e82e3f5"}, + "doctest_formatter": {:hex, :doctest_formatter, "0.4.1", "c69bf93853d1ec5785cbd22dcf0c2bd4dd357cc53f2e89d05850eed7e985462a", [:mix], [], "hexpm", "c1b07495a524126de133be4e077b28c4a2d8e1a14c9eeca962482e2067b5b068"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "markdown_code_block_formatter": {:hex, :markdown_code_block_formatter, "0.1.0", "1eb35408f0ce2cbd40086fea5bbb2aebbb4805ffc2c967f9e54aa724fa4bd222", [:mix], [], "hexpm", "ce27a7c7497074c48941c1d74ab9c39a08db31f2875b867c6d5671d7d70682b0"}, } From 02ac8ab6735cfa30765b3ebdcf374309c26c621d Mon Sep 17 00:00:00 2001 From: Angelika Cathor Date: Wed, 5 Nov 2025 17:45:54 +0100 Subject: [PATCH 3/5] Attempt to fix dialyzer warnings --- .github/workflows/ci.yml | 4 ++-- mix.exs | 3 ++- mix.lock | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bedb85bd..963d34851 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - elixir: [1.19.0] + elixir: [1.19.1] otp: [28.1] steps: @@ -84,7 +84,7 @@ jobs: otp: '27.0' - elixir: '1.18.1' otp: '27.2' - - elixir: '1.19.0' + - elixir: '1.19.1' otp: '28.1' steps: diff --git a/mix.exs b/mix.exs index be9a19346..0c024d93f 100644 --- a/mix.exs +++ b/mix.exs @@ -13,7 +13,8 @@ defmodule ExercismTestRunner.Mixfile do paths: ["_build"], plt_core_path: "priv/plts", plt_file: {:no_warn, "priv/plts/eventstore.plt"}, - ignore_warnings: ".dialyzer_ignore.exs" + ignore_warnings: ".dialyzer_ignore.exs", + flags: [:no_opaque] ] ] end diff --git a/mix.lock b/mix.lock index bc96803ff..d79e176fd 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, "doctest_formatter": {:hex, :doctest_formatter, "0.4.1", "c69bf93853d1ec5785cbd22dcf0c2bd4dd357cc53f2e89d05850eed7e985462a", [:mix], [], "hexpm", "c1b07495a524126de133be4e077b28c4a2d8e1a14c9eeca962482e2067b5b068"}, - "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, + "erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"}, "markdown_code_block_formatter": {:hex, :markdown_code_block_formatter, "0.1.0", "1eb35408f0ce2cbd40086fea5bbb2aebbb4805ffc2c967f9e54aa724fa4bd222", [:mix], [], "hexpm", "ce27a7c7497074c48941c1d74ab9c39a08db31f2875b867c6d5671d7d70682b0"}, } From 9401857a2afb32e29fe467d72735ee8a1a7a1ac6 Mon Sep 17 00:00:00 2001 From: Angelika Cathor Date: Fri, 7 Nov 2025 09:32:06 +0100 Subject: [PATCH 4/5] Upgrade Elixir and dialyxir --- .github/workflows/ci.yml | 4 ++-- mix.exs | 2 +- mix.lock | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 963d34851..f66944f14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - elixir: [1.19.1] + elixir: [1.19.2] otp: [28.1] steps: @@ -84,7 +84,7 @@ jobs: otp: '27.0' - elixir: '1.18.1' otp: '27.2' - - elixir: '1.19.1' + - elixir: '1.19.2' otp: '28.1' steps: diff --git a/mix.exs b/mix.exs index 0c024d93f..27117528d 100644 --- a/mix.exs +++ b/mix.exs @@ -25,7 +25,7 @@ defmodule ExercismTestRunner.Mixfile do defp deps do [ - {:dialyxir, "~> 1.3.0", runtime: false}, + {:dialyxir, "~> 1.4.7", runtime: false}, {:markdown_code_block_formatter, "~> 0.1.0", runtime: false}, {:doctest_formatter, "~> 0.4.0", runtime: false} ] diff --git a/mix.lock b/mix.lock index d79e176fd..3ed19a2a1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,5 @@ %{ - "dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"}, + "dialyxir": {:hex, :dialyxir, "1.4.7", "dda948fcee52962e4b6c5b4b16b2d8fa7d50d8645bbae8b8685c3f9ecb7f5f4d", [:mix], [{:erlex, ">= 0.2.8", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b34527202e6eb8cee198efec110996c25c5898f43a4094df157f8d28f27d9efe"}, "doctest_formatter": {:hex, :doctest_formatter, "0.4.1", "c69bf93853d1ec5785cbd22dcf0c2bd4dd357cc53f2e89d05850eed7e985462a", [:mix], [], "hexpm", "c1b07495a524126de133be4e077b28c4a2d8e1a14c9eeca962482e2067b5b068"}, "erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"}, "markdown_code_block_formatter": {:hex, :markdown_code_block_formatter, "0.1.0", "1eb35408f0ce2cbd40086fea5bbb2aebbb4805ffc2c967f9e54aa724fa4bd222", [:mix], [], "hexpm", "ce27a7c7497074c48941c1d74ab9c39a08db31f2875b867c6d5671d7d70682b0"}, From 5e6ea61e28ed6417654426f9cc26fe99e5d8c83b Mon Sep 17 00:00:00 2001 From: Angelika Cathor Date: Sun, 16 Nov 2025 08:20:09 +0100 Subject: [PATCH 5/5] Remove special mentions of 1.15 --- concepts/mapsets/about.md | 2 +- concepts/mapsets/introduction.md | 2 +- .../concept/gotta-snatch-em-all/.docs/hints.md | 4 +--- .../gotta-snatch-em-all/.docs/introduction.md | 2 +- .../concept/gotta-snatch-em-all/.meta/exemplar.ex | 15 +-------------- 5 files changed, 5 insertions(+), 20 deletions(-) diff --git a/concepts/mapsets/about.md b/concepts/mapsets/about.md index ce2c29ab0..abe645998 100644 --- a/concepts/mapsets/about.md +++ b/concepts/mapsets/about.md @@ -66,7 +66,7 @@ MapSet.symmetric_difference(b, a) # => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100]) ``` -You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2` (from Elixir 1.15). +You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2`. ```elixir a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) diff --git a/concepts/mapsets/introduction.md b/concepts/mapsets/introduction.md index aeeff3ea6..7f6b48faa 100644 --- a/concepts/mapsets/introduction.md +++ b/concepts/mapsets/introduction.md @@ -66,7 +66,7 @@ MapSet.symmetric_difference(b, a) # => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100]) ``` -You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2` (from Elixir 1.15). +You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2`. ```elixir a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) diff --git a/exercises/concept/gotta-snatch-em-all/.docs/hints.md b/exercises/concept/gotta-snatch-em-all/.docs/hints.md index 5a7fbfbbf..02187e2e0 100644 --- a/exercises/concept/gotta-snatch-em-all/.docs/hints.md +++ b/exercises/concept/gotta-snatch-em-all/.docs/hints.md @@ -47,7 +47,7 @@ ## 8. Shiny for the win -- Use [this `MapSet` function][split_with] to separate your collection (from Elixir 1.15, otherwise, [this][filter] and [that][reject] function can be used instead) +- Use [this `MapSet` function][split_with] to separate your collection - Use [this `String` function][starts_with] to detect shiny cards - [This `MapSet` function][to_list] can create a list - `MapSet`s do not have a notion of order, you should use [this `Enum` function][sort] to sort the cards, even if the tests pass without it @@ -64,8 +64,6 @@ [new_empty]: https://hexdocs.pm/elixir/MapSet.html#new/0 [union]: https://hexdocs.pm/elixir/MapSet.html#union/2 [split_with]: https://hexdocs.pm/elixir/MapSet.html#split_with/2 -[filter]: https://hexdocs.pm/elixir/MapSet.html#filter/2 -[reject]: https://hexdocs.pm/elixir/MapSet.html#reject/2 [starts_with]: https://hexdocs.pm/elixir/String.html#starts_with?/2 [enum]: https://hexdocs.pm/elixir/Enum.html [reduce]: https://hexdocs.pm/elixir/Enum.html#reduce/3 diff --git a/exercises/concept/gotta-snatch-em-all/.docs/introduction.md b/exercises/concept/gotta-snatch-em-all/.docs/introduction.md index 10f5d89c9..dcbd3e11e 100644 --- a/exercises/concept/gotta-snatch-em-all/.docs/introduction.md +++ b/exercises/concept/gotta-snatch-em-all/.docs/introduction.md @@ -68,7 +68,7 @@ MapSet.symmetric_difference(b, a) # => MapSet.new([2, 3, 4, 5, 6, 7, 8, 9, 100]) ``` -You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2` (from Elixir 1.15). +You can filter and partition sets with `MapSet.filter/2`, `MapSet.reject/2` and `MapSet.split_with/2`. ```elixir a = MapSet.new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) diff --git a/exercises/concept/gotta-snatch-em-all/.meta/exemplar.ex b/exercises/concept/gotta-snatch-em-all/.meta/exemplar.ex index 972512f9d..bde289d57 100644 --- a/exercises/concept/gotta-snatch-em-all/.meta/exemplar.ex +++ b/exercises/concept/gotta-snatch-em-all/.meta/exemplar.ex @@ -62,24 +62,11 @@ defmodule GottaSnatchEmAll do @spec split_shiny_cards(collection()) :: {[card()], [card()]} def split_shiny_cards(collection) do - {shiny, not_shiny} = split_with(collection, &String.starts_with?(&1, "Shiny")) + {shiny, not_shiny} = MapSet.split_with(collection, &String.starts_with?(&1, "Shiny")) shiny_list = shiny |> MapSet.to_list() |> Enum.sort() not_shiny_list = not_shiny |> MapSet.to_list() |> Enum.sort() {shiny_list, not_shiny_list} end - - # MapSet.split_with/2 was added in Elixir 1.15 - Switch to that when it becomes the minimum version - defp split_with(mapset, predicate) do - init = {MapSet.new(), MapSet.new()} - - Enum.reduce(mapset, init, fn item, {passes, fails} -> - if predicate.(item) do - {MapSet.put(passes, item), fails} - else - {passes, MapSet.put(fails, item)} - end - end) - end end