diff options
Diffstat (limited to 'aoc2023/build/packages')
402 files changed, 0 insertions, 73870 deletions
diff --git a/aoc2023/build/packages/adglent/LICENSE b/aoc2023/build/packages/adglent/LICENSE deleted file mode 100644 index c7c82cc..0000000 --- a/aoc2023/build/packages/adglent/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright 2023 John Björk - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/aoc2023/build/packages/adglent/README.md b/aoc2023/build/packages/adglent/README.md deleted file mode 100644 index fcd81eb..0000000 --- a/aoc2023/build/packages/adglent/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# adglent - -[](https://hex.pm/packages/adglent) -[](https://hexdocs.pm/adglent/) - -## About - -`adglent` is a Gleam library which can be used to setup testing code and a template for implementing solution to [Advent of code](https://adventofcode.com/) problems. - -> NOTE: `adglent` **only** supports `erlang` target (default) for Gleam. - -## Prerequisites - -`adglent` is written in `gleam` and runs and tests solutions written in Gleam. Read more about `gleam` at [gleam.run](https://gleam.run). - -The easiest way to install `gleam` is to use `asdf`: - -1. Install `asdf` according to the instructions at the [asdf website](https://asdf-vm.com/) -2. Install the gleam asdf plugin: `asdf plugin-add gleam` -3. Install the latest `asdf install gleam latest` -4. Use the latest gleam version globally: `asdf global gleam latest` - -> HINT: `asdf` can manage multiple versions of gleam and the version can be set globally and also locally (`asdf local gleam <VERSION>`) to use a specific gleam version in a project. - -## Installation - -Start a new gleam project for your AOC soluctions with `gleam new`. In the project folder run: - -```sh -gleam add --dev adglent -``` - -## Usage - -### Initializing - -First log in to [Advent of code](https://adventofcode.com/) and copy your personal `session-cookie`. The value can be found using developer tools in the browser (in Chrome: "Application->Cookies->https://adventofcode.com->session" and copy the Cookie-value) - -```sh -gleam run -m adglent/init -``` - -Input the AOC year, you personal AOC session cookie and select if `showtime` should be used for tests (otherwise it will assume the project uses `gleeunit` as is default for `gleam new <project>`) - -> NOTE: `showtime` is an alternate gleam test-runner. It is still quite new and havn't been tested in as many project as `gleeunit`. It has a different way of formatting the test-results and also supports the possibility to run specific test-modules (which can be useful in AOC). `showtime` is a standalone project but have been embedded into `adglent`. - -### Add day - -To start working on the solution for a specific day run: - -```sh -gleam run -m adglent/day <NUM> -``` - -Where `<NUM>` is the day number of the day you want to solve a problem for. - -> Example (start solving 1st of December): -> -> ```sh -> gleam run -m adglent/day 1 -> ``` - -Adding a day will add tests in `test/day<NUM>/day<NUM>_test.gleam`and a `src/day<NUM>/solve.gleam` file where the solution can be implemented. - -Furthermore it will also download the input for the problem to `src/day<NUM>/input.txt` - -Before running the tests you need to provide one or more example. These can be found in the problem description for that day at the AOC website. - -Add an example to a part of the problem by adding examples to the `part1_examples` or `part2_examples` lists. - -> Example (input "Hello Joe!" should give answer 613411): -> -> ```gleam -> const part1_examples: List(Example(Problem1AnswerType)) = [ -> Example("Hello Joe!", "613411"), -> ] -> ``` - -The type of the answer for a part can be adjusted if needed by changing the type aliases `Problem1AnswerType` / `Problem2AnswerType`. Note that this will change the type that the `part1` / `part2` functions in `solve.gleam` expect to return. - -### Testing - -To test all days in the project use: - -```sh -gleam test -``` - -If you are using `showtime` you can test a single day by running: - -```sh -gleam test -- --modules=day<NUM>/day<NUM>_test -``` - -> Example (test solution for 1st of December): -> -> ```sh -> gleam test -- modules=day1/day1_test -> ``` - -### Get the answer - -To get the (hopefully correct) answer after the tests are ok run: - -```sh -gleam run -m day<NUM>/solve <PART> -``` - -where `<NUM>` is the day to solve and `<PART>` is the part of the problem (1 or 2) to solve. - -This will run the solver and print the answer to stdout. - -### Module documentation - -Module documentation can be found at <https://hexdocs.pm/adglent>. diff --git a/aoc2023/build/packages/adglent/gleam.toml b/aoc2023/build/packages/adglent/gleam.toml deleted file mode 100644 index e1d81b8..0000000 --- a/aoc2023/build/packages/adglent/gleam.toml +++ /dev/null @@ -1,29 +0,0 @@ -name = "adglent" -version = "1.2.0" - -description = "Advent of code helper - automating setup of tests, solution template and problem input" -licences = ["Apache-2.0"] -repository = { type = "github", user = "JohnBjrk", repo = "adglent" } - -internal_modules = [ - "adglent/priv", - "adglent/priv/*", - "showtime/internal/*", -] -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" -simplifile = "~> 1.0" -gleam_http = "~> 3.5" -gleam_erlang = "~> 0.23.0" -gleam_otp = "~> 0.8.0" -gleam_community_ansi = "~> 1.2" -glint = "~> 0.13.0" -gap = "~> 1.0" -snag = "~> 0.2.0" -tom = "~> 0.2.0" -gleam_httpc = "~> 2.1" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/adglent/include/adglent_Example.hrl b/aoc2023/build/packages/adglent/include/adglent_Example.hrl deleted file mode 100644 index 615e473..0000000 --- a/aoc2023/build/packages/adglent/include/adglent_Example.hrl +++ /dev/null @@ -1 +0,0 @@ --record(example, {input :: binary(), answer :: any()}). diff --git a/aoc2023/build/packages/adglent/include/priv@toml_TomGetError.hrl b/aoc2023/build/packages/adglent/include/priv@toml_TomGetError.hrl deleted file mode 100644 index 4cd5ddd..0000000 --- a/aoc2023/build/packages/adglent/include/priv@toml_TomGetError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(tom_get_error, {error :: tom:get_error()}). diff --git a/aoc2023/build/packages/adglent/include/priv@toml_TomParseError.hrl b/aoc2023/build/packages/adglent/include/priv@toml_TomParseError.hrl deleted file mode 100644 index 7306934..0000000 --- a/aoc2023/build/packages/adglent/include/priv@toml_TomParseError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(tom_parse_error, {error :: tom:parse_error()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_Finished.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_Finished.hrl deleted file mode 100644 index 7d24e52..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_Finished.hrl +++ /dev/null @@ -1 +0,0 @@ --record(finished, {num_modules :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_HandlerState.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_HandlerState.hrl deleted file mode 100644 index 2eceb23..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@common_event_handler_HandlerState.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(handler_state, { - test_state :: showtime@internal@common@common_event_handler:test_state(), - num_done :: integer(), - events :: gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@internal@common@test_suite:test_run())) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ArgList.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ArgList.hrl deleted file mode 100644 index 79f34f8..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ArgList.hrl +++ /dev/null @@ -1 +0,0 @@ --record(arg_list, {arg_list :: list(gleam@dynamic:dynamic_())}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertEqual.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertEqual.hrl deleted file mode 100644 index c6458ba..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertEqual.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(assert_equal, { - details :: list(showtime@internal@common@test_result:reason_detail()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertMatch.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertMatch.hrl deleted file mode 100644 index 4920304..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertMatch.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(assert_match, { - details :: list(showtime@internal@common@test_result:reason_detail()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertNotEqual.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertNotEqual.hrl deleted file mode 100644 index 221c15f..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_AssertNotEqual.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(assert_not_equal, { - details :: list(showtime@internal@common@test_result:reason_detail()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErlangException.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErlangException.hrl deleted file mode 100644 index 9a31ba8..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErlangException.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(erlang_exception, { - class :: showtime@internal@common@test_result:class(), - reason :: showtime@internal@common@test_result:reason(), - stacktrace :: showtime@internal@common@test_result:trace_list(), - output_buffer :: list(binary()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErrorInfo.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErrorInfo.hrl deleted file mode 100644 index 97d0802..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ErrorInfo.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(error_info, { - error_info :: gleam@map:map_(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expected.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expected.hrl deleted file mode 100644 index 5e40ad3..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expected.hrl +++ /dev/null @@ -1 +0,0 @@ --record(expected, {value :: gleam@dynamic:dynamic_()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expression.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expression.hrl deleted file mode 100644 index 7aa0c35..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Expression.hrl +++ /dev/null @@ -1 +0,0 @@ --record(expression, {expression :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_File.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_File.hrl deleted file mode 100644 index 1274b74..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_File.hrl +++ /dev/null @@ -1 +0,0 @@ --record(file, {filename :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GenericException.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GenericException.hrl deleted file mode 100644 index 7c33d0d..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GenericException.hrl +++ /dev/null @@ -1 +0,0 @@ --record(generic_exception, {value :: gleam@dynamic:dynamic_()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamAssert.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamAssert.hrl deleted file mode 100644 index 095748c..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamAssert.hrl +++ /dev/null @@ -1 +0,0 @@ --record(gleam_assert, {value :: gleam@dynamic:dynamic_(), line_no :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamError.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamError.hrl deleted file mode 100644 index 68e6645..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_GleamError.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(gleam_error, { - details :: showtime@internal@common@test_result:gleam_error_detail() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Ignored.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Ignored.hrl deleted file mode 100644 index 87b7e2f..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Ignored.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ignored, {reason :: showtime@internal@common@test_result:ignore_reason()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_LetAssert.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_LetAssert.hrl deleted file mode 100644 index 5f3f60d..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_LetAssert.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(let_assert, { - module :: binary(), - function :: binary(), - line_no :: integer(), - message :: binary(), - value :: gleam@dynamic:dynamic_() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Line.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Line.hrl deleted file mode 100644 index 9807df6..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Line.hrl +++ /dev/null @@ -1 +0,0 @@ --record(line, {line_no :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Module.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Module.hrl deleted file mode 100644 index 8002c0c..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Module.hrl +++ /dev/null @@ -1 +0,0 @@ --record(module, {name :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Num.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Num.hrl deleted file mode 100644 index c36efa3..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Num.hrl +++ /dev/null @@ -1 +0,0 @@ --record(num, {arity :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Pattern.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Pattern.hrl deleted file mode 100644 index 6aa9c84..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Pattern.hrl +++ /dev/null @@ -1 +0,0 @@ --record(pattern, {pattern :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ReasonLine.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ReasonLine.hrl deleted file mode 100644 index b7ad1ab..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_ReasonLine.hrl +++ /dev/null @@ -1 +0,0 @@ --record(reason_line, {line_no :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TestFunctionReturn.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TestFunctionReturn.hrl deleted file mode 100644 index b0bc294..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TestFunctionReturn.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(test_function_return, { - value :: gleam@dynamic:dynamic_(), - output_buffer :: list(binary()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Trace.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Trace.hrl deleted file mode 100644 index 4cb007c..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Trace.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(trace, { - function :: binary(), - arity :: showtime@internal@common@test_result:arity_(), - extra_info :: list(showtime@internal@common@test_result:extra_info()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceList.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceList.hrl deleted file mode 100644 index c1aa9c5..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceList.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(trace_list, { - traces :: list(showtime@internal@common@test_result:trace()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceModule.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceModule.hrl deleted file mode 100644 index 595362f..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_TraceModule.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(trace_module, { - module :: binary(), - function :: binary(), - arity :: showtime@internal@common@test_result:arity_(), - extra_info :: list(showtime@internal@common@test_result:extra_info()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Value.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Value.hrl deleted file mode 100644 index 3a4b0dd..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_result_Value.hrl +++ /dev/null @@ -1 +0,0 @@ --record(value, {value :: gleam@dynamic:dynamic_()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_CompletedTestRun.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_CompletedTestRun.hrl deleted file mode 100644 index 927a0cf..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_CompletedTestRun.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(completed_test_run, { - test_function :: showtime@internal@common@test_suite:test_function(), - total_time :: integer(), - result :: {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()} -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTest.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTest.hrl deleted file mode 100644 index 13df1bf..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTest.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(end_test, { - test_module :: showtime@internal@common@test_suite:test_module(), - test_function :: showtime@internal@common@test_suite:test_function(), - result :: {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()} -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestRun.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestRun.hrl deleted file mode 100644 index 3f78991..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestRun.hrl +++ /dev/null @@ -1 +0,0 @@ --record(end_test_run, {num_modules :: integer()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestSuite.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestSuite.hrl deleted file mode 100644 index a7f37b3..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_EndTestSuite.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(end_test_suite, { - test_module :: showtime@internal@common@test_suite:test_module() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_OngoingTestRun.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_OngoingTestRun.hrl deleted file mode 100644 index f52e5cc..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_OngoingTestRun.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(ongoing_test_run, { - test_function :: showtime@internal@common@test_suite:test_function(), - started_at :: integer() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTest.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTest.hrl deleted file mode 100644 index d532609..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTest.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(start_test, { - test_module :: showtime@internal@common@test_suite:test_module(), - test_function :: showtime@internal@common@test_suite:test_function() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTestSuite.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTestSuite.hrl deleted file mode 100644 index d5a03d3..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_StartTestSuite.hrl +++ /dev/null @@ -1,3 +0,0 @@ --record(start_test_suite, { - test_module :: showtime@internal@common@test_suite:test_module() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestFunction.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestFunction.hrl deleted file mode 100644 index a783ba4..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestFunction.hrl +++ /dev/null @@ -1 +0,0 @@ --record(test_function, {name :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestModule.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestModule.hrl deleted file mode 100644 index ee9baaf..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestModule.hrl +++ /dev/null @@ -1 +0,0 @@ --record(test_module, {name :: binary(), path :: gleam@option:option(binary())}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestSuite.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestSuite.hrl deleted file mode 100644 index 253a946..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@common@test_suite_TestSuite.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(test_suite, { - module :: showtime@internal@common@test_suite:test_module(), - tests :: list(showtime@internal@common@test_suite:test_function()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeft.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeft.hrl deleted file mode 100644 index ca52968..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeft.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(align_left, { - content :: showtime@internal@reports@table:content(), - margin :: integer() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeftOverflow.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeftOverflow.hrl deleted file mode 100644 index 8d5a673..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignLeftOverflow.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(align_left_overflow, { - content :: showtime@internal@reports@table:content(), - margin :: integer() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRight.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRight.hrl deleted file mode 100644 index 7f7a3f0..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRight.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(align_right, { - content :: showtime@internal@reports@table:content(), - margin :: integer() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRightOverflow.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRightOverflow.hrl deleted file mode 100644 index 4fc4536..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_AlignRightOverflow.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(align_right_overflow, { - content :: showtime@internal@reports@table:content(), - margin :: integer() -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Aligned.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Aligned.hrl deleted file mode 100644 index 2343dfd..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Aligned.hrl +++ /dev/null @@ -1 +0,0 @@ --record(aligned, {content :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Content.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Content.hrl deleted file mode 100644 index 044891b..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Content.hrl +++ /dev/null @@ -1 +0,0 @@ --record(content, {unstyled_text :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Separator.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Separator.hrl deleted file mode 100644 index db3f822..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Separator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(separator, {char :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_StyledContent.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_StyledContent.hrl deleted file mode 100644 index ed500df..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_StyledContent.hrl +++ /dev/null @@ -1 +0,0 @@ --record(styled_content, {styled_text :: binary()}). diff --git a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Table.hrl b/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Table.hrl deleted file mode 100644 index 5b41bb1..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@internal@reports@table_Table.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(table, { - header :: gleam@option:option(binary()), - rows :: list(list(showtime@internal@reports@table:col())) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@meta_Meta.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@meta_Meta.hrl deleted file mode 100644 index 14184fb..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@meta_Meta.hrl +++ /dev/null @@ -1 +0,0 @@ --record(meta, {description :: binary(), tags :: list(binary())}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@should_Eq.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@should_Eq.hrl deleted file mode 100644 index 6ebea34..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@should_Eq.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(eq, { - a :: any(), - b :: any(), - meta :: gleam@option:option(showtime@tests@meta:meta()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@should_Fail.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@should_Fail.hrl deleted file mode 100644 index cf06a3c..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@should_Fail.hrl +++ /dev/null @@ -1 +0,0 @@ --record(fail, {meta :: gleam@option:option(showtime@tests@meta:meta())}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@should_IsError.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@should_IsError.hrl deleted file mode 100644 index e9cabf3..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@should_IsError.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(is_error, { - a :: {ok, any()} | {error, any()}, - meta :: gleam@option:option(showtime@tests@meta:meta()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@should_IsOk.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@should_IsOk.hrl deleted file mode 100644 index 37c24ca..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@should_IsOk.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(is_ok, { - a :: {ok, any()} | {error, any()}, - meta :: gleam@option:option(showtime@tests@meta:meta()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@should_NotEq.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@should_NotEq.hrl deleted file mode 100644 index 2a6bf48..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@should_NotEq.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(not_eq, { - a :: any(), - b :: any(), - meta :: gleam@option:option(showtime@tests@meta:meta()) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@test_MetaShould.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@test_MetaShould.hrl deleted file mode 100644 index a814a93..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@test_MetaShould.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(meta_should, { - equal :: fun((any(), any()) -> nil), - not_equal :: fun((any(), any()) -> nil) -}). diff --git a/aoc2023/build/packages/adglent/include/showtime@tests@test_Test.hrl b/aoc2023/build/packages/adglent/include/showtime@tests@test_Test.hrl deleted file mode 100644 index e75a0b7..0000000 --- a/aoc2023/build/packages/adglent/include/showtime@tests@test_Test.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(test, { - meta :: showtime@tests@meta:meta(), - test_function :: fun(() -> nil) -}). diff --git a/aoc2023/build/packages/adglent/src/adglent.app.src b/aoc2023/build/packages/adglent/src/adglent.app.src deleted file mode 100644 index aa44f8b..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.app.src +++ /dev/null @@ -1,45 +0,0 @@ -{application, adglent, [ - {vsn, "1.2.0"}, - {applications, [gap, - gleam_community_ansi, - gleam_erlang, - gleam_http, - gleam_httpc, - gleam_otp, - gleam_stdlib, - gleeunit, - glint, - simplifile, - snag, - tom]}, - {description, "Advent of code helper - automating setup of tests, solution template and problem input"}, - {modules, [adglent, - adglent@day, - adglent@init, - priv@aoc_client, - priv@errors, - priv@prompt, - priv@template, - priv@templates@solution, - priv@templates@test_main, - priv@templates@testfile_gleeunit, - priv@templates@testfile_showtime, - priv@toml, - showtime, - showtime@internal@common@cli, - showtime@internal@common@common_event_handler, - showtime@internal@common@test_result, - showtime@internal@common@test_suite, - showtime@internal@erlang@discover, - showtime@internal@erlang@event_handler, - showtime@internal@erlang@module_handler, - showtime@internal@erlang@runner, - showtime@internal@reports@compare, - showtime@internal@reports@formatter, - showtime@internal@reports@styles, - showtime@internal@reports@table, - showtime@tests@meta, - showtime@tests@should, - showtime@tests@test]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/adglent/src/adglent.erl b/aoc2023/build/packages/adglent/src/adglent.erl deleted file mode 100644 index e9df2b7..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.erl +++ /dev/null @@ -1,55 +0,0 @@ --module(adglent). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([inspect/1, get_input/1, get_test_folder/1, start_arguments/0, get_part/0]). --export_type([example/1, problem/0, charlist/0]). - --type example(OFF) :: {example, binary(), OFF}. - --type problem() :: first | second. - --type charlist() :: any(). - --spec inspect(any()) -> binary(). -inspect(Value) -> - Inspected_value = gleam@string:inspect(Value), - case begin - _pipe = Inspected_value, - gleam@string:starts_with(_pipe, <<"\""/utf8>>) - end of - true -> - _pipe@1 = Inspected_value, - _pipe@2 = gleam@string:drop_left(_pipe@1, 1), - gleam@string:drop_right(_pipe@2, 1); - - false -> - Inspected_value - end. - --spec get_input(binary()) -> {ok, binary()} | {error, simplifile:file_error()}. -get_input(Day) -> - simplifile:read( - <<<<"src/day"/utf8, Day/binary>>/binary, "/input.txt"/utf8>> - ). - --spec get_test_folder(binary()) -> binary(). -get_test_folder(Day) -> - <<"test/day"/utf8, Day/binary>>. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun unicode:characters_to_binary/1). - --spec get_part() -> {ok, problem()} | {error, nil}. -get_part() -> - case start_arguments() of - [<<"1"/utf8>>] -> - {ok, first}; - - [<<"2"/utf8>>] -> - {ok, second}; - - _ -> - {error, nil} - end. diff --git a/aoc2023/build/packages/adglent/src/adglent.gleam b/aoc2023/build/packages/adglent/src/adglent.gleam deleted file mode 100644 index 077d49d..0000000 --- a/aoc2023/build/packages/adglent/src/adglent.gleam +++ /dev/null @@ -1,56 +0,0 @@ -import simplifile.{type FileError} -import gleam/list -import gleam/string - -pub type Example(a) { - Example(input: String, answer: a) -} - -pub fn inspect(value: a) -> String { - let inspected_value = string.inspect(value) - case - inspected_value - |> string.starts_with("\"") - { - True -> - inspected_value - |> string.drop_left(1) - |> string.drop_right(1) - False -> inspected_value - } -} - -pub fn get_input(day: String) -> Result(String, FileError) { - simplifile.read("src/day" <> day <> "/input.txt") -} - -pub fn get_test_folder(day: String) -> String { - "test/day" <> day -} - -pub type Problem { - First - Second -} - -pub fn get_part() -> Result(Problem, Nil) { - case start_arguments() { - ["1"] -> Ok(First) - ["2"] -> Ok(Second) - _ -> Error(Nil) - } -} - -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(to_string) -} - -type Charlist - -/// Transform a charlist to a string -@external(erlang, "unicode", "characters_to_binary") -fn to_string(a: Charlist) -> String - -@external(erlang, "init", "get_plain_arguments") -fn get_start_arguments() -> List(Charlist) diff --git a/aoc2023/build/packages/adglent/src/adglent/day.gleam b/aoc2023/build/packages/adglent/src/adglent/day.gleam deleted file mode 100644 index 69e4ccc..0000000 --- a/aoc2023/build/packages/adglent/src/adglent/day.gleam +++ /dev/null @@ -1,126 +0,0 @@ -import adglent -import gleam/string -import gleam/result -import priv/template -import priv/templates/testfile_gleeunit -import priv/templates/testfile_showtime -import priv/templates/solution -import priv/toml -import priv/aoc_client -import priv/errors -import simplifile - -pub fn main() { - let day = - case adglent.start_arguments() { - [day] -> Ok(day) - args -> Error("Expected day - found: " <> string.join(args, ", ")) - } - |> errors.map_error("Error when parsing command args") - |> errors.print_error - |> errors.assert_ok - - let aoc_toml = - simplifile.read("aoc.toml") - |> errors.map_error("Could not read aoc.toml") - |> errors.print_error - |> errors.assert_ok - - let aoc_toml_version = toml.get_int(aoc_toml, ["version"]) - let year = - toml.get_string(aoc_toml, ["year"]) - |> errors.map_error("Could not read \"year\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - let session = - toml.get_string(aoc_toml, ["session"]) - |> errors.map_error("Could not read \"session\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - - let showtime = case aoc_toml_version { - Ok(2) -> { - toml.get_bool(aoc_toml, ["showtime"]) - |> errors.map_error("Could not read \"showtime\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - } - _ -> - toml.get_string(aoc_toml, ["showtime"]) - |> result.map(fn(bool_string) { - case bool_string { - "True" -> True - _ -> False - } - }) - |> errors.map_error("Could not read \"showtime\" from aoc.toml") - |> errors.print_error - |> errors.assert_ok - } - - let test_folder = adglent.get_test_folder(day) - let test_file = test_folder <> "/day" <> day <> "_test.gleam" - - simplifile.create_directory_all(test_folder) - |> errors.map_error("Could not create folder \"" <> test_folder <> "\"") - |> errors.print_error - |> errors.assert_ok - - let testfile_template = case showtime { - True -> testfile_showtime.template - False -> testfile_gleeunit.template - } - - template.render(testfile_template, [#("day", day)]) - |> create_file_if_not_present(test_file) - |> errors.print_result - |> errors.assert_ok - - let solutions_folder = "src/day" <> day - let solution_file = solutions_folder <> "/solve.gleam" - - simplifile.create_directory_all(solutions_folder) - |> errors.map_error("Could not create folder \"" <> solutions_folder <> "\"") - |> errors.print_error - |> errors.assert_ok - - template.render(solution.template, [#("day", day)]) - |> create_file_if_not_present(solution_file) - |> errors.print_result - |> errors.assert_ok - - create_file_if_not_present("input.txt", solutions_folder <> "/.gitignore") - |> errors.print_result - |> errors.assert_ok - - let input = - aoc_client.get_input(year, day, session) - |> errors.map_error("Error when fetching input") - |> errors.print_error - |> errors.assert_ok - - input - |> string.trim - |> create_file_if_not_present(solutions_folder <> "/input.txt") - |> errors.print_result - |> errors.assert_ok -} - -fn create_file_if_not_present( - content: String, - path: String, -) -> Result(String, String) { - case simplifile.is_file(path) { - True -> { - Ok(path <> " already exists - skipped") - } - False -> { - use _ <- result.try( - simplifile.create_file(path) - |> errors.map_messages("Created " <> path, "Could not create " <> path), - ) - simplifile.write(content, to: path) - |> errors.map_messages("Wrote " <> path, "Could not write to " <> path) - } - } -} diff --git a/aoc2023/build/packages/adglent/src/adglent/init.gleam b/aoc2023/build/packages/adglent/src/adglent/init.gleam deleted file mode 100644 index 42eb833..0000000 --- a/aoc2023/build/packages/adglent/src/adglent/init.gleam +++ /dev/null @@ -1,110 +0,0 @@ -import priv/prompt -import priv/template -import priv/templates/test_main -import priv/errors -import priv/toml -import simplifile -import gleam/string -import gleam/list -import gleam/result -import gleam/bool - -const aoc_toml_template = " -version = {{ version }} -year = \"{{ year }}\" -session = \"{{ session }}\" -showtime = {{ showtime }} -" - -pub fn main() { - let year = prompt.value("Year", "2023", False) - let session = prompt.value("Session Cookie", "", False) - let use_showtime = prompt.confirm("Use showtime", False) - - let aoc_toml_file = "aoc.toml" - let overwrite = case simplifile.create_file(aoc_toml_file) { - Ok(_) -> True - Error(simplifile.Eexist) -> - prompt.confirm("aoc.toml exits - overwrite", False) - _ -> panic as "Could not create aoc.toml" - } - case overwrite { - True -> { - template.render( - aoc_toml_template, - [ - #("version", "2"), - #("year", year), - #("session", session), - #( - "showtime", - bool.to_string(use_showtime) - |> string.lowercase, - ), - ], - ) - |> simplifile.write(to: aoc_toml_file) - |> errors.map_messages( - "aoc.toml - written", - "Error when writing aoc.toml", - ) - } - - False -> Ok("aoc.toml - skipped") - } - |> errors.print_result - - let gleam_toml = - simplifile.read("gleam.toml") - |> errors.map_error("Could not read gleam.toml") - |> errors.print_error - |> errors.assert_ok - - let name = - toml.get_string(gleam_toml, ["name"]) - |> errors.map_error("Could not read \"name\" from gleam.toml") - |> errors.print_error - |> errors.assert_ok - - let test_main_file = "test/" <> name <> "_test.gleam" - - case use_showtime { - True -> { - template.render(test_main.template, []) - |> simplifile.write(to: test_main_file) - |> errors.map_messages( - "Wrote " <> test_main_file, - "Could not write to " <> test_main_file, - ) - } - False -> Ok("Using existing (gleeunit) " <> test_main_file) - } - |> errors.print_result - |> errors.assert_ok - - case simplifile.is_file(".gitignore") { - True -> { - use gitignore <- result.try( - simplifile.read(".gitignore") - |> result.map_error(fn(err) { - "Could not read .gitignore: " <> string.inspect(err) - }), - ) - let aoc_toml_ignored = - string.split(gitignore, "\n") - |> list.find(fn(line) { line == "aoc.toml" }) - case aoc_toml_ignored { - Error(_) -> { - simplifile.append("\naoc.toml", to: ".gitignore") - |> errors.map_messages( - ".gitignore written", - "Error when writing .gitignore", - ) - } - Ok(_) -> Ok(".gitignore - skipped (already configured)") - } - } - False -> Error("Could not find .gitignore") - } - |> errors.print_result -} diff --git a/aoc2023/build/packages/adglent/src/adglent@day.erl b/aoc2023/build/packages/adglent/src/adglent@day.erl deleted file mode 100644 index b80368f..0000000 --- a/aoc2023/build/packages/adglent/src/adglent@day.erl +++ /dev/null @@ -1,278 +0,0 @@ --module(adglent@day). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec create_file_if_not_present(binary(), binary()) -> {ok, binary()} | - {error, binary()}. -create_file_if_not_present(Content, Path) -> - case simplifile:is_file(Path) of - true -> - {ok, <<Path/binary, " already exists - skipped"/utf8>>}; - - false -> - gleam@result:'try'( - begin - _pipe = simplifile:create_file(Path), - priv@errors:map_messages( - _pipe, - <<"Created "/utf8, Path/binary>>, - <<"Could not create "/utf8, Path/binary>> - ) - end, - fun(_) -> _pipe@1 = simplifile:write(Path, Content), - priv@errors:map_messages( - _pipe@1, - <<"Wrote "/utf8, Path/binary>>, - <<"Could not write to "/utf8, Path/binary>> - ) end - ) - end. - --spec main() -> binary(). -main() -> - Day@1 = begin - _pipe = case adglent:start_arguments() of - [Day] -> - {ok, Day}; - - Args -> - {error, - <<"Expected day - found: "/utf8, - (gleam@string:join(Args, <<", "/utf8>>))/binary>>} - end, - _pipe@1 = priv@errors:map_error( - _pipe, - <<"Error when parsing command args"/utf8>> - ), - _pipe@2 = priv@errors:print_error(_pipe@1), - priv@errors:assert_ok(_pipe@2) - end, - Aoc_toml = begin - _pipe@3 = simplifile:read(<<"aoc.toml"/utf8>>), - _pipe@4 = priv@errors:map_error( - _pipe@3, - <<"Could not read aoc.toml"/utf8>> - ), - _pipe@5 = priv@errors:print_error(_pipe@4), - priv@errors:assert_ok(_pipe@5) - end, - Aoc_toml_version = priv@toml:get_int(Aoc_toml, [<<"version"/utf8>>]), - Year = begin - _pipe@6 = priv@toml:get_string(Aoc_toml, [<<"year"/utf8>>]), - _pipe@7 = priv@errors:map_error( - _pipe@6, - <<"Could not read \"year\" from aoc.toml"/utf8>> - ), - _pipe@8 = priv@errors:print_error(_pipe@7), - priv@errors:assert_ok(_pipe@8) - end, - Session = begin - _pipe@9 = priv@toml:get_string(Aoc_toml, [<<"session"/utf8>>]), - _pipe@10 = priv@errors:map_error( - _pipe@9, - <<"Could not read \"session\" from aoc.toml"/utf8>> - ), - _pipe@11 = priv@errors:print_error(_pipe@10), - priv@errors:assert_ok(_pipe@11) - end, - Showtime = case Aoc_toml_version of - {ok, 2} -> - _pipe@12 = priv@toml:get_bool(Aoc_toml, [<<"showtime"/utf8>>]), - _pipe@13 = priv@errors:map_error( - _pipe@12, - <<"Could not read \"showtime\" from aoc.toml"/utf8>> - ), - _pipe@14 = priv@errors:print_error(_pipe@13), - priv@errors:assert_ok(_pipe@14); - - _ -> - _pipe@15 = priv@toml:get_string(Aoc_toml, [<<"showtime"/utf8>>]), - _pipe@16 = gleam@result:map( - _pipe@15, - fun(Bool_string) -> case Bool_string of - <<"True"/utf8>> -> - true; - - _ -> - false - end end - ), - _pipe@17 = priv@errors:map_error( - _pipe@16, - <<"Could not read \"showtime\" from aoc.toml"/utf8>> - ), - _pipe@18 = priv@errors:print_error(_pipe@17), - priv@errors:assert_ok(_pipe@18) - end, - Test_folder = adglent:get_test_folder(Day@1), - Test_file = <<<<<<Test_folder/binary, "/day"/utf8>>/binary, Day@1/binary>>/binary, - "_test.gleam"/utf8>>, - _pipe@19 = simplifile:create_directory_all(Test_folder), - _pipe@20 = priv@errors:map_error( - _pipe@19, - <<<<"Could not create folder \""/utf8, Test_folder/binary>>/binary, - "\""/utf8>> - ), - _pipe@21 = priv@errors:print_error(_pipe@20), - priv@errors:assert_ok(_pipe@21), - Testfile_template = case Showtime of - true -> - <<" -import gleam/list -import showtime/tests/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -"/utf8>>; - - false -> - <<" -import gleam/list -import gleeunit/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -"/utf8>> - end, - _pipe@22 = priv@template:render( - Testfile_template, - [{<<"day"/utf8>>, Day@1}] - ), - _pipe@23 = create_file_if_not_present(_pipe@22, Test_file), - _pipe@24 = priv@errors:print_result(_pipe@23), - priv@errors:assert_ok(_pipe@24), - Solutions_folder = <<"src/day"/utf8, Day@1/binary>>, - Solution_file = <<Solutions_folder/binary, "/solve.gleam"/utf8>>, - _pipe@25 = simplifile:create_directory_all(Solutions_folder), - _pipe@26 = priv@errors:map_error( - _pipe@25, - <<<<"Could not create folder \""/utf8, Solutions_folder/binary>>/binary, - "\""/utf8>> - ), - _pipe@27 = priv@errors:print_error(_pipe@26), - priv@errors:assert_ok(_pipe@27), - _pipe@28 = priv@template:render( - <<" -import adglent.{First, Second} -import gleam/io - -pub fn part1(input: String) { - todo as \"Implement solution to part 1\" -} - -pub fn part2(input: String) { - todo as \"Implement solution to part 2\" -} - -pub fn main() { - let assert Ok(part) = adglent.get_part() - let assert Ok(input) = adglent.get_input(\"{{ day }}\") - case part { - First -> - part1(input) - |> adglent.inspect - |> io.println - Second -> - part2(input) - |> adglent.inspect - |> io.println - } -} -"/utf8>>, - [{<<"day"/utf8>>, Day@1}] - ), - _pipe@29 = create_file_if_not_present(_pipe@28, Solution_file), - _pipe@30 = priv@errors:print_result(_pipe@29), - priv@errors:assert_ok(_pipe@30), - _pipe@31 = create_file_if_not_present( - <<"input.txt"/utf8>>, - <<Solutions_folder/binary, "/.gitignore"/utf8>> - ), - _pipe@32 = priv@errors:print_result(_pipe@31), - priv@errors:assert_ok(_pipe@32), - Input = begin - _pipe@33 = priv@aoc_client:get_input(Year, Day@1, Session), - _pipe@34 = priv@errors:map_error( - _pipe@33, - <<"Error when fetching input"/utf8>> - ), - _pipe@35 = priv@errors:print_error(_pipe@34), - priv@errors:assert_ok(_pipe@35) - end, - _pipe@36 = Input, - _pipe@37 = gleam@string:trim(_pipe@36), - _pipe@38 = create_file_if_not_present( - _pipe@37, - <<Solutions_folder/binary, "/input.txt"/utf8>> - ), - _pipe@39 = priv@errors:print_result(_pipe@38), - priv@errors:assert_ok(_pipe@39). diff --git a/aoc2023/build/packages/adglent/src/adglent@init.erl b/aoc2023/build/packages/adglent/src/adglent@init.erl deleted file mode 100644 index fb28101..0000000 --- a/aoc2023/build/packages/adglent/src/adglent@init.erl +++ /dev/null @@ -1,142 +0,0 @@ --module(adglent@init). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec main() -> {ok, binary()} | {error, binary()}. -main() -> - Year = priv@prompt:value(<<"Year"/utf8>>, <<"2023"/utf8>>, false), - Session = priv@prompt:value(<<"Session Cookie"/utf8>>, <<""/utf8>>, false), - Use_showtime = priv@prompt:confirm(<<"Use showtime"/utf8>>, false), - Aoc_toml_file = <<"aoc.toml"/utf8>>, - Overwrite = case simplifile:create_file(Aoc_toml_file) of - {ok, _} -> - true; - - {error, eexist} -> - priv@prompt:confirm(<<"aoc.toml exits - overwrite"/utf8>>, false); - - _ -> - erlang:error(#{gleam_error => panic, - message => <<"Could not create aoc.toml"/utf8>>, - module => <<"adglent/init"/utf8>>, - function => <<"main"/utf8>>, - line => 29}) - end, - _pipe@3 = case Overwrite of - true -> - _pipe@1 = priv@template:render( - <<" -version = {{ version }} -year = \"{{ year }}\" -session = \"{{ session }}\" -showtime = {{ showtime }} -"/utf8>>, - [{<<"version"/utf8>>, <<"2"/utf8>>}, - {<<"year"/utf8>>, Year}, - {<<"session"/utf8>>, Session}, - {<<"showtime"/utf8>>, - begin - _pipe = gleam@bool:to_string(Use_showtime), - gleam@string:lowercase(_pipe) - end}] - ), - _pipe@2 = simplifile:write(Aoc_toml_file, _pipe@1), - priv@errors:map_messages( - _pipe@2, - <<"aoc.toml - written"/utf8>>, - <<"Error when writing aoc.toml"/utf8>> - ); - - false -> - {ok, <<"aoc.toml - skipped"/utf8>>} - end, - priv@errors:print_result(_pipe@3), - Gleam_toml = begin - _pipe@4 = simplifile:read(<<"gleam.toml"/utf8>>), - _pipe@5 = priv@errors:map_error( - _pipe@4, - <<"Could not read gleam.toml"/utf8>> - ), - _pipe@6 = priv@errors:print_error(_pipe@5), - priv@errors:assert_ok(_pipe@6) - end, - Name = begin - _pipe@7 = priv@toml:get_string(Gleam_toml, [<<"name"/utf8>>]), - _pipe@8 = priv@errors:map_error( - _pipe@7, - <<"Could not read \"name\" from gleam.toml"/utf8>> - ), - _pipe@9 = priv@errors:print_error(_pipe@8), - priv@errors:assert_ok(_pipe@9) - end, - Test_main_file = <<<<"test/"/utf8, Name/binary>>/binary, - "_test.gleam"/utf8>>, - _pipe@12 = case Use_showtime of - true -> - _pipe@10 = priv@template:render( - <<" -import showtime - -pub fn main() { - showtime.main() -} -"/utf8>>, - [] - ), - _pipe@11 = simplifile:write(Test_main_file, _pipe@10), - priv@errors:map_messages( - _pipe@11, - <<"Wrote "/utf8, Test_main_file/binary>>, - <<"Could not write to "/utf8, Test_main_file/binary>> - ); - - false -> - {ok, <<"Using existing (gleeunit) "/utf8, Test_main_file/binary>>} - end, - _pipe@13 = priv@errors:print_result(_pipe@12), - priv@errors:assert_ok(_pipe@13), - _pipe@17 = case simplifile:is_file(<<".gitignore"/utf8>>) of - true -> - gleam@result:'try'( - begin - _pipe@14 = simplifile:read(<<".gitignore"/utf8>>), - gleam@result:map_error( - _pipe@14, - fun(Err) -> - <<"Could not read .gitignore: "/utf8, - (gleam@string:inspect(Err))/binary>> - end - ) - end, - fun(Gitignore) -> - Aoc_toml_ignored = begin - _pipe@15 = gleam@string:split(Gitignore, <<"\n"/utf8>>), - gleam@list:find( - _pipe@15, - fun(Line) -> Line =:= <<"aoc.toml"/utf8>> end - ) - end, - case Aoc_toml_ignored of - {error, _} -> - _pipe@16 = simplifile:append( - <<".gitignore"/utf8>>, - <<"\naoc.toml"/utf8>> - ), - priv@errors:map_messages( - _pipe@16, - <<".gitignore written"/utf8>>, - <<"Error when writing .gitignore"/utf8>> - ); - - {ok, _} -> - {ok, - <<".gitignore - skipped (already configured)"/utf8>>} - end - end - ); - - false -> - {error, <<"Could not find .gitignore"/utf8>>} - end, - priv@errors:print_result(_pipe@17). diff --git a/aoc2023/build/packages/adglent/src/adglent_ffi.erl b/aoc2023/build/packages/adglent/src/adglent_ffi.erl deleted file mode 100644 index a6a92e6..0000000 --- a/aoc2023/build/packages/adglent/src/adglent_ffi.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(adglent_ffi). - --export([get_line/1]). - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. diff --git a/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam b/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam deleted file mode 100644 index e18bafa..0000000 --- a/aoc2023/build/packages/adglent/src/priv/aoc_client.gleam +++ /dev/null @@ -1,37 +0,0 @@ -import gleam/result.{try} -import gleam/httpc -import gleam/http/request -import gleam/int -import gleam/string - -pub fn get_input( - year: String, - day: String, - session: String, -) -> Result(String, String) { - let url = "https://adventofcode.com/" <> year <> "/day/" <> day <> "/input" - use request <- try( - request.to(url) - |> result.map_error(fn(error) { - "Could not create request for \"" <> url <> "\": " <> string.inspect( - error, - ) - }), - ) - - // Send the HTTP request to the server - use response <- try( - request - |> request.prepend_header("Accept", "application/json") - |> request.prepend_header("Cookie", "session=" <> session <> ";") - |> httpc.send - |> result.map_error(fn(error) { - "Error when requesting \"" <> url <> "\": " <> string.inspect(error) - }), - ) - - case response.status { - status if status >= 200 && status < 300 -> Ok(response.body) - status -> Error(int.to_string(status) <> " - " <> response.body) - } -} diff --git a/aoc2023/build/packages/adglent/src/priv/errors.gleam b/aoc2023/build/packages/adglent/src/priv/errors.gleam deleted file mode 100644 index 14c35ca..0000000 --- a/aoc2023/build/packages/adglent/src/priv/errors.gleam +++ /dev/null @@ -1,54 +0,0 @@ -import gleam/result -import gleam/string -import gleam/io - -pub fn map_messages( - result: Result(a, b), - success_message: String, - error_message: String, -) -> Result(String, String) { - result - |> result.map_error(fn(error) { - "Error - " <> error_message <> ": " <> string.inspect(error) - }) - |> result.replace(success_message) -} - -pub fn map_error( - result: Result(a, b), - error_message: String, -) -> Result(a, String) { - result - |> result.map_error(fn(error) { - error_message <> ": " <> string.inspect(error) - }) -} - -pub fn print_result(result: Result(String, String)) { - result - |> result.unwrap_both - |> io.println - result -} - -pub fn print_error(result: Result(a, String)) { - result - |> result.map_error(fn(err) { - io.println(err) - err - }) -} - -pub fn assert_ok(result: Result(a, String)) { - let assert Ok(value) = - result - |> result.map_error(fn(err) { - halt(1) - err - }) - value -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil diff --git a/aoc2023/build/packages/adglent/src/priv/prompt.gleam b/aoc2023/build/packages/adglent/src/priv/prompt.gleam deleted file mode 100644 index 6cee35a..0000000 --- a/aoc2023/build/packages/adglent/src/priv/prompt.gleam +++ /dev/null @@ -1,38 +0,0 @@ -import gleam/result -import gleam/string - -pub fn confirm(message: String, auto_accept: Bool) -> Bool { - auto_accept || case - get_line(message <> "? (Y/N): ") - |> result.unwrap("n") - |> string.trim() - { - "Y" | "y" -> True - _ -> False - } -} - -pub fn value(message: String, default: String, auto_accept: Bool) -> String { - case get_value_of_default(message, default, auto_accept) { - "" -> default - value -> value - } -} - -fn get_value_of_default(message: String, default: String, auto_accept: Bool) { - case auto_accept { - True -> default - False -> - get_line(message <> "? (" <> default <> "): ") - |> result.unwrap("") - |> string.trim() - } -} - -pub type GetLineError { - Eof - NoData -} - -@external(erlang, "adglent_ffi", "get_line") -pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) diff --git a/aoc2023/build/packages/adglent/src/priv/template.gleam b/aoc2023/build/packages/adglent/src/priv/template.gleam deleted file mode 100644 index e946888..0000000 --- a/aoc2023/build/packages/adglent/src/priv/template.gleam +++ /dev/null @@ -1,18 +0,0 @@ -import gleam/list -import gleam/string - -pub fn render( - template: String, - substitutions: List(#(String, String)), -) -> String { - substitutions - |> list.fold( - template, - fn(template, substitution) { - let #(name, value) = substitution - template - |> string.replace("{{ " <> name <> " }}", value) - }, - ) - |> string.trim <> "\n" -} diff --git a/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam b/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam deleted file mode 100644 index 96085c3..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/solution.gleam +++ /dev/null @@ -1,27 +0,0 @@ -pub const template = " -import adglent.{First, Second} -import gleam/io - -pub fn part1(input: String) { - todo as \"Implement solution to part 1\" -} - -pub fn part2(input: String) { - todo as \"Implement solution to part 2\" -} - -pub fn main() { - let assert Ok(part) = adglent.get_part() - let assert Ok(input) = adglent.get_input(\"{{ day }}\") - case part { - First -> - part1(input) - |> adglent.inspect - |> io.println - Second -> - part2(input) - |> adglent.inspect - |> io.println - } -} -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam b/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam deleted file mode 100644 index 27548d3..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/test_main.gleam +++ /dev/null @@ -1,7 +0,0 @@ -pub const template = " -import showtime - -pub fn main() { - showtime.main() -} -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam b/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam deleted file mode 100644 index a1d56f6..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/testfile_gleeunit.gleam +++ /dev/null @@ -1,41 +0,0 @@ -pub const template = " -import gleam/list -import gleeunit/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -" diff --git a/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam b/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam deleted file mode 100644 index 699feb2..0000000 --- a/aoc2023/build/packages/adglent/src/priv/templates/testfile_showtime.gleam +++ /dev/null @@ -1,41 +0,0 @@ -pub const template = " -import gleam/list -import showtime/tests/should -import adglent.{type Example, Example} -import day{{ day }}/solve - -type Problem1AnswerType = - String - -type Problem2AnswerType = - String - -/// Add examples for part 1 here: -/// ```gleam -///const part1_examples: List(Example(Problem1AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part1_examples: List(Example(Problem1AnswerType)) = [] - -/// Add examples for part 2 here: -/// ```gleam -///const part2_examples: List(Example(Problem2AnswerType)) = [Example(\"some input\", \"\")] -/// ``` -const part2_examples: List(Example(Problem2AnswerType)) = [] - -pub fn part1_test() { - part1_examples - |> should.not_equal([]) - use example <- list.map(part1_examples) - solve.part1(example.input) - |> should.equal(example.answer) -} - -pub fn part2_test() { - part2_examples - |> should.not_equal([]) - use example <- list.map(part2_examples) - solve.part2(example.input) - |> should.equal(example.answer) -} - -" diff --git a/aoc2023/build/packages/adglent/src/priv/toml.gleam b/aoc2023/build/packages/adglent/src/priv/toml.gleam deleted file mode 100644 index 7042833..0000000 --- a/aoc2023/build/packages/adglent/src/priv/toml.gleam +++ /dev/null @@ -1,52 +0,0 @@ -import tom -import gleam/result - -pub type TomError { - TomParseError(error: tom.ParseError) - TomGetError(error: tom.GetError) -} - -pub fn get_string( - toml_content: String, - key_path: List(String), -) -> Result(String, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_string(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} - -pub fn get_bool( - toml_content: String, - key_path: List(String), -) -> Result(Bool, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_bool(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} - -pub fn get_int( - toml_content: String, - key_path: List(String), -) -> Result(Int, TomError) { - use toml <- result.try( - tom.parse(toml_content <> "\n") - |> result.map_error(TomParseError), - ) - use value <- result.try( - tom.get_int(toml, key_path) - |> result.map_error(TomGetError), - ) - Ok(value) -} diff --git a/aoc2023/build/packages/adglent/src/priv@aoc_client.erl b/aoc2023/build/packages/adglent/src/priv@aoc_client.erl deleted file mode 100644 index 1acb9b5..0000000 --- a/aoc2023/build/packages/adglent/src/priv@aoc_client.erl +++ /dev/null @@ -1,61 +0,0 @@ --module(priv@aoc_client). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_input/3]). - --spec get_input(binary(), binary(), binary()) -> {ok, binary()} | - {error, binary()}. -get_input(Year, Day, Session) -> - Url = <<<<<<<<"https://adventofcode.com/"/utf8, Year/binary>>/binary, - "/day/"/utf8>>/binary, - Day/binary>>/binary, - "/input"/utf8>>, - gleam@result:'try'( - begin - _pipe = gleam@http@request:to(Url), - gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<<<"Could not create request for \""/utf8, Url/binary>>/binary, - "\": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ) - end, - fun(Request) -> - gleam@result:'try'( - begin - _pipe@1 = Request, - _pipe@2 = gleam@http@request:prepend_header( - _pipe@1, - <<"Accept"/utf8>>, - <<"application/json"/utf8>> - ), - _pipe@3 = gleam@http@request:prepend_header( - _pipe@2, - <<"Cookie"/utf8>>, - <<<<"session="/utf8, Session/binary>>/binary, ";"/utf8>> - ), - _pipe@4 = gleam@httpc:send(_pipe@3), - gleam@result:map_error( - _pipe@4, - fun(Error@1) -> - <<<<<<"Error when requesting \""/utf8, Url/binary>>/binary, - "\": "/utf8>>/binary, - (gleam@string:inspect(Error@1))/binary>> - end - ) - end, - fun(Response) -> case erlang:element(2, Response) of - Status when (Status >= 200) andalso (Status < 300) -> - {ok, erlang:element(4, Response)}; - - Status@1 -> - {error, - <<<<(gleam@int:to_string(Status@1))/binary, - " - "/utf8>>/binary, - (erlang:element(4, Response))/binary>>} - end end - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/priv@errors.erl b/aoc2023/build/packages/adglent/src/priv@errors.erl deleted file mode 100644 index 978c675..0000000 --- a/aoc2023/build/packages/adglent/src/priv@errors.erl +++ /dev/null @@ -1,74 +0,0 @@ --module(priv@errors). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([map_messages/3, map_error/2, print_result/1, print_error/1, assert_ok/1]). - --spec map_messages({ok, any()} | {error, any()}, binary(), binary()) -> {ok, - binary()} | - {error, binary()}. -map_messages(Result, Success_message, Error_message) -> - _pipe = Result, - _pipe@1 = gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<<<"Error - "/utf8, Error_message/binary>>/binary, ": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ), - gleam@result:replace(_pipe@1, Success_message). - --spec map_error({ok, NIB} | {error, any()}, binary()) -> {ok, NIB} | - {error, binary()}. -map_error(Result, Error_message) -> - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Error) -> - <<<<Error_message/binary, ": "/utf8>>/binary, - (gleam@string:inspect(Error))/binary>> - end - ). - --spec print_result({ok, binary()} | {error, binary()}) -> {ok, binary()} | - {error, binary()}. -print_result(Result) -> - _pipe = Result, - _pipe@1 = gleam@result:unwrap_both(_pipe), - gleam@io:println(_pipe@1), - Result. - --spec print_error({ok, NIK} | {error, binary()}) -> {ok, NIK} | - {error, binary()}. -print_error(Result) -> - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Err) -> - gleam@io:println(Err), - Err - end - ). - --spec assert_ok({ok, NIO} | {error, binary()}) -> NIO. -assert_ok(Result) -> - _assert_subject = begin - _pipe = Result, - gleam@result:map_error( - _pipe, - fun(Err) -> - erlang:halt(1), - Err - end - ) - end, - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"priv/errors"/utf8>>, - function => <<"assert_ok"/utf8>>, - line => 43}) - end, - Value. diff --git a/aoc2023/build/packages/adglent/src/priv@prompt.erl b/aoc2023/build/packages/adglent/src/priv@prompt.erl deleted file mode 100644 index 0277f14..0000000 --- a/aoc2023/build/packages/adglent/src/priv@prompt.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(priv@prompt). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_line/1, confirm/2, value/3]). --export_type([get_line_error/0]). - --type get_line_error() :: eof | no_data. - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Prompt) -> - adglent_ffi:get_line(Prompt). - --spec confirm(binary(), boolean()) -> boolean(). -confirm(Message, Auto_accept) -> - Auto_accept orelse case begin - _pipe = adglent_ffi:get_line(<<Message/binary, "? (Y/N): "/utf8>>), - _pipe@1 = gleam@result:unwrap(_pipe, <<"n"/utf8>>), - gleam@string:trim(_pipe@1) - end of - <<"Y"/utf8>> -> - true; - - <<"y"/utf8>> -> - true; - - _ -> - false - end. - --spec get_value_of_default(binary(), binary(), boolean()) -> binary(). -get_value_of_default(Message, Default, Auto_accept) -> - case Auto_accept of - true -> - Default; - - false -> - _pipe = adglent_ffi:get_line( - <<<<<<Message/binary, "? ("/utf8>>/binary, Default/binary>>/binary, - "): "/utf8>> - ), - _pipe@1 = gleam@result:unwrap(_pipe, <<""/utf8>>), - gleam@string:trim(_pipe@1) - end. - --spec value(binary(), binary(), boolean()) -> binary(). -value(Message, Default, Auto_accept) -> - case get_value_of_default(Message, Default, Auto_accept) of - <<""/utf8>> -> - Default; - - Value -> - Value - end. diff --git a/aoc2023/build/packages/adglent/src/priv@template.erl b/aoc2023/build/packages/adglent/src/priv@template.erl deleted file mode 100644 index 6a5d0bf..0000000 --- a/aoc2023/build/packages/adglent/src/priv@template.erl +++ /dev/null @@ -1,25 +0,0 @@ --module(priv@template). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([render/2]). - --spec render(binary(), list({binary(), binary()})) -> binary(). -render(Template, Substitutions) -> - <<(begin - _pipe = Substitutions, - _pipe@2 = gleam@list:fold( - _pipe, - Template, - fun(Template@1, Substitution) -> - {Name, Value} = Substitution, - _pipe@1 = Template@1, - gleam@string:replace( - _pipe@1, - <<<<"{{ "/utf8, Name/binary>>/binary, " }}"/utf8>>, - Value - ) - end - ), - gleam@string:trim(_pipe@2) - end)/binary, - "\n"/utf8>>. diff --git a/aoc2023/build/packages/adglent/src/priv@templates@solution.erl b/aoc2023/build/packages/adglent/src/priv@templates@solution.erl deleted file mode 100644 index 7e36387..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@solution.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@solution). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl b/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl deleted file mode 100644 index ca6b127..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@test_main.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@test_main). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl b/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl deleted file mode 100644 index 2f5a41e..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@testfile_gleeunit.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@testfile_gleeunit). diff --git a/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl b/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl deleted file mode 100644 index bbbc8b2..0000000 --- a/aoc2023/build/packages/adglent/src/priv@templates@testfile_showtime.erl +++ /dev/null @@ -1 +0,0 @@ --module(priv@templates@testfile_showtime). diff --git a/aoc2023/build/packages/adglent/src/priv@toml.erl b/aoc2023/build/packages/adglent/src/priv@toml.erl deleted file mode 100644 index 6c41fbf..0000000 --- a/aoc2023/build/packages/adglent/src/priv@toml.erl +++ /dev/null @@ -1,83 +0,0 @@ --module(priv@toml). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_string/2, get_bool/2, get_int/2]). --export_type([tom_error/0]). - --type tom_error() :: {tom_parse_error, tom:parse_error()} | - {tom_get_error, tom:get_error()}. - --spec get_string(binary(), list(binary())) -> {ok, binary()} | - {error, tom_error()}. -get_string(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_string(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). - --spec get_bool(binary(), list(binary())) -> {ok, boolean()} | - {error, tom_error()}. -get_bool(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_bool(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). - --spec get_int(binary(), list(binary())) -> {ok, integer()} | - {error, tom_error()}. -get_int(Toml_content, Key_path) -> - gleam@result:'try'( - begin - _pipe = tom:parse(<<Toml_content/binary, "\n"/utf8>>), - gleam@result:map_error( - _pipe, - fun(Field@0) -> {tom_parse_error, Field@0} end - ) - end, - fun(Toml) -> - gleam@result:'try'( - begin - _pipe@1 = tom:get_int(Toml, Key_path), - gleam@result:map_error( - _pipe@1, - fun(Field@0) -> {tom_get_error, Field@0} end - ) - end, - fun(Value) -> {ok, Value} end - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime.erl b/aoc2023/build/packages/adglent/src/showtime.erl deleted file mode 100644 index 721bad4..0000000 --- a/aoc2023/build/packages/adglent/src/showtime.erl +++ /dev/null @@ -1,155 +0,0 @@ --module(showtime). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec mk_runner( - fun((gleam@option:option(list(binary())), list(binary()), showtime@internal@common@cli:capture()) -> OBY), - glint:command_input() -) -> OBY. -mk_runner(Func, Command) -> - _assert_subject = begin - _pipe = erlang:element(3, Command), - _pipe@1 = glint@flag:get_strings(_pipe, <<"modules"/utf8>>), - gleam@result:map(_pipe@1, fun(Modules) -> case Modules of - [] -> - none; - - Modules@1 -> - {some, Modules@1} - end end) - end, - {ok, Module_list} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 91}) - end, - _assert_subject@1 = begin - _pipe@2 = erlang:element(3, Command), - glint@flag:get_strings(_pipe@2, <<"ignore"/utf8>>) - end, - {ok, Ignore_tags} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 100}) - end, - _assert_subject@2 = begin - _pipe@3 = erlang:element(3, Command), - _pipe@4 = glint@flag:get_string(_pipe@3, <<"capture"/utf8>>), - _pipe@5 = gleam@result:map( - _pipe@4, - fun(Arg) -> gleam@string:lowercase(Arg) end - ), - gleam@result:map(_pipe@5, fun(Arg@1) -> case Arg@1 of - <<"no"/utf8>> -> - no; - - <<"yes"/utf8>> -> - yes; - - <<"mixed"/utf8>> -> - mixed - end end) - end, - {ok, Capture_output} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"showtime"/utf8>>, - function => <<"mk_runner"/utf8>>, - line => 104}) - end, - Func(Module_list, Ignore_tags, Capture_output). - --spec start_with_args( - list(binary()), - fun((gleam@option:option(list(binary())), list(binary()), showtime@internal@common@cli:capture()) -> any()) -) -> nil. -start_with_args(Args, Func) -> - Modules_flag = begin - _pipe = glint@flag:string_list(), - _pipe@1 = glint@flag:default(_pipe, []), - glint@flag:description( - _pipe@1, - <<"Run only tests in the modules in this list"/utf8>> - ) - end, - Ignore_flag = begin - _pipe@2 = glint@flag:string_list(), - _pipe@3 = glint@flag:default(_pipe@2, []), - glint@flag:description( - _pipe@3, - <<"Ignore tests that are have tags matching a tag in this list"/utf8>> - ) - end, - Capture_flag = begin - _pipe@4 = glint@flag:string(), - _pipe@5 = glint@flag:default(_pipe@4, <<"no"/utf8>>), - _pipe@6 = glint@flag:constraint( - _pipe@5, - glint@flag@constraint:one_of( - [<<"yes"/utf8>>, <<"no"/utf8>>, <<"mixed"/utf8>>] - ) - ), - glint@flag:description( - _pipe@6, - <<"Capture output: no (default) - output when tests are run, yes - output is captured and shown in report, mixed - output when run and in report"/utf8>> - ) - end, - _pipe@7 = glint:new(), - _pipe@12 = glint:add( - _pipe@7, - [], - begin - _pipe@8 = glint:command( - fun(_capture) -> mk_runner(Func, _capture) end - ), - _pipe@9 = glint:flag(_pipe@8, <<"modules"/utf8>>, Modules_flag), - _pipe@10 = glint:flag(_pipe@9, <<"ignore"/utf8>>, Ignore_flag), - _pipe@11 = glint:flag(_pipe@10, <<"capture"/utf8>>, Capture_flag), - glint:description(_pipe@11, <<"Runs test"/utf8>>) - end - ), - _pipe@13 = glint:with_pretty_help(_pipe@12, glint:default_pretty_help()), - glint:run(_pipe@13, Args). - --spec main() -> nil. -main() -> - start_with_args( - gleam@erlang:start_arguments(), - fun(Module_list, Ignore_tags, Capture) -> - Test_event_handler = showtime@internal@erlang@event_handler:start(), - Test_module_handler = showtime@internal@erlang@module_handler:start( - Test_event_handler, - fun showtime@internal@erlang@discover:collect_test_functions/1, - fun showtime@internal@erlang@runner:run_test_suite/4, - Ignore_tags, - Capture - ), - Test_event_handler(start_test_run), - Modules = showtime@internal@erlang@discover:collect_modules( - Test_module_handler, - Module_list - ), - Test_event_handler( - {end_test_run, - begin - _pipe = Modules, - gleam@list:length(_pipe) - end} - ), - nil - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime.gleam b/aoc2023/build/packages/adglent/src/showtime.gleam deleted file mode 100644 index f0401c9..0000000 --- a/aoc2023/build/packages/adglent/src/showtime.gleam +++ /dev/null @@ -1,116 +0,0 @@ -import glint.{type CommandInput, flag} -import glint/flag -import glint/flag/constraint.{one_of} -import gleam/result -import gleam/string -import showtime/internal/common/cli.{Mixed, No, Yes} -@target(erlang) -import gleam/list -@target(erlang) -import gleam/option.{None, Some} -@target(erlang) -import gleam/erlang.{start_arguments} -@target(erlang) -import showtime/internal/common/test_suite.{EndTestRun, StartTestRun} -@target(erlang) -import showtime/internal/erlang/event_handler -@target(erlang) -import showtime/internal/erlang/module_handler -@target(erlang) -import showtime/internal/erlang/runner -@target(erlang) -import showtime/internal/erlang/discover.{ - collect_modules, collect_test_functions, -} - -// @target(javascript) -// import gleam/io - -@target(erlang) -pub fn main() { - use module_list, ignore_tags, capture <- start_with_args(start_arguments()) - // Start event handler which will collect test-results and eventually - // print test report - let test_event_handler = event_handler.start() - // Start module handler which receives msg about modules to test and - // runs the test-suite for the module - let test_module_handler = - module_handler.start( - test_event_handler, - collect_test_functions, - runner.run_test_suite, - ignore_tags, - capture, - ) - - test_event_handler(StartTestRun) - // Collect modules and notify the module handler to start the test-suites - let modules = collect_modules(test_module_handler, module_list) - test_event_handler(EndTestRun( - modules - |> list.length(), - )) - Nil -} - -fn start_with_args(args, func) { - let modules_flag = - flag.string_list() - |> flag.default([]) - |> flag.description("Run only tests in the modules in this list") - - let ignore_flag = - flag.string_list() - |> flag.default([]) - |> flag.description( - "Ignore tests that are have tags matching a tag in this list", - ) - - let capture_flag = - flag.string() - |> flag.default("no") - |> flag.constraint(one_of(["yes", "no", "mixed"])) - |> flag.description( - "Capture output: no (default) - output when tests are run, yes - output is captured and shown in report, mixed - output when run and in report", - ) - - glint.new() - |> glint.add( - at: [], - do: glint.command(mk_runner(func, _)) - |> glint.flag("modules", modules_flag) - |> glint.flag("ignore", ignore_flag) - |> glint.flag("capture", capture_flag) - |> glint.description("Runs test"), - ) - |> glint.with_pretty_help(glint.default_pretty_help()) - |> glint.run(args) -} - -fn mk_runner(func, command: CommandInput) { - let assert Ok(module_list) = - command.flags - |> flag.get_strings("modules") - |> result.map(fn(modules) { - case modules { - [] -> None - modules -> Some(modules) - } - }) - let assert Ok(ignore_tags) = - command.flags - |> flag.get_strings("ignore") - - let assert Ok(capture_output) = - command.flags - |> flag.get_string("capture") - |> result.map(fn(arg) { string.lowercase(arg) }) - |> result.map(fn(arg) { - case arg { - "no" -> No - "yes" -> Yes - "mixed" -> Mixed - } - }) - func(module_list, ignore_tags, capture_output) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam deleted file mode 100644 index 1c03211..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam +++ /dev/null @@ -1,5 +0,0 @@ -pub type Capture { - Yes - No - Mixed -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam deleted file mode 100644 index b90af14..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam +++ /dev/null @@ -1,101 +0,0 @@ -import gleam/map.{type Map} -import showtime/internal/common/test_suite.{ - type TestEvent, type TestRun, CompletedTestRun, EndTest, EndTestRun, - EndTestSuite, OngoingTestRun, StartTest, StartTestRun, StartTestSuite, -} - -pub type TestState { - NotStarted - Running - Finished(num_modules: Int) -} - -pub type HandlerState { - HandlerState( - test_state: TestState, - num_done: Int, - events: Map(String, Map(String, TestRun)), - ) -} - -// This is the common event-handler (shared between erlang/JS targets) -// The main strategy is to collect the test-results in a map of maps: -// module_name -> -// test_name -> test_result -// It will also keep track of if it is running (i.e. did it receive the EndTestRun) -// so that the caller can determine when to print test-results -pub fn handle_event( - msg: TestEvent, - system_time: fn() -> Int, - state: HandlerState, -) { - let test_state = state.test_state - let num_done = state.num_done - let events = state.events - let #(updated_test_state, updated_num_done, updated_events) = case msg { - StartTestRun -> #(Running, num_done, events) - StartTestSuite(module) -> { - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(_) -> events - Error(_) -> - events - |> map.insert(module.name, map.new()) - } - #(test_state, num_done, new_events) - } - StartTest(module, test) -> { - let current_time = system_time() - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(module_events) -> { - let maybe_test_event = map.get(module_events, test.name) - case maybe_test_event { - Error(_) -> - events - |> map.insert( - module.name, - module_events - |> map.insert(test.name, OngoingTestRun(test, current_time)), - ) - Ok(_) -> events - } - } - Error(_) -> events - } - #(test_state, num_done, new_events) - } - EndTest(module, test, result) -> { - let current_time = system_time() - let maybe_module_events = map.get(events, module.name) - let new_events = case maybe_module_events { - Ok(module_events) -> { - let maybe_test_run = - module_events - |> map.get(test.name) - let updated_module_events = case maybe_test_run { - Ok(OngoingTestRun(test_function, started_at)) -> - module_events - |> map.insert( - test.name, - CompletedTestRun( - test_function, - current_time - started_at, - result, - ), - ) - Error(_) -> module_events - } - events - |> map.insert(module.name, updated_module_events) - } - Error(_) -> events - } - #(test_state, num_done, new_events) - } - EndTestSuite(_) -> #(test_state, num_done + 1, events) - EndTestRun(num_modules) -> #(Finished(num_modules), num_done, events) - _ -> #(Running, num_done, events) - } - HandlerState(updated_test_state, updated_num_done, updated_events) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam deleted file mode 100644 index a1d6bd9..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam +++ /dev/null @@ -1,119 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/map.{type Map} - -// These are all the types used for test-results -// NOTE: These are heavily used in the erlang/js ffi:s -// so any changes here are likely to break the ffi:s unless -// the corresponding change is introduced there -// -// Futhermore this has some erlang related names that should -// probably be cleaned up, but it is used by both the ffi:s - -// Currently only one reason, but could be possible to support -// more reasons in the future -pub type IgnoreReason { - Ignore -} - -// This is the return value from running the test-function -// or ignored if the test was ignored -pub type TestReturn { - TestFunctionReturn(value: Dynamic, output_buffer: List(String)) - Ignored(reason: IgnoreReason) -} - -// All data about an exception in the test function is captured -// in this type. -// This is also where the data about the assertions will end up (in reason) -pub type Exception { - ErlangException( - class: Class, - reason: Reason, - stacktrace: TraceList, - output_buffer: List(String), - ) -} - -// Alias for the test-result which is either a TestResult (passed test, ignored or a test-definition) -// or an Exception (failed test) -pub type TestResult = - Result(TestReturn, Exception) - -// Reason is either an assert equal (which is if the error was produced by gleeunit should) -// TODO: Add other asserts -// or it is a gleam error meaning that is was produced by showtime should -// TODO: Rename GleamError to ShowtimeError -pub type Reason { - AssertEqual(details: List(ReasonDetail)) - AssertNotEqual(details: List(ReasonDetail)) - AssertMatch(details: List(ReasonDetail)) - GleamError(details: GleamErrorDetail) - GleamAssert(value: Dynamic, line_no: Int) - GenericException(value: Dynamic) -} - -// ReasonDetail is the union-type used in erlang-exceptions where the reason -// is a list of such details -pub type ReasonDetail { - Module(name: String) - ReasonLine(line_no: Int) - Expression(expression: String) - Expected(value: Dynamic) - Value(value: Dynamic) - Pattern(pattern: String) -} - -// Gleam error detail is produced by showtime should and will hold all the information -// about the assertion (both expected and got) -pub type GleamErrorDetail { - LetAssert( - module: String, - function: String, - line_no: Int, - message: String, - value: Dynamic, - ) -} - -// Class is a part of standard erlang exceptions, but also used on js-side -// TODO: Extend to include a JS specific constructor -pub type Class { - ErlangError - Exit - Throw -} - -// The trace list is part of the standard erlang exception, but is also -// emulated on js-side. -// TODO: Maybe we need a js-version that contain some js-specific trace-elements -pub type TraceList { - TraceList(traces: List(Trace)) -} - -// Trace are the elements in the trace list in an erlang exception -// TODO: Maybe add a js-specific trace (since arity is not really a js attribute) -pub type Trace { - Trace(function: String, arity: Arity, extra_info: List(ExtraInfo)) - TraceModule( - module: String, - function: String, - arity: Arity, - extra_info: List(ExtraInfo), - ) -} - -// Extra info holds information about the file and line -// as well as some dynamic data in a map -// This is currently not used in the reporter -pub type ExtraInfo { - ErrorInfo(error_info: Map(Dynamic, Dynamic)) - File(filename: String) - Line(line_no: Int) -} - -// Arity is the erlang type for arity -// Can be either a number, or a list of arguments -pub type Arity { - Num(arity: Int) - ArgList(arg_list: List(Dynamic)) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam deleted file mode 100644 index eb58d64..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam +++ /dev/null @@ -1,63 +0,0 @@ -import gleam/option.{type Option} -import showtime/internal/common/test_result.{type TestResult} -import showtime/internal/common/cli.{type Capture} - -// The state (and result) of a test function -pub type TestRun { - OngoingTestRun(test_function: TestFunction, started_at: Int) - CompletedTestRun( - test_function: TestFunction, - total_time: Int, - result: TestResult, - ) -} - -// A test module (found by discovery) -pub type TestModule { - TestModule(name: String, path: Option(String)) -} - -// A test function -pub type TestFunction { - TestFunction(name: String) -} - -// A test suite is a test module together with the test functions -// that were collected from that module -pub type TestSuite { - TestSuite(module: TestModule, tests: List(TestFunction)) -} - -// Test event for the event handler -pub type TestEvent { - StartTestRun - StartTestSuite(test_module: TestModule) - StartTest(test_module: TestModule, test_function: TestFunction) - EndTest( - test_module: TestModule, - test_function: TestFunction, - result: TestResult, - ) - EndTestSuite(test_module: TestModule) - EndTestRun(num_modules: Int) -} - -// Interface for the module handler -pub type TestModuleHandler = - fn(TestModule) -> Nil - -// Interface for the event handler -pub type TestEventHandler = - fn(TestEvent) -> Nil - -// Interface for the module collector -pub type ModuleCollector = - fn(TestModuleHandler) -> List(TestModule) - -// Interface for the function collector -pub type TestFunctionCollector = - fn(TestModule) -> TestSuite - -// Interface for the test runner -pub type TestRunner = - fn(TestSuite, TestEventHandler, List(String), Capture) -> Nil diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam deleted file mode 100644 index ecb752d..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam +++ /dev/null @@ -1,167 +0,0 @@ -@target(erlang) -import gleam/io -@target(erlang) -import gleam/dynamic.{type Dynamic} -@target(erlang) -import gleam/list -@target(erlang) -import gleam/string -@target(erlang) -import gleam/int -@target(erlang) -import gleam/option.{type Option, None, Some} -@target(erlang) -import gleam/erlang/atom.{type Atom} -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestModule, type TestModuleHandler, type TestSuite, TestFunction, - TestModule, TestSuite, -} -import simplifile - -// Module collector for erlang -// Will search the test folder for files ending with _test and notify -// the module handler about each module it finds -@target(erlang) -pub fn collect_modules( - test_module_handler: TestModuleHandler, - only_modules: Option(List(String)), -) -> List(TestModule) { - collect_modules_in_folder("./test", test_module_handler, only_modules) -} - -@target(erlang) -fn collect_modules_in_folder( - path: String, - test_module_handler: TestModuleHandler, - only_modules: Option(List(String)), -) { - let module_prefix = get_module_prefix(path) - let assert Ok(files) = simplifile.read_directory(path) - let test_modules_in_folder = - files - |> list.filter(string.ends_with(_, "_test.gleam")) - |> list.filter_map(fn(test_module_file) { - let module_name = - module_prefix <> { - test_module_file - |> string.replace(".gleam", "") - } - case only_modules { - Some(only_modules_list) -> { - let module_in_list = - only_modules_list - |> list.any(fn(only_module_name) { - only_module_name == module_name - |> string.replace("@", "/") - }) - case module_in_list { - True -> { - let test_module = TestModule(module_name, Some(test_module_file)) - test_module_handler(test_module) - Ok(test_module) - } - - False -> Error(Nil) - } - } - None -> { - let test_module = TestModule(module_name, Some(test_module_file)) - test_module_handler(test_module) - Ok(test_module) - } - } - }) - let test_modules_in_subfolders = - files - |> list.map(fn(filename) { path <> "/" <> filename }) - |> list.filter(fn(file) { simplifile.is_directory(file) }) - |> list.fold( - [], - fn(modules, subfolder) { - modules - |> list.append(collect_modules_in_folder( - subfolder, - test_module_handler, - only_modules, - )) - }, - ) - test_modules_in_folder - |> list.append(test_modules_in_subfolders) -} - -@target(erlang) -fn get_module_prefix(path) { - let path_without_test = - path - |> string.replace("./test", "") - - let path_without_leading_slash = case - string.starts_with(path_without_test, "/") - { - True -> string.drop_left(path_without_test, 1) - False -> path_without_test - } - let module_prefix = - path_without_leading_slash - |> string.replace("/", "@") - case string.length(module_prefix) { - 0 -> module_prefix - _ -> module_prefix <> "@" - } -} - -// Test function collector for erlang -// Uses erlang `apply` to run `module_info` for the test module -// and collects all the exports ending with _test into a `TestSuite` -@target(erlang) -pub fn collect_test_functions(module: TestModule) -> TestSuite { - let test_functions: List(#(Atom, Int)) = - apply( - atom.create_from_string(module.name), - atom.create_from_string("module_info"), - [dynamic.from(atom.create_from_string("exports"))], - ) - |> dynamic.unsafe_coerce() - - let test_functions_filtered = - test_functions - |> list.map(fn(entry) { - let assert #(name, arity) = entry - #( - name - |> atom.to_string(), - arity, - ) - }) - |> list.filter_map(fn(entry) { - let assert #(name, arity) = entry - case string.ends_with(name, "_test") { - True -> - case arity { - 0 -> Ok(name) - _ -> { - io.println( - "WARNING: function \"" <> name <> "\" has arity: " <> int.to_string( - arity, - ) <> " - cannot be used as test (needs to be 0)", - ) - Error("Wrong arity") - } - } - False -> Error("Non matching name") - } - }) - |> list.filter(string.ends_with(_, "_test")) - |> list.map(fn(function_name) { TestFunction(function_name) }) - TestSuite(module, test_functions_filtered) -} - -@target(erlang) -@external(erlang, "erlang", "apply") -fn apply( - module module: Atom, - function function: Atom, - args args: List(Dynamic), -) -> Dynamic diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam deleted file mode 100644 index 62a9caf..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam +++ /dev/null @@ -1,91 +0,0 @@ -@target(erlang) -import gleam/io -@target(erlang) -import gleam/otp/actor.{Continue, Stop} -@target(erlang) -import gleam/erlang/process.{type Subject, Normal} -@target(erlang) -import gleam/map -@target(erlang) -import showtime/internal/common/test_suite.{type TestEvent, EndTestRun} -@target(erlang) -import showtime/internal/common/common_event_handler.{ - Finished, HandlerState, NotStarted, handle_event, -} -@target(erlang) -import showtime/internal/reports/formatter.{create_test_report} -@target(erlang) -import gleam/erlang.{Millisecond} -@target(erlang) -import gleam/option.{None} - -@target(erlang) -type EventHandlerMessage { - EventHandlerMessage(test_event: TestEvent, reply_to: Subject(Int)) -} - -// Starts an actor that receives test events and forwards the to the event handler -// When handler updates the state to `Finished` the actor will wait until handler -// reports that all modules are done and the stop -@target(erlang) -pub fn start() { - let assert Ok(subject) = - actor.start( - #(NotStarted, 0, map.new()), - fn(msg: EventHandlerMessage, state) { - let EventHandlerMessage(test_event, reply_to) = msg - let #(test_state, num_done, events) = state - let updated_state = - handle_event( - test_event, - system_time, - HandlerState(test_state, num_done, events), - ) - case updated_state { - HandlerState(Finished(num_modules), num_done, events) if num_done == num_modules -> { - let #(test_report, num_failed) = create_test_report(events) - io.println(test_report) - process.send(reply_to, num_failed) - Stop(Normal) - } - HandlerState(test_state, num_done, events) -> - Continue(#(test_state, num_done, events), None) - } - }, - ) - let parent_subject = process.new_subject() - - let selector = - process.new_selector() - |> process.selecting(parent_subject, fn(x) { x }) - - // Returns a callback that can receive test events - fn(test_event: TestEvent) { - case test_event { - EndTestRun(..) -> { - // When EndTestRun has been received the callback will wait until the - // actor has stopped - // TODO: Use a timeout? - process.send(subject, EventHandlerMessage(test_event, parent_subject)) - let num_failed = process.select_forever(selector) - case num_failed > 0 { - True -> halt(1) - False -> halt(0) - } - } - - // Normally just send the test event to the actor - _ -> - process.send(subject, EventHandlerMessage(test_event, parent_subject)) - } - } -} - -@target(erlang) -@external(erlang, "erlang", "halt") -fn halt(a: Int) -> Nil - -@target(erlang) -fn system_time() { - erlang.system_time(Millisecond) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam deleted file mode 100644 index 88cc251..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam +++ /dev/null @@ -1,43 +0,0 @@ -@target(erlang) -import gleam/otp/actor.{Continue} -@target(erlang) -import gleam/erlang/process -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestEventHandler, type TestFunctionCollector, type TestModule, - type TestRunner, EndTestSuite, StartTestSuite, -} -@target(erlang) -import showtime/internal/common/cli.{type Capture} -@target(erlang) -import gleam/option.{None} - -@target(erlang) -pub fn start( - test_event_handler: TestEventHandler, - test_function_collector: TestFunctionCollector, - run_test_suite: TestRunner, - ignore_tags: List(String), - capture: Capture, -) { - let assert Ok(subject) = - actor.start( - Nil, - fn(module: TestModule, state) { - process.start( - fn() { - let test_suite = test_function_collector(module) - test_event_handler(StartTestSuite(module)) - run_test_suite(test_suite, test_event_handler, ignore_tags, capture) - test_event_handler(EndTestSuite(module)) - }, - False, - ) - Continue(state, None) - }, - ) - fn(test_module: TestModule) { - process.send(subject, test_module) - Nil - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam deleted file mode 100644 index ebbf426..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam +++ /dev/null @@ -1,59 +0,0 @@ -@target(erlang) -import gleam/list -@target(erlang) -import gleam/erlang/atom.{type Atom} -@target(erlang) -import showtime/internal/common/test_suite.{ - type TestEventHandler, type TestSuite, EndTest, StartTest, -} -@target(erlang) -import showtime/internal/common/test_result.{type TestResult} -@target(erlang) -import showtime/internal/common/cli.{type Capture} - -// Runs all tests in a test suite -@target(erlang) -pub fn run_test_suite( - test_suite: TestSuite, - test_event_handler: TestEventHandler, - ignore_tags: List(String), - capture: Capture, -) { - test_suite.tests - |> list.each(fn(test) { - test_event_handler(StartTest(test_suite.module, test)) - let result = - run_test(test_suite.module.name, test.name, ignore_tags, capture) - test_event_handler(EndTest(test_suite.module, test, result)) - }) -} - -// Wrapper around the ffi function that converts names to atoms -@target(erlang) -pub fn run_test( - module_name: String, - test_name: String, - ignore_tags: List(String), - capture: Capture, -) -> TestResult { - let result = - run_test_ffi( - atom.create_from_string(module_name), - atom.create_from_string(test_name), - ignore_tags, - capture, - ) - result -} - -// Calls ffi for running a test function -// The ffi will take care of mapping the result and exception to the data-types -// used in gleam -@target(erlang) -@external(erlang, "showtime_ffi", "run_test") -fn run_test_ffi( - module module: Atom, - function function: Atom, - ignore_tags ignore_tags: List(String), - capture capture: Capture, -) -> TestResult diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam deleted file mode 100644 index 5ccddee..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam +++ /dev/null @@ -1,42 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/string -import showtime/internal/reports/styles.{expected_highlight, got_highlight} -import gap.{compare_lists, compare_strings} -import gap/styling.{from_comparison, highlight, to_styled_comparison} - -pub fn compare(expected: Dynamic, got: Dynamic) -> #(String, String) { - let expected_as_list = - expected - |> dynamic.list(dynamic.dynamic) - let got_as_list = - got - |> dynamic.list(dynamic.dynamic) - let expected_as_string = - expected - |> dynamic.string() - let got_as_string = - got - |> dynamic.string() - case expected_as_list, got_as_list, expected_as_string, got_as_string { - Ok(expected_list), Ok(got_list), _, _ -> { - let comparison = - compare_lists(expected_list, got_list) - |> from_comparison() - |> highlight(expected_highlight, got_highlight, fn(item) { item }) - |> to_styled_comparison() - #(comparison.first, comparison.second) - } - _, _, Ok(expected_string), Ok(got_string) -> { - let comparison = - compare_strings(expected_string, got_string) - |> from_comparison() - |> highlight(expected_highlight, got_highlight, fn(item) { item }) - |> to_styled_comparison() - #(comparison.first, comparison.second) - } - _, _, _, _ -> #( - expected_highlight(string.inspect(expected)), - got_highlight(string.inspect(got)), - ) - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam deleted file mode 100644 index 8c1a6ac..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam +++ /dev/null @@ -1,480 +0,0 @@ -import gleam/io -import gleam/int -import gleam/list -import gleam/string -import gleam/option.{type Option, None, Some} -import gleam/map.{type Map} -import gleam/dynamic.{type Dynamic} -import showtime/internal/common/test_result.{ - type GleamErrorDetail, type ReasonDetail, type Trace, AssertEqual, AssertMatch, - AssertNotEqual, Expected, Expression, GenericException, GleamAssert, - GleamError, Ignored, LetAssert, Pattern, Trace, TraceModule, Value, -} -import showtime/internal/common/test_suite.{type TestRun, CompletedTestRun} -import showtime/tests/should.{type Assertion, Eq, Fail, IsError, IsOk, NotEq} -import showtime/internal/reports/styles.{ - error_style, expected_highlight, failed_style, function_style, got_highlight, - heading_style, ignored_style, not_style, passed_style, stacktrace_style, -} -import showtime/internal/reports/compare.{compare} -import showtime/internal/reports/table.{ - AlignLeft, AlignLeftOverflow, AlignRight, Content, Separator, StyledContent, - Table, align_table, to_string, -} -import showtime/tests/meta.{type Meta} - -type GleeUnitAssertionType { - GleeUnitAssertEqual(message: String) - GleeUnitAssertNotEqual(message: String) - GleeUnitAssertMatch(message: String) -} - -type ModuleAndTest { - ModuleAndTestRun(module_name: String, test_run: TestRun) -} - -type UnifiedError { - UnifiedError( - meta: Option(Meta), - reason: String, - message: String, - expected: String, - got: String, - line: Option(Int), - stacktrace: List(Trace), - ) -} - -pub fn create_test_report(test_results: Map(String, Map(String, TestRun))) { - let all_test_runs = - test_results - |> map.values() - |> list.flat_map(map.values) - let failed_test_runs = - test_results - |> map.to_list() - |> list.flat_map(fn(entry) { - let #(module_name, test_module_results) = entry - test_module_results - |> map.values() - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(_test_function, _, result) -> - case result { - Error(_) -> Ok(ModuleAndTestRun(module_name, test_run)) - Ok(Ignored(_)) -> Error(Nil) - Ok(_) -> Error(Nil) - } - _ -> { - test_run - |> io.debug() - Error(Nil) - } - } - }) - }) - - let ignored_test_runs = - test_results - |> map.to_list() - |> list.flat_map(fn(entry) { - let #(module_name, test_module_results) = entry - test_module_results - |> map.values() - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(test_function, _, result) -> - case result { - Ok(Ignored(reason)) -> - Ok(#(module_name <> "." <> test_function.name, reason)) - _ -> Error(Nil) - } - _ -> Error(Nil) - } - }) - }) - - let failed_tests_report = - failed_test_runs - |> list.filter_map(fn(module_and_test_run) { - case module_and_test_run.test_run { - CompletedTestRun(test_function, _total_time, result) -> - case result { - Error(exception) -> - case exception.reason { - AssertEqual(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertEqual("Assert equal"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - AssertNotEqual(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertNotEqual("Assert not equal"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - AssertMatch(reason_details) -> - Ok(format_reason( - erlang_error_to_unified( - reason_details, - GleeUnitAssertMatch("Assert match"), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - GleamError(reason) -> - Ok(format_reason( - gleam_error_to_unified(reason, exception.stacktrace.traces), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - // GleamAssert(value) -> Error(Nil) - GleamAssert(value, line_no) -> - Ok(format_reason( - UnifiedError( - None, - "gleam assert", - "Assert failed", - "Patterns should match", - error_style(string.inspect(value)), - Some(line_no), - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - GenericException(value) -> - Ok(format_reason( - UnifiedError( - None, - "generic exception", - "Test function threw an exception", - "Exception in test function", - error_style(string.inspect(value)), - None, - exception.stacktrace.traces, - ), - module_and_test_run.module_name, - test_function.name, - exception.output_buffer, - )) - other -> { - io.println("Other: " <> string.inspect(other)) - panic - Error(Nil) - } - } - _ -> Error(Nil) - } - _ -> Error(Nil) - } - }) - |> list.fold([], fn(rows, test_rows) { list.append(rows, test_rows) }) - - let all_test_execution_time_reports = - all_test_runs - |> list.filter_map(fn(test_run) { - case test_run { - CompletedTestRun(test_function, total_time, _) -> - Ok(test_function.name <> ": " <> int.to_string(total_time) <> " ms") - _ -> Error(Nil) - } - }) - let _execution_times_report = - all_test_execution_time_reports - |> string.join("\n") - - let all_tests_count = - all_test_runs - |> list.length() - let ignored_tests_count = - ignored_test_runs - |> list.length() - let failed_tests_count = - failed_test_runs - |> list.length() - - let passed = - passed_style( - int.to_string(all_tests_count - failed_tests_count - ignored_tests_count) <> " passed", - ) - let failed = failed_style(int.to_string(failed_tests_count) <> " failed") - let ignored = case ignored_tests_count { - 0 -> "" - _ -> ", " <> ignored_style(int.to_string(ignored_tests_count) <> " ignored") - } - - let failed_tests_table = - Table(None, failed_tests_report) - |> align_table() - |> to_string() - - let test_report = - "\n" <> failed_tests_table <> "\n" <> passed <> ", " <> failed <> ignored - #(test_report, failed_tests_count) -} - -fn erlang_error_to_unified( - error_details: List(ReasonDetail), - assertion_type: GleeUnitAssertionType, - stacktrace: List(Trace), -) { - error_details - |> list.fold( - UnifiedError( - None, - "not_set", - assertion_type.message, - "", - "", - None, - stacktrace, - ), - fn(unified, reason) { - case reason { - Expression(expression) -> UnifiedError(..unified, reason: expression) - Expected(value) -> - case assertion_type { - GleeUnitAssertEqual(_messaged) -> - UnifiedError( - ..unified, - expected: expected_highlight(string.inspect(value)), - ) - _ -> unified - } - Value(value) -> - case assertion_type { - GleeUnitAssertNotEqual(_message) -> - UnifiedError( - ..unified, - expected: not_style("not ") <> string.inspect(value), - got: got_highlight(string.inspect(value)), - ) - _ -> - UnifiedError(..unified, got: got_highlight(string.inspect(value))) - } - Pattern(pattern) -> - case pattern { - "{ ok , _ }" -> - UnifiedError(..unified, expected: expected_highlight("Ok(_)")) - "{ error , _ }" -> - UnifiedError(..unified, expected: expected_highlight("Error(_)")) - _ -> unified - } - _ -> unified - } - }, - ) -} - -fn gleam_error_to_unified( - gleam_error: GleamErrorDetail, - stacktrace: List(Trace), -) -> UnifiedError { - case gleam_error { - LetAssert(_module, _function, _line_no, _message, value) -> { - let result: Result(Dynamic, Assertion(Dynamic, Dynamic)) = - dynamic.unsafe_coerce(value) - let assert Error(assertion) = result - case assertion { - Eq(got, expected, meta) -> { - let #(expected, got) = compare(expected, got) - UnifiedError( - meta, - "assert", - "Assert equal", - expected, - got, - None, - stacktrace, - ) - } - NotEq(got, expected, meta) -> - UnifiedError( - meta, - "assert", - "Assert not equal", - not_style("not ") <> string.inspect(expected), - string.inspect(got), - None, - stacktrace, - ) - IsOk(got, meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - expected_highlight("Ok(_)"), - got_highlight(string.inspect(got)), - None, - stacktrace, - ) - IsError(got, meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - expected_highlight("Error(_)"), - got_highlight(string.inspect(got)), - None, - stacktrace, - ) - Fail(meta) -> - UnifiedError( - meta, - "assert", - "Assert is Ok", - got_highlight("should.fail()"), - got_highlight("N/A - test always expected to fail"), - None, - stacktrace, - ) - } - } - } -} - -fn format_reason( - error: UnifiedError, - module: String, - function: String, - output_buffer: List(String), -) { - let meta = case error.meta { - Some(meta) -> - Some([ - AlignRight(StyledContent(heading_style("Description")), 2), - Separator(": "), - AlignLeft(Content(meta.description), 0), - ]) - - None -> None - } - - let stacktrace = - error.stacktrace - |> list.map(fn(trace) { - case trace { - Trace(function, _, _) if function == "" -> "(anonymous)" - TraceModule(module, function, _, _) if function == "" -> - module <> "." <> "(anonymous)" - Trace(function, _, _) -> function - TraceModule(module, function, _, _) -> module <> "." <> function - } - }) - let stacktrace_rows = case stacktrace { - [] -> [] - [first, ..rest] -> { - let first_row = - Some([ - AlignRight(StyledContent(heading_style("Stacktrace")), 2), - Separator(": "), - AlignLeft(StyledContent(stacktrace_style(first)), 0), - ]) - let rest_rows = - rest - |> list.map(fn(row) { - Some([ - AlignRight(Content(""), 2), - Separator(" "), - AlignLeft(StyledContent(stacktrace_style(row)), 0), - ]) - }) - [first_row, ..rest_rows] - } - } - - let output_rows = case - output_buffer - |> list.reverse() - |> list.map(fn(row) { string.trim_right(row) }) - { - [] -> [] - [first, ..rest] -> { - let first_row = - Some([ - AlignRight(StyledContent(heading_style("Output")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(stacktrace_style(first)), 0), - ]) - let rest_rows = - rest - |> list.map(fn(row) { - Some([ - AlignRight(Content(""), 2), - Separator(" "), - AlignLeftOverflow(StyledContent(stacktrace_style(row)), 0), - ]) - }) - [first_row, ..rest_rows] - } - } - - let line = - error.line - |> option.map(fn(line) { ":" <> int.to_string(line) }) - |> option.unwrap("") - - let arrow = - string.join( - list.repeat( - "-", - string.length(module) + 1 + { - string.length(function) + string.length(line) - } / 2, - ), - "", - ) <> "⌄" - let standard_table_rows = [ - Some([ - AlignRight(StyledContent(error_style("Failed")), 2), - Separator(": "), - AlignLeft(Content(arrow), 0), - ]), - Some([ - AlignRight(StyledContent(heading_style("Test")), 2), - Separator(": "), - AlignLeft( - StyledContent(module <> "." <> function_style(function <> line)), - 0, - ), - ]), - meta, - Some([ - AlignRight(StyledContent(heading_style("Expected")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(error.expected), 0), - ]), - Some([ - AlignRight(StyledContent(heading_style("Got")), 2), - Separator(": "), - AlignLeftOverflow(StyledContent(error.got), 0), - ]), - ] - standard_table_rows - |> list.append(stacktrace_rows) - |> list.append(output_rows) - |> list.append([ - Some([ - AlignRight(Content(""), 0), - AlignRight(Content(""), 0), - AlignRight(Content(""), 0), - ]), - ]) - |> list.filter_map(fn(row) { option.to_result(row, Nil) }) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam deleted file mode 100644 index b051dd3..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam +++ /dev/null @@ -1,84 +0,0 @@ -import gleam_community/ansi -import gleam/list -import gleam/string -import gleam/bit_array - -pub fn passed_style(text) { - bold_green(text) -} - -pub fn failed_style(text) { - bold_red(text) -} - -pub fn ignored_style(text) { - bold_yellow(text) -} - -pub fn error_style(text) { - bold_red(text) -} - -pub fn expected_highlight(text) { - bold_green(text) -} - -pub fn got_highlight(text) { - bold_red(text) -} - -pub fn not_style(text) { - ansi.bold(text) -} - -pub fn module_style(text: String) { - ansi.cyan(text) -} - -pub fn heading_style(text: String) { - ansi.cyan(text) -} - -pub fn function_style(text: String) { - bold_cyan(text) -} - -pub fn stacktrace_style(text: String) { - text -} - -fn bold_red(text: String) { - ansi.bold(ansi.red(text)) -} - -fn bold_green(text) { - ansi.bold(ansi.green(text)) -} - -fn bold_yellow(text) { - ansi.bold(ansi.yellow(text)) -} - -fn bold_cyan(text) { - ansi.bold(ansi.cyan(text)) -} - -pub fn strip_style(text) { - let #(new_text, _) = - text - |> string.to_graphemes() - |> list.fold( - #("", False), - fn(acc, char) { - let #(str, removing) = acc - let bit_char = bit_array.from_string(char) - case bit_char, removing { - <<0x1b>>, _ -> #(str, True) - <<0x6d>>, True -> #(str, False) - _, True -> #(str, True) - _, False -> #(str <> char, False) - } - }, - ) - new_text -} diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam deleted file mode 100644 index f8bc00c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam +++ /dev/null @@ -1,148 +0,0 @@ -import gleam/list -import gleam/string -import gleam/int -import gleam/option.{type Option} -import showtime/internal/reports/styles.{strip_style} - -pub type Content { - Content(unstyled_text: String) - StyledContent(styled_text: String) -} - -pub type Col { - AlignRight(content: Content, margin: Int) - AlignLeft(content: Content, margin: Int) - AlignRightOverflow(content: Content, margin: Int) - AlignLeftOverflow(content: Content, margin: Int) - Separator(char: String) - Aligned(content: String) -} - -pub type Table { - Table(header: Option(String), rows: List(List(Col))) -} - -pub fn to_string(table: Table) -> String { - let rows = - table.rows - |> list.map(fn(row) { - row - |> list.filter_map(fn(col) { - case col { - Separator(char) -> Ok(char) - Aligned(content) -> Ok(content) - _ -> Error(Nil) - } - }) - |> string.join("") - }) - |> string.join("\n") - let header = - table.header - |> option.map(fn(header) { header <> "\n" }) - |> option.unwrap("") - header <> rows -} - -pub fn align_table(table: Table) -> Table { - let cols = - table.rows - |> list.transpose() - let col_width = - cols - |> list.map(fn(col) { - col - |> list.map(fn(content) { - case content { - AlignRight(Content(unstyled), _) -> unstyled - AlignRight(StyledContent(styled), _) -> strip_style(styled) - AlignLeft(Content(unstyled), _) -> unstyled - AlignLeft(StyledContent(styled), _) -> strip_style(styled) - AlignLeftOverflow(_, _) -> "" - AlignRightOverflow(_, _) -> "" - Separator(char) -> char - Aligned(content) -> content - } - }) - |> list.fold(0, fn(max, str) { int.max(max, string.length(str)) }) - }) - let aligned_col = - cols - |> list.zip(col_width) - |> list.map(fn(col_and_width) { - let #(col, width) = col_and_width - col - |> list.map(fn(content) { - case content { - AlignRight(Content(unstyled), margin) -> - Aligned(pad_left( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignRight(StyledContent(styled), margin) -> - Aligned(pad_left( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignRightOverflow(Content(unstyled), margin) -> - Aligned(pad_left( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignRightOverflow(StyledContent(styled), margin) -> - Aligned(pad_left( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignLeft(Content(unstyled), margin) -> - Aligned(pad_right( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignLeft(StyledContent(styled), margin) -> - Aligned(pad_right( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - AlignLeftOverflow(Content(unstyled), margin) -> - Aligned(pad_right( - unstyled, - width + margin - string.length(unstyled), - " ", - )) - AlignLeftOverflow(StyledContent(styled), margin) -> - Aligned(pad_right( - styled, - width + margin - string.length(strip_style(styled)), - " ", - )) - Separator(char) -> Separator(char) - Aligned(content) -> Aligned(content) - } - }) - }) - let aligned_rows = - aligned_col - |> list.transpose() - Table(..table, rows: aligned_rows) -} - -fn pad_left(str: String, num: Int, char: String) { - let padding = - list.repeat(char, num) - |> string.join("") - padding <> str -} - -fn pad_right(str: String, num: Int, char: String) { - let padding = - list.repeat(char, num) - |> string.join("") - str <> padding -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam deleted file mode 100644 index cbba414..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam +++ /dev/null @@ -1,3 +0,0 @@ -pub type Meta { - Meta(description: String, tags: List(String)) -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam deleted file mode 100644 index 71578c7..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam +++ /dev/null @@ -1,113 +0,0 @@ -import gleam/option.{type Option, None, Some} -import showtime/tests/meta.{type Meta} - -pub type Assertion(t, e) { - Eq(a: t, b: t, meta: Option(Meta)) - NotEq(a: t, b: t, meta: Option(Meta)) - IsOk(a: Result(t, e), meta: Option(Meta)) - IsError(a: Result(t, e), meta: Option(Meta)) - Fail(meta: Option(Meta)) -} - -pub fn equal(a: t, b: t) { - evaluate(Eq(a, b, None)) -} - -pub fn equal_meta(a: t, b: t, meta: Meta) { - evaluate(Eq(a, b, Some(meta))) -} - -pub fn not_equal(a: t, b: t) { - evaluate(NotEq(a, b, None)) -} - -pub fn not_equal_meta(a: t, b: t, meta: Meta) { - evaluate(NotEq(a, b, Some(meta))) -} - -pub fn be_ok(a: Result(o, e)) { - evaluate(IsOk(a, None)) - let assert Ok(value) = a - value -} - -pub fn be_ok_meta(a: Result(o, e), meta: Meta) { - evaluate(IsOk(a, Some(meta))) -} - -pub fn be_error(a: Result(o, e)) { - evaluate(IsError(a, None)) - let assert Error(value) = a - value -} - -pub fn be_error_meta(a: Result(o, e), meta: Meta) { - evaluate(IsError(a, Some(meta))) -} - -pub fn fail() { - evaluate(Fail(None)) -} - -pub fn fail_meta(meta: Meta) { - evaluate(Fail(Some(meta))) -} - -pub fn be_true(a: Bool) { - a - |> equal(True) -} - -pub fn be_true_meta(a: Bool, meta: Meta) { - a - |> equal_meta(True, meta) -} - -pub fn be_false(a: Bool) { - a - |> equal(False) -} - -pub fn be_false_meta(a: Bool, meta: Meta) { - a - |> equal_meta(False, meta) -} - -@external(erlang, "showtime_ffi", "gleam_error") -fn gleam_error(value: Result(Nil, Assertion(a, b))) -> Nil - -pub fn evaluate(assertion) -> Nil { - case assertion { - Eq(a, b, _meta) -> - case a == b { - True -> Nil - False -> { - gleam_error(Error(assertion)) - } - } - NotEq(a, b, _meta) -> - case a != b { - True -> Nil - False -> { - gleam_error(Error(assertion)) - } - } - IsOk(a, _meta) -> - case a { - Ok(_) -> Nil - Error(_) -> { - gleam_error(Error(assertion)) - } - } - IsError(a, _meta) -> - case a { - Error(_) -> Nil - Ok(_) -> { - gleam_error(Error(assertion)) - } - } - Fail(_meta) -> { - gleam_error(Error(assertion)) - } - } -} diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam deleted file mode 100644 index 730f943..0000000 --- a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam +++ /dev/null @@ -1,57 +0,0 @@ -import showtime/tests/should -import showtime/tests/meta.{type Meta} -import gleam/io - -pub type Test { - Test(meta: Meta, test_function: fn() -> Nil) -} - -pub type MetaShould(t) { - MetaShould(equal: fn(t, t) -> Nil, not_equal: fn(t, t) -> Nil) -} - -pub fn test(meta: Meta, test_function: fn(Meta) -> Nil) { - Test(meta, fn() { test_function(meta) }) -} - -pub fn with_meta(meta: Meta, test_function: fn(MetaShould(a)) -> Nil) { - Test( - meta, - fn() { - test_function(MetaShould( - fn(a, b) { equal(a, b, meta) }, - fn(a, b) { not_equal(a, b, meta) }, - )) - }, - ) -} - -pub fn equal(a: t, b: t, meta: Meta) { - io.debug(a) - io.debug(b) - should.equal_meta(a, b, meta) -} - -pub fn not_equal(a: t, b: t, meta: Meta) { - should.equal_meta(a, b, meta) -} - -pub fn be_ok(a: Result(o, e), meta: Meta) { - should.be_ok_meta(a, meta) -} - -pub fn be_error(a: Result(o, e), meta: Meta) { - should.be_error_meta(a, meta) -} - -pub fn fail(meta: Meta) { - should.fail_meta(meta) -} - -pub fn be_true(a: Bool, meta: Meta) { - should.be_true_meta(a, meta) -} - -pub fn be_false(a: Bool, meta: Meta) { - should.be_false_meta(a, meta) -} diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl deleted file mode 100644 index f2d2396..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@cli.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(showtime@internal@common@cli). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([capture/0]). - --type capture() :: yes | no | mixed. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl deleted file mode 100644 index b0a6d7a..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@common_event_handler.erl +++ /dev/null @@ -1,131 +0,0 @@ --module(showtime@internal@common@common_event_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([handle_event/3]). --export_type([test_state/0, handler_state/0]). - --type test_state() :: not_started | running | {finished, integer()}. - --type handler_state() :: {handler_state, - test_state(), - integer(), - gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@internal@common@test_suite:test_run()))}. - --spec handle_event( - showtime@internal@common@test_suite:test_event(), - fun(() -> integer()), - handler_state() -) -> handler_state(). -handle_event(Msg, System_time, State) -> - Test_state = erlang:element(2, State), - Num_done = erlang:element(3, State), - Events = erlang:element(4, State), - {Updated_test_state, Updated_num_done, Updated_events} = case Msg of - start_test_run -> - {running, Num_done, Events}; - - {start_test_suite, Module} -> - Maybe_module_events = gleam@map:get( - Events, - erlang:element(2, Module) - ), - New_events = case Maybe_module_events of - {ok, _} -> - Events; - - {error, _} -> - _pipe = Events, - gleam@map:insert( - _pipe, - erlang:element(2, Module), - gleam@map:new() - ) - end, - {Test_state, Num_done, New_events}; - - {start_test, Module@1, Test} -> - Current_time = System_time(), - Maybe_module_events@1 = gleam@map:get( - Events, - erlang:element(2, Module@1) - ), - New_events@1 = case Maybe_module_events@1 of - {ok, Module_events} -> - Maybe_test_event = gleam@map:get( - Module_events, - erlang:element(2, Test) - ), - case Maybe_test_event of - {error, _} -> - _pipe@1 = Events, - gleam@map:insert( - _pipe@1, - erlang:element(2, Module@1), - begin - _pipe@2 = Module_events, - gleam@map:insert( - _pipe@2, - erlang:element(2, Test), - {ongoing_test_run, Test, Current_time} - ) - end - ); - - {ok, _} -> - Events - end; - - {error, _} -> - Events - end, - {Test_state, Num_done, New_events@1}; - - {end_test, Module@2, Test@1, Result} -> - Current_time@1 = System_time(), - Maybe_module_events@2 = gleam@map:get( - Events, - erlang:element(2, Module@2) - ), - New_events@2 = case Maybe_module_events@2 of - {ok, Module_events@1} -> - Maybe_test_run = begin - _pipe@3 = Module_events@1, - gleam@map:get(_pipe@3, erlang:element(2, Test@1)) - end, - Updated_module_events = case Maybe_test_run of - {ok, {ongoing_test_run, Test_function, Started_at}} -> - _pipe@4 = Module_events@1, - gleam@map:insert( - _pipe@4, - erlang:element(2, Test@1), - {completed_test_run, - Test_function, - Current_time@1 - Started_at, - Result} - ); - - {error, _} -> - Module_events@1 - end, - _pipe@5 = Events, - gleam@map:insert( - _pipe@5, - erlang:element(2, Module@2), - Updated_module_events - ); - - {error, _} -> - Events - end, - {Test_state, Num_done, New_events@2}; - - {end_test_suite, _} -> - {Test_state, Num_done + 1, Events}; - - {end_test_run, Num_modules} -> - {{finished, Num_modules}, Num_done, Events}; - - _ -> - {running, Num_done, Events} - end, - {handler_state, Updated_test_state, Updated_num_done, Updated_events}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl deleted file mode 100644 index b7b73be..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_result.erl +++ /dev/null @@ -1,54 +0,0 @@ --module(showtime@internal@common@test_result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([ignore_reason/0, test_return/0, exception/0, reason/0, reason_detail/0, gleam_error_detail/0, class/0, trace_list/0, trace/0, extra_info/0, arity_/0]). - --type ignore_reason() :: ignore. - --type test_return() :: {test_function_return, - gleam@dynamic:dynamic_(), - list(binary())} | - {ignored, ignore_reason()}. - --type exception() :: {erlang_exception, - class(), - reason(), - trace_list(), - list(binary())}. - --type reason() :: {assert_equal, list(reason_detail())} | - {assert_not_equal, list(reason_detail())} | - {assert_match, list(reason_detail())} | - {gleam_error, gleam_error_detail()} | - {gleam_assert, gleam@dynamic:dynamic_(), integer()} | - {generic_exception, gleam@dynamic:dynamic_()}. - --type reason_detail() :: {module, binary()} | - {reason_line, integer()} | - {expression, binary()} | - {expected, gleam@dynamic:dynamic_()} | - {value, gleam@dynamic:dynamic_()} | - {pattern, binary()}. - --type gleam_error_detail() :: {let_assert, - binary(), - binary(), - integer(), - binary(), - gleam@dynamic:dynamic_()}. - --type class() :: erlang_error | exit | throw. - --type trace_list() :: {trace_list, list(trace())}. - --type trace() :: {trace, binary(), arity_(), list(extra_info())} | - {trace_module, binary(), binary(), arity_(), list(extra_info())}. - --type extra_info() :: {error_info, - gleam@map:map_(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_())} | - {file, binary()} | - {line, integer()}. - --type arity_() :: {num, integer()} | {arg_list, list(gleam@dynamic:dynamic_())}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl b/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl deleted file mode 100644 index 6a56de8..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@common@test_suite.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(showtime@internal@common@test_suite). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([test_run/0, test_module/0, test_function/0, test_suite/0, test_event/0]). - --type test_run() :: {ongoing_test_run, test_function(), integer()} | - {completed_test_run, - test_function(), - integer(), - {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}}. - --type test_module() :: {test_module, binary(), gleam@option:option(binary())}. - --type test_function() :: {test_function, binary()}. - --type test_suite() :: {test_suite, test_module(), list(test_function())}. - --type test_event() :: start_test_run | - {start_test_suite, test_module()} | - {start_test, test_module(), test_function()} | - {end_test, - test_module(), - test_function(), - {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}} | - {end_test_suite, test_module()} | - {end_test_run, integer()}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl deleted file mode 100644 index f0548aa..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@discover.erl +++ /dev/null @@ -1,230 +0,0 @@ --module(showtime@internal@erlang@discover). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([collect_modules/2, collect_test_functions/1]). - --spec get_module_prefix(binary()) -> binary(). -get_module_prefix(Path) -> - Path_without_test = begin - _pipe = Path, - gleam@string:replace(_pipe, <<"./test"/utf8>>, <<""/utf8>>) - end, - Path_without_leading_slash = case gleam@string:starts_with( - Path_without_test, - <<"/"/utf8>> - ) of - true -> - gleam@string:drop_left(Path_without_test, 1); - - false -> - Path_without_test - end, - Module_prefix = begin - _pipe@1 = Path_without_leading_slash, - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"@"/utf8>>) - end, - case gleam@string:length(Module_prefix) of - 0 -> - Module_prefix; - - _ -> - <<Module_prefix/binary, "@"/utf8>> - end. - --spec collect_modules_in_folder( - binary(), - fun((showtime@internal@common@test_suite:test_module()) -> nil), - gleam@option:option(list(binary())) -) -> list(showtime@internal@common@test_suite:test_module()). -collect_modules_in_folder(Path, Test_module_handler, Only_modules) -> - Module_prefix = get_module_prefix(Path), - _assert_subject = simplifile:read_directory(Path), - {ok, Files} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_modules_in_folder"/utf8>>, - line => 40}) - end, - Test_modules_in_folder = begin - _pipe = Files, - _pipe@1 = gleam@list:filter( - _pipe, - fun(_capture) -> - gleam@string:ends_with(_capture, <<"_test.gleam"/utf8>>) - end - ), - gleam@list:filter_map( - _pipe@1, - fun(Test_module_file) -> - Module_name = <<Module_prefix/binary, - (begin - _pipe@2 = Test_module_file, - gleam@string:replace( - _pipe@2, - <<".gleam"/utf8>>, - <<""/utf8>> - ) - end)/binary>>, - case Only_modules of - {some, Only_modules_list} -> - Module_in_list = begin - _pipe@3 = Only_modules_list, - gleam@list:any( - _pipe@3, - fun(Only_module_name) -> - Only_module_name =:= begin - _pipe@4 = Module_name, - gleam@string:replace( - _pipe@4, - <<"@"/utf8>>, - <<"/"/utf8>> - ) - end - end - ) - end, - case Module_in_list of - true -> - Test_module = {test_module, - Module_name, - {some, Test_module_file}}, - Test_module_handler(Test_module), - {ok, Test_module}; - - false -> - {error, nil} - end; - - none -> - Test_module@1 = {test_module, - Module_name, - {some, Test_module_file}}, - Test_module_handler(Test_module@1), - {ok, Test_module@1} - end - end - ) - end, - Test_modules_in_subfolders = begin - _pipe@5 = Files, - _pipe@6 = gleam@list:map( - _pipe@5, - fun(Filename) -> - <<<<Path/binary, "/"/utf8>>/binary, Filename/binary>> - end - ), - _pipe@7 = gleam@list:filter( - _pipe@6, - fun(File) -> simplifile:is_directory(File) end - ), - gleam@list:fold( - _pipe@7, - [], - fun(Modules, Subfolder) -> _pipe@8 = Modules, - gleam@list:append( - _pipe@8, - collect_modules_in_folder( - Subfolder, - Test_module_handler, - Only_modules - ) - ) end - ) - end, - _pipe@9 = Test_modules_in_folder, - gleam@list:append(_pipe@9, Test_modules_in_subfolders). - --spec collect_modules( - fun((showtime@internal@common@test_suite:test_module()) -> nil), - gleam@option:option(list(binary())) -) -> list(showtime@internal@common@test_suite:test_module()). -collect_modules(Test_module_handler, Only_modules) -> - collect_modules_in_folder( - <<"./test"/utf8>>, - Test_module_handler, - Only_modules - ). - --spec collect_test_functions(showtime@internal@common@test_suite:test_module()) -> showtime@internal@common@test_suite:test_suite(). -collect_test_functions(Module) -> - Test_functions = begin - _pipe = erlang:apply( - erlang:binary_to_atom(erlang:element(2, Module)), - erlang:binary_to_atom(<<"module_info"/utf8>>), - [gleam@dynamic:from(erlang:binary_to_atom(<<"exports"/utf8>>))] - ), - gleam@dynamic:unsafe_coerce(_pipe) - end, - Test_functions_filtered = begin - _pipe@1 = Test_functions, - _pipe@3 = gleam@list:map( - _pipe@1, - fun(Entry) -> - {Name, Arity} = case Entry of - {_, _} -> Entry; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_test_functions"/utf8>>, - line => 131}) - end, - {begin - _pipe@2 = Name, - erlang:atom_to_binary(_pipe@2) - end, - Arity} - end - ), - _pipe@4 = gleam@list:filter_map( - _pipe@3, - fun(Entry@1) -> - {Name@1, Arity@1} = case Entry@1 of - {_, _} -> Entry@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"showtime/internal/erlang/discover"/utf8>>, - function => <<"collect_test_functions"/utf8>>, - line => 139}) - end, - case gleam@string:ends_with(Name@1, <<"_test"/utf8>>) of - true -> - case Arity@1 of - 0 -> - {ok, Name@1}; - - _ -> - gleam@io:println( - <<<<<<<<"WARNING: function \""/utf8, - Name@1/binary>>/binary, - "\" has arity: "/utf8>>/binary, - (gleam@int:to_string(Arity@1))/binary>>/binary, - " - cannot be used as test (needs to be 0)"/utf8>> - ), - {error, <<"Wrong arity"/utf8>>} - end; - - false -> - {error, <<"Non matching name"/utf8>>} - end - end - ), - _pipe@5 = gleam@list:filter( - _pipe@4, - fun(_capture) -> - gleam@string:ends_with(_capture, <<"_test"/utf8>>) - end - ), - gleam@list:map( - _pipe@5, - fun(Function_name) -> {test_function, Function_name} end - ) - end, - {test_suite, Module, Test_functions_filtered}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl deleted file mode 100644 index d72ce2c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@event_handler.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(showtime@internal@erlang@event_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([start/0]). --export_type([event_handler_message/0]). - --type event_handler_message() :: {event_handler_message, - showtime@internal@common@test_suite:test_event(), - gleam@erlang@process:subject(integer())}. - --spec system_time() -> integer(). -system_time() -> - os:system_time(millisecond). - --spec start() -> fun((showtime@internal@common@test_suite:test_event()) -> nil). -start() -> - _assert_subject = gleam@otp@actor:start( - {not_started, 0, gleam@map:new()}, - fun(Msg, State) -> - {event_handler_message, Test_event, Reply_to} = Msg, - {Test_state, Num_done, Events} = State, - Updated_state = showtime@internal@common@common_event_handler:handle_event( - Test_event, - fun system_time/0, - {handler_state, Test_state, Num_done, Events} - ), - case Updated_state of - {handler_state, {finished, Num_modules}, Num_done@1, Events@1} when Num_done@1 =:= Num_modules -> - {Test_report, Num_failed} = showtime@internal@reports@formatter:create_test_report( - Events@1 - ), - gleam@io:println(Test_report), - gleam@erlang@process:send(Reply_to, Num_failed), - {stop, normal}; - - {handler_state, Test_state@1, Num_done@2, Events@2} -> - {continue, {Test_state@1, Num_done@2, Events@2}, none} - end - end - ), - {ok, Subject} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/event_handler"/utf8>>, - function => <<"start"/utf8>>, - line => 32}) - end, - Parent_subject = gleam@erlang@process:new_subject(), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - gleam@erlang@process:selecting(_pipe, Parent_subject, fun(X) -> X end) - end, - fun(Test_event@1) -> case Test_event@1 of - {end_test_run, _} -> - gleam@erlang@process:send( - Subject, - {event_handler_message, Test_event@1, Parent_subject} - ), - Num_failed@1 = gleam_erlang_ffi:select(Selector), - case Num_failed@1 > 0 of - true -> - erlang:halt(1); - - false -> - erlang:halt(0) - end; - - _ -> - gleam@erlang@process:send( - Subject, - {event_handler_message, Test_event@1, Parent_subject} - ) - end end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl deleted file mode 100644 index a6959f5..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@module_handler.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(showtime@internal@erlang@module_handler). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([start/5]). - --spec start( - fun((showtime@internal@common@test_suite:test_event()) -> nil), - fun((showtime@internal@common@test_suite:test_module()) -> showtime@internal@common@test_suite:test_suite()), - fun((showtime@internal@common@test_suite:test_suite(), fun((showtime@internal@common@test_suite:test_event()) -> nil), list(binary()), showtime@internal@common@cli:capture()) -> nil), - list(binary()), - showtime@internal@common@cli:capture() -) -> fun((showtime@internal@common@test_suite:test_module()) -> nil). -start( - Test_event_handler, - Test_function_collector, - Run_test_suite, - Ignore_tags, - Capture -) -> - _assert_subject = gleam@otp@actor:start( - nil, - fun(Module, State) -> - gleam@erlang@process:start( - fun() -> - Test_suite = Test_function_collector(Module), - Test_event_handler({start_test_suite, Module}), - Run_test_suite( - Test_suite, - Test_event_handler, - Ignore_tags, - Capture - ), - Test_event_handler({end_test_suite, Module}) - end, - false - ), - {continue, State, none} - end - ), - {ok, Subject} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/erlang/module_handler"/utf8>>, - function => <<"start"/utf8>>, - line => 23}) - end, - fun(Test_module) -> - gleam@erlang@process:send(Subject, Test_module), - nil - end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl b/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl deleted file mode 100644 index 702fb75..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@erlang@runner.erl +++ /dev/null @@ -1,46 +0,0 @@ --module(showtime@internal@erlang@runner). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([run_test/4, run_test_suite/4]). - --spec run_test( - binary(), - binary(), - list(binary()), - showtime@internal@common@cli:capture() -) -> {ok, showtime@internal@common@test_result:test_return()} | - {error, showtime@internal@common@test_result:exception()}. -run_test(Module_name, Test_name, Ignore_tags, Capture) -> - Result = showtime_ffi:run_test( - erlang:binary_to_atom(Module_name), - erlang:binary_to_atom(Test_name), - Ignore_tags, - Capture - ), - Result. - --spec run_test_suite( - showtime@internal@common@test_suite:test_suite(), - fun((showtime@internal@common@test_suite:test_event()) -> nil), - list(binary()), - showtime@internal@common@cli:capture() -) -> nil. -run_test_suite(Test_suite, Test_event_handler, Ignore_tags, Capture) -> - _pipe = erlang:element(3, Test_suite), - gleam@list:each( - _pipe, - fun(Test) -> - Test_event_handler( - {start_test, erlang:element(2, Test_suite), Test} - ), - Result = run_test( - erlang:element(2, erlang:element(2, Test_suite)), - erlang:element(2, Test), - Ignore_tags, - Capture - ), - Test_event_handler( - {end_test, erlang:element(2, Test_suite), Test, Result} - ) - end - ). diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl deleted file mode 100644 index d2969b2..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@compare.erl +++ /dev/null @@ -1,61 +0,0 @@ --module(showtime@internal@reports@compare). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compare/2]). - --spec compare(gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> {binary(), - binary()}. -compare(Expected, Got) -> - Expected_as_list = begin - _pipe = Expected, - (gleam@dynamic:list(fun gleam@dynamic:dynamic/1))(_pipe) - end, - Got_as_list = begin - _pipe@1 = Got, - (gleam@dynamic:list(fun gleam@dynamic:dynamic/1))(_pipe@1) - end, - Expected_as_string = begin - _pipe@2 = Expected, - gleam@dynamic:string(_pipe@2) - end, - Got_as_string = begin - _pipe@3 = Got, - gleam@dynamic:string(_pipe@3) - end, - case {Expected_as_list, Got_as_list, Expected_as_string, Got_as_string} of - {{ok, Expected_list}, {ok, Got_list}, _, _} -> - Comparison = begin - _pipe@4 = gap:compare_lists(Expected_list, Got_list), - _pipe@5 = gap@styling:from_comparison(_pipe@4), - _pipe@6 = gap@styling:highlight( - _pipe@5, - fun showtime@internal@reports@styles:expected_highlight/1, - fun showtime@internal@reports@styles:got_highlight/1, - fun(Item) -> Item end - ), - gap@styling:to_styled_comparison(_pipe@6) - end, - {erlang:element(2, Comparison), erlang:element(3, Comparison)}; - - {_, _, {ok, Expected_string}, {ok, Got_string}} -> - Comparison@1 = begin - _pipe@7 = gap:compare_strings(Expected_string, Got_string), - _pipe@8 = gap@styling:from_comparison(_pipe@7), - _pipe@9 = gap@styling:highlight( - _pipe@8, - fun showtime@internal@reports@styles:expected_highlight/1, - fun showtime@internal@reports@styles:got_highlight/1, - fun(Item@1) -> Item@1 end - ), - gap@styling:to_styled_comparison(_pipe@9) - end, - {erlang:element(2, Comparison@1), erlang:element(3, Comparison@1)}; - - {_, _, _, _} -> - {showtime@internal@reports@styles:expected_highlight( - gleam@string:inspect(Expected) - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got) - )} - end. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl deleted file mode 100644 index faea091..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@formatter.erl +++ /dev/null @@ -1,749 +0,0 @@ --module(showtime@internal@reports@formatter). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([create_test_report/1]). --export_type([glee_unit_assertion_type/0, module_and_test/0, unified_error/0]). - --type glee_unit_assertion_type() :: {glee_unit_assert_equal, binary()} | - {glee_unit_assert_not_equal, binary()} | - {glee_unit_assert_match, binary()}. - --type module_and_test() :: {module_and_test_run, - binary(), - showtime@internal@common@test_suite:test_run()}. - --type unified_error() :: {unified_error, - gleam@option:option(showtime@tests@meta:meta()), - binary(), - binary(), - binary(), - binary(), - gleam@option:option(integer()), - list(showtime@internal@common@test_result:trace())}. - --spec erlang_error_to_unified( - list(showtime@internal@common@test_result:reason_detail()), - glee_unit_assertion_type(), - list(showtime@internal@common@test_result:trace()) -) -> unified_error(). -erlang_error_to_unified(Error_details, Assertion_type, Stacktrace) -> - _pipe = Error_details, - gleam@list:fold( - _pipe, - {unified_error, - none, - <<"not_set"/utf8>>, - erlang:element(2, Assertion_type), - <<""/utf8>>, - <<""/utf8>>, - none, - Stacktrace}, - fun(Unified, Reason) -> case Reason of - {expression, Expression} -> - erlang:setelement(3, Unified, Expression); - - {expected, Value} -> - case Assertion_type of - {glee_unit_assert_equal, _} -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - gleam@string:inspect(Value) - ) - ); - - _ -> - Unified - end; - - {value, Value@1} -> - case Assertion_type of - {glee_unit_assert_not_equal, _} -> - erlang:setelement( - 6, - erlang:setelement( - 5, - Unified, - <<(showtime@internal@reports@styles:not_style( - <<"not "/utf8>> - ))/binary, - (gleam@string:inspect(Value@1))/binary>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Value@1) - ) - ); - - _ -> - erlang:setelement( - 6, - Unified, - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Value@1) - ) - ) - end; - - {pattern, Pattern} -> - case Pattern of - <<"{ ok , _ }"/utf8>> -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - <<"Ok(_)"/utf8>> - ) - ); - - <<"{ error , _ }"/utf8>> -> - erlang:setelement( - 5, - Unified, - showtime@internal@reports@styles:expected_highlight( - <<"Error(_)"/utf8>> - ) - ); - - _ -> - Unified - end; - - _ -> - Unified - end end - ). - --spec gleam_error_to_unified( - showtime@internal@common@test_result:gleam_error_detail(), - list(showtime@internal@common@test_result:trace()) -) -> unified_error(). -gleam_error_to_unified(Gleam_error, Stacktrace) -> - case Gleam_error of - {let_assert, _, _, _, _, Value} -> - Result = gleam@dynamic:unsafe_coerce(Value), - {error, Assertion} = case Result of - {error, _} -> Result; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/internal/reports/formatter"/utf8>>, - function => <<"gleam_error_to_unified"/utf8>>, - line => 293}) - end, - case Assertion of - {eq, Got, Expected, Meta} -> - {Expected@1, Got@1} = showtime@internal@reports@compare:compare( - Expected, - Got - ), - {unified_error, - Meta, - <<"assert"/utf8>>, - <<"Assert equal"/utf8>>, - Expected@1, - Got@1, - none, - Stacktrace}; - - {not_eq, Got@2, Expected@2, Meta@1} -> - {unified_error, - Meta@1, - <<"assert"/utf8>>, - <<"Assert not equal"/utf8>>, - <<(showtime@internal@reports@styles:not_style( - <<"not "/utf8>> - ))/binary, - (gleam@string:inspect(Expected@2))/binary>>, - gleam@string:inspect(Got@2), - none, - Stacktrace}; - - {is_ok, Got@3, Meta@2} -> - {unified_error, - Meta@2, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:expected_highlight( - <<"Ok(_)"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got@3) - ), - none, - Stacktrace}; - - {is_error, Got@4, Meta@3} -> - {unified_error, - Meta@3, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:expected_highlight( - <<"Error(_)"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - gleam@string:inspect(Got@4) - ), - none, - Stacktrace}; - - {fail, Meta@4} -> - {unified_error, - Meta@4, - <<"assert"/utf8>>, - <<"Assert is Ok"/utf8>>, - showtime@internal@reports@styles:got_highlight( - <<"should.fail()"/utf8>> - ), - showtime@internal@reports@styles:got_highlight( - <<"N/A - test always expected to fail"/utf8>> - ), - none, - Stacktrace} - end - end. - --spec format_reason(unified_error(), binary(), binary(), list(binary())) -> list(list(showtime@internal@reports@table:col())). -format_reason(Error, Module, Function, Output_buffer) -> - Meta@1 = case erlang:element(2, Error) of - {some, Meta} -> - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Description"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, {content, erlang:element(2, Meta)}, 0}]}; - - none -> - none - end, - Stacktrace = begin - _pipe = erlang:element(8, Error), - gleam@list:map(_pipe, fun(Trace) -> case Trace of - {trace, Function@1, _, _} when Function@1 =:= <<""/utf8>> -> - <<"(anonymous)"/utf8>>; - - {trace_module, Module@1, Function@2, _, _} when Function@2 =:= <<""/utf8>> -> - <<<<Module@1/binary, "."/utf8>>/binary, - "(anonymous)"/utf8>>; - - {trace, Function@3, _, _} -> - Function@3; - - {trace_module, Module@2, Function@4, _, _} -> - <<<<Module@2/binary, "."/utf8>>/binary, - Function@4/binary>> - end end) - end, - Stacktrace_rows = case Stacktrace of - [] -> - []; - - [First | Rest] -> - First_row = {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Stacktrace"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - First - )}, - 0}]}, - Rest_rows = begin - _pipe@1 = Rest, - gleam@list:map( - _pipe@1, - fun(Row) -> - {some, - [{align_right, {content, <<""/utf8>>}, 2}, - {separator, <<" "/utf8>>}, - {align_left, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - Row - )}, - 0}]} - end - ) - end, - [First_row | Rest_rows] - end, - Output_rows = case begin - _pipe@2 = Output_buffer, - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:map( - _pipe@3, - fun(Row@1) -> gleam@string:trim_right(Row@1) end - ) - end of - [] -> - []; - - [First@1 | Rest@1] -> - First_row@1 = {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Output"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - First@1 - )}, - 0}]}, - Rest_rows@1 = begin - _pipe@4 = Rest@1, - gleam@list:map( - _pipe@4, - fun(Row@2) -> - {some, - [{align_right, {content, <<""/utf8>>}, 2}, - {separator, <<" "/utf8>>}, - {align_left_overflow, - {styled_content, - showtime@internal@reports@styles:stacktrace_style( - Row@2 - )}, - 0}]} - end - ) - end, - [First_row@1 | Rest_rows@1] - end, - Line@1 = begin - _pipe@5 = erlang:element(7, Error), - _pipe@6 = gleam@option:map( - _pipe@5, - fun(Line) -> <<":"/utf8, (gleam@int:to_string(Line))/binary>> end - ), - gleam@option:unwrap(_pipe@6, <<""/utf8>>) - end, - Arrow = <<(gleam@string:join( - gleam@list:repeat( - <<"-"/utf8>>, - (gleam@string:length(Module) + 1) + ((gleam@string:length( - Function - ) - + gleam@string:length(Line@1)) - div 2) - ), - <<""/utf8>> - ))/binary, - "⌄"/utf8>>, - Standard_table_rows = [{some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:error_style( - <<"Failed"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, {content, Arrow}, 0}]}, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Test"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left, - {styled_content, - <<<<Module/binary, "."/utf8>>/binary, - (showtime@internal@reports@styles:function_style( - <<Function/binary, Line@1/binary>> - ))/binary>>}, - 0}]}, - Meta@1, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Expected"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, erlang:element(5, Error)}, - 0}]}, - {some, - [{align_right, - {styled_content, - showtime@internal@reports@styles:heading_style( - <<"Got"/utf8>> - )}, - 2}, - {separator, <<": "/utf8>>}, - {align_left_overflow, - {styled_content, erlang:element(6, Error)}, - 0}]}], - _pipe@7 = Standard_table_rows, - _pipe@8 = gleam@list:append(_pipe@7, Stacktrace_rows), - _pipe@9 = gleam@list:append(_pipe@8, Output_rows), - _pipe@10 = gleam@list:append( - _pipe@9, - [{some, - [{align_right, {content, <<""/utf8>>}, 0}, - {align_right, {content, <<""/utf8>>}, 0}, - {align_right, {content, <<""/utf8>>}, 0}]}] - ), - gleam@list:filter_map( - _pipe@10, - fun(Row@3) -> gleam@option:to_result(Row@3, nil) end - ). - --spec create_test_report( - gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@internal@common@test_suite:test_run())) -) -> {binary(), integer()}. -create_test_report(Test_results) -> - All_test_runs = begin - _pipe = Test_results, - _pipe@1 = gleam@map:values(_pipe), - gleam@list:flat_map(_pipe@1, fun gleam@map:values/1) - end, - Failed_test_runs = begin - _pipe@2 = Test_results, - _pipe@3 = gleam@map:to_list(_pipe@2), - gleam@list:flat_map( - _pipe@3, - fun(Entry) -> - {Module_name, Test_module_results} = Entry, - _pipe@4 = Test_module_results, - _pipe@5 = gleam@map:values(_pipe@4), - gleam@list:filter_map(_pipe@5, fun(Test_run) -> case Test_run of - {completed_test_run, _, _, Result} -> - case Result of - {error, _} -> - {ok, - {module_and_test_run, - Module_name, - Test_run}}; - - {ok, {ignored, _}} -> - {error, nil}; - - {ok, _} -> - {error, nil} - end; - - _ -> - _pipe@6 = Test_run, - gleam@io:debug(_pipe@6), - {error, nil} - end end) - end - ) - end, - Ignored_test_runs = begin - _pipe@7 = Test_results, - _pipe@8 = gleam@map:to_list(_pipe@7), - gleam@list:flat_map( - _pipe@8, - fun(Entry@1) -> - {Module_name@1, Test_module_results@1} = Entry@1, - _pipe@9 = Test_module_results@1, - _pipe@10 = gleam@map:values(_pipe@9), - gleam@list:filter_map( - _pipe@10, - fun(Test_run@1) -> case Test_run@1 of - {completed_test_run, Test_function, _, Result@1} -> - case Result@1 of - {ok, {ignored, Reason}} -> - {ok, - {<<<<Module_name@1/binary, - "."/utf8>>/binary, - (erlang:element( - 2, - Test_function - ))/binary>>, - Reason}}; - - _ -> - {error, nil} - end; - - _ -> - {error, nil} - end end - ) - end - ) - end, - Failed_tests_report = begin - _pipe@11 = Failed_test_runs, - _pipe@12 = gleam@list:filter_map( - _pipe@11, - fun(Module_and_test_run) -> - case erlang:element(3, Module_and_test_run) of - {completed_test_run, Test_function@1, _, Result@2} -> - case Result@2 of - {error, Exception} -> - case erlang:element(3, Exception) of - {assert_equal, Reason_details} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details, - {glee_unit_assert_equal, - <<"Assert equal"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {assert_not_equal, Reason_details@1} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details@1, - {glee_unit_assert_not_equal, - <<"Assert not equal"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {assert_match, Reason_details@2} -> - {ok, - format_reason( - erlang_error_to_unified( - Reason_details@2, - {glee_unit_assert_match, - <<"Assert match"/utf8>>}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {gleam_error, Reason@1} -> - {ok, - format_reason( - gleam_error_to_unified( - Reason@1, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - ) - ), - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {gleam_assert, Value, Line_no} -> - {ok, - format_reason( - {unified_error, - none, - <<"gleam assert"/utf8>>, - <<"Assert failed"/utf8>>, - <<"Patterns should match"/utf8>>, - showtime@internal@reports@styles:error_style( - gleam@string:inspect( - Value - ) - ), - {some, Line_no}, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - )}, - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - {generic_exception, Value@1} -> - {ok, - format_reason( - {unified_error, - none, - <<"generic exception"/utf8>>, - <<"Test function threw an exception"/utf8>>, - <<"Exception in test function"/utf8>>, - showtime@internal@reports@styles:error_style( - gleam@string:inspect( - Value@1 - ) - ), - none, - erlang:element( - 2, - erlang:element( - 4, - Exception - ) - )}, - erlang:element( - 2, - Module_and_test_run - ), - erlang:element( - 2, - Test_function@1 - ), - erlang:element(5, Exception) - )}; - - Other -> - gleam@io:println( - <<"Other: "/utf8, - (gleam@string:inspect(Other))/binary>> - ), - erlang:error(#{gleam_error => panic, - message => <<"panic expression evaluated"/utf8>>, - module => <<"showtime/internal/reports/formatter"/utf8>>, - function => <<"create_test_report"/utf8>>, - line => 178}), - {error, nil} - end; - - _ -> - {error, nil} - end; - - _ -> - {error, nil} - end - end - ), - gleam@list:fold( - _pipe@12, - [], - fun(Rows, Test_rows) -> gleam@list:append(Rows, Test_rows) end - ) - end, - All_test_execution_time_reports = begin - _pipe@13 = All_test_runs, - gleam@list:filter_map(_pipe@13, fun(Test_run@2) -> case Test_run@2 of - {completed_test_run, Test_function@2, Total_time, _} -> - {ok, - <<<<<<(erlang:element(2, Test_function@2))/binary, - ": "/utf8>>/binary, - (gleam@int:to_string(Total_time))/binary>>/binary, - " ms"/utf8>>}; - - _ -> - {error, nil} - end end) - end, - _ = begin - _pipe@14 = All_test_execution_time_reports, - gleam@string:join(_pipe@14, <<"\n"/utf8>>) - end, - All_tests_count = begin - _pipe@15 = All_test_runs, - gleam@list:length(_pipe@15) - end, - Ignored_tests_count = begin - _pipe@16 = Ignored_test_runs, - gleam@list:length(_pipe@16) - end, - Failed_tests_count = begin - _pipe@17 = Failed_test_runs, - gleam@list:length(_pipe@17) - end, - Passed = showtime@internal@reports@styles:passed_style( - <<(gleam@int:to_string( - (All_tests_count - Failed_tests_count) - Ignored_tests_count - ))/binary, - " passed"/utf8>> - ), - Failed = showtime@internal@reports@styles:failed_style( - <<(gleam@int:to_string(Failed_tests_count))/binary, " failed"/utf8>> - ), - Ignored = case Ignored_tests_count of - 0 -> - <<""/utf8>>; - - _ -> - <<", "/utf8, - (showtime@internal@reports@styles:ignored_style( - <<(gleam@int:to_string(Ignored_tests_count))/binary, - " ignored"/utf8>> - ))/binary>> - end, - Failed_tests_table = begin - _pipe@18 = {table, none, Failed_tests_report}, - _pipe@19 = showtime@internal@reports@table:align_table(_pipe@18), - showtime@internal@reports@table:to_string(_pipe@19) - end, - Test_report = <<<<<<<<<<<<"\n"/utf8, Failed_tests_table/binary>>/binary, - "\n"/utf8>>/binary, - Passed/binary>>/binary, - ", "/utf8>>/binary, - Failed/binary>>/binary, - Ignored/binary>>, - {Test_report, Failed_tests_count}. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl deleted file mode 100644 index ec6230c..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@styles.erl +++ /dev/null @@ -1,93 +0,0 @@ --module(showtime@internal@reports@styles). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([not_style/1, module_style/1, heading_style/1, stacktrace_style/1, failed_style/1, error_style/1, got_highlight/1, passed_style/1, expected_highlight/1, ignored_style/1, function_style/1, strip_style/1]). - --spec not_style(binary()) -> binary(). -not_style(Text) -> - gleam_community@ansi:bold(Text). - --spec module_style(binary()) -> binary(). -module_style(Text) -> - gleam_community@ansi:cyan(Text). - --spec heading_style(binary()) -> binary(). -heading_style(Text) -> - gleam_community@ansi:cyan(Text). - --spec stacktrace_style(binary()) -> binary(). -stacktrace_style(Text) -> - Text. - --spec bold_red(binary()) -> binary(). -bold_red(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:red(Text)). - --spec failed_style(binary()) -> binary(). -failed_style(Text) -> - bold_red(Text). - --spec error_style(binary()) -> binary(). -error_style(Text) -> - bold_red(Text). - --spec got_highlight(binary()) -> binary(). -got_highlight(Text) -> - bold_red(Text). - --spec bold_green(binary()) -> binary(). -bold_green(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:green(Text)). - --spec passed_style(binary()) -> binary(). -passed_style(Text) -> - bold_green(Text). - --spec expected_highlight(binary()) -> binary(). -expected_highlight(Text) -> - bold_green(Text). - --spec bold_yellow(binary()) -> binary(). -bold_yellow(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:yellow(Text)). - --spec ignored_style(binary()) -> binary(). -ignored_style(Text) -> - bold_yellow(Text). - --spec bold_cyan(binary()) -> binary(). -bold_cyan(Text) -> - gleam_community@ansi:bold(gleam_community@ansi:cyan(Text)). - --spec function_style(binary()) -> binary(). -function_style(Text) -> - bold_cyan(Text). - --spec strip_style(binary()) -> binary(). -strip_style(Text) -> - {New_text, _} = begin - _pipe = Text, - _pipe@1 = gleam@string:to_graphemes(_pipe), - gleam@list:fold( - _pipe@1, - {<<""/utf8>>, false}, - fun(Acc, Char) -> - {Str, Removing} = Acc, - Bit_char = gleam_stdlib:identity(Char), - case {Bit_char, Removing} of - {<<16#1b>>, _} -> - {Str, true}; - - {<<16#6d>>, true} -> - {Str, false}; - - {_, true} -> - {Str, true}; - - {_, false} -> - {<<Str/binary, Char/binary>>, false} - end - end - ) - end, - New_text. diff --git a/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl b/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl deleted file mode 100644 index 35dbba3..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@internal@reports@table.erl +++ /dev/null @@ -1,229 +0,0 @@ --module(showtime@internal@reports@table). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_string/1, align_table/1]). --export_type([content/0, col/0, table/0]). - --type content() :: {content, binary()} | {styled_content, binary()}. - --type col() :: {align_right, content(), integer()} | - {align_left, content(), integer()} | - {align_right_overflow, content(), integer()} | - {align_left_overflow, content(), integer()} | - {separator, binary()} | - {aligned, binary()}. - --type table() :: {table, gleam@option:option(binary()), list(list(col()))}. - --spec to_string(table()) -> binary(). -to_string(Table) -> - Rows = begin - _pipe = erlang:element(3, Table), - _pipe@3 = gleam@list:map(_pipe, fun(Row) -> _pipe@1 = Row, - _pipe@2 = gleam@list:filter_map(_pipe@1, fun(Col) -> case Col of - {separator, Char} -> - {ok, Char}; - - {aligned, Content} -> - {ok, Content}; - - _ -> - {error, nil} - end end), - gleam@string:join(_pipe@2, <<""/utf8>>) end), - gleam@string:join(_pipe@3, <<"\n"/utf8>>) - end, - Header@1 = begin - _pipe@4 = erlang:element(2, Table), - _pipe@5 = gleam@option:map( - _pipe@4, - fun(Header) -> <<Header/binary, "\n"/utf8>> end - ), - gleam@option:unwrap(_pipe@5, <<""/utf8>>) - end, - <<Header@1/binary, Rows/binary>>. - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(Str, Num, Char) -> - Padding = begin - _pipe = gleam@list:repeat(Char, Num), - gleam@string:join(_pipe, <<""/utf8>>) - end, - <<Padding/binary, Str/binary>>. - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(Str, Num, Char) -> - Padding = begin - _pipe = gleam@list:repeat(Char, Num), - gleam@string:join(_pipe, <<""/utf8>>) - end, - <<Str/binary, Padding/binary>>. - --spec align_table(table()) -> table(). -align_table(Table) -> - Cols = begin - _pipe = erlang:element(3, Table), - gleam@list:transpose(_pipe) - end, - Col_width = begin - _pipe@1 = Cols, - gleam@list:map(_pipe@1, fun(Col) -> _pipe@2 = Col, - _pipe@3 = gleam@list:map( - _pipe@2, - fun(Content) -> case Content of - {align_right, {content, Unstyled}, _} -> - Unstyled; - - {align_right, {styled_content, Styled}, _} -> - showtime@internal@reports@styles:strip_style( - Styled - ); - - {align_left, {content, Unstyled@1}, _} -> - Unstyled@1; - - {align_left, {styled_content, Styled@1}, _} -> - showtime@internal@reports@styles:strip_style( - Styled@1 - ); - - {align_left_overflow, _, _} -> - <<""/utf8>>; - - {align_right_overflow, _, _} -> - <<""/utf8>>; - - {separator, Char} -> - Char; - - {aligned, Content@1} -> - Content@1 - end end - ), - gleam@list:fold( - _pipe@3, - 0, - fun(Max, Str) -> - gleam@int:max(Max, gleam@string:length(Str)) - end - ) end) - end, - Aligned_col = begin - _pipe@4 = Cols, - _pipe@5 = gleam@list:zip(_pipe@4, Col_width), - gleam@list:map( - _pipe@5, - fun(Col_and_width) -> - {Col@1, Width} = Col_and_width, - _pipe@6 = Col@1, - gleam@list:map(_pipe@6, fun(Content@2) -> case Content@2 of - {align_right, {content, Unstyled@2}, Margin} -> - {aligned, - pad_left( - Unstyled@2, - (Width + Margin) - gleam@string:length( - Unstyled@2 - ), - <<" "/utf8>> - )}; - - {align_right, {styled_content, Styled@2}, Margin@1} -> - {aligned, - pad_left( - Styled@2, - (Width + Margin@1) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@2 - ) - ), - <<" "/utf8>> - )}; - - {align_right_overflow, - {content, Unstyled@3}, - Margin@2} -> - {aligned, - pad_left( - Unstyled@3, - (Width + Margin@2) - gleam@string:length( - Unstyled@3 - ), - <<" "/utf8>> - )}; - - {align_right_overflow, - {styled_content, Styled@3}, - Margin@3} -> - {aligned, - pad_left( - Styled@3, - (Width + Margin@3) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@3 - ) - ), - <<" "/utf8>> - )}; - - {align_left, {content, Unstyled@4}, Margin@4} -> - {aligned, - pad_right( - Unstyled@4, - (Width + Margin@4) - gleam@string:length( - Unstyled@4 - ), - <<" "/utf8>> - )}; - - {align_left, {styled_content, Styled@4}, Margin@5} -> - {aligned, - pad_right( - Styled@4, - (Width + Margin@5) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@4 - ) - ), - <<" "/utf8>> - )}; - - {align_left_overflow, - {content, Unstyled@5}, - Margin@6} -> - {aligned, - pad_right( - Unstyled@5, - (Width + Margin@6) - gleam@string:length( - Unstyled@5 - ), - <<" "/utf8>> - )}; - - {align_left_overflow, - {styled_content, Styled@5}, - Margin@7} -> - {aligned, - pad_right( - Styled@5, - (Width + Margin@7) - gleam@string:length( - showtime@internal@reports@styles:strip_style( - Styled@5 - ) - ), - <<" "/utf8>> - )}; - - {separator, Char@1} -> - {separator, Char@1}; - - {aligned, Content@3} -> - {aligned, Content@3} - end end) - end - ) - end, - Aligned_rows = begin - _pipe@7 = Aligned_col, - gleam@list:transpose(_pipe@7) - end, - erlang:setelement(3, Table, Aligned_rows). diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl b/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl deleted file mode 100644 index c975467..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@meta.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(showtime@tests@meta). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([meta/0]). - --type meta() :: {meta, binary(), list(binary())}. - - diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@should.erl b/aoc2023/build/packages/adglent/src/showtime@tests@should.erl deleted file mode 100644 index 29906b4..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@should.erl +++ /dev/null @@ -1,143 +0,0 @@ --module(showtime@tests@should). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([evaluate/1, equal/2, equal_meta/3, not_equal/2, not_equal_meta/3, be_ok/1, be_ok_meta/2, be_error/1, be_error_meta/2, fail/0, fail_meta/1, be_true/1, be_true_meta/2, be_false/1, be_false_meta/2]). --export_type([assertion/2]). - --type assertion(MXP, MXQ) :: {eq, - MXP, - MXP, - gleam@option:option(showtime@tests@meta:meta())} | - {not_eq, MXP, MXP, gleam@option:option(showtime@tests@meta:meta())} | - {is_ok, - {ok, MXP} | {error, MXQ}, - gleam@option:option(showtime@tests@meta:meta())} | - {is_error, - {ok, MXP} | {error, MXQ}, - gleam@option:option(showtime@tests@meta:meta())} | - {fail, gleam@option:option(showtime@tests@meta:meta())}. - --spec evaluate(assertion(any(), any())) -> nil. -evaluate(Assertion) -> - case Assertion of - {eq, A, B, _} -> - case A =:= B of - true -> - nil; - - false -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {not_eq, A@1, B@1, _} -> - case A@1 /= B@1 of - true -> - nil; - - false -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {is_ok, A@2, _} -> - case A@2 of - {ok, _} -> - nil; - - {error, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {is_error, A@3, _} -> - case A@3 of - {error, _} -> - nil; - - {ok, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end; - - {fail, _} -> - showtime_ffi:gleam_error({error, Assertion}) - end. - --spec equal(MXR, MXR) -> nil. -equal(A, B) -> - evaluate({eq, A, B, none}). - --spec equal_meta(MXT, MXT, showtime@tests@meta:meta()) -> nil. -equal_meta(A, B, Meta) -> - evaluate({eq, A, B, {some, Meta}}). - --spec not_equal(MXV, MXV) -> nil. -not_equal(A, B) -> - evaluate({not_eq, A, B, none}). - --spec not_equal_meta(MXX, MXX, showtime@tests@meta:meta()) -> nil. -not_equal_meta(A, B, Meta) -> - evaluate({not_eq, A, B, {some, Meta}}). - --spec be_ok({ok, MXZ} | {error, any()}) -> MXZ. -be_ok(A) -> - evaluate({is_ok, A, none}), - {ok, Value} = case A of - {ok, _} -> A; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/tests/should"/utf8>>, - function => <<"be_ok"/utf8>>, - line => 30}) - end, - Value. - --spec be_ok_meta({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_ok_meta(A, Meta) -> - evaluate({is_ok, A, {some, Meta}}). - --spec be_error({ok, any()} | {error, MYK}) -> MYK. -be_error(A) -> - evaluate({is_error, A, none}), - {error, Value} = case A of - {error, _} -> A; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"showtime/tests/should"/utf8>>, - function => <<"be_error"/utf8>>, - line => 40}) - end, - Value. - --spec be_error_meta({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_error_meta(A, Meta) -> - evaluate({is_error, A, {some, Meta}}). - --spec fail() -> nil. -fail() -> - evaluate({fail, none}). - --spec fail_meta(showtime@tests@meta:meta()) -> nil. -fail_meta(Meta) -> - evaluate({fail, {some, Meta}}). - --spec be_true(boolean()) -> nil. -be_true(A) -> - _pipe = A, - equal(_pipe, true). - --spec be_true_meta(boolean(), showtime@tests@meta:meta()) -> nil. -be_true_meta(A, Meta) -> - _pipe = A, - equal_meta(_pipe, true, Meta). - --spec be_false(boolean()) -> nil. -be_false(A) -> - _pipe = A, - equal(_pipe, false). - --spec be_false_meta(boolean(), showtime@tests@meta:meta()) -> nil. -be_false_meta(A, Meta) -> - _pipe = A, - equal_meta(_pipe, false, Meta). diff --git a/aoc2023/build/packages/adglent/src/showtime@tests@test.erl b/aoc2023/build/packages/adglent/src/showtime@tests@test.erl deleted file mode 100644 index 2f23b9f..0000000 --- a/aoc2023/build/packages/adglent/src/showtime@tests@test.erl +++ /dev/null @@ -1,57 +0,0 @@ --module(showtime@tests@test). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([test/2, equal/3, not_equal/3, with_meta/2, be_ok/2, be_error/2, fail/1, be_true/2, be_false/2]). --export_type([test/0, meta_should/1]). - --type test() :: {test, showtime@tests@meta:meta(), fun(() -> nil)}. - --type meta_should(NDO) :: {meta_should, - fun((NDO, NDO) -> nil), - fun((NDO, NDO) -> nil)}. - --spec test(showtime@tests@meta:meta(), fun((showtime@tests@meta:meta()) -> nil)) -> test(). -test(Meta, Test_function) -> - {test, Meta, fun() -> Test_function(Meta) end}. - --spec equal(NDT, NDT, showtime@tests@meta:meta()) -> nil. -equal(A, B, Meta) -> - gleam@io:debug(A), - gleam@io:debug(B), - showtime@tests@should:equal_meta(A, B, Meta). - --spec not_equal(NDV, NDV, showtime@tests@meta:meta()) -> nil. -not_equal(A, B, Meta) -> - showtime@tests@should:equal_meta(A, B, Meta). - --spec with_meta(showtime@tests@meta:meta(), fun((meta_should(any())) -> nil)) -> test(). -with_meta(Meta, Test_function) -> - {test, - Meta, - fun() -> - Test_function( - {meta_should, - fun(A, B) -> equal(A, B, Meta) end, - fun(A@1, B@1) -> not_equal(A@1, B@1, Meta) end} - ) - end}. - --spec be_ok({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_ok(A, Meta) -> - showtime@tests@should:be_ok_meta(A, Meta). - --spec be_error({ok, any()} | {error, any()}, showtime@tests@meta:meta()) -> nil. -be_error(A, Meta) -> - showtime@tests@should:be_error_meta(A, Meta). - --spec fail(showtime@tests@meta:meta()) -> nil. -fail(Meta) -> - showtime@tests@should:fail_meta(Meta). - --spec be_true(boolean(), showtime@tests@meta:meta()) -> nil. -be_true(A, Meta) -> - showtime@tests@should:be_true_meta(A, Meta). - --spec be_false(boolean(), showtime@tests@meta:meta()) -> nil. -be_false(A, Meta) -> - showtime@tests@should:be_false_meta(A, Meta). diff --git a/aoc2023/build/packages/adglent/src/showtime_ffi.erl b/aoc2023/build/packages/adglent/src/showtime_ffi.erl deleted file mode 100644 index 3259623..0000000 --- a/aoc2023/build/packages/adglent/src/showtime_ffi.erl +++ /dev/null @@ -1,187 +0,0 @@ --module(showtime_ffi). - --export([run_test/4, functions/0, capture_output/1, gleam_error/1]). - -gleam_error(Value) -> - erlang:error(#{ - gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => Value, - module => <<"this/is/not/used"/utf8>>, - function => <<"gleam_error"/utf8>>, - % Not used - line => 0 - }). - -start_output_capture(Capture) -> - OldGroupLeader = group_leader(), - CapturePid = spawn(showtime_ffi, capture_output, [{[], {OldGroupLeader, Capture}}]), - group_leader(CapturePid, self()), - {CapturePid, OldGroupLeader}. - -stop_output_capture({CapturePid, OldGroupLeader}) -> - group_leader(OldGroupLeader, self()), - CapturePid ! {capture_done, self()}, - receive - Buffer -> - Buffer - end. - -capture_output({Buffer, {OldGroupLeader, Capture}}) -> - receive - {io_request, From, ReplyAs, {put_chars, unicode, BitString}} -> - case Capture of - yes -> - From ! {io_reply, ReplyAs, ok}, - capture_output({[BitString | Buffer], {OldGroupLeader, Capture}}); - mixed -> - OldGroupLeader ! {io_request, From, ReplyAs, {put_chars, unicode, BitString}}, - capture_output({[BitString | Buffer], {OldGroupLeader, Capture}}); - no -> - OldGroupLeader ! {io_request, From, ReplyAs, {put_chars, unicode, BitString}}, - capture_output({Buffer, {OldGroupLeader, Capture}}) - end; - {capture_done, SenderPid} -> - SenderPid ! Buffer; - OtherMessage -> - OldGroupLeader ! OtherMessage, - capture_output({Buffer, {OldGroupLeader, Capture}}) - end. - -run_test(Module, Function, IgnoreTags, Capture) -> - OutputCapture = start_output_capture(Capture), - try - Result = apply(Module, Function, []), - {ResultType, FinalResult} = - case Result of - {test, {meta, _Description, Tags}, TestFun} -> - case - lists:any( - fun(Tag) -> - lists:any(fun(IgnoreTag) -> IgnoreTag == Tag end, IgnoreTags) - end, - Tags - ) - of - true -> - {ignored, ignore}; - false -> - {test_function_return, TestFun()} - end; - DirectResult -> - {test_function_return, DirectResult} - end, - OutputCaptureBuffer = stop_output_capture(OutputCapture), - case ResultType of - ignored -> {ok, {ResultType, FinalResult}}; - _ -> {ok, {ResultType, FinalResult, OutputCaptureBuffer}} - end - catch - Class:Reason:Stacktrace -> - GleamReason = - case Reason of - {Assertion, ReasonList} -> - ErlangReasonList = - lists:map( - fun(ReasonDetail) -> - case ReasonDetail of - {line, LineNo} -> - {reason_line, LineNo}; - {expression, List} -> - {expression, list_to_binary(List)}; - {module, ModuleAtom} -> - {module, atom_to_binary(ModuleAtom)}; - {pattern, Pattern} -> - {pattern, list_to_binary(Pattern)}; - Other -> - Other - end - end, - ReasonList - ), - GleamAssertionType = - case Assertion of - assertEqual -> - assert_equal; - assertNotEqual -> - assert_not_equal; - assertMatch -> - assert_match; - OtherAssertionType -> - OtherAssertionType - end, - {GleamAssertionType, ErlangReasonList}; - #{ - function := GleamFunction, - gleam_error := GleamError, - line := Line, - message := Message, - module := GleamModule, - value := Value - } -> - case Value of - {error, {OkValue, _, _, _}} when OkValue == not_eq; OkValue == eq -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - {error, {OkValue, _, _}} when OkValue == is_ok; OkValue == is_error -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - {error, {OkValue, _}} when OkValue == fail -> - {gleam_error, - {GleamError, GleamModule, GleamFunction, Line, Message, Value}}; - _ -> - {gleam_assert, Value, Line} - end; - OtherReason -> - {generic_exception, OtherReason} - end, - GleamClass = - case Class of - error -> - erlang_error; - Other -> - Other - end, - GleamTraceList = - lists:map( - fun(Trace) -> - case Trace of - {ModuleName, FunctionName, Arity, ExtraInfoList} -> - {trace_module, atom_to_binary(ModuleName), - atom_to_binary(FunctionName), map_arity(Arity), - map_extra_info_list(ExtraInfoList)}; - {FunctionName, Arity, ExtraInfoList} -> - {trace, atom_to_binary(FunctionName), map_arity(Arity), - map_extra_info_list(ExtraInfoList)} - end - end, - Stacktrace - ), - OutputCaptureBufferCatch = stop_output_capture(OutputCapture), - {error, - {erlang_exception, GleamClass, GleamReason, {trace_list, GleamTraceList}, - OutputCaptureBufferCatch}} - end. - -map_extra_info_list(ExtraInfoList) -> - lists:map( - fun(ExtraInfo) -> - case ExtraInfo of - {file, FileNameList} -> {file, list_to_binary(FileNameList)}; - Other -> Other - end - end, - ExtraInfoList - ). - -map_arity(Arity) -> - if - is_list(Arity) -> - {arg_list, Arity}; - is_integer(Arity) -> - {num, Arity} - end. - -functions() -> - Funs = module_info(exports), - Funs. diff --git a/aoc2023/build/packages/gap/LICENSE b/aoc2023/build/packages/gap/LICENSE deleted file mode 100644 index d1cec9b..0000000 --- a/aoc2023/build/packages/gap/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2023 John Björk - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
\ No newline at end of file diff --git a/aoc2023/build/packages/gap/README.md b/aoc2023/build/packages/gap/README.md deleted file mode 100644 index 3e02686..0000000 --- a/aoc2023/build/packages/gap/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# gap - -[](https://hex.pm/packages/gap) -[](https://hexdocs.pm/gap/) - -A Gleam library for comparing strings/lists and producing a textual (styled) representation of the differences. - -A typical styled output from the comparison can look like this: - -<img src="https://github.com/JohnBjrk/gap/blob/main/static/example_diff_lucy.png?raw=true" alt="Image of two strings with highlighted differences" width="400vw"> - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add gap -``` - -Documentation can be found at <https://hexdocs.pm/gap>. - -## Usage - -# Introduction - -Gap implements string/list comparison by finding the longest common subsequence. The result of the comparison are two sequences -(one for each of the compared strings/lists) consisting of subsequences that are annotated as matching or non-matching. - -For example comparing the strings in the example above will look as follows: - -```gleam -let comparison = -compare_strings( - "lucy in the sky with diamonds", - "lucy is the shy with diagrams", -) -|> io.debug() -// StringComparison( -// [ -// Match(["l", "u", "c", "y", " ", "i"]), -// NoMatch(["n"]), -// Match([" ", "t", "h", "e", " ", "s"]), -// NoMatch(["k"]), -// Match(["y", " ", "w", "i", "t", "h", " ", "d", "i", "a", "m"]), -// NoMatch(["o", "n", "d"]), -// Match(["s"]), -// ], -// [ -// Match(["l", "u", "c", "y", " ", "i"]), -// NoMatch(["s", " "]), -// Match([" ", "t", "h", "e", " ", "s"]), -// NoMatch(["h"]), -// Match(["y", " ", "w", "i", "t", "h", " ", "d", "i"]), -// NoMatch(["a", "g", "r"]), -// Match(["a", "m", "s"]), -// ], -// ) -``` - -## Styling - -This is useful information but a bit overwhelming to look at (specially for longer string) so the library -has some built in functions to display the differences using colors instead. - -Using the same example again we can style the result and print it to the console - -```gleam -let comparison = -compare_strings( - "lucy in the sky with diamonds", - "lucy is the shy with diagrams", -) -|> to_styled() -io.println(comparison.first) -io.println(comparison.second) -``` - -This will give us something similar to the output above. - -## Comparing list - -It is also possible to compare lists with elements of arbitrary types. - -```gleam -pub type Warning { - Please - Mind - The(what: String) -} - -compare_lists([Mind, The("Gap")], [Please, Mind, The("What")]) -|> io.debug() -// ListComparison( -// [Match([Mind]), NoMatch([The("Gap")])], -// [NoMatch([Please]), Match([Mind]), NoMatch([The("What")])], -// ) -``` - -## Customize styling - -The visual representation of the comparison can be customized. To do this use a `Styling` created from -the comparison that should be styled. This example uses [gleam_community/ansi](https://hexdocs.pm/gleam_community_ansi/index.html) -to highlight the non-matches in different colors. - -```gleam -let comparison = -compare_strings( - "Strings are made of smaller things", - "Things are maybe smaller string", -) -|> from_comparison() -|> highlight( - fn(first) { ansi.cyan(first) }, - fn(second) { ansi.magenta(second) }, - fn(matching) { matching }, -) -|> to_styled_comparison() -io.println(comparison.first) -io.println(comparison.second) -``` - -This will output something similar to this - -<img src="https://github.com/JohnBjrk/gap/blob/main/static/example_diff_things.png?raw=true" alt="Image of two strings with highlighted differences" width="400vw"> - -### Serialization - -Furthermore it is also possible to customize the styling by changing the way that the comparison is serialized. An easy way to do -this is to use the utility function `mk_generic_serializer` which creates a serializer which some specific separator and a hook -for surrounding the result with some content. Here is a somewhat contrived example - -```gleam -let comparison = -compare_lists(["one", "two", "three"], ["two", "two", "tree"]) -|> from_comparison() -|> highlight( - fn(first) { first <> " was not found in other" }, - fn(second) { second <> " was not found in other" }, -) -|> serialize(mk_generic_serializer( - ", and ", - fn(result) { "Comparing the lists gave the following result: " <> result }, -)) -|> to_styled_comparison() -io.println(comparison.first) -io.println(comparison.second) -// Comparing the lists gave the following result: "one" was not found in other, and "two" was found in other, and "three" was not found in other -// Comparing the lists gave the following result: "two" was not found in other, and "two" was found in other, and "tree" was not found in other -``` - -### Custom serialization - -Serializers can of course have a custom implementation. The following example utilizes this together with custom highlighters, -creating a patch-like output (this is not exactly the same as patch-format since that shows the changes in relation to the original - to do -that both lists of matching/non-matching lines would need to be processed together) - -```gleam -let comparison = -compare_lists( - [ - "pub type Gap = List(EmptyString)", "", "pub type Traveler {", - " OnTrain", " OverGap(gap: Gap)", " OnPlatform", "}", - ], - [ - "pub type Traveler {", " OnTrain", " OverGap(gap: String)", - " OnPlatform", "}", - ], -) -|> from_comparison() -|> highlight( - fn(first) { "+" <> first }, - fn(second) { "-" <> second }, - fn(matching) { " " <> matching }, -) -|> serialize(fn(part) { - case part { - Part(acc, lines, highlight) -> - acc <> { - lines - |> list.map(fn(line) { highlight(line) }) - |> string.join("\n") - } <> "\n" - All(result) -> result - } -}) -|> to_styled_comparison() -io.println(comparison.first) -io.println(comparison.second) -// +pub type Gap = List(EmptyString) -// + -// pub type Traveler { -// OnTrain -// + OverGap(gap: Gap) -// OnPlatform -// } -// -// pub type Traveler { -// OnTrain -// - OverGap(gap: String) -// OnPlatform -// } -``` diff --git a/aoc2023/build/packages/gap/gleam.toml b/aoc2023/build/packages/gap/gleam.toml deleted file mode 100644 index ec35329..0000000 --- a/aoc2023/build/packages/gap/gleam.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "gap" -gleam = ">= 0.32.2" -version = "1.0.1" -description = "A Gleam library for comparing strings/lists and producing a textual (styled) representation of the differences." - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -repository = { type = "github", user = "JohnBjrk", repo = "gap" } -# links = [{ title = "Website", href = "https://gleam.run" }] - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_community_ansi = "~> 1.2" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/gap/include/gap@comparison_ListComparison.hrl b/aoc2023/build/packages/gap/include/gap@comparison_ListComparison.hrl deleted file mode 100644 index 5e4b20d..0000000 --- a/aoc2023/build/packages/gap/include/gap@comparison_ListComparison.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(list_comparison, { - first :: list(gap@comparison:match(list(any()))), - second :: list(gap@comparison:match(list(any()))) -}). diff --git a/aoc2023/build/packages/gap/include/gap@comparison_Match.hrl b/aoc2023/build/packages/gap/include/gap@comparison_Match.hrl deleted file mode 100644 index f1225dd..0000000 --- a/aoc2023/build/packages/gap/include/gap@comparison_Match.hrl +++ /dev/null @@ -1 +0,0 @@ --record(match, {item :: any()}). diff --git a/aoc2023/build/packages/gap/include/gap@comparison_NoMatch.hrl b/aoc2023/build/packages/gap/include/gap@comparison_NoMatch.hrl deleted file mode 100644 index 742783b..0000000 --- a/aoc2023/build/packages/gap/include/gap@comparison_NoMatch.hrl +++ /dev/null @@ -1 +0,0 @@ --record(no_match, {item :: any()}). diff --git a/aoc2023/build/packages/gap/include/gap@comparison_StringComparison.hrl b/aoc2023/build/packages/gap/include/gap@comparison_StringComparison.hrl deleted file mode 100644 index c0b1a75..0000000 --- a/aoc2023/build/packages/gap/include/gap@comparison_StringComparison.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(string_comparison, { - first :: list(gap@comparison:match(list(binary()))), - second :: list(gap@comparison:match(list(binary()))) -}). diff --git a/aoc2023/build/packages/gap/include/gap@styled_comparison_StyledComparison.hrl b/aoc2023/build/packages/gap/include/gap@styled_comparison_StyledComparison.hrl deleted file mode 100644 index 0e7c64a..0000000 --- a/aoc2023/build/packages/gap/include/gap@styled_comparison_StyledComparison.hrl +++ /dev/null @@ -1 +0,0 @@ --record(styled_comparison, {first :: binary(), second :: binary()}). diff --git a/aoc2023/build/packages/gap/include/gap@styling_All.hrl b/aoc2023/build/packages/gap/include/gap@styling_All.hrl deleted file mode 100644 index c11a9a6..0000000 --- a/aoc2023/build/packages/gap/include/gap@styling_All.hrl +++ /dev/null @@ -1 +0,0 @@ --record(all, {all :: binary()}). diff --git a/aoc2023/build/packages/gap/include/gap@styling_Highlighters.hrl b/aoc2023/build/packages/gap/include/gap@styling_Highlighters.hrl deleted file mode 100644 index 6e073b3..0000000 --- a/aoc2023/build/packages/gap/include/gap@styling_Highlighters.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(highlighters, { - first :: fun((binary()) -> binary()), - second :: fun((binary()) -> binary()), - matching :: fun((binary()) -> binary()) -}). diff --git a/aoc2023/build/packages/gap/include/gap@styling_Part.hrl b/aoc2023/build/packages/gap/include/gap@styling_Part.hrl deleted file mode 100644 index db45796..0000000 --- a/aoc2023/build/packages/gap/include/gap@styling_Part.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(part, { - acc :: binary(), - part :: list(any()), - highlight :: fun((binary()) -> binary()) -}). diff --git a/aoc2023/build/packages/gap/include/gap@styling_Styling.hrl b/aoc2023/build/packages/gap/include/gap@styling_Styling.hrl deleted file mode 100644 index a7341c6..0000000 --- a/aoc2023/build/packages/gap/include/gap@styling_Styling.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(styling, { - comparison :: gap@comparison:comparison(any()), - serializer :: gleam@option:option(fun((gap@styling:part(any())) -> binary())), - highlight :: gleam@option:option(gap@styling:highlighters()) -}). diff --git a/aoc2023/build/packages/gap/src/gap.app.src b/aoc2023/build/packages/gap/src/gap.app.src deleted file mode 100644 index 1abc7df..0000000 --- a/aoc2023/build/packages/gap/src/gap.app.src +++ /dev/null @@ -1,13 +0,0 @@ -{application, gap, [ - {vsn, "1.0.1"}, - {applications, [gleam_community_ansi, - gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for comparing strings/lists and producing a textual (styled) representation of the differences."}, - {modules, [gap, - gap@comparison, - gap@myers, - gap@styled_comparison, - gap@styling]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gap/src/gap.erl b/aoc2023/build/packages/gap/src/gap.erl deleted file mode 100644 index 827e5ce..0000000 --- a/aoc2023/build/packages/gap/src/gap.erl +++ /dev/null @@ -1,538 +0,0 @@ --module(gap). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_styled/1, compare_strings_with_algorithm/3, compare_lists_with_algorithm/3, myers/2, compare_lists/2, compare_strings/2, lcs/2]). --export_type([score/1]). - --type score(GAM) :: {score, integer(), gleam@option:option(GAM)}. - --spec to_styled(gap@comparison:comparison(any())) -> gap@styled_comparison:styled_comparison(). -to_styled(Comparison) -> - _pipe = Comparison, - _pipe@1 = gap@styling:from_comparison(_pipe), - _pipe@2 = gap@styling:highlight( - _pipe@1, - fun gap@styling:first_highlight_default/1, - fun gap@styling:second_highlight_default/1, - fun gap@styling:no_highlight/1 - ), - gap@styling:to_styled_comparison(_pipe@2). - --spec compare_strings_with_algorithm( - binary(), - binary(), - fun((list(binary()), list(binary())) -> gap@comparison:comparison(binary())) -) -> gap@comparison:comparison(binary()). -compare_strings_with_algorithm(First, Second, Algorithm) -> - Comparison = Algorithm( - gleam@string:to_graphemes(First), - gleam@string:to_graphemes(Second) - ), - case Comparison of - {list_comparison, First@1, Second@1} -> - {string_comparison, First@1, Second@1}; - - {string_comparison, First@2, Second@2} -> - {string_comparison, First@2, Second@2} - end. - --spec compare_lists_with_algorithm( - list(GBB), - list(GBB), - fun((list(GBB), list(GBB)) -> gap@comparison:comparison(GBB)) -) -> gap@comparison:comparison(GBB). -compare_lists_with_algorithm(First_sequence, Second_sequence, Algorithm) -> - Algorithm(First_sequence, Second_sequence). - --spec myers(list(GBG), list(GBG)) -> gap@comparison:comparison(GBG). -myers(First_sequence, Second_sequence) -> - Edits = gap@myers:difference(First_sequence, Second_sequence), - _pipe = Edits, - _pipe@1 = gleam@list:reverse(_pipe), - gleam@list:fold( - _pipe@1, - {list_comparison, [], []}, - fun(Comparison, Edit) -> case Comparison of - {list_comparison, First, Second} -> - case Edit of - {eq, Segment} -> - {list_comparison, - [{match, Segment} | First], - [{match, Segment} | Second]}; - - {ins, Segment@1} -> - {list_comparison, - First, - [{no_match, Segment@1} | Second]}; - - {del, Segment@2} -> - {list_comparison, - [{no_match, Segment@2} | First], - Second} - end; - - {string_comparison, _, _} -> - Comparison - end end - ). - --spec compare_lists(list(GAX), list(GAX)) -> gap@comparison:comparison(GAX). -compare_lists(First_sequence, Second_sequence) -> - myers(First_sequence, Second_sequence). - --spec compare_strings(binary(), binary()) -> gap@comparison:comparison(binary()). -compare_strings(First, Second) -> - Comparison = compare_lists( - gleam@string:to_graphemes(First), - gleam@string:to_graphemes(Second) - ), - case Comparison of - {list_comparison, First@1, Second@1} -> - {string_comparison, First@1, Second@1}; - - {string_comparison, First@2, Second@2} -> - {string_comparison, First@2, Second@2} - end. - --spec prepend_and_merge( - list(gap@comparison:match(list(GBO))), - gap@comparison:match(list(GBO)) -) -> list(gap@comparison:match(list(GBO))). -prepend_and_merge(Matches, Match) -> - case {Matches, Match} of - {[], _} -> - [Match]; - - {[{match, First_match} | Rest], {match, _}} -> - [{match, - begin - _pipe = erlang:element(2, Match), - gleam@list:append(_pipe, First_match) - end} | - Rest]; - - {[{no_match, First_match@1} | Rest@1], {no_match, _}} -> - [{no_match, - begin - _pipe@1 = erlang:element(2, Match), - gleam@list:append(_pipe@1, First_match@1) - end} | - Rest@1]; - - {Matches@1, Match@1} -> - [Match@1 | Matches@1] - end. - --spec append_and_merge( - list(gap@comparison:match(list(GBX))), - gap@comparison:match(list(GBX)) -) -> list(gap@comparison:match(list(GBX))). -append_and_merge(Matches, Match) -> - _pipe@3 = case {begin - _pipe = Matches, - gleam@list:reverse(_pipe) - end, - Match} of - {[], _} -> - [Match]; - - {[{match, First_match} | Rest], {match, _}} -> - [{match, - begin - _pipe@1 = First_match, - gleam@list:append(_pipe@1, erlang:element(2, Match)) - end} | - Rest]; - - {[{no_match, First_match@1} | Rest@1], {no_match, _}} -> - [{no_match, - begin - _pipe@2 = First_match@1, - gleam@list:append(_pipe@2, erlang:element(2, Match)) - end} | - Rest@1]; - - {Matches@1, Match@1} -> - [Match@1 | Matches@1] - end, - gleam@list:reverse(_pipe@3). - --spec collect_matches( - gleam@map:map_(GFY, any()), - list(GCH), - fun((GFY) -> integer()) -) -> list(gap@comparison:match(list(GCH))). -collect_matches(Tracking, Str, Extract_fun) -> - Matching_indexes = begin - _pipe = gleam@map:keys(Tracking), - _pipe@1 = gleam@list:map(_pipe, Extract_fun), - gleam@set:from_list(_pipe@1) - end, - Matches = begin - _pipe@2 = Str, - gleam@list:index_map( - _pipe@2, - fun(Index, Item) -> - case gleam@set:contains(Matching_indexes, Index) of - true -> - {match, Item}; - - false -> - {no_match, Item} - end - end - ) - end, - _pipe@3 = Matches, - _pipe@4 = gleam@list:chunk(_pipe@3, fun(Match) -> case Match of - {match, _} -> - true; - - {no_match, _} -> - false - end end), - gleam@list:map(_pipe@4, fun(Match_list) -> case Match_list of - [{match, _} | _] -> - {match, - gleam@list:filter_map( - Match_list, - fun(Match@1) -> case Match@1 of - {match, Item@1} -> - {ok, Item@1}; - - {no_match, _} -> - {error, nil} - end end - )}; - - [{no_match, _} | _] -> - {no_match, - gleam@list:filter_map( - Match_list, - fun(Match@2) -> case Match@2 of - {no_match, Item@2} -> - {ok, Item@2}; - - {match, _} -> - {error, nil} - end end - )} - end end). - --spec back_track( - gleam@map:map_({integer(), integer()}, score(GCL)), - integer(), - integer(), - list({{integer(), integer()}, GCL}) -) -> list({{integer(), integer()}, GCL}). -back_track(Diff_map, First_index, Second_index, Stack) -> - case (First_index =:= 0) orelse (Second_index =:= 0) of - true -> - This_score = begin - _pipe = gleam@map:get(Diff_map, {First_index, Second_index}), - gleam@result:unwrap(_pipe, {score, 0, none}) - end, - case This_score of - {score, _, {some, Item}} -> - [{{First_index, Second_index}, Item} | Stack]; - - _ -> - case {First_index, Second_index} of - {0, A} when A > 0 -> - back_track( - Diff_map, - First_index, - Second_index - 1, - Stack - ); - - {A@1, 0} when A@1 > 0 -> - back_track( - Diff_map, - First_index - 1, - Second_index, - Stack - ); - - {0, 0} -> - Stack; - - {_, _} -> - back_track( - Diff_map, - First_index - 1, - Second_index, - Stack - ) - end - end; - - false -> - This_score@1 = begin - _pipe@1 = gleam@map:get(Diff_map, {First_index, Second_index}), - gleam@result:unwrap(_pipe@1, {score, 0, none}) - end, - case This_score@1 of - {score, _, {some, Item@1}} -> - back_track( - Diff_map, - First_index - 1, - Second_index - 1, - [{{First_index, Second_index}, Item@1} | Stack] - ); - - {score, _, none} -> - Up = begin - _pipe@2 = gleam@map:get( - Diff_map, - {First_index, Second_index - 1} - ), - gleam@result:unwrap(_pipe@2, {score, 0, none}) - end, - Back = begin - _pipe@3 = gleam@map:get( - Diff_map, - {First_index - 1, Second_index} - ), - gleam@result:unwrap(_pipe@3, {score, 0, none}) - end, - case gleam@int:compare( - erlang:element(2, Up), - erlang:element(2, Back) - ) of - gt -> - back_track( - Diff_map, - First_index, - Second_index - 1, - Stack - ); - - lt -> - back_track( - Diff_map, - First_index - 1, - Second_index, - Stack - ); - - eq -> - case {First_index, Second_index} of - {0, A@2} when A@2 > 0 -> - back_track( - Diff_map, - First_index, - Second_index - 1, - Stack - ); - - {A@3, 0} when A@3 > 0 -> - back_track( - Diff_map, - First_index - 1, - Second_index, - Stack - ); - - {0, 0} -> - Stack; - - {_, _} -> - back_track( - Diff_map, - First_index - 1, - Second_index, - Stack - ) - end - end - end - end. - --spec build_diff_map( - GCR, - integer(), - GCR, - integer(), - gleam@map:map_({integer(), integer()}, score(GCR)) -) -> gleam@map:map_({integer(), integer()}, score(GCR)). -build_diff_map(First_item, First_index, Second_item, Second_index, Diff_map) -> - Prev_score = begin - _pipe = gleam@map:get(Diff_map, {First_index - 1, Second_index - 1}), - gleam@result:unwrap(_pipe, {score, 0, none}) - end, - Derived_score_up = begin - _pipe@1 = Diff_map, - _pipe@2 = gleam@map:get(_pipe@1, {First_index, Second_index - 1}), - gleam@result:unwrap(_pipe@2, {score, 0, none}) - end, - Derived_score_back = begin - _pipe@3 = Diff_map, - _pipe@4 = gleam@map:get(_pipe@3, {First_index - 1, Second_index}), - gleam@result:unwrap(_pipe@4, {score, 0, none}) - end, - Derived_score = gleam@int:max( - erlang:element(2, Derived_score_up), - erlang:element(2, Derived_score_back) - ), - This_score = case First_item =:= Second_item of - true -> - {score, erlang:element(2, Prev_score) + 1, {some, First_item}}; - - false -> - {score, Derived_score, none} - end, - _pipe@5 = Diff_map, - gleam@map:insert(_pipe@5, {First_index, Second_index}, This_score). - --spec lcs(list(GBK), list(GBK)) -> gap@comparison:comparison(GBK). -lcs(First_sequence, Second_sequence) -> - Leading_matches = begin - _pipe = gleam@list:zip(First_sequence, Second_sequence), - _pipe@1 = gleam@list:take_while( - _pipe, - fun(Pair) -> erlang:element(1, Pair) =:= erlang:element(2, Pair) end - ), - gleam@list:map(_pipe@1, fun gleam@pair:first/1) - end, - Num_leading_matches = gleam@list:length(Leading_matches), - Trailing_matches = begin - _pipe@2 = gleam@list:zip( - gleam@list:reverse(First_sequence), - gleam@list:reverse(Second_sequence) - ), - _pipe@3 = gleam@list:take_while( - _pipe@2, - fun(Pair@1) -> - erlang:element(1, Pair@1) =:= erlang:element(2, Pair@1) - end - ), - _pipe@4 = gleam@list:map(_pipe@3, fun gleam@pair:first/1), - gleam@list:reverse(_pipe@4) - end, - Num_trailing_matches = gleam@list:length(Trailing_matches), - First_sequence_to_diff = begin - _pipe@5 = First_sequence, - _pipe@6 = gleam@list:drop(_pipe@5, Num_leading_matches), - gleam@list:take( - _pipe@6, - (gleam@list:length(First_sequence) - Num_leading_matches) - Num_trailing_matches - ) - end, - Second_sequence_to_diff = begin - _pipe@7 = Second_sequence, - _pipe@8 = gleam@list:drop(_pipe@7, Num_leading_matches), - gleam@list:take( - _pipe@8, - (gleam@list:length(Second_sequence) - Num_leading_matches) - Num_trailing_matches - ) - end, - Diff_map@2 = begin - _pipe@9 = Second_sequence_to_diff, - gleam@list:index_fold( - _pipe@9, - gleam@map:new(), - fun(Diff_map, Item_second, Index_second) -> - _pipe@10 = First_sequence_to_diff, - gleam@list:index_fold( - _pipe@10, - Diff_map, - fun(Diff_map@1, Item_first, Index_first) -> - build_diff_map( - Item_first, - Index_first, - Item_second, - Index_second, - Diff_map@1 - ) - end - ) - end - ) - end, - {First_segments@1, Second_segments@1} = case {First_sequence_to_diff, - Second_sequence_to_diff} of - {[], []} -> - {[], []}; - - {First_matching, []} -> - {[{no_match, First_matching}], []}; - - {[], Second_matching} -> - {[], [{no_match, Second_matching}]}; - - {First_sequence_to_diff@1, Second_sequence_to_diff@1} -> - Tracking = begin - _pipe@11 = back_track( - Diff_map@2, - gleam@list:length(First_sequence_to_diff@1) - 1, - gleam@list:length(Second_sequence_to_diff@1) - 1, - [] - ), - gleam@map:from_list(_pipe@11) - end, - First_segments = collect_matches( - Tracking, - First_sequence_to_diff@1, - fun(Key) -> - {First, _} = Key, - First - end - ), - Second_segments = collect_matches( - Tracking, - Second_sequence_to_diff@1, - fun(Key@1) -> - {_, Second} = Key@1, - Second - end - ), - {First_segments, Second_segments} - end, - {First_segments_with_leading_trailing, - Second_segments_with_leading_trailing} = case {Leading_matches, - Trailing_matches} of - {[], []} -> - {First_segments@1, Second_segments@1}; - - {[], Trailing_matches@1} -> - {begin - _pipe@12 = First_segments@1, - append_and_merge(_pipe@12, {match, Trailing_matches@1}) - end, - begin - _pipe@13 = Second_segments@1, - append_and_merge(_pipe@13, {match, Trailing_matches@1}) - end}; - - {Leading_matches@1, []} -> - {begin - _pipe@14 = First_segments@1, - prepend_and_merge(_pipe@14, {match, Leading_matches@1}) - end, - begin - _pipe@15 = Second_segments@1, - prepend_and_merge(_pipe@15, {match, Leading_matches@1}) - end}; - - {Leading_matches@2, Trailing_matches@2} -> - {begin - _pipe@16 = First_segments@1, - _pipe@17 = prepend_and_merge( - _pipe@16, - {match, Leading_matches@2} - ), - append_and_merge(_pipe@17, {match, Trailing_matches@2}) - end, - begin - _pipe@18 = Second_segments@1, - _pipe@19 = prepend_and_merge( - _pipe@18, - {match, Leading_matches@2} - ), - append_and_merge(_pipe@19, {match, Trailing_matches@2}) - end} - end, - {list_comparison, - First_segments_with_leading_trailing, - Second_segments_with_leading_trailing}. diff --git a/aoc2023/build/packages/gap/src/gap.gleam b/aoc2023/build/packages/gap/src/gap.gleam deleted file mode 100644 index 7eb0e7f..0000000 --- a/aoc2023/build/packages/gap/src/gap.gleam +++ /dev/null @@ -1,438 +0,0 @@ -import gleam/string -import gleam/list -import gleam/pair -import gleam/map.{type Map} -import gleam/result -import gleam/option.{type Option, None, Some} -import gleam/int -import gleam/order.{Eq, Gt, Lt} -import gleam/set -import gap/comparison.{ - type Comparison, type Match, type Segments, ListComparison, Match, NoMatch, - StringComparison, -} -import gap/styled_comparison.{type StyledComparison} -import gap/styling.{ - first_highlight_default, from_comparison, highlight, no_highlight, - second_highlight_default, to_styled_comparison, -} -import gap/myers.{type Edit, Del, Eq as MyerEq, Ins} - -type MatchedItem(a) = - #(#(Int, Int), a) - -type Score(a) { - Score(value: Int, item: Option(a)) -} - -type DiffMap(a) = - Map(#(Int, Int), Score(a)) - -/// Creates a `StyledComparison` from `Comparison` using default values for -/// highting and serialization. -/// -/// ## Example -/// -/// ```gleam -/// > compare_strings("abc", "abe") |> to_styled() -/// ``` -/// This will return a `StyledComparison(first, second)` where "c" in `first` is green -/// and "e" in `second` is red. -pub fn to_styled(comparison: Comparison(a)) -> StyledComparison { - comparison - |> from_comparison() - |> highlight(first_highlight_default, second_highlight_default, no_highlight) - |> to_styled_comparison() -} - -/// Compare two string and return a `StringComparison` which will be styled as string -/// when passed to `to_styled` -/// -/// Will use the default `myers` algorithm -pub fn compare_strings(first: String, second: String) -> Comparison(String) { - let comparison = - compare_lists(string.to_graphemes(first), string.to_graphemes(second)) - case comparison { - ListComparison(first, second) -> StringComparison(first, second) - StringComparison(first, second) -> StringComparison(first, second) - } -} - -/// Compare two string and return a `StringComparison` which will be styled as string -/// when passed to `to_styled` -/// -/// Algorithm can be used to select either `myers` or the legacy `lcs` algorithm -pub fn compare_strings_with_algorithm( - first: String, - second: String, - algorithm, -) -> Comparison(String) { - let comparison = - algorithm(string.to_graphemes(first), string.to_graphemes(second)) - case comparison { - ListComparison(first, second) -> StringComparison(first, second) - StringComparison(first, second) -> StringComparison(first, second) - } -} - -/// Compare two lists and return a `ListComparison` which will be styled as list -/// when passed to `to_styled` -/// -/// Will use the default `myers` algorithm -pub fn compare_lists( - first_sequence: List(a), - second_sequence: List(a), -) -> Comparison(a) { - myers(first_sequence, second_sequence) -} - -/// Compare two lists and return a `ListComparison` which will be styled as list -/// when passed to `to_styled` -/// -/// Algorithm can be used to select either `myers` or the legacy `lcs` algorithm -pub fn compare_lists_with_algorithm( - first_sequence: List(a), - second_sequence: List(a), - algorithm, -) -> Comparison(a) { - algorithm(first_sequence, second_sequence) -} - -/// An adapter for the the `myers` algorithm. -/// Intended to be use as an argument to `compare_strings_with_algorithm` or -/// `compare_lists_with_algorithm` -pub fn myers(first_sequence: List(a), second_sequence: List(a)) -> Comparison(a) { - let edits = myers.difference(first_sequence, second_sequence) - edits - |> list.reverse() - |> list.fold( - ListComparison([], []), - fn(comparison: Comparison(a), edit: Edit(a)) { - case comparison { - ListComparison(first, second) -> { - case edit { - MyerEq(segment) -> - ListComparison( - [Match(segment), ..first], - [Match(segment), ..second], - ) - Ins(segment) -> ListComparison(first, [NoMatch(segment), ..second]) - Del(segment) -> ListComparison([NoMatch(segment), ..first], second) - } - } - StringComparison(..) -> comparison - } - }, - ) -} - -/// An adapter for the the `lcs` (longest common subsequence) algorithm. -/// Intended to be use as an argument to `compare_strings_with_algorithm` or -/// `compare_lists_with_algorithm` -pub fn lcs(first_sequence: List(a), second_sequence: List(a)) -> Comparison(a) { - let leading_matches = - list.zip(first_sequence, second_sequence) - |> list.take_while(fn(pair) { pair.0 == pair.1 }) - |> list.map(pair.first) - let num_leading_matches = list.length(leading_matches) - let trailing_matches = - list.zip(list.reverse(first_sequence), list.reverse(second_sequence)) - |> list.take_while(fn(pair) { pair.0 == pair.1 }) - |> list.map(pair.first) - |> list.reverse() - let num_trailing_matches = list.length(trailing_matches) - let first_sequence_to_diff = - first_sequence - |> list.drop(num_leading_matches) - |> list.take( - list.length(first_sequence) - num_leading_matches - num_trailing_matches, - ) - let second_sequence_to_diff = - second_sequence - |> list.drop(num_leading_matches) - |> list.take( - list.length(second_sequence) - num_leading_matches - num_trailing_matches, - ) - - let diff_map = - second_sequence_to_diff - |> list.index_fold( - map.new(), - fn(diff_map, item_second, index_second) { - first_sequence_to_diff - |> list.index_fold( - diff_map, - fn(diff_map, item_first, index_first) { - build_diff_map( - item_first, - index_first, - item_second, - index_second, - diff_map, - ) - }, - ) - }, - ) - let #(first_segments, second_segments) = case - first_sequence_to_diff, - second_sequence_to_diff - { - [], [] -> #([], []) - first_matching, [] -> #([NoMatch(first_matching)], []) - [], second_matching -> #([], [NoMatch(second_matching)]) - first_sequence_to_diff, second_sequence_to_diff -> { - let tracking = - back_track( - diff_map, - list.length(first_sequence_to_diff) - 1, - list.length(second_sequence_to_diff) - 1, - [], - ) - |> map.from_list() - - let first_segments = - collect_matches( - tracking, - first_sequence_to_diff, - fn(key) { - let #(first, _) = key - first - }, - ) - let second_segments = - collect_matches( - tracking, - second_sequence_to_diff, - fn(key) { - let #(_, second) = key - second - }, - ) - #(first_segments, second_segments) - } - } - - let #( - first_segments_with_leading_trailing, - second_segments_with_leading_trailing, - ) = case leading_matches, trailing_matches { - [], [] -> #(first_segments, second_segments) - [], trailing_matches -> #( - first_segments - |> append_and_merge(Match(trailing_matches)), - second_segments - |> append_and_merge(Match(trailing_matches)), - ) - leading_matches, [] -> #( - first_segments - |> prepend_and_merge(Match(leading_matches)), - second_segments - |> prepend_and_merge(Match(leading_matches)), - ) - leading_matches, trailing_matches -> #( - first_segments - |> prepend_and_merge(Match(leading_matches)) - |> append_and_merge(Match(trailing_matches)), - second_segments - |> prepend_and_merge(Match(leading_matches)) - |> append_and_merge(Match(trailing_matches)), - ) - } - - ListComparison( - first_segments_with_leading_trailing, - second_segments_with_leading_trailing, - ) -} - -fn prepend_and_merge( - matches: List(Match(List(a))), - match: Match(List(a)), -) -> List(Match(List(a))) { - case matches, match { - [], _ -> [match] - [Match(first_match), ..rest], Match(_) -> [ - Match( - match.item - |> list.append(first_match), - ), - ..rest - ] - [NoMatch(first_match), ..rest], NoMatch(_) -> [ - NoMatch( - match.item - |> list.append(first_match), - ), - ..rest - ] - matches, match -> [match, ..matches] - } -} - -fn append_and_merge( - matches: List(Match(List(a))), - match: Match(List(a)), -) -> List(Match(List(a))) { - case - matches - |> list.reverse(), - match - { - [], _ -> [match] - [Match(first_match), ..rest], Match(_) -> [ - Match( - first_match - |> list.append(match.item), - ), - ..rest - ] - [NoMatch(first_match), ..rest], NoMatch(_) -> [ - NoMatch( - first_match - |> list.append(match.item), - ), - ..rest - ] - matches, match -> [match, ..matches] - } - |> list.reverse() -} - -fn collect_matches(tracking, str: List(a), extract_fun) -> Segments(a) { - let matching_indexes = - map.keys(tracking) - |> list.map(extract_fun) - |> set.from_list() - - let matches = - str - |> list.index_map(fn(index, item) { - case set.contains(matching_indexes, index) { - True -> Match(item) - False -> NoMatch(item) - } - }) - - matches - |> list.chunk(fn(match) { - case match { - Match(_) -> True - NoMatch(_) -> False - } - }) - |> list.map(fn(match_list) { - case match_list { - [Match(_), ..] -> - Match(list.filter_map( - match_list, - fn(match) { - case match { - Match(item) -> Ok(item) - NoMatch(_) -> Error(Nil) - } - }, - )) - [NoMatch(_), ..] -> - NoMatch(list.filter_map( - match_list, - fn(match) { - case match { - NoMatch(item) -> Ok(item) - Match(_) -> Error(Nil) - } - }, - )) - } - }) -} - -fn back_track( - diff_map: DiffMap(a), - first_index: Int, - second_index: Int, - stack: List(MatchedItem(a)), -) -> List(MatchedItem(a)) { - case first_index == 0 || second_index == 0 { - True -> { - let this_score = - map.get(diff_map, #(first_index, second_index)) - |> result.unwrap(Score(0, None)) - case this_score { - Score(_, Some(item)) -> [#(#(first_index, second_index), item), ..stack] - _ -> - case first_index, second_index { - 0, a if a > 0 -> - back_track(diff_map, first_index, second_index - 1, stack) - a, 0 if a > 0 -> - back_track(diff_map, first_index - 1, second_index, stack) - 0, 0 -> stack - _, _ -> back_track(diff_map, first_index - 1, second_index, stack) - } - } - } - False -> { - let this_score = - map.get(diff_map, #(first_index, second_index)) - |> result.unwrap(Score(0, None)) - case this_score { - Score(_, Some(item)) -> - back_track( - diff_map, - first_index - 1, - second_index - 1, - [#(#(first_index, second_index), item), ..stack], - ) - Score(_, None) -> { - let up = - map.get(diff_map, #(first_index, second_index - 1)) - |> result.unwrap(Score(0, None)) - let back = - map.get(diff_map, #(first_index - 1, second_index)) - |> result.unwrap(Score(0, None)) - case int.compare(up.value, back.value) { - Gt -> back_track(diff_map, first_index, second_index - 1, stack) - Lt -> back_track(diff_map, first_index - 1, second_index, stack) - Eq -> - case first_index, second_index { - 0, a if a > 0 -> - back_track(diff_map, first_index, second_index - 1, stack) - a, 0 if a > 0 -> - back_track(diff_map, first_index - 1, second_index, stack) - 0, 0 -> stack - _, _ -> - back_track(diff_map, first_index - 1, second_index, stack) - } - } - } - } - } - } -} - -fn build_diff_map( - first_item: a, - first_index: Int, - second_item: a, - second_index: Int, - diff_map: DiffMap(a), -) -> DiffMap(a) { - let prev_score = - map.get(diff_map, #(first_index - 1, second_index - 1)) - |> result.unwrap(Score(0, None)) - let derived_score_up = - diff_map - |> map.get(#(first_index, second_index - 1)) - |> result.unwrap(Score(0, None)) - let derived_score_back = - diff_map - |> map.get(#(first_index - 1, second_index)) - |> result.unwrap(Score(0, None)) - let derived_score = int.max(derived_score_up.value, derived_score_back.value) - let this_score = case first_item == second_item { - True -> Score(prev_score.value + 1, Some(first_item)) - False -> Score(derived_score, None) - } - diff_map - |> map.insert(#(first_index, second_index), this_score) -} diff --git a/aoc2023/build/packages/gap/src/gap/comparison.gleam b/aoc2023/build/packages/gap/src/gap/comparison.gleam deleted file mode 100644 index da30c29..0000000 --- a/aoc2023/build/packages/gap/src/gap/comparison.gleam +++ /dev/null @@ -1,22 +0,0 @@ -/// Comparison of two strings or lists -/// -/// The comparison consists of two lists of matched segments. The segments represent -/// a sequence of succeeding matches or non-matches (up until the next match/non-match) -/// -/// For lists the elements in the segment will be same as the elements in the list, and -/// for strings the elements will be the graphemes of the string -pub type Comparison(a) { - ListComparison(first: Segments(a), second: Segments(a)) - StringComparison(first: Segments(String), second: Segments(String)) -} - -/// Indicating that the item has a matching (`Match`) or no matching (`NoMatch`) item in the -/// other string/list -pub type Match(a) { - Match(item: a) - NoMatch(item: a) -} - -/// List of segments of succeeding matches / non-matches -pub type Segments(a) = - List(Match(List(a))) diff --git a/aoc2023/build/packages/gap/src/gap/myers.gleam b/aoc2023/build/packages/gap/src/gap/myers.gleam deleted file mode 100644 index f0b8ddc..0000000 --- a/aoc2023/build/packages/gap/src/gap/myers.gleam +++ /dev/null @@ -1,122 +0,0 @@ -import gleam/list - -pub type Edit(a) { - Eq(List(a)) - Del(List(a)) - Ins(List(a)) -} - -type Path(a) { - Path(x: Int, y: Int, list1: List(a), list2: List(a), edits: List(Edit(a))) -} - -type Status(a) { - Done(edits: List(Edit(a))) - Next(paths: List(Path(a))) - Cont(path: Path(a)) -} - -/// The algorithm is outlined in the -/// "An O(ND) Difference Algorithm and Its Variations" paper by E. Myers. -/// -/// Adapted from the implementation of "myers_difference" in Elixirs List module -pub fn difference(list1: List(a), list2: List(a)) -> List(Edit(a)) { - let path = Path(0, 0, list1, list2, []) - find_script(0, list.length(list1) + list.length(list2), [path]) -} - -fn find_script(envelope: Int, max: Int, paths: List(Path(a))) { - case envelope > max { - True -> [] - False -> { - case each_diagonal(-envelope, envelope, paths, []) { - Done(edits) -> compact_reverse(edits, []) - Next(paths) -> find_script(envelope + 1, max, paths) - _ -> panic as "Didn't expect a Cont here" - } - } - } -} - -fn compact_reverse(edits: List(Edit(a)), acc: List(Edit(a))) -> List(Edit(a)) { - case edits, acc { - [], acc -> acc - [Eq(elem), ..rest], [Eq(result), ..acc_rest] -> - compact_reverse(rest, [Eq(list.flatten([elem, result])), ..acc_rest]) - [Del(elem), ..rest], [Del(result), ..acc_rest] -> - compact_reverse(rest, [Del(list.flatten([elem, result])), ..acc_rest]) - [Ins(elem), ..rest], [Ins(result), ..acc_rest] -> - compact_reverse(rest, [Ins(list.flatten([elem, result])), ..acc_rest]) - [Eq(elem), ..rest], acc -> compact_reverse(rest, [Eq(elem), ..acc]) - [Del(elem), ..rest], acc -> compact_reverse(rest, [Del(elem), ..acc]) - [Ins(elem), ..rest], acc -> compact_reverse(rest, [Ins(elem), ..acc]) - } -} - -fn each_diagonal( - diag: Int, - limit: Int, - paths: List(Path(a)), - next_paths: List(Path(a)), -) -> Status(a) { - case diag > limit { - True -> Next(list.reverse(next_paths)) - False -> { - let #(path, rest) = proceed_path(diag, limit, paths) - case follow_snake(path) { - Cont(path) -> each_diagonal(diag + 2, limit, rest, [path, ..next_paths]) - other -> other - } - } - } -} - -fn proceed_path( - diag: Int, - limit: Int, - paths: List(Path(a)), -) -> #(Path(a), List(Path(a))) { - let neg_limit = -limit - case diag, limit, paths { - 0, 0, [path] -> #(path, []) - diag, _limit, [path, ..] as paths if diag == neg_limit -> #( - move_down(path), - paths, - ) - diag, limit, [path, ..] as paths if diag == limit -> #( - move_right(path), - paths, - ) - _diag, _limit, [path1, path2, ..rest] -> { - case path1.y > path2.y { - True -> #(move_right(path1), [path2, ..rest]) - False -> #(move_down(path2), [path2, ..rest]) - } - } - } -} - -fn move_right(path: Path(a)) -> Path(a) { - case path { - Path(x, y, list1, [elem, ..rest], edits) -> - Path(x + 1, y, list1, rest, [Ins([elem]), ..edits]) - Path(x, y, list1, [], edits) -> Path(x + 1, y, list1, [], edits) - } -} - -fn move_down(path: Path(a)) -> Path(a) { - case path { - Path(x, y, [elem, ..rest], list2, edits) -> - Path(x, y + 1, rest, list2, [Del([elem]), ..edits]) - Path(x, y, [], list2, edits) -> Path(x, y + 1, [], list2, edits) - } -} - -fn follow_snake(path: Path(a)) -> Status(a) { - case path { - Path(x, y, [elem1, ..rest1], [elem2, ..rest2], edits) if elem1 == elem2 -> - follow_snake(Path(x + 1, y + 1, rest1, rest2, [Eq([elem1]), ..edits])) - Path(_x, _y, [], [], edits) -> Done(edits) - _ -> Cont(path) - } -} diff --git a/aoc2023/build/packages/gap/src/gap/styled_comparison.gleam b/aoc2023/build/packages/gap/src/gap/styled_comparison.gleam deleted file mode 100644 index 7103c2e..0000000 --- a/aoc2023/build/packages/gap/src/gap/styled_comparison.gleam +++ /dev/null @@ -1,4 +0,0 @@ -/// A comparison where the parts have been styled (serialized and highlighted) -pub type StyledComparison { - StyledComparison(first: String, second: String) -} diff --git a/aoc2023/build/packages/gap/src/gap/styling.gleam b/aoc2023/build/packages/gap/src/gap/styling.gleam deleted file mode 100644 index 623ae8a..0000000 --- a/aoc2023/build/packages/gap/src/gap/styling.gleam +++ /dev/null @@ -1,233 +0,0 @@ -import gleam/option.{type Option, None, Some} -import gleam/list -import gleam/string -import gleam_community/ansi -import gap/comparison.{ - type Comparison, type Segments, ListComparison, Match, NoMatch, - StringComparison, -} -import gap/styled_comparison.{type StyledComparison, StyledComparison} - -/// The `Highlighter`takes a string representation of the item that was not matching -/// and should return a string representation that can be used to visually indicate that -/// it is a non-matching item. -/// -/// The default implementation of the highlighters uses the -/// [gleam_community/ansi](https://hexdocs.pm/gleam_community_ansi/index.html) library -/// to set a different color for the item, but any type if indication can be used as long -/// as it returns a valid string -pub type Highlighter = - fn(String) -> String - -/// `Part` is used to indicate to a custom serializer if it should produce a serialization -/// based on a segment with items or the final string that contains already serialized segments -pub type Part(a) { - /// `acc` the already serialized part of the result, `part` is the current segment that should be serialized and appended and `highlighter` is the `Highlighter` that can be used to indicate non-matching items - Part(acc: String, part: List(a), highlight: Highlighter) - /// `all` is a string representing all serialized segments. This can be useful if some string should be prepended/appended to the final result - All(all: String) -} - -/// A `Serializer`can be used to create string representation of the comparison results -/// -/// See [serialize](#serialize) for adding custom serializers and [mk_generic_serializer](#mk_generic_serializer) -pub type Serializer(a) = - fn(Part(a)) -> String - -/// Highlighters to use for indicating matches / non-matches -/// -/// `first` is used to highlight non-matches in the first string/list -/// `second` is used to highlight non-matches in the second string/list -/// `matching` is used to highlight matches in the both strings/lists -pub type Highlighters { - Highlighters(first: Highlighter, second: Highlighter, matching: Highlighter) -} - -/// Styling of a `Comparison` -/// -/// See [from_comparison](#from_comparison) -pub opaque type Styling(a) { - Styling( - comparison: Comparison(a), - serializer: Option(Serializer(a)), - highlight: Option(Highlighters), - ) -} - -/// Create a new `Styling` from a `Comparison` -/// -/// The `Styling` can be customized by adding highlighters and a serializer -/// See [highlight](#highlight) and [serialize](#serialize) -pub fn from_comparison(comparison: Comparison(a)) -> Styling(a) { - Styling(comparison, None, None) -} - -/// Add highlighters to the `Styling` -/// -/// The highlighters are used to mark the matching/non-matching items in the -/// first/second list/string -pub fn highlight( - styling: Styling(a), - first: Highlighter, - second: Highlighter, - matching: Highlighter, -) -> Styling(a) { - Styling(..styling, highlight: Some(Highlighters(first, second, matching))) -} - -/// Add a serializer to the `Styling` -/// -/// The serializer is used to create string representation of the items in the segments of the `Comparison` -/// See [Part](#part) for details -/// -/// > **NOTE:** `StringComparison` will always use the default string serializer (concatenating the graphemes). -/// > If there is a need for custom serialization of `StringComparison` convert the string to a list of -/// > graphemes and treat it as a `ListComparison` -pub fn serialize(styling: Styling(a), serializer: Serializer(a)) -> Styling(a) { - Styling(..styling, serializer: Some(serializer)) -} - -/// Creates a styled comparison using either custom highlighters/serializer if they where added or default -/// highlighters and/or serializer -pub fn to_styled_comparison(styling: Styling(a)) -> StyledComparison { - let highlight = - styling.highlight - |> option.unwrap(Highlighters( - first_highlight_default, - second_highlight_default, - no_highlight, - )) - case styling.comparison { - StringComparison(first, second) -> - to_strings( - first, - second, - // NOTE: Using string serializer here because otherwise we need to have a specific string serializer on the styling - string_serializer, - highlight.first, - highlight.second, - highlight.matching, - ) - ListComparison(first, second) -> - to_strings( - first, - second, - option.unwrap(styling.serializer, generic_serializer), - highlight.first, - highlight.second, - highlight.matching, - ) - } -} - -/// Default highlighter for the first string/list in the comparison -pub fn first_highlight_default(string: String) -> String { - case string { - " " -> - string - |> ansi.underline() - |> ansi.bold() - |> ansi.green() - - _ -> - string - |> ansi.green() - |> ansi.bold() - } -} - -/// Default highlighter for the second string/list in the comparison -pub fn second_highlight_default(string: String) -> String { - case string { - " " -> - string - |> ansi.underline() - |> ansi.bold() - |> ansi.red() - - _ -> - string - |> ansi.red() - |> ansi.bold() - } -} - -/// Default highlighter used for matching items -pub fn no_highlight(string: String) -> String { - string -} - -fn string_serializer(part: Part(String)) -> String { - case part { - Part(acc, sequence, highlight) -> - acc <> { - sequence - |> list.map(highlight) - |> string.join("") - } - All(string) -> string - } -} - -fn generic_serializer(part: Part(a)) -> String { - mk_generic_serializer(", ", fn(all) { "[" <> all <> "]" })(part) -} - -/// Creates a generic serializer that uses `separator` between all items and calls -/// `around` for possibility to prepend/append strings to the final result -pub fn mk_generic_serializer(separator: String, around: fn(String) -> String) { - fn(part) { - case part { - Part(acc, sequence, highlight) -> { - let segment_separator = case acc { - "" -> "" - _ -> separator - } - acc <> segment_separator <> { - sequence - |> list.map(string.inspect) - |> list.map(highlight) - |> string.join(separator) - } - } - All(string) -> around(string) - } - } -} - -fn to_strings( - first: Segments(a), - second: Segments(a), - serializer: Serializer(a), - first_highlight: Highlighter, - second_highlight: Highlighter, - no_highlight: Highlighter, -) -> StyledComparison { - let first_styled = - first - |> list.fold( - "", - fn(str, match) { - case match { - Match(item) -> serializer(Part(str, item, no_highlight)) - NoMatch(item) -> serializer(Part(str, item, first_highlight)) - } - }, - ) - let second_styled = - second - |> list.fold( - "", - fn(str, match) { - case match { - Match(item) -> serializer(Part(str, item, no_highlight)) - NoMatch(item) -> serializer(Part(str, item, second_highlight)) - } - }, - ) - - StyledComparison( - serializer(All(first_styled)), - serializer(All(second_styled)), - ) -} diff --git a/aoc2023/build/packages/gap/src/gap@comparison.erl b/aoc2023/build/packages/gap/src/gap@comparison.erl deleted file mode 100644 index 36bd1c3..0000000 --- a/aoc2023/build/packages/gap/src/gap@comparison.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gap@comparison). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([comparison/1, match/1]). - --type comparison(FQT) :: {list_comparison, - list(match(list(FQT))), - list(match(list(FQT)))} | - {string_comparison, - list(match(list(binary()))), - list(match(list(binary())))}. - --type match(FQU) :: {match, FQU} | {no_match, FQU}. - - diff --git a/aoc2023/build/packages/gap/src/gap@myers.erl b/aoc2023/build/packages/gap/src/gap@myers.erl deleted file mode 100644 index 6a8ad35..0000000 --- a/aoc2023/build/packages/gap/src/gap@myers.erl +++ /dev/null @@ -1,156 +0,0 @@ --module(gap@myers). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([difference/2]). --export_type([edit/1, path/1, status/1]). - --type edit(FUV) :: {eq, list(FUV)} | {del, list(FUV)} | {ins, list(FUV)}. - --type path(FUW) :: {path, - integer(), - integer(), - list(FUW), - list(FUW), - list(edit(FUW))}. - --type status(FUX) :: {done, list(edit(FUX))} | - {next, list(path(FUX))} | - {cont, path(FUX)}. - --spec compact_reverse(list(edit(FVH)), list(edit(FVH))) -> list(edit(FVH)). -compact_reverse(Edits, Acc) -> - case {Edits, Acc} of - {[], Acc@1} -> - Acc@1; - - {[{eq, Elem} | Rest], [{eq, Result} | Acc_rest]} -> - compact_reverse( - Rest, - [{eq, gleam@list:flatten([Elem, Result])} | Acc_rest] - ); - - {[{del, Elem@1} | Rest@1], [{del, Result@1} | Acc_rest@1]} -> - compact_reverse( - Rest@1, - [{del, gleam@list:flatten([Elem@1, Result@1])} | Acc_rest@1] - ); - - {[{ins, Elem@2} | Rest@2], [{ins, Result@2} | Acc_rest@2]} -> - compact_reverse( - Rest@2, - [{ins, gleam@list:flatten([Elem@2, Result@2])} | Acc_rest@2] - ); - - {[{eq, Elem@3} | Rest@3], Acc@2} -> - compact_reverse(Rest@3, [{eq, Elem@3} | Acc@2]); - - {[{del, Elem@4} | Rest@4], Acc@3} -> - compact_reverse(Rest@4, [{del, Elem@4} | Acc@3]); - - {[{ins, Elem@5} | Rest@5], Acc@4} -> - compact_reverse(Rest@5, [{ins, Elem@5} | Acc@4]) - end. - --spec move_right(path(FWA)) -> path(FWA). -move_right(Path) -> - case Path of - {path, X, Y, List1, [Elem | Rest], Edits} -> - {path, X + 1, Y, List1, Rest, [{ins, [Elem]} | Edits]}; - - {path, X@1, Y@1, List1@1, [], Edits@1} -> - {path, X@1 + 1, Y@1, List1@1, [], Edits@1} - end. - --spec move_down(path(FWD)) -> path(FWD). -move_down(Path) -> - case Path of - {path, X, Y, [Elem | Rest], List2, Edits} -> - {path, X, Y + 1, Rest, List2, [{del, [Elem]} | Edits]}; - - {path, X@1, Y@1, [], List2@1, Edits@1} -> - {path, X@1, Y@1 + 1, [], List2@1, Edits@1} - end. - --spec proceed_path(integer(), integer(), list(path(FVU))) -> {path(FVU), - list(path(FVU))}. -proceed_path(Diag, Limit, Paths) -> - Neg_limit = - Limit, - case {Diag, Limit, Paths} of - {0, 0, [Path]} -> - {Path, []}; - - {Diag@1, _, [Path@1 | _] = Paths@1} when Diag@1 =:= Neg_limit -> - {move_down(Path@1), Paths@1}; - - {Diag@2, Limit@1, [Path@2 | _] = Paths@2} when Diag@2 =:= Limit@1 -> - {move_right(Path@2), Paths@2}; - - {_, _, [Path1, Path2 | Rest]} -> - case erlang:element(3, Path1) > erlang:element(3, Path2) of - true -> - {move_right(Path1), [Path2 | Rest]}; - - false -> - {move_down(Path2), [Path2 | Rest]} - end - end. - --spec follow_snake(path(FWG)) -> status(FWG). -follow_snake(Path) -> - case Path of - {path, X, Y, [Elem1 | Rest1], [Elem2 | Rest2], Edits} when Elem1 =:= Elem2 -> - follow_snake( - {path, X + 1, Y + 1, Rest1, Rest2, [{eq, [Elem1]} | Edits]} - ); - - {path, _, _, [], [], Edits@1} -> - {done, Edits@1}; - - _ -> - {cont, Path} - end. - --spec each_diagonal(integer(), integer(), list(path(FVO)), list(path(FVO))) -> status(FVO). -each_diagonal(Diag, Limit, Paths, Next_paths) -> - case Diag > Limit of - true -> - {next, gleam@list:reverse(Next_paths)}; - - false -> - {Path, Rest} = proceed_path(Diag, Limit, Paths), - case follow_snake(Path) of - {cont, Path@1} -> - each_diagonal(Diag + 2, Limit, Rest, [Path@1 | Next_paths]); - - Other -> - Other - end - end. - --spec find_script(integer(), integer(), list(path(FVD))) -> list(edit(FVD)). -find_script(Envelope, Max, Paths) -> - case Envelope > Max of - true -> - []; - - false -> - case each_diagonal(- Envelope, Envelope, Paths, []) of - {done, Edits} -> - compact_reverse(Edits, []); - - {next, Paths@1} -> - find_script(Envelope + 1, Max, Paths@1); - - _ -> - erlang:error(#{gleam_error => panic, - message => <<"Didn't expect a Cont here"/utf8>>, - module => <<"gap/myers"/utf8>>, - function => <<"find_script"/utf8>>, - line => 35}) - end - end. - --spec difference(list(FUY), list(FUY)) -> list(edit(FUY)). -difference(List1, List2) -> - Path = {path, 0, 0, List1, List2, []}, - find_script(0, gleam@list:length(List1) + gleam@list:length(List2), [Path]). diff --git a/aoc2023/build/packages/gap/src/gap@styled_comparison.erl b/aoc2023/build/packages/gap/src/gap@styled_comparison.erl deleted file mode 100644 index 14cc390..0000000 --- a/aoc2023/build/packages/gap/src/gap@styled_comparison.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gap@styled_comparison). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([styled_comparison/0]). - --type styled_comparison() :: {styled_comparison, binary(), binary()}. - - diff --git a/aoc2023/build/packages/gap/src/gap@styling.erl b/aoc2023/build/packages/gap/src/gap@styling.erl deleted file mode 100644 index ba226c3..0000000 --- a/aoc2023/build/packages/gap/src/gap@styling.erl +++ /dev/null @@ -1,202 +0,0 @@ --module(gap@styling). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_comparison/1, highlight/4, serialize/2, first_highlight_default/1, second_highlight_default/1, no_highlight/1, mk_generic_serializer/2, to_styled_comparison/1]). --export_type([part/1, highlighters/0, styling/1]). - --type part(FRE) :: {part, binary(), list(FRE), fun((binary()) -> binary())} | - {all, binary()}. - --type highlighters() :: {highlighters, - fun((binary()) -> binary()), - fun((binary()) -> binary()), - fun((binary()) -> binary())}. - --opaque styling(FRF) :: {styling, - gap@comparison:comparison(FRF), - gleam@option:option(fun((part(FRF)) -> binary())), - gleam@option:option(highlighters())}. - --spec from_comparison(gap@comparison:comparison(FRI)) -> styling(FRI). -from_comparison(Comparison) -> - {styling, Comparison, none, none}. - --spec highlight( - styling(FRL), - fun((binary()) -> binary()), - fun((binary()) -> binary()), - fun((binary()) -> binary()) -) -> styling(FRL). -highlight(Styling, First, Second, Matching) -> - erlang:setelement( - 4, - Styling, - {some, {highlighters, First, Second, Matching}} - ). - --spec serialize(styling(FRO), fun((part(FRO)) -> binary())) -> styling(FRO). -serialize(Styling, Serializer) -> - erlang:setelement(3, Styling, {some, Serializer}). - --spec first_highlight_default(binary()) -> binary(). -first_highlight_default(String) -> - case String of - <<" "/utf8>> -> - _pipe = String, - _pipe@1 = gleam_community@ansi:underline(_pipe), - _pipe@2 = gleam_community@ansi:bold(_pipe@1), - gleam_community@ansi:green(_pipe@2); - - _ -> - _pipe@3 = String, - _pipe@4 = gleam_community@ansi:green(_pipe@3), - gleam_community@ansi:bold(_pipe@4) - end. - --spec second_highlight_default(binary()) -> binary(). -second_highlight_default(String) -> - case String of - <<" "/utf8>> -> - _pipe = String, - _pipe@1 = gleam_community@ansi:underline(_pipe), - _pipe@2 = gleam_community@ansi:bold(_pipe@1), - gleam_community@ansi:red(_pipe@2); - - _ -> - _pipe@3 = String, - _pipe@4 = gleam_community@ansi:red(_pipe@3), - gleam_community@ansi:bold(_pipe@4) - end. - --spec no_highlight(binary()) -> binary(). -no_highlight(String) -> - String. - --spec string_serializer(part(binary())) -> binary(). -string_serializer(Part) -> - case Part of - {part, Acc, Sequence, Highlight} -> - <<Acc/binary, - (begin - _pipe = Sequence, - _pipe@1 = gleam@list:map(_pipe, Highlight), - gleam@string:join(_pipe@1, <<""/utf8>>) - end)/binary>>; - - {all, String} -> - String - end. - --spec mk_generic_serializer(binary(), fun((binary()) -> binary())) -> fun((part(any())) -> binary()). -mk_generic_serializer(Separator, Around) -> - fun(Part) -> case Part of - {part, Acc, Sequence, Highlight} -> - Segment_separator = case Acc of - <<""/utf8>> -> - <<""/utf8>>; - - _ -> - Separator - end, - <<<<Acc/binary, Segment_separator/binary>>/binary, - (begin - _pipe = Sequence, - _pipe@1 = gleam@list:map( - _pipe, - fun gleam@string:inspect/1 - ), - _pipe@2 = gleam@list:map(_pipe@1, Highlight), - gleam@string:join(_pipe@2, Separator) - end)/binary>>; - - {all, String} -> - Around(String) - end end. - --spec generic_serializer(part(any())) -> binary(). -generic_serializer(Part) -> - (mk_generic_serializer( - <<", "/utf8>>, - fun(All) -> <<<<"["/utf8, All/binary>>/binary, "]"/utf8>> end - ))(Part). - --spec to_strings( - list(gap@comparison:match(list(FRY))), - list(gap@comparison:match(list(FRY))), - fun((part(FRY)) -> binary()), - fun((binary()) -> binary()), - fun((binary()) -> binary()), - fun((binary()) -> binary()) -) -> gap@styled_comparison:styled_comparison(). -to_strings( - First, - Second, - Serializer, - First_highlight, - Second_highlight, - No_highlight -) -> - First_styled = begin - _pipe = First, - gleam@list:fold(_pipe, <<""/utf8>>, fun(Str, Match) -> case Match of - {match, Item} -> - Serializer({part, Str, Item, No_highlight}); - - {no_match, Item@1} -> - Serializer({part, Str, Item@1, First_highlight}) - end end) - end, - Second_styled = begin - _pipe@1 = Second, - gleam@list:fold( - _pipe@1, - <<""/utf8>>, - fun(Str@1, Match@1) -> case Match@1 of - {match, Item@2} -> - Serializer({part, Str@1, Item@2, No_highlight}); - - {no_match, Item@3} -> - Serializer({part, Str@1, Item@3, Second_highlight}) - end end - ) - end, - {styled_comparison, - Serializer({all, First_styled}), - Serializer({all, Second_styled})}. - --spec to_styled_comparison(styling(any())) -> gap@styled_comparison:styled_comparison(). -to_styled_comparison(Styling) -> - Highlight = begin - _pipe = erlang:element(4, Styling), - gleam@option:unwrap( - _pipe, - {highlighters, - fun first_highlight_default/1, - fun second_highlight_default/1, - fun no_highlight/1} - ) - end, - case erlang:element(2, Styling) of - {string_comparison, First, Second} -> - to_strings( - First, - Second, - fun string_serializer/1, - erlang:element(2, Highlight), - erlang:element(3, Highlight), - erlang:element(4, Highlight) - ); - - {list_comparison, First@1, Second@1} -> - to_strings( - First@1, - Second@1, - gleam@option:unwrap( - erlang:element(3, Styling), - fun generic_serializer/1 - ), - erlang:element(2, Highlight), - erlang:element(3, Highlight), - erlang:element(4, Highlight) - ) - end. diff --git a/aoc2023/build/packages/gap/src/gap_ffi.mjs b/aoc2023/build/packages/gap/src/gap_ffi.mjs deleted file mode 100644 index 235c80b..0000000 --- a/aoc2023/build/packages/gap/src/gap_ffi.mjs +++ /dev/null @@ -1,431 +0,0 @@ -import { - Error, - List, - Ok, - inspect, - toList, - makeError, - isEqual, -} from "./gleam.mjs"; -import * as $option from "../gleam_stdlib/gleam/option.mjs"; - -const HASHCODE_CACHE = new WeakMap(); -const Nil = undefined; - -class MutableMap { - static #hashcode_cache = new WeakMap(); - - static hash(value) { - let existing = this.#hashcode_cache.get(value); - if (existing) { - return existing; - } else if (value instanceof Object) { - let hashcode = inspect(value); - HASHCODE_CACHE.set(value, hashcode); - return hashcode; - } else { - return value.toString(); - } - } - - constructor() { - this.entries = new globalThis.Map(); - } - - get size() { - return this.entries.size; - } - - inspect() { - let entries = [...this.entries.values()] - .map((pair) => inspect(pair)) - .join(", "); - return `map.from_list([${entries}])`; - } - - toList() { - return List.fromArray([...this.entries.values()]); - } - - insert(k, v) { - this.entries.set(MutableMap.hash(k), [k, v]); - return this; - } - - delete(k) { - this.entries.delete(MutableMap.hash(k)); - return this; - } - - get(key) { - let code = MutableMap.hash(key); - if (this.entries.has(code)) { - return new Ok(this.entries.get(code)[1]); - } else { - return new Error(Nil); - } - } -} - -export function new_mutable_map() { - return new MutableMap(); -} - -export function mutable_map_size(map) { - return map.size; -} - -export function mutable_map_to_list(map) { - return map.toList(); -} - -export function mutable_map_remove(k, map) { - return map.delete(k); -} - -export function mutable_map_get(map, key) { - return map.get(key); -} - -export function mutable_map_insert(key, value, map) { - return map.insert(key, value); -} - -// From map.mjs - -export function size(map) { - return mutable_map_size(map); -} - -export function to_list(map) { - return mutable_map_to_list(map); -} - -export function new$() { - return new_mutable_map(); -} - -export function get(from, get) { - return mutable_map_get(from, get); -} - -function do_has_key(key, map) { - return !isEqual(get(map, key), new Error(undefined)); -} - -export function has_key(map, key) { - return do_has_key(key, map); -} - -export function insert(map, key, value) { - return mutable_map_insert(key, value, map); -} - -function insert_pair(map, pair) { - return insert(map, pair[0], pair[1]); -} - -export function update(map, key, fun) { - let _pipe = map; - let _pipe$1 = get(_pipe, key); - let _pipe$2 = $option.from_result(_pipe$1); - let _pipe$3 = fun(_pipe$2); - return ((_capture) => { - return insert(map, key, _capture); - })(_pipe$3); -} - -export function delete$(map, key) { - return mutable_map_remove(key, map); -} - -function fold_list_of_pair(loop$list, loop$initial) { - while (true) { - let list = loop$list; - let initial = loop$initial; - if (list.hasLength(0)) { - return initial; - } else if (list.atLeastLength(1)) { - let x = list.head; - let rest = list.tail; - loop$list = rest; - loop$initial = insert(initial, x[0], x[1]); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 98, - "fold_list_of_pair", - "No case clause matched", - { values: [list] } - ); - } - } -} - -function do_from_list(list) { - return fold_list_of_pair(list, new$()); -} - -export function from_list(list) { - return do_from_list(list); -} - -function do_fold(loop$list, loop$initial, loop$fun) { - while (true) { - let list = loop$list; - let initial = loop$initial; - let fun = loop$fun; - if (list.hasLength(0)) { - return initial; - } else if (list.atLeastLength(1)) { - let k = list.head[0]; - let v = list.head[1]; - let tail = list.tail; - loop$list = tail; - loop$initial = fun(initial, k, v); - loop$fun = fun; - } else { - throw makeError( - "case_no_match", - "gleam/map", - 558, - "do_fold", - "No case clause matched", - { values: [list] } - ); - } - } -} - -export function fold(map, initial, fun) { - let _pipe = map; - let _pipe$1 = to_list(_pipe); - return do_fold(_pipe$1, initial, fun); -} - -function do_map_values(f, map) { - let f$1 = (map, k, v) => { - return insert(map, k, f(k, v)); - }; - let _pipe = map; - return fold(_pipe, new$(), f$1); -} - -export function map_values(map, fun) { - return do_map_values(fun, map); -} - -function do_filter(f, map) { - let insert$1 = (map, k, v) => { - let $ = f(k, v); - if ($) { - return insert(map, k, v); - } else { - return map; - } - }; - let _pipe = map; - return fold(_pipe, new$(), insert$1); -} - -export function filter(map, property) { - return do_filter(property, map); -} - -function do_keys_acc(loop$list, loop$acc) { - while (true) { - let list = loop$list; - let acc = loop$acc; - if (list.hasLength(0)) { - return reverse_and_concat(acc, toList([])); - } else if (list.atLeastLength(1)) { - let x = list.head; - let xs = list.tail; - loop$list = xs; - loop$acc = toList([x[0]], acc); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 276, - "do_keys_acc", - "No case clause matched", - { values: [list] } - ); - } - } -} - -function do_keys(map) { - let list_of_pairs = (() => { - let _pipe = map; - return to_list(_pipe); - })(); - return do_keys_acc(list_of_pairs, toList([])); -} - -export function keys(map) { - return do_keys(map); -} - -function reverse_and_concat(loop$remaining, loop$accumulator) { - while (true) { - let remaining = loop$remaining; - let accumulator = loop$accumulator; - if (remaining.hasLength(0)) { - return accumulator; - } else if (remaining.atLeastLength(1)) { - let item = remaining.head; - let rest = remaining.tail; - loop$remaining = rest; - loop$accumulator = toList([item], accumulator); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 269, - "reverse_and_concat", - "No case clause matched", - { values: [remaining] } - ); - } - } -} - -function do_values_acc(loop$list, loop$acc) { - while (true) { - let list = loop$list; - let acc = loop$acc; - if (list.hasLength(0)) { - return reverse_and_concat(acc, toList([])); - } else if (list.atLeastLength(1)) { - let x = list.head; - let xs = list.tail; - loop$list = xs; - loop$acc = toList([x[1]], acc); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 314, - "do_values_acc", - "No case clause matched", - { values: [list] } - ); - } - } -} - -function do_values(map) { - let list_of_pairs = (() => { - let _pipe = map; - return to_list(_pipe); - })(); - return do_values_acc(list_of_pairs, toList([])); -} - -export function values(map) { - return do_values(map); -} - -function insert_taken(loop$map, loop$desired_keys, loop$acc) { - while (true) { - let map = loop$map; - let desired_keys = loop$desired_keys; - let acc = loop$acc; - let insert$1 = (taken, key) => { - let $ = get(map, key); - if ($.isOk()) { - let value = $[0]; - return insert(taken, key, value); - } else { - return taken; - } - }; - if (desired_keys.hasLength(0)) { - return acc; - } else if (desired_keys.atLeastLength(1)) { - let x = desired_keys.head; - let xs = desired_keys.tail; - loop$map = map; - loop$desired_keys = xs; - loop$acc = insert$1(acc, x); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 411, - "insert_taken", - "No case clause matched", - { values: [desired_keys] } - ); - } - } -} - -function do_take(desired_keys, map) { - return insert_taken(map, desired_keys, new$()); -} - -export function take(map, desired_keys) { - return do_take(desired_keys, map); -} - -function fold_inserts(loop$new_entries, loop$map) { - while (true) { - let new_entries = loop$new_entries; - let map = loop$map; - if (new_entries.hasLength(0)) { - return map; - } else if (new_entries.atLeastLength(1)) { - let x = new_entries.head; - let xs = new_entries.tail; - loop$new_entries = xs; - loop$map = insert_pair(map, x); - } else { - throw makeError( - "case_no_match", - "gleam/map", - 451, - "fold_inserts", - "No case clause matched", - { values: [new_entries] } - ); - } - } -} - -function do_merge(map, new_entries) { - let _pipe = new_entries; - let _pipe$1 = to_list(_pipe); - return fold_inserts(_pipe$1, map); -} - -export function merge(map, new_entries) { - return do_merge(map, new_entries); -} - -export function drop(loop$map, loop$disallowed_keys) { - while (true) { - let map = loop$map; - let disallowed_keys = loop$disallowed_keys; - if (disallowed_keys.hasLength(0)) { - return map; - } else if (disallowed_keys.atLeastLength(1)) { - let x = disallowed_keys.head; - let xs = disallowed_keys.tail; - loop$map = delete$(map, x); - loop$disallowed_keys = xs; - } else { - throw makeError( - "case_no_match", - "gleam/map", - 514, - "drop", - "No case clause matched", - { values: [disallowed_keys] } - ); - } - } -} diff --git a/aoc2023/build/packages/gleam.lock b/aoc2023/build/packages/gleam.lock deleted file mode 100644 index e69de29..0000000 --- a/aoc2023/build/packages/gleam.lock +++ /dev/null diff --git a/aoc2023/build/packages/gleam_community_ansi/LICENCE b/aoc2023/build/packages/gleam_community_ansi/LICENCE deleted file mode 100644 index a84f0ec..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
\ No newline at end of file diff --git a/aoc2023/build/packages/gleam_community_ansi/README.md b/aoc2023/build/packages/gleam_community_ansi/README.md deleted file mode 100644 index 90ab0d5..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/README.md +++ /dev/null @@ -1,72 +0,0 @@ -# gleam-community/ansi - -Format text with ANSI escape sequences. - -[](https://hex.pm/packages/gleam_community_ansi) -[](https://hexdocs.pm/gleam_community_ansi/) - -✨ This project is written in _pure Gleam_ so you can use it anywhere Gleam runs: -Erlang, Elixir, Node, Deno, even [some browsers](https://bit.ly/devtools-console-ansi-support)! - ---- - -## Quickstart - -```gleam -import gleam/io -import gleam_community/ansi - -pub fn main() { - let greeting = "Hello, " <> ansi.pink("world") <> "!" - - greeting - |> ansi.bg_white - |> io.println -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_ansi) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_ansi -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_ansi). - -## ANSI-what? - -ANSI escape sequences date back to the 70s as a standard way to format text on -various video text terminals. Since then they have been adopted by many software -terminal emulators and platforms, including some Web browsers, and are a simple -way to format text without platform-specific APIs. - -The point of this package is to abstract the specific codes away and give you an -easy-to-understand API for formatting and colouring terminal text. Still, here is -a quick couple of examples of what's happening under the hood. - -You can copy these examples straight into your terminal to see them in action! - -- Colour text yellow: - - ```shell - $ echo "\e[33mhello" - ``` - -- Colour the background pink: - - ```shell - $ echo "\e[45mhello" - ``` - -- Render text italic: - - ```shell - $ echo "\e[3mhello\e[23m" - ``` - -As you can see, the escape sequences are a bit obscure. Sure, you could hard code -them, or you could use this package! diff --git a/aoc2023/build/packages/gleam_community_ansi/gleam.toml b/aoc2023/build/packages/gleam_community_ansi/gleam.toml deleted file mode 100644 index 5da1f7e..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "gleam_community_ansi" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "ANSI colours, formatting, and control codes" -repository = { type = "github", user = "gleam-community", repo = "ansi" } -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_community_colour = "~> 1.2" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam b/aoc2023/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam deleted file mode 100644 index a542dda..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community/ansi.gleam +++ /dev/null @@ -1,2317 +0,0 @@ -//// -//// - **Text style** -//// - [`bold`](#bold) -//// - [`italic`](#italic) -//// - [`underline`](#underline) -//// - [`strikethrough`](#strikethrough) -//// - [`inverse`](#inverse) -//// - [`dim`](#dim) -//// - [`hidden`](#hidden) -//// - [`reset`](#reset) -//// - **Text colour** -//// - [`black`](#black) -//// - [`red`](#red) -//// - [`green`](#green) -//// - [`yellow`](#yellow) -//// - [`blue`](#blue) -//// - [`magenta`](#magenta) -//// - [`cyan`](#cyan) -//// - [`white`](#white) -//// - [`pink`](#pink) -//// - [`grey`](#grey) -//// - [`gray`](#gray) -//// - [`bright_black`](#bright_black) -//// - [`bright_red`](#bright_red) -//// - [`bright_green`](#bright_green) -//// - [`bright_yellow`](#bright_yellow) -//// - [`bright_blue`](#bright_blue) -//// - [`bright_magenta`](#bright_magenta) -//// - [`bright_cyan`](#bright_cyan) -//// - [`bright_white`](#bright_white) -//// - [`hex`](#hex) -//// - [`colour`](#colour) -//// - [`color`](#color) -//// - **Background colour** -//// - [`bg_black`](#bg_black) -//// - [`bg_red`](#bg_red) -//// - [`bg_green`](#bg_green) -//// - [`bg_yellow`](#bg_yellow) -//// - [`bg_blue`](#bg_blue) -//// - [`bg_magenta`](#bg_magenta) -//// - [`bg_cyan`](#bg_cyan) -//// - [`bg_white`](#bg_white) -//// - [`bg_pink`](#bg_pink) -//// - [`bg_bright_black`](#bg_bright_black) -//// - [`bg_bright_red`](#bg_bright_red) -//// - [`bg_bright_green`](#bg_bright_green) -//// - [`bg_bright_yellow`](#bg_bright_yellow) -//// - [`bg_bright_blue`](#bg_bright_blue) -//// - [`bg_bright_magenta`](#bg_bright_magenta) -//// - [`bg_bright_cyan`](#bg_bright_cyan) -//// - [`bg_bright_white`](#bg_bright_white) -//// - [`bg_hex`](#bg_hex) -//// - [`bg_colour`](#bg_colour) -//// - [`bg_color`](#bg_color) -//// -//// --- -//// -//// This package was heavily inspired by the `colours` module in the Deno standard -//// library. The original source code can be found -//// <a href="https://deno.land/std@0.167.0/fmt/colours.ts">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018-2022 the Deno authors. -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the Deno `colours` module: -// -// https://deno.land/std@0.167.0/fmt/colours.ts -// - -// This seems like a really handy reference if/when we want to expand this beyond -// formatting escape sequences: -// -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/list -import gleam/string -import gleam_community/colour.{type Colour} as gc_colour - -// CONSTS --------------------------------------------------------------------- - -const asci_escape_character = "" - -// TYPES ---------------------------------------------------------------------- - -type Code { - Code(open: String, close: String, regexp: String) -} - -// UTILITY -------------------------------------------------------------------- - -/// Builds colour code -fn code(open: List(Int), close: Int) -> Code { - let close_str = int.to_string(close) - let open_strs = list.map(open, int.to_string) - - Code( - open: asci_escape_character <> "[" <> string.join(open_strs, ";") <> "m", - close: asci_escape_character <> "[" <> close_str <> "m", - regexp: asci_escape_character <> "[" <> close_str <> "m", - ) -} - -/// Applies colour and background based on colour code and its associated text -fn run(text: String, code: Code) -> String { - code.open <> string.replace(text, code.regexp, code.open) <> code.close -} - -// STYLES --------------------------------------------------------------------- - -/// Reset the text modified -pub fn reset(text: String) -> String { - run(text, code([0], 0)) -} - -/// Style the given text bold. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bold("lucy") -/// // => "\x1B[1mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bold(text: String) -> String { - run(text, code([1], 22)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("lucy") -/// // => "\x1B[2mlucy\x1B[22m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[22m"` added to the string. This is the escape code -/// for the "default" bold/dim style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn dim(text: String) -> String { - run(text, code([2], 22)) -} - -/// Style the given text italic. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.italic("lucy") -/// // => "\x1B[3mlucy\x1B[23m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[23m"` added to the string. This is the escape code -/// for the "default" italic style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be underlined but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn italic(text: String) -> String { - run(text, code([3], 23)) -} - -/// Style the given text's colour to be dimmer. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.underline("lucy") -/// // => "\x1B[4mlucy\x1B[24m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[24m"` added to the string. This is the escape code -/// for the "default" underline style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn underline(text: String) -> String { - run(text, code([4], 24)) -} - -/// Inverse the given text's colour, and background colour. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.inverse("lucy") -/// // => "\x1B[7mlucy\x1B[27m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[27m"` added to the string. This is the escape code -/// for the "default" inverse style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn inverse(text: String) -> String { - run(text, code([7], 27)) -} - -/// Style the given text to be hidden. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hidden("lucy") -/// // => "\x1B[8mlucy\x1B[28m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[28m"` added to the string. This is the escape code -/// for the "default" hidden style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hidden(text: String) -> String { - run(text, code([8], 28)) -} - -/// Style the given text to be striked through. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.strikethrough("lucy") -/// // => "\x1B[9mlucy\x1B[29m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[29m"` added to the string. This is the escape code -/// for the "default" strikethrough style of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// style, it will use both the outter style and the inner style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.dim("Isn't " <> ansi.bold("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be dim but the text "fun?" will be -/// both underlined, *and* bold! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn strikethrough(text: String) -> String { - run(text, code([9], 29)) -} - -// FOREGROUND ----------------------------------------------------------------- - -/// Colour the given text black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.black("lucy") -/// // => "\x1B[30mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn black(text: String) -> String { - run(text, code([30], 39)) -} - -/// Colour the given text red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.red("lucy") -/// // => "\x1B[31mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn red(text: String) -> String { - run(text, code([31], 39)) -} - -/// Colour the given text green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.green("lucy") -/// // => "\x1B[32mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn green(text: String) -> String { - run(text, code([32], 39)) -} - -/// Colour the given text yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("lucy") -/// // => "\x1B[33mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn yellow(text: String) -> String { - run(text, code([33], 39)) -} - -/// Colour the given text blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.blue("lucy") -/// // => "\x1B[34mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn blue(text: String) -> String { - run(text, code([34], 39)) -} - -/// Colour the given text magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.magenta("lucy") -/// // => "\x1B[35mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn magenta(text: String) -> String { - run(text, code([35], 39)) -} - -/// Colour the given text cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.cyan("lucy") -/// // => "\x1B[36mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cyan(text: String) -> String { - run(text, code([36], 39)) -} - -/// Colour the given text white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.white("lucy") -/// // => "\x1B[37mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn white(text: String) -> String { - run(text, code([37], 39)) -} - -/// Colour the given text gray. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.gray("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn grey(text: String) -> String { - bright_black(text) -} - -/// This is an alias for [`grey`](#grey) for those who prefer the American English -/// spelling. -/// -pub fn gray(text: String) -> String { - bright_black(text) -} - -/// Colour the given text bright black. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_black("lucy") -/// // => "\x1B[90mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_black(text: String) -> String { - run(text, code([90], 39)) -} - -/// Colour the given text bright red. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bright_red("lucy") -/// // => "\x1B[91mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_red(text: String) -> String { - run(text, code([91], 39)) -} - -/// Colour the given text bright green. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_green("lucy") -/// // => "\x1B[92mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_green(text: String) -> String { - run(text, code([92], 39)) -} - -/// Colour the given text bright yellow. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_yellow("lucy") -/// // => "\x1B[93mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_yellow(text: String) -> String { - run(text, code([93], 39)) -} - -/// Colour the given text bright blue. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_blue("lucy") -/// // => "\x1B[94mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_blue(text: String) -> String { - run(text, code([94], 39)) -} - -/// Colour the given text bright gremagentaen. This should increase the luminosity -/// of the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_magenta("lucy") -/// // => "\x1B[95mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_magenta(text: String) -> String { - run(text, code([95], 39)) -} - -/// Colour the given text bright cyan. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_cyan("lucy") -/// // => "\x1B[96mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_cyan(text: String) -> String { - run(text, code([96], 39)) -} - -/// Colour the given text bright white. This should increase the luminosity of -/// the base colour, but some terminals will interpret this as bold instead. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// ansi.bright_white("lucy") -/// // => "\x1B[97mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href=""> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bright_white(text: String) -> String { - run(text, code([97], 39)) -} - -/// Colour the given text pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.pink("lucy") -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[39m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pink(text: String) -> String { - hex(text, 0xffaff3) -} - -/// Colour the given text the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[38;2;255;175;243mlucy\x1B[39m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn hex(text: String, colour: Int) -> String { - let colour = int.clamp(colour, max: 0xffffff, min: 0x0) - run( - text, - code( - [ - 38, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 39, - ), - ) -} - -/// Colour the given text the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - hex(text, hex_colour) -} - -/// This is an alias for [`colour`](#colour) for those who prefer the American English -/// spelling. -/// -pub fn color(text: String, color: Colour) -> String { - colour(text, color) -} - -// BACKGROUND ----------------------------------------------------------------- - -/// Colour the given text's background black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_black("lucy") -/// // => "\x1B[40mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_black(text: String) -> String { - run(text, code([40], 49)) -} - -/// Colour the given text's background red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_red("lucy") -/// // => "\x1B[41mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_red(text: String) -> String { - run(text, code([41], 49)) -} - -/// Colour the given text's background green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_green("lucy") -/// // => "\x1B[42mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_green(text: String) -> String { - run(text, code([42], 49)) -} - -/// Colour the given text's background yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_yellow("lucy") -/// // => "\x1B[43mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_yellow(text: String) -> String { - run(text, code([43], 49)) -} - -/// Colour the given text's background blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_blue("lucy") -/// // => "\x1B[44mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_blue(text: String) -> String { - run(text, code([44], 49)) -} - -/// Colour the given text's background magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_magenta("lucy") -/// // => "\x1B[45mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_magenta(text: String) -> String { - run(text, code([45], 49)) -} - -/// Colour the given text's background cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_cyan("lucy") -/// // => "\x1B[46mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_cyan(text: String) -> String { - run(text, code([46], 49)) -} - -/// Colour the given text's background white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_white("lucy") -/// // => "\x1B[47mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_white(text: String) -> String { - run(text, code([47], 49)) -} - -/// Colour the given text's background bright black. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_black("lucy") -/// // => "\x1B[100mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_black(text: String) -> String { - run(text, code([100], 49)) -} - -/// Colour the given text's background bright red. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_red("lucy") -/// // => "\x1B[101mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_red(text: String) -> String { - run(text, code([101], 49)) -} - -/// Colour the given text's background bright green. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_green("lucy") -/// // => "\x1B[102mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_green(text: String) -> String { - run(text, code([102], 49)) -} - -/// Colour the given text's background bright yellow. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_yellow("lucy") -/// // => "\x1B[103mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_yellow(text: String) -> String { - run(text, code([103], 49)) -} - -/// Colour the given text's background bright blue. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_blue("lucy") -/// // => "\x1B[104mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_blue(text: String) -> String { - run(text, code([104], 49)) -} - -/// Colour the given text's background bright magenta. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_magenta("lucy") -/// // => "\x1B[105mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_magenta(text: String) -> String { - run(text, code([105], 49)) -} - -/// Colour the given text's background bright cyan. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_cyan("lucy") -/// // => "\x1B[106mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_cyan(text: String) -> String { - run(text, code([106], 49)) -} - -/// Colour the given text's background bright white. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_bright_white("lucy") -/// // => "\x1B[107mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_bright_white(text: String) -> String { - run(text, code([107], 49)) -} - -/// Colour the given text's background pink. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.bg_pink("lucy") -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_pink(text: String) -> String { - bg_hex(text, 0xffaff3) -} - -/// Colour the given text's background the given colour represented by a hex `Int`. -/// -/// The given hex Int can be any valid [shorthand hexadecimal form](https://en.wikipedia.org/wiki/Web_colors#Shorthand_hexadecimal_form). -/// -/// ❗️ Note that if supplied hex Int is less than 0 or larger than 0xfffff the -/// colour will be set to black and white respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.hex("lucy", 0xffaff3) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_hex(text: String, colour: Int) -> String { - run( - text, - code( - [ - 48, - 2, - int.bitwise_shift_right(colour, 16) - |> int.bitwise_and(0xff), - int.bitwise_shift_right(colour, 8) - |> int.bitwise_and(0xff), - int.bitwise_and(colour, 0xff), - ], - 49, - ), - ) -} - -/// Colour the given text's background with the given colour represented by a `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// import gleam_community/ansi -/// import gleam_community/colour.{Colour} -/// -/// fn example() { -/// let pink = colour.from_hsl(0.8583, 1.0, 0,84) -/// ansi.bg_colour("lucy", pink) -/// // => "\x1B[48;2;255;175;243mlucy\x1B[49m" -/// } -/// ``` -/// -/// ❗️ Note the trailing `"\x1B[49m"` added to the string. This is the escape code -/// for the "default" colour of the terminal. This means text you write after -/// this will revert back to default. -/// -/// ✨ `gleam_community/ansi` is smart about nested styles; instead of using the default -/// colour, it will use the colour of the outter style. -/// -/// ```gleam -/// import gleam_community/ansi -/// -/// fn example() { -/// ansi.yellow("Isn't " <> ansi.pink("Gleam") <> " fun?") -/// } -/// ``` -/// -/// In this example, the text "Gleam" will be pink but the text "fun?" will be -/// yellow, *not* the default colour! -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/ansi/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn bg_colour(text: String, colour: Colour) -> String { - let hex_colour = gc_colour.to_rgb_hex(colour) - bg_hex(text, hex_colour) -} - -/// This is an alias for [`bg_colour`](#bg_colour) for those who prefer the American English -/// spelling. -/// -pub fn bg_color(text: String, colour: Colour) -> String { - bg_colour(text, colour) -} diff --git a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl b/aoc2023/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl deleted file mode 100644 index 8b7a4c9..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community@ansi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_community@ansi). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([reset/1, bold/1, dim/1, italic/1, underline/1, inverse/1, hidden/1, strikethrough/1, black/1, red/1, green/1, yellow/1, blue/1, magenta/1, cyan/1, white/1, bright_black/1, grey/1, gray/1, bright_red/1, bright_green/1, bright_yellow/1, bright_blue/1, bright_magenta/1, bright_cyan/1, bright_white/1, hex/2, pink/1, colour/2, color/2, bg_black/1, bg_red/1, bg_green/1, bg_yellow/1, bg_blue/1, bg_magenta/1, bg_cyan/1, bg_white/1, bg_bright_black/1, bg_bright_red/1, bg_bright_green/1, bg_bright_yellow/1, bg_bright_blue/1, bg_bright_magenta/1, bg_bright_cyan/1, bg_bright_white/1, bg_hex/2, bg_pink/1, bg_colour/2, bg_color/2]). --export_type([code/0]). - --type code() :: {code, binary(), binary(), binary()}. - --spec code(list(integer()), integer()) -> code(). -code(Open, Close) -> - Close_str = gleam@int:to_string(Close), - Open_strs = gleam@list:map(Open, fun gleam@int:to_string/1), - {code, - <<<<<<""/utf8, "["/utf8>>/binary, - (gleam@string:join(Open_strs, <<";"/utf8>>))/binary>>/binary, - "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>, - <<<<<<""/utf8, "["/utf8>>/binary, Close_str/binary>>/binary, "m"/utf8>>}. - --spec run(binary(), code()) -> binary(). -run(Text, Code) -> - <<<<(erlang:element(2, Code))/binary, - (gleam@string:replace( - Text, - erlang:element(4, Code), - erlang:element(2, Code) - ))/binary>>/binary, - (erlang:element(3, Code))/binary>>. - --spec reset(binary()) -> binary(). -reset(Text) -> - run(Text, code([0], 0)). - --spec bold(binary()) -> binary(). -bold(Text) -> - run(Text, code([1], 22)). - --spec dim(binary()) -> binary(). -dim(Text) -> - run(Text, code([2], 22)). - --spec italic(binary()) -> binary(). -italic(Text) -> - run(Text, code([3], 23)). - --spec underline(binary()) -> binary(). -underline(Text) -> - run(Text, code([4], 24)). - --spec inverse(binary()) -> binary(). -inverse(Text) -> - run(Text, code([7], 27)). - --spec hidden(binary()) -> binary(). -hidden(Text) -> - run(Text, code([8], 28)). - --spec strikethrough(binary()) -> binary(). -strikethrough(Text) -> - run(Text, code([9], 29)). - --spec black(binary()) -> binary(). -black(Text) -> - run(Text, code([30], 39)). - --spec red(binary()) -> binary(). -red(Text) -> - run(Text, code([31], 39)). - --spec green(binary()) -> binary(). -green(Text) -> - run(Text, code([32], 39)). - --spec yellow(binary()) -> binary(). -yellow(Text) -> - run(Text, code([33], 39)). - --spec blue(binary()) -> binary(). -blue(Text) -> - run(Text, code([34], 39)). - --spec magenta(binary()) -> binary(). -magenta(Text) -> - run(Text, code([35], 39)). - --spec cyan(binary()) -> binary(). -cyan(Text) -> - run(Text, code([36], 39)). - --spec white(binary()) -> binary(). -white(Text) -> - run(Text, code([37], 39)). - --spec bright_black(binary()) -> binary(). -bright_black(Text) -> - run(Text, code([90], 39)). - --spec grey(binary()) -> binary(). -grey(Text) -> - bright_black(Text). - --spec gray(binary()) -> binary(). -gray(Text) -> - bright_black(Text). - --spec bright_red(binary()) -> binary(). -bright_red(Text) -> - run(Text, code([91], 39)). - --spec bright_green(binary()) -> binary(). -bright_green(Text) -> - run(Text, code([92], 39)). - --spec bright_yellow(binary()) -> binary(). -bright_yellow(Text) -> - run(Text, code([93], 39)). - --spec bright_blue(binary()) -> binary(). -bright_blue(Text) -> - run(Text, code([94], 39)). - --spec bright_magenta(binary()) -> binary(). -bright_magenta(Text) -> - run(Text, code([95], 39)). - --spec bright_cyan(binary()) -> binary(). -bright_cyan(Text) -> - run(Text, code([96], 39)). - --spec bright_white(binary()) -> binary(). -bright_white(Text) -> - run(Text, code([97], 39)). - --spec hex(binary(), integer()) -> binary(). -hex(Text, Colour) -> - Colour@1 = gleam@int:clamp(Colour, 16#0, 16#ffffff), - run( - Text, - code( - [38, - 2, - begin - _pipe = erlang:'bsr'(Colour@1, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour@1, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour@1, 16#ff)], - 39 - ) - ). - --spec pink(binary()) -> binary(). -pink(Text) -> - hex(Text, 16#ffaff3). - --spec colour(binary(), gleam_community@colour:colour()) -> binary(). -colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - hex(Text, Hex_colour). - --spec color(binary(), gleam_community@colour:colour()) -> binary(). -color(Text, Color) -> - colour(Text, Color). - --spec bg_black(binary()) -> binary(). -bg_black(Text) -> - run(Text, code([40], 49)). - --spec bg_red(binary()) -> binary(). -bg_red(Text) -> - run(Text, code([41], 49)). - --spec bg_green(binary()) -> binary(). -bg_green(Text) -> - run(Text, code([42], 49)). - --spec bg_yellow(binary()) -> binary(). -bg_yellow(Text) -> - run(Text, code([43], 49)). - --spec bg_blue(binary()) -> binary(). -bg_blue(Text) -> - run(Text, code([44], 49)). - --spec bg_magenta(binary()) -> binary(). -bg_magenta(Text) -> - run(Text, code([45], 49)). - --spec bg_cyan(binary()) -> binary(). -bg_cyan(Text) -> - run(Text, code([46], 49)). - --spec bg_white(binary()) -> binary(). -bg_white(Text) -> - run(Text, code([47], 49)). - --spec bg_bright_black(binary()) -> binary(). -bg_bright_black(Text) -> - run(Text, code([100], 49)). - --spec bg_bright_red(binary()) -> binary(). -bg_bright_red(Text) -> - run(Text, code([101], 49)). - --spec bg_bright_green(binary()) -> binary(). -bg_bright_green(Text) -> - run(Text, code([102], 49)). - --spec bg_bright_yellow(binary()) -> binary(). -bg_bright_yellow(Text) -> - run(Text, code([103], 49)). - --spec bg_bright_blue(binary()) -> binary(). -bg_bright_blue(Text) -> - run(Text, code([104], 49)). - --spec bg_bright_magenta(binary()) -> binary(). -bg_bright_magenta(Text) -> - run(Text, code([105], 49)). - --spec bg_bright_cyan(binary()) -> binary(). -bg_bright_cyan(Text) -> - run(Text, code([106], 49)). - --spec bg_bright_white(binary()) -> binary(). -bg_bright_white(Text) -> - run(Text, code([107], 49)). - --spec bg_hex(binary(), integer()) -> binary(). -bg_hex(Text, Colour) -> - run( - Text, - code( - [48, - 2, - begin - _pipe = erlang:'bsr'(Colour, 16), - erlang:'band'(_pipe, 16#ff) - end, - begin - _pipe@1 = erlang:'bsr'(Colour, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - erlang:'band'(Colour, 16#ff)], - 49 - ) - ). - --spec bg_pink(binary()) -> binary(). -bg_pink(Text) -> - bg_hex(Text, 16#ffaff3). - --spec bg_colour(binary(), gleam_community@colour:colour()) -> binary(). -bg_colour(Text, Colour) -> - Hex_colour = gleam_community@colour:to_rgb_hex(Colour), - bg_hex(Text, Hex_colour). - --spec bg_color(binary(), gleam_community@colour:colour()) -> binary(). -bg_color(Text, Colour) -> - bg_colour(Text, Colour). diff --git a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src b/aoc2023/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src deleted file mode 100644 index dfcfdc3..0000000 --- a/aoc2023/build/packages/gleam_community_ansi/src/gleam_community_ansi.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_ansi, [ - {vsn, "1.2.0"}, - {applications, [gleam_community_colour, - gleam_stdlib, - gleeunit]}, - {description, "ANSI colours, formatting, and control codes"}, - {modules, [gleam_community@ansi]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_community_colour/LICENCE b/aoc2023/build/packages/gleam_community_colour/LICENCE deleted file mode 100644 index a84f0ec..0000000 --- a/aoc2023/build/packages/gleam_community_colour/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
\ No newline at end of file diff --git a/aoc2023/build/packages/gleam_community_colour/README.md b/aoc2023/build/packages/gleam_community_colour/README.md deleted file mode 100644 index 0eccdd7..0000000 --- a/aoc2023/build/packages/gleam_community_colour/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# gleam-community/colour - -A package for a standard Colour type, conversions, and other utilities. - -[](https://hex.pm/packages/gleam_community_colour) -[](https://hexdocs.pm/gleam_community_colour/) - -✨ This project is written in pure Gleam so you can use it anywhere Gleam runs: Erlang, Elixir, Node, Deno, and the browser! - ---- - -## Quickstart - -```gleam -import gleam_community/colour -import gleam_community/colour/accessibility - -pub fn main() { - let foreground = colour.from_hsl(h: 0.858, s: 1.0, l: 0.843) - - let background_options = [colour.light_grey, colour.dark_grey] - - let background = accessibility.maximum_contrast(foreground, background_options) -} -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_colour) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_colour -``` - -The docs can be found over at [hexdocs.pm](https://hexdocs.pm/gleam_community_colour). diff --git a/aoc2023/build/packages/gleam_community_colour/gleam.toml b/aoc2023/build/packages/gleam_community_colour/gleam.toml deleted file mode 100644 index 07a81bf..0000000 --- a/aoc2023/build/packages/gleam_community_colour/gleam.toml +++ /dev/null @@ -1,11 +0,0 @@ -name = "gleam_community_colour" -version = "1.2.0" -licences = ["Apache-2.0"] -description = "Colour types, conversions, and other utilities" -repository = { type = "github", user = "gleam-community", repo = "colour" } - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.11" diff --git a/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl b/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl deleted file mode 100644 index 06116df..0000000 --- a/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Hsla.hrl +++ /dev/null @@ -1 +0,0 @@ --record(hsla, {h :: float(), s :: float(), l :: float(), a :: float()}). diff --git a/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl b/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl deleted file mode 100644 index fff139e..0000000 --- a/aoc2023/build/packages/gleam_community_colour/include/gleam_community@colour_Rgba.hrl +++ /dev/null @@ -1 +0,0 @@ --record(rgba, {r :: float(), g :: float(), b :: float(), a :: float()}). diff --git a/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour.gleam b/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour.gleam deleted file mode 100644 index 1f5872f..0000000 --- a/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour.gleam +++ /dev/null @@ -1,1126 +0,0 @@ -//// -//// - **Types** -//// - [`Colour`](#Colour) -//// - [`Color`](#Color) -//// - **Constructors** -//// - [`from_rgb255`](#from_rgb255) -//// - [`from_rgb`](#from_rgb) -//// - [`from_rgba`](#from_rgba) -//// - [`from_hsl`](#from_hsl) -//// - [`from_hsla`](#from_hsla) -//// - [`from_rgb_hex`](#from_rgb_hex) -//// - [`from_rgba_hex`](#from_rgba_hex) -//// - [`from_rgb_hex_string`](#from_rgb_hex_string) -//// - [`from_rgba_hex_string`](#from_rgba_hex_string) -//// - **Conversions** -//// - [`to_rgba`](#to_rgba) -//// - [`to_hsla`](#hsla) -//// - [`to_css_rgba_string`](#to_css_rgba_string) -//// - [`to_rgba_hex_string`](#to_rgba_hex_string) -//// - [`to_rgb_hex_string`](#to_rgb_hex_string) -//// - [`to_rgba_hex`](#to_rgba_hex) -//// - [`to_rgb_hex`](#to_rgb_hex) -//// - **Colours** -//// - [`light_red`](#light_red) -//// - [`red`](#red) -//// - [`dark_red`](#dark_red) -//// - [`light_orange`](#light_orange) -//// - [`orange`](#orange) -//// - [`dark_orange`](#dark_orange) -//// - [`light_yellow`](#light_yellow) -//// - [`yellow`](#yellow) -//// - [`dark_yellow`](#dark_yellow) -//// - [`light_green`](#light_green) -//// - [`green`](#green) -//// - [`dark_green`](#dark_green) -//// - [`light_blue`](#light_blue) -//// - [`blue`](#blue) -//// - [`dark_blue`](#dark_blue) -//// - [`light_purple`](#light_purple) -//// - [`purple`](#purple) -//// - [`dark_purple`](#dark_purple) -//// - [`light_brown`](#light_brown) -//// - [`brown`](#brown) -//// - [`dark_brown`](#dark_brown) -//// - [`black`](#black) -//// - [`white`](#white) -//// - [`light_grey`](#light_grey) -//// - [`grey`](#grey) -//// - [`dark_grey`](#dark_grey) -//// - [`light_gray`](#light_gray) -//// - [`gray`](#gray) -//// - [`dark_gray`](#dark_gray) -//// - [`light_charcoal`](#light_charcoal) -//// - [`charcoal`](#charcoal) -//// - [`dark_charcoal`](#dark_charcoal) -//// - [`pink`](#pink) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color` module. -//// The original source code can be found -//// <a href="https://github.com/avh4/elm-color/">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright 2018 Aaron VonderHaar -//// -//// > Redistribution and use in source and binary forms, with or without modification, -//// are permitted provided that the following conditions are met: -//// -//// 1. Redistributions of source code must retain the above copyright notice, -//// this list of conditions and the following disclaimer. -//// -//// 2. Redistributions in binary form must reproduce the above copyright notice, -//// this list of conditions and the following disclaimer in the documentation -//// and/or other materials provided with the distribution. -//// -//// 3. Neither the name of the copyright holder nor the names of its contributors -//// may be used to endorse or promote products derived from this software without -//// specific prior written permission. -//// -//// > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -//// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -//// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -//// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -//// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -//// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -//// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color` module: -// -// https://github.com/avh4/elm-color/ -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/int -import gleam/float -import gleam/result -import gleam/string -import gleam/list - -// TYPES ---------------------------------------------------------------------- - -/// A representation of a colour that can be converted to RGBA or HSLA format. -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub opaque type Colour { - Rgba(r: Float, g: Float, b: Float, a: Float) - Hsla(h: Float, s: Float, l: Float, a: Float) -} - -/// Type alias for `Colour` -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// </br> -/// -pub type Color = - Colour - -// UTILITY -------------------------------------------------------------------- - -fn valid_colour_value(c: Float) -> Result(Float, Nil) { - case c >. 1.0 || c <. 0.0 { - True -> Error(Nil) - False -> Ok(c) - } -} - -fn hue_to_rgb(hue: Float, m1: Float, m2: Float) -> Float { - let h = case hue { - _ if hue <. 0.0 -> hue +. 1.0 - _ if hue >. 1.0 -> hue -. 1.0 - _ -> hue - } - - let h_t_6 = h *. 6.0 - let h_t_2 = h *. 2.0 - let h_t_3 = h *. 3.0 - - case h { - _ if h_t_6 <. 1.0 -> m1 +. { m2 -. m1 } *. h *. 6.0 - _ if h_t_2 <. 1.0 -> m2 - _ if h_t_3 <. 2.0 -> m1 +. { m2 -. m1 } *. { 2.0 /. 3.0 -. h } *. 6.0 - _ -> m1 - } -} - -fn hex_string_to_int(hex_string: String) -> Result(Int, Nil) { - let hex = case hex_string { - "#" <> hex_number -> hex_number - "0x" <> hex_number -> hex_number - _ -> hex_string - } - - hex - |> string.lowercase() - |> string.to_graphemes() - |> list.reverse() - |> list.index_fold( - Ok(0), - fn(total, char, index) { - case total { - Error(Nil) -> Error(Nil) - Ok(v) -> { - use num <- result.then(case char { - "a" -> Ok(10) - "b" -> Ok(11) - "c" -> Ok(12) - "d" -> Ok(13) - "e" -> Ok(14) - "f" -> Ok(15) - _ -> int.parse(char) - }) - use base <- result.then(int.power(16, int.to_float(index))) - Ok(v + float.round(int.to_float(num) *. base)) - } - } - }, - ) -} - -fn hsla_to_rgba( - h: Float, - s: Float, - l: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let m2 = case l <=. 0.5 { - True -> l *. { s +. 1.0 } - False -> l +. s -. l *. s - } - - let m1 = l *. 2.0 -. m2 - - let r = hue_to_rgb(h +. 1.0 /. 3.0, m1, m2) - let g = hue_to_rgb(h, m1, m2) - let b = hue_to_rgb(h -. 1.0 /. 3.0, m1, m2) - - #(r, g, b, a) -} - -fn rgba_to_hsla( - r: Float, - g: Float, - b: Float, - a: Float, -) -> #(Float, Float, Float, Float) { - let min_colour = float.min(r, float.min(g, b)) - - let max_colour = float.max(r, float.max(g, b)) - - let h1 = case True { - _ if max_colour == r -> float.divide(g -. b, max_colour -. min_colour) - _ if max_colour == g -> - float.divide(b -. r, max_colour -. min_colour) - |> result.then(fn(d) { Ok(2.0 +. d) }) - _ -> - float.divide(r -. g, max_colour -. min_colour) - |> result.then(fn(d) { Ok(4.0 +. d) }) - } - - let h2 = case h1 { - Ok(v) -> Ok(v *. { 1.0 /. 6.0 }) - _ -> h1 - } - - let h3 = case h2 { - Ok(v) if v <. 0.0 -> v +. 1.0 - Ok(v) -> v - _ -> 0.0 - } - - let l = { min_colour +. max_colour } /. 2.0 - - let s = case True { - _ if min_colour == max_colour -> 0.0 - _ if l <. 0.5 -> - { max_colour -. min_colour } /. { max_colour +. min_colour } - _ -> { max_colour -. min_colour } /. { 2.0 -. max_colour -. min_colour } - } - - #(h3, s, l, a) -} - -// CONSTRUCTORS --------------------------------------------------------------- - -/// Returns a `Result(Colour)` created from the given 8 bit RGB values. -/// -/// Returns `Error(Nil)` if the supplied RGB values are greater than 255 or less than 0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb255(r red: Int, g green: Int, b blue: Int) -> Result(Colour, Nil) { - use r <- result.then( - red - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use g <- result.then( - green - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - use b <- result.then( - blue - |> int.to_float() - |> float.divide(255.0) - |> result.then(valid_colour_value), - ) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGB values. -/// -/// If the supplied RGB values are greater than 1.0 or less than 0.0 returns `Error(Nil)` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb(1.0, 0.0, 0.0) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb( - r red: Float, - g green: Float, - b blue: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - - Ok(Rgba(r: r, g: g, b: b, a: 1.0)) -} - -/// Returns `Result(Colour)` created from the given RGBA values. -/// -/// Returns `Error(Nil)` if the supplied RGBA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rbga(1.0, 0.0, 0.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba( - r red: Float, - g green: Float, - b blue: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use r <- result.then(valid_colour_value(red)) - use g <- result.then(valid_colour_value(green)) - use b <- result.then(valid_colour_value(blue)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Rgba(r: r, g: g, b: b, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSLA values. -/// -/// Returns `Error(Nil)`f the supplied HSLA values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_hsla(0.0, 1.0, 0.5, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsla( - h hue: Float, - s saturation: Float, - l lightness: Float, - a alpha: Float, -) -> Result(Colour, Nil) { - use h <- result.then(valid_colour_value(hue)) - use s <- result.then(valid_colour_value(saturation)) - use l <- result.then(valid_colour_value(lightness)) - use a <- result.then(valid_colour_value(alpha)) - - Ok(Hsla(h: h, s: s, l: l, a: a)) -} - -/// Returns `Result(Colour)` created from the given HSL values. -/// -/// Returns `Error(Nil)` if the supplied HSL values are greater than 1.0 or less than 0.0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_hsla(0.0, 1.0, 0.5) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_hsl( - h hue: Float, - s saturation: Float, - l lightness: Float, -) -> Result(Colour, Nil) { - from_hsla(hue, saturation, lightness, 1.0) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex(0xff0000) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffff || hex < 0 { - True -> Error(Nil) - False -> { - let r = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - let g = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - let b = int.bitwise_and(hex, 0xff) - from_rgb255(r, g, b) - } - } -} - -/// Returns a `Result(Colour)` created from the given RGB hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb_hex_string("#ff0000") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgb_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgb_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given RGBA hex `String`. -/// -/// Returns `Error(Nil)` if the supplied hex `String` is invalid, or greater than `"#ffffffff" or less than `"#0"` -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex_string("#ff00007f") -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex_string(hex_string: String) -> Result(Colour, Nil) { - use hex_int <- result.then(hex_string_to_int(hex_string)) - - from_rgba_hex(hex_int) -} - -/// Returns a `Result(Colour)` created from the given hex `Int`. -/// -/// Returns `Error(Nil)` if the supplied hex `Int is greater than 0xffffffff or less than 0x0. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red_half_opacity) = from_rgba_hex(0xff00007f) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn from_rgba_hex(hex: Int) -> Result(Colour, Nil) { - case hex > 0xffffffff || hex < 0 { - True -> Error(Nil) - False -> { - // This won't fail because we are always dividing by 255.0 - let assert Ok(r) = - int.bitwise_shift_right(hex, 24) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(g) = - int.bitwise_shift_right(hex, 16) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(b) = - int.bitwise_shift_right(hex, 8) - |> int.bitwise_and(0xff) - |> int.to_float() - |> float.divide(255.0) - // This won't fail because we are always dividing by 255.0 - let assert Ok(a) = - int.bitwise_and(hex, 0xff) - |> int.to_float() - |> float.divide(255.0) - from_rgba(r, g, b, a) - } - } -} - -// CONVERSIONS ---------------------------------------------------------------- - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// R, G, B, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(r, g, b, a) = to_rgba(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Rgba(r, g, b, a) -> #(r, g, b, a) - Hsla(h, s, l, a) -> hsla_to_rgba(h, s, l, a) - } -} - -/// Returns `#(Float, Float, Float, Float)` representing the given `Colour`'s -/// H, S, L, and A values respectively. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let #(h, s, l, a) = to_hsla(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_hsla(colour: Colour) -> #(Float, Float, Float, Float) { - case colour { - Hsla(h, s, l, a) -> #(h, s, l, a) - Rgba(r, g, b, a) -> rgba_to_hsla(r, g, b, a) - } -} - -/// Returns an rgba formatted CSS `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgb255(255, 0, 0) -/// let css_red = to_css_rgba_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_css_rgba_string(colour: Colour) -> String { - let #(r, g, b, a) = to_rgba(colour) - - let percent = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 100.0 - let assert Ok(p) = - x - |> float.multiply(10_000.0) - |> float.round() - |> int.to_float() - |> float.divide(100.0) - - p - } - - let round_to = fn(x: Float) -> Float { - // This won't fail because we are always dividing by 1000.0 - let assert Ok(r) = - x - |> float.multiply(1000.0) - |> float.round() - |> int.to_float() - |> float.divide(1000.0) - - r - } - - string.join( - [ - "rgba(", - float.to_string(percent(r)) <> "%,", - float.to_string(percent(g)) <> "%,", - float.to_string(percent(b)) <> "%,", - float.to_string(round_to(a)), - ")", - ], - "", - ) -} - -/// Returns an rgba hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex = to_rgba_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex_string(colour: Colour) -> String { - to_rgba_hex(colour) - |> int.to_base16() -} - -/// Returns an rgb hex formatted `String` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex = to_rgb_hex_string(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex_string(colour: Colour) -> String { - to_rgb_hex(colour) - |> int.to_base16() -} - -/// Returns an hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(1.0, 0.0, 0.0, 1.0) -/// let red_hex_int = to_rgba_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgba_hex(colour: Colour) -> Int { - let #(r, g, b, a) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(24) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let blue = - b *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let alpha = - a *. 255.0 - |> float.round() - - red + green + blue + alpha -} - -/// Returns a rgb hex `Int` created from the given `Colour`. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// assert Ok(red) = from_rgba(255, 0, 0) -/// let red_hex_int = to_rgb_hex(red) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn to_rgb_hex(colour: Colour) -> Int { - let #(r, g, b, _) = to_rgba(colour) - - let red = - r *. 255.0 - |> float.round() - |> int.bitwise_shift_left(16) - - let green = - g *. 255.0 - |> float.round() - |> int.bitwise_shift_left(8) - - let blue = - b *. 255.0 - |> float.round() - - red + green + blue -} - -// COLOURS -------------------------------------------------------------------- - -/// A `Colour` reprsenting the colour RGBA(239, 41, 41, 1.0) -pub const light_red = Rgba( - r: 0.9372549019607843, - g: 0.1607843137254902, - b: 0.1607843137254902, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(204, 0, 0, 1.0) -pub const red = Rgba(r: 0.8, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(164, 0, 0, 1.0) -pub const dark_red = Rgba(r: 0.6431372549019608, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(252, 175, 62, 1.0) -pub const light_orange = Rgba( - r: 0.9882352941176471, - g: 0.6862745098039216, - b: 0.24313725490196078, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(245, 121, 0, 1.0) -pub const orange = Rgba( - r: 0.9607843137254902, - g: 0.4745098039215686, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(206, 92, 0, 1.0) -pub const dark_orange = Rgba( - r: 0.807843137254902, - g: 0.3607843137254902, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 233, 79, 1.0) -pub const light_yellow = Rgba( - r: 1.0, - g: 0.9137254901960784, - b: 0.30980392156862746, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(237, 212, 0, 1.0) -pub const yellow = Rgba( - r: 0.9294117647058824, - g: 0.8313725490196079, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(196, 160, 0, 1.0) -pub const dark_yellow = Rgba( - r: 0.7686274509803922, - g: 0.6274509803921569, - b: 0.0, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(138, 226, 52, 1.0) -pub const light_green = Rgba( - r: 0.5411764705882353, - g: 0.8862745098039215, - b: 0.20392156862745098, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(115, 210, 22, 1.0) -pub const green = Rgba( - r: 0.45098039215686275, - g: 0.8235294117647058, - b: 0.08627450980392157, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(78, 154, 6, 1.0) -pub const dark_green = Rgba( - r: 0.3058823529411765, - g: 0.6039215686274509, - b: 0.023529411764705882, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(114, 159, 207, 1.0) -pub const light_blue = Rgba( - r: 0.4470588235294118, - g: 0.6235294117647059, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(52, 101, 164, 1.0) -pub const blue = Rgba( - r: 0.20392156862745098, - g: 0.396078431372549, - b: 0.6431372549019608, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(32, 74, 135, 1.0) -pub const dark_blue = Rgba( - r: 0.12549019607843137, - g: 0.2901960784313726, - b: 0.5294117647058824, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(173, 127, 168, 1.0) -pub const light_purple = Rgba( - r: 0.6784313725490196, - g: 0.4980392156862745, - b: 0.6588235294117647, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(117, 80, 123, 1.0) -pub const purple = Rgba( - r: 0.4588235294117647, - g: 0.3137254901960784, - b: 0.4823529411764706, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(92, 53, 102, 1.0) -pub const dark_purple = Rgba( - r: 0.3607843137254902, - g: 0.20784313725490197, - b: 0.4, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(233, 185, 110, 1.0) -pub const light_brown = Rgba( - r: 0.9137254901960784, - g: 0.7254901960784313, - b: 0.43137254901960786, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(193, 125, 17, 1.0) -pub const brown = Rgba( - r: 0.7568627450980392, - g: 0.49019607843137253, - b: 0.06666666666666667, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(143, 89, 2, 1.0) -pub const dark_brown = Rgba( - r: 0.5607843137254902, - g: 0.34901960784313724, - b: 0.00784313725490196, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(0, 0, 0, 1.0) -pub const black = Rgba(r: 0.0, g: 0.0, b: 0.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(255, 255, 255, 1.0) -pub const white = Rgba(r: 1.0, g: 1.0, b: 1.0, a: 1.0) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_grey = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const grey = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_grey = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(238, 238, 236, 1.0) -pub const light_gray = Rgba( - r: 0.9333333333333333, - g: 0.9333333333333333, - b: 0.9254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(211, 215, 207, 1.0) -pub const gray = Rgba( - r: 0.8274509803921568, - g: 0.8431372549019608, - b: 0.8117647058823529, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(186, 189, 182, 1.0) -pub const dark_gray = Rgba( - r: 0.7294117647058823, - g: 0.7411764705882353, - b: 0.7137254901960784, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(136, 138, 133, 1.0) -pub const light_charcoal = Rgba( - r: 0.5333333333333333, - g: 0.5411764705882353, - b: 0.5215686274509804, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(85, 87, 83, 1.0) -pub const charcoal = Rgba( - r: 0.3333333333333333, - g: 0.3411764705882353, - b: 0.3254901960784314, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(46, 52, 54, 1.0) -pub const dark_charcoal = Rgba( - r: 0.1803921568627451, - g: 0.20392156862745098, - b: 0.21176470588235294, - a: 1.0, -) - -/// A `Colour` reprsenting the colour RGBA(255, 175, 243, 1.0) -pub const pink = Rgba( - r: 1.0, - g: 0.6862745098039216, - b: 0.9529411764705882, - a: 1.0, -) diff --git a/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam b/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam deleted file mode 100644 index 54f75e4..0000000 --- a/aoc2023/build/packages/gleam_community_colour/src/gleam_community/colour/accessibility.gleam +++ /dev/null @@ -1,173 +0,0 @@ -//// -//// - **Accessibility** -//// - [`luminance`](#luminance) -//// - [`contrast_ratio`](#contrast_ratio) -//// - [`maximum_contrast`](#maximum_contrast) -//// -//// --- -//// -//// This package was heavily inspired by the `elm-color-extra` module. -//// The original source code can be found -//// <a href="https://github.com/noahzgordon/elm-color-extra">here</a>. -//// -//// <details> -//// <summary>The license of that package is produced below:</summary> -//// -//// -//// > MIT License -//// -//// > Copyright (c) 2016 Andreas Köberle -//// -//// > Permission is hereby granted, free of charge, to any person obtaining a copy -//// of this software and associated documentation files (the "Software"), to deal -//// in the Software without restriction, including without limitation the rights -//// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -//// copies of the Software, and to permit persons to whom the Software is -//// furnished to do so, subject to the following conditions: -//// -//// > The above copyright notice and this permission notice shall be included in all -//// copies or substantial portions of the Software. -//// -//// > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -//// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -//// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -//// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -//// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -//// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -//// SOFTWARE. -//// -//// </details> -//// - -// Just in case we decide in the future to no longer include the above reference -// and license, this package was initially a port of the `elm-color-extra` module: -// -// https://github.com/noahzgordon/elm-color-extra -// - -// IMPORTS -------------------------------------------------------------------- - -import gleam/float -import gleam/list -import gleam_community/colour.{type Colour} - -// UTILITIES ------------------------------------------------------------------ - -fn intensity(colour_value: Float) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - case True { - _ if colour_value <=. 0.03928 -> colour_value /. 12.92 - _ -> { - // Is this guaranteed to be `OK`? - let assert Ok(i) = float.power({ colour_value +. 0.055 } /. 1.055, 2.4) - i - } - } -} - -// ACCESSIBILITY -------------------------------------------------------------- - -/// Returns the relative brightness of the given `Colour` as a `Float` between -/// 0.0, and 1.0 with 0.0 being the darkest possible colour and 1.0 being the lightest. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// luminance(colour.white) // 1.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn luminance(colour: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#relativeluminancedef - let #(r, g, b, _) = colour.to_rgba(colour) - - let r_intensity = intensity(r) - let g_intensity = intensity(g) - let b_intensity = intensity(b) - - 0.2126 *. r_intensity +. 0.7152 *. g_intensity +. 0.0722 *. b_intensity -} - -/// Returns the contrast between two `Colour` values as a `Float` between 1.0, -/// and 21.0 with 1.0 being no contrast and, 21.0 being the highest possible contrast. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// contrast_ratio(between: colour.white, and: colour.black) // 21.0 -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn contrast_ratio(between colour_a: Colour, and colour_b: Colour) -> Float { - // Calculation taken from https://www.w3.org/TR/WCAG20/#contrast-ratiodef - let luminance_a = luminance(colour_a) +. 0.05 - let luminance_b = luminance(colour_b) +. 0.05 - - case luminance_a >. luminance_b { - True -> luminance_a /. luminance_b - False -> luminance_b /. luminance_a - } -} - -/// Returns the `Colour` with the highest contrast between the base `Colour`, -/// and and the other provided `Colour` values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// ```gleam -/// fn example() { -/// maximum_contrast( -/// colour.yellow, -/// [colour.white, colour.dark_blue, colour.green], -/// ) -/// } -/// ``` -/// </details> -/// -/// <div style="position: relative;"> -/// <a style="position: absolute; left: 0;" href="https://github.com/gleam-community/colour/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// <a style="position: absolute; right: 0;" href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum_contrast( - base: Colour, - colours: List(Colour), -) -> Result(Colour, Nil) { - colours - |> list.sort(fn(colour_a, colour_b) { - let contrast_a = contrast_ratio(base, colour_a) - let contrast_b = contrast_ratio(base, colour_b) - - float.compare(contrast_b, contrast_a) - }) - |> list.first() -} diff --git a/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour.erl b/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour.erl deleted file mode 100644 index 21e4c81..0000000 --- a/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour.erl +++ /dev/null @@ -1,511 +0,0 @@ --module(gleam_community@colour). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_rgb255/3, from_rgb/3, from_rgba/4, from_hsla/4, from_hsl/3, from_rgb_hex/1, from_rgb_hex_string/1, from_rgba_hex/1, from_rgba_hex_string/1, to_rgba/1, to_hsla/1, to_css_rgba_string/1, to_rgba_hex/1, to_rgba_hex_string/1, to_rgb_hex/1, to_rgb_hex_string/1]). --export_type([colour/0]). - --opaque colour() :: {rgba, float(), float(), float(), float()} | - {hsla, float(), float(), float(), float()}. - --spec valid_colour_value(float()) -> {ok, float()} | {error, nil}. -valid_colour_value(C) -> - case (C > 1.0) orelse (C < +0.0) of - true -> - {error, nil}; - - false -> - {ok, C} - end. - --spec hue_to_rgb(float(), float(), float()) -> float(). -hue_to_rgb(Hue, M1, M2) -> - H = case Hue of - _ when Hue < +0.0 -> - Hue + 1.0; - - _ when Hue > 1.0 -> - Hue - 1.0; - - _ -> - Hue - end, - H_t_6 = H * 6.0, - H_t_2 = H * 2.0, - H_t_3 = H * 3.0, - case H of - _ when H_t_6 < 1.0 -> - M1 + (((M2 - M1) * H) * 6.0); - - _ when H_t_2 < 1.0 -> - M2; - - _ when H_t_3 < 2.0 -> - M1 + (((M2 - M1) * ((2.0 / 3.0) - H)) * 6.0); - - _ -> - M1 - end. - --spec hex_string_to_int(binary()) -> {ok, integer()} | {error, nil}. -hex_string_to_int(Hex_string) -> - Hex = case Hex_string of - <<"#"/utf8, Hex_number/binary>> -> - Hex_number; - - <<"0x"/utf8, Hex_number@1/binary>> -> - Hex_number@1; - - _ -> - Hex_string - end, - _pipe = Hex, - _pipe@1 = gleam@string:lowercase(_pipe), - _pipe@2 = gleam@string:to_graphemes(_pipe@1), - _pipe@3 = gleam@list:reverse(_pipe@2), - gleam@list:index_fold( - _pipe@3, - {ok, 0}, - fun(Total, Char, Index) -> case Total of - {error, nil} -> - {error, nil}; - - {ok, V} -> - gleam@result:then(case Char of - <<"a"/utf8>> -> - {ok, 10}; - - <<"b"/utf8>> -> - {ok, 11}; - - <<"c"/utf8>> -> - {ok, 12}; - - <<"d"/utf8>> -> - {ok, 13}; - - <<"e"/utf8>> -> - {ok, 14}; - - <<"f"/utf8>> -> - {ok, 15}; - - _ -> - gleam@int:parse(Char) - end, fun(Num) -> - gleam@result:then( - gleam@int:power(16, gleam@int:to_float(Index)), - fun(Base) -> - {ok, - V + gleam@float:round( - gleam@int:to_float(Num) * Base - )} - end - ) - end) - end end - ). - --spec hsla_to_rgba(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -hsla_to_rgba(H, S, L, A) -> - M2 = case L =< 0.5 of - true -> - L * (S + 1.0); - - false -> - (L + S) - (L * S) - end, - M1 = (L * 2.0) - M2, - R = hue_to_rgb(H + (1.0 / 3.0), M1, M2), - G = hue_to_rgb(H, M1, M2), - B = hue_to_rgb(H - (1.0 / 3.0), M1, M2), - {R, G, B, A}. - --spec rgba_to_hsla(float(), float(), float(), float()) -> {float(), - float(), - float(), - float()}. -rgba_to_hsla(R, G, B, A) -> - Min_colour = gleam@float:min(R, gleam@float:min(G, B)), - Max_colour = gleam@float:max(R, gleam@float:max(G, B)), - H1 = case true of - _ when Max_colour =:= R -> - gleam@float:divide(G - B, Max_colour - Min_colour); - - _ when Max_colour =:= G -> - _pipe = gleam@float:divide(B - R, Max_colour - Min_colour), - gleam@result:then(_pipe, fun(D) -> {ok, 2.0 + D} end); - - _ -> - _pipe@1 = gleam@float:divide(R - G, Max_colour - Min_colour), - gleam@result:then(_pipe@1, fun(D@1) -> {ok, 4.0 + D@1} end) - end, - H2 = case H1 of - {ok, V} -> - {ok, V * (1.0 / 6.0)}; - - _ -> - H1 - end, - H3 = case H2 of - {ok, V@1} when V@1 < +0.0 -> - V@1 + 1.0; - - {ok, V@2} -> - V@2; - - _ -> - +0.0 - end, - L = (Min_colour + Max_colour) / 2.0, - S = case true of - _ when Min_colour =:= Max_colour -> - +0.0; - - _ when L < 0.5 -> - case (Max_colour + Min_colour) of - 0.0 -> 0.0; - Gleam@denominator -> (Max_colour - Min_colour) / Gleam@denominator - end; - - _ -> - case ((2.0 - Max_colour) - Min_colour) of - 0.0 -> 0.0; - Gleam@denominator@1 -> (Max_colour - Min_colour) / Gleam@denominator@1 - end - end, - {H3, S, L, A}. - --spec from_rgb255(integer(), integer(), integer()) -> {ok, colour()} | - {error, nil}. -from_rgb255(Red, Green, Blue) -> - gleam@result:then( - begin - _pipe = Red, - _pipe@1 = gleam@int:to_float(_pipe), - _pipe@2 = gleam@float:divide(_pipe@1, 255.0), - gleam@result:then(_pipe@2, fun valid_colour_value/1) - end, - fun(R) -> - gleam@result:then( - begin - _pipe@3 = Green, - _pipe@4 = gleam@int:to_float(_pipe@3), - _pipe@5 = gleam@float:divide(_pipe@4, 255.0), - gleam@result:then(_pipe@5, fun valid_colour_value/1) - end, - fun(G) -> - gleam@result:then( - begin - _pipe@6 = Blue, - _pipe@7 = gleam@int:to_float(_pipe@6), - _pipe@8 = gleam@float:divide(_pipe@7, 255.0), - gleam@result:then(_pipe@8, fun valid_colour_value/1) - end, - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgb(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_rgb(Red, Green, Blue) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> {ok, {rgba, R, G, B, 1.0}} end - ) - end - ) - end - ). - --spec from_rgba(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_rgba(Red, Green, Blue, Alpha) -> - gleam@result:then( - valid_colour_value(Red), - fun(R) -> - gleam@result:then( - valid_colour_value(Green), - fun(G) -> - gleam@result:then( - valid_colour_value(Blue), - fun(B) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {rgba, R, G, B, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsla(float(), float(), float(), float()) -> {ok, colour()} | - {error, nil}. -from_hsla(Hue, Saturation, Lightness, Alpha) -> - gleam@result:then( - valid_colour_value(Hue), - fun(H) -> - gleam@result:then( - valid_colour_value(Saturation), - fun(S) -> - gleam@result:then( - valid_colour_value(Lightness), - fun(L) -> - gleam@result:then( - valid_colour_value(Alpha), - fun(A) -> {ok, {hsla, H, S, L, A}} end - ) - end - ) - end - ) - end - ). - --spec from_hsl(float(), float(), float()) -> {ok, colour()} | {error, nil}. -from_hsl(Hue, Saturation, Lightness) -> - from_hsla(Hue, Saturation, Lightness, 1.0). - --spec from_rgb_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgb_hex(Hex) -> - case (Hex > 16#ffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - R = begin - _pipe = erlang:'bsr'(Hex, 16), - erlang:'band'(_pipe, 16#ff) - end, - G = begin - _pipe@1 = erlang:'bsr'(Hex, 8), - erlang:'band'(_pipe@1, 16#ff) - end, - B = erlang:'band'(Hex, 16#ff), - from_rgb255(R, G, B) - end. - --spec from_rgb_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgb_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgb_hex(Hex_int) end - ). - --spec from_rgba_hex(integer()) -> {ok, colour()} | {error, nil}. -from_rgba_hex(Hex) -> - case (Hex > 16#ffffffff) orelse (Hex < 0) of - true -> - {error, nil}; - - false -> - _assert_subject = begin - _pipe = erlang:'bsr'(Hex, 24), - _pipe@1 = erlang:'band'(_pipe, 16#ff), - _pipe@2 = gleam@int:to_float(_pipe@1), - gleam@float:divide(_pipe@2, 255.0) - end, - {ok, R} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 588}) - end, - _assert_subject@1 = begin - _pipe@3 = erlang:'bsr'(Hex, 16), - _pipe@4 = erlang:'band'(_pipe@3, 16#ff), - _pipe@5 = gleam@int:to_float(_pipe@4), - gleam@float:divide(_pipe@5, 255.0) - end, - {ok, G} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 594}) - end, - _assert_subject@2 = begin - _pipe@6 = erlang:'bsr'(Hex, 8), - _pipe@7 = erlang:'band'(_pipe@6, 16#ff), - _pipe@8 = gleam@int:to_float(_pipe@7), - gleam@float:divide(_pipe@8, 255.0) - end, - {ok, B} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 600}) - end, - _assert_subject@3 = begin - _pipe@9 = erlang:'band'(Hex, 16#ff), - _pipe@10 = gleam@int:to_float(_pipe@9), - gleam@float:divide(_pipe@10, 255.0) - end, - {ok, A} = case _assert_subject@3 of - {ok, _} -> _assert_subject@3; - _assert_fail@3 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@3, - module => <<"gleam_community/colour"/utf8>>, - function => <<"from_rgba_hex"/utf8>>, - line => 606}) - end, - from_rgba(R, G, B, A) - end. - --spec from_rgba_hex_string(binary()) -> {ok, colour()} | {error, nil}. -from_rgba_hex_string(Hex_string) -> - gleam@result:then( - hex_string_to_int(Hex_string), - fun(Hex_int) -> from_rgba_hex(Hex_int) end - ). - --spec to_rgba(colour()) -> {float(), float(), float(), float()}. -to_rgba(Colour) -> - case Colour of - {rgba, R, G, B, A} -> - {R, G, B, A}; - - {hsla, H, S, L, A@1} -> - hsla_to_rgba(H, S, L, A@1) - end. - --spec to_hsla(colour()) -> {float(), float(), float(), float()}. -to_hsla(Colour) -> - case Colour of - {hsla, H, S, L, A} -> - {H, S, L, A}; - - {rgba, R, G, B, A@1} -> - rgba_to_hsla(R, G, B, A@1) - end. - --spec to_css_rgba_string(colour()) -> binary(). -to_css_rgba_string(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Percent = fun(X) -> - _assert_subject = begin - _pipe = X, - _pipe@1 = gleam@float:multiply(_pipe, 10000.0), - _pipe@2 = gleam@float:round(_pipe@1), - _pipe@3 = gleam@int:to_float(_pipe@2), - gleam@float:divide(_pipe@3, 100.0) - end, - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 704}) - end, - P - end, - Round_to = fun(X@1) -> - _assert_subject@1 = begin - _pipe@4 = X@1, - _pipe@5 = gleam@float:multiply(_pipe@4, 1000.0), - _pipe@6 = gleam@float:round(_pipe@5), - _pipe@7 = gleam@int:to_float(_pipe@6), - gleam@float:divide(_pipe@7, 1000.0) - end, - {ok, R@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/colour"/utf8>>, - function => <<"to_css_rgba_string"/utf8>>, - line => 716}) - end, - R@1 - end, - gleam@string:join( - [<<"rgba("/utf8>>, - <<(gleam@float:to_string(Percent(R)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(G)))/binary, "%,"/utf8>>, - <<(gleam@float:to_string(Percent(B)))/binary, "%,"/utf8>>, - gleam@float:to_string(Round_to(A)), - <<")"/utf8>>], - <<""/utf8>> - ). - --spec to_rgba_hex(colour()) -> integer(). -to_rgba_hex(Colour) -> - {R, G, B, A} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 24) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 16) - end, - Blue = begin - _pipe@4 = B * 255.0, - _pipe@5 = gleam@float:round(_pipe@4), - erlang:'bsl'(_pipe@5, 8) - end, - Alpha = begin - _pipe@6 = A * 255.0, - gleam@float:round(_pipe@6) - end, - ((Red + Green) + Blue) + Alpha. - --spec to_rgba_hex_string(colour()) -> binary(). -to_rgba_hex_string(Colour) -> - _pipe = to_rgba_hex(Colour), - gleam@int:to_base16(_pipe). - --spec to_rgb_hex(colour()) -> integer(). -to_rgb_hex(Colour) -> - {R, G, B, _} = to_rgba(Colour), - Red = begin - _pipe = R * 255.0, - _pipe@1 = gleam@float:round(_pipe), - erlang:'bsl'(_pipe@1, 16) - end, - Green = begin - _pipe@2 = G * 255.0, - _pipe@3 = gleam@float:round(_pipe@2), - erlang:'bsl'(_pipe@3, 8) - end, - Blue = begin - _pipe@4 = B * 255.0, - gleam@float:round(_pipe@4) - end, - (Red + Green) + Blue. - --spec to_rgb_hex_string(colour()) -> binary(). -to_rgb_hex_string(Colour) -> - _pipe = to_rgb_hex(Colour), - gleam@int:to_base16(_pipe). diff --git a/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl b/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl deleted file mode 100644 index 64d37bf..0000000 --- a/aoc2023/build/packages/gleam_community_colour/src/gleam_community@colour@accessibility.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(gleam_community@colour@accessibility). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([luminance/1, contrast_ratio/2, maximum_contrast/2]). - --spec intensity(float()) -> float(). -intensity(Colour_value) -> - case true of - _ when Colour_value =< 0.03928 -> - Colour_value / 12.92; - - _ -> - _assert_subject = gleam@float:power( - (Colour_value + 0.055) / 1.055, - 2.4 - ), - {ok, I} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/colour/accessibility"/utf8>>, - function => <<"intensity"/utf8>>, - line => 62}) - end, - I - end. - --spec luminance(gleam_community@colour:colour()) -> float(). -luminance(Colour) -> - {R, G, B, _} = gleam_community@colour:to_rgba(Colour), - R_intensity = intensity(R), - G_intensity = intensity(G), - B_intensity = intensity(B), - ((0.2126 * R_intensity) + (0.7152 * G_intensity)) + (0.0722 * B_intensity). - --spec contrast_ratio( - gleam_community@colour:colour(), - gleam_community@colour:colour() -) -> float(). -contrast_ratio(Colour_a, Colour_b) -> - Luminance_a = luminance(Colour_a) + 0.05, - Luminance_b = luminance(Colour_b) + 0.05, - case Luminance_a > Luminance_b of - true -> - case Luminance_b of - 0.0 -> 0.0; - Gleam@denominator -> Luminance_a / Gleam@denominator - end; - - false -> - case Luminance_a of - 0.0 -> 0.0; - Gleam@denominator@1 -> Luminance_b / Gleam@denominator@1 - end - end. - --spec maximum_contrast( - gleam_community@colour:colour(), - list(gleam_community@colour:colour()) -) -> {ok, gleam_community@colour:colour()} | {error, nil}. -maximum_contrast(Base, Colours) -> - _pipe = Colours, - _pipe@1 = gleam@list:sort( - _pipe, - fun(Colour_a, Colour_b) -> - Contrast_a = contrast_ratio(Base, Colour_a), - Contrast_b = contrast_ratio(Base, Colour_b), - gleam@float:compare(Contrast_b, Contrast_a) - end - ), - gleam@list:first(_pipe@1). diff --git a/aoc2023/build/packages/gleam_community_colour/src/gleam_community_colour.app.src b/aoc2023/build/packages/gleam_community_colour/src/gleam_community_colour.app.src deleted file mode 100644 index a327650..0000000 --- a/aoc2023/build/packages/gleam_community_colour/src/gleam_community_colour.app.src +++ /dev/null @@ -1,9 +0,0 @@ -{application, gleam_community_colour, [ - {vsn, "1.2.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Colour types, conversions, and other utilities"}, - {modules, [gleam_community@colour, - gleam_community@colour@accessibility]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_community_maths/LICENCE b/aoc2023/build/packages/gleam_community_maths/LICENCE deleted file mode 100644 index a84f0ec..0000000 --- a/aoc2023/build/packages/gleam_community_maths/LICENCE +++ /dev/null @@ -1,190 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2023 Gleam Community Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.
\ No newline at end of file diff --git a/aoc2023/build/packages/gleam_community_maths/README.md b/aoc2023/build/packages/gleam_community_maths/README.md deleted file mode 100644 index c912757..0000000 --- a/aoc2023/build/packages/gleam_community_maths/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# gleam-community/maths - -[](https://hex.pm/packages/gleam_community_maths) -[](https://hexdocs.pm/gleam_community_maths/) - -A basic mathematics library that contains some of the most fundamental mathematics functions and utilities. - -The library supports both targets: Erlang and JavaScript. - -## Quickstart - -```gleam -import gleam_community/maths/arithmetics -import gleam_community/maths/combinatorics -import gleam_community/maths/elementary -import gleam_community/maths/piecewise -import gleam_community/maths/predicates -import gleam/float - -pub fn main() { - // Evaluate the sine function - elementary.sin(elementary.pi()) - // Returns Float: 0.0 - - // Find the greatest common divisor - arithmetics.gcd(54, 24) - // Returns Int: 6 - - // Find the minimum and maximum of a list - piecewise.extrema([10.0, 3.0, 50.0, 20.0, 3.0], float.compare) - // Returns Tuple: Ok(#(3.0, 50.0)) - - // Find the list indices of the smallest value - piecewise.arg_minimum([10, 3, 50, 20, 3], float.compare) - // Returns List: Ok([1, 4]) - - // Determine if a number is fractional - predicates.is_fractional(0.3333) - // Returns Bool: True - - // Determine if 28 is a power of 3 - predicates.is_power(28, 3) - // Returns Bool: False - - // Generate all k = 1 combinations of [1, 2] - combinatorics.list_combination([1, 2], 1) - // Returns List: Ok([[1], [2]]) -} - -``` - -## Installation - -`gleam_community` packages are published to [hex.pm](https://hex.pm/packages/gleam_community_maths) -with the prefix `gleam_community_`. You can add them to your Gleam projects directly: - -```sh -gleam add gleam_community_maths -``` diff --git a/aoc2023/build/packages/gleam_community_maths/gleam.toml b/aoc2023/build/packages/gleam_community_maths/gleam.toml deleted file mode 100644 index 9dc5fd7..0000000 --- a/aoc2023/build/packages/gleam_community_maths/gleam.toml +++ /dev/null @@ -1,12 +0,0 @@ -name = "gleam_community_maths" -version = "1.0.1" - -licences = ["Apache-2.0"] -description = "A basic maths library" -repository = { type = "github", user = "gleam-community", repo = "maths" } - -[dependencies] -gleam_stdlib = "~> 0.33" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/arithmetics.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/arithmetics.gleam deleted file mode 100644 index 3e0f63a..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/arithmetics.gleam +++ /dev/null @@ -1,618 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Arithmetics: A module containing a collection of fundamental mathematical functions relating to simple arithmetics (addition, subtraction, multiplication, etc.), but also number theory. -//// -//// * **Division functions** -//// * [`gcd`](#gcd) -//// * [`lcm`](#lcm) -//// * [`divisors`](#divisors) -//// * [`proper_divisors`](#proper_divisors) -//// * **Sums and products** -//// * [`float_sum`](#float_sum) -//// * [`int_sum`](#int_sum) -//// * [`float_product`](#float_product) -//// * [`int_product`](#int_product) -//// * [`float_cumulative_sum`](#float_cumulative_sum) -//// * [`int_cumulative_sum`](#int_cumulative_sum) -//// * [`float_cumulative_product`](#float_cumulative_product) -//// * [`int_cumulative_product`](#int_cumulative_product) -//// - -import gleam/int -import gleam/list -import gleam_community/maths/conversion -import gleam_community/maths/elementary -import gleam_community/maths/piecewise - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function calculates the greatest common multiple of two integers $$x, y \in \mathbb{Z}$$. -/// The greatest common multiple is the largest positive integer that is divisible by both $$x$$ and $$y$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example() { -/// arithmetics.lcm(1, 1) -/// |> should.equal(1) -/// -/// arithmetics.lcm(100, 10) -/// |> should.equal(10) -/// -/// arithmetics.gcd(-36, -17) -/// |> should.equal(1) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn gcd(x: Int, y: Int) -> Int { - let absx: Int = piecewise.int_absolute_value(x) - let absy: Int = piecewise.int_absolute_value(y) - do_gcd(absx, absy) -} - -fn do_gcd(x: Int, y: Int) -> Int { - case x == 0 { - True -> y - False -> { - let assert Ok(z) = int.modulo(y, x) - do_gcd(z, x) - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function calculates the least common multiple of two integers $$x, y \in \mathbb{Z}$$. -/// The least common multiple is the smallest positive integer that has both $$x$$ and $$y$$ as factors. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example() { -/// arithmetics.lcm(1, 1) -/// |> should.equal(1) -/// -/// arithmetics.lcm(100, 10) -/// |> should.equal(100) -/// -/// arithmetics.lcm(-36, -17) -/// |> should.equal(612) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn lcm(x: Int, y: Int) -> Int { - let absx: Int = piecewise.int_absolute_value(x) - let absy: Int = piecewise.int_absolute_value(y) - absx * absy / do_gcd(absx, absy) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function returns all the positive divisors of an integer, including the number iteself. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example() { -/// arithmetics.divisors(4) -/// |> should.equal([1, 2, 4]) -/// -/// arithmetics.divisors(6) -/// |> should.equal([1, 2, 3, 6]) -/// -/// arithmetics.proper_divisors(13) -/// |> should.equal([1, 13]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn divisors(n: Int) -> List(Int) { - find_divisors(n) -} - -fn find_divisors(n: Int) -> List(Int) { - let nabs: Float = piecewise.float_absolute_value(conversion.int_to_float(n)) - let assert Ok(sqrt_result) = elementary.square_root(nabs) - let max: Int = conversion.float_to_int(sqrt_result) + 1 - list.range(2, max) - |> list.fold( - [1, n], - fn(acc: List(Int), i: Int) -> List(Int) { - case n % i == 0 { - True -> [i, n / i, ..acc] - False -> acc - } - }, - ) - |> list.unique() - |> list.sort(int.compare) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function returns all the positive divisors of an integer, excluding the number iteself. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example() { -/// arithmetics.proper_divisors(4) -/// |> should.equal([1, 2]) -/// -/// arithmetics.proper_divisors(6) -/// |> should.equal([1, 2, 3]) -/// -/// arithmetics.proper_divisors(13) -/// |> should.equal([1]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn proper_divisors(n: Int) -> List(Int) { - let divisors: List(Int) = find_divisors(n) - divisors - |> list.take(list.length(divisors) - 1) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the sum of the elements in a list: -/// -/// \\[ -/// \sum_{i=1}^n x_i -/// \\] -/// -/// In the formula, $$n$$ is the length of the list and $$x_i \in \mathbb{R}$$ is the value in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns an error -/// [] -/// |> arithmetics.float_sum() -/// |> should.equal(0.0) -/// -/// // Valid input returns a result -/// [1.0, 2.0, 3.0] -/// |> arithmetics.float_sum() -/// |> should.equal(6.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_sum(arr: List(Float)) -> Float { - case arr { - [] -> 0.0 - _ -> - arr - |> list.fold(0.0, fn(acc: Float, a: Float) -> Float { a +. acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the sum of the elements in a list: -/// -/// \\[ -/// \sum_{i=1}^n x_i -/// \\] -/// -/// In the formula, $$n$$ is the length of the list and $$x_i \in \mathbb{Z}$$ is the value in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns 0 -/// [] -/// |> arithmetics.int_sum() -/// |> should.equal(0) -/// -/// // Valid input returns a result -/// [1, 2, 3] -/// |> arithmetics.int_sum() -/// |> should.equal(6) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_sum(arr: List(Int)) -> Int { - case arr { - [] -> 0 - _ -> - arr - |> list.fold(0, fn(acc: Int, a: Int) -> Int { a + acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the product of the elements in a list: -/// -/// \\[ -/// \prod_{i=1}^n x_i -/// \\] -/// -/// In the formula, $$n$$ is the length of the list and $$x_i \in \mathbb{R}$$ is the value in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns 0.0 -/// [] -/// |> arithmetics.float_product() -/// |> should.equal(0.0) -/// -/// // Valid input returns a result -/// [1.0, 2.0, 3.0] -/// |> arithmetics.float_product() -/// |> should.equal(6.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_product(arr: List(Float)) -> Float { - case arr { - [] -> 1.0 - _ -> - arr - |> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the product of the elements in a list: -/// -/// \\[ -/// \prod_{i=1}^n x_i -/// \\] -/// -/// In the formula, $$n$$ is the length of the list and $$x_i \in \mathbb{Z}$$ is the value in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns 0 -/// [] -/// |> arithmetics.int_product() -/// |> should.equal(0) -/// -/// // Valid input returns a result -/// [1, 2, 3] -/// |> arithmetics.int_product() -/// |> should.equal(6) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_product(arr: List(Int)) -> Int { - case arr { - [] -> 1 - _ -> - arr - |> list.fold(1, fn(acc: Int, a: Int) -> Int { a * acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the cumulative sum of the elements in a list: -/// -/// \\[ -/// v_j = \sum_{i=1}^j x_i \\;\\; \forall j = 1,\dots, n -/// \\] -/// -/// In the formula, $$v_j$$ is the $$j$$'th element in the cumulative sum of $$n$$ elements. -/// That is, $$n$$ is the length of the list and $$x_i \in \mathbb{R}$$ is the value in the input list indexed by $$i$$. -/// The value $$v_j$$ is thus the sum of the $$1$$ to $$j$$ first elements in the given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// [] -/// |> arithmetics.float_cumulative_sum() -/// |> should.equal([]) -/// -/// // Valid input returns a result -/// [1.0, 2.0, 3.0] -/// |> arithmetics.float_cumulative_sum() -/// |> should.equal([1.0, 3.0, 6.0]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_cumulative_sum(arr: List(Float)) -> List(Float) { - case arr { - [] -> [] - _ -> - arr - |> list.scan(0.0, fn(acc: Float, a: Float) -> Float { a +. acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the cumulative sum of the elements in a list: -/// -/// \\[ -/// v_j = \sum_{i=1}^j x_i \\;\\; \forall j = 1,\dots, n -/// \\] -/// -/// In the formula, $$v_j$$ is the $$j$$'th element in the cumulative sum of $$n$$ elements. -/// That is, $$n$$ is the length of the list and $$x_i \in \mathbb{Z}$$ is the value in the input list indexed by $$i$$. -/// The value $$v_j$$ is thus the sum of the $$1$$ to $$j$$ first elements in the given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// [] -/// |> arithmetics.int_cumulative_sum() -/// |> should.equal([]) -/// -/// // Valid input returns a result -/// [1, 2, 3] -/// |> arithmetics.int_cumulative_sum() -/// |> should.equal([1, 3, 6]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_cumulative_sum(arr: List(Int)) -> List(Int) { - case arr { - [] -> [] - _ -> - arr - |> list.scan(0, fn(acc: Int, a: Int) -> Int { a + acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the cumulative product of the elements in a list: -/// -/// \\[ -/// v_j = \prod_{i=1}^j x_i \\;\\; \forall j = 1,\dots, n -/// \\] -/// -/// In the formula, $$v_j$$ is the $$j$$'th element in the cumulative product of $$n$$ elements. -/// That is, $$n$$ is the length of the list and $$x_i \in \mathbb{R}$$ is the value in the input list indexed by $$i$$. -/// The value $$v_j$$ is thus the sum of the $$1$$ to $$j$$ first elements in the given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns an error -/// [] -/// |> arithmetics.float_cumulative_product() -/// |> should.equal([]) -/// -/// // Valid input returns a result -/// [1.0, 2.0, 3.0] -/// |> arithmetics.float_cumulative_product() -/// |> should.equal([1.0, 2.0, 6.0]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_cumumlative_product(arr: List(Float)) -> List(Float) { - case arr { - [] -> [] - _ -> - arr - |> list.scan(1.0, fn(acc: Float, a: Float) -> Float { a *. acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the cumulative product of the elements in a list: -/// -/// \\[ -/// v_j = \prod_{i=1}^j x_i \\;\\; \forall j = 1,\dots, n -/// \\] -/// -/// In the formula, $$v_j$$ is the $$j$$'th element in the cumulative product of $$n$$ elements. -/// That is, $$n$$ is the length of the list and $$x_i \in \mathbb{Z}$$ is the value in the input list indexed by $$i$$. -/// The value $$v_j$$ is thus the product of the $$1$$ to $$j$$ first elements in the given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/arithmetics -/// -/// pub fn example () { -/// // An empty list returns an error -/// [] -/// |> arithmetics.int_cumulative_product() -/// |> should.equal([]) -/// -/// // Valid input returns a result -/// [1, 2, 3] -/// |> arithmetics.int_cumulative_product() -/// |> should.equal([1, 2, 6]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_cumulative_product(arr: List(Int)) -> List(Int) { - case arr { - [] -> [] - _ -> - arr - |> list.scan(1, fn(acc: Int, a: Int) -> Int { a * acc }) - } -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/combinatorics.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/combinatorics.gleam deleted file mode 100644 index ee771a1..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/combinatorics.gleam +++ /dev/null @@ -1,432 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Combinatorics: A module that offers mathematical functions related to counting, arrangements, and combinations. -//// -//// * **Combinatorial functions** -//// * [`combination`](#combination) -//// * [`factorial`](#factorial) -//// * [`permutation`](#permutation) -//// * [`list_combination`](#list_combination) -//// * [`list_permutation`](#list_permutation) -//// * [`cartesian_product`](#cartesian_product) -//// - -import gleam/list -import gleam/set - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A combinatorial function for computing the number of a $$k$$-combinations of $$n$$ elements: -/// -/// \\[ -/// C(n, k) = \binom{n}{k} = \frac{n!}{k! (n-k)!} -/// \\] -/// Also known as "$$n$$ choose $$k$$" or the binomial coefficient. -/// -/// The implementation uses the effecient iterative multiplicative formula for the computation. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/combinatorics -/// -/// pub fn example() { -/// // Invalid input gives an error -/// // Error on: n = -1 < 0 -/// combinatorics.combination(-1, 1) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// combinatorics.combination(4, 0) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.combination(4, 4) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.combination(4, 2) -/// |> should.equal(Ok(6)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn combination(n: Int, k: Int) -> Result(Int, String) { - case n < 0 { - True -> - "Invalid input argument: n < 0. Valid input is n > 0." - |> Error - False -> - case k < 0 || k > n { - True -> - 0 - |> Ok - False -> - case k == 0 || k == n { - True -> - 1 - |> Ok - False -> { - let min = case k < n - k { - True -> k - False -> n - k - } - list.range(1, min) - |> list.fold( - 1, - fn(acc: Int, x: Int) -> Int { acc * { n + 1 - x } / x }, - ) - |> Ok - } - } - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A combinatorial function for computing the total number of combinations of $$n$$ -/// elements, that is $$n!$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/combinatorics -/// -/// pub fn example() { -/// // Invalid input gives an error -/// combinatorics.factorial(-1) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// combinatorics.factorial(0) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.factorial(1) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.factorial(2) -/// |> should.equal(Ok(2)) -/// -/// combinatorics.factorial(3) -/// |> should.equal(Ok(6)) -/// -/// combinatorics.factorial(4) -/// |> should.equal(Ok(24)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn factorial(n) -> Result(Int, String) { - case n < 0 { - True -> - "Invalid input argument: n < 0. Valid input is n > 0." - |> Error - False -> - case n { - 0 -> - 1 - |> Ok - 1 -> - 1 - |> Ok - _ -> - list.range(1, n) - |> list.fold(1, fn(acc: Int, x: Int) { acc * x }) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A combinatorial function for computing the number of $$k$$-permuations (without repetitions) -/// of $$n$$ elements: -/// -/// \\[ -/// P(n, k) = \frac{n!}{(n - k)!} -/// \\] -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/combinatorics -/// -/// pub fn example() { -/// // Invalid input gives an error -/// // Error on: n = -1 < 0 -/// combinatorics.permutation(-1, 1) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// combinatorics.permutation(4, 0) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.permutation(4, 4) -/// |> should.equal(Ok(1)) -/// -/// combinatorics.permutation(4, 2) -/// |> should.equal(Ok(12)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn permutation(n: Int, k: Int) -> Result(Int, String) { - case n < 0 { - True -> - "Invalid input argument: n < 0. Valid input is n > 0." - |> Error - False -> - case k < 0 || k > n { - True -> - 0 - |> Ok - False -> - case k == n { - True -> - 1 - |> Ok - False -> { - let assert Ok(v1) = factorial(n) - let assert Ok(v2) = factorial(n - k) - v1 / v2 - |> Ok - } - } - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Generate all $$k$$-combinations based on a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/set -/// import gleam_community/maths/combinatorics -/// -/// pub fn example () { -/// let assert Ok(result) = combinatorics.list_combination([1, 2, 3, 4], 3) -/// result -/// |> set.from_list() -/// |> should.equal(set.from_list([[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]])) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn list_combination(arr: List(a), k: Int) -> Result(List(List(a)), String) { - case k < 0 { - True -> - "Invalid input argument: k < 0. Valid input is k > 0." - |> Error - False -> { - case k > list.length(arr) { - True -> - "Invalid input argument: k > length(arr). Valid input is 0 < k <= length(arr)." - |> Error - False -> { - do_list_combination(arr, k, []) - |> Ok - } - } - } - } -} - -fn do_list_combination(arr: List(a), k: Int, prefix: List(a)) -> List(List(a)) { - case k { - 0 -> [list.reverse(prefix)] - _ -> - case arr { - [] -> [] - [x, ..xs] -> { - let with_x = do_list_combination(xs, k - 1, [x, ..prefix]) - let without_x = do_list_combination(xs, k, prefix) - list.append(with_x, without_x) - } - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Generate all permutations of a given list. -/// -/// Repeated elements are treated as distinct for the -/// purpose of permutations, so two identical elements -/// for example will appear "both ways round". This -/// means lists with repeated elements return the same -/// number of permutations as ones without. -/// -/// N.B. The output of this function is a list of size -/// factorial in the size of the input list. Caution is -/// advised on input lists longer than ~11 elements, which -/// may cause the VM to use unholy amounts of memory for -/// the output. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/set -/// import gleam_community/maths/combinatorics -/// -/// pub fn example () { -/// [1, 2, 3] -/// |> combinatorics.list_permutation() -/// |> set.from_list() -/// |> should.equal(set.from_list([ -/// [1, 2, 3], -/// [2, 1, 3], -/// [3, 1, 2], -/// [1, 3, 2], -/// [2, 3, 1], -/// [3, 2, 1], -/// ])) -/// -/// [1.0, 1.0] -/// |> combinatorics.list_permutation() -/// |> should.equal([[1.0, 1.0], [1.0, 1.0]]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn list_permutation(arr: List(a)) -> List(List(a)) { - case arr { - [] -> [[]] - _ -> { - use x <- list.flat_map(arr) - // `x` is drawn from the list `arr` above, - // so Ok(...) can be safely asserted as the result of `list.pop` below - let assert Ok(#(_, remaining)) = list.pop(arr, fn(y) { x == y }) - list.map(list_permutation(remaining), fn(perm) { [x, ..perm] }) - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Generate a list containing all combinations of pairs of elements coming from two given lists. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/list -/// import gleam_community/maths/combinatorics -/// -/// pub fn example () { -/// [] -/// |> combinatorics.cartesian_product([]) -/// |> should.equal([]) -/// -/// [1.0, 10.0] -/// |> combinatorics.cartesian_product([1.0, 2.0]) -/// |> should.equal([#(1.0, 1.0), #(1.0, 2.0), #(10.0, 1.0), #(10.0, 2.0)]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cartesian_product(xarr: List(a), yarr: List(a)) -> List(#(a, a)) { - let xset: set.Set(a) = - xarr - |> set.from_list() - let yset: set.Set(a) = - yarr - |> set.from_list() - xset - |> set.fold( - set.new(), - fn(accumulator0: set.Set(#(a, a)), member0: a) -> set.Set(#(a, a)) { - set.fold( - yset, - accumulator0, - fn(accumulator1: set.Set(#(a, a)), member1: a) -> set.Set(#(a, a)) { - set.insert(accumulator1, #(member0, member1)) - }, - ) - }, - ) - |> set.to_list() -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/conversion.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/conversion.gleam deleted file mode 100644 index 017aabd..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/conversion.gleam +++ /dev/null @@ -1,183 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Conversion: A module containing various functions for converting between types and quantities. -//// -//// * **Misc. functions** -//// * [`float_to_int`](#float_to_int) -//// * [`int_to_float`](#int_to_float) -//// * [`degrees_to_radians`](#degrees_to_radians) -//// * [`radians_to_degrees`](#radians_to_degrees) - -import gleam/int - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A function that produces a number of type `Float` from an `Int`. -/// -/// Note: The function is equivalent to the `int.to_float` function in the Gleam stdlib. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/conversion -/// -/// pub fn example() { -/// conversion.int_to_float(-1) -/// |> should.equal(-1.0) -/// -/// conversion.int_to_float(1) -/// |> should.equal(1.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_to_float(x: Int) -> Float { - int.to_float(x) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function returns the integral part of a given floating point value. -/// That is, everything after the decimal point of a given floating point value is discarded and only the integer value before the decimal point is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/conversion -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// conversion.float_to_int(12.0654) -/// |> should.equal(12) -/// -/// // Note: Making the following function call is equivalent -/// // but instead of returning a value of type 'Int' a value -/// // of type 'Float' is returned. -/// piecewise.round(12.0654, option.Some(0), option.Some(piecewise.RoundToZero)) -/// |> should.equal(Ok(12.0)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_to_int(x: Float) -> Int { - do_to_int(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../../maths.mjs", "truncate") -fn do_to_int(a: Float) -> Int - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Convert a value in degrees to a value measured in radians. -/// That is, $$1 \text{ degrees } = \frac{\pi}{180} \text{ radians }$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/conversion -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// conversion.degrees_to_radians(360.) -/// |> should.equal(2. *. elementary.pi()) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn degrees_to_radians(x: Float) -> Float { - x *. do_pi() /. 180.0 -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Convert a value in degrees to a value measured in radians. -/// That is, $$1 \text{ radians } = \frac{180}{\pi} \text{ degrees }$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/conversion -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// conversion.radians_to_degrees(0.0) -/// |> should.equal(0.0) -/// -/// conversion.radians_to_degrees(2. *. elementary.pi()) -/// |> should.equal(360.) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn radians_to_degrees(x: Float) -> Float { - x *. 180.0 /. do_pi() -} - -@external(erlang, "math", "pi") -@external(javascript, "../../maths.mjs", "pi") -fn do_pi() -> Float diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/elementary.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/elementary.gleam deleted file mode 100644 index 1b518a4..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/elementary.gleam +++ /dev/null @@ -1,1256 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Elementary: A module containing a comprehensive set of foundational mathematical functions and constants. -//// -//// * **Trigonometric and hyperbolic functions** -//// * [`acos`](#acos) -//// * [`acosh`](#acosh) -//// * [`asin`](#asin) -//// * [`asinh`](#asinh) -//// * [`atan`](#atan) -//// * [`atan2`](#atan2) -//// * [`atanh`](#atanh) -//// * [`cos`](#cos) -//// * [`cosh`](#cosh) -//// * [`sin`](#sin) -//// * [`sinh`](#sinh) -//// * [`tan`](#tan) -//// * [`tanh`](#tanh) -//// * **Powers, logs and roots** -//// * [`exponential`](#exponential) -//// * [`natural_logarithm`](#natural_logarithm) -//// * [`logarithm`](#logarithm) -//// * [`logarithm_2`](#logarithm_2) -//// * [`logarithm_10`](#logarithm_10) -//// * [`power`](#power) -//// * [`square_root`](#square_root) -//// * [`cube_root`](#cube_root) -//// * [`nth_root`](#nth_root) -//// * **Mathematical constants** -//// * [`pi`](#pi) -//// * [`tau`](#tau) -//// * [`e`](#e) -//// - -import gleam/int -import gleam/option - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse cosine function: -/// -/// \\[ -/// \forall x \in \[-1, 1\], \\; \cos^{-1}{(x)} = y \in \[0, \pi \] -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\[-1, 1\]$$ as input and returns a -/// numeric value $$y$$ that lies in the range $$\[0, \pi \]$$ (an angle in radians). -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.acos(1.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.acos(1.1) -/// |> should.be_error() -/// -/// elementary.acos(-1.1) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn acos(x: Float) -> Result(Float, String) { - case x >=. -1.0 && x <=. 1.0 { - True -> - do_acos(x) - |> Ok - False -> - "Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1." - |> Error - } -} - -@external(erlang, "math", "acos") -@external(javascript, "../../maths.mjs", "acos") -fn do_acos(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse hyperbolic cosine function: -/// -/// \\[ -/// \forall x \in [1, +\infty\), \\; \cosh^{-1}{(x)} = y \in \[0, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\[1, +\infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\[0, +\infty\)$$ (an angle in radians). -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.acosh(1.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.acosh(0.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn acosh(x: Float) -> Result(Float, String) { - case x >=. 1.0 { - True -> - do_acosh(x) - |> Ok - False -> - "Invalid input argument: x < 1. Valid input is x >= 1." - |> Error - } -} - -@external(erlang, "math", "acosh") -@external(javascript, "../../maths.mjs", "acosh") -fn do_acosh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse sine function: -/// -/// \\[ -/// \forall x \in \[-1, 1\], \\; \sin^{-1}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\[-1, 1\]$$ as input and returns a numeric -/// value $$y$$ that lies in the range $$\[-\frac{\pi}{2}, \frac{\pi}{2}\]$$ (an angle in radians). -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.asin(0.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.asin(1.1) -/// |> should.be_error() -/// -/// elementary.asin(-1.1) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn asin(x: Float) -> Result(Float, String) { - case x >=. -1.0 && x <=. 1.0 { - True -> - do_asin(x) - |> Ok - False -> - "Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1." - |> Error - } -} - -@external(erlang, "math", "asin") -@external(javascript, "../../maths.mjs", "asin") -fn do_asin(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse hyperbolic sine function: -/// -/// \\[ -/// \forall x \in \(-\infty, \infty\), \\; \sinh^{-1}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, +\infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, +\infty\)$$ (an angle in radians). -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.asinh(0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn asinh(x: Float) -> Float { - do_asinh(x) -} - -@external(erlang, "math", "asinh") -@external(javascript, "../../maths.mjs", "asinh") -fn do_asinh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse tangent function: -/// -/// \\[ -/// \forall x \in \(-\infty, \infty\), \\; \tan^{-1}{(x)} = y \in \[-\frac{\pi}{2}, \frac{\pi}{2}\] -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, +\infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\[-\frac{\pi}{2}, \frac{\pi}{2}\]$$ (an angle in radians). -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.atan(0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn atan(x: Float) -> Float { - do_atan(x) -} - -@external(erlang, "math", "atan") -@external(javascript, "../../maths.mjs", "atan") -fn do_atan(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse 2-argument tangent function: -/// -/// \\[ -/// \text{atan2}(y, x) = -/// \begin{cases} -/// \tan^{-1}(\frac y x) &\text{if } x > 0, \\\\ -/// \tan^{-1}(\frac y x) + \pi &\text{if } x < 0 \text{ and } y \ge 0, \\\\ -/// \tan^{-1}(\frac y x) - \pi &\text{if } x < 0 \text{ and } y < 0, \\\\ -/// +\frac{\pi}{2} &\text{if } x = 0 \text{ and } y > 0, \\\\ -/// -\frac{\pi}{2} &\text{if } x = 0 \text{ and } y < 0, \\\\ -/// \text{undefined} &\text{if } x = 0 \text{ and } y = 0. -/// \end{cases} -/// \\] -/// -/// The function returns the angle in radians from the x-axis to the line containing the -/// origin $$\(0, 0\)$$ and a point given as input with coordinates $$\(x, y\)$$. The numeric value -/// returned by $$\text{atan2}(y, x)$$ is in the range $$\[-\pi, \pi\]$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.atan2(0.0, 0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn atan2(y: Float, x: Float) -> Float { - do_atan2(y, x) -} - -@external(erlang, "math", "atan2") -@external(javascript, "../../maths.mjs", "atan2") -fn do_atan2(a: Float, b: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The inverse hyperbolic tangent function: -/// -/// \\[ -/// \forall x \in \(-1, 1\), \\; \tanh^{-1}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-1, 1\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$ (an angle in radians). -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.atanh(0.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.atanh(1.0) -/// |> should.be_error() -/// -/// elementary.atanh(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn atanh(x: Float) -> Result(Float, String) { - case x >. -1.0 && x <. 1.0 { - True -> - do_atanh(x) - |> Ok - False -> - "Invalid input argument: x > -1 or x < 1. Valid input is -1. < x < 1." - |> Error - } -} - -@external(erlang, "math", "atanh") -@external(javascript, "../../maths.mjs", "atanh") -fn do_atanh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The cosine function: -/// -/// \\[ -/// \forall x \in \(-\infty, +\infty\), \\; \cos{(x)} = y \in \[-1, 1\] -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, \infty\)$$ (an angle in radians) -/// as input and returns a numeric value $$y$$ that lies in the range $$\[-1, 1\]$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.cos(0.0) -/// |> should.equal(1.0) -/// -/// elementary.cos(elementary.pi()) -/// |> should.equal(-1.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cos(x: Float) -> Float { - do_cos(x) -} - -@external(erlang, "math", "cos") -@external(javascript, "../../maths.mjs", "cos") -fn do_cos(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The hyperbolic cosine function: -/// -/// \\[ -/// \forall x \in \(-\infty, \infty\), \\; \cosh{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, \infty\)$$ as input (an angle in radians) -/// and returns a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$. -/// If the input value is too large an overflow error might occur. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.cosh(0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cosh(x: Float) -> Float { - do_cosh(x) -} - -@external(erlang, "math", "cosh") -@external(javascript, "../../maths.mjs", "cosh") -fn do_cosh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The sine function: -/// -/// \\[ -/// \forall x \in \(-\infty, +\infty\), \\; \sin{(x)} = y \in \[-1, 1\] -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, \infty\)$$ (an angle in radians) -/// as input and returns a numeric value $$y$$ that lies in the range $$\[-1, 1\]$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.sin(0.0) -/// |> should.equal(0.0) -/// -/// elementary.sin(0.5 *. elementary.pi()) -/// |> should.equal(1.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn sin(x: Float) -> Float { - do_sin(x) -} - -@external(erlang, "math", "sin") -@external(javascript, "../../maths.mjs", "sin") -fn do_sin(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The hyperbolic sine function: -/// -/// \\[ -/// \forall x \in \(-\infty, +\infty\), \\; \sinh{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, +\infty\)$$ as input -/// (an angle in radians) and returns a numeric value $$y$$ that lies in the range -/// $$\(-\infty, +\infty\)$$. If the input value is too large an overflow error might -/// occur. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.sinh(0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn sinh(x: Float) -> Float { - do_sinh(x) -} - -@external(erlang, "math", "sinh") -@external(javascript, "../../maths.mjs", "sinh") -fn do_sinh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The tangent function: -/// -/// \\[ -/// \forall x \in \(-\infty, +\infty\), \\; \tan{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, +\infty\)$$ as input -/// (an angle in radians) and returns a numeric value $$y$$ that lies in the range -/// $$\(-\infty, +\infty\)$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.tan(0.0) -/// |> should.equal(0.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn tan(x: Float) -> Float { - do_tan(x) -} - -@external(erlang, "math", "tan") -@external(javascript, "../../maths.mjs", "tan") -fn do_tan(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The hyperbolic tangent function: -/// -/// \\[ -/// \forall x \in \(-\infty, \infty\), \\; \tanh{(x)} = y \in \[-1, 1\] -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(-\infty, \infty\)$$ as input (an angle in radians) -/// and returns a numeric value $$y$$ that lies in the range $$\[-1, 1\]$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example () { -/// elementary.tanh(0.0) -/// |> should.equal(0.0) -/// -/// elementary.tanh(25.0) -/// |> should.equal(1.0) -/// -/// elementary.tanh(-25.0) -/// |> should.equal(-1.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn tanh(x: Float) -> Float { - do_tanh(x) -} - -@external(erlang, "math", "tanh") -@external(javascript, "../../maths.mjs", "tanh") -fn do_tanh(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The exponential function: -/// -/// \\[ -/// \forall x \in \(-\infty, \infty\), \\; e^{(x)} = y \in \(0, +\infty\) -/// \\] -/// -/// $$e \approx 2.71828\dots$$ is Eulers' number. -/// -/// Note: If the input value $$x$$ is too large an overflow error might occur. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.exponential(0.0) -/// |> should.equal(1.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn exponential(x: Float) -> Float { - do_exponential(x) -} - -@external(erlang, "math", "exp") -@external(javascript, "../../maths.mjs", "exponential") -fn do_exponential(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The natural logarithm function: -/// -/// \\[ -/// \forall x \in \(0, \infty\), \\; \log_{e}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(0, \infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$. -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example () { -/// elementary.natural_logarithm(1.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.natural_logarithm(elementary.e()) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.natural_logarithm(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn natural_logarithm(x: Float) -> Result(Float, String) { - case x >. 0.0 { - True -> - do_natural_logarithm(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error - } -} - -@external(erlang, "math", "log") -@external(javascript, "../../maths.mjs", "logarithm") -fn do_natural_logarithm(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The base $$b$$ logarithm function (computed through the "change of base" formula): -/// -/// \\[ -/// \forall x \in \(0, \infty\) \textnormal{ and } b > 1, \\; \log_{b}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(0, \infty\)$$ and a base $$b > 1$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$. -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/elementary -/// -/// pub fn example () { -/// elementary.logarithm(1.0, option.Some(10.0)) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.logarithm(elementary.e(), option.Some(elementary.e())) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.logarithm(-1.0, option.Some(2.0)) -/// |> should.be_error() -/// } -/// </details> -/// -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String) { - case x >. 0.0 { - True -> - case base { - option.Some(a) -> - case a >. 0.0 && a != 1.0 { - True -> { - // Apply the "change of base formula" - let assert Ok(numerator) = logarithm_10(x) - let assert Ok(denominator) = logarithm_10(a) - numerator /. denominator - |> Ok - } - False -> - "Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1." - |> Error - } - _ -> - "Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1." - |> Error - } - _ -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The The base-2 logarithm function: -/// -/// \\[ -/// \forall x \in \(0, \infty), \\; \log_{2}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(0, \infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$. -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example () { -/// elementary.logarithm_2(1.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.logarithm_2(2.0) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.logarithm_2(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn logarithm_2(x: Float) -> Result(Float, String) { - case x >. 0.0 { - True -> - do_logarithm_2(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error - } -} - -@external(erlang, "math", "log2") -@external(javascript, "../../maths.mjs", "logarithm_2") -fn do_logarithm_2(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The base-10 logarithm function: -/// -/// \\[ -/// \forall x \in \(0, \infty), \\; \log_{10}{(x)} = y \in \(-\infty, +\infty\) -/// \\] -/// -/// The function takes a number $$x$$ in its domain $$\(0, \infty\)$$ as input and returns -/// a numeric value $$y$$ that lies in the range $$\(-\infty, \infty\)$$. -/// If the input value is outside the domain of the function an error is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example () { -/// elementary.logarithm_10(1.0) -/// |> should.equal(Ok(0.0)) -/// -/// elementary.logarithm_10(10.0) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.logarithm_10(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn logarithm_10(x: Float) -> Result(Float, String) { - case x >. 0.0 { - True -> - do_logarithm_10(x) - |> Ok - False -> - "Invalid input argument: x <= 0. Valid input is x > 0." - |> Error - } -} - -@external(erlang, "math", "log10") -@external(javascript, "../../maths.mjs", "logarithm_10") -fn do_logarithm_10(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The exponentiation function: $$y = x^{a}$$. -/// -/// Note that the function is not defined if: -/// 1. The base is negative ($$x < 0$$) and the exponent is fractional -/// ($$a = \frac{n}{m}$$ is an irrreducible fraction). An error will be returned -/// as an imaginary number will otherwise have to be returned. -/// 2. The base is zero ($$x = 0$$) and the exponent is negative ($$a < 0$$) then the -/// expression is equivalent to the exponent $$y$$ divided by $$0$$ and an -/// error will have to be returned as the expression is otherwise undefined. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.power(2., -1.) -/// |> should.equal(Ok(0.5)) -/// -/// elementary.power(2., 2.) -/// |> should.equal(Ok(4.0)) -/// -/// elementary.power(-1., 0.5) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn power(x: Float, y: Float) -> Result(Float, String) { - let fractional: Bool = do_ceiling(y) -. y >. 0.0 - // In the following check: - // 1. If the base (x) is negative and the exponent (y) is fractional - // then return an error as it will otherwise be an imaginary number - // 2. If the base (x) is 0 and the exponent (y) is negative then the - // expression is equivalent to the exponent (y) divided by 0 and an - // error should be returned - case x <. 0.0 && fractional || x == 0.0 && y <. 0.0 { - True -> - "Invalid input argument: x < 0 and y is fractional or x = 0 and y < 0." - |> Error - False -> - do_power(x, y) - |> Ok - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../../maths.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -@external(erlang, "math", "ceil") -@external(javascript, "../../maths.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The square root function: $$y = \sqrt[2]{x} = x^{\frac{1}{2}}$$. -/// -/// Note that the function is not defined if: -/// 1. The input is negative ($$x < 0$$). An error will be returned -/// as an imaginary number will otherwise have to be returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.square_root(1.0) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.square_root(4.0) -/// |> should.equal(Ok(2.0)) -/// -/// elementary.square_root(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn square_root(x: Float) -> Result(Float, String) { - // In the following check: - // 1. If x is negative then return an error as it will otherwise be an - // imaginary number - case x <. 0.0 { - True -> - "Invalid input argument: x < 0." - |> Error - False -> { - let assert Ok(result) = power(x, 1.0 /. 2.0) - result - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The cube root function: $$y = \sqrt[3]{x} = x^{\frac{1}{3}}$$. -/// -/// Note that the function is not defined if: -/// 1. The input is negative ($$x < 0$$). An error will be returned -/// as an imaginary number will otherwise have to be returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.cube_root(1.0) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.cube_root(27.0) -/// |> should.equal(Ok(3.0)) -/// -/// elementary.cube_root(-1.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn cube_root(x: Float) -> Result(Float, String) { - // In the following check: - // 1. If x is negative then return an error as it will otherwise be an - // imaginary number - case x <. 0.0 { - True -> - "Invalid input argument: x < 0." - |> Error - False -> { - let assert Ok(result) = power(x, 1.0 /. 3.0) - result - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The $$n$$'th root function: $$y = \sqrt[n]{x} = x^{\frac{1}{n}}$$. -/// -/// Note that the function is not defined if: -/// 1. The input is negative ($$x < 0$$). An error will be returned -/// as an imaginary number will otherwise have to be returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// elementary.nth_root(1.0, 2) -/// |> should.equal(Ok(1.0)) -/// -/// elementary.nth_root(27.0, 3) -/// |> should.equal(Ok(3.0)) -/// -/// elementary.nth_root(256.0, 4) -/// |> should.equal(Ok(4.0)) -/// -/// elementary.nth_root(-1.0, 2) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn nth_root(x: Float, n: Int) -> Result(Float, String) { - // In the following check: - // 1. If x is negative then return an error as it will otherwise be an - // imaginary number - case x <. 0.0 { - True -> - "Invalid input argument: x < 0. Valid input is x > 0" - |> Error - False -> - case n >= 1 { - True -> { - let assert Ok(result) = power(x, 1.0 /. int.to_float(n)) - result - |> Ok - } - False -> - "Invalid input argument: n < 1. Valid input is n >= 2." - |> Error - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The mathematical constant pi: $$\pi \approx 3.1415\dots$$ -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn pi() -> Float { - do_pi() -} - -@external(erlang, "math", "pi") -@external(javascript, "../../maths.mjs", "pi") -fn do_pi() -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The mathematical constant tau: $$\tau = 2 \cdot \pi \approx 6.283\dots$$ -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn tau() -> Float { - 2.0 *. pi() -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Euler's number $$e \approx 2.71828\dots$$. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// -/// pub fn example() { -/// // Test that the constant is approximately equal to 2.7128... -/// elementary.e() -/// |> elementary.is_close(2.7128, 0.0, 0.000001) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn e() -> Float { - exponential(1.0) -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/metrics.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/metrics.gleam deleted file mode 100644 index 1dab2b4..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/metrics.gleam +++ /dev/null @@ -1,560 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Metrics: A module offering functions for calculating distances and other types of metrics. -//// -//// * **Distances** -//// * [`norm`](#norm) -//// * [`manhatten_distance`](#float_manhatten_distance) -//// * [`minkowski_distance`](#minkowski_distance) -//// * [`euclidean_distance`](#euclidean_distance) -//// * **Basic statistical measures** -//// * [`mean`](#mean) -//// * [`median`](#median) -//// * [`variance`](#variance) -//// * [`standard_deviation`](#standard_deviation) -//// - -import gleam_community/maths/elementary -import gleam_community/maths/piecewise -import gleam_community/maths/arithmetics -import gleam_community/maths/predicates -import gleam_community/maths/conversion -import gleam/list -import gleam/pair -import gleam/float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the $$p$$-norm of a list (representing a vector): -/// -/// \\[ -/// \left( \sum_{i=1}^n \left|x_i\right|^{p} \right)^{\frac{1}{p}} -/// \\] -/// -/// In the formula, $$n$$ is the length of the list and $$x_i$$ is the value in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/metrics -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// -/// [1.0, 1.0, 1.0] -/// |> metrics.norm(1.0) -/// |> predicates.is_close(3.0, 0.0, tol) -/// |> should.be_true() -/// -/// [1.0, 1.0, 1.0] -/// |> metrics.norm(-1.0) -/// |> predicates.is_close(0.3333333333333333, 0.0, tol) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn norm(arr: List(Float), p: Float) -> Float { - case arr { - [] -> 0.0 - _ -> { - let agg: Float = - arr - |> list.fold( - 0.0, - fn(acc: Float, a: Float) -> Float { - let assert Ok(result) = - elementary.power(piecewise.float_absolute_value(a), p) - result +. acc - }, - ) - let assert Ok(result) = elementary.power(agg, 1.0 /. p) - result - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the Manhatten distance between two lists (representing vectors): -/// -/// \\[ -/// \sum_{i=1}^n \left|x_i - y_i \right| -/// \\] -/// -/// In the formula, $$n$$ is the length of the two lists and $$x_i, y_i$$ are the values in the respective input lists indexed by $$i, j$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/metrics -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// -/// // Empty lists returns 0.0 -/// metrics.float_manhatten_distance([], []) -/// |> should.equal(Ok(0.0)) -/// -/// // Differing lengths returns error -/// metrics.manhatten_distance([], [1.0]) -/// |> should.be_error() -/// -/// let assert Ok(result) = metrics.manhatten_distance([0.0, 0.0], [1.0, 2.0]) -/// result -/// |> predicates.is_close(3.0, 0.0, tol) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn manhatten_distance( - xarr: List(Float), - yarr: List(Float), -) -> Result(Float, String) { - minkowski_distance(xarr, yarr, 1.0) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the Minkowski distance between two lists (representing vectors): -/// -/// \\[ -/// \left( \sum_{i=1}^n \left|x_i - y_i \right|^{p} \right)^{\frac{1}{p}} -/// \\] -/// -/// In the formula, $$p >= 1$$ is the order, $$n$$ is the length of the two lists and $$x_i, y_i$$ are the values in the respective input lists indexed by $$i, j$$. -/// -/// The Minkowski distance is a generalization of both the Euclidean distance ($$p=2$$) and the Manhattan distance ($$p = 1$$). -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/metrics -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// -/// // Empty lists returns 0.0 -/// metrics.minkowski_distance([], [], 1.0) -/// |> should.equal(Ok(0.0)) -/// -/// // Differing lengths returns error -/// metrics.minkowski_distance([], [1.0], 1.0) -/// |> should.be_error() -/// -/// // Test order < 1 -/// metrics.minkowski_distance([0.0, 0.0], [0.0, 0.0], -1.0) -/// |> should.be_error() -/// -/// let assert Ok(result) = metrics.minkowski_distance([0.0, 0.0], [1.0, 2.0], 1.0) -/// result -/// |> predicates.is_close(3.0, 0.0, tol) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn minkowski_distance( - xarr: List(Float), - yarr: List(Float), - p: Float, -) -> Result(Float, String) { - let xlen: Int = list.length(xarr) - let ylen: Int = list.length(yarr) - case xlen == ylen { - False -> - "Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)." - |> Error - True -> - case p <. 1.0 { - True -> - "Invalid input argument: p < 1. Valid input is p >= 1." - |> Error - False -> - list.zip(xarr, yarr) - |> list.map(fn(tuple: #(Float, Float)) -> Float { - pair.first(tuple) -. pair.second(tuple) - }) - |> norm(p) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the Euclidean distance between two lists (representing vectors): -/// -/// \\[ -/// \left( \sum_{i=1}^n \left|x_i - y_i \right|^{2} \right)^{\frac{1}{2}} -/// \\] -/// -/// In the formula, $$n$$ is the length of the two lists and $$x_i, y_i$$ are the values in the respective input lists indexed by $$i, j$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/metrics -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// -/// // Empty lists returns 0.0 -/// metrics.euclidean_distance([], []) -/// |> should.equal(Ok(0.0)) -/// -/// // Differing lengths returns error -/// metrics.euclidean_distance([], [1.0]) -/// |> should.be_error() -/// -/// let assert Ok(result) = metrics.euclidean_distance([0.0, 0.0], [1.0, 2.0]) -/// result -/// |> predicates.is_close(2.23606797749979, 0.0, tol) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn euclidean_distance( - xarr: List(Float), - yarr: List(Float), -) -> Result(Float, String) { - minkowski_distance(xarr, yarr, 2.0) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/nicklasxyz/gleam_stats/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the arithmetic mean of the elements in a list: -/// -/// \\[ -/// \bar{x} = \frac{1}{n}\sum_{i=1}^n x_i -/// \\] -/// -/// In the formula, $$n$$ is the sample size (the length of the list) and -/// $$x_i$$ is the sample point in the input list indexed by $$i$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/metrics -/// -/// pub fn example () { -/// // An empty list returns an error -/// [] -/// |> metrics.mean() -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [1., 2., 3.] -/// |> metrics.mean() -/// |> should.equal(Ok(2.)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn mean(arr: List(Float)) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> - arr - |> arithmetics.float_sum() - |> fn(a: Float) -> Float { - a /. conversion.int_to_float(list.length(arr)) - } - |> Ok - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/nicklasxyz/gleam_stats/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the median of the elements in a list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/metrics -/// -/// pub fn example () { -/// // An empty list returns an error -/// [] -/// |> metrics.median() -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [1., 2., 3.] -/// |> metrics.median() -/// |> should.equal(Ok(2.)) -/// -/// [1., 2., 3., 4.] -/// |> metrics.median() -/// |> should.equal(Ok(2.5)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn median(arr: List(Float)) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let count: Int = list.length(arr) - let mid: Int = list.length(arr) / 2 - let sorted: List(Float) = list.sort(arr, float.compare) - case predicates.is_odd(count) { - // If there is an odd number of elements in the list, then the median - // is just the middle value - True -> { - let assert Ok(val0) = list.at(sorted, mid) - val0 - |> Ok - } - // If there is an even number of elements in the list, then the median - // is the mean of the two middle values - False -> { - let assert Ok(val0) = list.at(sorted, mid - 1) - let assert Ok(val1) = list.at(sorted, mid) - [val0, val1] - |> mean() - } - } - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/nicklasxyz/gleam_stats/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the sample variance of the elements in a list: -/// \\[ -/// s^{2} = \frac{1}{n - d} \sum_{i=1}^{n}(x_i - \bar{x}) -/// \\] -/// -/// In the formula, $$n$$ is the sample size (the length of the list) and -/// $$x_i$$ is the sample point in the input list indexed by $$i$$. -/// Furthermore, $$\bar{x}$$ is the sample mean and $$d$$ is the "Delta -/// Degrees of Freedom", and is by default set to $$d = 0$$, which gives a biased -/// estimate of the sample variance. Setting $$d = 1$$ gives an unbiased estimate. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/metrics -/// -/// pub fn example () { -/// // Degrees of freedom -/// let ddof: Int = 1 -/// -/// // An empty list returns an error -/// [] -/// |> metrics.variance(ddof) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [1., 2., 3.] -/// |> metrics.variance(ddof) -/// |> should.equal(Ok(1.)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> - case ddof < 0 { - True -> - "Invalid input argument: ddof < 0. Valid input is ddof >= 0." - |> Error - False -> { - let assert Ok(mean) = mean(arr) - arr - |> list.map(fn(a: Float) -> Float { - let assert Ok(result) = elementary.power(a -. mean, 2.0) - result - }) - |> arithmetics.float_sum() - |> fn(a: Float) -> Float { - a /. { - conversion.int_to_float(list.length(arr)) -. conversion.int_to_float( - ddof, - ) - } - } - |> Ok - } - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/nicklasxyz/gleam_stats/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Calculcate the sample standard deviation of the elements in a list: -/// \\[ -/// s = \left(\frac{1}{n - d} \sum_{i=1}^{n}(x_i - \bar{x})\right)^{\frac{1}{2}} -/// \\] -/// -/// In the formula, $$n$$ is the sample size (the length of the list) and -/// $$x_i$$ is the sample point in the input list indexed by $$i$$. -/// Furthermore, $$\bar{x}$$ is the sample mean and $$d$$ is the "Delta -/// Degrees of Freedom", and is by default set to $$d = 0$$, which gives a biased -/// estimate of the sample standard deviation. Setting $$d = 1$$ gives an unbiased estimate. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/metrics -/// -/// pub fn example () { -/// // Degrees of freedom -/// let ddof: Int = 1 -/// -/// // An empty list returns an error -/// [] -/// |> metrics.standard_deviationddof) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [1., 2., 3.] -/// |> metrics.standard_deviation(ddof) -/// |> should.equal(Ok(1.)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> - case ddof < 0 { - True -> - "Invalid input argument: ddof < 0. Valid input is ddof >= 0." - |> Error - False -> { - let assert Ok(variance) = variance(arr, ddof) - // The computed variance will always be positive - // So an error should never be returned - let assert Ok(stdev) = elementary.square_root(variance) - stdev - |> Ok - } - } - } -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/piecewise.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/piecewise.gleam deleted file mode 100644 index 3b40a18..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/piecewise.gleam +++ /dev/null @@ -1,1228 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Piecewise: A module containing functions that have different definitions depending on conditions or intervals of their domain. -//// -//// * **Rounding functions** -//// * [`ceiling`](#ceiling) -//// * [`floor`](#floor) -//// * [`truncate`](#truncate) -//// * [`round`](#round) -//// * **Sign and absolute value functions** -//// * [`float_absolute_value`](#float_absolute_value) -//// * [`int_absolute_value`](#int_absolute_value) -//// * [`float_absolute_difference`](#float_absolute_difference) -//// * [`int_absolute_difference`](#int_absolute_difference) -//// * [`float_sign`](#float_sign) -//// * [`int_sign`](#int_sign) -//// * [`float_copy_sign`](#float_copy_sign) -//// * [`int_copy_sign`](#float_copy_sign) -//// * [`float_flip_sign`](#float_flip_sign) -//// * [`int_flip_sign`](#int_flip_sign) -//// * **Misc. mathematical functions** -//// * [`minimum`](#minimum) -//// * [`maximum`](#maximum) -//// * [`minmax`](#minmax) -//// * [`list_minimum`](#list_minimum) -//// * [`list_maximum`](#list_maximum) -//// * [`extrema`](#extrema) -//// * [`arg_minimum`](#arg_minimum) -//// * [`arg_maximum`](#arg_maximum) -//// - -import gleam/option -import gleam/list -import gleam/order -import gleam/pair -import gleam/int -import gleam_community/maths/conversion -import gleam_community/maths/elementary - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The ceiling function rounds a given input value $$x \in \mathbb{R}$$ to the nearest integer value (at the specified digit) that is larger than or equal to the input $$x$$. -/// -/// Note: The ceiling function is used as an alias for the rounding function [`round`](#round) with rounding mode `RoundUp`. -/// -/// <details> -/// <summary>Details</summary> -/// -/// For example, $$12.0654$$ is rounded to: -/// - $$13.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.1$$ for 1 digit after the decimal point (`digits = 1`) -/// - $$12.07$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.066$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// For example, $$12.0654$$ is rounded to: -/// - $$20.0$$ for 1 digit places before the decimal point (`digit = -1`) -/// - $$100.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$1000.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// </details> -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.ceiling(12.0654, option.Some(1)) -/// |> should.equal(Ok(12.1)) -/// -/// piecewise.ceiling(12.0654, option.Some(2)) -/// |> should.equal(Ok(12.07)) -/// -/// piecewise.ceiling(12.0654, option.Some(3)) -/// |> should.equal(Ok(12.066)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn ceiling(x: Float, digits: option.Option(Int)) -> Result(Float, String) { - round(x, digits, option.Some(RoundUp)) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The floor function rounds input $$x \in \mathbb{R}$$ to the nearest integer value (at the specified digit) that is less than or equal to the input $$x$$. -/// -/// Note: The floor function is used as an alias for the rounding function [`round`](#round) with rounding mode `RoundDown`. -/// -/// <details> -/// <summary>Details</summary> -/// -/// For example, $$12.0654$$ is rounded to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.0$$ for 1 digits after the decimal point (`digits = 1`) -/// - $$12.06$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// </details> -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.floor(12.0654, option.Some(1)) -/// |> should.equal(Ok(12.0)) -/// -/// piecewise.floor(12.0654, option.Some(2)) -/// |> should.equal(Ok(12.06)) -/// -/// piecewise.floor(12.0654, option.Some(3)) -/// |> should.equal(Ok(12.065)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn floor(x: Float, digits: option.Option(Int)) -> Result(Float, String) { - round(x, digits, option.Some(RoundDown)) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The truncate function rounds a given input $$x \in \mathbb{R}$$ to the nearest integer value (at the specified digit) that is less than or equal to the absolute value of the input $$x$$. -/// -/// Note: The truncate function is used as an alias for the rounding function [`round`](#round) with rounding mode `RoundToZero`. -/// -/// <details> -/// <summary>Details</summary> -/// -/// For example, $$12.0654$$ is rounded to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.0$$ for 1 digits after the decimal point (`digits = 1`) -/// - $$12.06$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// </details> -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.truncate(12.0654, option.Some(1)) -/// |> should.equal(Ok(12.0)) -/// -/// piecewise.truncate(12.0654, option.Some(2)) -/// |> should.equal(Ok(12.0)) -/// -/// piecewise.truncate(12.0654, option.Some(3)) -/// |> should.equal(Ok(12.0)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn truncate(x: Float, digits: option.Option(Int)) -> Result(Float, String) { - round(x, digits, option.Some(RoundToZero)) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function rounds a float to a specific number of digits (after the decimal place or before if negative) using a specified rounding mode. -/// -/// Valid rounding modes include: -/// - `RoundNearest` (default): The input $$x$$ is rounded to the nearest integer value (at the specified digit) with ties (fractional values of 0.5) being rounded to the nearest even integer. -/// - `RoundTiesAway`: The input $$x$$ is rounded to the nearest integer value (at the specified digit) with ties (fractional values of 0.5) being rounded away from zero (C/C++ rounding behavior). -/// - `RoundTiesUp`: The input $$x$$ is rounded to the nearest integer value (at the specified digit) with ties (fractional values of 0.5) being rounded towards $$+\infty$$ (Java/JavaScript rounding behaviour). -/// - `RoundToZero`: The input $$x$$ is rounded to the nearest integer value (at the specified digit) that is less than or equal to the absolute value of the input $$x$$. An alias for this rounding mode is [`truncate`](#truncate). -/// - `RoundDown`: The input $$x$$ is rounded to the nearest integer value (at the specified digit) that is less than or equal to the input $$x$$. An alias for this rounding mode is [`floor`](#floor). -/// - `RoundUp`: The input $$x$$ is rounded to the nearest integer value (at the specified digit) that is larger than or equal to the input $$x$$. An alias for this rounding mode is [`ceiling`](#ceiling). -/// -/// <details> -/// <summary>Details</summary> -/// -/// The `RoundNearest` rounding mode, rounds $$12.0654$$ to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.1$$ for 1 digit after the decimal point (`digits = 1`) -/// - $$12.07$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// The `RoundTiesAway` rounding mode, rounds $$12.0654$$ to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.1$$ for 1 digit after the decimal point (`digits = 1`) -/// - $$12.07$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// The `RoundTiesUp` rounding mode, rounds $$12.0654$$ to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.1$$ for 1 digits after the decimal point (`digits = 1`) -/// - $$12.07$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// The `RoundToZero` rounding mode, rounds $$12.0654$$ to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.0$$ for 1 digit after the decimal point (`digits = 1`) -/// - $$12.06$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// The `RoundDown` rounding mode, rounds $$12.0654$$ to: -/// - $$12.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.0$$ for 1 digits after the decimal point (`digits = 1`) -/// - $$12.06$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.065$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$10.0$$ for 1 digit before the decimal point (`digits = -1`) -/// - $$0.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$0.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// The `RoundUp` rounding mode, rounds $$12.0654$$ to: -/// - $$13.0$$ for 0 digits after the decimal point (`digits = 0`) -/// - $$12.1$$ for 1 digit after the decimal point (`digits = 1`) -/// - $$12.07$$ for 2 digits after the decimal point (`digits = 2`) -/// - $$12.066$$ for 3 digits after the decimal point (`digits = 3`) -/// -/// It is also possible to specify a negative number of digits. In that case, the negative number refers to the digits before the decimal point. -/// - $$20.0$$ for 1 digit places before the decimal point (`digit = -1`) -/// - $$100.0$$ for 2 digits before the decimal point (`digits = -2`) -/// - $$1000.0$$ for 3 digits before the decimal point (`digits = -3`) -/// -/// </details> -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/option -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// // The default number of digits is 0 if None is provided -/// piecewise.round(12.0654, option.None, option.Some(piecewise.RoundNearest)) -/// |> should.equal(Ok(12.0)) -/// -/// // The default rounding mode is "RoundNearest" if None is provided -/// piecewise.round(12.0654, option.None, option.None) -/// |> should.equal(Ok(12.0)) -/// -/// // Try different rounding modes -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundNearest)) -/// |> should.equal(Ok(12.07)) -/// -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundTiesAway)) -/// |> should.equal(Ok(12.07)) -/// -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundTiesUp)) -/// |> should.equal(Ok(12.07)) -/// -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundToZero)) -/// |> should.equal(Ok(12.06)) -/// -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundDown)) -/// |> should.equal(Ok(12.06)) -/// -/// piecewise.round(12.0654, option.Some(2), option.Some(piecewise.RoundUp)) -/// |> should.equal(Ok(12.07)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn round( - x: Float, - digits: option.Option(Int), - mode: option.Option(RoundingMode), -) -> Result(Float, String) { - case digits { - option.Some(a) -> { - let assert Ok(p) = elementary.power(10.0, conversion.int_to_float(a)) - // Round the given input x using at the specified digit - do_round(p, x, mode) - } - // Round the given input x using at the default digit - option.None -> do_round(1.0, x, mode) - } -} - -pub type RoundingMode { - RoundNearest - RoundTiesAway - RoundTiesUp - RoundToZero - RoundDown - RoundUp -} - -fn do_round( - p: Float, - x: Float, - mode: option.Option(RoundingMode), -) -> Result(Float, String) { - case mode { - // Determine the rounding mode - option.Some(RoundNearest) -> - round_to_nearest(p, x) - |> Ok - option.Some(RoundTiesAway) -> - round_ties_away(p, x) - |> Ok - option.Some(RoundTiesUp) -> - round_ties_up(p, x) - |> Ok - option.Some(RoundToZero) -> - round_to_zero(p, x) - |> Ok - option.Some(RoundDown) -> - round_down(p, x) - |> Ok - option.Some(RoundUp) -> - round_up(p, x) - |> Ok - // Otherwise, use the default rounding mode - option.None -> - round_to_nearest(p, x) - |> Ok - } -} - -fn round_to_nearest(p: Float, x: Float) -> Float { - let xabs: Float = float_absolute_value(x) *. p - let xabs_truncated: Float = truncate_float(xabs) - let remainder: Float = xabs -. xabs_truncated - case remainder { - _ if remainder >. 0.5 -> float_sign(x) *. truncate_float(xabs +. 1.0) /. p - _ if remainder == 0.5 -> { - let assert Ok(is_even) = int.modulo(conversion.float_to_int(xabs), 2) - case is_even == 0 { - True -> float_sign(x) *. xabs_truncated /. p - False -> float_sign(x) *. truncate_float(xabs +. 1.0) /. p - } - } - _ -> float_sign(x) *. xabs_truncated /. p - } -} - -fn round_ties_away(p: Float, x: Float) -> Float { - let xabs: Float = float_absolute_value(x) *. p - let remainder: Float = xabs -. truncate_float(xabs) - case remainder { - _ if remainder >=. 0.5 -> float_sign(x) *. truncate_float(xabs +. 1.0) /. p - _ -> float_sign(x) *. truncate_float(xabs) /. p - } -} - -fn round_ties_up(p: Float, x: Float) -> Float { - let xabs: Float = float_absolute_value(x) *. p - let xabs_truncated: Float = truncate_float(xabs) - let remainder: Float = xabs -. xabs_truncated - case remainder { - _ if remainder >=. 0.5 && x >=. 0.0 -> - float_sign(x) *. truncate_float(xabs +. 1.0) /. p - _ -> float_sign(x) *. xabs_truncated /. p - } -} - -// Rounding mode: ToZero / Truncate -fn round_to_zero(p: Float, x: Float) -> Float { - truncate_float(x *. p) /. p -} - -fn truncate_float(x: Float) -> Float { - do_truncate_float(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../../maths.mjs", "truncate") -fn do_truncate_float(a: Float) -> Float - -// Rounding mode: Down / Floor -fn round_down(p: Float, x: Float) -> Float { - do_floor(x *. p) /. p -} - -@external(erlang, "math", "floor") -@external(javascript, "../../maths.mjs", "floor") -fn do_floor(a: Float) -> Float - -// Rounding mode: Up / Ceiling -fn round_up(p: Float, x: Float) -> Float { - do_ceiling(x *. p) /. p -} - -@external(erlang, "math", "ceil") -@external(javascript, "../../maths.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The absolute value: -/// -/// \\[ -/// \forall x, y \in \mathbb{R}, \\; |x| \in \mathbb{R}_{+}. -/// \\] -/// -/// The function takes an input $$x$$ and returns a positive float value. -/// -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_absolute_value(x: Float) -> Float { - case x >. 0.0 { - True -> x - False -> -1.0 *. x - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The absolute value: -/// -/// \\[ -/// \forall x, y \in \mathbb{Z}, \\; |x| \in \mathbb{Z}_{+}. -/// \\] -/// -/// The function takes an input $$x$$ and returns a positive integer value. -/// -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_absolute_value(x: Int) -> Int { - case x > 0 { - True -> x - False -> -1 * x - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The absolute difference: -/// -/// \\[ -/// \forall x, y \in \mathbb{R}, \\; |x - y| \in \mathbb{R}_{+}. -/// \\] -/// -/// The function takes two inputs $$x$$ and $$y$$ and returns a positive float -/// value which is the the absolute difference of the inputs. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.float_absolute_difference(-10.0, 10.0) -/// |> should.equal(20.0) -/// -/// piecewise.float_absolute_difference(0.0, -2.0) -/// |> should.equal(2.0) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_absolute_difference(a: Float, b: Float) -> Float { - a -. b - |> float_absolute_value() -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The absolute difference: -/// -/// \\[ -/// \forall x, y \in \mathbb{Z}, \\; |x - y| \in \mathbb{Z}_{+}. -/// \\] -/// -/// The function takes two inputs $$x$$ and $$y$$ and returns a positive integer value which is the the absolute difference of the inputs. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.absolute_difference(-10, 10) -/// |> should.equal(20) -/// -/// piecewise.absolute_difference(0, -2) -/// |> should.equal(2) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_absolute_difference(a: Int, b: Int) -> Int { - a - b - |> int_absolute_value() -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function takes an input $$x \in \mathbb{R}$$ and returns the sign of -/// the input, indicating whether it is positive (+1.0), negative (-1.0), or -/// zero (0.0). -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_sign(x: Float) -> Float { - do_float_sign(x) -} - -@target(erlang) -fn do_float_sign(x: Float) -> Float { - case x <. 0.0 { - True -> -1.0 - False -> - case x == 0.0 { - True -> 0.0 - False -> 1.0 - } - } -} - -@target(javascript) -@external(javascript, "../../maths.mjs", "sign") -fn do_float_sign(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function takes an input $$x \in \mathbb{Z}$$ and returns the sign of -/// the input, indicating whether it is positive (+1), negative (-1), or zero -/// (0). -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_sign(x: Int) -> Int { - do_int_sign(x) -} - -@target(erlang) -fn do_int_sign(x: Int) -> Int { - case x < 0 { - True -> -1 - False -> - case x == 0 { - True -> 0 - False -> 1 - } - } -} - -@target(javascript) -@external(javascript, "../../maths.mjs", "sign") -fn do_int_sign(a: Int) -> Int - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function takes two arguments $$x, y \in \mathbb{R}$$ and returns $$x$$ such that it has the same sign as $$y$$. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_copy_sign(x: Float, y: Float) -> Float { - case float_sign(x) == float_sign(y) { - // x and y have the same sign, just return x - True -> x - // x and y have different signs: - // - x is positive and y is negative, then flip sign of x - // - x is negative and y is positive, then flip sign of x - False -> float_flip_sign(x) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function takes two arguments $$x, y \in \mathbb{Z}$$ and returns $$x$$ such that it has the same sign as $$y$$. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_copy_sign(x: Int, y: Int) -> Int { - case int_sign(x) == int_sign(y) { - // x and y have the same sign, just return x - True -> x - // x and y have different signs: - // - x is positive and y is negative, then flip sign of x - // - x is negative and y is positive, then flip sign of x - False -> int_flip_sign(x) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function flips the sign of a given input value $$x \in \mathbb{R}$$. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn float_flip_sign(x: Float) -> Float { - -1.0 *. x -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function flips the sign of a given input value $$x \in \mathbb{Z}$$. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn int_flip_sign(x: Int) -> Int { - -1 * x -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The minimum function takes two arguments $$x, y$$ along with a function -/// for comparing $$x, y$$. The function returns the smallest of the two given -/// values. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.minimum(2.0, 1.5, float.compare) -/// |> should.equal(1.5) -/// -/// piecewise.minimum(1.5, 2.0, float.compare) -/// |> should.equal(1.5) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn minimum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a { - case compare(x, y) { - order.Lt -> x - order.Eq -> x - order.Gt -> y - } -} - -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The maximum function takes two arguments $$x, y$$ along with a function -/// for comparing $$x, y$$. The function returns the largest of the two given -/// values. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.maximum(2.0, 1.5, float.compare) -/// |> should.equal(1.5) -/// -/// piecewise.maximum(1.5, 2.0, float.compare) -/// |> should.equal(1.5) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn maximum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a { - case compare(x, y) { - order.Lt -> y - order.Eq -> y - order.Gt -> x - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The minmax function takes two arguments $$x, y$$ along with a function -/// for comparing $$x, y$$. The function returns a tuple with the smallest -/// value first and largest second. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example() { -/// piecewise.minmax(2.0, 1.5, float.compare) -/// |> should.equal(#(1.5, 2.0)) -/// -/// piecewise.minmax(1.5, 2.0, float.compare) -/// |> should.equal(#(1.5, 2.0)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) -> #(a, a) { - #(minimum(x, y, compare), maximum(x, y, compare)) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Returns the minimum value of a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/int -/// import gleam_community/maths/piecewise -/// -/// pub fn example () { -/// // An empty lists returns an error -/// [] -/// |> piecewise.list_minimum(int.compare) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [4, 4, 3, 2, 1] -/// |> piecewise.list_minimum(int.compare) -/// |> should.equal(Ok(1)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -pub fn list_minimum( - arr: List(a), - compare: fn(a, a) -> order.Order, -) -> Result(a, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let assert Ok(val0) = list.at(arr, 0) - arr - |> list.fold( - val0, - fn(acc: a, element: a) { - case compare(element, acc) { - order.Lt -> element - _ -> acc - } - }, - ) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Returns the maximum value of a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example () { -/// // An empty lists returns an error -/// [] -/// |> piecewise.list_maximum(float.compare) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [4.0, 4.0, 3.0, 2.0, 1.0] -/// |> piecewise.list_maximum(float.compare) -/// |> should.equal(Ok(4.0)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn list_maximum( - arr: List(a), - compare: fn(a, a) -> order.Order, -) -> Result(a, String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let assert Ok(val0) = list.at(arr, 0) - arr - |> list.fold( - val0, - fn(acc: a, element: a) { - case compare(acc, element) { - order.Lt -> element - _ -> acc - } - }, - ) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Returns the indices of the minimum values in a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example () { -/// // An empty lists returns an error -/// [] -/// |> piecewise.arg_minimum(float.compare) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [4.0, 4.0, 3.0, 2.0, 1.0] -/// |> piecewise.arg_minimum(float.compare) -/// |> should.equal(Ok([4])) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn arg_minimum( - arr: List(a), - compare: fn(a, a) -> order.Order, -) -> Result(List(Int), String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let assert Ok(min) = - arr - |> list_minimum(compare) - arr - |> list.index_map(fn(index: Int, element: a) -> Int { - case compare(element, min) { - order.Eq -> index - _ -> -1 - } - }) - |> list.filter(fn(index: Int) -> Bool { - case index { - -1 -> False - _ -> True - } - }) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Returns the indices of the maximum values in a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example () { -/// // An empty lists returns an error -/// [] -/// |> piecewise.arg_maximum(float.compare) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [4.0, 4.0, 3.0, 2.0, 1.0] -/// |> piecewise.arg_maximum(float.compare) -/// |> should.equal(Ok([0, 1])) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn arg_maximum( - arr: List(a), - compare: fn(a, a) -> order.Order, -) -> Result(List(Int), String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let assert Ok(max) = - arr - |> list_maximum(compare) - arr - |> list.index_map(fn(index: Int, element: a) -> Int { - case compare(element, max) { - order.Eq -> index - _ -> -1 - } - }) - |> list.filter(fn(index: Int) -> Bool { - case index { - -1 -> False - _ -> True - } - }) - |> Ok - } - } -} - -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Returns a tuple consisting of the minimum and maximum values of a given list. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/float -/// import gleam_community/maths/piecewise -/// -/// pub fn example () { -/// // An empty lists returns an error -/// [] -/// |> piecewise.extrema(float.compare) -/// |> should.be_error() -/// -/// // Valid input returns a result -/// [4.0, 4.0, 3.0, 2.0, 1.0] -/// |> piecewise.extrema(float.compare) -/// |> should.equal(Ok(#(1.0, 4.0))) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn extrema( - arr: List(a), - compare: fn(a, a) -> order.Order, -) -> Result(#(a, a), String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - let assert Ok(val_max) = list.at(arr, 0) - let assert Ok(val_min) = list.at(arr, 0) - arr - |> list.fold( - #(val_min, val_max), - fn(acc: #(a, a), element: a) { - let first: a = pair.first(acc) - let second: a = pair.second(acc) - case compare(element, first), compare(second, element) { - order.Lt, order.Lt -> #(element, element) - order.Lt, _ -> #(element, second) - _, order.Lt -> #(first, element) - _, _ -> #(first, second) - } - }, - ) - |> Ok - } - } -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/predicates.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/predicates.gleam deleted file mode 100644 index f8d357c..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/predicates.gleam +++ /dev/null @@ -1,363 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Predicates: A module containing functions for testing various mathematical properties of numbers. -//// -//// * **Tests** -//// * [`is_close`](#is_close) -//// * [`list_all_close`](#all_close) -//// * [`is_fractional`](#is_fractional) -//// * [`is_power`](#is_power) -//// * [`is_perfect`](#is_perfect) -//// * [`is_even`](#is_even) -//// * [`is_odd`](#is_odd) - -import gleam/pair -import gleam/int -import gleam/list -import gleam/option -import gleam_community/maths/elementary -import gleam_community/maths/piecewise -import gleam_community/maths/arithmetics - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Determine if a given value $$a$$ is close to or equivalent to a reference value -/// $$b$$ based on supplied relative $$r_{tol}$$ and absolute $$a_{tol}$$ tolerance values. -/// The equivalance of the two given values are then determined based on the equation: -/// -/// \\[ -/// \|a - b\| \leq (a_{tol} + r_{tol} \cdot \|b\|) -/// \\] -/// -/// `True` is returned if statement holds, otherwise `False` is returned. -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example () { -/// let val: Float = 99. -/// let ref_val: Float = 100. -/// // We set 'atol' and 'rtol' such that the values are equivalent -/// // if 'val' is within 1 percent of 'ref_val' +/- 0.1 -/// let rtol: Float = 0.01 -/// let atol: Float = 0.10 -/// floatx.is_close(val, ref_val, rtol, atol) -/// |> should.be_true() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_close(a: Float, b: Float, rtol: Float, atol: Float) -> Bool { - let x: Float = float_absolute_difference(a, b) - let y: Float = atol +. rtol *. float_absolute_value(b) - case x <=. y { - True -> True - False -> False - } -} - -fn float_absolute_value(x: Float) -> Float { - case x >. 0.0 { - True -> x - False -> -1.0 *. x - } -} - -fn float_absolute_difference(a: Float, b: Float) -> Float { - a -. b - |> float_absolute_value() -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Determine if a list of values are close to or equivalent to a another list of reference values. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam/list -/// import gleam_community/maths/tests -/// -/// pub fn example () { -/// let val: Float = 99. -/// let ref_val: Float = 100. -/// let xarr: List(Float) = list.repeat(val, 42) -/// let yarr: List(Float) = list.repeat(ref_val, 42) -/// // We set 'atol' and 'rtol' such that the values are equivalent -/// // if 'val' is within 1 percent of 'ref_val' +/- 0.1 -/// let rtol: Float = 0.01 -/// let atol: Float = 0.10 -/// tests.all_close(xarr, yarr, rtol, atol) -/// |> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) { -/// case zarr { -/// Ok(arr) -> -/// arr -/// |> list.all(fn(a: Bool) -> Bool { a }) -/// |> Ok -/// _ -> Nil |> Error -/// } -/// } -/// |> should.equal(Ok(True)) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn all_close( - xarr: List(Float), - yarr: List(Float), - rtol: Float, - atol: Float, -) -> Result(List(Bool), String) { - let xlen: Int = list.length(xarr) - let ylen: Int = list.length(yarr) - case xlen == ylen { - False -> - "Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)." - |> Error - True -> - list.zip(xarr, yarr) - |> list.map(fn(z: #(Float, Float)) -> Bool { - is_close(pair.first(z), pair.second(z), rtol, atol) - }) - |> Ok - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Determine if a given value is fractional. -/// -/// `True` is returned if the given value is fractional, otherwise `False` is returned. -/// -/// <details> -/// <summary>Example</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example () { -/// tests.is_fractional(0.3333) -/// |> should.equal(True) -/// -/// tests.is_fractional(1.0) -/// |> should.equal(False) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_fractional(x: Float) -> Bool { - do_ceiling(x) -. x >. 0.0 -} - -@external(erlang, "math", "ceil") -@external(javascript, "../../maths.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A function that tests whether a given integer value $$x \in \mathbb{Z}$$ is a power of another integer value $$y \in \mathbb{Z}$$. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example() { -/// // Check if 4 is a power of 2 (it is) -/// tests.is_power(4, 2) -/// |> should.equal(True) -/// -/// // Check if 5 is a power of 2 (it is not) -/// tests.is_power(5, 2) -/// |> should.equal(False) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_power(x: Int, y: Int) -> Bool { - let assert Ok(value) = - elementary.logarithm(int.to_float(x), option.Some(int.to_float(y))) - let assert Ok(truncated) = piecewise.truncate(value, option.Some(0)) - let rem = value -. truncated - rem == 0.0 -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A function that tests whether a given integer value $$n \in \mathbb{Z}$$ is a perfect number. A number is perfect if it is equal to the sum of its proper positive divisors. -/// -/// <details> -/// <summary>Details</summary> -/// -/// For example: -/// - $$6$$ is a perfect number since the divisors of 6 are $$1 + 2 + 3 = 6$$. -/// - $$28$$ is a perfect number since the divisors of 28 are $$1 + 2 + 4 + 7 + 14 = 28$$ -/// -/// </details> -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example() { -/// tests.is_perfect(6) -/// |> should.equal(True) -/// -/// tests.is_perfect(28) -/// |> should.equal(True) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_perfect(n: Int) -> Bool { - do_sum(arithmetics.proper_divisors(n)) == n -} - -fn do_sum(arr: List(Int)) -> Int { - case arr { - [] -> 0 - _ -> - arr - |> list.fold(0, fn(acc: Int, a: Int) -> Int { a + acc }) - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A function that tests whether a given integer value $$x \in \mathbb{Z}$$ is even. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example() { -/// tests.is_even(-3) -/// |> should.equal(False) -/// -/// tests.is_even(-4) -/// |> should.equal(True) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// A function that tests whether a given integer value $$x \in \mathbb{Z}$$ is odd. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/tests -/// -/// pub fn example() { -/// tests.is_odd(-3) -/// |> should.equal(True) -/// -/// tests.is_odd(-4) -/// |> should.equal(False) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/sequences.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/sequences.gleam deleted file mode 100644 index e7c0388..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/sequences.gleam +++ /dev/null @@ -1,302 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Sequences: A module containing functions for generating various types of sequences, ranges and intervals. -//// -//// * **Ranges and intervals** -//// * [`arange`](#arange) -//// * [`linear_space`](#linear_space) -//// * [`logarithmic_space`](#logarithmic_space) -//// * [`geometric_space`](#geometric_space) - -import gleam_community/maths/elementary -import gleam_community/maths/piecewise -import gleam_community/maths/conversion -import gleam/list - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function returns a list with evenly spaced values within a given interval based on a start, stop value and a given increment (step-length) between consecutive values. -/// The list returned includes the given start value but excludes the stop value. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/sequences -/// -/// pub fn example () { -/// sequences.arange(1.0, 5.0, 1.0) -/// |> should.equal([1.0, 2.0, 3.0, 4.0]) -/// -/// // No points returned since -/// // start smaller than stop and positive step -/// sequences.arange(5.0, 1.0, 1.0) -/// |> should.equal([]) -/// -/// // Points returned since -/// // start smaller than stop but negative step -/// sequences.arange(5.0, 1.0, -1.0) -/// |> should.equal([5.0, 4.0, 3.0, 2.0]) -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn arange(start: Float, stop: Float, step: Float) -> List(Float) { - case start >=. stop && step >. 0.0 || start <=. stop && step <. 0.0 { - True -> [] - False -> { - let direction: Float = case start <=. stop { - True -> 1.0 - False -> -1.0 - } - let step_abs: Float = piecewise.float_absolute_value(step) - let num: Float = piecewise.float_absolute_value(start -. stop) /. step_abs - - list.range(0, conversion.float_to_int(num) - 1) - |> list.map(fn(i: Int) -> Float { - start +. conversion.int_to_float(i) *. step_abs *. direction - }) - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Generate a linearly spaced list of points over a specified interval. The endpoint of the interval can optionally be included/excluded. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/sequences -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// let assert Ok(linspace) = sequences.linear_space(10.0, 50.0, 5, True) -/// let assert Ok(result) = -/// predicates.all_close(linspace, [10.0, 20.0, 30.0, 40.0, 50.0], 0.0, tol) -/// result -/// |> list.all(fn(x) { x == True }) -/// |> should.be_true() -/// -/// // A negative number of points (-5) does not work -/// sequences.linear_space(10.0, 50.0, -5, True) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn linear_space( - start: Float, - stop: Float, - num: Int, - endpoint: Bool, -) -> Result(List(Float), String) { - let direction: Float = case start <=. stop { - True -> 1.0 - False -> -1.0 - } - case num > 0 { - True -> - case endpoint { - True -> { - let increment: Float = - piecewise.float_absolute_value(start -. stop) /. conversion.int_to_float( - num - 1, - ) - list.range(0, num - 1) - |> list.map(fn(i: Int) -> Float { - start +. conversion.int_to_float(i) *. increment *. direction - }) - |> Ok - } - False -> { - let increment: Float = - piecewise.float_absolute_value(start -. stop) /. conversion.int_to_float( - num, - ) - list.range(0, num - 1) - |> list.map(fn(i: Int) -> Float { - start +. conversion.int_to_float(i) *. increment *. direction - }) - |> Ok - } - } - - False -> - "Invalid input: num < 0. Valid input is num > 0." - |> Error - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// Generate a logarithmically spaced list of points over a specified interval. The endpoint of the interval can optionally be included/excluded. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/sequences -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// let assert Ok(logspace) = sequences.logarithmic_space(1.0, 3.0, 3, True, 10.0) -/// let assert Ok(result) = -/// predicates.all_close(logspace, [10.0, 100.0, 1000.0], 0.0, tol) -/// result -/// |> list.all(fn(x) { x == True }) -/// |> should.be_true() -/// -/// // A negative number of points (-3) does not work -/// sequences.logarithmic_space(1.0, 3.0, -3, False, 10.0) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn logarithmic_space( - start: Float, - stop: Float, - num: Int, - endpoint: Bool, - base: Float, -) -> Result(List(Float), String) { - case num > 0 { - True -> { - let assert Ok(linspace) = linear_space(start, stop, num, endpoint) - linspace - |> list.map(fn(i: Float) -> Float { - let assert Ok(result) = elementary.power(base, i) - result - }) - |> Ok - } - False -> - "Invalid input: num < 0. Valid input is num > 0." - |> Error - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The function returns a list of numbers spaced evenly on a log scale (a geometric progression). Each point in the list is a constant multiple of the previous. -/// The function is similar to the [`logarithmic_space`](#logarithmic_space) function, but with endpoints specified directly. -/// -/// <details> -/// <summary>Example:</summary> -/// -/// import gleeunit/should -/// import gleam_community/maths/elementary -/// import gleam_community/maths/sequences -/// import gleam_community/maths/predicates -/// -/// pub fn example () { -/// let assert Ok(tol) = elementary.power(-10.0, -6.0) -/// let assert Ok(logspace) = sequences.geometric_space(10.0, 1000.0, 3, True) -/// let assert Ok(result) = -/// predicates.all_close(logspace, [10.0, 100.0, 1000.0], 0.0, tol) -/// result -/// |> list.all(fn(x) { x == True }) -/// |> should.be_true() -/// -/// // Input (start and stop can't be equal to 0.0) -/// sequences.geometric_space(0.0, 1000.0, 3, False) -/// |> should.be_error() -/// -/// sequences.geometric_space(-1000.0, 0.0, 3, False) -/// |> should.be_error() -/// -/// // A negative number of points (-3) does not work -/// sequences.geometric_space(10.0, 1000.0, -3, False) -/// |> should.be_error() -/// } -/// </details> -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn geometric_space( - start: Float, - stop: Float, - num: Int, - endpoint: Bool, -) -> Result(List(Float), String) { - case start == 0.0 || stop == 0.0 { - True -> - "" - |> Error - False -> - case num > 0 { - True -> { - let assert Ok(log_start) = elementary.logarithm_10(start) - let assert Ok(log_stop) = elementary.logarithm_10(stop) - logarithmic_space(log_start, log_stop, num, endpoint, 10.0) - } - False -> - "Invalid input: num < 0. Valid input is num > 0." - |> Error - } - } -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/special.gleam b/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/special.gleam deleted file mode 100644 index dfd9cbb..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community/maths/special.gleam +++ /dev/null @@ -1,205 +0,0 @@ -////<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css" integrity="sha384-GvrOXuhMATgEsSwCs4smul74iXGOixntILdUW9XmUC6+HX0sLNAK3q71HotJqlAn" crossorigin="anonymous"> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js" integrity="sha384-cpW21h6RZv/phavutF+AuVYrr+dA8xD9zs6FwLpaCct6O9ctzYFfFr4dgmgccOTx" crossorigin="anonymous"></script> -////<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"></script> -////<script> -//// document.addEventListener("DOMContentLoaded", function() { -//// renderMathInElement(document.body, { -//// // customised options -//// // • auto-render specific keys, e.g.: -//// delimiters: [ -//// {left: '$$', right: '$$', display: false}, -//// // {left: '$', right: '$', display: false}, -//// // {left: '\\(', right: '\\)', display: false}, -//// {left: '\\[', right: '\\]', display: true} -//// ], -//// // • rendering keys, e.g.: -//// throwOnError : false -//// }); -//// }); -////</script> -////<style> -//// .katex { font-size: 1.1em; } -////</style> -//// -//// --- -//// -//// Special: A module containing special mathematical functions. -//// -//// * **Special mathematical functions** -//// * [`beta`](#beta) -//// * [`erf`](#erf) -//// * [`gamma`](#gamma) -//// * [`incomplete_gamma`](#incomplete_gamma) -//// - -import gleam_community/maths/conversion -import gleam_community/maths/elementary -import gleam_community/maths/piecewise -import gleam/list - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The beta function over the real numbers: -/// -/// \\[ -/// \text{B}(x, y) = \frac{\Gamma(x) \cdot \Gamma(y)}{\Gamma(x + y)} -/// \\] -/// -/// The beta function is evaluated through the use of the gamma function. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn beta(x: Float, y: Float) -> Float { - gamma(x) *. gamma(y) /. gamma(x +. y) -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The error function. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn erf(x: Float) -> Float { - let assert [a1, a2, a3, a4, a5]: List(Float) = [ - 0.254829592, -0.284496736, 1.421413741, -1.453152027, 1.061405429, - ] - let p: Float = 0.3275911 - - let sign: Float = piecewise.float_sign(x) - let x: Float = piecewise.float_absolute_value(x) - - // Formula 7.1.26 given in Abramowitz and Stegun. - let t: Float = 1.0 /. { 1.0 +. p *. x } - let y: Float = - 1.0 -. { { { { a5 *. t +. a4 } *. t +. a3 } *. t +. a2 } *. t +. a1 } *. t *. elementary.exponential( - -1.0 *. x *. x, - ) - sign *. y -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The gamma function over the real numbers. The function is essentially equal to the -/// factorial for any positive integer argument: $$\Gamma(n) = (n - 1)!$$ -/// -/// The implemented gamma function is approximated through Lanczos approximation -/// using the same coefficients used by the GNU Scientific Library. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn gamma(x: Float) -> Float { - gamma_lanczos(x) -} - -const lanczos_g: Float = 7.0 - -const lanczos_p: List(Float) = [ - 0.99999999999980993, 676.5203681218851, -1259.1392167224028, - 771.32342877765313, -176.61502916214059, 12.507343278686905, - -0.13857109526572012, 0.0000099843695780195716, 0.00000015056327351493116, -] - -fn gamma_lanczos(x: Float) -> Float { - case x <. 0.5 { - True -> - elementary.pi() /. { - elementary.sin(elementary.pi() *. x) *. gamma_lanczos(1.0 -. x) - } - False -> { - let z = x -. 1.0 - let x: Float = - list.index_fold( - lanczos_p, - 0.0, - fn(acc: Float, v: Float, index: Int) { - case index > 0 { - True -> acc +. v /. { z +. conversion.int_to_float(index) } - False -> v - } - }, - ) - let t: Float = z +. lanczos_g +. 0.5 - let assert Ok(v1) = elementary.power(2.0 *. elementary.pi(), 0.5) - let assert Ok(v2) = elementary.power(t, z +. 0.5) - v1 *. v2 *. elementary.exponential(-1.0 *. t) *. x - } - } -} - -/// <div style="text-align: right;"> -/// <a href="https://github.com/gleam-community/maths/issues"> -/// <small>Spot a typo? Open an issue!</small> -/// </a> -/// </div> -/// -/// The lower incomplete gamma function over the real numbers. -/// -/// The implemented incomplete gamma function is evaluated through a power series -/// expansion. -/// -/// <div style="text-align: right;"> -/// <a href="#"> -/// <small>Back to top ↑</small> -/// </a> -/// </div> -/// -pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, String) { - case a >. 0.0 && x >=. 0.0 { - True -> { - let assert Ok(v) = elementary.power(x, a) - v *. elementary.exponential(-1.0 *. x) *. incomplete_gamma_sum( - a, - x, - 1.0 /. a, - 0.0, - 1.0, - ) - |> Ok - } - - False -> - "Invlaid input argument: a <= 0 or x < 0. Valid input is a > 0 and x >= 0." - |> Error - } -} - -fn incomplete_gamma_sum( - a: Float, - x: Float, - t: Float, - s: Float, - n: Float, -) -> Float { - case t { - 0.0 -> s - _ -> { - let ns: Float = s +. t - let nt: Float = t *. { x /. { a +. n } } - incomplete_gamma_sum(a, x, nt, ns, n +. 1.0) - } - } -} diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@arithmetics.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@arithmetics.erl deleted file mode 100644 index ca266c8..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@arithmetics.erl +++ /dev/null @@ -1,172 +0,0 @@ --module(gleam_community@maths@arithmetics). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([gcd/2, lcm/2, divisors/1, proper_divisors/1, float_sum/1, int_sum/1, float_product/1, int_product/1, float_cumulative_sum/1, int_cumulative_sum/1, float_cumumlative_product/1, int_cumulative_product/1]). - --spec do_gcd(integer(), integer()) -> integer(). -do_gcd(X, Y) -> - case X =:= 0 of - true -> - Y; - - false -> - _assert_subject = gleam@int:modulo(Y, X), - {ok, Z} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/arithmetics"/utf8>>, - function => <<"do_gcd"/utf8>>, - line => 93}) - end, - do_gcd(Z, X) - end. - --spec gcd(integer(), integer()) -> integer(). -gcd(X, Y) -> - Absx = gleam_community@maths@piecewise:int_absolute_value(X), - Absy = gleam_community@maths@piecewise:int_absolute_value(Y), - do_gcd(Absx, Absy). - --spec lcm(integer(), integer()) -> integer(). -lcm(X, Y) -> - Absx = gleam_community@maths@piecewise:int_absolute_value(X), - Absy = gleam_community@maths@piecewise:int_absolute_value(Y), - case do_gcd(Absx, Absy) of - 0 -> 0; - Gleam@denominator -> (Absx * Absy) div Gleam@denominator - end. - --spec find_divisors(integer()) -> list(integer()). -find_divisors(N) -> - Nabs = gleam_community@maths@piecewise:float_absolute_value( - gleam_community@maths@conversion:int_to_float(N) - ), - _assert_subject = gleam_community@maths@elementary:square_root(Nabs), - {ok, Sqrt_result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/arithmetics"/utf8>>, - function => <<"find_divisors"/utf8>>, - line => 176}) - end, - Max = gleam_community@maths@conversion:float_to_int(Sqrt_result) + 1, - _pipe = gleam@list:range(2, Max), - _pipe@1 = gleam@list:fold(_pipe, [1, N], fun(Acc, I) -> case (case I of - 0 -> 0; - Gleam@denominator -> N rem Gleam@denominator - end) =:= 0 of - true -> - [I, case I of - 0 -> 0; - Gleam@denominator@1 -> N div Gleam@denominator@1 - end | Acc]; - - false -> - Acc - end end), - _pipe@2 = gleam@list:unique(_pipe@1), - gleam@list:sort(_pipe@2, fun gleam@int:compare/2). - --spec divisors(integer()) -> list(integer()). -divisors(N) -> - find_divisors(N). - --spec proper_divisors(integer()) -> list(integer()). -proper_divisors(N) -> - Divisors = find_divisors(N), - _pipe = Divisors, - gleam@list:take(_pipe, gleam@list:length(Divisors) - 1). - --spec float_sum(list(float())) -> float(). -float_sum(Arr) -> - case Arr of - [] -> - +0.0; - - _ -> - _pipe = Arr, - gleam@list:fold(_pipe, +0.0, fun(Acc, A) -> A + Acc end) - end. - --spec int_sum(list(integer())) -> integer(). -int_sum(Arr) -> - case Arr of - [] -> - 0; - - _ -> - _pipe = Arr, - gleam@list:fold(_pipe, 0, fun(Acc, A) -> A + Acc end) - end. - --spec float_product(list(float())) -> float(). -float_product(Arr) -> - case Arr of - [] -> - 1.0; - - _ -> - _pipe = Arr, - gleam@list:fold(_pipe, 1.0, fun(Acc, A) -> A * Acc end) - end. - --spec int_product(list(integer())) -> integer(). -int_product(Arr) -> - case Arr of - [] -> - 1; - - _ -> - _pipe = Arr, - gleam@list:fold(_pipe, 1, fun(Acc, A) -> A * Acc end) - end. - --spec float_cumulative_sum(list(float())) -> list(float()). -float_cumulative_sum(Arr) -> - case Arr of - [] -> - []; - - _ -> - _pipe = Arr, - gleam@list:scan(_pipe, +0.0, fun(Acc, A) -> A + Acc end) - end. - --spec int_cumulative_sum(list(integer())) -> list(integer()). -int_cumulative_sum(Arr) -> - case Arr of - [] -> - []; - - _ -> - _pipe = Arr, - gleam@list:scan(_pipe, 0, fun(Acc, A) -> A + Acc end) - end. - --spec float_cumumlative_product(list(float())) -> list(float()). -float_cumumlative_product(Arr) -> - case Arr of - [] -> - []; - - _ -> - _pipe = Arr, - gleam@list:scan(_pipe, 1.0, fun(Acc, A) -> A * Acc end) - end. - --spec int_cumulative_product(list(integer())) -> list(integer()). -int_cumulative_product(Arr) -> - case Arr of - [] -> - []; - - _ -> - _pipe = Arr, - gleam@list:scan(_pipe, 1, fun(Acc, A) -> A * Acc end) - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@combinatorics.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@combinatorics.erl deleted file mode 100644 index 17644c4..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@combinatorics.erl +++ /dev/null @@ -1,218 +0,0 @@ --module(gleam_community@maths@combinatorics). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([combination/2, factorial/1, permutation/2, list_combination/2, list_permutation/1, cartesian_product/2]). - --spec combination(integer(), integer()) -> {ok, integer()} | {error, binary()}. -combination(N, K) -> - case N < 0 of - true -> - _pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>, - {error, _pipe}; - - false -> - case (K < 0) orelse (K > N) of - true -> - _pipe@1 = 0, - {ok, _pipe@1}; - - false -> - case (K =:= 0) orelse (K =:= N) of - true -> - _pipe@2 = 1, - {ok, _pipe@2}; - - false -> - Min = case K < (N - K) of - true -> - K; - - false -> - N - K - end, - _pipe@3 = gleam@list:range(1, Min), - _pipe@4 = gleam@list:fold( - _pipe@3, - 1, - fun(Acc, X) -> case X of - 0 -> 0; - Gleam@denominator -> (Acc * ((N + 1) - X)) - div Gleam@denominator - end end - ), - {ok, _pipe@4} - end - end - end. - --spec factorial(integer()) -> {ok, integer()} | {error, binary()}. -factorial(N) -> - case N < 0 of - true -> - _pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>, - {error, _pipe}; - - false -> - case N of - 0 -> - _pipe@1 = 1, - {ok, _pipe@1}; - - 1 -> - _pipe@2 = 1, - {ok, _pipe@2}; - - _ -> - _pipe@3 = gleam@list:range(1, N), - _pipe@4 = gleam@list:fold( - _pipe@3, - 1, - fun(Acc, X) -> Acc * X end - ), - {ok, _pipe@4} - end - end. - --spec permutation(integer(), integer()) -> {ok, integer()} | {error, binary()}. -permutation(N, K) -> - case N < 0 of - true -> - _pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>, - {error, _pipe}; - - false -> - case (K < 0) orelse (K > N) of - true -> - _pipe@1 = 0, - {ok, _pipe@1}; - - false -> - case K =:= N of - true -> - _pipe@2 = 1, - {ok, _pipe@2}; - - false -> - _assert_subject = factorial(N), - {ok, V1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/combinatorics"/utf8>>, - function => <<"permutation"/utf8>>, - line => 241}) - end, - _assert_subject@1 = factorial(N - K), - {ok, V2} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/combinatorics"/utf8>>, - function => <<"permutation"/utf8>>, - line => 242}) - end, - _pipe@3 = case V2 of - 0 -> 0; - Gleam@denominator -> V1 div Gleam@denominator - end, - {ok, _pipe@3} - end - end - end. - --spec do_list_combination(list(GIO), integer(), list(GIO)) -> list(list(GIO)). -do_list_combination(Arr, K, Prefix) -> - case K of - 0 -> - [gleam@list:reverse(Prefix)]; - - _ -> - case Arr of - [] -> - []; - - [X | Xs] -> - With_x = do_list_combination(Xs, K - 1, [X | Prefix]), - Without_x = do_list_combination(Xs, K, Prefix), - gleam@list:append(With_x, Without_x) - end - end. - --spec list_combination(list(GII), integer()) -> {ok, list(list(GII))} | - {error, binary()}. -list_combination(Arr, K) -> - case K < 0 of - true -> - _pipe = <<"Invalid input argument: k < 0. Valid input is k > 0."/utf8>>, - {error, _pipe}; - - false -> - case K > gleam@list:length(Arr) of - true -> - _pipe@1 = <<"Invalid input argument: k > length(arr). Valid input is 0 < k <= length(arr)."/utf8>>, - {error, _pipe@1}; - - false -> - _pipe@2 = do_list_combination(Arr, K, []), - {ok, _pipe@2} - end - end. - --spec list_permutation(list(GIT)) -> list(list(GIT)). -list_permutation(Arr) -> - case Arr of - [] -> - [[]]; - - _ -> - gleam@list:flat_map( - Arr, - fun(X) -> - _assert_subject = gleam@list:pop(Arr, fun(Y) -> X =:= Y end), - {ok, {_, Remaining}} = case _assert_subject of - {ok, {_, _}} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/combinatorics"/utf8>>, - function => <<"list_permutation"/utf8>>, - line => 373}) - end, - gleam@list:map( - list_permutation(Remaining), - fun(Perm) -> [X | Perm] end - ) - end - ) - end. - --spec cartesian_product(list(GIX), list(GIX)) -> list({GIX, GIX}). -cartesian_product(Xarr, Yarr) -> - Xset = begin - _pipe = Xarr, - gleam@set:from_list(_pipe) - end, - Yset = begin - _pipe@1 = Yarr, - gleam@set:from_list(_pipe@1) - end, - _pipe@2 = Xset, - _pipe@3 = gleam@set:fold( - _pipe@2, - gleam@set:new(), - fun(Accumulator0, Member0) -> - gleam@set:fold( - Yset, - Accumulator0, - fun(Accumulator1, Member1) -> - gleam@set:insert(Accumulator1, {Member0, Member1}) - end - ) - end - ), - gleam@set:to_list(_pipe@3). diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@conversion.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@conversion.erl deleted file mode 100644 index 0f6decb..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@conversion.erl +++ /dev/null @@ -1,23 +0,0 @@ --module(gleam_community@maths@conversion). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([int_to_float/1, float_to_int/1, degrees_to_radians/1, radians_to_degrees/1]). - --spec int_to_float(integer()) -> float(). -int_to_float(X) -> - gleam@int:to_float(X). - --spec float_to_int(float()) -> integer(). -float_to_int(X) -> - erlang:trunc(X). - --spec degrees_to_radians(float()) -> float(). -degrees_to_radians(X) -> - (X * math:pi()) / 180.0. - --spec radians_to_degrees(float()) -> float(). -radians_to_degrees(X) -> - case math:pi() of - 0.0 -> 0.0; - Gleam@denominator -> (X * 180.0) / Gleam@denominator - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@elementary.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@elementary.erl deleted file mode 100644 index dab5d68..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@elementary.erl +++ /dev/null @@ -1,284 +0,0 @@ --module(gleam_community@maths@elementary). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([acos/1, acosh/1, asin/1, asinh/1, atan/1, atan2/2, atanh/1, cos/1, cosh/1, sin/1, sinh/1, tan/1, tanh/1, exponential/1, natural_logarithm/1, logarithm_2/1, logarithm_10/1, logarithm/2, power/2, square_root/1, cube_root/1, nth_root/2, pi/0, tau/0, e/0]). - --spec acos(float()) -> {ok, float()} | {error, binary()}. -acos(X) -> - case (X >= -1.0) andalso (X =< 1.0) of - true -> - _pipe = math:acos(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1."/utf8>>, - {error, _pipe@1} - end. - --spec acosh(float()) -> {ok, float()} | {error, binary()}. -acosh(X) -> - case X >= 1.0 of - true -> - _pipe = math:acosh(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x < 1. Valid input is x >= 1."/utf8>>, - {error, _pipe@1} - end. - --spec asin(float()) -> {ok, float()} | {error, binary()}. -asin(X) -> - case (X >= -1.0) andalso (X =< 1.0) of - true -> - _pipe = math:asin(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1."/utf8>>, - {error, _pipe@1} - end. - --spec asinh(float()) -> float(). -asinh(X) -> - math:asinh(X). - --spec atan(float()) -> float(). -atan(X) -> - math:atan(X). - --spec atan2(float(), float()) -> float(). -atan2(Y, X) -> - math:atan2(Y, X). - --spec atanh(float()) -> {ok, float()} | {error, binary()}. -atanh(X) -> - case (X > -1.0) andalso (X < 1.0) of - true -> - _pipe = math:atanh(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x > -1 or x < 1. Valid input is -1. < x < 1."/utf8>>, - {error, _pipe@1} - end. - --spec cos(float()) -> float(). -cos(X) -> - math:cos(X). - --spec cosh(float()) -> float(). -cosh(X) -> - math:cosh(X). - --spec sin(float()) -> float(). -sin(X) -> - math:sin(X). - --spec sinh(float()) -> float(). -sinh(X) -> - math:sinh(X). - --spec tan(float()) -> float(). -tan(X) -> - math:tan(X). - --spec tanh(float()) -> float(). -tanh(X) -> - math:tanh(X). - --spec exponential(float()) -> float(). -exponential(X) -> - math:exp(X). - --spec natural_logarithm(float()) -> {ok, float()} | {error, binary()}. -natural_logarithm(X) -> - case X > +0.0 of - true -> - _pipe = math:log(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x <= 0. Valid input is x > 0."/utf8>>, - {error, _pipe@1} - end. - --spec logarithm_2(float()) -> {ok, float()} | {error, binary()}. -logarithm_2(X) -> - case X > +0.0 of - true -> - _pipe = math:log2(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x <= 0. Valid input is x > 0."/utf8>>, - {error, _pipe@1} - end. - --spec logarithm_10(float()) -> {ok, float()} | {error, binary()}. -logarithm_10(X) -> - case X > +0.0 of - true -> - _pipe = math:log10(X), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: x <= 0. Valid input is x > 0."/utf8>>, - {error, _pipe@1} - end. - --spec logarithm(float(), gleam@option:option(float())) -> {ok, float()} | - {error, binary()}. -logarithm(X, Base) -> - case X > +0.0 of - true -> - case Base of - {some, A} -> - case (A > +0.0) andalso (A /= 1.0) of - true -> - _assert_subject = logarithm_10(X), - {ok, Numerator} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/elementary"/utf8>>, - function => <<"logarithm"/utf8>>, - line => 820}) - end, - _assert_subject@1 = logarithm_10(A), - {ok, Denominator} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/elementary"/utf8>>, - function => <<"logarithm"/utf8>>, - line => 821}) - end, - _pipe = case Denominator of - 0.0 -> 0.0; - Gleam@denominator -> Numerator / Gleam@denominator - end, - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1."/utf8>>, - {error, _pipe@1} - end; - - _ -> - _pipe@2 = <<"Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1."/utf8>>, - {error, _pipe@2} - end; - - _ -> - _pipe@3 = <<"Invalid input argument: x <= 0. Valid input is x > 0."/utf8>>, - {error, _pipe@3} - end. - --spec power(float(), float()) -> {ok, float()} | {error, binary()}. -power(X, Y) -> - Fractional = (math:ceil(Y) - Y) > +0.0, - case ((X < +0.0) andalso Fractional) orelse ((X =:= +0.0) andalso (Y < +0.0)) of - true -> - _pipe = <<"Invalid input argument: x < 0 and y is fractional or x = 0 and y < 0."/utf8>>, - {error, _pipe}; - - false -> - _pipe@1 = math:pow(X, Y), - {ok, _pipe@1} - end. - --spec square_root(float()) -> {ok, float()} | {error, binary()}. -square_root(X) -> - case X < +0.0 of - true -> - _pipe = <<"Invalid input argument: x < 0."/utf8>>, - {error, _pipe}; - - false -> - _assert_subject = power(X, 1.0 / 2.0), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/elementary"/utf8>>, - function => <<"square_root"/utf8>>, - line => 1066}) - end, - _pipe@1 = Result, - {ok, _pipe@1} - end. - --spec cube_root(float()) -> {ok, float()} | {error, binary()}. -cube_root(X) -> - case X < +0.0 of - true -> - _pipe = <<"Invalid input argument: x < 0."/utf8>>, - {error, _pipe}; - - false -> - _assert_subject = power(X, 1.0 / 3.0), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/elementary"/utf8>>, - function => <<"cube_root"/utf8>>, - line => 1118}) - end, - _pipe@1 = Result, - {ok, _pipe@1} - end. - --spec nth_root(float(), integer()) -> {ok, float()} | {error, binary()}. -nth_root(X, N) -> - case X < +0.0 of - true -> - _pipe = <<"Invalid input argument: x < 0. Valid input is x > 0"/utf8>>, - {error, _pipe}; - - false -> - case N >= 1 of - true -> - _assert_subject = power(X, case gleam@int:to_float(N) of - 0.0 -> 0.0; - Gleam@denominator -> 1.0 / Gleam@denominator - end), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/elementary"/utf8>>, - function => <<"nth_root"/utf8>>, - line => 1175}) - end, - _pipe@1 = Result, - {ok, _pipe@1}; - - false -> - _pipe@2 = <<"Invalid input argument: n < 1. Valid input is n >= 2."/utf8>>, - {error, _pipe@2} - end - end. - --spec pi() -> float(). -pi() -> - math:pi(). - --spec tau() -> float(). -tau() -> - 2.0 * pi(). - --spec e() -> float(). -e() -> - exponential(1.0). diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@metrics.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@metrics.erl deleted file mode 100644 index 2a58da6..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@metrics.erl +++ /dev/null @@ -1,278 +0,0 @@ --module(gleam_community@maths@metrics). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([norm/2, minkowski_distance/3, manhatten_distance/2, euclidean_distance/2, mean/1, median/1, variance/2, standard_deviation/2]). - --spec norm(list(float()), float()) -> float(). -norm(Arr, P) -> - case Arr of - [] -> - +0.0; - - _ -> - Agg = begin - _pipe = Arr, - gleam@list:fold( - _pipe, - +0.0, - fun(Acc, A) -> - _assert_subject = gleam_community@maths@elementary:power( - gleam_community@maths@piecewise:float_absolute_value( - A - ), - P - ), - {ok, Result} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"norm"/utf8>>, - line => 101}) - end, - Result + Acc - end - ) - end, - _assert_subject@1 = gleam_community@maths@elementary:power( - Agg, - case P of - 0.0 -> 0.0; - Gleam@denominator -> 1.0 / Gleam@denominator - end - ), - {ok, Result@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"norm"/utf8>>, - line => 106}) - end, - Result@1 - end. - --spec minkowski_distance(list(float()), list(float()), float()) -> {ok, float()} | - {error, binary()}. -minkowski_distance(Xarr, Yarr, P) -> - Xlen = gleam@list:length(Xarr), - Ylen = gleam@list:length(Yarr), - case Xlen =:= Ylen of - false -> - _pipe = <<"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."/utf8>>, - {error, _pipe}; - - true -> - case P < 1.0 of - true -> - _pipe@1 = <<"Invalid input argument: p < 1. Valid input is p >= 1."/utf8>>, - {error, _pipe@1}; - - false -> - _pipe@2 = gleam@list:zip(Xarr, Yarr), - _pipe@3 = gleam@list:map( - _pipe@2, - fun(Tuple) -> - gleam@pair:first(Tuple) - gleam@pair:second(Tuple) - end - ), - _pipe@4 = norm(_pipe@3, P), - {ok, _pipe@4} - end - end. - --spec manhatten_distance(list(float()), list(float())) -> {ok, float()} | - {error, binary()}. -manhatten_distance(Xarr, Yarr) -> - minkowski_distance(Xarr, Yarr, 1.0). - --spec euclidean_distance(list(float()), list(float())) -> {ok, float()} | - {error, binary()}. -euclidean_distance(Xarr, Yarr) -> - minkowski_distance(Xarr, Yarr, 2.0). - --spec mean(list(float())) -> {ok, float()} | {error, binary()}. -mean(Arr) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _pipe@1 = Arr, - _pipe@2 = gleam_community@maths@arithmetics:float_sum(_pipe@1), - _pipe@3 = (fun(A) -> - case gleam_community@maths@conversion:int_to_float( - gleam@list:length(Arr) - ) of - 0.0 -> 0.0; - Gleam@denominator -> A / Gleam@denominator - end - end)(_pipe@2), - {ok, _pipe@3} - end. - --spec median(list(float())) -> {ok, float()} | {error, binary()}. -median(Arr) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - Count = gleam@list:length(Arr), - Mid = gleam@list:length(Arr) div 2, - Sorted = gleam@list:sort(Arr, fun gleam@float:compare/2), - case gleam_community@maths@predicates:is_odd(Count) of - true -> - _assert_subject = gleam@list:at(Sorted, Mid), - {ok, Val0} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"median"/utf8>>, - line => 402}) - end, - _pipe@1 = Val0, - {ok, _pipe@1}; - - false -> - _assert_subject@1 = gleam@list:at(Sorted, Mid - 1), - {ok, Val0@1} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"median"/utf8>>, - line => 409}) - end, - _assert_subject@2 = gleam@list:at(Sorted, Mid), - {ok, Val1} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"median"/utf8>>, - line => 410}) - end, - _pipe@2 = [Val0@1, Val1], - mean(_pipe@2) - end - end. - --spec variance(list(float()), integer()) -> {ok, float()} | {error, binary()}. -variance(Arr, Ddof) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - case Ddof < 0 of - true -> - _pipe@1 = <<"Invalid input argument: ddof < 0. Valid input is ddof >= 0."/utf8>>, - {error, _pipe@1}; - - false -> - _assert_subject = mean(Arr), - {ok, Mean} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"variance"/utf8>>, - line => 475}) - end, - _pipe@2 = Arr, - _pipe@3 = gleam@list:map( - _pipe@2, - fun(A) -> - _assert_subject@1 = gleam_community@maths@elementary:power( - A - Mean, - 2.0 - ), - {ok, Result} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"variance"/utf8>>, - line => 478}) - end, - Result - end - ), - _pipe@4 = gleam_community@maths@arithmetics:float_sum( - _pipe@3 - ), - _pipe@5 = (fun(A@1) -> - case (gleam_community@maths@conversion:int_to_float( - gleam@list:length(Arr) - ) - - gleam_community@maths@conversion:int_to_float(Ddof)) of - 0.0 -> 0.0; - Gleam@denominator -> A@1 / Gleam@denominator - end - end)(_pipe@4), - {ok, _pipe@5} - end - end. - --spec standard_deviation(list(float()), integer()) -> {ok, float()} | - {error, binary()}. -standard_deviation(Arr, Ddof) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - case Ddof < 0 of - true -> - _pipe@1 = <<"Invalid input argument: ddof < 0. Valid input is ddof >= 0."/utf8>>, - {error, _pipe@1}; - - false -> - _assert_subject = variance(Arr, Ddof), - {ok, Variance} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"standard_deviation"/utf8>>, - line => 551}) - end, - _assert_subject@1 = gleam_community@maths@elementary:square_root( - Variance - ), - {ok, Stdev} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/metrics"/utf8>>, - function => <<"standard_deviation"/utf8>>, - line => 554}) - end, - _pipe@2 = Stdev, - {ok, _pipe@2} - end - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@piecewise.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@piecewise.erl deleted file mode 100644 index 258d879..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@piecewise.erl +++ /dev/null @@ -1,553 +0,0 @@ --module(gleam_community@maths@piecewise). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([float_absolute_value/1, int_absolute_value/1, float_absolute_difference/2, int_absolute_difference/2, float_sign/1, round/3, ceiling/2, floor/2, truncate/2, int_sign/1, float_flip_sign/1, float_copy_sign/2, int_flip_sign/1, int_copy_sign/2, minimum/3, maximum/3, minmax/3, list_minimum/2, list_maximum/2, arg_minimum/2, arg_maximum/2, extrema/2]). --export_type([rounding_mode/0]). - --type rounding_mode() :: round_nearest | - round_ties_away | - round_ties_up | - round_to_zero | - round_down | - round_up. - --spec truncate_float(float()) -> float(). -truncate_float(X) -> - erlang:trunc(X). - --spec round_to_zero(float(), float()) -> float(). -round_to_zero(P, X) -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> truncate_float(X * P) / Gleam@denominator - end. - --spec round_down(float(), float()) -> float(). -round_down(P, X) -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> math:floor(X * P) / Gleam@denominator - end. - --spec round_up(float(), float()) -> float(). -round_up(P, X) -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> math:ceil(X * P) / Gleam@denominator - end. - --spec float_absolute_value(float()) -> float(). -float_absolute_value(X) -> - case X > +0.0 of - true -> - X; - - false -> - -1.0 * X - end. - --spec int_absolute_value(integer()) -> integer(). -int_absolute_value(X) -> - case X > 0 of - true -> - X; - - false -> - -1 * X - end. - --spec float_absolute_difference(float(), float()) -> float(). -float_absolute_difference(A, B) -> - _pipe = A - B, - float_absolute_value(_pipe). - --spec int_absolute_difference(integer(), integer()) -> integer(). -int_absolute_difference(A, B) -> - _pipe = A - B, - int_absolute_value(_pipe). - --spec do_float_sign(float()) -> float(). -do_float_sign(X) -> - case X < +0.0 of - true -> - -1.0; - - false -> - case X =:= +0.0 of - true -> - +0.0; - - false -> - 1.0 - end - end. - --spec float_sign(float()) -> float(). -float_sign(X) -> - do_float_sign(X). - --spec round_to_nearest(float(), float()) -> float(). -round_to_nearest(P, X) -> - Xabs = float_absolute_value(X) * P, - Xabs_truncated = truncate_float(Xabs), - Remainder = Xabs - Xabs_truncated, - case Remainder of - _ when Remainder > 0.5 -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> (float_sign(X) * truncate_float(Xabs + 1.0)) - / Gleam@denominator - end; - - _ when Remainder =:= 0.5 -> - _assert_subject = gleam@int:modulo( - gleam_community@maths@conversion:float_to_int(Xabs), - 2 - ), - {ok, Is_even} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"round_to_nearest"/utf8>>, - line => 423}) - end, - case Is_even =:= 0 of - true -> - case P of - 0.0 -> 0.0; - Gleam@denominator@1 -> (float_sign(X) * Xabs_truncated) - / Gleam@denominator@1 - end; - - false -> - case P of - 0.0 -> 0.0; - Gleam@denominator@2 -> (float_sign(X) * truncate_float( - Xabs + 1.0 - )) - / Gleam@denominator@2 - end - end; - - _ -> - case P of - 0.0 -> 0.0; - Gleam@denominator@3 -> (float_sign(X) * Xabs_truncated) / Gleam@denominator@3 - end - end. - --spec round_ties_away(float(), float()) -> float(). -round_ties_away(P, X) -> - Xabs = float_absolute_value(X) * P, - Remainder = Xabs - truncate_float(Xabs), - case Remainder of - _ when Remainder >= 0.5 -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> (float_sign(X) * truncate_float(Xabs + 1.0)) - / Gleam@denominator - end; - - _ -> - case P of - 0.0 -> 0.0; - Gleam@denominator@1 -> (float_sign(X) * truncate_float(Xabs)) / Gleam@denominator@1 - end - end. - --spec round_ties_up(float(), float()) -> float(). -round_ties_up(P, X) -> - Xabs = float_absolute_value(X) * P, - Xabs_truncated = truncate_float(Xabs), - Remainder = Xabs - Xabs_truncated, - case Remainder of - _ when (Remainder >= 0.5) andalso (X >= +0.0) -> - case P of - 0.0 -> 0.0; - Gleam@denominator -> (float_sign(X) * truncate_float(Xabs + 1.0)) - / Gleam@denominator - end; - - _ -> - case P of - 0.0 -> 0.0; - Gleam@denominator@1 -> (float_sign(X) * Xabs_truncated) / Gleam@denominator@1 - end - end. - --spec do_round(float(), float(), gleam@option:option(rounding_mode())) -> {ok, - float()} | - {error, binary()}. -do_round(P, X, Mode) -> - case Mode of - {some, round_nearest} -> - _pipe = round_to_nearest(P, X), - {ok, _pipe}; - - {some, round_ties_away} -> - _pipe@1 = round_ties_away(P, X), - {ok, _pipe@1}; - - {some, round_ties_up} -> - _pipe@2 = round_ties_up(P, X), - {ok, _pipe@2}; - - {some, round_to_zero} -> - _pipe@3 = round_to_zero(P, X), - {ok, _pipe@3}; - - {some, round_down} -> - _pipe@4 = round_down(P, X), - {ok, _pipe@4}; - - {some, round_up} -> - _pipe@5 = round_up(P, X), - {ok, _pipe@5}; - - none -> - _pipe@6 = round_to_nearest(P, X), - {ok, _pipe@6} - end. - --spec round( - float(), - gleam@option:option(integer()), - gleam@option:option(rounding_mode()) -) -> {ok, float()} | {error, binary()}. -round(X, Digits, Mode) -> - case Digits of - {some, A} -> - _assert_subject = gleam_community@maths@elementary:power( - 10.0, - gleam_community@maths@conversion:int_to_float(A) - ), - {ok, P} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"round"/utf8>>, - line => 366}) - end, - do_round(P, X, Mode); - - none -> - do_round(1.0, X, Mode) - end. - --spec ceiling(float(), gleam@option:option(integer())) -> {ok, float()} | - {error, binary()}. -ceiling(X, Digits) -> - round(X, Digits, {some, round_up}). - --spec floor(float(), gleam@option:option(integer())) -> {ok, float()} | - {error, binary()}. -floor(X, Digits) -> - round(X, Digits, {some, round_down}). - --spec truncate(float(), gleam@option:option(integer())) -> {ok, float()} | - {error, binary()}. -truncate(X, Digits) -> - round(X, Digits, {some, round_to_zero}). - --spec do_int_sign(integer()) -> integer(). -do_int_sign(X) -> - case X < 0 of - true -> - -1; - - false -> - case X =:= 0 of - true -> - 0; - - false -> - 1 - end - end. - --spec int_sign(integer()) -> integer(). -int_sign(X) -> - do_int_sign(X). - --spec float_flip_sign(float()) -> float(). -float_flip_sign(X) -> - -1.0 * X. - --spec float_copy_sign(float(), float()) -> float(). -float_copy_sign(X, Y) -> - case float_sign(X) =:= float_sign(Y) of - true -> - X; - - false -> - float_flip_sign(X) - end. - --spec int_flip_sign(integer()) -> integer(). -int_flip_sign(X) -> - -1 * X. - --spec int_copy_sign(integer(), integer()) -> integer(). -int_copy_sign(X, Y) -> - case int_sign(X) =:= int_sign(Y) of - true -> - X; - - false -> - int_flip_sign(X) - end. - --spec minimum(FQL, FQL, fun((FQL, FQL) -> gleam@order:order())) -> FQL. -minimum(X, Y, Compare) -> - case Compare(X, Y) of - lt -> - X; - - eq -> - X; - - gt -> - Y - end. - --spec maximum(FQM, FQM, fun((FQM, FQM) -> gleam@order:order())) -> FQM. -maximum(X, Y, Compare) -> - case Compare(X, Y) of - lt -> - Y; - - eq -> - Y; - - gt -> - X - end. - --spec minmax(FQN, FQN, fun((FQN, FQN) -> gleam@order:order())) -> {FQN, FQN}. -minmax(X, Y, Compare) -> - {minimum(X, Y, Compare), maximum(X, Y, Compare)}. - --spec list_minimum(list(FQO), fun((FQO, FQO) -> gleam@order:order())) -> {ok, - FQO} | - {error, binary()}. -list_minimum(Arr, Compare) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _assert_subject = gleam@list:at(Arr, 0), - {ok, Val0} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"list_minimum"/utf8>>, - line => 945}) - end, - _pipe@1 = Arr, - _pipe@2 = gleam@list:fold( - _pipe@1, - Val0, - fun(Acc, Element) -> case Compare(Element, Acc) of - lt -> - Element; - - _ -> - Acc - end end - ), - {ok, _pipe@2} - end. - --spec list_maximum(list(FQS), fun((FQS, FQS) -> gleam@order:order())) -> {ok, - FQS} | - {error, binary()}. -list_maximum(Arr, Compare) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _assert_subject = gleam@list:at(Arr, 0), - {ok, Val0} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"list_maximum"/utf8>>, - line => 1004}) - end, - _pipe@1 = Arr, - _pipe@2 = gleam@list:fold( - _pipe@1, - Val0, - fun(Acc, Element) -> case Compare(Acc, Element) of - lt -> - Element; - - _ -> - Acc - end end - ), - {ok, _pipe@2} - end. - --spec arg_minimum(list(FQW), fun((FQW, FQW) -> gleam@order:order())) -> {ok, - list(integer())} | - {error, binary()}. -arg_minimum(Arr, Compare) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _assert_subject = begin - _pipe@1 = Arr, - list_minimum(_pipe@1, Compare) - end, - {ok, Min} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"arg_minimum"/utf8>>, - line => 1069}) - end, - _pipe@2 = Arr, - _pipe@3 = gleam@list:index_map( - _pipe@2, - fun(Index, Element) -> case Compare(Element, Min) of - eq -> - Index; - - _ -> - -1 - end end - ), - _pipe@4 = gleam@list:filter(_pipe@3, fun(Index@1) -> case Index@1 of - -1 -> - false; - - _ -> - true - end end), - {ok, _pipe@4} - end. - --spec arg_maximum(list(FRB), fun((FRB, FRB) -> gleam@order:order())) -> {ok, - list(integer())} | - {error, binary()}. -arg_maximum(Arr, Compare) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _assert_subject = begin - _pipe@1 = Arr, - list_maximum(_pipe@1, Compare) - end, - {ok, Max} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"arg_maximum"/utf8>>, - line => 1139}) - end, - _pipe@2 = Arr, - _pipe@3 = gleam@list:index_map( - _pipe@2, - fun(Index, Element) -> case Compare(Element, Max) of - eq -> - Index; - - _ -> - -1 - end end - ), - _pipe@4 = gleam@list:filter(_pipe@3, fun(Index@1) -> case Index@1 of - -1 -> - false; - - _ -> - true - end end), - {ok, _pipe@4} - end. - --spec extrema(list(FRG), fun((FRG, FRG) -> gleam@order:order())) -> {ok, - {FRG, FRG}} | - {error, binary()}. -extrema(Arr, Compare) -> - case Arr of - [] -> - _pipe = <<"Invalid input argument: The list is empty."/utf8>>, - {error, _pipe}; - - _ -> - _assert_subject = gleam@list:at(Arr, 0), - {ok, Val_max} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"extrema"/utf8>>, - line => 1209}) - end, - _assert_subject@1 = gleam@list:at(Arr, 0), - {ok, Val_min} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/piecewise"/utf8>>, - function => <<"extrema"/utf8>>, - line => 1210}) - end, - _pipe@1 = Arr, - _pipe@2 = gleam@list:fold( - _pipe@1, - {Val_min, Val_max}, - fun(Acc, Element) -> - First = gleam@pair:first(Acc), - Second = gleam@pair:second(Acc), - case {Compare(Element, First), Compare(Second, Element)} of - {lt, lt} -> - {Element, Element}; - - {lt, _} -> - {Element, Second}; - - {_, lt} -> - {First, Element}; - - {_, _} -> - {First, Second} - end - end - ), - {ok, _pipe@2} - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@predicates.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@predicates.erl deleted file mode 100644 index d991d89..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@predicates.erl +++ /dev/null @@ -1,118 +0,0 @@ --module(gleam_community@maths@predicates). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_close/4, all_close/4, is_fractional/1, is_power/2, is_perfect/1, is_even/1, is_odd/1]). - --spec float_absolute_value(float()) -> float(). -float_absolute_value(X) -> - case X > +0.0 of - true -> - X; - - false -> - -1.0 * X - end. - --spec float_absolute_difference(float(), float()) -> float(). -float_absolute_difference(A, B) -> - _pipe = A - B, - float_absolute_value(_pipe). - --spec is_close(float(), float(), float(), float()) -> boolean(). -is_close(A, B, Rtol, Atol) -> - X = float_absolute_difference(A, B), - Y = Atol + (Rtol * float_absolute_value(B)), - case X =< Y of - true -> - true; - - false -> - false - end. - --spec all_close(list(float()), list(float()), float(), float()) -> {ok, - list(boolean())} | - {error, binary()}. -all_close(Xarr, Yarr, Rtol, Atol) -> - Xlen = gleam@list:length(Xarr), - Ylen = gleam@list:length(Yarr), - case Xlen =:= Ylen of - false -> - _pipe = <<"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."/utf8>>, - {error, _pipe}; - - true -> - _pipe@1 = gleam@list:zip(Xarr, Yarr), - _pipe@2 = gleam@list:map( - _pipe@1, - fun(Z) -> - is_close( - gleam@pair:first(Z), - gleam@pair:second(Z), - Rtol, - Atol - ) - end - ), - {ok, _pipe@2} - end. - --spec is_fractional(float()) -> boolean(). -is_fractional(X) -> - (math:ceil(X) - X) > +0.0. - --spec is_power(integer(), integer()) -> boolean(). -is_power(X, Y) -> - _assert_subject = gleam_community@maths@elementary:logarithm( - gleam@int:to_float(X), - {some, gleam@int:to_float(Y)} - ), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/predicates"/utf8>>, - function => <<"is_power"/utf8>>, - line => 241}) - end, - _assert_subject@1 = gleam_community@maths@piecewise:truncate( - Value, - {some, 0} - ), - {ok, Truncated} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/predicates"/utf8>>, - function => <<"is_power"/utf8>>, - line => 243}) - end, - Rem = Value - Truncated, - Rem =:= +0.0. - --spec do_sum(list(integer())) -> integer(). -do_sum(Arr) -> - case Arr of - [] -> - 0; - - _ -> - _pipe = Arr, - gleam@list:fold(_pipe, 0, fun(Acc, A) -> A + Acc end) - end. - --spec is_perfect(integer()) -> boolean(). -is_perfect(N) -> - do_sum(gleam_community@maths@arithmetics:proper_divisors(N)) =:= N. - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@sequences.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@sequences.erl deleted file mode 100644 index 74dcff4..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@sequences.erl +++ /dev/null @@ -1,199 +0,0 @@ --module(gleam_community@maths@sequences). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([arange/3, linear_space/4, logarithmic_space/5, geometric_space/4]). - --spec arange(float(), float(), float()) -> list(float()). -arange(Start, Stop, Step) -> - case ((Start >= Stop) andalso (Step > +0.0)) orelse ((Start =< Stop) andalso (Step - < +0.0)) of - true -> - []; - - false -> - Direction = case Start =< Stop of - true -> - 1.0; - - false -> - -1.0 - end, - Step_abs = gleam_community@maths@piecewise:float_absolute_value( - Step - ), - Num = case Step_abs of - 0.0 -> 0.0; - Gleam@denominator -> gleam_community@maths@piecewise:float_absolute_value( - Start - Stop - ) - / Gleam@denominator - end, - _pipe = gleam@list:range( - 0, - gleam_community@maths@conversion:float_to_int(Num) - 1 - ), - gleam@list:map( - _pipe, - fun(I) -> - Start + ((gleam_community@maths@conversion:int_to_float(I) * Step_abs) - * Direction) - end - ) - end. - --spec linear_space(float(), float(), integer(), boolean()) -> {ok, - list(float())} | - {error, binary()}. -linear_space(Start, Stop, Num, Endpoint) -> - Direction = case Start =< Stop of - true -> - 1.0; - - false -> - -1.0 - end, - case Num > 0 of - true -> - case Endpoint of - true -> - Increment = case gleam_community@maths@conversion:int_to_float( - Num - 1 - ) of - 0.0 -> 0.0; - Gleam@denominator -> gleam_community@maths@piecewise:float_absolute_value( - Start - Stop - ) - / Gleam@denominator - end, - _pipe = gleam@list:range(0, Num - 1), - _pipe@1 = gleam@list:map( - _pipe, - fun(I) -> - Start + ((gleam_community@maths@conversion:int_to_float( - I - ) - * Increment) - * Direction) - end - ), - {ok, _pipe@1}; - - false -> - Increment@1 = case gleam_community@maths@conversion:int_to_float( - Num - ) of - 0.0 -> 0.0; - Gleam@denominator@1 -> gleam_community@maths@piecewise:float_absolute_value( - Start - Stop - ) - / Gleam@denominator@1 - end, - _pipe@2 = gleam@list:range(0, Num - 1), - _pipe@3 = gleam@list:map( - _pipe@2, - fun(I@1) -> - Start + ((gleam_community@maths@conversion:int_to_float( - I@1 - ) - * Increment@1) - * Direction) - end - ), - {ok, _pipe@3} - end; - - false -> - _pipe@4 = <<"Invalid input: num < 0. Valid input is num > 0."/utf8>>, - {error, _pipe@4} - end. - --spec logarithmic_space(float(), float(), integer(), boolean(), float()) -> {ok, - list(float())} | - {error, binary()}. -logarithmic_space(Start, Stop, Num, Endpoint, Base) -> - case Num > 0 of - true -> - _assert_subject = linear_space(Start, Stop, Num, Endpoint), - {ok, Linspace} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/sequences"/utf8>>, - function => <<"logarithmic_space"/utf8>>, - line => 221}) - end, - _pipe = Linspace, - _pipe@1 = gleam@list:map( - _pipe, - fun(I) -> - _assert_subject@1 = gleam_community@maths@elementary:power( - Base, - I - ), - {ok, Result} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/sequences"/utf8>>, - function => <<"logarithmic_space"/utf8>>, - line => 224}) - end, - Result - end - ), - {ok, _pipe@1}; - - false -> - _pipe@2 = <<"Invalid input: num < 0. Valid input is num > 0."/utf8>>, - {error, _pipe@2} - end. - --spec geometric_space(float(), float(), integer(), boolean()) -> {ok, - list(float())} | - {error, binary()}. -geometric_space(Start, Stop, Num, Endpoint) -> - case (Start =:= +0.0) orelse (Stop =:= +0.0) of - true -> - _pipe = <<""/utf8>>, - {error, _pipe}; - - false -> - case Num > 0 of - true -> - _assert_subject = gleam_community@maths@elementary:logarithm_10( - Start - ), - {ok, Log_start} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/sequences"/utf8>>, - function => <<"geometric_space"/utf8>>, - line => 293}) - end, - _assert_subject@1 = gleam_community@maths@elementary:logarithm_10( - Stop - ), - {ok, Log_stop} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/sequences"/utf8>>, - function => <<"geometric_space"/utf8>>, - line => 294}) - end, - logarithmic_space(Log_start, Log_stop, Num, Endpoint, 10.0); - - false -> - _pipe@1 = <<"Invalid input: num < 0. Valid input is num > 0."/utf8>>, - {error, _pipe@1} - end - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@special.erl b/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@special.erl deleted file mode 100644 index 925f4bb..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community@maths@special.erl +++ /dev/null @@ -1,157 +0,0 @@ --module(gleam_community@maths@special). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([erf/1, gamma/1, beta/2, incomplete_gamma/2]). - --spec erf(float()) -> float(). -erf(X) -> - _assert_subject = [0.254829592, - -0.284496736, - 1.421413741, - -1.453152027, - 1.061405429], - [A1, A2, A3, A4, A5] = case _assert_subject of - [_, _, _, _, _] -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/special"/utf8>>, - function => <<"erf"/utf8>>, - line => 79}) - end, - P = 0.3275911, - Sign = gleam_community@maths@piecewise:float_sign(X), - X@1 = gleam_community@maths@piecewise:float_absolute_value(X), - T = case (1.0 + (P * X@1)) of - 0.0 -> 0.0; - Gleam@denominator -> 1.0 / Gleam@denominator - end, - Y = 1.0 - ((((((((((A5 * T) + A4) * T) + A3) * T) + A2) * T) + A1) * T) * gleam_community@maths@elementary:exponential( - (-1.0 * X@1) * X@1 - )), - Sign * Y. - --spec gamma_lanczos(float()) -> float(). -gamma_lanczos(X) -> - case X < 0.5 of - true -> - case (gleam_community@maths@elementary:sin( - gleam_community@maths@elementary:pi() * X - ) - * gamma_lanczos(1.0 - X)) of - 0.0 -> 0.0; - Gleam@denominator -> gleam_community@maths@elementary:pi() / Gleam@denominator - end; - - false -> - Z = X - 1.0, - X@1 = gleam@list:index_fold( - [0.99999999999980993, - 676.5203681218851, - -1259.1392167224028, - 771.32342877765313, - -176.61502916214059, - 12.507343278686905, - -0.13857109526572012, - 0.0000099843695780195716, - 0.00000015056327351493116], - +0.0, - fun(Acc, V, Index) -> case Index > 0 of - true -> - Acc + (case (Z + gleam_community@maths@conversion:int_to_float( - Index - )) of - 0.0 -> 0.0; - Gleam@denominator@1 -> V / Gleam@denominator@1 - end); - - false -> - V - end end - ), - T = (Z + 7.0) + 0.5, - _assert_subject = gleam_community@maths@elementary:power( - 2.0 * gleam_community@maths@elementary:pi(), - 0.5 - ), - {ok, V1} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/special"/utf8>>, - function => <<"gamma_lanczos"/utf8>>, - line => 146}) - end, - _assert_subject@1 = gleam_community@maths@elementary:power( - T, - Z + 0.5 - ), - {ok, V2} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"gleam_community/maths/special"/utf8>>, - function => <<"gamma_lanczos"/utf8>>, - line => 147}) - end, - ((V1 * V2) * gleam_community@maths@elementary:exponential(-1.0 * T)) - * X@1 - end. - --spec gamma(float()) -> float(). -gamma(X) -> - gamma_lanczos(X). - --spec beta(float(), float()) -> float(). -beta(X, Y) -> - case gamma(X + Y) of - 0.0 -> 0.0; - Gleam@denominator -> (gamma(X) * gamma(Y)) / Gleam@denominator - end. - --spec incomplete_gamma_sum(float(), float(), float(), float(), float()) -> float(). -incomplete_gamma_sum(A, X, T, S, N) -> - case T of - +0.0 -> - S; - - _ -> - Ns = S + T, - Nt = T * (case (A + N) of - 0.0 -> 0.0; - Gleam@denominator -> X / Gleam@denominator - end), - incomplete_gamma_sum(A, X, Nt, Ns, N + 1.0) - end. - --spec incomplete_gamma(float(), float()) -> {ok, float()} | {error, binary()}. -incomplete_gamma(A, X) -> - case (A > +0.0) andalso (X >= +0.0) of - true -> - _assert_subject = gleam_community@maths@elementary:power(X, A), - {ok, V} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam_community/maths/special"/utf8>>, - function => <<"incomplete_gamma"/utf8>>, - line => 173}) - end, - _pipe = (V * gleam_community@maths@elementary:exponential(-1.0 * X)) - * incomplete_gamma_sum(A, X, case A of - 0.0 -> 0.0; - Gleam@denominator -> 1.0 / Gleam@denominator - end, +0.0, 1.0), - {ok, _pipe}; - - false -> - _pipe@1 = <<"Invlaid input argument: a <= 0 or x < 0. Valid input is a > 0 and x >= 0."/utf8>>, - {error, _pipe@1} - end. diff --git a/aoc2023/build/packages/gleam_community_maths/src/gleam_community_maths.app.src b/aoc2023/build/packages/gleam_community_maths/src/gleam_community_maths.app.src deleted file mode 100644 index 091e679..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/gleam_community_maths.app.src +++ /dev/null @@ -1,16 +0,0 @@ -{application, gleam_community_maths, [ - {vsn, "1.0.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A basic maths library"}, - {modules, [gleam_community@maths@arithmetics, - gleam_community@maths@combinatorics, - gleam_community@maths@conversion, - gleam_community@maths@elementary, - gleam_community@maths@metrics, - gleam_community@maths@piecewise, - gleam_community@maths@predicates, - gleam_community@maths@sequences, - gleam_community@maths@special]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_community_maths/src/maths.mjs b/aoc2023/build/packages/gleam_community_maths/src/maths.mjs deleted file mode 100644 index 5c5ab31..0000000 --- a/aoc2023/build/packages/gleam_community_maths/src/maths.mjs +++ /dev/null @@ -1,95 +0,0 @@ -export function sin(float) { - return Math.sin(float) -} - -export function pi() { - return Math.PI -} - -export function acos(float) { - return Math.acos(float) -} - -export function acosh(float) { - return Math.acosh(float) -} - -export function asin(float) { - return Math.asin(float) -} - -export function asinh(float) { - return Math.asinh(float) -} - -export function atan(float) { - return Math.atan(float) -} - -export function tan(float) { - return Math.tan(float) -} - -export function atan2(floaty, floatx) { - return Math.atan2(floaty, floatx) -} - -export function atanh(float) { - return Math.atanh(float) -} - -export function cos(float) { - return Math.cos(float) -} - -export function cosh(float) { - return Math.cosh(float) -} - -export function exponential(float) { - return Math.exp(float) -} - -export function ceiling(float) { - return Math.ceil(float) -} - -export function floor(float) { - return Math.floor(float) -} - -export function power(base, exponent) { - return Math.pow(base, exponent) -} - -export function logarithm(float) { - return Math.log(float) -} - -export function logarithm_10(float) { - return Math.log10(float) -} - -export function logarithm_2(float) { - return Math.log2(float) -} - -export function sinh(float) { - return Math.sinh(float) -} - -export function tanh(float) { - return Math.tanh(float) -} - -export function sign(float) { - return Math.sign(float) -} - -export function truncate(float) { - return Math.trunc(float) -} - -export function to_int(float) { - return Math.trunc(float) -} diff --git a/aoc2023/build/packages/gleam_erlang/LICENSE b/aoc2023/build/packages/gleam_erlang/LICENSE deleted file mode 100644 index 59e1345..0000000 --- a/aoc2023/build/packages/gleam_erlang/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/aoc2023/build/packages/gleam_erlang/README.md b/aoc2023/build/packages/gleam_erlang/README.md deleted file mode 100644 index ffee4cd..0000000 --- a/aoc2023/build/packages/gleam_erlang/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Gleam Erlang 🐙 - -A library for making use of Erlang specific code! - -## Features - -- Typed Erlang processes and message sending. -- Erlang binary format (de)serialisation. -- Functions for working with Erlang's charlists. -- Reading, writing, and deletion of files. -- Basic distributed Erlang support and working with nodes. -- Reading and writing of environment variables. -- Functions for working with atoms. - -## Usage - -Add this library to your Gleam project - -```shell -gleam add gleam_erlang -``` - -And then use it in your code - -```gleam -import gleam/io -import gleam/erlang/file - -pub fn main() { - assert Ok(contents) = file.read("pokedex.txt") - io.println(contents) -} -``` - -Documentation can be found at <https://hexdocs.pm/gleam_erlang/>. - -This library requires OTP 23.0 or higher. diff --git a/aoc2023/build/packages/gleam_erlang/gleam.toml b/aoc2023/build/packages/gleam_erlang/gleam.toml deleted file mode 100644 index 8d62603..0000000 --- a/aoc2023/build/packages/gleam_erlang/gleam.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "gleam_erlang" - -version = "0.23.1" -licences = ["Apache-2.0"] -description = "A Gleam library for working with Erlang" - -repository = { type = "github", user = "gleam-lang", repo = "erlang" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 0.6" diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl deleted file mode 100644 index b38d11e..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@file_FileInfo.hrl +++ /dev/null @@ -1,15 +0,0 @@ --record(file_info, { - size :: integer(), - file_type :: gleam@erlang@file:file_type(), - access :: gleam@erlang@file:access(), - atime :: integer(), - mtime :: integer(), - ctime :: integer(), - mode :: integer(), - links :: integer(), - major_device :: integer(), - minor_device :: integer(), - inode :: integer(), - user_id :: integer(), - group_id :: integer() -}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl deleted file mode 100644 index 4cd0452..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Abnormal.hrl +++ /dev/null @@ -1 +0,0 @@ --record(abnormal, {reason :: binary()}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl deleted file mode 100644 index 5dd5047..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_CalleeDown.hrl +++ /dev/null @@ -1 +0,0 @@ --record(callee_down, {reason :: gleam@dynamic:dynamic_()}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl deleted file mode 100644 index b82b49f..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Cancelled.hrl +++ /dev/null @@ -1 +0,0 @@ --record(cancelled, {time_remaining :: integer()}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl deleted file mode 100644 index c476308..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ExitMessage.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(exit_message, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@erlang@process:exit_reason() -}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl deleted file mode 100644 index df0b6b7..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessDown.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(process_down, { - pid :: gleam@erlang@process:pid_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl deleted file mode 100644 index ce552e2..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_ProcessMonitor.hrl +++ /dev/null @@ -1 +0,0 @@ --record(process_monitor, {tag :: gleam@erlang:reference_()}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl deleted file mode 100644 index abc46b2..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang@process_Subject.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(subject, { - owner :: gleam@erlang@process:pid_(), - tag :: gleam@erlang:reference_() -}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl deleted file mode 100644 index 52c9896..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_ApplicationFailedToStart.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(application_failed_to_start, { - name :: gleam@erlang@atom:atom_(), - reason :: gleam@dynamic:dynamic_() -}). diff --git a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl b/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl deleted file mode 100644 index fde3c61..0000000 --- a/aoc2023/build/packages/gleam_erlang/include/gleam@erlang_UnknownApplication.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unknown_application, {name :: gleam@erlang@atom:atom_()}). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang.gleam deleted file mode 100644 index 783cd53..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang.gleam +++ /dev/null @@ -1,158 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/list -import gleam/erlang/atom.{type Atom} -import gleam/erlang/charlist.{type Charlist} - -@external(erlang, "io_lib", "format") -fn erl_format(a: String, b: List(a)) -> Charlist - -/// Return a string representation of any term -pub fn format(term: any) -> String { - charlist.to_string(erl_format("~p", [term])) -} - -@external(erlang, "erlang", "term_to_binary") -pub fn term_to_binary(a: a) -> BitArray - -type Safe { - Safe -} - -@external(erlang, "erlang", "binary_to_term") -fn erl_binary_to_term(a: BitArray, b: List(Safe)) -> Dynamic - -pub fn binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, [Safe]) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -pub fn unsafe_binary_to_term(binary: BitArray) -> Result(Dynamic, Nil) { - case rescue(fn() { erl_binary_to_term(binary, []) }) { - Ok(term) -> Ok(term) - Error(_) -> Error(Nil) - } -} - -/// Error value returned by `get_line` function -/// -pub type GetLineError { - Eof - NoData -} - -/// Reads a line from standard input with the given prompt. -/// -/// # Example -/// -/// > get_line("Language: ") -/// // -> Language: <- gleam -/// Ok("gleam\n") -/// -@external(erlang, "gleam_erlang_ffi", "get_line") -pub fn get_line(prompt prompt: String) -> Result(String, GetLineError) - -pub type TimeUnit { - Second - Millisecond - Microsecond - Nanosecond -} - -/// Returns the current OS system time. -/// -/// <https://erlang.org/doc/apps/erts/time_correction.html#OS_System_Time> -@external(erlang, "os", "system_time") -pub fn system_time(a: TimeUnit) -> Int - -/// Returns the current OS system time as a tuple of Ints -/// -/// http://erlang.org/doc/man/os.html#timestamp-0 -@external(erlang, "os", "timestamp") -pub fn erlang_timestamp() -> #(Int, Int, Int) - -/// Gleam doesn't offer any way to raise exceptions, but they may still occur -/// due to bugs when working with unsafe code, such as when calling Erlang -/// function. -/// -/// This function will catch any error thrown and convert it into a result -/// rather than crashing the process. -/// -@external(erlang, "gleam_erlang_ffi", "rescue") -pub fn rescue(a: fn() -> a) -> Result(a, Crash) - -pub type Crash { - Exited(Dynamic) - Thrown(Dynamic) - Errored(Dynamic) -} - -@external(erlang, "init", "get_plain_arguments") -fn get_start_arguments() -> List(Charlist) - -/// Get the arguments given to the program when it was started. -/// -/// This is sometimes called `argv` in other languages. -pub fn start_arguments() -> List(String) { - get_start_arguments() - |> list.map(charlist.to_string) -} - -/// Starts an OTP application's process tree in the background, as well as -/// the trees of any applications that the given application depends upon. An -/// OTP application typically maps onto a Gleam or Hex package. -/// -/// Returns a list of the applications that were started. Calling this function -/// for application that have already been started is a no-op so you do not need -/// to check the application state beforehand. -/// -/// In Gleam we prefer to not use these implicit background process trees, but -/// you will likely still need to start the trees of OTP applications written in -/// other BEAM languages such as Erlang or Elixir, including those included by -/// default with Erlang/OTP. -/// -/// For more information see the OTP documentation. -/// - <https://www.erlang.org/doc/man/application.html#ensure_all_started-1> -/// - <https://www.erlang.org/doc/man/application.html#start-1> -/// -@external(erlang, "gleam_erlang_ffi", "ensure_all_started") -pub fn ensure_all_started( - application application: Atom, -) -> Result(List(Atom), EnsureAllStartedError) - -pub type EnsureAllStartedError { - UnknownApplication(name: Atom) - ApplicationFailedToStart(name: Atom, reason: Dynamic) -} - -/// A unique reference value. -/// -/// It holds no particular meaning or value, but unique values are often useful -/// in programs are used heavily within both Gleam and Erlang's OTP frameworks. -/// -/// More can be read about references in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/efficiency_guide/advanced.html#unique_references -/// -pub type Reference - -/// Create a new unique reference. -/// -@external(erlang, "erlang", "make_ref") -pub fn make_reference() -> Reference - -/// Returns the path of a package's `priv` directory, where extra non-Gleam -/// or Erlang files are typically kept. -/// -/// Returns an error if no package was found with the given name. -/// -/// # Example -/// -/// ```gleam -/// > erlang.priv_directory("my_app") -/// // -> Ok("/some/location/my_app/priv") -/// ``` -/// -@external(erlang, "gleam_erlang_ffi", "priv_directory") -pub fn priv_directory(name: String) -> Result(String, Nil) diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam deleted file mode 100644 index a27289c..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/atom.gleam +++ /dev/null @@ -1,79 +0,0 @@ -import gleam/dynamic.{type DecodeErrors, type Dynamic} - -/// Atom is a special string-like data-type that is most commonly used for -/// interfacing with code written in other BEAM languages such as Erlang and -/// Elixir. It is preferable to define your own custom types to use instead of -/// atoms where possible. -/// -/// Atoms are not used much in typical Gleam code! -/// -/// ## Creating atoms -/// -/// We can create atoms with the the [`create_from_string`](#create_from_string) -/// function, though we must be careful when doing so as atoms are never -/// garbage collected. If we create too many atoms (for example, if we convert -/// user input into atoms) we may hit the max limit of atoms and cause the -/// virtual machine to crash. -/// -pub type Atom - -/// An error returned when no atom is found in the virtual machine's atom table -/// for a given string when calling the [`from_string`](#from_string) function. -pub type FromStringError { - AtomNotLoaded -} - -/// Finds an existing Atom for the given String. -/// -/// If no atom is found in the virtual machine's atom table for the String then -/// an error is returned. -/// -/// ## Examples -/// -/// > from_string("ok") -/// Ok(create_from_string("ok")) -/// -/// > from_string("some_new_atom") -/// Error(AtomNotLoaded) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_string") -pub fn from_string(a: String) -> Result(Atom, FromStringError) - -/// Creates an atom from a string, inserting a new value into the virtual -/// machine's atom table if an atom does not already exist for the given -/// string. -/// -/// We must be careful when using this function as there is a limit to the -/// number of atom that can fit in the virtual machine's atom table. Never -/// convert user input into atoms as filling the atom table will cause the -/// virtual machine to crash! -/// -@external(erlang, "erlang", "binary_to_atom") -pub fn create_from_string(a: String) -> Atom - -/// Returns a `String` corresponding to the text representation of the given -/// `Atom`. -/// -/// ## Examples -/// -/// > let ok_atom = create_from_string("ok") -/// > to_string(ok_atom) -/// "ok" -/// -@external(erlang, "erlang", "atom_to_binary") -pub fn to_string(a: Atom) -> String - -/// Checks to see whether a `Dynamic` value is an atom, and return the atom if -/// it is. -/// -/// ## Examples -/// -/// > import gleam/dynamic -/// > from_dynamic(dynamic.from(create_from_string("hello"))) -/// Ok(create_from_string("hello")) -/// -/// > from_dynamic(dynamic.from(123)) -/// Error([DecodeError(expected: "Atom", found: "Int", path: [])]) -/// -@external(erlang, "gleam_erlang_ffi", "atom_from_dynamic") -pub fn from_dynamic(from from: Dynamic) -> Result(Atom, DecodeErrors) diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam deleted file mode 100644 index e5b6d65..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/charlist.gleam +++ /dev/null @@ -1,25 +0,0 @@ -//// A charlist is a list of integers where all the integers are valid code -//// points. -//// -//// In practice, you will not come across them often, except perhaps when -//// interfacing with Erlang, in particular when using older libraries that do -//// not accept binaries as arguments. - -/// A list of characters represented as ints. Commonly used by older Erlang -/// modules. -pub type Charlist - -/// Transform a charlist to a string -@external(erlang, "unicode", "characters_to_binary") -pub fn to_string(a: Charlist) -> String - -// Calls `unicode:characters_to_binary(Data, unicode, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_binary-1> - -/// Transform a string to a charlist -@external(erlang, "unicode", "characters_to_list") -pub fn from_string(a: String) -> Charlist -// Calls `unicode:characters_to_list(Data, unicode)` -// Note: `unicode is an alias for utf8` -// See <https://www.erlang.org/doc/man/unicode.html#characters_to_list-1> diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/file.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/file.gleam deleted file mode 100644 index 48e11a7..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/file.gleam +++ /dev/null @@ -1,737 +0,0 @@ -//// Working with files on the filesystem. -//// -//// The functions included in this module are for high-level concepts such as -//// reading and writing. - -import gleam/bit_array -import gleam/result - -/// Reason represents all of the reasons that Erlang surfaces of why a file -/// system operation could fail. Most of these reasons are POSIX errors, which -/// come from the operating system and start with `E`. Others have been added to -/// represent other issues that may arise. -pub type Reason { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 -} - -/// The type of file found by `file_info` or `link_info`. -/// -pub type FileType { - Device - Directory - Other - Regular - Symlink -} - -/// The read/write permissions a user can have for a file. -/// -pub type Access { - NoAccess - Read - ReadWrite - Write -} - -/// Meta information for a file. -/// -/// Timestamps are in seconds before or after the Unix time epoch, -/// `1970-01-01 00:00:00 UTC`. -/// -pub type FileInfo { - FileInfo( - /// File size in bytes. - /// - size: Int, - /// `Regular`, `Directory`, `Symlink`, `Device`, or `Other`. - /// - file_type: FileType, - /// `ReadWrite`, `Read`, `Write`, or `NoAccess`. - /// - access: Access, - /// Timestamp of most recent access. - /// - atime: Int, - /// Timestamp of most recent modification. - /// - mtime: Int, - /// Timestamp of most recent change (or file creation, depending on - /// operating system). - /// - ctime: Int, - /// File permissions encoded as a sum of bit values, including but not - /// limited to: - /// - /// Owner read, write, execute. - /// - /// `0o400`, `0o200`, `0o100` - /// - /// Group read, write, execute. - /// - /// `0o40`, `0o20`, `0o10` - /// - /// Other read, write, execute. - /// - /// `0o4`, `0o2`, `0o1` - /// - /// Set user ID, group ID on execution. - /// - /// `0x800`, `0x400` - /// - mode: Int, - /// Total links to a file (always `1` for file systems without links). - /// - links: Int, - /// The file system where a file is located (`0` for drive `A:` on Windows, - /// `1` for `B:`, etc.). - /// - major_device: Int, - /// Character device (or `0` on non-Unix systems). - /// - minor_device: Int, - /// The `inode` number for a file (always `0` on non-Unix file systems). - /// - inode: Int, - /// The owner of a file (always `0` on non-Unix file systems). - /// - user_id: Int, - /// The group id of a file (always `0` on non-Unix file systems). - /// - group_id: Int, - ) -} - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To get `FileInfo` about a symlink itself, use `link_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > file_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 140, -/// file_type: Directory, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > file_info("/does_not_exist") -/// Error(Enoent) -/// -/// > file_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_info(a: String) -> Result(FileInfo, Reason) { - do_file_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "file_info") -fn do_file_info(a: String) -> Result(FileInfo, Reason) - -/// Results in `FileInfo` about the given `path` on success, otherwise a -/// `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To get `FileInfo` about a symlink's target, use `file_info`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_info("gleam.toml") -/// Ok(FileInfo( -/// size: 430, -/// file_type: Regular, -/// access: ReadWrite, -/// atime: 1680580321, -/// mtime: 1680580272, -/// ctime: 1680580272, -/// mode: 33188, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 469028, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/root") -/// Ok(FileInfo( -/// size: 16, -/// file_type: Directory, -/// access: Read, -/// atime: 1677789967, -/// mtime: 1664561240, -/// ctime: 1664561240, -/// mode: 16877, -/// links: 11, -/// major_device: 54, -/// minor_device: 0, -/// inode: 34, -/// user_id: 0, -/// group_id: 0, -/// )) -/// -/// > link_info("./build/dev/erlang/rad/priv") -/// Ok(FileInfo( -/// size: 41, -/// file_type: Symlink, -/// access: ReadWrite, -/// atime: 1680581150, -/// mtime: 1680581150, -/// ctime: 1680581150, -/// mode: 41471, -/// links: 1, -/// major_device: 64, -/// minor_device: 0, -/// inode: 471587, -/// user_id: 1000, -/// group_id: 1000, -/// )) -/// -/// > link_info("/does_not_exist") -/// Error(Enoent) -/// -/// > link_info("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_info(a: String) -> Result(FileInfo, Reason) { - do_link_info(a) -} - -@external(erlang, "gleam_erlang_ffi", "link_info") -fn do_link_info(a: String) -> Result(FileInfo, Reason) - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Directory` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_directory("/tmp") -/// Ok(True) -/// -/// > is_directory("resume.pdf") -/// Ok(False) -/// -/// > is_directory("/does_not_exist") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_directory(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Directory -} - -/// Results in a `Bool` on success that indicates whether the given `path` has -/// a `Regular` `FileType`, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// -/// ## Examples -/// -/// ```gleam -/// > is_regular("resume.pdf") -/// Ok(True) -/// -/// > is_regular("/tmp") -/// Ok(False) -/// -/// > is_regular("/does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn is_regular(path: String) -> Result(Bool, Reason) { - use FileInfo(file_type: file_type, ..) <- result.map(over: do_file_info(path)) - file_type == Regular -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link's target. -/// To find whether a symlink itself exists, use `link_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > file_exists("resume.pdf") -/// Ok(True) -/// -/// > file_exists("/tmp") -/// Ok(True) -/// -/// > file_exists("/does_not_exist") -/// Ok(False) -/// -/// > file_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn file_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_file_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Results in a `Bool` on success that indicates whether the given `path` -/// exists, otherwise a `Reason` for failure. -/// -/// When `path` refers to a symlink, the result pertains to the link itself. -/// To find whether a symlink's target exists, use `file_exists`. -/// -/// ## Examples -/// -/// ```gleam -/// > link_exists("resume.pdf") -/// Ok(True) -/// -/// > link_exists("/tmp") -/// Ok(True) -/// -/// > link_exists("/does_not_exist") -/// Ok(False) -/// -/// > link_exists("/root/.local/maybe_exists") -/// Error(Eacces) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn link_exists(path: String) -> Result(Bool, Reason) { - let result = - path - |> do_link_info - |> result.replace(True) - case result { - Error(Enoent) -> Ok(False) - _ -> result - } -} - -/// Tries to create a directory. Missing parent directories are not created. -/// -/// Returns a Result of nil if the directory is created or Reason if the -/// operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > make_directory("/tmp/foo") -/// Ok(Nil) -/// -/// > make_directory("relative_directory") -/// Ok(Nil) -/// -/// > make_directory("/tmp/missing_intermediate_directory/foo") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "make_directory") -pub fn make_directory(a: String) -> Result(Nil, Reason) - -/// Lists all files in a directory, except files with -/// [raw filenames](https://www.erlang.org/doc/apps/stdlib/unicode_usage.html#notes-about-raw-filenames). -/// -/// Returns a Result containing the list of filenames in the directory, or Reason -/// if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > list_directory("/tmp") -/// Ok(["FB01293B-8597-4359-80D5-130140A0C0DE","AlTest2.out"]) -/// -/// > list_directory("resume.docx") -/// Error(Enotdir) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "list_directory") -pub fn list_directory(a: String) -> Result(List(String), Reason) - -/// Deletes a directory. -/// -/// The directory must be empty before it can be deleted. Returns a nil Success -/// or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > delete_directory("foo") -/// Ok(Nil) -/// -/// > delete_directory("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_directory") -pub fn delete_directory(a: String) -> Result(Nil, Reason) - -/// Deletes a file or directory recursively. -/// -/// Returns a nil Success or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > recursive_delete("foo") -/// Ok(Nil) -/// -/// > recursive_delete("/bar") -/// Ok(Nil) -/// -/// > recursive_delete("does_not_exist/") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "recursive_delete") -pub fn recursive_delete(a: String) -> Result(Nil, Reason) - -/// Read the contents of the given file as a String -/// -/// Assumes the file is UTF-8 encoded. Returns a Result containing the file's -/// contents as a String if the operation was successful, or Reason if the file -/// operation failed. If the file is not UTF-8 encoded, the `NotUTF8` variant -/// will be returned. -/// -/// ## Examples -/// -/// ```gleam -/// > read("example.txt") -/// Ok("Hello, World!") -/// -/// > read(from: "example.txt") -/// Ok("Hello, World!") -/// -/// > read("does_not_exist.txt") -/// Error(Enoent) -/// -/// > read("cat.gif") -/// Error(NotUTF8) -/// ``` -/// -@deprecated("Use the simplifile package instead?") -pub fn read(from path: String) -> Result(String, Reason) { - path - |> do_read_bits() - |> result.then(fn(content) { - case bit_array.to_string(content) { - Ok(string) -> Ok(string) - Error(Nil) -> Error(NotUtf8) - } - }) -} - -/// Read the contents of the given file as a BitString -/// -/// Returns a Result containing the file's contents as a BitString if the -/// operation was successful, or Reason if the operation failed. -/// -/// ## Examples -/// -/// ```gleam -/// > read_bits("example.txt") -/// Ok(<<"Hello, World!">>) -/// -/// > read_bits(from: "cat.gif") -/// Ok(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// -/// > read_bits("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn read_bits(from path: String) -> Result(BitArray, Reason) { - do_read_bits(path) -} - -@external(erlang, "gleam_erlang_ffi", "read_file") -fn do_read_bits(a: path) -> Result(BitArray, Reason) - -/// Write the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > write(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > write("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_write_bits(path) -} - -/// Write the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > write_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > write_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn write_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_write_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "write_file") -fn do_write_bits(a: BitArray, b: String) -> Result(Nil, Reason) - -/// Append the given String contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append("Hello, World!", "file.txt") -/// Ok(Nil) -/// -/// > append(to: "file.txt", contents: "Hello, World!") -/// Ok(Nil) -/// -/// > append("Hello, World!", "does_not_exist/file.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -pub fn append(contents contents: String, to path: String) -> Result(Nil, Reason) { - contents - |> bit_array.from_string - |> do_append_bits(path) -} - -/// Append the given BitString contents to a file of the given name. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "cat.gif") -/// Ok(Nil) -/// -/// > append_bits(to: "cat.gif", contents: <<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>) -/// Ok(Nil) -/// -/// > append_bits(<<71,73,70,56,57,97,1,0,1,0,0,0,0,59>>, "does_not_exist/cat.gif") -/// Error(Enoent) -/// ``` -/// -pub fn append_bits( - contents contents: BitArray, - to path: String, -) -> Result(Nil, Reason) { - do_append_bits(contents, path) -} - -@external(erlang, "gleam_erlang_ffi", "append_file") -fn do_append_bits( - contents contents: BitArray, - path path: String, -) -> Result(Nil, Reason) - -/// Delete the given file. -/// -/// Returns a Result with Nil if the operation was successful or a Reason -/// otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > delete("file.txt") -/// Ok(Nil) -/// -/// > delete("does_not_exist.txt") -/// Error(Enoent) -/// ``` -/// -@deprecated("Use the simplifile package instead") -@external(erlang, "gleam_erlang_ffi", "delete_file") -pub fn delete(a: String) -> Result(Nil, Reason) diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/node.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/node.gleam deleted file mode 100644 index 339415c..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/node.gleam +++ /dev/null @@ -1,62 +0,0 @@ -import gleam/erlang/atom.{type Atom} - -pub type Node - -type DoNotLeak - -/// Return the current node. -/// -@external(erlang, "erlang", "node") -pub fn self() -> Node - -/// Return a list of all visible nodes in the cluster, not including the current -/// node. -/// -/// The current node can be included by calling `self()` and prepending the -/// result. -/// -/// ```gleam -/// let all_nodes = [node.self(), ..node.visible()] -/// ``` -/// -@external(erlang, "erlang", "nodes") -pub fn visible() -> List(Node) - -pub type ConnectError { - /// Was unable to connect to the node. - FailedToConnect - /// The local node is not alive, so it is not possible to connect to the other - /// node. - LocalNodeIsNotAlive -} - -// TODO: test unknown node -// TODO: test successfully connecting -/// Establish a connection to a node, so the nodes can send messages to each -/// other and any other connected nodes. -/// -/// Returns `Error(FailedToConnect)` if the node is not reachable. -/// -/// Returns `Error(LocalNodeIsNotAlive)` if the local node is not alive, meaning -/// it is not running in distributed mode. -/// -@external(erlang, "gleam_erlang_ffi", "connect_node") -pub fn connect(node: Atom) -> Result(Node, ConnectError) - -// TODO: test -/// Send a message to a named process on a given node. -/// -/// These messages are untyped, like regular Erlang messages. -/// -pub fn send(node: Node, name: Atom, message: message) -> Nil { - raw_send(#(name, node), message) - Nil -} - -@external(erlang, "erlang", "send") -fn raw_send(receiver: #(Atom, Node), message: message) -> DoNotLeak - -/// Convert a node to the atom of its name. -/// -@external(erlang, "gleam_erlang_ffi", "identity") -pub fn to_atom(node: Node) -> Atom diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/os.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/os.gleam deleted file mode 100644 index e135974..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/os.gleam +++ /dev/null @@ -1,95 +0,0 @@ -//// Access to the shell's environment variables - -import gleam/map.{type Map} - -/// Returns the list of all available environment variables as a list of key, -/// tuples. -/// -/// ## Examples -/// -/// > get_all_env() -/// map.from_list([ -/// #("SHELL", "/bin/bash"), -/// #("PWD", "/home/j3rn"), -/// ... -/// ]) -/// -@external(erlang, "gleam_erlang_ffi", "get_all_env") -pub fn get_all_env() -> Map(String, String) - -/// Returns the value associated with the given environment variable name. -/// -/// ## Examples -/// -/// > get_env("SHELL") -/// "/bin/bash" -/// -/// > get_env(name: "PWD") -/// "/home/j3rn" -/// -@external(erlang, "gleam_erlang_ffi", "get_env") -pub fn get_env(name name: String) -> Result(String, Nil) - -/// Associates the given value with the given environment variable name. -/// -/// ## Examples -/// -/// > set_env("MYVAR", "MYVALUE") -/// Nil -/// > get_env("MYVAR") -/// "MYVALUE" -/// -/// > set_env(value: "MYVALUE", name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "set_env") -pub fn set_env(name name: String, value value: String) -> Nil - -/// Removes the environment variable with the given name. -/// -/// Returns Nil regardless of whether the variable ever existed. -/// -/// ## Examples -/// -/// > get_env("MYVAR") -/// Ok("MYVALUE") -/// > unset_env("MYVAR") -/// Nil -/// > get_env("MYVAR") -/// Error(Nil) -/// -/// > unset_env(name: "MYVAR") -/// Nil -/// -@external(erlang, "gleam_erlang_ffi", "unset_env") -pub fn unset_env(name name: String) -> Nil - -/// Represents operating system kernels -pub type OsFamily { - // The family which includes modern versions of the Windows operating system. - WindowsNt - // The family of operating systems based on the open source Linux kernel. - Linux - // The family of Apple operating systems such as macOS and iOS. - Darwin - // The family of operating systems based on the FreeBSD kernel. - FreeBsd - // An operating system kernel other than Linux, Darwin, FreeBSD, or NT. - Other(String) -} - -/// Returns the kernel of the host operating system. -/// -/// Unknown kernels are reported as `Other(String)`; e.g. `Other("sunos")`. -/// -/// ## Examples -/// -/// > family() -/// Linux -/// > family() -/// Darwin -/// > family() -/// Other("sunos") -/// -@external(erlang, "gleam_erlang_ffi", "os_family") -pub fn family() -> OsFamily diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/process.gleam b/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/process.gleam deleted file mode 100644 index f660306..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam/erlang/process.gleam +++ /dev/null @@ -1,744 +0,0 @@ -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang.{type Reference} -import gleam/erlang/atom.{type Atom} - -/// A `Pid` (or Process identifier) is a reference to an Erlang process. Each -/// process has a `Pid` and it is one of the lowest level building blocks of -/// inter-process communication in the Erlang and Gleam OTP frameworks. -/// -pub type Pid - -/// Get the `Pid` for the current process. -@external(erlang, "erlang", "self") -pub fn self() -> Pid - -/// Create a new Erlang process that runs concurrently to the creator. In other -/// languages this might be called a fibre, a green thread, or a coroutine. -/// -/// If `linked` is `True` then the created process is linked to the creator -/// process. When a process terminates an exit signal is sent to all other -/// processes that are linked to it, causing the process to either terminate or -/// have to handle the signal. -/// -/// More can be read about processes and links in the [Erlang documentation][1]. -/// -/// [1]: https://www.erlang.org/doc/reference_manual/processes.html -/// -pub fn start(running implementation: fn() -> anything, linked link: Bool) -> Pid { - case link { - True -> spawn_link(implementation) - False -> spawn(implementation) - } -} - -@external(erlang, "erlang", "spawn") -fn spawn(a: fn() -> anything) -> Pid - -@external(erlang, "erlang", "spawn_link") -fn spawn_link(a: fn() -> anything) -> Pid - -/// A `Subject` is a value that processes can use to send and receive messages -/// to and from each other in a well typed way. -/// -/// Each subject is "owned" by the process that created it. Any process can use -/// the `send` function to sent a message of the correct type to the process -/// that owns the subject, and the owner can use the `receive` function or the -/// `Selector` type to receive these messages. -/// -/// The `Subject` type is similar to the "channel" types found in other -/// languages and the "topic" concept found in some pub-sub systems. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// -/// // Send a message with the subject -/// send(subject, "Hello, Joe!") -/// -/// // Receive the message -/// receive(subject, within: 10) -/// ``` -/// -pub opaque type Subject(message) { - Subject(owner: Pid, tag: Reference) -} - -/// Create a new `Subject` owned by the current process. -/// -pub fn new_subject() -> Subject(message) { - Subject(owner: self(), tag: erlang.make_reference()) -} - -/// Get the owner process for a `Subject`. This is the process that created the -/// `Subject` and will receive messages sent with it. -/// -pub fn subject_owner(subject: Subject(message)) -> Pid { - subject.owner -} - -type DoNotLeak - -@external(erlang, "erlang", "send") -fn raw_send(a: Pid, b: message) -> DoNotLeak - -/// Send a message to a process using a `Subject`. The message must be of the -/// type that the `Subject` accepts. -/// -/// This function does not wait for the `Subject` owner process to call the -/// `receive` function, instead it returns once the message has been placed in -/// the process' mailbox. -/// -/// # Ordering -/// -/// If process P1 sends two messages to process P2 it is guaranteed that process -/// P1 will receive the messages in the order they were sent. -/// -/// If you wish to receive the messages in a different order you can send them -/// on two different subjects and the receiver function can call the `receive` -/// function for each subject in the desired order, or you can write some Erlang -/// code to perform a selective receive. -/// -/// # Examples -/// -/// ```gleam -/// let subject = new_subject() -/// send(subject, "Hello, Joe!") -/// ``` -/// -pub fn send(subject: Subject(message), message: message) -> Nil { - raw_send(subject.owner, #(subject.tag, message)) - Nil -} - -/// Receive a message that has been sent to current process using the `Subject`. -/// -/// If there is not an existing message for the `Subject` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject` can receive a message using -/// it. If a process that does not own the `Subject` attempts to receive with it -/// then it will not receive a message. -/// -/// To wait for messages from multiple `Subject`s at the same time see the -/// `Selector` type. -/// -pub fn receive( - from subject: Subject(message), - within milliseconds: Int, -) -> Result(message, Nil) { - new_selector() - |> selecting(subject, fn(x) { x }) - |> select(within: milliseconds) -} - -/// A type that enables a process to wait for messages from multiple `Subject`s -/// at the same time, returning whichever message arrives first. -/// -/// Used with the `new_selector`, `selecting`, and `select` functions. -/// -/// # Examples -/// -/// ```gleam -/// > let int_subject = new_subject() -/// > let float_subject = new_subject() -/// > send(int_subject, 1) -/// > -/// > let selector = -/// > new_selector() -/// > |> selecting(int_subject, int.to_string) -/// > |> selecting(float_subject, float.to_string) -/// > -/// > select(selector, 10) -/// Ok("1") -/// ``` -/// -pub type Selector(payload) - -/// Create a new `Selector` which can be used to receive messages on multiple -/// `Subject`s at once. -/// -@external(erlang, "gleam_erlang_ffi", "new_selector") -pub fn new_selector() -> Selector(payload) - -/// Receive a message that has been sent to current process using any of the -/// `Subject`s that have been added to the `Selector` with the `selecting` -/// function. -/// -/// If there is not an existing message for the `Selector` in the process' -/// mailbox or one does not arrive `within` the permitted timeout then the -/// `Error(Nil)` is returned. -/// -/// Only the process that is owner of the `Subject`s can receive a message using -/// them. If a process that does not own the a `Subject` attempts to receive -/// with it then it will not receive a message. -/// -/// To wait forever for the next message rather than for a limited amount of -/// time see the `select_forever` function. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select( - from from: Selector(payload), - within within: Int, -) -> Result(payload, Nil) - -/// Similar to the `select` function but will wait forever for a message to -/// arrive rather than timing out after a specified amount of time. -/// -@external(erlang, "gleam_erlang_ffi", "select") -pub fn select_forever(from from: Selector(payload)) -> payload - -/// Add a transformation function to a selector. When a message is received -/// using this selector the transformation function is applied to the message. -/// -/// This function can be used to change the type of messages received and may -/// be useful when combined with the `merge_selector` function. -/// -@external(erlang, "gleam_erlang_ffi", "map_selector") -pub fn map_selector(a: Selector(a), b: fn(a) -> b) -> Selector(b) - -/// Merge one selector into another, producing a selector that contains the -/// message handlers of both. -/// -/// If a subject is handled by both selectors the handler function of the -/// second selector is used. -/// -@external(erlang, "gleam_erlang_ffi", "merge_selector") -pub fn merge_selector(a: Selector(a), b: Selector(a)) -> Selector(a) - -pub type ExitMessage { - ExitMessage(pid: Pid, reason: ExitReason) -} - -pub type ExitReason { - Normal - Killed - Abnormal(reason: String) -} - -/// Add a handler for trapped exit messages. In order for these messages to be -/// sent to the process when a linked process exits the process must call the -/// `trap_exit` beforehand. -/// -pub fn selecting_trapped_exits( - selector: Selector(a), - handler: fn(ExitMessage) -> a, -) -> Selector(a) { - let tag = atom.create_from_string("EXIT") - let handler = fn(message: #(Atom, Pid, Dynamic)) -> a { - let reason = message.2 - let normal = dynamic.from(Normal) - let killed = dynamic.from(Killed) - let reason = case dynamic.string(reason) { - _ if reason == normal -> Normal - _ if reason == killed -> Killed - Ok(reason) -> Abnormal(reason) - Error(_) -> Abnormal(string.inspect(reason)) - } - handler(ExitMessage(message.1, reason)) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -// TODO: implement in Gleam -/// Discard all messages in the current process' mailbox. -/// -/// Warning: This function may cause other processes to crash if they sent a -/// message to the current process and are waiting for a response, so use with -/// caution. -/// -@external(erlang, "gleam_erlang_ffi", "flush_messages") -pub fn flush_messages() -> Nil - -/// Add a new `Subject` to the `Selector` to that it's messages can be received. -/// -/// The `mapping` function provided with the `Subject` can be used to convert -/// the type of messages received using this `Subject`. This is useful for when -/// you wish to add multiple `Subject`s to a `Seletor` when they have differing -/// message types. If you do not wish to transform the incoming messages in any -/// way then the `identity` function can be given. -/// -pub fn selecting( - selector: Selector(payload), - for subject: Subject(message), - mapping transform: fn(message) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(Reference, message)) { transform(message.1) } - insert_selector_handler(selector, #(subject.tag, 2), handler) -} - -/// Add a handler to a selector for 2 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record2( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic)) { transform(message.1) } - insert_selector_handler(selector, #(tag, 2), handler) -} - -/// Add a handler to a selector for 3 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record3( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic)) { - transform(message.1, message.2) - } - insert_selector_handler(selector, #(tag, 3), handler) -} - -/// Add a handler to a selector for 4 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record4( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3) - } - insert_selector_handler(selector, #(tag, 4), handler) -} - -/// Add a handler to a selector for 5 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record5( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4) - } - insert_selector_handler(selector, #(tag, 5), handler) -} - -/// Add a handler to a selector for 6 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record6( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> payload, -) -> Selector(payload) { - let handler = fn(message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic)) { - transform(message.1, message.2, message.3, message.4, message.5) - } - insert_selector_handler(selector, #(tag, 6), handler) -} - -/// Add a handler to a selector for 7 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record7( - selector: Selector(payload), - tag: tag, - mapping transform: fn(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #(tag, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - ) { - transform(message.1, message.2, message.3, message.4, message.5, message.6) - } - insert_selector_handler(selector, #(tag, 7), handler) -} - -/// Add a handler to a selector for 8 element tuple messages with a given tag -/// element in the first position. -/// -/// Typically you want to use the `selecting` function with a `Subject` instead, -/// but this function may be useful if you need to receive messages sent from -/// other BEAM languages that do not use the `Subject` type. -/// -pub fn selecting_record8( - selector: Selector(payload), - tag: tag, - mapping transform: fn( - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ) -> - payload, -) -> Selector(payload) { - let handler = fn( - message: #( - tag, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - Dynamic, - ), - ) { - transform( - message.1, - message.2, - message.3, - message.4, - message.5, - message.6, - message.7, - ) - } - insert_selector_handler(selector, #(tag, 8), handler) -} - -type AnythingSelectorTag { - Anything -} - -/// Add a catch-all handler to a selector that will be used when no other -/// handler in a selector is suitable for a given message. -/// -/// This may be useful for when you want to ensure that any message in the inbox -/// is handled, or when you need to handle messages from other BEAM languages -/// which do not use subjects or record format messages. -/// -pub fn selecting_anything( - selector: Selector(payload), - mapping handler: fn(Dynamic) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, Anything, handler) -} - -@external(erlang, "gleam_erlang_ffi", "insert_selector_handler") -fn insert_selector_handler( - a: Selector(payload), - for for: tag, - mapping mapping: fn(message) -> payload, -) -> Selector(payload) - -/// Suspends the process calling this function for the specified number of -/// milliseconds. -/// -@external(erlang, "gleam_erlang_ffi", "sleep") -pub fn sleep(a: Int) -> Nil - -/// Suspends the process forever! This may be useful for suspending the main -/// process in a Gleam program when it has no more work to do but we want other -/// processes to continue to work. -/// -@external(erlang, "gleam_erlang_ffi", "sleep_forever") -pub fn sleep_forever() -> Nil - -/// Check to see whether the process for a given `Pid` is alive. -/// -/// See the [Erlang documentation][1] for more information. -/// -/// [1]: http://erlang.org/doc/man/erlang.html#is_process_alive-1 -/// -@external(erlang, "erlang", "is_process_alive") -pub fn is_alive(a: Pid) -> Bool - -type ProcessMonitorFlag { - Process -} - -@external(erlang, "erlang", "monitor") -fn erlang_monitor_process(a: ProcessMonitorFlag, b: Pid) -> Reference - -pub opaque type ProcessMonitor { - ProcessMonitor(tag: Reference) -} - -/// A message received when a monitored process exits. -/// -pub type ProcessDown { - ProcessDown(pid: Pid, reason: Dynamic) -} - -/// Start monitoring a process so that when the monitored process exits a -/// message is sent to the monitoring process. -/// -/// The message is only sent once, when the target process exits. If the -/// process was not alive when this function is called the message will never -/// be received. -/// -/// The down message can be received with a `Selector` and the -/// `selecting_process_down` function. -/// -/// The process can be demonitored with the `demonitor_process` function. -/// -pub fn monitor_process(pid: Pid) -> ProcessMonitor { - Process - |> erlang_monitor_process(pid) - |> ProcessMonitor -} - -/// Add a `ProcessMonitor` to a `Selector` so that the `ProcessDown` message can -/// be received using the `Selector` and the `select` function. -/// -pub fn selecting_process_down( - selector: Selector(payload), - monitor: ProcessMonitor, - mapping: fn(ProcessDown) -> payload, -) -> Selector(payload) { - insert_selector_handler(selector, monitor.tag, mapping) -} - -/// Remove the monitor for a process so that when the monitor process exits a -/// `ProcessDown` message is not sent to the monitoring process. -/// -/// If the message has already been sent it is removed from the monitoring -/// process' mailbox. -/// -@external(erlang, "gleam_erlang_ffi", "demonitor") -pub fn demonitor_process(monitor monitor: ProcessMonitor) -> Nil - -/// An error returned when making a call to a process. -/// -pub type CallError(msg) { - /// The process being called exited before it sent a response. - /// - CalleeDown(reason: Dynamic) - - /// The process being called did not response within the permitted amount of - /// time. - /// - CallTimeout -} - -// This function is based off of Erlang's gen:do_call/4. -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time then an error is returned. -/// -pub fn try_call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> Result(response, CallError(response)) { - let reply_subject = new_subject() - - // Monitor the callee process so we can tell if it goes down (meaning we - // won't get a reply) - let monitor = monitor_process(subject_owner(subject)) - - // Send the request to the process over the channel - send(subject, make_request(reply_subject)) - - // Await a reply or handle failure modes (timeout, process down, etc) - let result = - new_selector() - |> selecting(reply_subject, Ok) - |> selecting_process_down( - monitor, - fn(down: ProcessDown) { Error(CalleeDown(reason: down.reason)) }, - ) - |> select(timeout) - - // Demonitor the process and close the channels as we're done - demonitor_process(monitor) - - // Prepare an appropriate error (if present) for the caller - case result { - Error(Nil) -> Error(CallTimeout) - Ok(res) -> res - } -} - -/// Send a message to a process and wait for a reply. -/// -/// If the receiving process exits or does not reply within the allowed amount -/// of time the calling process crashes. If you wish an error to be returned -/// instead see the `try_call` function. -/// -pub fn call( - subject: Subject(request), - make_request: fn(Subject(response)) -> request, - within timeout: Int, -) -> response { - let assert Ok(resp) = try_call(subject, make_request, timeout) - resp -} - -/// Creates a link between the calling process and another process. -/// -/// When a process crashes any linked processes will also crash. This is useful -/// to ensure that groups of processes that depend on each other all either -/// succeed or fail together. -/// -/// Returns `True` if the link was created successfully, returns `False` if the -/// process was not alive and as such could not be linked. -/// -@external(erlang, "gleam_erlang_ffi", "link") -pub fn link(pid pid: Pid) -> Bool - -@external(erlang, "erlang", "unlink") -fn erlang_unlink(pid pid: Pid) -> Bool - -/// Removes any existing link between the caller process and the target process. -/// -pub fn unlink(pid: Pid) -> Nil { - erlang_unlink(pid) - Nil -} - -pub type Timer - -@external(erlang, "erlang", "send_after") -fn erlang_send_after(a: Int, b: Pid, c: msg) -> Timer - -/// Send a message over a channel after a specified number of milliseconds. -/// -pub fn send_after(subject: Subject(msg), delay: Int, message: msg) -> Timer { - erlang_send_after(delay, subject.owner, #(subject.tag, message)) -} - -@external(erlang, "erlang", "cancel_timer") -fn erlang_cancel_timer(a: Timer) -> Dynamic - -/// Values returned when a timer is cancelled. -/// -pub type Cancelled { - /// The timer could not be found. It likely has already triggered. - /// - TimerNotFound - - /// The timer was found and cancelled before it triggered. - /// - /// The amount of remaining time before the timer was due to be triggered is - /// returned in milliseconds. - /// - Cancelled(time_remaining: Int) -} - -/// Cancel a given timer, causing it not to trigger if it has not done already. -/// -pub fn cancel_timer(timer: Timer) -> Cancelled { - case dynamic.int(erlang_cancel_timer(timer)) { - Ok(i) -> Cancelled(i) - Error(_) -> TimerNotFound - } -} - -type KillFlag { - Kill -} - -@external(erlang, "erlang", "exit") -fn erlang_kill(to to: Pid, because because: KillFlag) -> Bool - -// Go, my pretties. Kill! Kill! -// - Bart Simpson -// -/// Send an untrappable `kill` exit signal to the target process. -/// -/// See the documentation for the Erlang [`erlang:exit`][1] function for more -/// information. -/// -/// [1]: https://erlang.org/doc/man/erlang.html#exit-1 -/// -pub fn kill(pid: Pid) -> Nil { - erlang_kill(pid, Kill) - Nil -} - -@external(erlang, "erlang", "exit") -fn erlang_send_exit(to to: Pid, because because: whatever) -> Bool - -// TODO: test -/// Sends an exit signal to a process, indicating that the process is to shut -/// down. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_exit(to pid: Pid) -> Nil { - erlang_send_exit(pid, Normal) - Nil -} - -/// Sends an exit signal to a process, indicating that the process is to shut -/// down due to an abnormal reason such as a failure. -/// -/// See the [Erlang documentation][erl] for more information. -/// [erl]: http://erlang.org/doc/man/erlang.html#exit-2 -/// -pub fn send_abnormal_exit(pid: Pid, reason: String) -> Nil { - erlang_send_exit(pid, Abnormal(reason)) - Nil -} - -/// Set whether the current process is to trap exit signals or not. -/// -/// When not trapping exits if a linked process crashes the exit signal -/// propagates to the process which will also crash. -/// This is the normal behaviour before this function is called. -/// -/// When trapping exits (after this function is called) if a linked process -/// crashes an exit message is sent to the process instead. These messages can -/// be handled with the `selecting_trapped_exits` function. -/// -@external(erlang, "gleam_erlang_ffi", "trap_exits") -pub fn trap_exits(a: Bool) -> Nil - -/// Register a process under a given name, allowing it to be looked up using -/// the `named` function. -/// -/// This function will return an error under the following conditions: -/// - The process for the pid no longer exists. -/// - The name has already been registered. -/// - The process already has a name. -/// - The name is the atom `undefined`, which is reserved by Erlang. -/// -@external(erlang, "gleam_erlang_ffi", "register_process") -pub fn register(pid: Pid, name: Atom) -> Result(Nil, Nil) - -/// Un-register a process name, after which the process can no longer be looked -/// up by that name, and both the name and the process can be re-used in other -/// registrations. -/// -/// It is possible to un-register process that are not from your application, -/// including those from Erlang/OTP itself. This is not recommended and will -/// likely result in undesirable behaviour and crashes. -/// -@external(erlang, "gleam_erlang_ffi", "unregister_process") -pub fn unregister(name: Atom) -> Result(Nil, Nil) - -/// Look up a process by name, returning the pid if it exists. -/// -@external(erlang, "gleam_erlang_ffi", "process_named") -pub fn named(name: Atom) -> Result(Pid, Nil) diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang.erl deleted file mode 100644 index 14a5538..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(gleam@erlang). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([format/1, term_to_binary/1, get_line/1, system_time/1, erlang_timestamp/0, rescue/1, binary_to_term/1, unsafe_binary_to_term/1, start_arguments/0, ensure_all_started/1, make_reference/0, priv_directory/1]). --export_type([safe/0, get_line_error/0, time_unit/0, crash/0, ensure_all_started_error/0, reference_/0]). - --type safe() :: safe. - --type get_line_error() :: eof | no_data. - --type time_unit() :: second | millisecond | microsecond | nanosecond. - --type crash() :: {exited, gleam@dynamic:dynamic_()} | - {thrown, gleam@dynamic:dynamic_()} | - {errored, gleam@dynamic:dynamic_()}. - --type ensure_all_started_error() :: {unknown_application, - gleam@erlang@atom:atom_()} | - {application_failed_to_start, - gleam@erlang@atom:atom_(), - gleam@dynamic:dynamic_()}. - --type reference_() :: any(). - --spec format(any()) -> binary(). -format(Term) -> - unicode:characters_to_binary(io_lib:format(<<"~p"/utf8>>, [Term])). - --spec term_to_binary(any()) -> bitstring(). -term_to_binary(A) -> - erlang:term_to_binary(A). - --spec get_line(binary()) -> {ok, binary()} | {error, get_line_error()}. -get_line(Prompt) -> - gleam_erlang_ffi:get_line(Prompt). - --spec system_time(time_unit()) -> integer(). -system_time(A) -> - os:system_time(A). - --spec erlang_timestamp() -> {integer(), integer(), integer()}. -erlang_timestamp() -> - os:timestamp(). - --spec rescue(fun(() -> FHH)) -> {ok, FHH} | {error, crash()}. -rescue(A) -> - gleam_erlang_ffi:rescue(A). - --spec binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue( - fun() -> erlang:binary_to_term(Binary, [safe]) end - ) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec unsafe_binary_to_term(bitstring()) -> {ok, gleam@dynamic:dynamic_()} | - {error, nil}. -unsafe_binary_to_term(Binary) -> - case gleam_erlang_ffi:rescue(fun() -> erlang:binary_to_term(Binary, []) end) of - {ok, Term} -> - {ok, Term}; - - {error, _} -> - {error, nil} - end. - --spec start_arguments() -> list(binary()). -start_arguments() -> - _pipe = init:get_plain_arguments(), - gleam@list:map(_pipe, fun unicode:characters_to_binary/1). - --spec ensure_all_started(gleam@erlang@atom:atom_()) -> {ok, - list(gleam@erlang@atom:atom_())} | - {error, ensure_all_started_error()}. -ensure_all_started(Application) -> - gleam_erlang_ffi:ensure_all_started(Application). - --spec make_reference() -> reference_(). -make_reference() -> - erlang:make_ref(). - --spec priv_directory(binary()) -> {ok, binary()} | {error, nil}. -priv_directory(Name) -> - gleam_erlang_ffi:priv_directory(Name). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@atom.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@atom.erl deleted file mode 100644 index e9ad530..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@atom.erl +++ /dev/null @@ -1,26 +0,0 @@ --module(gleam@erlang@atom). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, create_from_string/1, to_string/1, from_dynamic/1]). --export_type([atom_/0, from_string_error/0]). - --type atom_() :: any(). - --type from_string_error() :: atom_not_loaded. - --spec from_string(binary()) -> {ok, atom_()} | {error, from_string_error()}. -from_string(A) -> - gleam_erlang_ffi:atom_from_string(A). - --spec create_from_string(binary()) -> atom_(). -create_from_string(A) -> - erlang:binary_to_atom(A). - --spec to_string(atom_()) -> binary(). -to_string(A) -> - erlang:atom_to_binary(A). - --spec from_dynamic(gleam@dynamic:dynamic_()) -> {ok, atom_()} | - {error, list(gleam@dynamic:decode_error())}. -from_dynamic(From) -> - gleam_erlang_ffi:atom_from_dynamic(From). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl deleted file mode 100644 index 9f9c0fa..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@charlist.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(gleam@erlang@charlist). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_string/1, from_string/1]). --export_type([charlist/0]). - --type charlist() :: any(). - --spec to_string(charlist()) -> binary(). -to_string(A) -> - unicode:characters_to_binary(A). - --spec from_string(binary()) -> charlist(). -from_string(A) -> - unicode:characters_to_list(A). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@file.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@file.erl deleted file mode 100644 index 1fe6628..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@file.erl +++ /dev/null @@ -1,190 +0,0 @@ --module(gleam@erlang@file). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([file_info/1, link_info/1, is_directory/1, is_regular/1, file_exists/1, link_exists/1, make_directory/1, list_directory/1, delete_directory/1, recursive_delete/1, read/1, read_bits/1, write/2, write_bits/2, append/2, append_bits/2, delete/1]). --export_type([reason/0, file_type/0, access/0, file_info/0]). - --type reason() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8. - --type file_type() :: device | directory | other | regular | symlink. - --type access() :: no_access | read | read_write | write. - --type file_info() :: {file_info, - integer(), - file_type(), - access(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer(), - integer()}. - --spec file_info(binary()) -> {ok, file_info()} | {error, reason()}. -file_info(A) -> - gleam_erlang_ffi:file_info(A). - --spec link_info(binary()) -> {ok, file_info()} | {error, reason()}. -link_info(A) -> - gleam_erlang_ffi:link_info(A). - --spec is_directory(binary()) -> {ok, boolean()} | {error, reason()}. -is_directory(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= directory - end - ). - --spec is_regular(binary()) -> {ok, boolean()} | {error, reason()}. -is_regular(Path) -> - gleam@result:map( - gleam_erlang_ffi:file_info(Path), - fun(_use0) -> - {file_info, _, File_type, _, _, _, _, _, _, _, _, _, _, _} = _use0, - File_type =:= regular - end - ). - --spec file_exists(binary()) -> {ok, boolean()} | {error, reason()}. -file_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:file_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec link_exists(binary()) -> {ok, boolean()} | {error, reason()}. -link_exists(Path) -> - Result = begin - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:link_info(_pipe), - gleam@result:replace(_pipe@1, true) - end, - case Result of - {error, enoent} -> - {ok, false}; - - _ -> - Result - end. - --spec make_directory(binary()) -> {ok, nil} | {error, reason()}. -make_directory(A) -> - gleam_erlang_ffi:make_directory(A). - --spec list_directory(binary()) -> {ok, list(binary())} | {error, reason()}. -list_directory(A) -> - gleam_erlang_ffi:list_directory(A). - --spec delete_directory(binary()) -> {ok, nil} | {error, reason()}. -delete_directory(A) -> - gleam_erlang_ffi:delete_directory(A). - --spec recursive_delete(binary()) -> {ok, nil} | {error, reason()}. -recursive_delete(A) -> - gleam_erlang_ffi:recursive_delete(A). - --spec read(binary()) -> {ok, binary()} | {error, reason()}. -read(Path) -> - _pipe = Path, - _pipe@1 = gleam_erlang_ffi:read_file(_pipe), - gleam@result:then( - _pipe@1, - fun(Content) -> case gleam@bit_array:to_string(Content) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, not_utf8} - end end - ). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, reason()}. -read_bits(Path) -> - gleam_erlang_ffi:read_file(Path). - --spec write(binary(), binary()) -> {ok, nil} | {error, reason()}. -write(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:write_file(_pipe@1, Path). - --spec write_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -write_bits(Contents, Path) -> - gleam_erlang_ffi:write_file(Contents, Path). - --spec append(binary(), binary()) -> {ok, nil} | {error, reason()}. -append(Contents, Path) -> - _pipe = Contents, - _pipe@1 = gleam_stdlib:identity(_pipe), - gleam_erlang_ffi:append_file(_pipe@1, Path). - --spec append_bits(bitstring(), binary()) -> {ok, nil} | {error, reason()}. -append_bits(Contents, Path) -> - gleam_erlang_ffi:append_file(Contents, Path). - --spec delete(binary()) -> {ok, nil} | {error, reason()}. -delete(A) -> - gleam_erlang_ffi:delete_file(A). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@node.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@node.erl deleted file mode 100644 index f57d029..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@node.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@erlang@node). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, visible/0, connect/1, send/3, to_atom/1]). --export_type([node_/0, do_not_leak/0, connect_error/0]). - --type node_() :: any(). - --type do_not_leak() :: any(). - --type connect_error() :: failed_to_connect | local_node_is_not_alive. - --spec self() -> node_(). -self() -> - erlang:node(). - --spec visible() -> list(node_()). -visible() -> - erlang:nodes(). - --spec connect(gleam@erlang@atom:atom_()) -> {ok, node_()} | - {error, connect_error()}. -connect(Node) -> - gleam_erlang_ffi:connect_node(Node). - --spec send(node_(), gleam@erlang@atom:atom_(), any()) -> nil. -send(Node, Name, Message) -> - erlang:send({Name, Node}, Message), - nil. - --spec to_atom(node_()) -> gleam@erlang@atom:atom_(). -to_atom(Node) -> - gleam_erlang_ffi:identity(Node). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@os.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@os.erl deleted file mode 100644 index 6604255..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@os.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@erlang@os). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get_all_env/0, get_env/1, set_env/2, unset_env/1, family/0]). --export_type([os_family/0]). - --type os_family() :: windows_nt | linux | darwin | free_bsd | {other, binary()}. - --spec get_all_env() -> gleam@map:map_(binary(), binary()). -get_all_env() -> - gleam_erlang_ffi:get_all_env(). - --spec get_env(binary()) -> {ok, binary()} | {error, nil}. -get_env(Name) -> - gleam_erlang_ffi:get_env(Name). - --spec set_env(binary(), binary()) -> nil. -set_env(Name, Value) -> - gleam_erlang_ffi:set_env(Name, Value). - --spec unset_env(binary()) -> nil. -unset_env(Name) -> - gleam_erlang_ffi:unset_env(Name). - --spec family() -> os_family(). -family() -> - gleam_erlang_ffi:os_family(). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@process.erl b/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@process.erl deleted file mode 100644 index fc8e0ff..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam@erlang@process.erl +++ /dev/null @@ -1,374 +0,0 @@ --module(gleam@erlang@process). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([self/0, start/2, new_subject/0, subject_owner/1, send/2, new_selector/0, select/2, select_forever/1, map_selector/2, merge_selector/2, flush_messages/0, selecting_trapped_exits/2, selecting/3, 'receive'/2, selecting_record2/3, selecting_record3/3, selecting_record4/3, selecting_record5/3, selecting_record6/3, selecting_record7/3, selecting_record8/3, selecting_anything/2, sleep/1, sleep_forever/0, is_alive/1, monitor_process/1, selecting_process_down/3, demonitor_process/1, try_call/3, call/3, link/1, unlink/1, send_after/3, cancel_timer/1, kill/1, send_exit/1, send_abnormal_exit/2, trap_exits/1, register/2, unregister/1, named/1]). --export_type([pid_/0, subject/1, do_not_leak/0, selector/1, exit_message/0, exit_reason/0, anything_selector_tag/0, process_monitor_flag/0, process_monitor/0, process_down/0, call_error/1, timer/0, cancelled/0, kill_flag/0]). - --type pid_() :: any(). - --opaque subject(FJD) :: {subject, pid_(), gleam@erlang:reference_()} | - {gleam_phantom, FJD}. - --type do_not_leak() :: any(). - --type selector(FJE) :: any() | {gleam_phantom, FJE}. - --type exit_message() :: {exit_message, pid_(), exit_reason()}. - --type exit_reason() :: normal | killed | {abnormal, binary()}. - --type anything_selector_tag() :: anything. - --type process_monitor_flag() :: process. - --opaque process_monitor() :: {process_monitor, gleam@erlang:reference_()}. - --type process_down() :: {process_down, pid_(), gleam@dynamic:dynamic_()}. - --type call_error(FJF) :: {callee_down, gleam@dynamic:dynamic_()} | - call_timeout | - {gleam_phantom, FJF}. - --type timer() :: any(). - --type cancelled() :: timer_not_found | {cancelled, integer()}. - --type kill_flag() :: kill. - --spec self() -> pid_(). -self() -> - erlang:self(). - --spec start(fun(() -> any()), boolean()) -> pid_(). -start(Implementation, Link) -> - case Link of - true -> - erlang:spawn_link(Implementation); - - false -> - erlang:spawn(Implementation) - end. - --spec new_subject() -> subject(any()). -new_subject() -> - {subject, erlang:self(), erlang:make_ref()}. - --spec subject_owner(subject(any())) -> pid_(). -subject_owner(Subject) -> - erlang:element(2, Subject). - --spec send(subject(FJO), FJO) -> nil. -send(Subject, Message) -> - erlang:send( - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ), - nil. - --spec new_selector() -> selector(any()). -new_selector() -> - gleam_erlang_ffi:new_selector(). - --spec select(selector(FJW), integer()) -> {ok, FJW} | {error, nil}. -select(From, Within) -> - gleam_erlang_ffi:select(From, Within). - --spec select_forever(selector(FKA)) -> FKA. -select_forever(From) -> - gleam_erlang_ffi:select(From). - --spec map_selector(selector(FKC), fun((FKC) -> FKE)) -> selector(FKE). -map_selector(A, B) -> - gleam_erlang_ffi:map_selector(A, B). - --spec merge_selector(selector(FKG), selector(FKG)) -> selector(FKG). -merge_selector(A, B) -> - gleam_erlang_ffi:merge_selector(A, B). - --spec flush_messages() -> nil. -flush_messages() -> - gleam_erlang_ffi:flush_messages(). - --spec selecting_trapped_exits(selector(FKK), fun((exit_message()) -> FKK)) -> selector(FKK). -selecting_trapped_exits(Selector, Handler) -> - Tag = erlang:binary_to_atom(<<"EXIT"/utf8>>), - Handler@1 = fun(Message) -> - Reason = erlang:element(3, Message), - Normal = gleam@dynamic:from(normal), - Killed = gleam@dynamic:from(killed), - Reason@2 = case gleam@dynamic:string(Reason) of - _ when Reason =:= Normal -> - normal; - - _ when Reason =:= Killed -> - killed; - - {ok, Reason@1} -> - {abnormal, Reason@1}; - - {error, _} -> - {abnormal, gleam@string:inspect(Reason)} - end, - Handler({exit_message, erlang:element(2, Message), Reason@2}) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler@1). - --spec selecting(selector(FKN), subject(FKP), fun((FKP) -> FKN)) -> selector(FKN). -selecting(Selector, Subject, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler( - Selector, - {erlang:element(3, Subject), 2}, - Handler - ). - --spec 'receive'(subject(FJQ), integer()) -> {ok, FJQ} | {error, nil}. -'receive'(Subject, Milliseconds) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting(_pipe, Subject, fun(X) -> X end), - gleam_erlang_ffi:select(_pipe@1, Milliseconds). - --spec selecting_record2( - selector(FKS), - any(), - fun((gleam@dynamic:dynamic_()) -> FKS) -) -> selector(FKS). -selecting_record2(Selector, Tag, Transform) -> - Handler = fun(Message) -> Transform(erlang:element(2, Message)) end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 2}, Handler). - --spec selecting_record3( - selector(FKW), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FKW) -) -> selector(FKW). -selecting_record3(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform(erlang:element(2, Message), erlang:element(3, Message)) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 3}, Handler). - --spec selecting_record4( - selector(FLA), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLA) -) -> selector(FLA). -selecting_record4(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 4}, Handler). - --spec selecting_record5( - selector(FLE), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLE) -) -> selector(FLE). -selecting_record5(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 5}, Handler). - --spec selecting_record6( - selector(FLI), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLI) -) -> selector(FLI). -selecting_record6(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 6}, Handler). - --spec selecting_record7( - selector(FLM), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLM) -) -> selector(FLM). -selecting_record7(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 7}, Handler). - --spec selecting_record8( - selector(FLQ), - any(), - fun((gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_(), gleam@dynamic:dynamic_()) -> FLQ) -) -> selector(FLQ). -selecting_record8(Selector, Tag, Transform) -> - Handler = fun(Message) -> - Transform( - erlang:element(2, Message), - erlang:element(3, Message), - erlang:element(4, Message), - erlang:element(5, Message), - erlang:element(6, Message), - erlang:element(7, Message), - erlang:element(8, Message) - ) - end, - gleam_erlang_ffi:insert_selector_handler(Selector, {Tag, 8}, Handler). - --spec selecting_anything(selector(FLU), fun((gleam@dynamic:dynamic_()) -> FLU)) -> selector(FLU). -selecting_anything(Selector, Handler) -> - gleam_erlang_ffi:insert_selector_handler(Selector, anything, Handler). - --spec sleep(integer()) -> nil. -sleep(A) -> - gleam_erlang_ffi:sleep(A). - --spec sleep_forever() -> nil. -sleep_forever() -> - gleam_erlang_ffi:sleep_forever(). - --spec is_alive(pid_()) -> boolean(). -is_alive(A) -> - erlang:is_process_alive(A). - --spec monitor_process(pid_()) -> process_monitor(). -monitor_process(Pid) -> - _pipe = process, - _pipe@1 = erlang:monitor(_pipe, Pid), - {process_monitor, _pipe@1}. - --spec selecting_process_down( - selector(FMC), - process_monitor(), - fun((process_down()) -> FMC) -) -> selector(FMC). -selecting_process_down(Selector, Monitor, Mapping) -> - gleam_erlang_ffi:insert_selector_handler( - Selector, - erlang:element(2, Monitor), - Mapping - ). - --spec demonitor_process(process_monitor()) -> nil. -demonitor_process(Monitor) -> - gleam_erlang_ffi:demonitor(Monitor). - --spec try_call(subject(FMF), fun((subject(FMH)) -> FMF), integer()) -> {ok, FMH} | - {error, call_error(FMH)}. -try_call(Subject, Make_request, Timeout) -> - Reply_subject = new_subject(), - Monitor = monitor_process(subject_owner(Subject)), - send(Subject, Make_request(Reply_subject)), - Result = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = selecting( - _pipe, - Reply_subject, - fun(Field@0) -> {ok, Field@0} end - ), - _pipe@2 = selecting_process_down( - _pipe@1, - Monitor, - fun(Down) -> {error, {callee_down, erlang:element(3, Down)}} end - ), - gleam_erlang_ffi:select(_pipe@2, Timeout) - end, - gleam_erlang_ffi:demonitor(Monitor), - case Result of - {error, nil} -> - {error, call_timeout}; - - {ok, Res} -> - Res - end. - --spec call(subject(FMM), fun((subject(FMO)) -> FMM), integer()) -> FMO. -call(Subject, Make_request, Timeout) -> - _assert_subject = try_call(Subject, Make_request, Timeout), - {ok, Resp} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/erlang/process"/utf8>>, - function => <<"call"/utf8>>, - line => 593}) - end, - Resp. - --spec link(pid_()) -> boolean(). -link(Pid) -> - gleam_erlang_ffi:link(Pid). - --spec unlink(pid_()) -> nil. -unlink(Pid) -> - erlang:unlink(Pid), - nil. - --spec send_after(subject(FMR), integer(), FMR) -> timer(). -send_after(Subject, Delay, Message) -> - erlang:send_after( - Delay, - erlang:element(2, Subject), - {erlang:element(3, Subject), Message} - ). - --spec cancel_timer(timer()) -> cancelled(). -cancel_timer(Timer) -> - case gleam@dynamic:int(erlang:cancel_timer(Timer)) of - {ok, I} -> - {cancelled, I}; - - {error, _} -> - timer_not_found - end. - --spec kill(pid_()) -> nil. -kill(Pid) -> - erlang:exit(Pid, kill), - nil. - --spec send_exit(pid_()) -> nil. -send_exit(Pid) -> - erlang:exit(Pid, normal), - nil. - --spec send_abnormal_exit(pid_(), binary()) -> nil. -send_abnormal_exit(Pid, Reason) -> - erlang:exit(Pid, {abnormal, Reason}), - nil. - --spec trap_exits(boolean()) -> nil. -trap_exits(A) -> - gleam_erlang_ffi:trap_exits(A). - --spec register(pid_(), gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -register(Pid, Name) -> - gleam_erlang_ffi:register_process(Pid, Name). - --spec unregister(gleam@erlang@atom:atom_()) -> {ok, nil} | {error, nil}. -unregister(Name) -> - gleam_erlang_ffi:unregister_process(Name). - --spec named(gleam@erlang@atom:atom_()) -> {ok, pid_()} | {error, nil}. -named(Name) -> - gleam_erlang_ffi:process_named(Name). diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam_erlang.app.src b/aoc2023/build/packages/gleam_erlang/src/gleam_erlang.app.src deleted file mode 100644 index bb1b8e6..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam_erlang.app.src +++ /dev/null @@ -1,14 +0,0 @@ -{application, gleam_erlang, [ - {vsn, "0.23.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A Gleam library for working with Erlang"}, - {modules, [gleam@erlang, - gleam@erlang@atom, - gleam@erlang@charlist, - gleam@erlang@file, - gleam@erlang@node, - gleam@erlang@os, - gleam@erlang@process]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl b/aoc2023/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl deleted file mode 100644 index 872126f..0000000 --- a/aoc2023/build/packages/gleam_erlang/src/gleam_erlang_ffi.erl +++ /dev/null @@ -1,263 +0,0 @@ --module(gleam_erlang_ffi). --export([ - atom_from_dynamic/1, rescue/1, atom_from_string/1, get_line/1, - ensure_all_started/1, sleep/1, os_family/0, sleep_forever/0, read_file/1, - append_file/2, write_file/2, delete_file/1, get_all_env/0, get_env/1, - set_env/2, unset_env/1, delete_directory/1, recursive_delete/1, - list_directory/1, demonitor/1, make_directory/1, new_selector/0, link/1, - insert_selector_handler/3, select/1, select/2, trap_exits/1, map_selector/2, - merge_selector/2, flush_messages/0, file_info/1, link_info/1, - priv_directory/1, connect_node/1, register_process/2, unregister_process/1, - process_named/1, identity/1 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - --spec atom_from_string(binary()) -> {ok, atom()} | {error, atom_not_loaded}. -atom_from_string(S) -> - try {ok, binary_to_existing_atom(S)} - catch error:badarg -> {error, atom_not_loaded} - end. - -atom_from_dynamic(Data) when is_atom(Data) -> - {ok, Data}; -atom_from_dynamic(Data) -> - {error, [{decode_error, <<"Atom">>, gleam@dynamic:classify(Data), []}]}. - --spec get_line(io:prompt()) -> {ok, unicode:unicode_binary()} | {error, eof | no_data}. -get_line(Prompt) -> - case io:get_line(Prompt) of - eof -> {error, eof}; - {error, _} -> {error, no_data}; - Data when is_binary(Data) -> {ok, Data}; - Data when is_list(Data) -> {ok, unicode:characters_to_binary(Data)} - end. - -rescue(F) -> - try {ok, F()} - catch - throw:X -> {error, {thrown, X}}; - error:X -> {error, {errored, X}}; - exit:X -> {error, {exited, X}} - end. - -ensure_all_started(Application) -> - case application:ensure_all_started(Application) of - {ok, _} = Ok -> Ok; - - {error, {ProblemApp, {"no such file or directory", _}}} -> - {error, {unknown_application, ProblemApp}} - end. - -sleep(Microseconds) -> - timer:sleep(Microseconds), - nil. - -sleep_forever() -> - timer:sleep(infinity), - nil. - -file_info_result(Result) -> - case Result of - {ok, {file_info, Size, Type, Access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}} when Access =:= none -> - {ok, {file_info, Size, Type, no_access, Atime, Mtime, Ctime, Mode, Links, MajorDevice, MinorDevice, Inode, Uid, Gid}}; - {ok, _} -> - Result; - {error, Reason} when ?is_posix_error(Reason) -> - Result - end. - -file_info(Filename) -> - file_info_result(file:read_file_info(Filename, [{time, posix}])). - -link_info(Filename) -> - file_info_result(file:read_link_info(Filename, [{time, posix}])). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -get_all_env() -> - BinVars = lists:map(fun(VarString) -> - [VarName, VarVal] = string:split(VarString, "="), - {list_to_binary(VarName), list_to_binary(VarVal)} - end, os:getenv()), - maps:from_list(BinVars). - -get_env(Name) -> - case os:getenv(binary_to_list(Name)) of - false -> {error, nil}; - Value -> {ok, list_to_binary(Value)} - end. - -set_env(Name, Value) -> - os:putenv(binary_to_list(Name), binary_to_list(Value)), - nil. - -unset_env(Name) -> - os:unsetenv(binary_to_list(Name)), - nil. - -os_family() -> - case os:type() of - {win32, nt} -> - windows_nt; - {unix, linux} -> - linux; - {unix, darwin} -> - darwin; - {unix, freebsd} -> - free_bsd; - {_, Other} -> - {other, atom_to_binary(Other, utf8)} - end. - -new_selector() -> - {selector, #{}}. - -map_selector({selector, Handlers}, Fn) -> - MappedHandlers = maps:map(fun(_Tag, Handler) -> - fun(Message) -> Fn(Handler(Message)) end - end, Handlers), - {selector, MappedHandlers}. - -merge_selector({selector, HandlersA}, {selector, HandlersB}) -> - {selector, maps:merge(HandlersA, HandlersB)}. - -insert_selector_handler({selector, Handlers}, Tag, Fn) -> - {selector, Handlers#{Tag => Fn}}. - -select(Selector) -> - {ok, Message} = select(Selector, infinity), - Message. - -select({selector, Handlers}, Timeout) -> - AnythingHandler = maps:get(anything, Handlers, undefined), - receive - % Monitored process down messages. - % This is special cased so we can selectively receive based on the - % reference as well as the record tag. - {'DOWN', Ref, process, Pid, Reason} when is_map_key(Ref, Handlers) -> - Fn = maps:get(Ref, Handlers), - {ok, Fn({process_down, Pid, Reason})}; - - Msg when is_map_key({element(1, Msg), tuple_size(Msg)}, Handlers) -> - Fn = maps:get({element(1, Msg), tuple_size(Msg)}, Handlers), - {ok, Fn(Msg)}; - - Msg when AnythingHandler =/= undefined -> - {ok, AnythingHandler(Msg)} - after Timeout -> - {error, nil} - end. - -demonitor({_, Reference}) -> - erlang:demonitor(Reference, [flush]). - -link(Pid) -> - try - erlang:link(Pid) - catch - error:_ -> false - end. - -trap_exits(ShouldTrap) -> - erlang:process_flag(trap_exit, ShouldTrap), - nil. - -flush_messages() -> - receive _Message -> flush_messages() - after 0 -> nil - end. - -priv_directory(Name) -> - try erlang:binary_to_existing_atom(Name) of - Atom -> - case code:priv_dir(Atom) of - {error, _} -> {error, nil}; - Path -> {ok, unicode:characters_to_binary(Path)} - end - catch - error:badarg -> {error, nil} - end. - -connect_node(Node) -> - case net_kernel:connect_node(Node) of - true -> {ok, Node}; - false -> {error, failed_to_connect}; - ignored -> {error, local_node_is_not_alive} - end. - -register_process(Pid, Name) -> - try - true = erlang:register(Name, Pid), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -unregister_process(Name) -> - try - true = erlang:unregister(Name), - {ok, nil} - catch - error:badarg -> {error, nil} - end. - -process_named(Name) -> - case erlang:whereis(Name) of - Pid when is_pid(Pid) -> {ok, Pid}; - _ -> {error, nil} - end. - -identity(X) -> - X. diff --git a/aoc2023/build/packages/gleam_http/LICENSE b/aoc2023/build/packages/gleam_http/LICENSE deleted file mode 100644 index 619ec77..0000000 --- a/aoc2023/build/packages/gleam_http/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/aoc2023/build/packages/gleam_http/README.md b/aoc2023/build/packages/gleam_http/README.md deleted file mode 100644 index 9e06952..0000000 --- a/aoc2023/build/packages/gleam_http/README.md +++ /dev/null @@ -1,67 +0,0 @@ -# Gleam HTTP - -Types and functions for HTTP clients and servers! - -## HTTP Service Example - -```gleam -import gleam/http/elli -import gleam/http/response.{Response} -import gleam/http/request.{Request} -import gleam/bit_builder.{BitBuilder} - -// Define a HTTP service -// -pub fn my_service(request: Request(t)) -> Response(BitBuilder) { - let body = bit_builder.from_string("Hello, world!") - - response.new(200) - |> response.prepend_header("made-with", "Gleam") - |> response.set_body(body) -} - -// Start it on port 3000 using the Elli web server -// -pub fn main() { - elli.become(my_service, on_port: 3000) -} -``` - -## Server adapters - -In the example above the Elli Erlang web server is used to run the Gleam HTTP -service. Here's a full list of the server adapters available, sorted -alphabetically. - -| Adapter | About | -| --- | --- | -| [Mist][mist] | [Mist][mist] is a high performance pure Gleam web server | -| [gleam_cowboy][cowboy-adapter] | [Cowboy][cowboy] is an Erlang HTTP2 & HTTP1.1 web server | -| [gleam_elli][elli-adapter] | [Elli][elli] is an Erlang HTTP1.1 web server | -| [gleam_plug][plug-adapter] | [Plug][plug] is an Elixir web application interface | - -[cowboy]:https://github.com/ninenines/cowboy -[cowboy-adapter]: https://github.com/gleam-lang/cowboy -[elli]:https://github.com/elli-lib/elli -[elli-adapter]: https://github.com/gleam-lang/elli -[plug]:https://github.com/elixir-plug/plug -[plug-adapter]: https://github.com/gleam-lang/plug -[mist]: https://github.com/rawhat/mist - -## Client adapters - -Client adapters are used to send HTTP requests to services over the network. -Here's a full list of the client adapters available, sorted alphabetically. - -| Adapter | About | -| --- | --- | -| [gleam_fetch][fetch-adapter] | [fetch][fetch] is a HTTP client included with JavaScript | -| [gleam_hackney][hackney-adapter] | [Hackney][hackney] is a simple HTTP client for Erlang | -| [gleam_httpc][httpc-adapter] | [httpc][httpc] is a HTTP client included with Erlang | - -[hackney]: https://github.com/benoitc/hackney -[hackney-adapter]: https://github.com/gleam-lang/hackney -[httpc]: https://erlang.org/doc/man/httpc.html -[httpc-adapter]: https://github.com/gleam-lang/httpc -[fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API -[fetch-adapter]: https://github.com/gleam-lang/fetch diff --git a/aoc2023/build/packages/gleam_http/gleam.toml b/aoc2023/build/packages/gleam_http/gleam.toml deleted file mode 100644 index ba733e8..0000000 --- a/aoc2023/build/packages/gleam_http/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "gleam_http" -version = "3.5.2" -licences = ["Apache-2.0"] -description = "Types and functions for Gleam HTTP clients and servers" -gleam = ">= 0.32.0" - -repository = { type = "github", user = "gleam-lang", repo = "http" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl deleted file mode 100644 index 78a7d02..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http@cookie_Attributes.hrl +++ /dev/null @@ -1,8 +0,0 @@ --record(attributes, { - max_age :: gleam@option:option(integer()), - domain :: gleam@option:option(binary()), - path :: gleam@option:option(binary()), - secure :: boolean(), - http_only :: boolean(), - same_site :: gleam@option:option(gleam@http@cookie:same_site_policy()) -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http@request_Request.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http@request_Request.hrl deleted file mode 100644 index c8bbae6..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http@request_Request.hrl +++ /dev/null @@ -1,10 +0,0 @@ --record(request, { - method :: gleam@http:method(), - headers :: list({binary(), binary()}), - body :: any(), - scheme :: gleam@http:scheme(), - host :: binary(), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()) -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http@response_Response.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http@response_Response.hrl deleted file mode 100644 index ba6f077..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http@response_Response.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(response, { - status :: integer(), - headers :: list({binary(), binary()}), - body :: any() -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForBody.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForBody.hrl deleted file mode 100644 index abd56dd..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForBody.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(more_required_for_body, { - chunk :: bitstring(), - continuation :: fun((bitstring()) -> {ok, gleam@http:multipart_body()} | - {error, nil}) -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl deleted file mode 100644 index 43729c1..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http_MoreRequiredForHeaders.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(more_required_for_headers, { - continuation :: fun((bitstring()) -> {ok, gleam@http:multipart_headers()} | - {error, nil}) -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartBody.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartBody.hrl deleted file mode 100644 index 4521591..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartBody.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(multipart_body, { - chunk :: bitstring(), - done :: boolean(), - remaining :: bitstring() -}). diff --git a/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartHeaders.hrl b/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartHeaders.hrl deleted file mode 100644 index d9fca5c..0000000 --- a/aoc2023/build/packages/gleam_http/include/gleam@http_MultipartHeaders.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(multipart_headers, { - headers :: list({binary(), binary()}), - remaining :: bitstring() -}). diff --git a/aoc2023/build/packages/gleam_http/src/gleam/http.gleam b/aoc2023/build/packages/gleam_http/src/gleam/http.gleam deleted file mode 100644 index a892006..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam/http.gleam +++ /dev/null @@ -1,560 +0,0 @@ -//// Functions for working with HTTP data structures in Gleam. -//// -//// This module makes it easy to create and modify Requests and Responses, data types. -//// A general HTTP message type is defined that enables functions to work on both requests and responses. -//// -//// This module does not implement a HTTP client or HTTP server, but it can be used as a base for them. - -import gleam/dynamic.{type DecodeError, type Dynamic, DecodeError} -import gleam/string -import gleam/bit_array -import gleam/result -import gleam/list -import gleam/bool - -/// HTTP standard method as defined by [RFC 2616](https://tools.ietf.org/html/rfc2616), -/// and PATCH which is defined by [RFC 5789](https://tools.ietf.org/html/rfc5789). -pub type Method { - Get - Post - Head - Put - Delete - Trace - Connect - Options - Patch - - /// Non-standard but valid HTTP methods. - Other(String) -} - -// TODO: check if the a is a valid HTTP method (i.e. it is a token, as per the -// spec) and return Ok(Other(s)) if so. -pub fn parse_method(s) -> Result(Method, Nil) { - case string.lowercase(s) { - "connect" -> Ok(Connect) - "delete" -> Ok(Delete) - "get" -> Ok(Get) - "head" -> Ok(Head) - "options" -> Ok(Options) - "patch" -> Ok(Patch) - "post" -> Ok(Post) - "put" -> Ok(Put) - "trace" -> Ok(Trace) - _ -> Error(Nil) - } -} - -pub fn method_to_string(method: Method) -> String { - case method { - Connect -> "connect" - Delete -> "delete" - Get -> "get" - Head -> "head" - Options -> "options" - Patch -> "patch" - Post -> "post" - Put -> "put" - Trace -> "trace" - Other(s) -> s - } -} - -/// The two URI schemes for HTTP -/// -pub type Scheme { - Http - Https -} - -/// Convert a scheme into a string. -/// -/// # Examples -/// -/// > scheme_to_string(Http) -/// "http" -/// -/// > scheme_to_string(Https) -/// "https" -/// -pub fn scheme_to_string(scheme: Scheme) -> String { - case scheme { - Http -> "http" - Https -> "https" - } -} - -/// Parse a HTTP scheme from a string -/// -/// # Examples -/// -/// > scheme_from_string("http") -/// Ok(Http) -/// -/// > scheme_from_string("ftp") -/// Error(Nil) -/// -pub fn scheme_from_string(scheme: String) -> Result(Scheme, Nil) { - case string.lowercase(scheme) { - "http" -> Ok(Http) - "https" -> Ok(Https) - _ -> Error(Nil) - } -} - -pub fn method_from_dynamic(value: Dynamic) -> Result(Method, List(DecodeError)) { - case do_method_from_dynamic(value) { - Ok(method) -> Ok(method) - Error(_) -> Error([DecodeError("HTTP method", dynamic.classify(value), [])]) - } -} - -pub type MultipartHeaders { - /// The headers for the part have been fully parsed. - MultipartHeaders( - headers: List(Header), - /// The remaining content that has not yet been parsed. This will contain - /// the body for this part, if any, and can be parsed with the - /// `parse_multipart_body` function. - remaining: BitArray, - ) - /// More input is required to parse the headers for this part. - MoreRequiredForHeaders( - /// Call this function to continue parsing the headers for this part. - continuation: fn(BitArray) -> Result(MultipartHeaders, Nil), - ) -} - -pub type MultipartBody { - /// The body for the part has been fully parsed. - MultipartBody( - // The rest of the body for this part. The full body of the part is this - // concatenated onto the end of each chunk returned by any previous - // `MoreRequiredForBody` returns. - chunk: BitArray, - /// This is `True` if this was the last part in the multipart message, - /// otherwise there are more parts to parse. - done: Bool, - /// The remaining content that has not yet been parsed. This will contain - /// the next part if `done` is `False`, otherwise it will contain the - /// epilogue, if any. - remaining: BitArray, - ) - MoreRequiredForBody( - // The body that has been parsed so far. The full body of the part is this - // concatenated with the chunk returned by each `MoreRequiredForBody` return - // value, and the final `MultipartBody` return value. - chunk: BitArray, - /// Call this function to continue parsing the body for this part. - continuation: fn(BitArray) -> Result(MultipartBody, Nil), - ) -} - -/// Parse the headers for part of a multipart message, as defined in RFC 2045. -/// -/// This function skips any preamble before the boundary. The preamble may be -/// retrieved using `parse_multipart_body`. -/// -/// This function will accept input of any size, it is up to the caller to limit -/// it if needed. -/// -/// To enable streaming parsing of multipart messages, this function will return -/// a continuation if there is not enough data to fully parse the headers. -/// Further information is available in the documentation for `MultipartBody`. -/// -pub fn parse_multipart_headers( - data: BitArray, - boundary: String, -) -> Result(MultipartHeaders, Nil) { - let boundary = bit_array.from_string(boundary) - // TODO: rewrite this to use a bit pattern once JavaScript supports - // the `b:binary-size(bsize)` pattern. - let prefix = <<45, 45, boundary:bits>> - case bit_array.slice(data, 0, bit_array.byte_size(prefix)) == Ok(prefix) { - // There is no preamble, parse the headers. - True -> parse_headers_after_prelude(data, boundary) - // There is a preamble, skip it before parsing. - False -> skip_preamble(data, boundary) - } -} - -/// Parse the body for part of a multipart message, as defined in RFC 2045. The -/// body is everything until the next boundary. This function is generally to be -/// called after calling `parse_multipart_headers` for a given part. -/// -/// This function will accept input of any size, it is up to the caller to limit -/// it if needed. -/// -/// To enable streaming parsing of multipart messages, this function will return -/// a continuation if there is not enough data to fully parse the body, along -/// with the data that has been parsed so far. Further information is available -/// in the documentation for `MultipartBody`. -/// -pub fn parse_multipart_body( - data: BitArray, - boundary: String, -) -> Result(MultipartBody, Nil) { - boundary - |> bit_array.from_string - |> parse_body_with_bit_array(data, _) -} - -fn parse_body_with_bit_array( - data: BitArray, - boundary: BitArray, -) -> Result(MultipartBody, Nil) { - let bsize = bit_array.byte_size(boundary) - let prefix = bit_array.slice(data, 0, 2 + bsize) - case prefix == Ok(<<45, 45, boundary:bits>>) { - True -> Ok(MultipartBody(<<>>, done: False, remaining: data)) - False -> parse_body_loop(data, boundary, <<>>) - } -} - -fn parse_body_loop( - data: BitArray, - boundary: BitArray, - body: BitArray, -) -> Result(MultipartBody, Nil) { - let dsize = bit_array.byte_size(data) - let bsize = bit_array.byte_size(boundary) - let required = 6 + bsize - case data { - _ if dsize < required -> { - more_please_body(parse_body_loop(_, boundary, <<>>), body, data) - } - - // TODO: flatten this into a single case expression once JavaScript supports - // the `b:binary-size(bsize)` pattern. - // - // \r\n - <<13, 10, data:bytes>> -> { - let desired = <<45, 45, boundary:bits>> - let size = bit_array.byte_size(desired) - let dsize = bit_array.byte_size(data) - let prefix = bit_array.slice(data, 0, size) - let rest = bit_array.slice(data, size, dsize - size) - case prefix == Ok(desired), rest { - // --boundary\r\n - True, Ok(<<13, 10, _:bytes>>) -> - Ok(MultipartBody(body, done: False, remaining: data)) - - // --boundary-- - True, Ok(<<45, 45, data:bytes>>) -> - Ok(MultipartBody(body, done: True, remaining: data)) - - False, _ -> parse_body_loop(data, boundary, <<body:bits, 13, 10>>) - _, _ -> Error(Nil) - } - } - - <<char, data:bytes>> -> { - parse_body_loop(data, boundary, <<body:bits, char>>) - } - } -} - -fn parse_headers_after_prelude( - data: BitArray, - boundary: BitArray, -) -> Result(MultipartHeaders, Nil) { - let dsize = bit_array.byte_size(data) - let bsize = bit_array.byte_size(boundary) - let required_size = bsize + 4 - - // TODO: this could be written as a single case expression if JavaScript had - // support for the `b:binary-size(bsize)` pattern. Rewrite this once the - // compiler support this. - - use <- bool.guard( - when: dsize < required_size, - return: more_please_headers(parse_headers_after_prelude(_, boundary), data), - ) - - use prefix <- result.try(bit_array.slice(data, 0, required_size - 2)) - use second <- result.try(bit_array.slice(data, 2 + bsize, 2)) - let desired = <<45, 45, boundary:bits>> - - use <- bool.guard(prefix != desired, return: Error(Nil)) - - case second == <<45, 45>> { - // --boundary-- - // The last boundary. Return the epilogue. - True -> { - let rest_size = dsize - required_size - use data <- result.map(bit_array.slice(data, required_size, rest_size)) - MultipartHeaders([], remaining: data) - } - - // --boundary - False -> { - let start = required_size - 2 - let rest_size = dsize - required_size + 2 - use data <- result.try(bit_array.slice(data, start, rest_size)) - do_parse_headers(data) - } - } -} - -fn skip_preamble( - data: BitArray, - boundary: BitArray, -) -> Result(MultipartHeaders, Nil) { - let data_size = bit_array.byte_size(data) - let boundary_size = bit_array.byte_size(boundary) - let required = boundary_size + 4 - case data { - _ if data_size < required -> - more_please_headers(skip_preamble(_, boundary), data) - - // TODO: change this to use one non-nested case expression once the compiler - // supports the `b:binary-size(bsize)` pattern on JS. - // \r\n-- - <<13, 10, 45, 45, data:bytes>> -> { - case bit_array.slice(data, 0, boundary_size) { - // --boundary - Ok(prefix) if prefix == boundary -> { - let start = boundary_size - let length = bit_array.byte_size(data) - boundary_size - use rest <- result.try(bit_array.slice(data, start, length)) - do_parse_headers(rest) - } - Ok(_) -> skip_preamble(data, boundary) - Error(_) -> Error(Nil) - } - } - - <<_, data:bytes>> -> skip_preamble(data, boundary) - } -} - -fn skip_whitespace(data: BitArray) -> BitArray { - case data { - // Space or tab. - <<32, data:bytes>> | <<9, data:bytes>> -> skip_whitespace(data) - _ -> data - } -} - -fn do_parse_headers(data: BitArray) -> Result(MultipartHeaders, Nil) { - case data { - // \r\n\r\n - // We've reached the end, there are no headers. - <<13, 10, 13, 10, data:bytes>> -> Ok(MultipartHeaders([], remaining: data)) - - // \r\n - // Skip the line break after the boundary. - <<13, 10, data:bytes>> -> parse_header_name(data, [], <<>>) - - <<13>> | <<>> -> more_please_headers(do_parse_headers, data) - - _ -> Error(Nil) - } -} - -fn parse_header_name( - data: BitArray, - headers: List(Header), - name: BitArray, -) -> Result(MultipartHeaders, Nil) { - case skip_whitespace(data) { - // : - <<58, data:bytes>> -> - data - |> skip_whitespace - |> parse_header_value(headers, name, <<>>) - - <<char, data:bytes>> -> - parse_header_name(data, headers, <<name:bits, char>>) - - <<>> -> more_please_headers(parse_header_name(_, headers, name), data) - } -} - -fn parse_header_value( - data: BitArray, - headers: List(Header), - name: BitArray, - value: BitArray, -) -> Result(MultipartHeaders, Nil) { - let size = bit_array.byte_size(data) - case data { - // We need at least 4 bytes to check for the end of the headers. - _ if size < 4 -> - fn(data) { - data - |> skip_whitespace - |> parse_header_value(headers, name, value) - } - |> more_please_headers(data) - - // \r\n\r\n - <<13, 10, 13, 10, data:bytes>> -> { - use name <- result.try(bit_array.to_string(name)) - use value <- result.map(bit_array.to_string(value)) - let headers = list.reverse([#(string.lowercase(name), value), ..headers]) - MultipartHeaders(headers, data) - } - - // \r\n\s - // \r\n\t - <<13, 10, 32, data:bytes>> | <<13, 10, 9, data:bytes>> -> - parse_header_value(data, headers, name, value) - - // \r\n - <<13, 10, data:bytes>> -> { - use name <- result.try(bit_array.to_string(name)) - use value <- result.try(bit_array.to_string(value)) - let headers = [#(string.lowercase(name), value), ..headers] - parse_header_name(data, headers, <<>>) - } - - <<char, rest:bytes>> -> { - let value = <<value:bits, char>> - parse_header_value(rest, headers, name, value) - } - - _ -> Error(Nil) - } -} - -fn more_please_headers( - continuation: fn(BitArray) -> Result(MultipartHeaders, Nil), - existing: BitArray, -) -> Result(MultipartHeaders, Nil) { - Ok(MoreRequiredForHeaders(fn(more) { - use <- bool.guard(more == <<>>, return: Error(Nil)) - continuation(<<existing:bits, more:bits>>) - })) -} - -pub type ContentDisposition { - ContentDisposition(String, parameters: List(#(String, String))) -} - -pub fn parse_content_disposition( - header: String, -) -> Result(ContentDisposition, Nil) { - parse_content_disposition_type(header, "") -} - -fn parse_content_disposition_type( - header: String, - name: String, -) -> Result(ContentDisposition, Nil) { - case string.pop_grapheme(header) { - Error(Nil) -> Ok(ContentDisposition(name, [])) - - Ok(#(" ", rest)) | Ok(#("\t", rest)) | Ok(#(";", rest)) -> { - let result = parse_rfc_2045_parameters(rest, []) - use parameters <- result.map(result) - ContentDisposition(name, parameters) - } - - Ok(#(grapheme, rest)) -> - parse_content_disposition_type(rest, name <> string.lowercase(grapheme)) - } -} - -fn parse_rfc_2045_parameters( - header: String, - parameters: List(#(String, String)), -) -> Result(List(#(String, String)), Nil) { - case string.pop_grapheme(header) { - Error(Nil) -> Ok(list.reverse(parameters)) - - Ok(#(";", rest)) | Ok(#(" ", rest)) | Ok(#("\t", rest)) -> - parse_rfc_2045_parameters(rest, parameters) - - Ok(#(grapheme, rest)) -> { - let acc = string.lowercase(grapheme) - use #(parameter, rest) <- result.try(parse_rfc_2045_parameter(rest, acc)) - parse_rfc_2045_parameters(rest, [parameter, ..parameters]) - } - } -} - -fn parse_rfc_2045_parameter( - header: String, - name: String, -) -> Result(#(#(String, String), String), Nil) { - use #(grapheme, rest) <- result.try(string.pop_grapheme(header)) - case grapheme { - "=" -> parse_rfc_2045_parameter_value(rest, name) - _ -> parse_rfc_2045_parameter(rest, name <> string.lowercase(grapheme)) - } -} - -fn parse_rfc_2045_parameter_value( - header: String, - name: String, -) -> Result(#(#(String, String), String), Nil) { - case string.pop_grapheme(header) { - Error(Nil) -> Error(Nil) - Ok(#("\"", rest)) -> parse_rfc_2045_parameter_quoted_value(rest, name, "") - Ok(#(grapheme, rest)) -> - Ok(parse_rfc_2045_parameter_unquoted_value(rest, name, grapheme)) - } -} - -fn parse_rfc_2045_parameter_quoted_value( - header: String, - name: String, - value: String, -) -> Result(#(#(String, String), String), Nil) { - case string.pop_grapheme(header) { - Error(Nil) -> Error(Nil) - Ok(#("\"", rest)) -> Ok(#(#(name, value), rest)) - Ok(#("\\", rest)) -> { - use #(grapheme, rest) <- result.try(string.pop_grapheme(rest)) - parse_rfc_2045_parameter_quoted_value(rest, name, value <> grapheme) - } - Ok(#(grapheme, rest)) -> - parse_rfc_2045_parameter_quoted_value(rest, name, value <> grapheme) - } -} - -fn parse_rfc_2045_parameter_unquoted_value( - header: String, - name: String, - value: String, -) -> #(#(String, String), String) { - case string.pop_grapheme(header) { - Error(Nil) -> #(#(name, value), header) - - Ok(#(";", rest)) | Ok(#(" ", rest)) | Ok(#("\t", rest)) -> #( - #(name, value), - rest, - ) - - Ok(#(grapheme, rest)) -> - parse_rfc_2045_parameter_unquoted_value(rest, name, value <> grapheme) - } -} - -fn more_please_body( - continuation: fn(BitArray) -> Result(MultipartBody, Nil), - chunk: BitArray, - existing: BitArray, -) -> Result(MultipartBody, Nil) { - fn(more) { - use <- bool.guard(more == <<>>, return: Error(Nil)) - continuation(<<existing:bits, more:bits>>) - } - |> MoreRequiredForBody(chunk, _) - |> Ok -} - -@target(erlang) -@external(erlang, "gleam_http_native", "decode_method") -fn do_method_from_dynamic(a: Dynamic) -> Result(Method, nil) - -@target(javascript) -@external(javascript, "../gleam_http_native.mjs", "decode_method") -fn do_method_from_dynamic(a: Dynamic) -> Result(Method, Nil) - -/// A HTTP header is a key-value pair. Header keys should be all lowercase -/// characters. -pub type Header = - #(String, String) diff --git a/aoc2023/build/packages/gleam_http/src/gleam/http/cookie.gleam b/aoc2023/build/packages/gleam_http/src/gleam/http/cookie.gleam deleted file mode 100644 index e9ccb55..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam/http/cookie.gleam +++ /dev/null @@ -1,128 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/regex -import gleam/string -import gleam/option.{type Option, Some} -import gleam/http.{type Scheme} - -/// Policy options for the SameSite cookie attribute -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite -pub type SameSitePolicy { - Lax - Strict - None -} - -fn same_site_to_string(policy) { - case policy { - Lax -> "Lax" - Strict -> "Strict" - None -> "None" - } -} - -/// Attributes of a cookie when sent to a client in the `set-cookie` header. -pub type Attributes { - Attributes( - max_age: Option(Int), - domain: Option(String), - path: Option(String), - secure: Bool, - http_only: Bool, - same_site: Option(SameSitePolicy), - ) -} - -/// Helper to create sensible default attributes for a set cookie. -/// -/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Attributes -pub fn defaults(scheme: Scheme) { - Attributes( - max_age: option.None, - domain: option.None, - path: option.Some("/"), - secure: scheme == http.Https, - http_only: True, - same_site: Some(Lax), - ) -} - -const epoch = "Expires=Thu, 01 Jan 1970 00:00:00 GMT" - -fn cookie_attributes_to_list(attributes) { - let Attributes( - max_age: max_age, - domain: domain, - path: path, - secure: secure, - http_only: http_only, - same_site: same_site, - ) = attributes - [ - // Expires is a deprecated attribute for cookies, it has been replaced with MaxAge - // MaxAge is widely supported and so Expires values are not set. - // Only when deleting cookies is the exception made to use the old format, - // to ensure complete clearup of cookies if required by an application. - case max_age { - option.Some(0) -> option.Some([epoch]) - _ -> option.None - }, - option.map(max_age, fn(max_age) { ["Max-Age=", int.to_string(max_age)] }), - option.map(domain, fn(domain) { ["Domain=", domain] }), - option.map(path, fn(path) { ["Path=", path] }), - case secure { - True -> option.Some(["Secure"]) - False -> option.None - }, - case http_only { - True -> option.Some(["HttpOnly"]) - False -> option.None - }, - option.map( - same_site, - fn(same_site) { ["SameSite=", same_site_to_string(same_site)] }, - ), - ] - |> list.filter_map(option.to_result(_, Nil)) -} - -pub fn set_header(name: String, value: String, attributes: Attributes) -> String { - [[name, "=", value], ..cookie_attributes_to_list(attributes)] - |> list.map(string.join(_, "")) - |> string.join("; ") -} - -/// Parse a list of cookies from a header string. Any malformed cookies will be -/// discarded. -/// -pub fn parse(cookie_string: String) -> List(#(String, String)) { - let assert Ok(re) = regex.from_string("[,;]") - regex.split(re, cookie_string) - |> list.filter_map(fn(pair) { - case string.split_once(string.trim(pair), "=") { - Ok(#("", _)) -> Error(Nil) - Ok(#(key, value)) -> { - let key = string.trim(key) - let value = string.trim(value) - use _ <- result.then(check_token(key)) - use _ <- result.then(check_token(value)) - Ok(#(key, value)) - } - Error(Nil) -> Error(Nil) - } - }) -} - -fn check_token(token: String) -> Result(Nil, Nil) { - case string.pop_grapheme(token) { - Error(Nil) -> Ok(Nil) - Ok(#(" ", _)) -> Error(Nil) - Ok(#("\t", _)) -> Error(Nil) - Ok(#("\r", _)) -> Error(Nil) - Ok(#("\n", _)) -> Error(Nil) - Ok(#("\f", _)) -> Error(Nil) - Ok(#(_, rest)) -> check_token(rest) - } -} diff --git a/aoc2023/build/packages/gleam_http/src/gleam/http/request.gleam b/aoc2023/build/packages/gleam_http/src/gleam/http/request.gleam deleted file mode 100644 index 0bf9af9..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam/http/request.gleam +++ /dev/null @@ -1,267 +0,0 @@ -import gleam/result -// TODO: validate_req -import gleam/http.{type Header, type Method, type Scheme, Get} -import gleam/http/cookie -import gleam/option.{type Option} -import gleam/uri.{type Uri, Uri} -import gleam/list -import gleam/string -import gleam/string_builder - -// TODO: document -pub type Request(body) { - Request( - method: Method, - headers: List(Header), - body: body, - scheme: Scheme, - host: String, - port: Option(Int), - path: String, - query: Option(String), - ) -} - -/// Return the uri that a request was sent to. -/// -pub fn to_uri(request: Request(a)) -> Uri { - Uri( - scheme: option.Some(http.scheme_to_string(request.scheme)), - userinfo: option.None, - host: option.Some(request.host), - port: request.port, - path: request.path, - query: request.query, - fragment: option.None, - ) -} - -/// Construct a request from a URI. -/// -pub fn from_uri(uri: Uri) -> Result(Request(String), Nil) { - use scheme <- result.then( - uri.scheme - |> option.unwrap("") - |> http.scheme_from_string, - ) - use host <- result.then( - uri.host - |> option.to_result(Nil), - ) - let req = - Request( - method: Get, - headers: [], - body: "", - scheme: scheme, - host: host, - port: uri.port, - path: uri.path, - query: uri.query, - ) - Ok(req) -} - -/// Get the value for a given header. -/// -/// If the request does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(request: Request(body), key: String) -> Result(String, Nil) { - list.key_find(request.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If already present, it is replaced. -pub fn set_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = list.key_set(request.headers, string.lowercase(key), value) - Request(..request, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - request: Request(body), - key: String, - value: String, -) -> Request(body) { - let headers = [#(string.lowercase(key), value), ..request.headers] - Request(..request, headers: headers) -} - -// TODO: record update syntax, which can't be done currently as body type changes -/// Set the body of the request, overwriting any existing body. -/// -pub fn set_body(req: Request(old_body), body: new_body) -> Request(new_body) { - let Request( - method: method, - headers: headers, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - .., - ) = req - Request( - method: method, - headers: headers, - body: body, - scheme: scheme, - host: host, - port: port, - path: path, - query: query, - ) -} - -/// Update the body of a request using a given function. -/// -pub fn map( - request: Request(old_body), - transform: fn(old_body) -> new_body, -) -> Request(new_body) { - request.body - |> transform - |> set_body(request, _) -} - -/// Return the non-empty segments of a request path. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> set_path("/one/two/three") -/// > |> path_segments -/// ["one", "two", "three"] -/// ``` -/// -pub fn path_segments(request: Request(body)) -> List(String) { - request.path - |> uri.path_segments -} - -/// Decode the query of a request. -pub fn get_query(request: Request(body)) -> Result(List(#(String, String)), Nil) { - case request.query { - option.Some(query_string) -> uri.parse_query(query_string) - option.None -> Ok([]) - } -} - -// TODO: escape -/// Set the query of the request. -/// -pub fn set_query( - req: Request(body), - query: List(#(String, String)), -) -> Request(body) { - let pair = fn(t: #(String, String)) { - string_builder.from_strings([t.0, "=", t.1]) - } - let query = - query - |> list.map(pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string - |> option.Some - Request(..req, query: query) -} - -/// Set the method of the request. -/// -pub fn set_method(req: Request(body), method: Method) -> Request(body) { - Request(..req, method: method) -} - -/// A request with commonly used default values. This request can be used as -/// an initial value and then update to create the desired request. -/// -pub fn new() -> Request(String) { - Request( - method: Get, - headers: [], - body: "", - scheme: http.Https, - host: "localhost", - port: option.None, - path: "", - query: option.None, - ) -} - -/// Construct a request from a URL string -/// -pub fn to(url: String) -> Result(Request(String), Nil) { - url - |> uri.parse - |> result.then(from_uri) -} - -/// Set the scheme (protocol) of the request. -/// -pub fn set_scheme(req: Request(body), scheme: Scheme) -> Request(body) { - Request(..req, scheme: scheme) -} - -/// Set the method of the request. -/// -pub fn set_host(req: Request(body), host: String) -> Request(body) { - Request(..req, host: host) -} - -/// Set the port of the request. -/// -pub fn set_port(req: Request(body), port: Int) -> Request(body) { - Request(..req, port: option.Some(port)) -} - -/// Set the path of the request. -/// -pub fn set_path(req: Request(body), path: String) -> Request(body) { - Request(..req, path: path) -} - -/// Send a cookie with a request -/// -/// Multiple cookies are added to the same cookie header. -pub fn set_cookie(req: Request(body), name: String, value: String) { - let new_cookie_string = string.join([name, value], "=") - - let #(cookies_string, headers) = case list.key_pop(req.headers, "cookie") { - Ok(#(cookies_string, headers)) -> { - let cookies_string = - string.join([cookies_string, new_cookie_string], "; ") - #(cookies_string, headers) - } - Error(Nil) -> #(new_cookie_string, req.headers) - } - - Request(..req, headers: [#("cookie", cookies_string), ..headers]) -} - -/// Fetch the cookies sent in a request. -/// -/// Note badly formed cookie pairs will be ignored. -/// RFC6265 specifies that invalid cookie names/attributes should be ignored. -pub fn get_cookies(req) -> List(#(String, String)) { - let Request(headers: headers, ..) = req - - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} diff --git a/aoc2023/build/packages/gleam_http/src/gleam/http/response.gleam b/aoc2023/build/packages/gleam_http/src/gleam/http/response.gleam deleted file mode 100644 index 87f9140..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam/http/response.gleam +++ /dev/null @@ -1,141 +0,0 @@ -import gleam/result -import gleam/http.{type Header} -import gleam/http/cookie -import gleam/list -import gleam/string -import gleam/option - -// TODO: document -pub type Response(body) { - Response(status: Int, headers: List(Header), body: body) -} - -/// Update the body of a response using a given result returning function. -/// -/// If the given function returns an `Ok` value the body is set, if it returns -/// an `Error` value then the error is returned. -/// -pub fn try_map( - response: Response(old_body), - transform: fn(old_body) -> Result(new_body, error), -) -> Result(Response(new_body), error) { - use body <- result.then(transform(response.body)) - Ok(set_body(response, body)) -} - -/// Construct an empty Response. -/// -/// The body type of the returned response is `String` and could be set with a -/// call to `set_body`. -/// -pub fn new(status: Int) -> Response(String) { - Response(status: status, headers: [], body: "") -} - -/// Get the value for a given header. -/// -/// If the response does not have that header then `Error(Nil)` is returned. -/// -pub fn get_header(response: Response(body), key: String) -> Result(String, Nil) { - list.key_find(response.headers, string.lowercase(key)) -} - -/// Set the header with the given value under the given header key. -/// -/// If the response already has that key, it is replaced. -pub fn set_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = list.key_set(response.headers, string.lowercase(key), value) - Response(..response, headers: headers) -} - -/// Prepend the header with the given value under the given header key. -/// -/// Similar to `set_header` except if the header already exists it prepends -/// another header with the same key. -pub fn prepend_header( - response: Response(body), - key: String, - value: String, -) -> Response(body) { - let headers = [#(string.lowercase(key), value), ..response.headers] - Response(..response, headers: headers) -} - -/// Set the body of the response, overwriting any existing body. -/// -pub fn set_body( - response: Response(old_body), - body: new_body, -) -> Response(new_body) { - let Response(status: status, headers: headers, ..) = response - Response(status: status, headers: headers, body: body) -} - -/// Update the body of a response using a given function. -/// -pub fn map( - response: Response(old_body), - transform: fn(old_body) -> new_body, -) -> Response(new_body) { - response.body - |> transform - |> set_body(response, _) -} - -/// Create a response that redirects to the given uri. -/// -pub fn redirect(uri: String) -> Response(String) { - Response( - status: 303, - headers: [#("location", uri)], - body: string.append("You are being redirected to ", uri), - ) -} - -/// Fetch the cookies sent in a response. -/// -/// Badly formed cookies will be discarded. -/// -pub fn get_cookies(resp) -> List(#(String, String)) { - let Response(headers: headers, ..) = resp - headers - |> list.filter_map(fn(header) { - let #(name, value) = header - case name { - "set-cookie" -> Ok(cookie.parse(value)) - _ -> Error(Nil) - } - }) - |> list.flatten() -} - -/// Set a cookie value for a client -/// -pub fn set_cookie( - response: Response(t), - name: String, - value: String, - attributes: cookie.Attributes, -) -> Response(t) { - prepend_header( - response, - "set-cookie", - cookie.set_header(name, value, attributes), - ) -} - -/// Expire a cookie value for a client -/// -/// Note: The attributes value should be the same as when the response cookie was set. -pub fn expire_cookie( - response: Response(t), - name: String, - attributes: cookie.Attributes, -) -> Response(t) { - let attrs = cookie.Attributes(..attributes, max_age: option.Some(0)) - set_cookie(response, name, "", attrs) -} diff --git a/aoc2023/build/packages/gleam_http/src/gleam/http/service.gleam b/aoc2023/build/packages/gleam_http/src/gleam/http/service.gleam deleted file mode 100644 index 3dfac87..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam/http/service.gleam +++ /dev/null @@ -1,82 +0,0 @@ -import gleam/http.{Delete, Patch, Post, Put} -import gleam/http/request.{type Request} -import gleam/http/response.{type Response} -import gleam/list -import gleam/result - -// TODO: document -pub type Service(in, out) = - fn(Request(in)) -> Response(out) - -pub type Middleware(before_req, before_resp, after_req, after_resp) = - fn(Service(before_req, before_resp)) -> Service(after_req, after_resp) - -/// A middleware that transform the response body returned by the service using -/// a given function. -/// -pub fn map_response_body( - service: Service(req, a), - with mapper: fn(a) -> b, -) -> Service(req, b) { - fn(req) { - req - |> service - |> response.map(mapper) - } -} - -/// A middleware that prepends a header to the request. -/// -pub fn prepend_response_header( - service: Service(req, resp), - key: String, - value: String, -) -> Service(req, resp) { - fn(req) { - req - |> service - |> response.prepend_header(key, value) - } -} - -fn ensure_post(req: Request(a)) { - case req.method { - Post -> Ok(req) - _ -> Error(Nil) - } -} - -fn get_override_method(request: Request(t)) -> Result(http.Method, Nil) { - use query_params <- result.then(request.get_query(request)) - use method <- result.then(list.key_find(query_params, "_method")) - use method <- result.then(http.parse_method(method)) - case method { - Put | Patch | Delete -> Ok(method) - _ -> Error(Nil) - } -} - -/// A middleware that overrides an incoming POST request with a method given in -/// the request's `_method` query paramerter. This is useful as web browsers -/// typically only support GET and POST requests, but our application may -/// expect other HTTP methods that are more semantically correct. -/// -/// The methods PUT, PATCH, and DELETE are accepted for overriding, all others -/// are ignored. -/// -/// The `_method` query paramerter can be specified in a HTML form like so: -/// -/// <form method="POST" action="/item/1?_method=DELETE"> -/// <button type="submit">Delete item</button> -/// </form> -/// -pub fn method_override(service: Service(req, resp)) -> Service(req, resp) { - fn(request) { - request - |> ensure_post - |> result.then(get_override_method) - |> result.map(request.set_method(request, _)) - |> result.unwrap(request) - |> service - } -} diff --git a/aoc2023/build/packages/gleam_http/src/gleam@http.erl b/aoc2023/build/packages/gleam_http/src/gleam@http.erl deleted file mode 100644 index 91ee6e8..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam@http.erl +++ /dev/null @@ -1,626 +0,0 @@ --module(gleam@http). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse_method/1, method_to_string/1, scheme_to_string/1, scheme_from_string/1, parse_content_disposition/1, parse_multipart_body/2, method_from_dynamic/1, parse_multipart_headers/2]). --export_type([method/0, scheme/0, multipart_headers/0, multipart_body/0, content_disposition/0]). - --type method() :: get | - post | - head | - put | - delete | - trace | - connect | - options | - patch | - {other, binary()}. - --type scheme() :: http | https. - --type multipart_headers() :: {multipart_headers, - list({binary(), binary()}), - bitstring()} | - {more_required_for_headers, - fun((bitstring()) -> {ok, multipart_headers()} | {error, nil})}. - --type multipart_body() :: {multipart_body, bitstring(), boolean(), bitstring()} | - {more_required_for_body, - bitstring(), - fun((bitstring()) -> {ok, multipart_body()} | {error, nil})}. - --type content_disposition() :: {content_disposition, - binary(), - list({binary(), binary()})}. - --spec parse_method(binary()) -> {ok, method()} | {error, nil}. -parse_method(S) -> - case gleam@string:lowercase(S) of - <<"connect"/utf8>> -> - {ok, connect}; - - <<"delete"/utf8>> -> - {ok, delete}; - - <<"get"/utf8>> -> - {ok, get}; - - <<"head"/utf8>> -> - {ok, head}; - - <<"options"/utf8>> -> - {ok, options}; - - <<"patch"/utf8>> -> - {ok, patch}; - - <<"post"/utf8>> -> - {ok, post}; - - <<"put"/utf8>> -> - {ok, put}; - - <<"trace"/utf8>> -> - {ok, trace}; - - _ -> - {error, nil} - end. - --spec method_to_string(method()) -> binary(). -method_to_string(Method) -> - case Method of - connect -> - <<"connect"/utf8>>; - - delete -> - <<"delete"/utf8>>; - - get -> - <<"get"/utf8>>; - - head -> - <<"head"/utf8>>; - - options -> - <<"options"/utf8>>; - - patch -> - <<"patch"/utf8>>; - - post -> - <<"post"/utf8>>; - - put -> - <<"put"/utf8>>; - - trace -> - <<"trace"/utf8>>; - - {other, S} -> - S - end. - --spec scheme_to_string(scheme()) -> binary(). -scheme_to_string(Scheme) -> - case Scheme of - http -> - <<"http"/utf8>>; - - https -> - <<"https"/utf8>> - end. - --spec scheme_from_string(binary()) -> {ok, scheme()} | {error, nil}. -scheme_from_string(Scheme) -> - case gleam@string:lowercase(Scheme) of - <<"http"/utf8>> -> - {ok, http}; - - <<"https"/utf8>> -> - {ok, https}; - - _ -> - {error, nil} - end. - --spec skip_whitespace(bitstring()) -> bitstring(). -skip_whitespace(Data) -> - case Data of - <<32, Data@1/binary>> -> - skip_whitespace(Data@1); - - <<9, Data@1/binary>> -> - skip_whitespace(Data@1); - - _ -> - Data - end. - --spec more_please_headers( - fun((bitstring()) -> {ok, multipart_headers()} | {error, nil}), - bitstring() -) -> {ok, multipart_headers()} | {error, nil}. -more_please_headers(Continuation, Existing) -> - {ok, - {more_required_for_headers, - fun(More) -> - gleam@bool:guard( - More =:= <<>>, - {error, nil}, - fun() -> - Continuation(<<Existing/bitstring, More/bitstring>>) - end - ) - end}}. - --spec parse_rfc_2045_parameter_quoted_value(binary(), binary(), binary()) -> {ok, - {{binary(), binary()}, binary()}} | - {error, nil}. -parse_rfc_2045_parameter_quoted_value(Header, Name, Value) -> - case gleam@string:pop_grapheme(Header) of - {error, nil} -> - {error, nil}; - - {ok, {<<"\""/utf8>>, Rest}} -> - {ok, {{Name, Value}, Rest}}; - - {ok, {<<"\\"/utf8>>, Rest@1}} -> - gleam@result:'try'( - gleam@string:pop_grapheme(Rest@1), - fun(_use0) -> - {Grapheme, Rest@2} = _use0, - parse_rfc_2045_parameter_quoted_value( - Rest@2, - Name, - <<Value/binary, Grapheme/binary>> - ) - end - ); - - {ok, {Grapheme@1, Rest@3}} -> - parse_rfc_2045_parameter_quoted_value( - Rest@3, - Name, - <<Value/binary, Grapheme@1/binary>> - ) - end. - --spec parse_rfc_2045_parameter_unquoted_value(binary(), binary(), binary()) -> {{binary(), - binary()}, - binary()}. -parse_rfc_2045_parameter_unquoted_value(Header, Name, Value) -> - case gleam@string:pop_grapheme(Header) of - {error, nil} -> - {{Name, Value}, Header}; - - {ok, {<<";"/utf8>>, Rest}} -> - {{Name, Value}, Rest}; - - {ok, {<<" "/utf8>>, Rest}} -> - {{Name, Value}, Rest}; - - {ok, {<<"\t"/utf8>>, Rest}} -> - {{Name, Value}, Rest}; - - {ok, {Grapheme, Rest@1}} -> - parse_rfc_2045_parameter_unquoted_value( - Rest@1, - Name, - <<Value/binary, Grapheme/binary>> - ) - end. - --spec parse_rfc_2045_parameter_value(binary(), binary()) -> {ok, - {{binary(), binary()}, binary()}} | - {error, nil}. -parse_rfc_2045_parameter_value(Header, Name) -> - case gleam@string:pop_grapheme(Header) of - {error, nil} -> - {error, nil}; - - {ok, {<<"\""/utf8>>, Rest}} -> - parse_rfc_2045_parameter_quoted_value(Rest, Name, <<""/utf8>>); - - {ok, {Grapheme, Rest@1}} -> - {ok, - parse_rfc_2045_parameter_unquoted_value(Rest@1, Name, Grapheme)} - end. - --spec parse_rfc_2045_parameter(binary(), binary()) -> {ok, - {{binary(), binary()}, binary()}} | - {error, nil}. -parse_rfc_2045_parameter(Header, Name) -> - gleam@result:'try'( - gleam@string:pop_grapheme(Header), - fun(_use0) -> - {Grapheme, Rest} = _use0, - case Grapheme of - <<"="/utf8>> -> - parse_rfc_2045_parameter_value(Rest, Name); - - _ -> - parse_rfc_2045_parameter( - Rest, - <<Name/binary, - (gleam@string:lowercase(Grapheme))/binary>> - ) - end - end - ). - --spec parse_rfc_2045_parameters(binary(), list({binary(), binary()})) -> {ok, - list({binary(), binary()})} | - {error, nil}. -parse_rfc_2045_parameters(Header, Parameters) -> - case gleam@string:pop_grapheme(Header) of - {error, nil} -> - {ok, gleam@list:reverse(Parameters)}; - - {ok, {<<";"/utf8>>, Rest}} -> - parse_rfc_2045_parameters(Rest, Parameters); - - {ok, {<<" "/utf8>>, Rest}} -> - parse_rfc_2045_parameters(Rest, Parameters); - - {ok, {<<"\t"/utf8>>, Rest}} -> - parse_rfc_2045_parameters(Rest, Parameters); - - {ok, {Grapheme, Rest@1}} -> - Acc = gleam@string:lowercase(Grapheme), - gleam@result:'try'( - parse_rfc_2045_parameter(Rest@1, Acc), - fun(_use0) -> - {Parameter, Rest@2} = _use0, - parse_rfc_2045_parameters(Rest@2, [Parameter | Parameters]) - end - ) - end. - --spec parse_content_disposition_type(binary(), binary()) -> {ok, - content_disposition()} | - {error, nil}. -parse_content_disposition_type(Header, Name) -> - case gleam@string:pop_grapheme(Header) of - {error, nil} -> - {ok, {content_disposition, Name, []}}; - - {ok, {<<" "/utf8>>, Rest}} -> - Result = parse_rfc_2045_parameters(Rest, []), - gleam@result:map( - Result, - fun(Parameters) -> {content_disposition, Name, Parameters} end - ); - - {ok, {<<"\t"/utf8>>, Rest}} -> - Result = parse_rfc_2045_parameters(Rest, []), - gleam@result:map( - Result, - fun(Parameters) -> {content_disposition, Name, Parameters} end - ); - - {ok, {<<";"/utf8>>, Rest}} -> - Result = parse_rfc_2045_parameters(Rest, []), - gleam@result:map( - Result, - fun(Parameters) -> {content_disposition, Name, Parameters} end - ); - - {ok, {Grapheme, Rest@1}} -> - parse_content_disposition_type( - Rest@1, - <<Name/binary, (gleam@string:lowercase(Grapheme))/binary>> - ) - end. - --spec parse_content_disposition(binary()) -> {ok, content_disposition()} | - {error, nil}. -parse_content_disposition(Header) -> - parse_content_disposition_type(Header, <<""/utf8>>). - --spec more_please_body( - fun((bitstring()) -> {ok, multipart_body()} | {error, nil}), - bitstring(), - bitstring() -) -> {ok, multipart_body()} | {error, nil}. -more_please_body(Continuation, Chunk, Existing) -> - _pipe = fun(More) -> - gleam@bool:guard( - More =:= <<>>, - {error, nil}, - fun() -> Continuation(<<Existing/bitstring, More/bitstring>>) end - ) - end, - _pipe@1 = {more_required_for_body, Chunk, _pipe}, - {ok, _pipe@1}. - --spec parse_body_loop(bitstring(), bitstring(), bitstring()) -> {ok, - multipart_body()} | - {error, nil}. -parse_body_loop(Data, Boundary, Body) -> - Dsize = erlang:byte_size(Data), - Bsize = erlang:byte_size(Boundary), - Required = 6 + Bsize, - case Data of - _ when Dsize < Required -> - more_please_body( - fun(_capture) -> parse_body_loop(_capture, Boundary, <<>>) end, - Body, - Data - ); - - <<13, 10, Data@1/binary>> -> - Desired = <<45, 45, Boundary/bitstring>>, - Size = erlang:byte_size(Desired), - Dsize@1 = erlang:byte_size(Data@1), - Prefix = gleam_stdlib:bit_array_slice(Data@1, 0, Size), - Rest = gleam_stdlib:bit_array_slice(Data@1, Size, Dsize@1 - Size), - case {Prefix =:= {ok, Desired}, Rest} of - {true, {ok, <<13, 10, _/binary>>}} -> - {ok, {multipart_body, Body, false, Data@1}}; - - {true, {ok, <<45, 45, Data@2/binary>>}} -> - {ok, {multipart_body, Body, true, Data@2}}; - - {false, _} -> - parse_body_loop( - Data@1, - Boundary, - <<Body/bitstring, 13, 10>> - ); - - {_, _} -> - {error, nil} - end; - - <<Char, Data@3/binary>> -> - parse_body_loop(Data@3, Boundary, <<Body/bitstring, Char>>) - end. - --spec parse_body_with_bit_array(bitstring(), bitstring()) -> {ok, - multipart_body()} | - {error, nil}. -parse_body_with_bit_array(Data, Boundary) -> - Bsize = erlang:byte_size(Boundary), - Prefix = gleam_stdlib:bit_array_slice(Data, 0, 2 + Bsize), - case Prefix =:= {ok, <<45, 45, Boundary/bitstring>>} of - true -> - {ok, {multipart_body, <<>>, false, Data}}; - - false -> - parse_body_loop(Data, Boundary, <<>>) - end. - --spec parse_multipart_body(bitstring(), binary()) -> {ok, multipart_body()} | - {error, nil}. -parse_multipart_body(Data, Boundary) -> - _pipe = Boundary, - _pipe@1 = gleam_stdlib:identity(_pipe), - parse_body_with_bit_array(Data, _pipe@1). - --spec method_from_dynamic(gleam@dynamic:dynamic_()) -> {ok, method()} | - {error, list(gleam@dynamic:decode_error())}. -method_from_dynamic(Value) -> - case gleam_http_native:decode_method(Value) of - {ok, Method} -> - {ok, Method}; - - {error, _} -> - {error, - [{decode_error, - <<"HTTP method"/utf8>>, - gleam@dynamic:classify(Value), - []}]} - end. - --spec parse_header_value( - bitstring(), - list({binary(), binary()}), - bitstring(), - bitstring() -) -> {ok, multipart_headers()} | {error, nil}. -parse_header_value(Data, Headers, Name, Value) -> - Size = erlang:byte_size(Data), - case Data of - _ when Size < 4 -> - _pipe@2 = fun(Data@1) -> _pipe = Data@1, - _pipe@1 = skip_whitespace(_pipe), - parse_header_value(_pipe@1, Headers, Name, Value) end, - more_please_headers(_pipe@2, Data); - - <<13, 10, 13, 10, Data@2/binary>> -> - gleam@result:'try'( - gleam@bit_array:to_string(Name), - fun(Name@1) -> - gleam@result:map( - gleam@bit_array:to_string(Value), - fun(Value@1) -> - Headers@1 = gleam@list:reverse( - [{gleam@string:lowercase(Name@1), Value@1} | - Headers] - ), - {multipart_headers, Headers@1, Data@2} - end - ) - end - ); - - <<13, 10, 32, Data@3/binary>> -> - parse_header_value(Data@3, Headers, Name, Value); - - <<13, 10, 9, Data@3/binary>> -> - parse_header_value(Data@3, Headers, Name, Value); - - <<13, 10, Data@4/binary>> -> - gleam@result:'try'( - gleam@bit_array:to_string(Name), - fun(Name@2) -> - gleam@result:'try'( - gleam@bit_array:to_string(Value), - fun(Value@2) -> - Headers@2 = [{gleam@string:lowercase(Name@2), - Value@2} | - Headers], - parse_header_name(Data@4, Headers@2, <<>>) - end - ) - end - ); - - <<Char, Rest/binary>> -> - Value@3 = <<Value/bitstring, Char>>, - parse_header_value(Rest, Headers, Name, Value@3); - - _ -> - {error, nil} - end. - --spec parse_header_name(bitstring(), list({binary(), binary()}), bitstring()) -> {ok, - multipart_headers()} | - {error, nil}. -parse_header_name(Data, Headers, Name) -> - case skip_whitespace(Data) of - <<58, Data@1/binary>> -> - _pipe = Data@1, - _pipe@1 = skip_whitespace(_pipe), - parse_header_value(_pipe@1, Headers, Name, <<>>); - - <<Char, Data@2/binary>> -> - parse_header_name(Data@2, Headers, <<Name/bitstring, Char>>); - - <<>> -> - more_please_headers( - fun(_capture) -> parse_header_name(_capture, Headers, Name) end, - Data - ) - end. - --spec do_parse_headers(bitstring()) -> {ok, multipart_headers()} | {error, nil}. -do_parse_headers(Data) -> - case Data of - <<13, 10, 13, 10, Data@1/binary>> -> - {ok, {multipart_headers, [], Data@1}}; - - <<13, 10, Data@2/binary>> -> - parse_header_name(Data@2, [], <<>>); - - <<13>> -> - more_please_headers(fun do_parse_headers/1, Data); - - <<>> -> - more_please_headers(fun do_parse_headers/1, Data); - - _ -> - {error, nil} - end. - --spec parse_headers_after_prelude(bitstring(), bitstring()) -> {ok, - multipart_headers()} | - {error, nil}. -parse_headers_after_prelude(Data, Boundary) -> - Dsize = erlang:byte_size(Data), - Bsize = erlang:byte_size(Boundary), - Required_size = Bsize + 4, - gleam@bool:guard( - Dsize < Required_size, - more_please_headers( - fun(_capture) -> parse_headers_after_prelude(_capture, Boundary) end, - Data - ), - fun() -> - gleam@result:'try'( - gleam_stdlib:bit_array_slice(Data, 0, Required_size - 2), - fun(Prefix) -> - gleam@result:'try'( - gleam_stdlib:bit_array_slice(Data, 2 + Bsize, 2), - fun(Second) -> - Desired = <<45, 45, Boundary/bitstring>>, - gleam@bool:guard( - Prefix /= Desired, - {error, nil}, - fun() -> case Second =:= <<45, 45>> of - true -> - Rest_size = Dsize - Required_size, - gleam@result:map( - gleam_stdlib:bit_array_slice( - Data, - Required_size, - Rest_size - ), - fun(Data@1) -> - {multipart_headers, - [], - Data@1} - end - ); - - false -> - Start = Required_size - 2, - Rest_size@1 = (Dsize - Required_size) - + 2, - gleam@result:'try'( - gleam_stdlib:bit_array_slice( - Data, - Start, - Rest_size@1 - ), - fun(Data@2) -> - do_parse_headers(Data@2) - end - ) - end end - ) - end - ) - end - ) - end - ). - --spec skip_preamble(bitstring(), bitstring()) -> {ok, multipart_headers()} | - {error, nil}. -skip_preamble(Data, Boundary) -> - Data_size = erlang:byte_size(Data), - Boundary_size = erlang:byte_size(Boundary), - Required = Boundary_size + 4, - case Data of - _ when Data_size < Required -> - more_please_headers( - fun(_capture) -> skip_preamble(_capture, Boundary) end, - Data - ); - - <<13, 10, 45, 45, Data@1/binary>> -> - case gleam_stdlib:bit_array_slice(Data@1, 0, Boundary_size) of - {ok, Prefix} when Prefix =:= Boundary -> - Start = Boundary_size, - Length = erlang:byte_size(Data@1) - Boundary_size, - gleam@result:'try'( - gleam_stdlib:bit_array_slice(Data@1, Start, Length), - fun(Rest) -> do_parse_headers(Rest) end - ); - - {ok, _} -> - skip_preamble(Data@1, Boundary); - - {error, _} -> - {error, nil} - end; - - <<_, Data@2/binary>> -> - skip_preamble(Data@2, Boundary) - end. - --spec parse_multipart_headers(bitstring(), binary()) -> {ok, - multipart_headers()} | - {error, nil}. -parse_multipart_headers(Data, Boundary) -> - Boundary@1 = gleam_stdlib:identity(Boundary), - Prefix = <<45, 45, Boundary@1/bitstring>>, - case gleam_stdlib:bit_array_slice(Data, 0, erlang:byte_size(Prefix)) =:= {ok, - Prefix} of - true -> - parse_headers_after_prelude(Data, Boundary@1); - - false -> - skip_preamble(Data, Boundary@1) - end. diff --git a/aoc2023/build/packages/gleam_http/src/gleam@http@cookie.erl b/aoc2023/build/packages/gleam_http/src/gleam@http@cookie.erl deleted file mode 100644 index 9d6d13e..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam@http@cookie.erl +++ /dev/null @@ -1,153 +0,0 @@ --module(gleam@http@cookie). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([defaults/1, set_header/3, parse/1]). --export_type([same_site_policy/0, attributes/0]). - --type same_site_policy() :: lax | strict | none. - --type attributes() :: {attributes, - gleam@option:option(integer()), - gleam@option:option(binary()), - gleam@option:option(binary()), - boolean(), - boolean(), - gleam@option:option(same_site_policy())}. - --spec same_site_to_string(same_site_policy()) -> binary(). -same_site_to_string(Policy) -> - case Policy of - lax -> - <<"Lax"/utf8>>; - - strict -> - <<"Strict"/utf8>>; - - none -> - <<"None"/utf8>> - end. - --spec defaults(gleam@http:scheme()) -> attributes(). -defaults(Scheme) -> - {attributes, - none, - none, - {some, <<"/"/utf8>>}, - Scheme =:= https, - true, - {some, lax}}. - --spec cookie_attributes_to_list(attributes()) -> list(list(binary())). -cookie_attributes_to_list(Attributes) -> - {attributes, Max_age, Domain, Path, Secure, Http_only, Same_site} = Attributes, - _pipe = [case Max_age of - {some, 0} -> - {some, [<<"Expires=Thu, 01 Jan 1970 00:00:00 GMT"/utf8>>]}; - - _ -> - none - end, gleam@option:map( - Max_age, - fun(Max_age@1) -> - [<<"Max-Age="/utf8>>, gleam@int:to_string(Max_age@1)] - end - ), gleam@option:map( - Domain, - fun(Domain@1) -> [<<"Domain="/utf8>>, Domain@1] end - ), gleam@option:map(Path, fun(Path@1) -> [<<"Path="/utf8>>, Path@1] end), case Secure of - true -> - {some, [<<"Secure"/utf8>>]}; - - false -> - none - end, case Http_only of - true -> - {some, [<<"HttpOnly"/utf8>>]}; - - false -> - none - end, gleam@option:map( - Same_site, - fun(Same_site@1) -> - [<<"SameSite="/utf8>>, same_site_to_string(Same_site@1)] - end - )], - gleam@list:filter_map( - _pipe, - fun(_capture) -> gleam@option:to_result(_capture, nil) end - ). - --spec set_header(binary(), binary(), attributes()) -> binary(). -set_header(Name, Value, Attributes) -> - _pipe = [[Name, <<"="/utf8>>, Value] | - cookie_attributes_to_list(Attributes)], - _pipe@1 = gleam@list:map( - _pipe, - fun(_capture) -> gleam@string:join(_capture, <<""/utf8>>) end - ), - gleam@string:join(_pipe@1, <<"; "/utf8>>). - --spec check_token(binary()) -> {ok, nil} | {error, nil}. -check_token(Token) -> - case gleam@string:pop_grapheme(Token) of - {error, nil} -> - {ok, nil}; - - {ok, {<<" "/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\t"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\r"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\n"/utf8>>, _}} -> - {error, nil}; - - {ok, {<<"\f"/utf8>>, _}} -> - {error, nil}; - - {ok, {_, Rest}} -> - check_token(Rest) - end. - --spec parse(binary()) -> list({binary(), binary()}). -parse(Cookie_string) -> - _assert_subject = gleam@regex:from_string(<<"[,;]"/utf8>>), - {ok, Re} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/http/cookie"/utf8>>, - function => <<"parse"/utf8>>, - line => 101}) - end, - _pipe = gleam@regex:split(Re, Cookie_string), - gleam@list:filter_map( - _pipe, - fun(Pair) -> - case gleam@string:split_once(gleam@string:trim(Pair), <<"="/utf8>>) of - {ok, {<<""/utf8>>, _}} -> - {error, nil}; - - {ok, {Key, Value}} -> - Key@1 = gleam@string:trim(Key), - Value@1 = gleam@string:trim(Value), - gleam@result:then( - check_token(Key@1), - fun(_) -> - gleam@result:then( - check_token(Value@1), - fun(_) -> {ok, {Key@1, Value@1}} end - ) - end - ); - - {error, nil} -> - {error, nil} - end - end - ). diff --git a/aoc2023/build/packages/gleam_http/src/gleam@http@request.erl b/aoc2023/build/packages/gleam_http/src/gleam@http@request.erl deleted file mode 100644 index 630788d..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam@http@request.erl +++ /dev/null @@ -1,202 +0,0 @@ --module(gleam@http@request). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([to_uri/1, from_uri/1, get_header/2, set_header/3, prepend_header/3, set_body/2, map/2, path_segments/1, get_query/1, set_query/2, set_method/2, new/0, to/1, set_scheme/2, set_host/2, set_port/2, set_path/2, set_cookie/3, get_cookies/1]). --export_type([request/1]). - --type request(FYJ) :: {request, - gleam@http:method(), - list({binary(), binary()}), - FYJ, - gleam@http:scheme(), - binary(), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary())}. - --spec to_uri(request(any())) -> gleam@uri:uri(). -to_uri(Request) -> - {uri, - {some, gleam@http:scheme_to_string(erlang:element(5, Request))}, - none, - {some, erlang:element(6, Request)}, - erlang:element(7, Request), - erlang:element(8, Request), - erlang:element(9, Request), - none}. - --spec from_uri(gleam@uri:uri()) -> {ok, request(binary())} | {error, nil}. -from_uri(Uri) -> - gleam@result:then( - begin - _pipe = erlang:element(2, Uri), - _pipe@1 = gleam@option:unwrap(_pipe, <<""/utf8>>), - gleam@http:scheme_from_string(_pipe@1) - end, - fun(Scheme) -> - gleam@result:then( - begin - _pipe@2 = erlang:element(4, Uri), - gleam@option:to_result(_pipe@2, nil) - end, - fun(Host) -> - Req = {request, - get, - [], - <<""/utf8>>, - Scheme, - Host, - erlang:element(5, Uri), - erlang:element(6, Uri), - erlang:element(7, Uri)}, - {ok, Req} - end - ) - end - ). - --spec get_header(request(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Request, Key) -> - gleam@list:key_find(erlang:element(3, Request), gleam@string:lowercase(Key)). - --spec set_header(request(FYT), binary(), binary()) -> request(FYT). -set_header(Request, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Request), - gleam@string:lowercase(Key), - Value - ), - erlang:setelement(3, Request, Headers). - --spec prepend_header(request(FYW), binary(), binary()) -> request(FYW). -prepend_header(Request, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Request)], - erlang:setelement(3, Request, Headers). - --spec set_body(request(any()), FZB) -> request(FZB). -set_body(Req, Body) -> - {request, Method, Headers, _, Scheme, Host, Port, Path, Query} = Req, - {request, Method, Headers, Body, Scheme, Host, Port, Path, Query}. - --spec map(request(FZD), fun((FZD) -> FZF)) -> request(FZF). -map(Request, Transform) -> - _pipe = erlang:element(4, Request), - _pipe@1 = Transform(_pipe), - set_body(Request, _pipe@1). - --spec path_segments(request(any())) -> list(binary()). -path_segments(Request) -> - _pipe = erlang:element(8, Request), - gleam@uri:path_segments(_pipe). - --spec get_query(request(any())) -> {ok, list({binary(), binary()})} | - {error, nil}. -get_query(Request) -> - case erlang:element(9, Request) of - {some, Query_string} -> - gleam@uri:parse_query(Query_string); - - none -> - {ok, []} - end. - --spec set_query(request(FZP), list({binary(), binary()})) -> request(FZP). -set_query(Req, Query) -> - Pair = fun(T) -> - gleam@string_builder:from_strings( - [erlang:element(1, T), <<"="/utf8>>, erlang:element(2, T)] - ) - end, - Query@1 = begin - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, Pair), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - _pipe@4 = gleam@string_builder:to_string(_pipe@3), - {some, _pipe@4} - end, - erlang:setelement(9, Req, Query@1). - --spec set_method(request(FZT), gleam@http:method()) -> request(FZT). -set_method(Req, Method) -> - erlang:setelement(2, Req, Method). - --spec new() -> request(binary()). -new() -> - {request, - get, - [], - <<""/utf8>>, - https, - <<"localhost"/utf8>>, - none, - <<""/utf8>>, - none}. - --spec to(binary()) -> {ok, request(binary())} | {error, nil}. -to(Url) -> - _pipe = Url, - _pipe@1 = gleam@uri:parse(_pipe), - gleam@result:then(_pipe@1, fun from_uri/1). - --spec set_scheme(request(GAA), gleam@http:scheme()) -> request(GAA). -set_scheme(Req, Scheme) -> - erlang:setelement(5, Req, Scheme). - --spec set_host(request(GAD), binary()) -> request(GAD). -set_host(Req, Host) -> - erlang:setelement(6, Req, Host). - --spec set_port(request(GAG), integer()) -> request(GAG). -set_port(Req, Port) -> - erlang:setelement(7, Req, {some, Port}). - --spec set_path(request(GAJ), binary()) -> request(GAJ). -set_path(Req, Path) -> - erlang:setelement(8, Req, Path). - --spec set_cookie(request(GAM), binary(), binary()) -> request(GAM). -set_cookie(Req, Name, Value) -> - New_cookie_string = gleam@string:join([Name, Value], <<"="/utf8>>), - {Cookies_string@2, Headers@1} = case gleam@list:key_pop( - erlang:element(3, Req), - <<"cookie"/utf8>> - ) of - {ok, {Cookies_string, Headers}} -> - Cookies_string@1 = gleam@string:join( - [Cookies_string, New_cookie_string], - <<"; "/utf8>> - ), - {Cookies_string@1, Headers}; - - {error, nil} -> - {New_cookie_string, erlang:element(3, Req)} - end, - erlang:setelement( - 3, - Req, - [{<<"cookie"/utf8>>, Cookies_string@2} | Headers@1] - ). - --spec get_cookies(request(any())) -> list({binary(), binary()}). -get_cookies(Req) -> - {request, _, Headers, _, _, _, _, _, _} = Req, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). diff --git a/aoc2023/build/packages/gleam_http/src/gleam@http@response.erl b/aoc2023/build/packages/gleam_http/src/gleam@http@response.erl deleted file mode 100644 index b073c1d..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam@http@response.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@http@response). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/1, get_header/2, set_header/3, prepend_header/3, set_body/2, try_map/2, map/2, redirect/1, get_cookies/1, set_cookie/4, expire_cookie/3]). --export_type([response/1]). - --type response(GFN) :: {response, integer(), list({binary(), binary()}), GFN}. - --spec new(integer()) -> response(binary()). -new(Status) -> - {response, Status, [], <<""/utf8>>}. - --spec get_header(response(any()), binary()) -> {ok, binary()} | {error, nil}. -get_header(Response, Key) -> - gleam@list:key_find( - erlang:element(3, Response), - gleam@string:lowercase(Key) - ). - --spec set_header(response(GGC), binary(), binary()) -> response(GGC). -set_header(Response, Key, Value) -> - Headers = gleam@list:key_set( - erlang:element(3, Response), - gleam@string:lowercase(Key), - Value - ), - erlang:setelement(3, Response, Headers). - --spec prepend_header(response(GGF), binary(), binary()) -> response(GGF). -prepend_header(Response, Key, Value) -> - Headers = [{gleam@string:lowercase(Key), Value} | - erlang:element(3, Response)], - erlang:setelement(3, Response, Headers). - --spec set_body(response(any()), GGK) -> response(GGK). -set_body(Response, Body) -> - {response, Status, Headers, _} = Response, - {response, Status, Headers, Body}. - --spec try_map(response(GFO), fun((GFO) -> {ok, GFQ} | {error, GFR})) -> {ok, - response(GFQ)} | - {error, GFR}. -try_map(Response, Transform) -> - gleam@result:then( - Transform(erlang:element(4, Response)), - fun(Body) -> {ok, set_body(Response, Body)} end - ). - --spec map(response(GGM), fun((GGM) -> GGO)) -> response(GGO). -map(Response, Transform) -> - _pipe = erlang:element(4, Response), - _pipe@1 = Transform(_pipe), - set_body(Response, _pipe@1). - --spec redirect(binary()) -> response(binary()). -redirect(Uri) -> - {response, - 303, - [{<<"location"/utf8>>, Uri}], - gleam@string:append(<<"You are being redirected to "/utf8>>, Uri)}. - --spec get_cookies(response(any())) -> list({binary(), binary()}). -get_cookies(Resp) -> - {response, _, Headers, _} = Resp, - _pipe = Headers, - _pipe@1 = gleam@list:filter_map( - _pipe, - fun(Header) -> - {Name, Value} = Header, - case Name of - <<"set-cookie"/utf8>> -> - {ok, gleam@http@cookie:parse(Value)}; - - _ -> - {error, nil} - end - end - ), - gleam@list:flatten(_pipe@1). - --spec set_cookie( - response(GGT), - binary(), - binary(), - gleam@http@cookie:attributes() -) -> response(GGT). -set_cookie(Response, Name, Value, Attributes) -> - prepend_header( - Response, - <<"set-cookie"/utf8>>, - gleam@http@cookie:set_header(Name, Value, Attributes) - ). - --spec expire_cookie(response(GGW), binary(), gleam@http@cookie:attributes()) -> response(GGW). -expire_cookie(Response, Name, Attributes) -> - Attrs = erlang:setelement(2, Attributes, {some, 0}), - set_cookie(Response, Name, <<""/utf8>>, Attrs). diff --git a/aoc2023/build/packages/gleam_http/src/gleam@http@service.erl b/aoc2023/build/packages/gleam_http/src/gleam@http@service.erl deleted file mode 100644 index d07b31f..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam@http@service.erl +++ /dev/null @@ -1,82 +0,0 @@ --module(gleam@http@service). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([map_response_body/2, prepend_response_header/3, method_override/1]). - --spec map_response_body( - fun((gleam@http@request:request(GJL)) -> gleam@http@response:response(GJM)), - fun((GJM) -> GJP) -) -> fun((gleam@http@request:request(GJL)) -> gleam@http@response:response(GJP)). -map_response_body(Service, Mapper) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:map(_pipe@1, Mapper) end. - --spec prepend_response_header( - fun((gleam@http@request:request(GJS)) -> gleam@http@response:response(GJT)), - binary(), - binary() -) -> fun((gleam@http@request:request(GJS)) -> gleam@http@response:response(GJT)). -prepend_response_header(Service, Key, Value) -> - fun(Req) -> _pipe = Req, - _pipe@1 = Service(_pipe), - gleam@http@response:prepend_header(_pipe@1, Key, Value) end. - --spec ensure_post(gleam@http@request:request(GJY)) -> {ok, - gleam@http@request:request(GJY)} | - {error, nil}. -ensure_post(Req) -> - case erlang:element(2, Req) of - post -> - {ok, Req}; - - _ -> - {error, nil} - end. - --spec get_override_method(gleam@http@request:request(any())) -> {ok, - gleam@http:method()} | - {error, nil}. -get_override_method(Request) -> - gleam@result:then( - gleam@http@request:get_query(Request), - fun(Query_params) -> - gleam@result:then( - gleam@list:key_find(Query_params, <<"_method"/utf8>>), - fun(Method) -> - gleam@result:then( - gleam@http:parse_method(Method), - fun(Method@1) -> case Method@1 of - put -> - {ok, Method@1}; - - patch -> - {ok, Method@1}; - - delete -> - {ok, Method@1}; - - _ -> - {error, nil} - end end - ) - end - ) - end - ). - --spec method_override( - fun((gleam@http@request:request(GKF)) -> gleam@http@response:response(GKG)) -) -> fun((gleam@http@request:request(GKF)) -> gleam@http@response:response(GKG)). -method_override(Service) -> - fun(Request) -> _pipe = Request, - _pipe@1 = ensure_post(_pipe), - _pipe@2 = gleam@result:then(_pipe@1, fun get_override_method/1), - _pipe@3 = gleam@result:map( - _pipe@2, - fun(_capture) -> - gleam@http@request:set_method(Request, _capture) - end - ), - _pipe@4 = gleam@result:unwrap(_pipe@3, Request), - Service(_pipe@4) end. diff --git a/aoc2023/build/packages/gleam_http/src/gleam_http.app.src b/aoc2023/build/packages/gleam_http/src/gleam_http.app.src deleted file mode 100644 index c37ad54..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam_http.app.src +++ /dev/null @@ -1,12 +0,0 @@ -{application, gleam_http, [ - {vsn, "3.5.2"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Types and functions for Gleam HTTP clients and servers"}, - {modules, [gleam@http, - gleam@http@cookie, - gleam@http@request, - gleam@http@response, - gleam@http@service]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_http/src/gleam_http_native.erl b/aoc2023/build/packages/gleam_http/src/gleam_http_native.erl deleted file mode 100644 index bb499bb..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam_http_native.erl +++ /dev/null @@ -1,88 +0,0 @@ --module(gleam_http_native). --export([decode_method/1]). - -decode_method(Term) -> - case Term of - "connect" -> {ok, connect}; - "delete" -> {ok, delete}; - "get" -> {ok, get}; - "head" -> {ok, head}; - "options" -> {ok, options}; - "patch" -> {ok, patch}; - "post" -> {ok, post}; - "put" -> {ok, put}; - "trace" -> {ok, trace}; - "CONNECT" -> {ok, connect}; - "DELETE" -> {ok, delete}; - "GET" -> {ok, get}; - "HEAD" -> {ok, head}; - "OPTIONS" -> {ok, options}; - "PATCH" -> {ok, patch}; - "POST" -> {ok, post}; - "PUT" -> {ok, put}; - "TRACE" -> {ok, trace}; - "Connect" -> {ok, connect}; - "Delete" -> {ok, delete}; - "Get" -> {ok, get}; - "Head" -> {ok, head}; - "Options" -> {ok, options}; - "Patch" -> {ok, patch}; - "Post" -> {ok, post}; - "Put" -> {ok, put}; - "Trace" -> {ok, trace}; - 'connect' -> {ok, connect}; - 'delete' -> {ok, delete}; - 'get' -> {ok, get}; - 'head' -> {ok, head}; - 'options' -> {ok, options}; - 'patch' -> {ok, patch}; - 'post' -> {ok, post}; - 'put' -> {ok, put}; - 'trace' -> {ok, trace}; - 'CONNECT' -> {ok, connect}; - 'DELETE' -> {ok, delete}; - 'GET' -> {ok, get}; - 'HEAD' -> {ok, head}; - 'OPTIONS' -> {ok, options}; - 'PATCH' -> {ok, patch}; - 'POST' -> {ok, post}; - 'PUT' -> {ok, put}; - 'TRACE' -> {ok, trace}; - 'Connect' -> {ok, connect}; - 'Delete' -> {ok, delete}; - 'Get' -> {ok, get}; - 'Head' -> {ok, head}; - 'Options' -> {ok, options}; - 'Patch' -> {ok, patch}; - 'Post' -> {ok, post}; - 'Put' -> {ok, put}; - 'Trace' -> {ok, trace}; - <<"connect">> -> {ok, connect}; - <<"delete">> -> {ok, delete}; - <<"get">> -> {ok, get}; - <<"head">> -> {ok, head}; - <<"options">> -> {ok, options}; - <<"patch">> -> {ok, patch}; - <<"post">> -> {ok, post}; - <<"put">> -> {ok, put}; - <<"trace">> -> {ok, trace}; - <<"CONNECT">> -> {ok, connect}; - <<"DELETE">> -> {ok, delete}; - <<"GET">> -> {ok, get}; - <<"HEAD">> -> {ok, head}; - <<"OPTIONS">> -> {ok, options}; - <<"PATCH">> -> {ok, patch}; - <<"POST">> -> {ok, post}; - <<"PUT">> -> {ok, put}; - <<"TRACE">> -> {ok, trace}; - <<"Connect">> -> {ok, connect}; - <<"Delete">> -> {ok, delete}; - <<"Get">> -> {ok, get}; - <<"Head">> -> {ok, head}; - <<"Options">> -> {ok, options}; - <<"Patch">> -> {ok, patch}; - <<"Post">> -> {ok, post}; - <<"Put">> -> {ok, put}; - <<"Trace">> -> {ok, trace}; - _ -> {error, nil} - end. diff --git a/aoc2023/build/packages/gleam_http/src/gleam_http_native.mjs b/aoc2023/build/packages/gleam_http/src/gleam_http_native.mjs deleted file mode 100644 index c871a8b..0000000 --- a/aoc2023/build/packages/gleam_http/src/gleam_http_native.mjs +++ /dev/null @@ -1,38 +0,0 @@ -import { Ok, Error } from "./gleam.mjs"; -import { - Get, - Post, - Head, - Put, - Delete, - Trace, - Connect, - Options, - Patch, -} from "./gleam/http.mjs"; - -export function decode_method(value) { - try { - switch (value.toLowerCase()) { - case "get": - return new Ok(new Get()); - case "post": - return new Ok(new Post()); - case "head": - return new Ok(new Head()); - case "put": - return new Ok(new Put()); - case "delete": - return new Ok(new Delete()); - case "trace": - return new Ok(new Trace()); - case "connect": - return new Ok(new Connect()); - case "options": - return new Ok(new Options()); - case "patch": - return new Ok(new Patch()); - } - } catch {} - return new Error(undefined); -} diff --git a/aoc2023/build/packages/gleam_httpc/LICENSE b/aoc2023/build/packages/gleam_httpc/LICENSE deleted file mode 100644 index 59e1345..0000000 --- a/aoc2023/build/packages/gleam_httpc/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright {{copyright_year}}, {{author_name}} <{{author_email}}>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/aoc2023/build/packages/gleam_httpc/README.md b/aoc2023/build/packages/gleam_httpc/README.md deleted file mode 100644 index c2363c5..0000000 --- a/aoc2023/build/packages/gleam_httpc/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# httpc -<a href="https://github.com/gleam-lang/httpc/releases"><img src="https://img.shields.io/github/release/gleam-lang/httpc" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> - - -Bindings to Erlang's built in HTTP client, `httpc`. - -```gleam -import gleam/httpc -import gleam/http.{Get} -import gleam/http/request -import gleam/http/response -import gleeunit/should - -pub fn main() { - // Prepare a HTTP request record - let request = request.new() - |> request.set_method(Get) - |> request.set_host("test-api.service.hmrc.gov.uk") - |> request.set_path("/hello/world") - |> request.prepend_header("accept", "application/vnd.hmrc.1.0+json") - - // Send the HTTP request to the server - try resp = httpc.send(req) - - // We get a response record back - resp.status - |> should.equal(200) - - resp - |> response.get_header("content-type") - |> should.equal(Ok("application/json")) - - resp.body - |> should.equal("{\"message\":\"Hello World\"}") - - Ok(resp) -} -``` - -## Installation - -```shell -gleam add gleam_httpc -``` - -## Use with Erlang/OTP versions older than 26.0 - -Older versions of HTTPC do not verify TLS connections by default, so with them -your connection may not be secure when using this library. Consider upgrading to -a newer version of Erlang/OTP, or using a different HTTP client such as -[hackney](https://github.com/gleam-lang/hackney). diff --git a/aoc2023/build/packages/gleam_httpc/gleam.toml b/aoc2023/build/packages/gleam_httpc/gleam.toml deleted file mode 100644 index d623a94..0000000 --- a/aoc2023/build/packages/gleam_httpc/gleam.toml +++ /dev/null @@ -1,23 +0,0 @@ -name = "gleam_httpc" -version = "2.1.1" -gleam = ">= 0.32.0" - -licences = ["Apache-2.0"] -description = "Gleam bindings to Erlang's built in HTTP client, httpc" - -repository = { type = "github", user = "gleam-lang", repo = "httpc" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[erlang] -extra_applications = ["inets", "ssl"] - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_http = "~> 3.0" - -[dev-dependencies] -gleeunit = "~> 0.6" -gleam_erlang = "~> 0.9" diff --git a/aoc2023/build/packages/gleam_httpc/src/gleam/httpc.gleam b/aoc2023/build/packages/gleam_httpc/src/gleam/httpc.gleam deleted file mode 100644 index cf166c3..0000000 --- a/aoc2023/build/packages/gleam_httpc/src/gleam/httpc.gleam +++ /dev/null @@ -1,105 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/http.{type Method} -import gleam/http/response.{type Response, Response} -import gleam/http/request.{type Request} -import gleam/bit_array -import gleam/result -import gleam/list -import gleam/uri - -type Charlist - -@external(erlang, "erlang", "binary_to_list") -fn binary_to_list(a: String) -> Charlist - -@external(erlang, "erlang", "list_to_binary") -fn list_to_binary(a: Charlist) -> String - -type ErlHttpOption - -type BodyFormat { - Binary -} - -type ErlOption { - BodyFormat(BodyFormat) -} - -@external(erlang, "httpc", "request") -fn erl_request( - a: Method, - b: #(Charlist, List(#(Charlist, Charlist)), Charlist, BitArray), - c: List(ErlHttpOption), - d: List(ErlOption), -) -> Result( - #(#(Charlist, Int, Charlist), List(#(Charlist, Charlist)), BitArray), - Dynamic, -) - -@external(erlang, "httpc", "request") -fn erl_request_no_body( - a: Method, - b: #(Charlist, List(#(Charlist, Charlist))), - c: List(ErlHttpOption), - d: List(ErlOption), -) -> Result( - #(#(Charlist, Int, Charlist), List(#(Charlist, Charlist)), BitArray), - Dynamic, -) - -fn charlist_header(header: #(String, String)) -> #(Charlist, Charlist) { - let #(k, v) = header - #(binary_to_list(k), binary_to_list(v)) -} - -fn string_header(header: #(Charlist, Charlist)) -> #(String, String) { - let #(k, v) = header - #(list_to_binary(k), list_to_binary(v)) -} - -// TODO: test -// TODO: refine error type -pub fn send_bits(req: Request(BitArray)) -> Result(Response(BitArray), Dynamic) { - let erl_url = - req - |> request.to_uri - |> uri.to_string - |> binary_to_list - let erl_headers = list.map(req.headers, charlist_header) - let erl_http_options = [] - let erl_options = [BodyFormat(Binary)] - - use response <- result.then(case req.method { - http.Options | http.Head | http.Get -> { - let erl_req = #(erl_url, erl_headers) - erl_request_no_body(req.method, erl_req, erl_http_options, erl_options) - } - _ -> { - let erl_content_type = - req - |> request.get_header("content-type") - |> result.unwrap("application/octet-stream") - |> binary_to_list - let erl_req = #(erl_url, erl_headers, erl_content_type, req.body) - erl_request(req.method, erl_req, erl_http_options, erl_options) - } - }) - - let #(#(_version, status, _status), headers, resp_body) = response - Ok(Response(status, list.map(headers, string_header), resp_body)) -} - -// TODO: test -// TODO: refine error type -pub fn send(req: Request(String)) -> Result(Response(String), Dynamic) { - use resp <- result.then( - req - |> request.map(bit_array.from_string) - |> send_bits, - ) - - case bit_array.to_string(resp.body) { - Ok(body) -> Ok(response.set_body(resp, body)) - Error(_) -> Error(dynamic.from("Response body was not valid UTF-8")) - } -} diff --git a/aoc2023/build/packages/gleam_httpc/src/gleam@httpc.erl b/aoc2023/build/packages/gleam_httpc/src/gleam@httpc.erl deleted file mode 100644 index 1d634df..0000000 --- a/aoc2023/build/packages/gleam_httpc/src/gleam@httpc.erl +++ /dev/null @@ -1,118 +0,0 @@ --module(gleam@httpc). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([send_bits/1, send/1]). --export_type([charlist/0, erl_http_option/0, body_format/0, erl_option/0]). - --type charlist() :: any(). - --type erl_http_option() :: any(). - --type body_format() :: binary. - --type erl_option() :: {body_format, body_format()}. - --spec charlist_header({binary(), binary()}) -> {charlist(), charlist()}. -charlist_header(Header) -> - {K, V} = Header, - {erlang:binary_to_list(K), erlang:binary_to_list(V)}. - --spec string_header({charlist(), charlist()}) -> {binary(), binary()}. -string_header(Header) -> - {K, V} = Header, - {erlang:list_to_binary(K), erlang:list_to_binary(V)}. - --spec send_bits(gleam@http@request:request(bitstring())) -> {ok, - gleam@http@response:response(bitstring())} | - {error, gleam@dynamic:dynamic_()}. -send_bits(Req) -> - Erl_url = begin - _pipe = Req, - _pipe@1 = gleam@http@request:to_uri(_pipe), - _pipe@2 = gleam@uri:to_string(_pipe@1), - erlang:binary_to_list(_pipe@2) - end, - Erl_headers = gleam@list:map(erlang:element(3, Req), fun charlist_header/1), - Erl_http_options = [], - Erl_options = [{body_format, binary}], - gleam@result:then(case erlang:element(2, Req) of - options -> - Erl_req = {Erl_url, Erl_headers}, - httpc:request( - erlang:element(2, Req), - Erl_req, - Erl_http_options, - Erl_options - ); - - head -> - Erl_req = {Erl_url, Erl_headers}, - httpc:request( - erlang:element(2, Req), - Erl_req, - Erl_http_options, - Erl_options - ); - - get -> - Erl_req = {Erl_url, Erl_headers}, - httpc:request( - erlang:element(2, Req), - Erl_req, - Erl_http_options, - Erl_options - ); - - _ -> - Erl_content_type = begin - _pipe@3 = Req, - _pipe@4 = gleam@http@request:get_header( - _pipe@3, - <<"content-type"/utf8>> - ), - _pipe@5 = gleam@result:unwrap( - _pipe@4, - <<"application/octet-stream"/utf8>> - ), - erlang:binary_to_list(_pipe@5) - end, - Erl_req@1 = {Erl_url, - Erl_headers, - Erl_content_type, - erlang:element(4, Req)}, - httpc:request( - erlang:element(2, Req), - Erl_req@1, - Erl_http_options, - Erl_options - ) - end, fun(Response) -> - {{_, Status, _}, Headers, Resp_body} = Response, - {ok, - {response, - Status, - gleam@list:map(Headers, fun string_header/1), - Resp_body}} - end). - --spec send(gleam@http@request:request(binary())) -> {ok, - gleam@http@response:response(binary())} | - {error, gleam@dynamic:dynamic_()}. -send(Req) -> - gleam@result:then( - begin - _pipe = Req, - _pipe@1 = gleam@http@request:map(_pipe, fun gleam_stdlib:identity/1), - send_bits(_pipe@1) - end, - fun(Resp) -> case gleam@bit_array:to_string(erlang:element(4, Resp)) of - {ok, Body} -> - {ok, gleam@http@response:set_body(Resp, Body)}; - - {error, _} -> - {error, - gleam@dynamic:from( - <<"Response body was not valid UTF-8"/utf8>> - )} - end end - ). diff --git a/aoc2023/build/packages/gleam_httpc/src/gleam_httpc.app.src b/aoc2023/build/packages/gleam_httpc/src/gleam_httpc.app.src deleted file mode 100644 index c0d2b20..0000000 --- a/aoc2023/build/packages/gleam_httpc/src/gleam_httpc.app.src +++ /dev/null @@ -1,12 +0,0 @@ -{application, gleam_httpc, [ - {vsn, "2.1.1"}, - {applications, [gleam_erlang, - gleam_http, - gleam_stdlib, - gleeunit, - inets, - ssl]}, - {description, "Gleam bindings to Erlang's built in HTTP client, httpc"}, - {modules, [gleam@httpc]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_otp/LICENCE b/aoc2023/build/packages/gleam_otp/LICENCE deleted file mode 100644 index 619ec77..0000000 --- a/aoc2023/build/packages/gleam_otp/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2019, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/aoc2023/build/packages/gleam_otp/README.md b/aoc2023/build/packages/gleam_otp/README.md deleted file mode 100644 index 3c313a1..0000000 --- a/aoc2023/build/packages/gleam_otp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Gleam OTP - -<a href="https://github.com/gleam-lang/otp/releases"><img src="https://img.shields.io/github/release/gleam-lang/otp" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> - - -A Gleam library for building fault tolerant multi-core programs using the -actor model. It is compatible with Erlang's OTP framework. - -This library is experimental and will likely have many breaking changes in the -future! - -Gleam’s actor system is built with a few primary goals: - -- Full type safety of actors and messages. -- Be compatible with Erlang’s OTP actor framework. -- Provide fault tolerance and self-healing through supervisors. -- Have equivalent performance to Erlang’s OTP. - -This library documents its abstractions and functionality, but you may also wish -to read the documentation or other material on Erlang’s OTP framework to get a -fuller understanding of OTP, the problems it solves, and and the motivations for -its design. - -## Usage - -Add this library to your Gleam project. - -```shell -gleam add gleam_otp -``` - -## Actor hierarchy - -This library provides several different types of actor that can be used in -Gleam programs. - -### Process - -The process is the lowest level building block of OTP, all other actors are -built on top of processes either directly or indirectly. Typically this -abstraction would be not be used very often in Gleam applications, favour -other actor types that provide more functionality. - -Gleam's process module is defined in the `gleam_erlang` library. - -[[Documentation]](https://hexdocs.pm/gleam_erlang/gleam/erlang/process.html) - -### Actor - -The `actor` is the most commonly used process type in Gleam and serves as a good -building block for other abstractions. Like Erlang's `gen_server` it handles -OTP's system messages automatically to enable OTP's debugging and tracing -functionality. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/actor.html) - -### Task - -A task is a kind of process that performs a single task and then shuts down. -Commonly tasks are used to convert sequential code into concurrent code by -performing computation in another process. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/task.html) - -### Supervisor - -Supervisors is a process that starts and then supervises a group of processes, -restarting them if they crash. Supervisors can start other supervisors, -resulting in a hierarchical process structure called a supervision tree, -providing fault tolerance to a Gleam application. - -[[Documentation]](https://hexdocs.pm/gleam_otp/gleam/otp/supervisor.html) - -## Limitations and known issues - -This library is experimental there are some limitations that not yet been resolved. - -- There is no support for named processes. They are untyped global mutable - variables which may be uninitialized, more research is needed to find a - suitable type safe alternative. -- There are relatively few actor abstractions provided by this library. More - will be added in the future. -- Actors do not yet support all OTP system messages. Unsupported messages are - dropped. -- Supervisors do not yet support different shutdown periods per child. In - practice this means that children that are supervisors do not get an - unlimited amount of time to shut down, as is expected in Erlang or Elixir. -- This library has not seen much testing compared to the Erlang OTP - libraries, both in terms of unit tests and real world testing in - applications. diff --git a/aoc2023/build/packages/gleam_otp/gleam.toml b/aoc2023/build/packages/gleam_otp/gleam.toml deleted file mode 100644 index 26e451b..0000000 --- a/aoc2023/build/packages/gleam_otp/gleam.toml +++ /dev/null @@ -1,19 +0,0 @@ -name = "gleam_otp" -version = "0.8.0" -licences = ["Apache-2.0"] -description = "Fault tolerant multicore Gleam programs with OTP" - -gleam = ">= 0.32.0" - -repository = { type = "github", user = "gleam-lang", repo = "otp" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.32" -gleam_erlang = "~> 0.22" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl deleted file mode 100644 index 85677d1..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Continue.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(continue, { - state :: any(), - selector :: gleam@option:option(gleam@erlang@process:selector(any())) -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl deleted file mode 100644 index 75faa95..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Ready.hrl +++ /dev/null @@ -1 +0,0 @@ --record(ready, {state :: any(), selector :: gleam@erlang@process:selector(any())}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl deleted file mode 100644 index 5287439..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@actor_Spec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(spec, { - init :: fun(() -> gleam@otp@actor:init_result(any(), any())), - init_timeout :: integer(), - loop :: fun((any(), any()) -> gleam@otp@actor:next(any(), any())) -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl deleted file mode 100644 index 3ed0b01..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@intensity_tracker_IntensityTracker.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(intensity_tracker, { - limit :: integer(), - period :: integer(), - events :: list(integer()) -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl deleted file mode 100644 index 7afd07f..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_ChildSpec.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(child_spec, { - start :: fun((any()) -> {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()}), - returning :: fun((any(), gleam@erlang@process:subject(any())) -> any()) -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl deleted file mode 100644 index b10bd9f..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@supervisor_Spec.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(spec, { - argument :: any(), - max_frequency :: integer(), - frequency_period :: integer(), - init :: fun((gleam@otp@supervisor:children(any())) -> gleam@otp@supervisor:children(any())) -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl deleted file mode 100644 index 99ab4cb..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@system_StatusInfo.hrl +++ /dev/null @@ -1,7 +0,0 @@ --record(status_info, { - module :: gleam@erlang@atom:atom_(), - parent :: gleam@erlang@process:pid_(), - mode :: gleam@otp@system:mode(), - debug_state :: gleam@otp@system:debug_state(), - state :: gleam@dynamic:dynamic_() -}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl deleted file mode 100644 index 7c83874..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Exit.hrl +++ /dev/null @@ -1 +0,0 @@ --record(exit, {reason :: gleam@dynamic:dynamic_()}). diff --git a/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl b/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl deleted file mode 100644 index 959bea8..0000000 --- a/aoc2023/build/packages/gleam_otp/include/gleam@otp@task_Task.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(task, { - owner :: gleam@erlang@process:pid_(), - pid :: gleam@erlang@process:pid_(), - monitor :: gleam@erlang@process:process_monitor(), - selector :: gleam@erlang@process:selector(gleam@otp@task:message(any())) -}). diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/actor.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/actor.gleam deleted file mode 100644 index 9f6a6c4..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/actor.gleam +++ /dev/null @@ -1,504 +0,0 @@ -//// This module provides the _Actor_ abstraction, one of the most common -//// building blocks of Gleam OTP programs. -//// -//// An Actor is a process like any other BEAM process and can be be used to hold -//// state, execute code, and communicate with other processes by sending and -//// receiving messages. The advantage of using the actor abstraction over a bare -//// process is that it provides a single interface for commonly needed -//// functionality, including support for the [tracing and debugging -//// features in OTP](erlang-sys). -//// -//// Gleam's Actor is similar to Erlang's `gen_server` and Elixir's `GenServer` -//// but differs in that it offers a fully typed interface. This different API is -//// why Gleam uses the name Actor rather than some variation of generic-server. -//// -//// [erlang-sys]: https://www.erlang.org/doc/man/sys.html -//// -//// ## Example -//// -//// An Actor can be used to create a client-server interaction between an Actor -//// (the server) and other processes (the clients). In this example we have an -//// Actor that works as a stack, allowing clients to push and pop elements. -//// -//// ```gleam -//// pub fn main() { -//// // Start the actor with initial state of an empty list, and the -//// // `handle_message` callback function (defined below). -//// // We assert that it starts successfully. -//// // -//// // In real-world Gleam OTP programs we would likely write a wrapper functions -//// // called `start`, `push` `pop`, `shutdown` to start and interact with the -//// // Actor. We are not doing that here for the sake of showing how the Actor -//// // API works. -//// let assert Ok(actor) = actor.start([], handle_message) -//// -//// // We can send a message to the actor to push elements onto the stack. -//// process.send(actor, Push("Joe")) -//// process.send(actor, Push("Mike")) -//// process.send(actor, Push("Robert")) -//// -//// // The `Push` message expects no response, these messages are sent purely for -//// // the side effect of mutating the state held by the actor. -//// // -//// // We can also send the `Pop` message to take a value off of the actor's -//// // stack. This message expects a response, so we use `process.call` to send a -//// // message and wait until a reply is received. -//// // -//// // In this instance we are giving the actor 10 milliseconds to reply, if the -//// // `call` function doesn't get a reply within this time it will panic and -//// // crash the client process. -//// let assert Ok("Robert") = process.call(actor, Pop, 10) -//// let assert Ok("Mike") = process.call(actor, Pop, 10) -//// let assert Ok("Joe") = process.call(actor, Pop, 10) -//// -//// // The stack is now empty, so if we pop again the actor replies with an error. -//// let assert Error(Nil) = process.call(actor, Pop, 10) -//// -//// // Lastly, we can send a message to the actor asking it to shut down. -//// process.send(actor, Shutdown) -//// } -//// ``` -//// -//// Here is the code that is used to implement this actor: -//// -//// ```gleam -//// // First step of implementing the stack Actor is to define the message type that -//// // it can receive. -//// // -//// // The type of the elements in the stack is no fixed so a type parameter is used -//// // for it instead of a concrete type such as `String` or `Int`. -//// pub type Message(element) { -//// // The `Shutdown` message is used to tell the actor to stop. -//// // It is the simplest message type, it contains no data. -//// Shutdown -//// -//// // The `Push` message is used to add a new element to the stack. -//// // It contains the item to add, the type of which is the `element` -//// // parameterised type. -//// Push(push: element) -//// -//// // The `Pop` message is used to remove an element from the stack. -//// // It contains a `Subject`, which is used to send the response back to the -//// // message sender. In this case the reply is of type `Result(element, Nil)`. -//// Pop(reply_with: Subject(Result(element, Nil))) -//// } -//// -//// // The last part is to implement the `handle_message` callback function. -//// // -//// // This function is called by the Actor each for each message it receives. -//// // Actor is single threaded only does one thing at a time, so it handles -//// // messages sequentially and one at a time, in the order they are received. -//// // -//// // The function takes the message and the current state, and returns a data -//// // structure that indicates what to do next, along with the new state. -//// fn handle_message( -//// message: Message(e), -//// stack: List(e), -//// ) -> actor.Next(Message(e), List(e)) { -//// case message { -//// // For the `Shutdown` message we return the `actor.Stop` value, which causes -//// // the actor to discard any remaining messages and stop. -//// Shutdown -> actor.Stop(process.Normal) -//// -//// // For the `Push` message we add the new element to the stack and return -//// // `actor.continue` with this new stack, causing the actor to process any -//// // queued messages or wait for more. -//// Push(value) -> { -//// let new_state = [value, ..stack] -//// actor.continue(new_state) -//// } -//// -//// // For the `Pop` message we attempt to remove an element from the stack, -//// // sending it or an error back to the caller, before continuing. -//// Pop(client) -> -//// case stack { -//// [] -> { -//// // When the stack is empty we can't pop an element, so we send an -//// // error back. -//// process.send(client, Error(Nil)) -//// actor.continue([]) -//// } -//// -//// [first, ..rest] -> { -//// // Otherwise we send the first element back and use the remaining -//// // elements as the new state. -//// process.send(client, Ok(first)) -//// actor.continue(rest) -//// } -//// } -//// } -//// } -//// ``` - -import gleam/erlang/process.{ - type ExitReason, type Pid, type Selector, type Subject, Abnormal, -} -import gleam/erlang/charlist.{type Charlist} -import gleam/otp/system.{ - type DebugState, type Mode, type StatusInfo, type SystemMessage, GetState, - GetStatus, Resume, Running, StatusInfo, Suspend, Suspended, -} -import gleam/string -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom -import gleam/option.{type Option, None, Some} - -type Message(message) { - /// A regular message excepted by the process - Message(message) - - /// An OTP system message, for debugging or maintenance - System(SystemMessage) - - /// An unexpected message - Unexpected(Dynamic) -} - -/// The type used to indicate what to do after handling a message. -/// -pub type Next(message, state) { - /// Continue handling messages. - /// - Continue(state: state, selector: Option(Selector(message))) - - /// Stop handling messages and shut down. - /// - Stop(ExitReason) -} - -pub fn continue(state: state) -> Next(message, state) { - Continue(state, None) -} - -pub fn with_selector( - value: Next(message, state), - selector: Selector(message), -) -> Next(message, state) { - case value { - Continue(state, _) -> Continue(state, Some(selector)) - _ -> value - } -} - -/// The type used to indicate whether an actor has started successfully or not. -/// -pub type InitResult(state, message) { - /// The actor has successfully initialised. The actor can start handling - /// messages and actor's channel sender can be returned to the parent - /// process. - /// - Ready(state: state, selector: Selector(message)) - - /// The actor has failed to initialise. The actor shuts down and an error is - /// returned to the parent process. - /// - Failed(String) -} - -type Self(state, msg) { - Self( - mode: Mode, - parent: Pid, - state: state, - subject: Subject(msg), - selector: Selector(Message(msg)), - debug_state: DebugState, - message_handler: fn(msg, state) -> Next(msg, state), - ) -} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an actor. -/// -/// If you do not need to configure the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub type Spec(state, msg) { - Spec( - /// The initialisation functionality for the actor. This function is called - /// just after the actor starts but before the channel sender is returned - /// to the parent. - /// - /// This function is used to ensure that any required data or state is - /// correct. If this function returns an error it means that the actor has - /// failed to start and an error is returned to the parent. - /// - init: fn() -> InitResult(state, msg), - /// How many milliseconds the `init` function has to return before it is - /// considered to have taken too long and failed. - /// - init_timeout: Int, - /// This function is called to handle each message that the actor receives. - /// - loop: fn(msg, state) -> Next(msg, state), - ) -} - -// TODO: Check needed functionality here to be OTP compatible -fn exit_process(reason: ExitReason) -> ExitReason { - // TODO - reason -} - -fn receive_message(self: Self(state, msg)) -> Message(msg) { - let selector = case self.mode { - // When suspended we only respond to system messages - Suspended -> - process.new_selector() - |> selecting_system_messages - - // When running we respond to all messages - Running -> - // We add the handler for unexpected messages first so that the user - // supplied selector can override it if desired - process.new_selector() - |> process.selecting_anything(Unexpected) - |> process.merge_selector(self.selector) - |> selecting_system_messages - } - - process.select_forever(selector) -} - -fn selecting_system_messages( - selector: Selector(Message(msg)), -) -> Selector(Message(msg)) { - selector - |> process.selecting_record3( - atom.create_from_string("system"), - convert_system_message, - ) -} - -@external(erlang, "gleam_otp_external", "convert_system_message") -fn convert_system_message(a: Dynamic, b: Dynamic) -> Message(msg) - -fn process_status_info(self: Self(state, msg)) -> StatusInfo { - StatusInfo( - module: atom.create_from_string("gleam@otp@actor"), - parent: self.parent, - mode: self.mode, - debug_state: self.debug_state, - state: dynamic.from(self.state), - ) -} - -fn loop(self: Self(state, msg)) -> ExitReason { - case receive_message(self) { - System(system) -> - case system { - GetState(callback) -> { - callback(dynamic.from(self.state)) - loop(self) - } - Resume(callback) -> { - callback() - loop(Self(..self, mode: Running)) - } - Suspend(callback) -> { - callback() - loop(Self(..self, mode: Suspended)) - } - GetStatus(callback) -> { - callback(process_status_info(self)) - loop(self) - } - } - - Unexpected(message) -> { - log_warning( - charlist.from_string("Actor discarding unexpected message: ~s"), - [charlist.from_string(string.inspect(message))], - ) - loop(self) - } - - Message(msg) -> - case self.message_handler(msg, self.state) { - Stop(reason) -> exit_process(reason) - Continue(state: state, selector: new_selector) -> { - let selector = - new_selector - |> option.map(init_selector(self.subject, _)) - |> option.unwrap(self.selector) - loop(Self(..self, state: state, selector: selector)) - } - } - } -} - -// TODO: replace this when we have Gleam bindings to the logger -@external(erlang, "logger", "warning") -fn log_warning(a: Charlist, b: List(Charlist)) -> Nil - -fn initialise_actor( - spec: Spec(state, msg), - ack: Subject(Result(Subject(msg), ExitReason)), -) { - let subject = process.new_subject() - case spec.init() { - Ready(state, selector) -> { - let selector = init_selector(subject, selector) - // Signal to parent that the process has initialised successfully - process.send(ack, Ok(subject)) - // Start message receive loop - let self = - Self( - state: state, - parent: process.subject_owner(ack), - subject: subject, - selector: selector, - message_handler: spec.loop, - debug_state: system.debug_state([]), - mode: Running, - ) - loop(self) - } - - Failed(reason) -> { - process.send(ack, Error(Abnormal(reason))) - exit_process(Abnormal(reason)) - } - } -} - -fn init_selector(subject, selector) { - process.new_selector() - |> process.selecting(subject, Message) - |> process.merge_selector(process.map_selector(selector, Message)) -} - -pub type StartError { - InitTimeout - InitFailed(ExitReason) - InitCrashed(Dynamic) -} - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - Result(Subject(msg), StartError) - -/// An Erlang supervisor compatible process start result. -/// -/// If you wish to convert this into a `StartResult` compatible with Gleam -/// supervisors see the `from_erlang_start_result` and `wrap_erlang_starter` -/// functions. -/// -pub type ErlangStartResult = - Result(Pid, Dynamic) - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - case res { - Ok(x) -> Ok(process.subject_owner(x)) - Error(x) -> Error(dynamic.from(x)) - } -} - -type StartInitMessage(msg) { - Ack(Result(Subject(msg), ExitReason)) - Mon(process.ProcessDown) -} - -// TODO: test init_timeout. Currently if we test it eunit prints an error from -// the process death. How do we avoid this? -// -/// Start an actor from a given specification. If the actor's `init` function -/// returns an error or does not return within `init_timeout` then an error is -/// returned. -/// -/// If you do not need to specify the initialisation behaviour of your actor -/// consider using the `start` function. -/// -pub fn start_spec(spec: Spec(state, msg)) -> Result(Subject(msg), StartError) { - let ack_subject = process.new_subject() - - let child = - process.start( - linked: True, - running: fn() { initialise_actor(spec, ack_subject) }, - ) - - let monitor = process.monitor_process(child) - let selector = - process.new_selector() - |> process.selecting(ack_subject, Ack) - |> process.selecting_process_down(monitor, Mon) - - let result = case process.select(selector, spec.init_timeout) { - // Child started OK - Ok(Ack(Ok(channel))) -> Ok(channel) - - // Child initialiser returned an error - Ok(Ack(Error(reason))) -> Error(InitFailed(reason)) - - // Child went down while initialising - Ok(Mon(down)) -> Error(InitCrashed(down.reason)) - - // Child did not finish initialising in time - Error(Nil) -> { - process.kill(child) - Error(InitTimeout) - } - } - - // Remove the monitor used for the starting of the actor as to avoid an extra - // message arriving at the parent if the child dies later. - process.demonitor_process(monitor) - - result -} - -/// Start an actor with a given initial state and message handling loop -/// function. -/// -/// This function returns a `Result` but it will always be `Ok` so it is safe -/// to use with `assert` if you are not starting this actor as part of a -/// supervision tree. -/// -/// If you wish to configure the initialisation behaviour of a new actor see -/// the `Spec` record and the `start_spec` function. -/// -pub fn start( - state: state, - loop: fn(msg, state) -> Next(msg, state), -) -> Result(Subject(msg), StartError) { - start_spec(Spec( - init: fn() { Ready(state, process.new_selector()) }, - loop: loop, - init_timeout: 5000, - )) -} - -/// Send a message over a given channel. -/// -/// This is a re-export of `process.send`, for the sake of convenience. -/// -pub fn send(subject: Subject(msg), msg: msg) -> Nil { - process.send(subject, msg) -} - -// TODO: test -/// Send a synchronous message and wait for a response from the receiving -/// process. -/// -/// If a reply is not received within the given timeout then the sender process -/// crashes. If you wish receive a `Result` rather than crashing see the -/// `process.try_call` function. -/// -/// This is a re-export of `process.call`, for the sake of convenience. -/// -pub fn call( - selector: Subject(message), - make_message: fn(Subject(reply)) -> message, - timeout: Int, -) -> reply { - process.call(selector, make_message, timeout) -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam deleted file mode 100644 index 2044be0..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/intensity_tracker.gleam +++ /dev/null @@ -1,46 +0,0 @@ -//// The intensity tracker is used to monitor how frequently an event happens, -//// erroring if it happens too many times within a period of time. - -import gleam/list - -// TODO: test -pub opaque type IntensityTracker { - IntensityTracker(limit: Int, period: Int, events: List(Int)) -} - -pub type TooIntense { - TooIntense -} - -pub fn new(limit limit: Int, period period: Int) -> IntensityTracker { - IntensityTracker(limit: limit, period: period, events: []) -} - -@external(erlang, "erlang", "monotonic_time") -fn monotonic_time(a: Int) -> Int - -fn now_seconds() -> Int { - monotonic_time(1) -} - -pub fn trim_window(events: List(Int), now: Int, period: Int) -> List(Int) { - case events { - [] -> [] - [event, ..events] -> - case now >= event + period { - True -> [event, ..trim_window(events, now, period)] - False -> [] - } - } -} - -pub fn add_event( - tracker: IntensityTracker, -) -> Result(IntensityTracker, TooIntense) { - let now = now_seconds() - let events = trim_window([now, ..tracker.events], now, tracker.period) - case list.length(events) >= tracker.limit { - True -> Error(TooIntense) - False -> Ok(IntensityTracker(..tracker, events: events)) - } -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/port.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/port.gleam deleted file mode 100644 index 4e1b4d8..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/port.gleam +++ /dev/null @@ -1,9 +0,0 @@ -/// Ports are how code running on the Erlang virtual machine interacts with -/// the outside world. Bytes of data can be sent to and read from ports, -/// providing a form of message passing to an external program or resource. -/// -/// For more information on ports see the [Erlang ports documentation][1]. -/// -/// [1]: https://erlang.org/doc/reference_manual/ports.html -/// -pub type Port diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam deleted file mode 100644 index b99ad8e..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/supervisor.gleam +++ /dev/null @@ -1,410 +0,0 @@ -// TODO: specify amount of time permitted for shut-down -import gleam/result -import gleam/string -import gleam/option.{type Option, None, Some} -import gleam/erlang/process.{type Pid, type Subject} -import gleam/otp/actor.{type StartError} -import gleam/otp/intensity_tracker.{type IntensityTracker} -import gleam/erlang/node.{type Node} - -/// This data structure holds all the values required by the `start_spec` -/// function in order to create an supervisor. -/// -/// If you do not need to configure the behaviour of your supervisor consider -/// using the `start` function. -/// -pub type Spec(argument, return) { - Spec( - argument: argument, - max_frequency: Int, - frequency_period: Int, - init: fn(Children(argument)) -> Children(return), - ) -} - -/// This type represents the starting children of a supervisor within the -/// `init` function. -/// -pub opaque type Children(argument) { - Ready(Starter(argument)) - Failed(ChildStartError) -} - -/// This type contains all the information required to start a new child and -/// add it to the `Children`. -/// -/// This is typically created with the `worker` function. -/// -pub opaque type ChildSpec(msg, argument, returning) { - ChildSpec( - // TODO: merge this into one field - start: fn(argument) -> Result(Subject(msg), StartError), - returning: fn(argument, Subject(msg)) -> returning, - ) -} - -type ChildStartError { - ChildStartError(previous_pid: Option(Pid), error: StartError) -} - -pub opaque type Message { - Exit(process.ExitMessage) - RetryRestart(Pid) -} - -type Instruction { - StartAll - StartFrom(Pid) -} - -type State(a) { - State( - restarts: IntensityTracker, - starter: Starter(a), - retry_restarts: Subject(Pid), - ) -} - -type Starter(argument) { - Starter( - argument: argument, - exec: Option( - fn(Instruction) -> - Result(#(Starter(argument), Instruction), ChildStartError), - ), - ) -} - -type Child(argument) { - Child(pid: Pid, argument: argument) -} - -fn start_child( - child_spec: ChildSpec(msg, argument_in, argument_out), - argument: argument_in, -) -> Result(Child(argument_out), ChildStartError) { - use subject <- result.then( - child_spec.start(argument) - |> result.map_error(ChildStartError(None, _)), - ) - - Ok(Child( - pid: process.subject_owner(subject), - // Merge the new child's pid into the argument to produce the new argument - // used to start any remaining children. - argument: child_spec.returning(argument, subject), - )) -} - -// TODO: more sophsiticated stopping of processes. i.e. give supervisors -// more time to shut down. -fn shutdown_child(pid: Pid, _spec: ChildSpec(msg, arg_1, arg_2)) -> Nil { - process.send_exit(pid) -} - -fn perform_instruction_for_child( - argument: argument_in, - instruction: Instruction, - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Result(#(Child(argument_out), Instruction), ChildStartError) { - let current = child.pid - case instruction { - // This child is older than the StartFrom target, we don't need to - // restart it - StartFrom(target) if target != current -> Ok(#(child, instruction)) - - // This pid either is the cause of the problem, or we have the StartAll - // instruction. Either way it and its younger siblings need to be restarted. - _ -> { - shutdown_child(current, child_spec) - use child <- result.then(start_child(child_spec, argument)) - Ok(#(child, StartAll)) - } - } -} - -fn add_child_to_starter( - starter: Starter(argument_in), - child_spec: ChildSpec(msg, argument_in, argument_out), - child: Child(argument_out), -) -> Starter(argument_out) { - let starter = fn(instruction) { - // Restart the older children. We use `try` to return early if the older - // children failed to start - use #(starter, instruction) <- result.then(case starter.exec { - Some(start) -> start(instruction) - None -> Ok(#(starter, instruction)) - }) - - // Perform the instruction, restarting the child as required - use #(child, instruction) <- result.then(perform_instruction_for_child( - starter.argument, - instruction, - child_spec, - child, - )) - - // Create a new starter for the next time the supervisor needs to restart - let starter = add_child_to_starter(starter, child_spec, child) - - Ok(#(starter, instruction)) - } - - Starter(exec: Some(starter), argument: child.argument) -} - -fn start_and_add_child( - state: Starter(argument_0), - child_spec: ChildSpec(msg, argument_0, argument_1), -) -> Children(argument_1) { - case start_child(child_spec, state.argument) { - Ok(child) -> Ready(add_child_to_starter(state, child_spec, child)) - Error(reason) -> Failed(reason) - } -} - -/// Add a child to the collection of children of the supervisor -/// -/// This function starts the child from the child spec. -/// -pub fn add( - children: Children(argument), - child_spec: ChildSpec(msg, argument, new_argument), -) -> Children(new_argument) { - case children { - // If one of the previous children has failed then we cannot continue - Failed(fail) -> Failed(fail) - - // If everything is OK so far then we can add the child - Ready(state) -> start_and_add_child(state, child_spec) - } -} - -// TODO: test -// TODO: unlimitd shut down duration -/// Prepare a new supervisor type child. -/// -/// If you wish to prepare a new non-supervisor type child see the `worker` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -/// Note: Gleam supervisors do not yet support different shutdown periods per -/// child so this function is currently identical in behaviour to `worker`. It is -/// recommended to use this function for supervisor children nevertheless so the -/// correct shut down behaviour is used in later releases of this library. -/// -pub fn supervisor( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -/// Prepare a new worker type child. -/// -/// If you wish to prepare a new supervisor type child see the `supervisor` -/// function. -/// -/// If you wish to change the type of the argument for later children see the -/// `returning` function. -/// -pub fn worker( - start: fn(argument) -> Result(Subject(msg), StartError), -) -> ChildSpec(msg, argument, argument) { - ChildSpec(start: start, returning: fn(argument, _channel) { argument }) -} - -// TODO: test -/// As each child is added to a supervisors children a new argument is prepared -/// with which to start the next child. By default argument is the same as the -/// previous argument, but this function can be used to change it to something -/// else by passing a function that takes the previous argument and the sender -/// of the previous child. -/// -pub fn returning( - child: ChildSpec(msg, argument_a, argument_b), - updater: fn(argument_a, Subject(msg)) -> argument_c, -) -> ChildSpec(msg, argument_a, argument_c) { - ChildSpec(start: child.start, returning: updater) -} - -fn init( - spec: Spec(argument, return), -) -> actor.InitResult(State(return), Message) { - // Create a subject so that we can asynchronously retry restarting when we - // fail to bring an exited child - let retry = process.new_subject() - - // Trap exits so that we get a message when a child crashes - process.trap_exits(True) - - // Combine selectors - let selector = - process.new_selector() - |> process.selecting(retry, RetryRestart) - |> process.selecting_trapped_exits(Exit) - - // Start any children - let result = - Starter(argument: spec.argument, exec: None) - |> Ready - |> spec.init - - // Pass back up the result - case result { - Ready(starter) -> { - let restarts = - intensity_tracker.new( - limit: spec.max_frequency, - period: spec.frequency_period, - ) - let state = - State(starter: starter, restarts: restarts, retry_restarts: retry) - actor.Ready(state, selector) - } - - Failed(error) -> - actor.Failed(case error.error { - actor.InitTimeout -> "Child initialisation timed out" - actor.InitCrashed(reason) -> - string.append( - "Child crashed during initialisation: ", - string.inspect(reason), - ) - actor.InitFailed(reason) -> - string.append( - "Child failed to start during initialisation: ", - string.inspect(reason), - ) - }) - } -} - -type HandleExitError { - RestartFailed(pid: Pid, restarts: IntensityTracker) - TooManyRestarts -} - -fn handle_exit(pid: Pid, state: State(a)) -> actor.Next(Message, State(a)) { - let outcome = { - // If we are handling an exit then we must have some children - let assert Some(start) = state.starter.exec - - // Check to see if there has been too many restarts in this period - use restarts <- result.then( - state.restarts - |> intensity_tracker.add_event - |> result.map_error(fn(_) { TooManyRestarts }), - ) - - // Restart the exited child and any following children - use #(starter, _) <- result.then( - start(StartFrom(pid)) - |> result.map_error(fn(e: ChildStartError) { - RestartFailed(option.unwrap(e.previous_pid, pid), restarts) - }), - ) - - Ok(State(..state, starter: starter, restarts: restarts)) - } - - case outcome { - Ok(state) -> actor.continue(state) - Error(RestartFailed(failed_child, restarts)) -> { - // Asynchronously enqueue the restarting of this child again as we were - // unable to restart them this time. We do this asynchronously as we want - // to have a chance to handle any system messages that have come in. - process.send(state.retry_restarts, failed_child) - let state = State(..state, restarts: restarts) - actor.continue(state) - } - Error(TooManyRestarts) -> - actor.Stop(process.Abnormal( - "Child processes restarted too many times within allowed period", - )) - } -} - -fn loop( - message: Message, - state: State(argument), -) -> actor.Next(Message, State(argument)) { - case message { - Exit(exit_message) -> handle_exit(exit_message.pid, state) - RetryRestart(pid) -> handle_exit(pid, state) - } -} - -/// Start a supervisor from a given specification. -/// -pub fn start_spec(spec: Spec(a, b)) -> Result(Subject(Message), StartError) { - actor.start_spec(actor.Spec( - init: fn() { init(spec) }, - loop: loop, - init_timeout: 60_000, - )) -} - -/// Start a supervisor from a given `init` function. -/// -/// The init argument passed to children will be `Nil` and the maximum restart -/// intensity will be 1 restart per 5 seconds (the same as the default for -/// [Erlang supervisors][erl-sup]). If you wish to specify these values, see -/// the `start_spec` function and the `Spec` type. -/// -/// [erl-sup]: https://www.erlang.org/doc/design_principles/sup_princ.html#maximum-restart-intensity -/// -pub fn start( - init: fn(Children(Nil)) -> Children(a), -) -> Result(Subject(Message), StartError) { - start_spec(Spec( - init: init, - argument: Nil, - max_frequency: 1, - frequency_period: 5, - )) -} - -/// A type used to describe the situation in which an Erlang based application -/// is starting. -/// -/// For more information see the [Erlang distributed application -/// documentation][1] and the Learn Your Some Erlang chapter on [distributed -/// applications][2]. -/// -/// [1]: https://erlang.org/doc/design_principles/distributed_applications.html -/// [2]: https://learnyousomeerlang.com/distributed-otp-applications -/// -pub type ApplicationStartMode { - Normal - Takeover(Node) - Failover(Node) -} - -pub type ApplicationStop - -@external(erlang, "gleam_otp_external", "application_stopped") -pub fn application_stopped() -> ApplicationStop - -/// The result of starting a Gleam actor. -/// -/// This type is compatible with Gleam supervisors. If you wish to convert it -/// to a type compatible with Erlang supervisors see the `ErlangStartResult` -/// type and `erlang_start_result` function. -/// -pub type StartResult(msg) = - actor.StartResult(msg) - -/// An Erlang supervisor compatible process start result. -/// -pub type ErlangStartResult = - actor.ErlangStartResult - -/// Convert a Gleam actor start result into an Erlang supervisor compatible -/// process start result. -/// -pub fn to_erlang_start_result(res: StartResult(msg)) -> ErlangStartResult { - actor.to_erlang_start_result(res) -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/system.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/system.gleam deleted file mode 100644 index c05646b..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/system.gleam +++ /dev/null @@ -1,89 +0,0 @@ -import gleam/dynamic.{type Dynamic} -import gleam/erlang/atom.{type Atom} -import gleam/erlang/process.{type Pid} - -pub type Mode { - Running - Suspended -} - -pub type DebugOption { - NoDebug -} - -pub type DebugState - -@external(erlang, "sys", "debug_options") -pub fn debug_state(a: List(DebugOption)) -> DebugState - -pub type StatusInfo { - StatusInfo( - module: Atom, - parent: Pid, - mode: Mode, - debug_state: DebugState, - state: Dynamic, - ) -} - -// TODO: document -// TODO: implement remaining messages -pub type SystemMessage { - // {replace_state, StateFn} - // {change_code, Mod, Vsn, Extra} - // {terminate, Reason} - // {debug, {log, Flag}} - // {debug, {trace, Flag}} - // {debug, {log_to_file, FileName}} - // {debug, {statistics, Flag}} - // {debug, no_debug} - // {debug, {install, {Func, FuncState}}} - // {debug, {install, {FuncId, Func, FuncState}}} - // {debug, {remove, FuncOrId}} - Resume(fn() -> Nil) - Suspend(fn() -> Nil) - GetState(fn(Dynamic) -> Nil) - GetStatus(fn(StatusInfo) -> Nil) -} - -type DoNotLeak - -/// Get the state of a given OTP compatible process. This function is only -/// intended for debugging. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#get_state-1 -/// -@external(erlang, "sys", "get_state") -pub fn get_state(from from: Pid) -> Dynamic - -@external(erlang, "sys", "suspend") -fn erl_suspend(a: Pid) -> DoNotLeak - -/// Request an OTP compatible process to suspend, causing it to only handle -/// system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#suspend-1 -/// -pub fn suspend(pid: Pid) -> Nil { - erl_suspend(pid) - Nil -} - -@external(erlang, "sys", "resume") -fn erl_resume(from from: Pid) -> DoNotLeak - -/// Request a suspended OTP compatible process to result, causing it to handle -/// all messages rather than only system messages. -/// -/// For more information see the [Erlang documentation][1]. -/// -/// [1]: https://erlang.org/doc/man/sys.html#resume-1 -/// -pub fn resume(pid: Pid) -> Nil { - erl_resume(pid) - Nil -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam/otp/task.gleam b/aoc2023/build/packages/gleam_otp/src/gleam/otp/task.gleam deleted file mode 100644 index b2b2c5c..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam/otp/task.gleam +++ /dev/null @@ -1,151 +0,0 @@ -//// A task is a kind of process that performs a single task and then shuts -//// down. Commonly tasks are used to convert sequential code into concurrent -//// code by performing computation in another process. -//// -//// let task = task.async(fn() { do_some_work() }) -//// let value = do_some_other_work() -//// value + task.await(task, 100) -//// -//// Tasks spawned with async can be awaited on by their caller process (and -//// only their caller) as shown in the example above. They are implemented by -//// spawning a process that sends a message to the caller once the given -//// computation is performed. -//// -//// There are two important things to consider when using `async`: -//// -//// 1. If you are using async tasks, you must await a reply as they are always -//// sent. -//// -//// 2. async tasks link the caller and the spawned process. This means that, -//// if the caller crashes, the task will crash too and vice-versa. This is -//// on purpose: if the process meant to receive the result no longer -//// exists, there is no purpose in completing the computation. -//// -//// This module is inspired by Elixir's [Task module][1]. -//// -//// [1]: https://hexdocs.pm/elixir/master/Task.html -//// - -// TODO: await_many -import gleam/erlang/process.{type Pid, type ProcessMonitor, type Selector} -import gleam/dynamic.{type Dynamic} - -pub opaque type Task(value) { - Task( - owner: Pid, - pid: Pid, - monitor: ProcessMonitor, - selector: Selector(Message(value)), - ) -} - -// TODO: test -/// Spawn a task process that calls a given function in order to perform some -/// work. The result of this function is send back to the parent and can be -/// received using the `await` function. -/// -/// See the top level module documentation for more information on async/await. -/// -pub fn async(work: fn() -> value) -> Task(value) { - let owner = process.self() - let subject = process.new_subject() - let pid = - process.start(linked: True, running: fn() { process.send(subject, work()) }) - let monitor = process.monitor_process(pid) - let selector = - process.new_selector() - |> process.selecting_process_down(monitor, FromMonitor) - |> process.selecting(subject, FromSubject) - Task(owner: owner, pid: pid, monitor: monitor, selector: selector) -} - -pub type AwaitError { - Timeout - Exit(reason: Dynamic) -} - -// We can only wait on a task if we are the owner of it so crash if we are -// waiting on a task we don't own. -fn assert_owner(task: Task(a)) -> Nil { - let self = process.self() - case task.owner == self { - True -> Nil - False -> - process.send_abnormal_exit( - self, - "awaited on a task that does not belong to this process", - ) - } -} - -type Message(value) { - FromMonitor(process.ProcessDown) - FromSubject(value) -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then an error is returned. -/// -pub fn try_await(task: Task(value), timeout: Int) -> Result(value, AwaitError) { - assert_owner(task) - case process.select(task.selector, timeout) { - // The task process has sent back a value - Ok(FromSubject(x)) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - Ok(FromMonitor(process.ProcessDown(reason: reason, ..))) -> - Error(Exit(reason)) - - // The task process is alive but has not sent a value yet - Error(Nil) -> Error(Timeout) - } -} - -// TODO: test -/// Wait for the value computed by a task. -/// -/// If the a value is not received before the timeout has elapsed or if the -/// task process crashes then this function crashes. -/// -pub fn await(task: Task(value), timeout: Int) -> value { - let assert Ok(value) = try_await(task, timeout) - value -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! This function does not return until there is a value to -/// receive. If a value is not received then the process will be stuck waiting -/// forever. -/// -pub fn try_await_forever(task: Task(value)) -> Result(value, AwaitError) { - assert_owner(task) - case process.select_forever(task.selector) { - // The task process has sent back a value - FromSubject(x) -> { - process.demonitor_process(task.monitor) - Ok(x) - } - - // The task process crashed without sending a value - FromMonitor(process.ProcessDown(reason: reason, ..)) -> Error(Exit(reason)) - } -} - -/// Wait endlessly for the value computed by a task. -/// -/// Be Careful! Like `try_await_forever`, this function does not return until there is a value to -/// receive. -/// -/// If the task process crashes then this function crashes. -/// -pub fn await_forever(task: Task(value)) -> value { - let assert Ok(value) = try_await_forever(task) - value -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@actor.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@actor.erl deleted file mode 100644 index 0606147..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@actor.erl +++ /dev/null @@ -1,273 +0,0 @@ --module(gleam@otp@actor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([continue/1, with_selector/2, to_erlang_start_result/1, start_spec/1, start/2, send/2, call/3]). --export_type([message/1, next/2, init_result/2, self/2, spec/2, start_error/0, start_init_message/1]). - --type message(GAS) :: {message, GAS} | - {system, gleam@otp@system:system_message()} | - {unexpected, gleam@dynamic:dynamic_()}. - --type next(GAT, GAU) :: {continue, - GAU, - gleam@option:option(gleam@erlang@process:selector(GAT))} | - {stop, gleam@erlang@process:exit_reason()}. - --type init_result(GAV, GAW) :: {ready, GAV, gleam@erlang@process:selector(GAW)} | - {failed, binary()}. - --type self(GAX, GAY) :: {self, - gleam@otp@system:mode(), - gleam@erlang@process:pid_(), - GAX, - gleam@erlang@process:subject(GAY), - gleam@erlang@process:selector(message(GAY)), - gleam@otp@system:debug_state(), - fun((GAY, GAX) -> next(GAY, GAX))}. - --type spec(GAZ, GBA) :: {spec, - fun(() -> init_result(GAZ, GBA)), - integer(), - fun((GBA, GAZ) -> next(GBA, GAZ))}. - --type start_error() :: init_timeout | - {init_failed, gleam@erlang@process:exit_reason()} | - {init_crashed, gleam@dynamic:dynamic_()}. - --type start_init_message(GBB) :: {ack, - {ok, gleam@erlang@process:subject(GBB)} | - {error, gleam@erlang@process:exit_reason()}} | - {mon, gleam@erlang@process:process_down()}. - --spec continue(GBI) -> next(any(), GBI). -continue(State) -> - {continue, State, none}. - --spec with_selector(next(GBM, GBN), gleam@erlang@process:selector(GBM)) -> next(GBM, GBN). -with_selector(Value, Selector) -> - case Value of - {continue, State, _} -> - {continue, State, {some, Selector}}; - - _ -> - Value - end. - --spec exit_process(gleam@erlang@process:exit_reason()) -> gleam@erlang@process:exit_reason(). -exit_process(Reason) -> - Reason. - --spec selecting_system_messages(gleam@erlang@process:selector(message(GBY))) -> gleam@erlang@process:selector(message(GBY)). -selecting_system_messages(Selector) -> - _pipe = Selector, - gleam@erlang@process:selecting_record3( - _pipe, - erlang:binary_to_atom(<<"system"/utf8>>), - fun gleam_otp_external:convert_system_message/2 - ). - --spec receive_message(self(any(), GBU)) -> message(GBU). -receive_message(Self) -> - Selector = case erlang:element(2, Self) of - suspended -> - _pipe = gleam_erlang_ffi:new_selector(), - selecting_system_messages(_pipe); - - running -> - _pipe@1 = gleam_erlang_ffi:new_selector(), - _pipe@2 = gleam@erlang@process:selecting_anything( - _pipe@1, - fun(Field@0) -> {unexpected, Field@0} end - ), - _pipe@3 = gleam_erlang_ffi:merge_selector( - _pipe@2, - erlang:element(6, Self) - ), - selecting_system_messages(_pipe@3) - end, - gleam_erlang_ffi:select(Selector). - --spec process_status_info(self(any(), any())) -> gleam@otp@system:status_info(). -process_status_info(Self) -> - {status_info, - erlang:binary_to_atom(<<"gleam@otp@actor"/utf8>>), - erlang:element(3, Self), - erlang:element(2, Self), - erlang:element(7, Self), - gleam@dynamic:from(erlang:element(4, Self))}. - --spec init_selector( - gleam@erlang@process:subject(GGN), - gleam@erlang@process:selector(GGN) -) -> gleam@erlang@process:selector(message(GGN)). -init_selector(Subject, Selector) -> - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Subject, - fun(Field@0) -> {message, Field@0} end - ), - gleam_erlang_ffi:merge_selector( - _pipe@1, - gleam_erlang_ffi:map_selector( - Selector, - fun(Field@0) -> {message, Field@0} end - ) - ). - --spec loop(self(any(), any())) -> gleam@erlang@process:exit_reason(). -loop(Self) -> - case receive_message(Self) of - {system, System} -> - case System of - {get_state, Callback} -> - Callback(gleam@dynamic:from(erlang:element(4, Self))), - loop(Self); - - {resume, Callback@1} -> - Callback@1(), - loop(erlang:setelement(2, Self, running)); - - {suspend, Callback@2} -> - Callback@2(), - loop(erlang:setelement(2, Self, suspended)); - - {get_status, Callback@3} -> - Callback@3(process_status_info(Self)), - loop(Self) - end; - - {unexpected, Message} -> - logger:warning( - unicode:characters_to_list( - <<"Actor discarding unexpected message: ~s"/utf8>> - ), - [unicode:characters_to_list(gleam@string:inspect(Message))] - ), - loop(Self); - - {message, Msg} -> - case (erlang:element(8, Self))(Msg, erlang:element(4, Self)) of - {stop, Reason} -> - exit_process(Reason); - - {continue, State, New_selector} -> - Selector = begin - _pipe = New_selector, - _pipe@1 = gleam@option:map( - _pipe, - fun(_capture) -> - init_selector(erlang:element(5, Self), _capture) - end - ), - gleam@option:unwrap(_pipe@1, erlang:element(6, Self)) - end, - loop( - erlang:setelement( - 6, - erlang:setelement(4, Self, State), - Selector - ) - ) - end - end. - --spec initialise_actor( - spec(any(), GCP), - gleam@erlang@process:subject({ok, gleam@erlang@process:subject(GCP)} | - {error, gleam@erlang@process:exit_reason()}) -) -> gleam@erlang@process:exit_reason(). -initialise_actor(Spec, Ack) -> - Subject = gleam@erlang@process:new_subject(), - case (erlang:element(2, Spec))() of - {ready, State, Selector} -> - Selector@1 = init_selector(Subject, Selector), - gleam@erlang@process:send(Ack, {ok, Subject}), - Self = {self, - running, - gleam@erlang@process:subject_owner(Ack), - State, - Subject, - Selector@1, - sys:debug_options([]), - erlang:element(4, Spec)}, - loop(Self); - - {failed, Reason} -> - gleam@erlang@process:send(Ack, {error, {abnormal, Reason}}), - exit_process({abnormal, Reason}) - end. - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | {error, start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - case Res of - {ok, X} -> - {ok, gleam@erlang@process:subject_owner(X)}; - - {error, X@1} -> - {error, gleam@dynamic:from(X@1)} - end. - --spec start_spec(spec(any(), GDD)) -> {ok, gleam@erlang@process:subject(GDD)} | - {error, start_error()}. -start_spec(Spec) -> - Ack_subject = gleam@erlang@process:new_subject(), - Child = gleam@erlang@process:start( - fun() -> initialise_actor(Spec, Ack_subject) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Child), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Ack_subject, - fun(Field@0) -> {ack, Field@0} end - ), - gleam@erlang@process:selecting_process_down( - _pipe@1, - Monitor, - fun(Field@0) -> {mon, Field@0} end - ) - end, - Result = case gleam_erlang_ffi:select(Selector, erlang:element(3, Spec)) of - {ok, {ack, {ok, Channel}}} -> - {ok, Channel}; - - {ok, {ack, {error, Reason}}} -> - {error, {init_failed, Reason}}; - - {ok, {mon, Down}} -> - {error, {init_crashed, erlang:element(3, Down)}}; - - {error, nil} -> - gleam@erlang@process:kill(Child), - {error, init_timeout} - end, - gleam_erlang_ffi:demonitor(Monitor), - Result. - --spec start(GDJ, fun((GDK, GDJ) -> next(GDK, GDJ))) -> {ok, - gleam@erlang@process:subject(GDK)} | - {error, start_error()}. -start(State, Loop) -> - start_spec( - {spec, - fun() -> {ready, State, gleam_erlang_ffi:new_selector()} end, - 5000, - Loop} - ). - --spec send(gleam@erlang@process:subject(GDQ), GDQ) -> nil. -send(Subject, Msg) -> - gleam@erlang@process:send(Subject, Msg). - --spec call( - gleam@erlang@process:subject(GDS), - fun((gleam@erlang@process:subject(GDU)) -> GDS), - integer() -) -> GDU. -call(Selector, Make_message, Timeout) -> - gleam@erlang@process:call(Selector, Make_message, Timeout). diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl deleted file mode 100644 index 8792f14..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@intensity_tracker.erl +++ /dev/null @@ -1,53 +0,0 @@ --module(gleam@otp@intensity_tracker). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/2, trim_window/3, add_event/1]). --export_type([intensity_tracker/0, too_intense/0]). - --opaque intensity_tracker() :: {intensity_tracker, - integer(), - integer(), - list(integer())}. - --type too_intense() :: too_intense. - --spec new(integer(), integer()) -> intensity_tracker(). -new(Limit, Period) -> - {intensity_tracker, Limit, Period, []}. - --spec now_seconds() -> integer(). -now_seconds() -> - erlang:monotonic_time(1). - --spec trim_window(list(integer()), integer(), integer()) -> list(integer()). -trim_window(Events, Now, Period) -> - case Events of - [] -> - []; - - [Event | Events@1] -> - case Now >= (Event + Period) of - true -> - [Event | trim_window(Events@1, Now, Period)]; - - false -> - [] - end - end. - --spec add_event(intensity_tracker()) -> {ok, intensity_tracker()} | - {error, too_intense()}. -add_event(Tracker) -> - Now = now_seconds(), - Events = trim_window( - [Now | erlang:element(4, Tracker)], - Now, - erlang:element(3, Tracker) - ), - case gleam@list:length(Events) >= erlang:element(2, Tracker) of - true -> - {error, too_intense}; - - false -> - {ok, erlang:setelement(4, Tracker, Events)} - end. diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@port.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@port.erl deleted file mode 100644 index b205739..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@port.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(gleam@otp@port). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export_type([port_/0]). - --type port_() :: any(). - - diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@supervisor.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@supervisor.erl deleted file mode 100644 index 39118f1..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@supervisor.erl +++ /dev/null @@ -1,322 +0,0 @@ --module(gleam@otp@supervisor). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([add/2, supervisor/1, worker/1, returning/2, start_spec/1, start/1, application_stopped/0, to_erlang_start_result/1]). --export_type([spec/2, children/1, child_spec/3, child_start_error/0, message/0, instruction/0, state/1, starter/1, child/1, handle_exit_error/0, application_start_mode/0, application_stop/0]). - --type spec(GLS, GLT) :: {spec, - GLS, - integer(), - integer(), - fun((children(GLS)) -> children(GLT))}. - --opaque children(GLU) :: {ready, starter(GLU)} | {failed, child_start_error()}. - --opaque child_spec(GLV, GLW, GLX) :: {child_spec, - fun((GLW) -> {ok, gleam@erlang@process:subject(GLV)} | - {error, gleam@otp@actor:start_error()}), - fun((GLW, gleam@erlang@process:subject(GLV)) -> GLX)}. - --type child_start_error() :: {child_start_error, - gleam@option:option(gleam@erlang@process:pid_()), - gleam@otp@actor:start_error()}. - --opaque message() :: {exit, gleam@erlang@process:exit_message()} | - {retry_restart, gleam@erlang@process:pid_()}. - --type instruction() :: start_all | {start_from, gleam@erlang@process:pid_()}. - --type state(GLY) :: {state, - gleam@otp@intensity_tracker:intensity_tracker(), - starter(GLY), - gleam@erlang@process:subject(gleam@erlang@process:pid_())}. - --type starter(GLZ) :: {starter, - GLZ, - gleam@option:option(fun((instruction()) -> {ok, - {starter(GLZ), instruction()}} | - {error, child_start_error()}))}. - --type child(GMA) :: {child, gleam@erlang@process:pid_(), GMA}. - --type handle_exit_error() :: {restart_failed, - gleam@erlang@process:pid_(), - gleam@otp@intensity_tracker:intensity_tracker()} | - too_many_restarts. - --type application_start_mode() :: normal | - {takeover, gleam@erlang@node:node_()} | - {failover, gleam@erlang@node:node_()}. - --type application_stop() :: any(). - --spec start_child(child_spec(any(), GME, GMF), GME) -> {ok, child(GMF)} | - {error, child_start_error()}. -start_child(Child_spec, Argument) -> - gleam@result:then( - begin - _pipe = (erlang:element(2, Child_spec))(Argument), - gleam@result:map_error( - _pipe, - fun(_capture) -> {child_start_error, none, _capture} end - ) - end, - fun(Subject) -> - {ok, - {child, - gleam@erlang@process:subject_owner(Subject), - (erlang:element(3, Child_spec))(Argument, Subject)}} - end - ). - --spec shutdown_child( - gleam@erlang@process:pid_(), - child_spec(any(), any(), any()) -) -> nil. -shutdown_child(Pid, _) -> - gleam@erlang@process:send_exit(Pid). - --spec perform_instruction_for_child( - GMS, - instruction(), - child_spec(any(), GMS, GMU), - child(GMU) -) -> {ok, {child(GMU), instruction()}} | {error, child_start_error()}. -perform_instruction_for_child(Argument, Instruction, Child_spec, Child) -> - Current = erlang:element(2, Child), - case Instruction of - {start_from, Target} when Target =/= Current -> - {ok, {Child, Instruction}}; - - _ -> - shutdown_child(Current, Child_spec), - gleam@result:then( - start_child(Child_spec, Argument), - fun(Child@1) -> {ok, {Child@1, start_all}} end - ) - end. - --spec add_child_to_starter( - starter(GNC), - child_spec(any(), GNC, GNF), - child(GNF) -) -> starter(GNF). -add_child_to_starter(Starter, Child_spec, Child) -> - Starter@3 = fun(Instruction) -> - gleam@result:then(case erlang:element(3, Starter) of - {some, Start} -> - Start(Instruction); - - none -> - {ok, {Starter, Instruction}} - end, fun(_use0) -> - {Starter@1, Instruction@1} = _use0, - gleam@result:then( - perform_instruction_for_child( - erlang:element(2, Starter@1), - Instruction@1, - Child_spec, - Child - ), - fun(_use0@1) -> - {Child@1, Instruction@2} = _use0@1, - Starter@2 = add_child_to_starter( - Starter@1, - Child_spec, - Child@1 - ), - {ok, {Starter@2, Instruction@2}} - end - ) - end) - end, - {starter, erlang:element(3, Child), {some, Starter@3}}. - --spec start_and_add_child(starter(GNL), child_spec(any(), GNL, GNO)) -> children(GNO). -start_and_add_child(State, Child_spec) -> - case start_child(Child_spec, erlang:element(2, State)) of - {ok, Child} -> - {ready, add_child_to_starter(State, Child_spec, Child)}; - - {error, Reason} -> - {failed, Reason} - end. - --spec add(children(GNT), child_spec(any(), GNT, GNW)) -> children(GNW). -add(Children, Child_spec) -> - case Children of - {failed, Fail} -> - {failed, Fail}; - - {ready, State} -> - start_and_add_child(State, Child_spec) - end. - --spec supervisor( - fun((GOB) -> {ok, gleam@erlang@process:subject(GOC)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOC, GOB, GOB). -supervisor(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec worker( - fun((GOJ) -> {ok, gleam@erlang@process:subject(GOK)} | - {error, gleam@otp@actor:start_error()}) -) -> child_spec(GOK, GOJ, GOJ). -worker(Start) -> - {child_spec, Start, fun(Argument, _) -> Argument end}. - --spec returning( - child_spec(GOR, GOS, any()), - fun((GOS, gleam@erlang@process:subject(GOR)) -> GOY) -) -> child_spec(GOR, GOS, GOY). -returning(Child, Updater) -> - {child_spec, erlang:element(2, Child), Updater}. - --spec init(spec(any(), GPD)) -> gleam@otp@actor:init_result(state(GPD), message()). -init(Spec) -> - Retry = gleam@erlang@process:new_subject(), - gleam_erlang_ffi:trap_exits(true), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting( - _pipe, - Retry, - fun(Field@0) -> {retry_restart, Field@0} end - ), - gleam@erlang@process:selecting_trapped_exits( - _pipe@1, - fun(Field@0) -> {exit, Field@0} end - ) - end, - Result = begin - _pipe@2 = {starter, erlang:element(2, Spec), none}, - _pipe@3 = {ready, _pipe@2}, - (erlang:element(5, Spec))(_pipe@3) - end, - case Result of - {ready, Starter} -> - Restarts = gleam@otp@intensity_tracker:new( - erlang:element(3, Spec), - erlang:element(4, Spec) - ), - State = {state, Restarts, Starter, Retry}, - {ready, State, Selector}; - - {failed, Error} -> - {failed, case erlang:element(3, Error) of - init_timeout -> - <<"Child initialisation timed out"/utf8>>; - - {init_crashed, Reason} -> - gleam@string:append( - <<"Child crashed during initialisation: "/utf8>>, - gleam@string:inspect(Reason) - ); - - {init_failed, Reason@1} -> - gleam@string:append( - <<"Child failed to start during initialisation: "/utf8>>, - gleam@string:inspect(Reason@1) - ) - end} - end. - --spec handle_exit(gleam@erlang@process:pid_(), state(GPJ)) -> gleam@otp@actor:next(message(), state(GPJ)). -handle_exit(Pid, State) -> - Outcome = begin - _assert_subject = erlang:element(3, erlang:element(3, State)), - {some, Start} = case _assert_subject of - {some, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/supervisor"/utf8>>, - function => <<"handle_exit"/utf8>>, - line => 293}) - end, - gleam@result:then( - begin - _pipe = erlang:element(2, State), - _pipe@1 = gleam@otp@intensity_tracker:add_event(_pipe), - gleam@result:map_error(_pipe@1, fun(_) -> too_many_restarts end) - end, - fun(Restarts) -> - gleam@result:then( - begin - _pipe@2 = Start({start_from, Pid}), - gleam@result:map_error( - _pipe@2, - fun(E) -> - {restart_failed, - gleam@option:unwrap( - erlang:element(2, E), - Pid - ), - Restarts} - end - ) - end, - fun(_use0) -> - {Starter, _} = _use0, - {ok, - erlang:setelement( - 2, - erlang:setelement(3, State, Starter), - Restarts - )} - end - ) - end - ) - end, - case Outcome of - {ok, State@1} -> - gleam@otp@actor:continue(State@1); - - {error, {restart_failed, Failed_child, Restarts@1}} -> - gleam@erlang@process:send(erlang:element(4, State), Failed_child), - State@2 = erlang:setelement(2, State, Restarts@1), - gleam@otp@actor:continue(State@2); - - {error, too_many_restarts} -> - {stop, - {abnormal, - <<"Child processes restarted too many times within allowed period"/utf8>>}} - end. - --spec loop(message(), state(GPO)) -> gleam@otp@actor:next(message(), state(GPO)). -loop(Message, State) -> - case Message of - {exit, Exit_message} -> - handle_exit(erlang:element(2, Exit_message), State); - - {retry_restart, Pid} -> - handle_exit(Pid, State) - end. - --spec start_spec(spec(any(), any())) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start_spec(Spec) -> - gleam@otp@actor:start_spec( - {spec, fun() -> init(Spec) end, 60000, fun loop/2} - ). - --spec start(fun((children(nil)) -> children(any()))) -> {ok, - gleam@erlang@process:subject(message())} | - {error, gleam@otp@actor:start_error()}. -start(Init) -> - start_spec({spec, nil, 1, 5, Init}). - --spec application_stopped() -> application_stop(). -application_stopped() -> - gleam_otp_external:application_stopped(). - --spec to_erlang_start_result( - {ok, gleam@erlang@process:subject(any())} | - {error, gleam@otp@actor:start_error()} -) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. -to_erlang_start_result(Res) -> - gleam@otp@actor:to_erlang_start_result(Res). diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@system.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@system.erl deleted file mode 100644 index 622e5ea..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@system.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam@otp@system). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([debug_state/1, get_state/1, suspend/1, resume/1]). --export_type([mode/0, debug_option/0, debug_state/0, status_info/0, system_message/0, do_not_leak/0]). - --type mode() :: running | suspended. - --type debug_option() :: no_debug. - --type debug_state() :: any(). - --type status_info() :: {status_info, - gleam@erlang@atom:atom_(), - gleam@erlang@process:pid_(), - mode(), - debug_state(), - gleam@dynamic:dynamic_()}. - --type system_message() :: {resume, fun(() -> nil)} | - {suspend, fun(() -> nil)} | - {get_state, fun((gleam@dynamic:dynamic_()) -> nil)} | - {get_status, fun((status_info()) -> nil)}. - --type do_not_leak() :: any(). - --spec debug_state(list(debug_option())) -> debug_state(). -debug_state(A) -> - sys:debug_options(A). - --spec get_state(gleam@erlang@process:pid_()) -> gleam@dynamic:dynamic_(). -get_state(From) -> - sys:get_state(From). - --spec suspend(gleam@erlang@process:pid_()) -> nil. -suspend(Pid) -> - sys:suspend(Pid), - nil. - --spec resume(gleam@erlang@process:pid_()) -> nil. -resume(Pid) -> - sys:resume(Pid), - nil. diff --git a/aoc2023/build/packages/gleam_otp/src/gleam@otp@task.erl b/aoc2023/build/packages/gleam_otp/src/gleam@otp@task.erl deleted file mode 100644 index e004284..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam@otp@task.erl +++ /dev/null @@ -1,111 +0,0 @@ --module(gleam@otp@task). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([async/1, try_await/2, await/2, try_await_forever/1, await_forever/1]). --export_type([task/1, await_error/0, message/1]). - --opaque task(FWJ) :: {task, - gleam@erlang@process:pid_(), - gleam@erlang@process:pid_(), - gleam@erlang@process:process_monitor(), - gleam@erlang@process:selector(message(FWJ))}. - --type await_error() :: timeout | {exit, gleam@dynamic:dynamic_()}. - --type message(FWK) :: {from_monitor, gleam@erlang@process:process_down()} | - {from_subject, FWK}. - --spec async(fun(() -> FWL)) -> task(FWL). -async(Work) -> - Owner = erlang:self(), - Subject = gleam@erlang@process:new_subject(), - Pid = gleam@erlang@process:start( - fun() -> gleam@erlang@process:send(Subject, Work()) end, - true - ), - Monitor = gleam@erlang@process:monitor_process(Pid), - Selector = begin - _pipe = gleam_erlang_ffi:new_selector(), - _pipe@1 = gleam@erlang@process:selecting_process_down( - _pipe, - Monitor, - fun(Field@0) -> {from_monitor, Field@0} end - ), - gleam@erlang@process:selecting( - _pipe@1, - Subject, - fun(Field@0) -> {from_subject, Field@0} end - ) - end, - {task, Owner, Pid, Monitor, Selector}. - --spec assert_owner(task(any())) -> nil. -assert_owner(Task) -> - Self = erlang:self(), - case erlang:element(2, Task) =:= Self of - true -> - nil; - - false -> - gleam@erlang@process:send_abnormal_exit( - Self, - <<"awaited on a task that does not belong to this process"/utf8>> - ) - end. - --spec try_await(task(FWP), integer()) -> {ok, FWP} | {error, await_error()}. -try_await(Task, Timeout) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task), Timeout) of - {ok, {from_subject, X}} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {ok, {from_monitor, {process_down, _, Reason}}} -> - {error, {exit, Reason}}; - - {error, nil} -> - {error, timeout} - end. - --spec await(task(FWT), integer()) -> FWT. -await(Task, Timeout) -> - _assert_subject = try_await(Task, Timeout), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await"/utf8>>, - line => 117}) - end, - Value. - --spec try_await_forever(task(FWV)) -> {ok, FWV} | {error, await_error()}. -try_await_forever(Task) -> - assert_owner(Task), - case gleam_erlang_ffi:select(erlang:element(5, Task)) of - {from_subject, X} -> - gleam_erlang_ffi:demonitor(erlang:element(4, Task)), - {ok, X}; - - {from_monitor, {process_down, _, Reason}} -> - {error, {exit, Reason}} - end. - --spec await_forever(task(FWZ)) -> FWZ. -await_forever(Task) -> - _assert_subject = try_await_forever(Task), - {ok, Value} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"gleam/otp/task"/utf8>>, - function => <<"await_forever"/utf8>>, - line => 149}) - end, - Value. diff --git a/aoc2023/build/packages/gleam_otp/src/gleam_otp.app.src b/aoc2023/build/packages/gleam_otp/src/gleam_otp.app.src deleted file mode 100644 index 5c52295..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam_otp.app.src +++ /dev/null @@ -1,15 +0,0 @@ -{application, gleam_otp, [ - {vsn, "0.8.0"}, - {applications, [gleam_erlang, - gleam_stdlib, - gleeunit]}, - {description, "Fault tolerant multicore Gleam programs with OTP"}, - {modules, [gleam@otp@actor, - gleam@otp@intensity_tracker, - gleam@otp@port, - gleam@otp@supervisor, - gleam@otp@system, - gleam@otp@task, - gleam_otp]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_otp/src/gleam_otp.erl b/aoc2023/build/packages/gleam_otp/src/gleam_otp.erl deleted file mode 100644 index 9381ad2..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam_otp.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(gleam_otp). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([main/0]). - --spec spawn_task(integer()) -> gleam@otp@task:task(nil). -spawn_task(I) -> - gleam@otp@task:async(fun() -> case (I rem 500) =:= 0 of - true -> - gleam@io:println( - <<"Hello from "/utf8, (gleam@int:to_string(I))/binary>> - ); - - false -> - nil - end end). - --spec main() -> integer(). -main() -> - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ), - _pipe = gleam@list:range(0, 1000000), - _pipe@1 = gleam@list:map(_pipe, fun spawn_task/1), - gleam@list:each(_pipe@1, fun gleam@otp@task:await_forever/1), - gleam@io:debug( - gleam_otp_test_external:get_message_queue_length(erlang:self()) - ). diff --git a/aoc2023/build/packages/gleam_otp/src/gleam_otp.gleam b/aoc2023/build/packages/gleam_otp/src/gleam_otp.gleam deleted file mode 100644 index 69cdd5b..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam_otp.gleam +++ /dev/null @@ -1,27 +0,0 @@ -import gleam/io -import gleam/int -import gleam/list -import gleam/otp/task -import gleam/erlang/process.{type Pid} - -@external(erlang, "gleam_otp_test_external", "get_message_queue_length") -fn get_message_queue_length(pid pid: Pid) -> Int - -fn spawn_task(i) { - task.async(fn() { - case i % 500 == 0 { - True -> io.println("Hello from " <> int.to_string(i)) - False -> Nil - } - }) -} - -pub fn main() { - io.debug(get_message_queue_length(process.self())) - - list.range(0, 1_000_000) - |> list.map(spawn_task) - |> list.each(task.await_forever) - - io.debug(get_message_queue_length(process.self())) -} diff --git a/aoc2023/build/packages/gleam_otp/src/gleam_otp_external.erl b/aoc2023/build/packages/gleam_otp/src/gleam_otp_external.erl deleted file mode 100644 index 8910a67..0000000 --- a/aoc2023/build/packages/gleam_otp/src/gleam_otp_external.erl +++ /dev/null @@ -1,43 +0,0 @@ --module(gleam_otp_external). - --export([application_stopped/0, convert_system_message/2]). - -% TODO: support other system messages -% {replace_state, StateFn} -% {change_code, Mod, Vsn, Extra} -% {terminate, Reason} -% {debug, {log, Flag}} -% {debug, {trace, Flag}} -% {debug, {log_to_file, FileName}} -% {debug, {statistics, Flag}} -% {debug, no_debug} -% {debug, {install, {Func, FuncState}}} -% {debug, {install, {FuncId, Func, FuncState}}} -% {debug, {remove, FuncOrId}} -% GetStatus(Subject(StatusInfo)) -convert_system_message({From, Ref}, Request) when is_pid(From) -> - Reply = fun(Msg) -> - erlang:send(From, {Ref, Msg}), - nil - end, - System = fun(Callback) -> - {system, {Request, Callback}} - end, - case Request of - get_status -> System(fun(Status) -> Reply(process_status(Status)) end); - get_state -> System(Reply); - suspend -> System(fun() -> Reply(ok) end); - resume -> System(fun() -> Reply(ok) end); - Other -> {unexpeceted, Other} - end. - -process_status({status_info, Module, Parent, Mode, DebugState, State}) -> - Data = [ - get(), Mode, Parent, DebugState, - [{header, "Status for Gleam process " ++ pid_to_list(self())}, - {data, [{'Status', Mode}, {'Parent', Parent}, {'State', State}]}] - ], - {status, self(), {module, Module}, Data}. - -application_stopped() -> - ok. diff --git a/aoc2023/build/packages/gleam_stdlib/LICENCE b/aoc2023/build/packages/gleam_stdlib/LICENCE deleted file mode 100644 index c1dabd0..0000000 --- a/aoc2023/build/packages/gleam_stdlib/LICENCE +++ /dev/null @@ -1,191 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2018, Louis Pilfold <louis@lpil.uk>. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/aoc2023/build/packages/gleam_stdlib/README.md b/aoc2023/build/packages/gleam_stdlib/README.md deleted file mode 100644 index 05c68ca..0000000 --- a/aoc2023/build/packages/gleam_stdlib/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# stdlib - -<a href="https://github.com/gleam-lang/stdlib/releases"><img src="https://img.shields.io/github/release/gleam-lang/stdlib" alt="GitHub release"></a> -<a href="https://discord.gg/Fm8Pwmy"><img src="https://img.shields.io/discord/768594524158427167?color=blue" alt="Discord chat"></a> - - -Gleam's standard library! -Documentation available on [HexDocs](https://hexdocs.pm/gleam_stdlib/). - -## Installation - -Add `gleam_stdlib` to your Gleam project. - -```sh -gleam add gleam_stdlib -``` - -## Usage - -Import the modules you want to use and write some code! - -```gleam -import gleam/string - -pub fn greet(name: String) -> String { - string.concat(["Hello ", name, "!"]) -} -``` - -## Targets - -Gleam's standard library supports both targets: Erlang and JavaScript. - -### Compatibility - -This library is compatible with all versions of Erlang/OTP, NodeJS, and -major browsers that are currently supported by their maintainers. If you -have a compatibility issue with any platform open an issue and we'll see -what we can do to help. diff --git a/aoc2023/build/packages/gleam_stdlib/gleam.toml b/aoc2023/build/packages/gleam_stdlib/gleam.toml deleted file mode 100644 index 0cb0531..0000000 --- a/aoc2023/build/packages/gleam_stdlib/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "gleam_stdlib" -version = "0.33.0" -gleam = ">= 0.32.0" -licences = ["Apache-2.0"] -description = "A standard library for the Gleam programming language" - -repository = { type = "github", user = "gleam-lang", repo = "stdlib" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[javascript.deno] -allow_read = [ - "./", -] diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl deleted file mode 100644 index b1135f2..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@dynamic_DecodeError.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(decode_error, { - expected :: binary(), - found :: binary(), - path :: list(binary()) -}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl deleted file mode 100644 index b0d08dc..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Iterator.hrl +++ /dev/null @@ -1 +0,0 @@ --record(iterator, {continuation :: fun(() -> gleam@iterator:action(any()))}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl deleted file mode 100644 index 1f61922..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@iterator_Next.hrl +++ /dev/null @@ -1 +0,0 @@ --record(next, {element :: any(), accumulator :: any()}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl deleted file mode 100644 index 88ac25e..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@queue_Queue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(queue, {in :: list(any()), out :: list(any())}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl deleted file mode 100644 index ad5511e..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_CompileError.hrl +++ /dev/null @@ -1 +0,0 @@ --record(compile_error, {error :: binary(), byte_index :: integer()}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl deleted file mode 100644 index 4216619..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Match.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(match, { - content :: binary(), - submatches :: list(gleam@option:option(binary())) -}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl deleted file mode 100644 index 0074603..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@regex_Options.hrl +++ /dev/null @@ -1 +0,0 @@ --record(options, {case_insensitive :: boolean(), multi_line :: boolean()}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@set_Set.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@set_Set.hrl deleted file mode 100644 index 6e1e226..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@set_Set.hrl +++ /dev/null @@ -1 +0,0 @@ --record(set, {map :: gleam@dict:dict(any(), list(nil))}). diff --git a/aoc2023/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl b/aoc2023/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl deleted file mode 100644 index 50150f4..0000000 --- a/aoc2023/build/packages/gleam_stdlib/include/gleam@uri_Uri.hrl +++ /dev/null @@ -1,9 +0,0 @@ --record(uri, { - scheme :: gleam@option:option(binary()), - userinfo :: gleam@option:option(binary()), - host :: gleam@option:option(binary()), - port :: gleam@option:option(integer()), - path :: binary(), - 'query' :: gleam@option:option(binary()), - fragment :: gleam@option:option(binary()) -}). diff --git a/aoc2023/build/packages/gleam_stdlib/src/dict.mjs b/aoc2023/build/packages/gleam_stdlib/src/dict.mjs deleted file mode 100644 index a8309e0..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/dict.mjs +++ /dev/null @@ -1,957 +0,0 @@ -/** - * This file uses jsdoc to annotate types. - * These types can be checked using the typescript compiler with "checkjs" option. - */ - -import { isEqual } from "./gleam.mjs"; - -const referenceMap = new WeakMap(); -const tempDataView = new DataView(new ArrayBuffer(8)); -let referenceUID = 0; -/** - * hash the object by reference using a weak map and incrementing uid - * @param {any} o - * @returns {number} - */ -function hashByReference(o) { - const known = referenceMap.get(o); - if (known !== undefined) { - return known; - } - const hash = referenceUID++; - if (referenceUID === 0x7fffffff) { - referenceUID = 0; - } - referenceMap.set(o, hash); - return hash; -} -/** - * merge two hashes in an order sensitive way - * @param {number} a - * @param {number} b - * @returns {number} - */ -function hashMerge(a, b) { - return (a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2))) | 0; -} -/** - * standard string hash popularised by java - * @param {string} s - * @returns {number} - */ -function hashString(s) { - let hash = 0; - const len = s.length; - for (let i = 0; i < len; i++) { - hash = (Math.imul(31, hash) + s.charCodeAt(i)) | 0; - } - return hash; -} -/** - * hash a number by converting to two integers and do some jumbling - * @param {number} n - * @returns {number} - */ -function hashNumber(n) { - tempDataView.setFloat64(0, n); - const i = tempDataView.getInt32(0); - const j = tempDataView.getInt32(4); - return Math.imul(0x45d9f3b, (i >> 16) ^ i) ^ j; -} -/** - * hash a BigInt by converting it to a string and hashing that - * @param {BigInt} n - * @returns {number} - */ -function hashBigInt(n) { - return hashString(n.toString()); -} -/** - * hash any js object - * @param {any} o - * @returns {number} - */ -function hashObject(o) { - const proto = Object.getPrototypeOf(o); - if (proto !== null && typeof proto.hashCode === "function") { - try { - const code = o.hashCode(o); - if (typeof code === "number") { - return code; - } - } catch {} - } - if (o instanceof Promise || o instanceof WeakSet || o instanceof WeakMap) { - return hashByReference(o); - } - if (o instanceof Date) { - return hashNumber(o.getTime()); - } - let h = 0; - if (o instanceof ArrayBuffer) { - o = new Uint8Array(o); - } - if (Array.isArray(o) || o instanceof Uint8Array) { - for (let i = 0; i < o.length; i++) { - h = (Math.imul(31, h) + getHash(o[i])) | 0; - } - } else if (o instanceof Set) { - o.forEach((v) => { - h = (h + getHash(v)) | 0; - }); - } else if (o instanceof Map) { - o.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - } else { - const keys = Object.keys(o); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - const v = o[k]; - h = (h + hashMerge(getHash(v), hashString(k))) | 0; - } - } - return h; -} -/** - * hash any js value - * @param {any} u - * @returns {number} - */ -export function getHash(u) { - if (u === null) return 0x42108422; - if (u === undefined) return 0x42108423; - if (u === true) return 0x42108421; - if (u === false) return 0x42108420; - switch (typeof u) { - case "number": - return hashNumber(u); - case "string": - return hashString(u); - case "bigint": - return hashBigInt(u); - case "object": - return hashObject(u); - case "symbol": - return hashByReference(u); - case "function": - return hashByReference(u); - default: - return 0; // should be unreachable - } -} -/** - * @template K,V - * @typedef {ArrayNode<K,V> | IndexNode<K,V> | CollisionNode<K,V>} Node - */ -/** - * @template K,V - * @typedef {{ type: typeof ENTRY, k: K, v: V }} Entry - */ -/** - * @template K,V - * @typedef {{ type: typeof ARRAY_NODE, size: number, array: (undefined | Entry<K,V> | Node<K,V>)[] }} ArrayNode - */ -/** - * @template K,V - * @typedef {{ type: typeof INDEX_NODE, bitmap: number, array: (Entry<K,V> | Node<K,V>)[] }} IndexNode - */ -/** - * @template K,V - * @typedef {{ type: typeof COLLISION_NODE, hash: number, array: Entry<K, V>[] }} CollisionNode - */ -/** - * @typedef {{ val: boolean }} Flag - */ -const SHIFT = 5; // number of bits you need to shift by to get the next bucket -const BUCKET_SIZE = Math.pow(2, SHIFT); -const MASK = BUCKET_SIZE - 1; // used to zero out all bits not in the bucket -const MAX_INDEX_NODE = BUCKET_SIZE / 2; // when does index node grow into array node -const MIN_ARRAY_NODE = BUCKET_SIZE / 4; // when does array node shrink to index node -const ENTRY = 0; -const ARRAY_NODE = 1; -const INDEX_NODE = 2; -const COLLISION_NODE = 3; -/** @type {IndexNode<any,any>} */ -const EMPTY = { - type: INDEX_NODE, - bitmap: 0, - array: [], -}; -/** - * Mask the hash to get only the bucket corresponding to shift - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function mask(hash, shift) { - return (hash >>> shift) & MASK; -} -/** - * Set only the Nth bit where N is the masked hash - * @param {number} hash - * @param {number} shift - * @returns {number} - */ -function bitpos(hash, shift) { - return 1 << mask(hash, shift); -} -/** - * Count the number of 1 bits in a number - * @param {number} x - * @returns {number} - */ -function bitcount(x) { - x -= (x >> 1) & 0x55555555; - x = (x & 0x33333333) + ((x >> 2) & 0x33333333); - x = (x + (x >> 4)) & 0x0f0f0f0f; - x += x >> 8; - x += x >> 16; - return x & 0x7f; -} -/** - * Calculate the array index of an item in a bitmap index node - * @param {number} bitmap - * @param {number} bit - * @returns {number} - */ -function index(bitmap, bit) { - return bitcount(bitmap & (bit - 1)); -} -/** - * Efficiently copy an array and set one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function cloneAndSet(arr, at, val) { - const len = arr.length; - const out = new Array(len); - for (let i = 0; i < len; ++i) { - out[i] = arr[i]; - } - out[at] = val; - return out; -} -/** - * Efficiently copy an array and insert one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @param {T} val - * @returns {T[]} - */ -function spliceIn(arr, at, val) { - const len = arr.length; - const out = new Array(len + 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - out[g++] = val; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Efficiently copy an array and remove one value at an index - * @template T - * @param {T[]} arr - * @param {number} at - * @returns {T[]} - */ -function spliceOut(arr, at) { - const len = arr.length; - const out = new Array(len - 1); - let i = 0; - let g = 0; - while (i < at) { - out[g++] = arr[i++]; - } - ++i; - while (i < len) { - out[g++] = arr[i++]; - } - return out; -} -/** - * Create a new node containing two entries - * @template K,V - * @param {number} shift - * @param {K} key1 - * @param {V} val1 - * @param {number} key2hash - * @param {K} key2 - * @param {V} val2 - * @returns {Node<K,V>} - */ -function createNode(shift, key1, val1, key2hash, key2, val2) { - const key1hash = getHash(key1); - if (key1hash === key2hash) { - return { - type: COLLISION_NODE, - hash: key1hash, - array: [ - { type: ENTRY, k: key1, v: val1 }, - { type: ENTRY, k: key2, v: val2 }, - ], - }; - } - const addedLeaf = { val: false }; - return assoc( - assocIndex(EMPTY, shift, key1hash, key1, val1, addedLeaf), - shift, - key2hash, - key2, - val2, - addedLeaf - ); -} -/** - * @template T,K,V - * @callback AssocFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @param {V} val - * @param {Flag} addedLeaf - * @returns {Node<K,V>} - */ -/** - * Associate a node with a new entry, creating a new node - * @template T,K,V - * @type {AssocFunction<Node<K,V>,K,V>} - */ -function assoc(root, shift, hash, key, val, addedLeaf) { - switch (root.type) { - case ARRAY_NODE: - return assocArray(root, shift, hash, key, val, addedLeaf); - case INDEX_NODE: - return assocIndex(root, shift, hash, key, val, addedLeaf); - case COLLISION_NODE: - return assocCollision(root, shift, hash, key, val, addedLeaf); - } -} -/** - * @template T,K,V - * @type {AssocFunction<ArrayNode<K,V>,K,V>} - */ -function assocArray(root, shift, hash, key, val, addedLeaf) { - const idx = mask(hash, shift); - const node = root.array[idx]; - // if the corresponding index is empty set the index to a newly created node - if (node === undefined) { - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size + 1, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - if (node.type === ENTRY) { - // if keys are equal replace the entry - if (isEqual(key, node.k)) { - if (val === node.v) { - return root; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // otherwise upgrade the entry to a node and insert - addedLeaf.val = true; - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, node.k, node.v, hash, key, val) - ), - }; - } - // otherwise call assoc on the child node - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - // if the child node hasn't changed just return the old root - if (n === node) { - return root; - } - // otherwise set the index to the new node - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template T,K,V - * @type {AssocFunction<IndexNode<K,V>,K,V>} - */ -function assocIndex(root, shift, hash, key, val, addedLeaf) { - const bit = bitpos(hash, shift); - const idx = index(root.bitmap, bit); - // if there is already a item at this hash index.. - if ((root.bitmap & bit) !== 0) { - // if there is a node at the index (not an entry), call assoc on the child node - const node = root.array[idx]; - if (node.type !== ENTRY) { - const n = assoc(node, shift + SHIFT, hash, key, val, addedLeaf); - if (n === node) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise there is an entry at the index - // if the keys are equal replace the entry with the updated value - const nodeKey = node.k; - if (isEqual(key, nodeKey)) { - if (val === node.v) { - return root; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }), - }; - } - // if the keys are not equal, replace the entry with a new child node - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet( - root.array, - idx, - createNode(shift + SHIFT, nodeKey, node.v, hash, key, val) - ), - }; - } else { - // else there is currently no item at the hash index - const n = root.array.length; - // if the number of nodes is at the maximum, expand this node into an array node - if (n >= MAX_INDEX_NODE) { - // create a 32 length array for the new array node (one for each bit in the hash) - const nodes = new Array(32); - // create and insert a node for the new entry - const jdx = mask(hash, shift); - nodes[jdx] = assocIndex(EMPTY, shift + SHIFT, hash, key, val, addedLeaf); - let j = 0; - let bitmap = root.bitmap; - // place each item in the index node into the correct spot in the array node - // loop through all 32 bits / array positions - for (let i = 0; i < 32; i++) { - if ((bitmap & 1) !== 0) { - const node = root.array[j++]; - nodes[i] = node; - } - // shift the bitmap to process the next bit - bitmap = bitmap >>> 1; - } - return { - type: ARRAY_NODE, - size: n + 1, - array: nodes, - }; - } else { - // else there is still space in this index node - // simply insert a new entry at the hash index - const newArray = spliceIn(root.array, idx, { - type: ENTRY, - k: key, - v: val, - }); - addedLeaf.val = true; - return { - type: INDEX_NODE, - bitmap: root.bitmap | bit, - array: newArray, - }; - } - } -} -/** - * @template T,K,V - * @type {AssocFunction<CollisionNode<K,V>,K,V>} - */ -function assocCollision(root, shift, hash, key, val, addedLeaf) { - // if there is a hash collision - if (hash === root.hash) { - const idx = collisionIndexOf(root, key); - // if this key already exists replace the entry with the new value - if (idx !== -1) { - const entry = root.array[idx]; - if (entry.v === val) { - return root; - } - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, idx, { type: ENTRY, k: key, v: val }), - }; - } - // otherwise insert the entry at the end of the array - const size = root.array.length; - addedLeaf.val = true; - return { - type: COLLISION_NODE, - hash: hash, - array: cloneAndSet(root.array, size, { type: ENTRY, k: key, v: val }), - }; - } - // if there is no hash collision, upgrade to an index node - return assoc( - { - type: INDEX_NODE, - bitmap: bitpos(root.hash, shift), - array: [root], - }, - shift, - hash, - key, - val, - addedLeaf - ); -} -/** - * Find the index of a key in the collision node's array - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {number} - */ -function collisionIndexOf(root, key) { - const size = root.array.length; - for (let i = 0; i < size; i++) { - if (isEqual(key, root.array[i].k)) { - return i; - } - } - return -1; -} -/** - * @template T,K,V - * @callback FindFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -/** - * Return the found entry or undefined if not present in the root - * @template K,V - * @type {FindFunction<Node<K,V>,K,V>} - */ -function find(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return findArray(root, shift, hash, key); - case INDEX_NODE: - return findIndex(root, shift, hash, key); - case COLLISION_NODE: - return findCollision(root, key); - } -} -/** - * @template K,V - * @type {FindFunction<ArrayNode<K,V>,K,V>} - */ -function findArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return undefined; - } - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @type {FindFunction<IndexNode<K,V>,K,V>} - */ -function findIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return undefined; - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - if (node.type !== ENTRY) { - return find(node, shift + SHIFT, hash, key); - } - if (isEqual(key, node.k)) { - return node; - } - return undefined; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Entry<K,V>} - */ -function findCollision(root, key) { - const idx = collisionIndexOf(root, key); - if (idx < 0) { - return undefined; - } - return root.array[idx]; -} -/** - * @template T,K,V - * @callback WithoutFunction - * @param {T} root - * @param {number} shift - * @param {number} hash - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -/** - * Remove an entry from the root, returning the updated root. - * Returns undefined if the node should be removed from the parent. - * @template K,V - * @type {WithoutFunction<Node<K,V>,K,V>} - * */ -function without(root, shift, hash, key) { - switch (root.type) { - case ARRAY_NODE: - return withoutArray(root, shift, hash, key); - case INDEX_NODE: - return withoutIndex(root, shift, hash, key); - case COLLISION_NODE: - return withoutCollision(root, key); - } -} -/** - * @template K,V - * @type {WithoutFunction<ArrayNode<K,V>,K,V>} - */ -function withoutArray(root, shift, hash, key) { - const idx = mask(hash, shift); - const node = root.array[idx]; - if (node === undefined) { - return root; // already empty - } - let n = undefined; - // if node is an entry and the keys are not equal there is nothing to remove - // if node is not an entry do a recursive call - if (node.type === ENTRY) { - if (!isEqual(node.k, key)) { - return root; // no changes - } - } else { - n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - } - // if the recursive call returned undefined the node should be removed - if (n === undefined) { - // if the number of child nodes is at the minimum, pack into an index node - if (root.size <= MIN_ARRAY_NODE) { - const arr = root.array; - const out = new Array(root.size - 1); - let i = 0; - let j = 0; - let bitmap = 0; - while (i < idx) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - ++i; // skip copying the removed node - while (i < arr.length) { - const nv = arr[i]; - if (nv !== undefined) { - out[j] = nv; - bitmap |= 1 << i; - ++j; - } - ++i; - } - return { - type: INDEX_NODE, - bitmap: bitmap, - array: out, - }; - } - return { - type: ARRAY_NODE, - size: root.size - 1, - array: cloneAndSet(root.array, idx, n), - }; - } - return { - type: ARRAY_NODE, - size: root.size, - array: cloneAndSet(root.array, idx, n), - }; -} -/** - * @template K,V - * @type {WithoutFunction<IndexNode<K,V>,K,V>} - */ -function withoutIndex(root, shift, hash, key) { - const bit = bitpos(hash, shift); - if ((root.bitmap & bit) === 0) { - return root; // already empty - } - const idx = index(root.bitmap, bit); - const node = root.array[idx]; - // if the item is not an entry - if (node.type !== ENTRY) { - const n = without(node, shift + SHIFT, hash, key); - if (n === node) { - return root; // no changes - } - // if not undefined, the child node still has items, so update it - if (n !== undefined) { - return { - type: INDEX_NODE, - bitmap: root.bitmap, - array: cloneAndSet(root.array, idx, n), - }; - } - // otherwise the child node should be removed - // if it was the only child node, remove this node from the parent - if (root.bitmap === bit) { - return undefined; - } - // otherwise just remove the child node - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - // otherwise the item is an entry, remove it if the key matches - if (isEqual(key, node.k)) { - if (root.bitmap === bit) { - return undefined; - } - return { - type: INDEX_NODE, - bitmap: root.bitmap ^ bit, - array: spliceOut(root.array, idx), - }; - } - return root; -} -/** - * @template K,V - * @param {CollisionNode<K,V>} root - * @param {K} key - * @returns {undefined | Node<K,V>} - */ -function withoutCollision(root, key) { - const idx = collisionIndexOf(root, key); - // if the key not found, no changes - if (idx < 0) { - return root; - } - // otherwise the entry was found, remove it - // if it was the only entry in this node, remove the whole node - if (root.array.length === 1) { - return undefined; - } - // otherwise just remove the entry - return { - type: COLLISION_NODE, - hash: root.hash, - array: spliceOut(root.array, idx), - }; -} -/** - * @template K,V - * @param {undefined | Node<K,V>} root - * @param {(value:V,key:K)=>void} fn - * @returns {void} - */ -function forEach(root, fn) { - if (root === undefined) { - return; - } - const items = root.array; - const size = items.length; - for (let i = 0; i < size; i++) { - const item = items[i]; - if (item === undefined) { - continue; - } - if (item.type === ENTRY) { - fn(item.v, item.k); - continue; - } - forEach(item, fn); - } -} -/** - * Extra wrapper to keep track of Dict size and clean up the API - * @template K,V - */ -export default class Dict { - /** - * @template V - * @param {Record<string,V>} o - * @returns {Dict<string,V>} - */ - static fromObject(o) { - const keys = Object.keys(o); - /** @type Dict<string,V> */ - let m = Dict.new(); - for (let i = 0; i < keys.length; i++) { - const k = keys[i]; - m = m.set(k, o[k]); - } - return m; - } - /** - * @template K,V - * @param {Map<K,V>} o - * @returns {Dict<K,V>} - */ - static fromMap(o) { - /** @type Dict<K,V> */ - let m = Dict.new(); - o.forEach((v, k) => { - m = m.set(k, v); - }); - return m; - } - static new() { - return new Dict(undefined, 0); - } - /** - * @param {undefined | Node<K,V>} root - * @param {number} size - */ - constructor(root, size) { - this.root = root; - this.size = size; - } - /** - * @template NotFound - * @param {K} key - * @param {NotFound} notFound - * @returns {NotFound | V} - */ - get(key, notFound) { - if (this.root === undefined) { - return notFound; - } - const found = find(this.root, 0, getHash(key), key); - if (found === undefined) { - return notFound; - } - return found.v; - } - /** - * @param {K} key - * @param {V} val - * @returns {Dict<K,V>} - */ - set(key, val) { - const addedLeaf = { val: false }; - const root = this.root === undefined ? EMPTY : this.root; - const newRoot = assoc(root, 0, getHash(key), key, val, addedLeaf); - if (newRoot === this.root) { - return this; - } - return new Dict(newRoot, addedLeaf.val ? this.size + 1 : this.size); - } - /** - * @param {K} key - * @returns {Dict<K,V>} - */ - delete(key) { - if (this.root === undefined) { - return this; - } - const newRoot = without(this.root, 0, getHash(key), key); - if (newRoot === this.root) { - return this; - } - if (newRoot === undefined) { - return Dict.new(); - } - return new Dict(newRoot, this.size - 1); - } - /** - * @param {K} key - * @returns {boolean} - */ - has(key) { - if (this.root === undefined) { - return false; - } - return find(this.root, 0, getHash(key), key) !== undefined; - } - /** - * @returns {[K,V][]} - */ - entries() { - if (this.root === undefined) { - return []; - } - /** @type [K,V][] */ - const result = []; - this.forEach((v, k) => result.push([k, v])); - return result; - } - /** - * - * @param {(val:V,key:K)=>void} fn - */ - forEach(fn) { - forEach(this.root, fn); - } - hashCode() { - let h = 0; - this.forEach((v, k) => { - h = (h + hashMerge(getHash(v), getHash(k))) | 0; - }); - return h; - } - /** - * @param {unknown} o - * @returns {boolean} - */ - equals(o) { - if (!(o instanceof Dict) || this.size !== o.size) { - return false; - } - let equal = true; - this.forEach((v, k) => { - equal = equal && isEqual(o.get(k, !v), v); - }); - return equal; - } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam deleted file mode 100644 index eab2f0b..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/base.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/bit_array - -@deprecated("Please use `base64_encode` in the `gleam/bit_array` module instead.") -pub fn encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_encode(input, padding) -} - -@deprecated("Please use `base64_decode` in the `gleam/bit_array` module instead.") -pub fn decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_decode(encoded) -} - -@deprecated("Please use `base64_url_encode` in the `gleam/bit_array` module instead.") -pub fn url_encode64(input: BitArray, padding: Bool) -> String { - bit_array.base64_url_encode(input, padding) -} - -@deprecated("Please use `base64_url_decode` in the `gleam/bit_array` module instead.") -pub fn url_decode64(encoded: String) -> Result(BitArray, Nil) { - bit_array.base64_url_decode(encoded) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam deleted file mode 100644 index 79860e9..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_array.gleam +++ /dev/null @@ -1,157 +0,0 @@ -//// BitArrays are a sequence of binary data of any length. - -import gleam/string - -/// Converts a UTF-8 `String` type into a `BitArray`. -/// -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_from_string") -pub fn from_string(x: String) -> BitArray - -/// Returns an integer which is the number of bytes in the bit array. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -pub fn byte_size(x: BitArray) -> Int - -/// Creates a new bit array by joining two bit arrays. -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: from_string("butter"), suffix: from_string("fly")) -/// from_string("butterfly") -/// ``` -/// -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - concat([first, second]) -} - -/// Extracts a sub-section of a bit array. -/// -/// The slice will start at given position and continue up to specified -/// length. -/// A negative length can be used to extract bytes at the end of a bit array. -/// -/// This function runs in constant time. -/// -@external(erlang, "gleam_stdlib", "bit_array_slice") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_slice") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) - -/// Tests to see whether a bit array is valid UTF-8. -/// -pub fn is_utf8(bits: BitArray) -> Bool { - do_is_utf8(bits) -} - -@target(erlang) -fn do_is_utf8(bits: BitArray) -> Bool { - case bits { - <<>> -> True - <<_:utf8, rest:bytes>> -> do_is_utf8(rest) - _ -> False - } -} - -@target(javascript) -fn do_is_utf8(bits: BitArray) -> Bool { - case to_string(bits) { - Ok(_) -> True - _ -> False - } -} - -/// Converts a bit array to a string. -/// -/// Returns an error if the bit array is invalid UTF-8 data. -/// -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - do_to_string(bits) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "identity") -fn unsafe_to_string(a: BitArray) -> String - -@target(erlang) -fn do_to_string(bits: BitArray) -> Result(String, Nil) { - case is_utf8(bits) { - True -> Ok(unsafe_to_string(bits)) - False -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "bit_array_to_string") -fn do_to_string(a: BitArray) -> Result(String, Nil) - -/// Creates a new bit array by joining multiple binaries. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([from_string("butter"), from_string("fly")]) -/// from_string("butterfly") -/// ``` -/// -@external(erlang, "gleam_stdlib", "bit_array_concat") -@external(javascript, "../gleam_stdlib.mjs", "bit_array_concat") -pub fn concat(bit_arrays: List(BitArray)) -> BitArray - -/// Encodes a BitArray into a base 64 encoded string. -/// -pub fn base64_encode(input: BitArray, padding: Bool) -> String { - let encoded = encode64(input) - case padding { - True -> encoded - False -> string.replace(encoded, "=", "") - } -} - -@external(erlang, "base64", "encode") -@external(javascript, "../gleam_stdlib.mjs", "encode64") -fn encode64(a: BitArray) -> String - -/// Decodes a base 64 encoded string into a `BitArray`. -/// -pub fn base64_decode(encoded: String) -> Result(BitArray, Nil) { - let padded = case byte_size(from_string(encoded)) % 4 { - 0 -> encoded - n -> string.append(encoded, string.repeat("=", 4 - n)) - } - decode64(padded) -} - -@external(erlang, "gleam_stdlib", "base_decode64") -@external(javascript, "../gleam_stdlib.mjs", "decode64") -fn decode64(a: String) -> Result(BitArray, Nil) - -/// Encodes a `BitArray` into a base 64 encoded string with URL and filename safe alphabet. -/// -pub fn base64_url_encode(input: BitArray, padding: Bool) -> String { - base64_encode(input, padding) - |> string.replace("+", "-") - |> string.replace("/", "_") -} - -/// Decodes a base 64 encoded string with URL and filename safe alphabet into a `BitArray`. -/// -pub fn base64_url_decode(encoded: String) -> Result(BitArray, Nil) { - encoded - |> string.replace("-", "+") - |> string.replace("_", "/") - |> base64_decode() -} - -@external(erlang, "binary", "encode_hex") -@external(javascript, "../gleam_stdlib.mjs", "base16_encode") -pub fn base16_encode(input: BitArray) -> String - -@external(erlang, "gleam_stdlib", "base16_decode") -@external(javascript, "../gleam_stdlib.mjs", "base16_decode") -pub fn base16_decode(input: String) -> Result(BitArray, Nil) diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam deleted file mode 100644 index ce6fe52..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_builder.gleam +++ /dev/null @@ -1,80 +0,0 @@ -//// This module has been deprecated in favour of `gleam/bytes_builder`. - -import gleam/bytes_builder -import gleam/string_builder.{type StringBuilder} - -pub type BitBuilder = - bytes_builder.BytesBuilder - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn new() -> BitBuilder { - bytes_builder.new() -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend(to: BitBuilder, prefix: BitArray) -> BitBuilder { - bytes_builder.prepend(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append(to: BitBuilder, suffix: BitArray) -> BitBuilder { - bytes_builder.append(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_builder(to: BitBuilder, prefix: BitBuilder) -> BitBuilder { - bytes_builder.prepend_builder(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_builder( - to first: BitBuilder, - suffix second: BitBuilder, -) -> BitBuilder { - bytes_builder.append_builder(first, second) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn prepend_string(to: BitBuilder, prefix: String) -> BitBuilder { - bytes_builder.prepend_string(to, prefix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn append_string(to: BitBuilder, suffix: String) -> BitBuilder { - bytes_builder.append_string(to, suffix) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat(builders: List(BitBuilder)) -> BitBuilder { - bytes_builder.concat(builders) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn concat_bit_strings(bits: List(BitArray)) -> BitBuilder { - bytes_builder.concat_bit_arrays(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string(string: String) -> BitBuilder { - bytes_builder.from_string(string) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_string_builder(builder: StringBuilder) -> BitBuilder { - bytes_builder.from_string_builder(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn from_bit_string(bits: BitArray) -> BitBuilder { - bytes_builder.from_bit_array(bits) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn to_bit_string(builder: BitBuilder) -> BitArray { - bytes_builder.to_bit_array(builder) -} - -@deprecated("Please use the `gleam/bytes_builder` module instead.") -pub fn byte_size(builder: BitBuilder) -> Int { - bytes_builder.byte_size(builder) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam deleted file mode 100644 index b703da0..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bit_string.gleam +++ /dev/null @@ -1,43 +0,0 @@ -//// This module has been deprecated. Please use the `gleam/bit_array` module -//// instead. - -import gleam/bit_array - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn from_string(x: String) -> BitArray { - bit_array.from_string(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn byte_size(x: BitArray) -> Int { - bit_array.byte_size(x) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn append(to first: BitArray, suffix second: BitArray) -> BitArray { - bit_array.append(first, second) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn slice( - from string: BitArray, - at position: Int, - take length: Int, -) -> Result(BitArray, Nil) { - bit_array.slice(string, position, length) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn is_utf8(bits: BitArray) -> Bool { - bit_array.is_utf8(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn to_string(bits: BitArray) -> Result(String, Nil) { - bit_array.to_string(bits) -} - -@deprecated("Please use the `gleam/bit_array` module instead.") -pub fn concat(bit_strings: List(BitArray)) -> BitArray { - bit_array.concat(bit_strings) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam deleted file mode 100644 index 91bd6b7..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bool.gleam +++ /dev/null @@ -1,428 +0,0 @@ -//// A type with two possible values, `True` and `False`. Used to indicate whether -//// things are... true or false! -//// -//// Often is it clearer and offers more type safety to define a custom type -//// than to use `Bool`. For example, rather than having a `is_teacher: Bool` -//// field consider having a `role: SchoolRole` field where `SchoolRole` is a custom -//// type that can be either `Student` or `Teacher`. - -import gleam/order.{type Order} - -/// Returns the and of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `&&` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > and(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > and(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > False |> and(True) -/// False -/// ``` -/// -pub fn and(a: Bool, b: Bool) -> Bool { - a && b -} - -/// Returns the or of two bools, but it evaluates both arguments. -/// -/// It's the function equivalent of the `||` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > or(True, True) -/// True -/// ``` -/// -/// ```gleam -/// > or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > False |> or(True) -/// True -/// ``` -/// -pub fn or(a: Bool, b: Bool) -> Bool { - a || b -} - -/// Returns the opposite bool value. -/// -/// This is the same as the `!` or `not` operators in some other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(True) -/// False -/// ``` -/// -/// ```gleam -/// > negate(False) -/// True -/// ``` -/// -pub fn negate(bool: Bool) -> Bool { - case bool { - True -> False - False -> True - } -} - -/// Returns the nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > nor(True, True) -/// False -/// ``` -/// -pub fn nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> False - } -} - -/// Returns the nand of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > nand(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > nand(True, True) -/// False -/// ``` -/// -pub fn nand(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive or of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_or(False, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_or(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_or(True, True) -/// False -/// ``` -/// -pub fn exclusive_or(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> False - False, True -> True - True, False -> True - True, True -> False - } -} - -/// Returns the exclusive nor of two bools. -/// -/// ## Examples -/// -/// ```gleam -/// > exclusive_nor(False, False) -/// True -/// ``` -/// -/// ```gleam -/// > exclusive_nor(False, True) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > exclusive_nor(True, True) -/// True -/// ``` -/// -pub fn exclusive_nor(a: Bool, b: Bool) -> Bool { - case a, b { - False, False -> True - False, True -> False - True, False -> False - True, True -> True - } -} - -/// Compares two bools and returns the first value's `Order` to the second. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/order -/// > compare(True, False) -/// order.Gt -/// ``` -/// -pub fn compare(a: Bool, with b: Bool) -> Order { - case a, b { - True, True -> order.Eq - True, False -> order.Gt - False, False -> order.Eq - False, True -> order.Lt - } -} - -/// Returns `True` if either argument's value is `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(True, False) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, True) -/// True -/// ``` -/// -/// ```gleam -/// > max(False, False) -/// False -/// ``` -/// -pub fn max(a: Bool, b: Bool) -> Bool { - case a { - True -> True - False -> b - } -} - -/// Returns `False` if either bool value is `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(True, False) -/// False -/// ``` -/// -/// ```gleam -/// > min(False, True) -/// False -/// -/// > min(False, False) -/// False -/// ``` -/// -pub fn min(a: Bool, b: Bool) -> Bool { - case a { - False -> False - True -> b - } -} - -/// Returns a numeric representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(True) -/// 1 -/// -/// > to_int(False) -/// 0 -/// ``` -/// -pub fn to_int(bool: Bool) -> Int { - case bool { - False -> 0 - True -> 1 - } -} - -/// Returns a string representation of the given bool. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(True) -/// "True" -/// ``` -/// -/// ```gleam -/// > to_string(False) -/// "False" -/// ``` -/// -pub fn to_string(bool: Bool) -> String { - case bool { - False -> "False" - True -> "True" - } -} - -/// Run a callback function if the given bool is `False`, otherwise return a -/// default value. -/// -/// With a `use` expression this function can simulate the early-return pattern -/// found in some other programming languages. -/// -/// In a procedural language: -/// -/// ```js -/// if (predicate) return value; -/// // ... -/// ``` -/// -/// In Gleam with a `use` expression: -/// -/// ```gleam -/// use <- guard(when: predicate, return: value) -/// // ... -/// ``` -/// -/// Like everything in Gleam `use` is an expression, so it short circuits the -/// current block, not the entire function. As a result you can assign the value -/// to a variable: -/// -/// ```gleam -/// let x = { -/// use <- guard(when: predicate, return: value) -/// // ... -/// } -/// ``` -/// -/// Note that unlike in procedural languages the `return` value is evaluated -/// even when the predicate is `False`, so it is advisable not to perform -/// expensive computation there. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Welcome!" -/// ``` -/// -/// ```gleam -/// > let name = "Kamaka" -/// > use <- guard(when: name == "", return: "Welcome!") -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -pub fn guard( - when requirement: Bool, - return consequence: t, - otherwise alternative: fn() -> t, -) -> t { - case requirement { - True -> consequence - False -> alternative() - } -} - -/// Runs a callback function if the given bool is `True`, otherwise runs an -/// alternative callback function. -/// -/// Useful when further computation should be delayed regardless of the given -/// bool's value. -/// -/// See [`guard`](#guard) for more info. -/// -/// ## Examples -/// -/// ```gleam -/// > let name = "Kamaka" -/// > let inquiry = fn() { "How may we address you?" } -/// > use <- lazy_guard(when: name == "", return: inquiry) -/// > "Hello, " <> name -/// "Hello, Kamaka" -/// ``` -/// -/// ```gleam -/// > import gleam/int -/// > let name = "" -/// > let greeting = fn() { "Hello, " <> name } -/// > use <- lazy_guard(when: name == "", otherwise: greeting) -/// > let number = int.random(1, 99) -/// > let name = "User " <> int.to_string(number) -/// > "Welcome, " <> name -/// "Welcome, User 54" -/// ``` -/// -pub fn lazy_guard( - when requirement: Bool, - return consequence: fn() -> a, - otherwise alternative: fn() -> a, -) -> a { - case requirement { - True -> consequence() - False -> alternative() - } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam deleted file mode 100644 index 20c145d..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/bytes_builder.gleam +++ /dev/null @@ -1,197 +0,0 @@ -//// BytesBuilder is a type used for efficiently concatenating bytes together -//// without copying. -//// -//// If we append one bit array to another the bit arrays must be copied to a -//// new location in memory so that they can sit together. This behaviour -//// enables efficient reading of the string but copying can be expensive, -//// especially if we want to join many bit arrays together. -//// -//// BytesBuilder is different in that it can be joined together in constant -//// time using minimal memory, and then can be efficiently converted to a -//// bit array using the `to_bit_array` function. -//// -//// Byte builders are always byte aligned, so that a number of bits that is not -//// divisible by 8 will be padded with 0s. -//// -//// On Erlang this type is compatible with Erlang's iolists. - -// TODO: pad bit arrays to byte boundaries when adding to a builder. -import gleam/string_builder.{type StringBuilder} -import gleam/list -import gleam/bit_array - -pub opaque type BytesBuilder { - Bytes(BitArray) - Text(StringBuilder) - Many(List(BytesBuilder)) -} - -/// Create an empty `BytesBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> BytesBuilder { - concat([]) -} - -/// Prepends a bit array to the start of a builder. -/// -/// Runs in constant time. -/// -pub fn prepend(to second: BytesBuilder, prefix first: BitArray) -> BytesBuilder { - append_builder(from_bit_array(first), second) -} - -/// Appends a bit array to the end of a builder. -/// -/// Runs in constant time. -/// -pub fn append(to first: BytesBuilder, suffix second: BitArray) -> BytesBuilder { - append_builder(first, from_bit_array(second)) -} - -/// Prepends a builder onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to second: BytesBuilder, - prefix first: BytesBuilder, -) -> BytesBuilder { - append_builder(first, second) -} - -/// Appends a builder onto the end of another. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "iodata_append") -pub fn append_builder( - to first: BytesBuilder, - suffix second: BytesBuilder, -) -> BytesBuilder { - case second { - Many(builders) -> Many([first, ..builders]) - _ -> Many([first, second]) - } -} - -/// Prepends a string onto the start of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn prepend_string( - to second: BytesBuilder, - prefix first: String, -) -> BytesBuilder { - append_builder(from_string(first), second) -} - -/// Appends a string onto the end of a builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time with the length of the string otherwise. -/// -pub fn append_string( - to first: BytesBuilder, - suffix second: String, -) -> BytesBuilder { - append_builder(first, from_string(second)) -} - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat(builders: List(BytesBuilder)) -> BytesBuilder { - Many(builders) -} - -/// Joins a list of bit arrays into a single builder. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "identity") -pub fn concat_bit_arrays(bits: List(BitArray)) -> BytesBuilder { - bits - |> list.map(fn(b) { from_bit_array(b) }) - |> concat() -} - -/// Creates a new builder from a string. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string(string: String) -> BytesBuilder { - Text(string_builder.from_string(string)) -} - -/// Creates a new builder from a string builder. -/// -/// Runs in constant time when running on Erlang. -/// Runs in linear time otherwise. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_string_builder(builder: StringBuilder) -> BytesBuilder { - Text(builder) -} - -/// Creates a new builder from a bit array. -/// -/// Runs in constant time. -/// -@external(erlang, "gleam_stdlib", "wrap_list") -pub fn from_bit_array(bits: BitArray) -> BytesBuilder { - Bytes(bits) -} - -/// Turns an builder into a bit array. -/// -/// Runs in linear time. -/// -/// When running on Erlang this function is implemented natively by the -/// virtual machine and is highly optimised. -/// -@external(erlang, "erlang", "list_to_bitstring") -pub fn to_bit_array(builder: BytesBuilder) -> BitArray { - [[builder]] - |> to_list([]) - |> list.reverse - |> bit_array.concat -} - -fn to_list( - stack: List(List(BytesBuilder)), - acc: List(BitArray), -) -> List(BitArray) { - case stack { - [] -> acc - - [[], ..remaining_stack] -> to_list(remaining_stack, acc) - - [[Bytes(bits), ..rest], ..remaining_stack] -> - to_list([rest, ..remaining_stack], [bits, ..acc]) - - [[Text(builder), ..rest], ..remaining_stack] -> { - let bits = bit_array.from_string(string_builder.to_string(builder)) - to_list([rest, ..remaining_stack], [bits, ..acc]) - } - - [[Many(builders), ..rest], ..remaining_stack] -> - to_list([builders, rest, ..remaining_stack], acc) - } -} - -/// Returns the size of the builder's content in bytes. -/// -/// Runs in linear time. -/// -@external(erlang, "erlang", "iolist_size") -pub fn byte_size(builder: BytesBuilder) -> Int { - [[builder]] - |> to_list([]) - |> list.fold(0, fn(acc, builder) { bit_array.byte_size(builder) + acc }) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam deleted file mode 100644 index 280bf9d..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/dict.gleam +++ /dev/null @@ -1,544 +0,0 @@ -import gleam/option.{type Option} - -/// A dictionary of keys and values. -/// -/// Any type can be used for the keys and values of a dict, but all the keys -/// must be of the same type and all the values must be of the same type. -/// -/// Each key can only be present in a dict once. -/// -/// Dicts are not ordered in any way, and any unintentional ordering is not to -/// be relied upon in your code as it may change in future versions of Erlang -/// or Gleam. -/// -/// See [the Erlang map module](https://erlang.org/doc/man/maps.html) for more -/// information. -/// -pub type Dict(key, value) - -/// Determines the number of key-value pairs in the dict. -/// This function runs in constant time and does not need to iterate the dict. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> size() -/// 0 -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", "value") |> size() -/// 1 -/// ``` -/// -pub fn size(dict: Dict(k, v)) -> Int { - do_size(dict) -} - -@external(erlang, "maps", "size") -@external(javascript, "../gleam_stdlib.mjs", "map_size") -fn do_size(a: Dict(k, v)) -> Int - -/// Converts the dict to a list of 2-element tuples `#(key, value)`, one for -/// each key-value pair in the dict. -/// -/// The tuples in the list have no specific order. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> to_list() -/// [] -/// ``` -/// -/// ```gleam -/// > new() |> insert("key", 0) |> to_list() -/// [#("key", 0)] -/// ``` -/// -pub fn to_list(dict: Dict(key, value)) -> List(#(key, value)) { - do_to_list(dict) -} - -@external(erlang, "maps", "to_list") -@external(javascript, "../gleam_stdlib.mjs", "map_to_list") -fn do_to_list(a: Dict(key, value)) -> List(#(key, value)) - -/// Converts a list of 2-element tuples `#(key, value)` to a dict. -/// -/// If two tuples have the same key the last one in the list will be the one -/// that is present in the dict. -/// -pub fn from_list(list: List(#(k, v))) -> Dict(k, v) { - do_from_list(list) -} - -@target(erlang) -@external(erlang, "maps", "from_list") -fn do_from_list(a: List(#(key, value))) -> Dict(key, value) - -@target(javascript) -fn fold_list_of_pair( - over list: List(#(k, v)), - from initial: Dict(k, v), -) -> Dict(k, v) { - case list { - [] -> initial - [x, ..rest] -> fold_list_of_pair(rest, insert(initial, x.0, x.1)) - } -} - -@target(javascript) -fn do_from_list(list: List(#(k, v))) -> Dict(k, v) { - fold_list_of_pair(list, new()) -} - -/// Determines whether or not a value present in the dict for a given key. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("a") -/// True -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> has_key("b") -/// False -/// ``` -/// -pub fn has_key(dict: Dict(k, v), key: k) -> Bool { - do_has_key(key, dict) -} - -@target(erlang) -@external(erlang, "maps", "is_key") -fn do_has_key(a: key, b: Dict(key, v)) -> Bool - -@target(javascript) -fn do_has_key(key: k, dict: Dict(k, v)) -> Bool { - get(dict, key) != Error(Nil) -} - -/// Creates a fresh dict that contains no values. -/// -pub fn new() -> Dict(key, value) { - do_new() -} - -@external(erlang, "maps", "new") -@external(javascript, "../gleam_stdlib.mjs", "new_map") -fn do_new() -> Dict(key, value) - -/// Fetches a value from a dict for a given key. -/// -/// The dict may not have a value for the key, so the value is wrapped in a -/// `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> get("b") -/// Error(Nil) -/// ``` -/// -pub fn get(from: Dict(key, value), get: key) -> Result(value, Nil) { - do_get(from, get) -} - -@external(erlang, "gleam_stdlib", "map_get") -@external(javascript, "../gleam_stdlib.mjs", "map_get") -fn do_get(a: Dict(key, value), b: key) -> Result(value, Nil) - -/// Inserts a value into the dict with the given key. -/// -/// If the dict already has a value for the given key then the value is -/// replaced with the new value. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert("a", 0) |> to_list -/// [#("a", 0)] -/// ``` -/// -/// ```gleam -/// > new() |> insert("a", 0) |> insert("a", 5) |> to_list -/// [#("a", 5)] -/// ``` -/// -pub fn insert(into dict: Dict(k, v), for key: k, insert value: v) -> Dict(k, v) { - do_insert(key, value, dict) -} - -@external(erlang, "maps", "put") -@external(javascript, "../gleam_stdlib.mjs", "map_insert") -fn do_insert(a: key, b: value, c: Dict(key, value)) -> Dict(key, value) - -/// Updates all values in a given dict by calling a given function on each key -/// and value. -/// -/// ## Examples -/// -/// ```gleam -/// > [#(3, 3), #(2, 4)] -/// > |> from_list -/// > |> map_values(fn(key, value) { key * value }) -/// [#(3, 9), #(2, 8)] -/// ``` -/// -pub fn map_values(in dict: Dict(k, v), with fun: fn(k, v) -> w) -> Dict(k, w) { - do_map_values(fun, dict) -} - -@target(erlang) -@external(erlang, "maps", "map") -fn do_map_values(a: fn(key, value) -> b, b: Dict(key, value)) -> Dict(key, b) - -@target(javascript) -fn do_map_values(f: fn(key, value) -> b, dict: Dict(key, value)) -> Dict(key, b) { - let f = fn(dict, k, v) { insert(dict, k, f(k, v)) } - dict - |> fold(from: new(), with: f) -} - -/// Gets a list of all keys in a given dict. -/// -/// Dicts are not ordered so the keys are not returned in any specific order. Do -/// not write code that relies on the order keys are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > keys([#("a", 0), #("b", 1)]) -/// ["a", "b"] -/// ``` -/// -pub fn keys(dict: Dict(keys, v)) -> List(keys) { - do_keys(dict) -} - -@target(erlang) -@external(erlang, "maps", "keys") -fn do_keys(a: Dict(keys, v)) -> List(keys) - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(dict: Dict(k, v)) -> List(k) { - let list_of_pairs = to_list(dict) - do_keys_acc(list_of_pairs, []) -} - -/// Gets a list of all values in a given dict. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order values are returned by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > values(from_list([#("a", 0), #("b", 1)])) -/// [0, 1] -/// ``` -/// -pub fn values(dict: Dict(k, values)) -> List(values) { - do_values(dict) -} - -@target(erlang) -@external(erlang, "maps", "values") -fn do_values(a: Dict(k, values)) -> List(values) - -@target(javascript) -fn do_values_acc(list: List(#(k, v)), acc: List(v)) -> List(v) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_values_acc(xs, [x.1, ..acc]) - } -} - -@target(javascript) -fn do_values(dict: Dict(k, v)) -> List(v) { - let list_of_pairs = to_list(dict) - do_values_acc(list_of_pairs, []) -} - -/// Creates a new dict from a given dict, minus any entries that a given function -/// returns `False` for. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { value != 0 }) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> filter(fn(key, value) { True }) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn filter( - in dict: Dict(k, v), - keeping predicate: fn(k, v) -> Bool, -) -> Dict(k, v) { - do_filter(predicate, dict) -} - -@target(erlang) -@external(erlang, "maps", "filter") -fn do_filter(a: fn(key, value) -> Bool, b: Dict(key, value)) -> Dict(key, value) - -@target(javascript) -fn do_filter( - f: fn(key, value) -> Bool, - dict: Dict(key, value), -) -> Dict(key, value) { - let insert = fn(dict, k, v) { - case f(k, v) { - True -> insert(dict, k, v) - _ -> dict - } - } - dict - |> fold(from: new(), with: insert) -} - -/// Creates a new dict from a given dict, only including any entries for which the -/// keys are in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["b"]) -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > from_list([#("a", 0), #("b", 1)]) -/// > |> take(["a", "b", "c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn take(from dict: Dict(k, v), keeping desired_keys: List(k)) -> Dict(k, v) { - do_take(desired_keys, dict) -} - -@target(erlang) -@external(erlang, "maps", "with") -fn do_take(a: List(k), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_taken( - dict: Dict(k, v), - desired_keys: List(k), - acc: Dict(k, v), -) -> Dict(k, v) { - let insert = fn(taken, key) { - case get(dict, key) { - Ok(value) -> insert(taken, key, value) - _ -> taken - } - } - case desired_keys { - [] -> acc - [x, ..xs] -> insert_taken(dict, xs, insert(acc, x)) - } -} - -@target(javascript) -fn do_take(desired_keys: List(k), dict: Dict(k, v)) -> Dict(k, v) { - insert_taken(dict, desired_keys, new()) -} - -/// Creates a new dict from a pair of given dicts by combining their entries. -/// -/// If there are entries with the same keys in both dicts the entry from the -/// second dict takes precedence. -/// -/// ## Examples -/// -/// ```gleam -/// > let a = from_list([#("a", 0), #("b", 1)]) -/// > let b = from_list([#("b", 2), #("c", 3)]) -/// > merge(a, b) -/// from_list([#("a", 0), #("b", 2), #("c", 3)]) -/// ``` -/// -pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v) { - do_merge(dict, new_entries) -} - -@target(erlang) -@external(erlang, "maps", "merge") -fn do_merge(a: Dict(k, v), b: Dict(k, v)) -> Dict(k, v) - -@target(javascript) -fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) { - insert(dict, pair.0, pair.1) -} - -@target(javascript) -fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) { - case new_entries { - [] -> dict - [x, ..xs] -> fold_inserts(xs, insert_pair(dict, x)) - } -} - -@target(javascript) -fn do_merge(dict: Dict(k, v), new_entries: Dict(k, v)) -> Dict(k, v) { - new_entries - |> to_list - |> fold_inserts(dict) -} - -/// Creates a new dict from a given dict with all the same entries except for the -/// one with a given key, if it exists. -/// -/// ## Examples -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "a") -/// from_list([#("b", 1)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], "c") -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -pub fn delete(from dict: Dict(k, v), delete key: k) -> Dict(k, v) { - do_delete(key, dict) -} - -@external(erlang, "maps", "remove") -@external(javascript, "../gleam_stdlib.mjs", "map_remove") -fn do_delete(a: k, b: Dict(k, v)) -> Dict(k, v) - -/// Creates a new dict from a given dict with all the same entries except any with -/// keys found in a given list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a"]) -/// from_list([#("b", 2)]) -/// ``` -/// -/// ```gleam -/// > delete([#("a", 0), #("b", 1)], ["c"]) -/// from_list([#("a", 0), #("b", 1)]) -/// ``` -/// -/// ```gleam -/// > drop([#("a", 0), #("b", 1)], ["a", "b", "c"]) -/// from_list([]) -/// ``` -/// -pub fn drop(from dict: Dict(k, v), drop disallowed_keys: List(k)) -> Dict(k, v) { - case disallowed_keys { - [] -> dict - [x, ..xs] -> drop(delete(dict, x), xs) - } -} - -/// Creates a new dict with one entry updated using a given function. -/// -/// If there was not an entry in the dict for the given key then the function -/// gets `None` as its argument, otherwise it gets `Some(value)`. -/// -/// ## Example -/// -/// ```gleam -/// > let increment = fn(x) { -/// > case x { -/// > Some(i) -> i + 1 -/// > None -> 0 -/// > } -/// > } -/// > let dict = from_list([#("a", 0)]) -/// > -/// > update(dict, "a", increment) -/// from_list([#("a", 1)]) -/// ``` -/// -/// ```gleam -/// > update(dict, "b", increment) -/// from_list([#("a", 0), #("b", 0)]) -/// ``` -/// -pub fn update( - in dict: Dict(k, v), - update key: k, - with fun: fn(Option(v)) -> v, -) -> Dict(k, v) { - dict - |> get(key) - |> option.from_result - |> fun - |> insert(dict, key, _) -} - -fn do_fold(list: List(#(k, v)), initial: acc, fun: fn(acc, k, v) -> acc) -> acc { - case list { - [] -> initial - [#(k, v), ..rest] -> do_fold(rest, fun(initial, k, v), fun) - } -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Dicts are not ordered so the values are not returned in any specific order. Do -/// not write code that relies on the order entries are used by this function -/// as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > let dict = from_list([#("a", 1), #("b", 3), #("c", 9)]) -/// > fold(dict, 0, fn(accumulator, key, value) { accumulator + value }) -/// 13 -/// ``` -/// -/// ```gleam -/// > import gleam/string.{append} -/// > fold(dict, "", fn(accumulator, key, value) { append(accumulator, key) }) -/// "abc" -/// ``` -/// -pub fn fold( - over dict: Dict(k, v), - from initial: acc, - with fun: fn(acc, k, v) -> acc, -) -> acc { - dict - |> to_list - |> do_fold(initial, fun) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam deleted file mode 100644 index c71c6f3..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/dynamic.gleam +++ /dev/null @@ -1,1508 +0,0 @@ -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option} -import gleam/result -import gleam/string_builder -@target(erlang) -import gleam/bit_array - -/// `Dynamic` data is data that we don't know the type of yet. -/// We likely get data like this from interop with Erlang, or from -/// IO with the outside world. -/// -pub type Dynamic - -/// Error returned when unexpected data is encountered -/// -pub type DecodeError { - DecodeError(expected: String, found: String, path: List(String)) -} - -pub type DecodeErrors = - List(DecodeError) - -pub type Decoder(t) = - fn(Dynamic) -> Result(t, DecodeErrors) - -/// Converts any Gleam data into `Dynamic` data. -/// -pub fn from(a) -> Dynamic { - do_from(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from(a: anything) -> Dynamic - -/// Unsafely casts a Dynamic value into any other type. -/// -/// This is an escape hatch for the type system that may be useful when wrapping -/// native Erlang APIs. It is to be used as a last measure only! -/// -/// If you can avoid using this function, do! -/// -pub fn unsafe_coerce(a: Dynamic) -> anything { - do_unsafe_coerce(a) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_unsafe_coerce(a: Dynamic) -> a - -/// Decodes a `Dynamic` value from a `Dynamic` value. -/// -/// This function doesn't seem very useful at first, but it can be convenient -/// when you need to give a decoder function but you don't actually care what -/// the to-decode value is. -/// -pub fn dynamic(value: Dynamic) -> Result(Dynamic, List(DecodeError)) { - Ok(value) -} - -/// Checks to see whether a `Dynamic` value is a bit array, and returns that bit -/// array if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bit_array(from("Hello")) == bit_array.from_string("Hello") -/// True -/// ``` -/// -/// ```gleam -/// > bit_array(from(123)) -/// Error([DecodeError(expected: "BitArray", found: "Int", path: [])]) -/// ``` -/// -pub fn bit_array(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - decode_bit_array(data) -} - -@deprecated("Please use `bit_array` instead") -pub fn bit_string(from data: Dynamic) -> Result(BitArray, DecodeErrors) { - bit_array(data) -} - -@external(erlang, "gleam_stdlib", "decode_bit_array") -@external(javascript, "../gleam_stdlib.mjs", "decode_bit_array") -fn decode_bit_array(a: Dynamic) -> Result(BitArray, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a string, and returns that string if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > string(from("Hello")) -/// Ok("Hello") -/// ``` -/// -/// ```gleam -/// > string(from(123)) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn string(from data: Dynamic) -> Result(String, DecodeErrors) { - decode_string(data) -} - -fn map_errors( - result: Result(t, DecodeErrors), - f: fn(DecodeError) -> DecodeError, -) -> Result(t, DecodeErrors) { - result.map_error(result, list.map(_, f)) -} - -@target(erlang) -fn decode_string(data: Dynamic) -> Result(String, DecodeErrors) { - bit_array(data) - |> map_errors(put_expected(_, "String")) - |> result.try(fn(raw) { - case bit_array.to_string(raw) { - Ok(string) -> Ok(string) - Error(Nil) -> - Error([DecodeError(expected: "String", found: "BitArray", path: [])]) - } - }) -} - -@target(erlang) -fn put_expected(error: DecodeError, expected: String) -> DecodeError { - DecodeError(..error, expected: expected) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "decode_string") -fn decode_string(a: Dynamic) -> Result(String, DecodeErrors) - -/// Return a string indicating the type of the dynamic value. -/// -/// ```gleam -/// > classify(from("Hello")) -/// "String" -/// ``` -/// -pub fn classify(data: Dynamic) -> String { - do_classify(data) -} - -@external(erlang, "gleam_stdlib", "classify_dynamic") -@external(javascript, "../gleam_stdlib.mjs", "classify_dynamic") -fn do_classify(a: Dynamic) -> String - -/// Checks to see whether a `Dynamic` value is an int, and returns that int if it -/// is. -/// -/// ## Examples -/// -/// ```gleam -/// > int(from(123)) -/// Ok(123) -/// ``` -/// -/// ```gleam -/// > int(from("Hello")) -/// Error([DecodeError(expected: "Int", found: "String", path: [])]) -/// ``` -/// -pub fn int(from data: Dynamic) -> Result(Int, DecodeErrors) { - decode_int(data) -} - -@external(erlang, "gleam_stdlib", "decode_int") -@external(javascript, "../gleam_stdlib.mjs", "decode_int") -fn decode_int(a: Dynamic) -> Result(Int, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a float, and returns that float if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > float(from(2.0)) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > float(from(123)) -/// Error([DecodeError(expected: "Float", found: "Int", path: [])]) -/// ``` -/// -pub fn float(from data: Dynamic) -> Result(Float, DecodeErrors) { - decode_float(data) -} - -@external(erlang, "gleam_stdlib", "decode_float") -@external(javascript, "../gleam_stdlib.mjs", "decode_float") -fn decode_float(a: Dynamic) -> Result(Float, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a bool, and returns that bool if -/// it is. -/// -/// ## Examples -/// -/// ```gleam -/// > bool(from(True)) -/// Ok(True) -/// ``` -/// -/// ```gleam -/// > bool(from(123)) -/// Error([DecodeError(expected: "Bool", found: "Int", path: [])]) -/// ``` -/// -pub fn bool(from data: Dynamic) -> Result(Bool, DecodeErrors) { - decode_bool(data) -} - -@external(erlang, "gleam_stdlib", "decode_bool") -@external(javascript, "../gleam_stdlib.mjs", "decode_bool") -fn decode_bool(a: Dynamic) -> Result(Bool, DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a list, and returns that list if it -/// is. The types of the elements are not checked. -/// -/// If you wish to decode all the elements in the list use the `list` function -/// instead. -/// -/// ## Examples -/// -/// ```gleam -/// > shallow_list(from(["a", "b", "c"])) -/// Ok([from("a"), from("b"), from("c")]) -/// ``` -/// -/// ```gleam -/// > shallow_list(1) -/// Error([DecodeError(expected: "List", found: "Int", path: [])]) -/// ``` -/// -pub fn shallow_list(from value: Dynamic) -> Result(List(Dynamic), DecodeErrors) { - decode_list(value) -} - -@external(erlang, "gleam_stdlib", "decode_list") -@external(javascript, "../gleam_stdlib.mjs", "decode_list") -fn decode_list(a: Dynamic) -> Result(List(Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_result") -@external(javascript, "../gleam_stdlib.mjs", "decode_result") -fn decode_result(a: Dynamic) -> Result(Result(a, e), DecodeErrors) - -/// Checks to see whether a `Dynamic` value is a result of a particular type, and -/// returns that result if it is. -/// -/// The `ok` and `error` arguments are decoders for decoding the `Ok` and -/// `Error` values of the result. -/// -/// ## Examples -/// -/// ```gleam -/// > from(Ok(1)) -/// > |> result(ok: int, error: string) -/// Ok(Ok(1)) -/// ``` -/// -/// ```gleam -/// > from(Error("boom")) -/// > |> result(ok: int, error: string) -/// Ok(Error("boom")) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> result(ok: int, error: string) -/// Error([DecodeError(expected: "Result", found: "Int", path: [])]) -/// ``` -/// -pub fn result( - ok decode_ok: Decoder(a), - error decode_error: Decoder(e), -) -> Decoder(Result(a, e)) { - fn(value) { - use inner_result <- result.try(decode_result(value)) - - case inner_result { - Ok(raw) -> { - use value <- result.try( - decode_ok(raw) - |> map_errors(push_path(_, "ok")), - ) - Ok(Ok(value)) - } - Error(raw) -> { - use value <- result.try( - decode_error(raw) - |> map_errors(push_path(_, "error")), - ) - Ok(Error(value)) - } - } - } -} - -/// Checks to see whether a `Dynamic` value is a list of a particular type, and -/// returns that list if it is. -/// -/// The second argument is a decoder function used to decode the elements of -/// the list. The list is only decoded if all elements in the list can be -/// successfully decoded using this function. -/// -/// If you do not wish to decode all the elements in the list use the `shallow_list` -/// function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > from(["a", "b", "c"]) -/// > |> list(of: string) -/// Ok(["a", "b", "c"]) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> list(of: string) -/// Error([DecodeError(expected: "String", found: "Int", path: ["*"])]) -/// ``` -/// -/// ```gleam -/// > from("ok") -/// > |> list(of: string) -/// Error([DecodeError(expected: "List", found: "String", path: [])]) -/// ``` -/// -pub fn list( - of decoder_type: fn(Dynamic) -> Result(inner, DecodeErrors), -) -> Decoder(List(inner)) { - fn(dynamic) { - use list <- result.try(shallow_list(dynamic)) - list - |> list.try_map(decoder_type) - |> map_errors(push_path(_, "*")) - } -} - -/// Checks to see if a `Dynamic` value is a nullable version of a particular -/// type, and returns a corresponding `Option` if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from("Hello") -/// > |> optional(string) -/// Ok(Some("Hello")) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("null")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("nil")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(atom.from_string("undefined")) -/// > |> optional(string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> optional(string) -/// Error([DecodeError(expected: "String", found: "Int", path: [])]) -/// ``` -/// -pub fn optional(of decode: Decoder(inner)) -> Decoder(Option(inner)) { - fn(value) { decode_optional(value, decode) } -} - -@external(erlang, "gleam_stdlib", "decode_option") -@external(javascript, "../gleam_stdlib.mjs", "decode_option") -fn decode_optional(a: Dynamic, b: Decoder(a)) -> Result(Option(a), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a map with a specific field, and returns -/// the value of that field if it is. -/// -/// This will not succeed on a record. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok("World") -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn field(named name: a, of inner_type: Decoder(t)) -> Decoder(t) { - fn(value) { - let missing_field_error = - DecodeError(expected: "field", found: "nothing", path: []) - - use maybe_inner <- result.try(decode_field(value, name)) - maybe_inner - |> option.to_result([missing_field_error]) - |> result.try(inner_type) - |> map_errors(push_path(_, name)) - } -} - -/// Checks to see if a `Dynamic` value is a map with a specific field. -/// If the map does not have the specified field, returns an `Ok(None)` instead of failing; otherwise, -/// returns the decoded field wrapped in `Some(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> dict.insert("Hello", "World") -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(Some("World")) -/// ``` -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() -/// > |> from -/// > |> field(named: "Hello", of: string) -/// Ok(None) -/// ``` -/// -/// ```gleam -/// > from(123) -/// > |> field("Hello", string) -/// Error([DecodeError(expected: "Map", found: "Int", path: [])]) -/// ``` -/// -pub fn optional_field( - named name: a, - of inner_type: Decoder(t), -) -> Decoder(Option(t)) { - fn(value) { - use maybe_inner <- result.try(decode_field(value, name)) - case maybe_inner { - option.None -> Ok(option.None) - option.Some(dynamic_inner) -> - dynamic_inner - |> decode_optional(inner_type) - |> map_errors(push_path(_, name)) - } - } -} - -@external(erlang, "gleam_stdlib", "decode_field") -@external(javascript, "../gleam_stdlib.mjs", "decode_field") -fn decode_field(a: Dynamic, b: name) -> Result(Option(Dynamic), DecodeErrors) - -/// Checks to see if a `Dynamic` value is a tuple large enough to have a certain -/// index, and returns the value of that index if it is. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(0, int) -/// Ok(from(1)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> element(2, int) -/// Error([ -/// DecodeError( -/// expected: "Tuple of at least 3 elements", -/// found: "Tuple of 2 elements", -/// path: [], -/// ), -/// ]) -/// ``` -/// -pub fn element(at index: Int, of inner_type: Decoder(t)) -> Decoder(t) { - fn(data: Dynamic) { - use tuple <- result.try(decode_tuple(data)) - let size = tuple_size(tuple) - use data <- result.try(case index >= 0 { - True -> - case index < size { - True -> tuple_get(tuple, index) - False -> at_least_decode_tuple_error(index + 1, data) - } - False -> - case int.absolute_value(index) <= size { - True -> tuple_get(tuple, size + index) - False -> at_least_decode_tuple_error(int.absolute_value(index), data) - } - }) - inner_type(data) - |> map_errors(push_path(_, index)) - } -} - -fn at_least_decode_tuple_error( - size: Int, - data: Dynamic, -) -> Result(a, DecodeErrors) { - let s = case size { - 1 -> "" - _ -> "s" - } - let error = - ["Tuple of at least ", int.to_string(size), " element", s] - |> string_builder.from_strings - |> string_builder.to_string - |> DecodeError(found: classify(data), path: []) - Error([error]) -} - -// A tuple of unknown size -type UnknownTuple - -@external(erlang, "gleam_stdlib", "decode_tuple") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple") -fn decode_tuple(a: Dynamic) -> Result(UnknownTuple, DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple2") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple2") -fn decode_tuple2(a: Dynamic) -> Result(#(Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple3") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple3") -fn decode_tuple3( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple4") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple4") -fn decode_tuple4( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple5") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple5") -fn decode_tuple5( - a: Dynamic, -) -> Result(#(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), DecodeErrors) - -@external(erlang, "gleam_stdlib", "decode_tuple6") -@external(javascript, "../gleam_stdlib.mjs", "decode_tuple6") -fn decode_tuple6( - a: Dynamic, -) -> Result( - #(Dynamic, Dynamic, Dynamic, Dynamic, Dynamic, Dynamic), - DecodeErrors, -) - -@external(erlang, "gleam_stdlib", "tuple_get") -@external(javascript, "../gleam_stdlib.mjs", "tuple_get") -fn tuple_get(a: UnknownTuple, b: Int) -> Result(Dynamic, DecodeErrors) - -@external(erlang, "gleam_stdlib", "size_of_tuple") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn tuple_size(a: UnknownTuple) -> Int - -fn tuple_errors( - result: Result(a, List(DecodeError)), - name: String, -) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> list.map(errors, push_path(_, name)) - } -} - -fn push_path(error: DecodeError, name: t) -> DecodeError { - let name = from(name) - let decoder = any([string, fn(x) { result.map(int(x), int.to_string) }]) - let name = case decoder(name) { - Ok(name) -> name - Error(_) -> - ["<", classify(name), ">"] - |> string_builder.from_strings - |> string_builder.to_string - } - DecodeError(..error, path: [name, ..error.path]) -} - -/// Checks to see if a `Dynamic` value is a 2-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0)) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from([1, 2]) -/// > |> tuple2(int, int) -/// Ok(#(1, 2)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0)]) -/// > |> tuple2(int, float) -/// Ok(#(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple2(int, float) -/// Error([ -/// DecodeError(expected: "Tuple of 2 elements", found: "Tuple of 3 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple2(int, float) -/// Error([DecodeError(expected: "Tuple of 2 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple2( - first decode1: Decoder(a), - second decode2: Decoder(b), -) -> Decoder(#(a, b)) { - fn(value) { - use #(a, b) <- result.try(decode_tuple2(value)) - case decode1(a), decode2(b) { - Ok(a), Ok(b) -> Ok(#(a, b)) - a, b -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 3-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3)) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3]) -/// > |> tuple3(int, int, int) -/// Ok(#(1, 2, 3)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3")]) -/// > |> tuple3(int, float, string) -/// Ok(#(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple3(int, float, string) -/// Error([ -/// DecodeError(expected: "Tuple of 3 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple3( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), -) -> Decoder(#(a, b, c)) { - fn(value) { - use #(a, b, c) <- result.try(decode_tuple3(value)) - case decode1(a), decode2(b), decode3(c) { - Ok(a), Ok(b), Ok(c) -> Ok(#(a, b, c)) - a, b, c -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 4-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4)) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4)) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4]) -/// > |> tuple4(int, int, int, int) -/// Ok(#(1, 2, 3, 4)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4)]) -/// > |> tuple4(int, float, string, int) -/// Ok(#(1, 2.0, "3", 4)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple4(int, float, string, int) -/// Error([ -/// DecodeError(expected: "Tuple of 4 elements", found: "String", path: []), -/// ]) -/// ``` -/// -pub fn tuple4( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), -) -> Decoder(#(a, b, c, d)) { - fn(value) { - use #(a, b, c, d) <- result.try(decode_tuple4(value)) - case decode1(a), decode2(b), decode3(c), decode4(d) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(#(a, b, c, d)) - a, b, c, d -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 5-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5)) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5)) -/// > |> tuple5(int, float, string, int, int) -/// Ok(#(1, 2.0, "3", 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5]) -/// > |> tuple5(int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True)]) -/// > |> tuple5(int, float, string, int, bool) -/// Ok(#(1, 2.0, "3", 4, True)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple5(int, float, string, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 5 elements", found: "Tuple of 2 elements", path: [])), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple5(int, float, string, int, int) -/// Error([DecodeError(expected: "Tuple of 5 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple5( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), -) -> Decoder(#(a, b, c, d, e)) { - fn(value) { - use #(a, b, c, d, e) <- result.try(decode_tuple5(value)) - case decode1(a), decode2(b), decode3(c), decode4(d), decode5(e) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(#(a, b, c, d, e)) - a, b, c, d, e -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a 6-element tuple, list or array containing -/// specifically typed elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2, 3, 4, 5, 6)) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2.0, "3", 4, 5, 6)) -/// > |> tuple6(int, float, string, int, int, int) -/// Ok(#(1, 2.0, "3", 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([1, 2, 3, 4, 5, 6]) -/// > |> tuple6(int, int, int, int, int, int) -/// Ok(#(1, 2, 3, 4, 5, 6)) -/// ``` -/// -/// ```gleam -/// > from([from(1), from(2.0), from("3"), from(4), from(True), from(False)]) -/// > |> tuple6(int, float, string, int, bool, bool) -/// Ok(#(1, 2.0, "3", 4, True, False)) -/// ``` -/// -/// ```gleam -/// > from(#(1, 2)) -/// > |> tuple6(int, float, string, int, int, int) -/// Error([ -/// DecodeError(expected: "Tuple of 6 elements", found: "Tuple of 2 elements", path: []), -/// ]) -/// ``` -/// -/// ```gleam -/// > from("") -/// > |> tuple6(int, float, string, int, int, int) -/// Error([DecodeError(expected: "Tuple of 6 elements", found: "String", path: [])]) -/// ``` -/// -pub fn tuple6( - first decode1: Decoder(a), - second decode2: Decoder(b), - third decode3: Decoder(c), - fourth decode4: Decoder(d), - fifth decode5: Decoder(e), - sixth decode6: Decoder(f), -) -> Decoder(#(a, b, c, d, e, f)) { - fn(value) { - use #(a, b, c, d, e, f) <- result.try(decode_tuple6(value)) - case - decode1(a), - decode2(b), - decode3(c), - decode4(d), - decode5(e), - decode6(f) - { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> Ok(#(a, b, c, d, e, f)) - a, b, c, d, e, f -> - tuple_errors(a, "0") - |> list.append(tuple_errors(b, "1")) - |> list.append(tuple_errors(c, "2")) - |> list.append(tuple_errors(d, "3")) - |> list.append(tuple_errors(e, "4")) - |> list.append(tuple_errors(f, "5")) - |> Error - } - } -} - -/// Checks to see if a `Dynamic` value is a dict. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/dict -/// > dict.new() |> from |> map(string, int) -/// Ok(dict.new()) -/// ``` -/// -/// ```gleam -/// > from(1) |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "Int", path: [])) -/// ``` -/// -/// ```gleam -/// > from("") |> map(string, int) -/// Error(DecodeError(expected: "Map", found: "String", path: [])) -/// ``` -/// -pub fn dict( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - fn(value) { - use map <- result.try(decode_map(value)) - use pairs <- result.try( - map - |> dict.to_list - |> list.try_map(fn(pair) { - let #(k, v) = pair - use k <- result.try( - key_type(k) - |> map_errors(push_path(_, "keys")), - ) - use v <- result.try( - value_type(v) - |> map_errors(push_path(_, "values")), - ) - Ok(#(k, v)) - }), - ) - Ok(dict.from_list(pairs)) - } -} - -@deprecated("Use `dict` instead") -pub fn map( - of key_type: Decoder(k), - to value_type: Decoder(v), -) -> Decoder(Dict(k, v)) { - dict(key_type, value_type) -} - -@external(erlang, "gleam_stdlib", "decode_map") -@external(javascript, "../gleam_stdlib.mjs", "decode_map") -fn decode_map(a: Dynamic) -> Result(Dict(Dynamic, Dynamic), DecodeErrors) - -/// Joins multiple decoders into one. When run they will each be tried in turn -/// until one succeeds, or they all fail. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/result -/// > let bool_or_string = any(of: [ -/// > string, -/// > fn(x) { result.map(bool(x), fn(_) { "a bool" }) } -/// > ]) -/// > bool_or_string(from("ok")) -/// Ok("ok") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(True)) -/// Ok("a bool") -/// ``` -/// -/// ```gleam -/// > bool_or_string(from(1)) -/// Error(DecodeError(expected: "another type", found: "Int", path: [])) -/// ``` -/// -pub fn any(of decoders: List(Decoder(t))) -> Decoder(t) { - fn(data) { - case decoders { - [] -> - Error([ - DecodeError(found: classify(data), expected: "another type", path: []), - ]) - - [decoder, ..decoders] -> - case decoder(data) { - Ok(decoded) -> Ok(decoded) - Error(_) -> any(decoders)(data) - } - } - } -} - -/// Decode 1 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode1(MyRecord, element(0, int)) -/// Ok(MyRecord(1)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode1(MyRecord, element(0, int)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// ]) -/// ``` -/// -pub fn decode1(constructor: fn(t1) -> t, t1: Decoder(t1)) -> Decoder(t) { - fn(value) { - case t1(value) { - Ok(a) -> Ok(constructor(a)) - a -> Error(all_errors(a)) - } - } -} - -/// Decode 2 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Ok(MyRecord(1, 2.0)) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode2(MyRecord, element(0, int), element(1, float)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode2( - constructor: fn(t1, t2) -> t, - t1: Decoder(t1), - t2: Decoder(t2), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value) { - Ok(a), Ok(b) -> Ok(constructor(a, b)) - a, b -> Error(list.concat([all_errors(a), all_errors(b)])) - } - } -} - -/// Decode 3 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.0, "3")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Ok(MyRecord(1, 2.0, "3")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "")) -/// > |> decode3(MyRecord, element(0, int), element(1, float), element(2, string)) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode3( - constructor: fn(t1, t2, t3) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), -) -> Decoder(t) { - fn(value) { - case t1(value), t2(value), t3(value) { - Ok(a), Ok(b), Ok(c) -> Ok(constructor(a, b, c)) - a, b, c -> - Error(list.concat([all_errors(a), all_errors(b), all_errors(c)])) - } - } -} - -/// Decode 4 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "")) -/// > |> decode4( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode4( - constructor: fn(t1, t2, t3, t4) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x) { - Ok(a), Ok(b), Ok(c), Ok(d) -> Ok(constructor(a, b, c, d)) - a, b, c, d -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - ])) - } - } -} - -/// Decode 5 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "")) -/// > |> decode5( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode5( - constructor: fn(t1, t2, t3, t4, t5) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e) -> Ok(constructor(a, b, c, d, e)) - a, b, c, d, e -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - ])) - } - } -} - -/// Decode 6 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "")) -/// > |> decode6( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode6( - constructor: fn(t1, t2, t3, t4, t5, t6) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f) -> - Ok(constructor(a, b, c, d, e, f)) - a, b, c, d, e, f -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - ])) - } - } -} - -/// Decode 7 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "")) -/// > |> decode7( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode7( - constructor: fn(t1, t2, t3, t4, t5, t6, t7) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g) -> - Ok(constructor(a, b, c, d, e, f, g)) - a, b, c, d, e, f, g -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - ])) - } - } -} - -/// Decode 8 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "")) -/// > |> decode8( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode8( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h) -> - Ok(constructor(a, b, c, d, e, f, g, h)) - a, b, c, d, e, f, g, h -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - ])) - } - } -} - -/// Decode 9 values from a `Dynamic` value. -/// -/// ## Examples -/// -/// ```gleam -/// > from(#(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Ok(MyRecord(1, 2.1, "3", "4", "5", "6", "7", "8", "9")) -/// ``` -/// -/// ```gleam -/// > from(#("", "", "", "", "", "", "", "", "")) -/// > |> decode9( -/// > MyRecord, -/// > element(0, int), -/// > element(1, float), -/// > element(2, string), -/// > element(3, string), -/// > element(4, string), -/// > element(5, string), -/// > element(6, string), -/// > element(7, string), -/// > element(8, string), -/// > ) -/// Error([ -/// DecodeError(expected: "Int", found: "String", path: ["0"]), -/// DecodeError(expected: "Float", found: "String", path: ["1"]), -/// ]) -/// ``` -/// -pub fn decode9( - constructor: fn(t1, t2, t3, t4, t5, t6, t7, t8, t9) -> t, - t1: Decoder(t1), - t2: Decoder(t2), - t3: Decoder(t3), - t4: Decoder(t4), - t5: Decoder(t5), - t6: Decoder(t6), - t7: Decoder(t7), - t8: Decoder(t8), - t9: Decoder(t9), -) -> Decoder(t) { - fn(x: Dynamic) { - case t1(x), t2(x), t3(x), t4(x), t5(x), t6(x), t7(x), t8(x), t9(x) { - Ok(a), Ok(b), Ok(c), Ok(d), Ok(e), Ok(f), Ok(g), Ok(h), Ok(i) -> - Ok(constructor(a, b, c, d, e, f, g, h, i)) - a, b, c, d, e, f, g, h, i -> - Error(list.concat([ - all_errors(a), - all_errors(b), - all_errors(c), - all_errors(d), - all_errors(e), - all_errors(f), - all_errors(g), - all_errors(h), - all_errors(i), - ])) - } - } -} - -fn all_errors(result: Result(a, List(DecodeError))) -> List(DecodeError) { - case result { - Ok(_) -> [] - Error(errors) -> errors - } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam deleted file mode 100644 index 5d62419..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/float.gleam +++ /dev/null @@ -1,546 +0,0 @@ -//// Functions for working with floats. -//// -//// ## Division by zero -//// -//// Gleam runs on the Erlang virtual machine, which does not follow the IEEE -//// 754 standard for floating point arithmetic and does not have an `Infinity` -//// value. In Erlang division by zero results in a crash, however Gleam does -//// not have partial functions and operators in core so instead division by zero -//// returns zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/order.{type Order} - -/// Attempts to parse a string as a `Float`, returning `Error(Nil)` if it was -/// not possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2.3") -/// Ok(2.3) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Float, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_float") -@external(javascript, "../gleam_stdlib.mjs", "parse_float") -fn do_parse(a: String) -> Result(Float, Nil) - -/// Returns the string representation of the provided `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2.3) -/// "2.3" -/// ``` -/// -pub fn to_string(x: Float) -> String { - do_to_string(x) -} - -@external(erlang, "gleam_stdlib", "float_to_string") -@external(javascript, "../gleam_stdlib.mjs", "float_to_string") -fn do_to_string(a: Float) -> String - -/// Restricts a `Float` between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(1.2, min: 1.4, max: 1.6) -/// 1.4 -/// ``` -/// -pub fn clamp(x: Float, min min_bound: Float, max max_bound: Float) -> Float { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two `Float`s, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2.0, 2.3) -/// Lt -/// ``` -/// -/// To handle -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems) -/// you may use [`loosely_compare`](#loosely_compare) instead. -/// -pub fn compare(a: Float, with b: Float) -> Order { - case a == b { - True -> order.Eq - False -> - case a <. b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two `Float`s within a tolerance, returning an `Order`: -/// `Lt` for lower than, `Eq` for equals, or `Gt` for greater than. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_compare(5.0, with: 5.3, tolerating: 0.5) -/// Eq -/// ``` -/// -/// If you want to check only for equality you may use -/// [`loosely_equals`](#loosely_equals) instead. -/// -pub fn loosely_compare( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Order { - let difference = absolute_value(a -. b) - case difference <=. tolerance { - True -> order.Eq - False -> compare(a, b) - } -} - -/// Checks for equality of two `Float`s within a tolerance, -/// returning an `Bool`. -/// -/// This function allows Float comparison while handling -/// [Floating Point Imprecision](https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems). -/// -/// Notice: For `Float`s the tolerance won't be exact: -/// `5.3 - 5.0` is not exactly `0.3`. -/// -/// ## Examples -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.3, tolerating: 0.5) -/// True -/// ``` -/// -/// ```gleam -/// > loosely_equals(5.0, with: 5.1, tolerating: 0.1) -/// False -/// ``` -/// -pub fn loosely_equals( - a: Float, - with b: Float, - tolerating tolerance: Float, -) -> Bool { - let difference = absolute_value(a -. b) - difference <=. tolerance -} - -/// Compares two `Float`s, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2.0, 2.3) -/// 2.0 -/// ``` -/// -pub fn min(a: Float, b: Float) -> Float { - case a <. b { - True -> a - False -> b - } -} - -/// Compares two `Float`s, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2.0, 2.3) -/// 2.3 -/// ``` -/// -pub fn max(a: Float, b: Float) -> Float { - case a >. b { - True -> a - False -> b - } -} - -/// Rounds the value to the next highest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > ceiling(2.3) -/// 3.0 -/// ``` -/// -pub fn ceiling(x: Float) -> Float { - do_ceiling(x) -} - -@external(erlang, "math", "ceil") -@external(javascript, "../gleam_stdlib.mjs", "ceiling") -fn do_ceiling(a: Float) -> Float - -/// Rounds the value to the next lowest whole number as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor(2.3) -/// 2.0 -/// ``` -/// -pub fn floor(x: Float) -> Float { - do_floor(x) -} - -@external(erlang, "math", "floor") -@external(javascript, "../gleam_stdlib.mjs", "floor") -fn do_floor(a: Float) -> Float - -/// Rounds the value to the nearest whole number as an `Int`. -/// -/// ## Examples -/// -/// ```gleam -/// > round(2.3) -/// 2 -/// ``` -/// -/// ```gleam -/// > round(2.5) -/// 3 -/// ``` -/// -pub fn round(x: Float) -> Int { - do_round(x) -} - -@target(erlang) -@external(erlang, "erlang", "round") -fn do_round(a: Float) -> Int - -@target(javascript) -fn do_round(x: Float) -> Int { - case x >=. 0.0 { - True -> js_round(x) - _ -> 0 - js_round(negate(x)) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "round") -fn js_round(a: Float) -> Int - -/// Returns the value as an `Int`, truncating all decimal digits. -/// -/// ## Examples -/// -/// ```gleam -/// > truncate(2.4343434847383438) -/// 2 -/// ``` -/// -pub fn truncate(x: Float) -> Int { - do_truncate(x) -} - -@external(erlang, "erlang", "trunc") -@external(javascript, "../gleam_stdlib.mjs", "truncate") -fn do_truncate(a: Float) -> Int - -/// Returns the absolute value of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12.5) -/// 12.5 -/// ``` -/// -/// ```gleam -/// > absolute_value(10.2) -/// 10.2 -/// ``` -/// -pub fn absolute_value(x: Float) -> Float { - case x >=. 0.0 { - True -> x - _ -> 0.0 -. x - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2.0, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2.0, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8.0, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4.0 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1.0, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Float, of exponent: Float) -> Result(Float, Nil) { - let fractional: Bool = ceiling(exponent) -. exponent >. 0.0 - // In the following check: - // 1. If the base is negative and the exponent is fractional then - // return an error as it will otherwise be an imaginary number - // 2. If the base is 0 and the exponent is negative then the expression - // is equivalent to the exponent divided by 0 and an error should be - // returned - case base <. 0.0 && fractional || base == 0.0 && exponent <. 0.0 { - True -> Error(Nil) - False -> Ok(do_power(base, exponent)) - } -} - -@external(erlang, "math", "pow") -@external(javascript, "../gleam_stdlib.mjs", "power") -fn do_power(a: Float, b: Float) -> Float - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4.0) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16.0) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Float) -> Result(Float, Nil) { - power(x, 0.5) -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1.0) -/// -1.0 -/// ``` -/// -pub fn negate(x: Float) -> Float { - -1.0 *. x -} - -/// Sums a list of `Float`s. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1.0, 2.2, 3.3]) -/// 6.5 -/// ``` -/// -pub fn sum(numbers: List(Float)) -> Float { - numbers - |> do_sum(0.0) -} - -fn do_sum(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x +. initial) - } -} - -/// Multiplies a list of `Float`s and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2.5, 3.2, 4.2]) -/// 33.6 -/// ``` -/// -pub fn product(numbers: List(Float)) -> Float { - case numbers { - [] -> 1.0 - _ -> do_product(numbers, 1.0) - } -} - -fn do_product(numbers: List(Float), initial: Float) -> Float { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x *. initial) - } -} - -/// Generates a random float between the given minimum and maximum values. -/// -/// -/// ## Examples -/// -/// ```gleam -/// > random(1.0, 5.0) -/// 2.646355926896028 -/// ``` -/// -pub fn random(min: Float, max: Float) -> Float { - do_random_uniform() *. { max -. min } +. min -} - -/// Returns a random float uniformly distributed in the value range -/// 0.0 =< X < 1.0 and updates the state in the process dictionary. -/// See: <https://www.erlang.org/doc/man/rand.html#uniform-0> -/// -@external(erlang, "rand", "uniform") -@external(javascript, "../gleam_stdlib.mjs", "random_uniform") -fn do_random_uniform() -> Float - -/// Returns division of the inputs as a `Result`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0.0, 1.0) -/// Ok(1.0) -/// ``` -/// -/// ```gleam -/// > divide(1.0, 0.0) -/// Error(Nil) -/// ``` -/// -pub fn divide(a: Float, by b: Float) -> Result(Float, Nil) { - case b { - 0.0 -> Error(Nil) - b -> Ok(a /. b) - } -} - -/// Adds two floats together. -/// -/// It's the function equivalent of the `+.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1.0, 2.0) -/// 3.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 0.0, add) -/// 6.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> add(2.0) -/// 5.0 -/// ``` -/// -pub fn add(a: Float, b: Float) -> Float { - a +. b -} - -/// Multiplies two floats together. -/// -/// It's the function equivalent of the `*.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2.0, 4.0) -/// 8.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2.0, 3.0, 4.0], 1.0, multiply) -/// 24.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> multiply(2.0) -/// 6.0 -/// ``` -/// -pub fn multiply(a: Float, b: Float) -> Float { - a *. b -} - -/// Subtracts one float from another. -/// -/// It's the function equivalent of the `-.` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3.0, 1.0) -/// 2.0 -/// ``` -/// -/// ```gleam -/// > import gleam/list -/// > list.fold([1.0, 2.0, 3.0], 10.0, subtract) -/// 4.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(_, 2.0) -/// 1.0 -/// ``` -/// -/// ```gleam -/// > 3.0 |> subtract(2.0, _) -/// -1.0 -/// ``` -/// -pub fn subtract(a: Float, b: Float) -> Float { - a -. b -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam deleted file mode 100644 index daa997d..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/function.gleam +++ /dev/null @@ -1,162 +0,0 @@ -/// Takes two functions and chains them together to form one function that -/// takes the input from the first and returns the output of the second. -/// -pub fn compose(fun1: fn(a) -> b, fun2: fn(b) -> c) -> fn(a) -> c { - fn(a) { fun2(fun1(a)) } -} - -/// Takes a function with `2` arguments (an arity of `2`), and returns the -/// curried equivalent. -/// -/// `fn(a, b) -> c` becomes `fn(a) -> fn(b) -> c`. -/// -/// ## Examples -/// -/// *Currying* creates a new function that is identical to the given function -/// except that arguments must now be supplied one by one over several function -/// calls. It thus is the process of taking a function with `n` arguments -/// and producing a sequence of `n` single-argument functions. Given: -/// -/// ```gleam -/// > fn my_fun(i: Int, s: String) -> String { ... } -/// ``` -/// -/// …calling `curry2(my_fun)` would return the curried equivalent, like so: -/// -/// ```gleam -/// > curry2(my_fun) -/// fn(Int) -> fn(String) -> String -/// ``` -/// -/// Currying is useful when you want to partially apply a function with -/// some arguments and then pass it somewhere else, for example: -/// -/// ```gleam -/// > import gleam/list -/// > let multiply = curry2(fn(x, y) { x * y }) -/// > let doubles = list.map([1, 2, 3], multiply(2)) -/// [2, 4, 6] -/// ``` -/// -pub fn curry2(fun: fn(a, b) -> value) { - fn(a) { fn(b) { fun(a, b) } } -} - -/// Takes a function with `3` arguments (an arity of `3`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c) -> d` becomes `fn(a) -> fn(b) -> fn(c) -> d`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry3(fun: fn(a, b, c) -> value) { - fn(a) { fn(b) { fn(c) { fun(a, b, c) } } } -} - -/// Takes a function with `4` arguments (an arity of `4`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d) -> e` becomes `fn(a) -> fn(b) -> fn(c) -> fn(d) -> e`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry4(fun: fn(a, b, c, d) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fun(a, b, c, d) } } } } -} - -/// Takes a function with `5` arguments (an arity of `5`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e) -> f` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> f`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry5(fun: fn(a, b, c, d, e) -> value) { - fn(a) { fn(b) { fn(c) { fn(d) { fn(e) { fun(a, b, c, d, e) } } } } } -} - -/// Takes a function with `6` arguments (an arity of `6`), and returns the -/// curried equivalent. -/// -/// `fn(a, b, c, d, e, f) -> g` becomes -/// `fn(a) -> fn(b) -> fn(c) -> fn(d) -> fn(e) -> fn(f) -> g`. -/// -/// See [`curry2`](#curry2) for a detailed explanation. -/// -pub fn curry6(fun: fn(a, b, c, d, e, f) -> value) { - fn(a) { - fn(b) { fn(c) { fn(d) { fn(e) { fn(f) { fun(a, b, c, d, e, f) } } } } } - } -} - -/// Takes a function that takes two arguments and returns a new function that -/// takes the same two arguments, but in reverse order. -/// -pub fn flip(fun: fn(a, b) -> c) -> fn(b, a) -> c { - fn(b, a) { fun(a, b) } -} - -/// Takes a single argument and always returns its input value. -/// -pub fn identity(x: a) -> a { - x -} - -/// Takes a single argument and returns a new function that -/// ignores its argument and always returns the input value. -/// -pub fn constant(value: a) -> fn(b) -> a { - fn(_) { value } -} - -/// Takes an argument and a single function, -/// calls that function with that argument -/// and returns that argument instead of the function return value. -/// Useful for running synchronous side effects in a pipeline. -/// -pub fn tap(arg: a, effect: fn(a) -> b) -> a { - effect(arg) - arg -} - -/// Takes a function with arity one and an argument, -/// calls that function with the argument and returns the function return value. -/// -/// Useful for concisely calling functions returned as a part of a pipeline. -/// -/// ## Example -/// -/// ```gleam -/// > let doubler = fn() { -/// > fn(x: Int) { x * 2 } -/// > } -/// > -/// > doubler() -/// > |> apply1(2) -/// 4 -/// ``` -/// -pub fn apply1(fun: fn(a) -> value, arg1: a) -> value { - fun(arg1) -} - -/// Takes a function with arity two and two arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply2(fun: fn(a, b) -> value, arg1: a, arg2: b) -> value { - fun(arg1, arg2) -} - -/// Takes a function with arity three and three arguments, -/// calls that function with the arguments -/// and returns the function return value. -/// -/// See [`apply1`](#apply1) for more details. -/// -pub fn apply3(fun: fn(a, b, c) -> value, arg1: a, arg2: b, arg3: c) -> value { - fun(arg1, arg2, arg3) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam deleted file mode 100644 index d93c16a..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/int.gleam +++ /dev/null @@ -1,874 +0,0 @@ -//// Functions for working with integers. -//// -//// ## Division by zero -//// -//// In Erlang division by zero results in a crash, however Gleam does not have -//// partial functions and operators in core so instead division by zero returns -//// zero, a behaviour taken from Pony, Coq, and Lean. -//// -//// This may seem unexpected at first, but it is no less mathematically valid -//// than crashing or returning a special value. Division by zero is undefined -//// in mathematics. - -import gleam/float -import gleam/order.{type Order} - -/// Returns the absolute value of the input. -/// -/// ## Examples -/// -/// ```gleam -/// > absolute_value(-12) -/// 12 -/// ``` -/// -/// ```gleam -/// > absolute_value(10) -/// 10 -/// ``` -/// -pub fn absolute_value(x: Int) -> Int { - case x >= 0 { - True -> x - False -> x * -1 - } -} - -/// Returns the results of the base being raised to the power of the -/// exponent, as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > power(2, -1.0) -/// Ok(0.5) -/// ``` -/// -/// ```gleam -/// > power(2, 2.0) -/// Ok(4.0) -/// ``` -/// -/// ```gleam -/// > power(8, 1.5) -/// Ok(22.627416997969522) -/// ``` -/// -/// ```gleam -/// > 4 |> power(of: 2.0) -/// Ok(16.0) -/// ``` -/// -/// ```gleam -/// > power(-1, 0.5) -/// Error(Nil) -/// ``` -/// -pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) { - base - |> to_float() - |> float.power(exponent) -} - -/// Returns the square root of the input as a `Float`. -/// -/// ## Examples -/// -/// ```gleam -/// > square_root(4) -/// Ok(2.0) -/// ``` -/// -/// ```gleam -/// > square_root(-16) -/// Error(Nil) -/// ``` -/// -pub fn square_root(x: Int) -> Result(Float, Nil) { - x - |> to_float() - |> float.square_root() -} - -/// Parses a given string as an int if possible. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("2") -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > parse("ABC") -/// Error(Nil) -/// ``` -/// -pub fn parse(string: String) -> Result(Int, Nil) { - do_parse(string) -} - -@external(erlang, "gleam_stdlib", "parse_int") -@external(javascript, "../gleam_stdlib.mjs", "parse_int") -fn do_parse(a: String) -> Result(Int, Nil) - -/// Parses a given string as an int in a given base if possible. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > base_parse("10", 2) -/// Ok(2) -/// -/// > base_parse("30", 16) -/// Ok(48) -/// -/// > base_parse("1C", 36) -/// Ok(48) -/// -/// > base_parse("48", 1) -/// Error(Nil) -/// -/// > base_parse("48", 37) -/// Error(Nil) -/// ``` -/// -pub fn base_parse(string: String, base: Int) -> Result(Int, Nil) { - case base >= 2 && base <= 36 { - True -> do_base_parse(string, base) - False -> Error(Nil) - } -} - -@external(erlang, "gleam_stdlib", "int_from_base_string") -@external(javascript, "../gleam_stdlib.mjs", "int_from_base_string") -fn do_base_parse(a: String, b: Int) -> Result(Int, Nil) - -/// Prints a given int to a string. -/// -/// ## Examples -/// -/// ```gleam -/// > to_string(2) -/// "2" -/// ``` -/// -pub fn to_string(x: Int) { - do_to_string(x) -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "to_string") -fn do_to_string(a: Int) -> String - -/// Error value when trying to operate with a base out of the allowed range. -/// -pub type InvalidBase { - InvalidBase -} - -/// Prints a given int to a string using the base number provided. -/// Supports only bases 2 to 36, for values outside of which this function returns an `Error(InvalidBase)`. -/// For common bases (2, 8, 16, 36), use the `to_baseN` functions. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base_string(2, 2) -/// Ok("10") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 16) -/// Ok("30") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 36) -/// Ok("1C") -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > to_base_string(48, 37) -/// Error(InvalidBase) -/// ``` -/// -pub fn to_base_string(x: Int, base: Int) -> Result(String, InvalidBase) { - case base >= 2 && base <= 36 { - True -> Ok(do_to_base_string(x, base)) - False -> Error(InvalidBase) - } -} - -@external(erlang, "erlang", "integer_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "int_to_base_string") -fn do_to_base_string(a: Int, b: Int) -> String - -/// Prints a given int to a string using base-2. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base2(2) -/// "10" -/// ``` -/// -pub fn to_base2(x: Int) -> String { - do_to_base_string(x, 2) -} - -/// Prints a given int to a string using base-8. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base8(15) -/// "17" -/// ``` -/// -pub fn to_base8(x: Int) -> String { - do_to_base_string(x, 8) -} - -/// Prints a given int to a string using base-16. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base16(48) -/// "30" -/// ``` -/// -pub fn to_base16(x: Int) -> String { - do_to_base_string(x, 16) -} - -/// Prints a given int to a string using base-36. -/// -/// ## Examples -/// -/// ```gleam -/// > to_base36(48) -/// "1C" -/// ``` -/// -pub fn to_base36(x: Int) -> String { - do_to_base_string(x, 36) -} - -/// Takes an int and returns its value as a float. -/// -/// ## Examples -/// -/// ```gleam -/// > to_float(5) -/// 5.0 -/// ``` -/// -/// ```gleam -/// > to_float(0) -/// 0.0 -/// ``` -/// -/// ```gleam -/// > to_float(-3) -/// -3.0 -/// ``` -/// -pub fn to_float(x: Int) -> Float { - do_to_float(x) -} - -@external(erlang, "erlang", "float") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_float(a: Int) -> Float - -/// Restricts an int between a lower and upper bound. -/// -/// ## Examples -/// -/// ```gleam -/// > clamp(40, min: 50, max: 60) -/// 50 -/// ``` -/// -pub fn clamp(x: Int, min min_bound: Int, max max_bound: Int) -> Int { - x - |> min(max_bound) - |> max(min_bound) -} - -/// Compares two ints, returning an order. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(2, 3) -/// Lt -/// ``` -/// -/// ```gleam -/// > compare(4, 3) -/// Gt -/// ``` -/// -/// ```gleam -/// > compare(3, 3) -/// Eq -/// ``` -/// -pub fn compare(a: Int, with b: Int) -> Order { - case a == b { - True -> order.Eq - False -> - case a < b { - True -> order.Lt - False -> order.Gt - } - } -} - -/// Compares two ints, returning the smaller of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > min(2, 3) -/// 2 -/// ``` -/// -pub fn min(a: Int, b: Int) -> Int { - case a < b { - True -> a - False -> b - } -} - -/// Compares two ints, returning the larger of the two. -/// -/// ## Examples -/// -/// ```gleam -/// > max(2, 3) -/// 3 -/// ``` -/// -pub fn max(a: Int, b: Int) -> Int { - case a > b { - True -> a - False -> b - } -} - -/// Returns whether the value provided is even. -/// -/// ## Examples -/// -/// ```gleam -/// > is_even(2) -/// True -/// ``` -/// -/// ```gleam -/// > is_even(3) -/// False -/// ``` -/// -pub fn is_even(x: Int) -> Bool { - x % 2 == 0 -} - -/// Returns whether the value provided is odd. -/// -/// ## Examples -/// -/// ```gleam -/// > is_odd(3) -/// True -/// ``` -/// -/// ```gleam -/// > is_odd(2) -/// False -/// ``` -/// -pub fn is_odd(x: Int) -> Bool { - x % 2 != 0 -} - -/// Returns the negative of the value provided. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(1) -/// -1 -/// ``` -/// -pub fn negate(x: Int) -> Int { - -1 * x -} - -/// Sums a list of ints. -/// -/// ## Example -/// -/// ```gleam -/// > sum([1, 2, 3]) -/// 6 -/// ``` -/// -pub fn sum(numbers: List(Int)) -> Int { - numbers - |> do_sum(0) -} - -fn do_sum(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_sum(rest, x + initial) - } -} - -/// Multiplies a list of ints and returns the product. -/// -/// ## Example -/// -/// ```gleam -/// > product([2, 3, 4]) -/// 24 -/// ``` -/// -pub fn product(numbers: List(Int)) -> Int { - case numbers { - [] -> 1 - _ -> do_product(numbers, 1) - } -} - -fn do_product(numbers: List(Int), initial: Int) -> Int { - case numbers { - [] -> initial - [x, ..rest] -> do_product(rest, x * initial) - } -} - -/// Splits an integer into its digit representation in the specified base -/// -/// ## Examples -/// -/// ```gleam -/// > digits(234, 10) -/// Ok([2,3,4]) -/// ``` -/// -/// ```gleam -/// > digits(234, 1) -/// Error(InvalidBase) -/// ``` -/// -pub fn digits(x: Int, base: Int) -> Result(List(Int), InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> Ok(do_digits(x, base, [])) - } -} - -fn do_digits(x: Int, base: Int, acc: List(Int)) -> List(Int) { - case absolute_value(x) < base { - True -> [x, ..acc] - False -> do_digits(x / base, base, [x % base, ..acc]) - } -} - -/// Joins a list of digits into a single value. -/// Returns an error if the base is less than 2 or if the list contains a digit greater than or equal to the specified base. -/// -/// ## Examples -/// -/// ```gleam -/// > undigits([2,3,4], 10) -/// Ok(234) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 1) -/// Error(InvalidBase) -/// ``` -/// -/// ```gleam -/// > undigits([2,3,4], 2) -/// Error(InvalidBase) -/// ``` -/// -pub fn undigits(numbers: List(Int), base: Int) -> Result(Int, InvalidBase) { - case base < 2 { - True -> Error(InvalidBase) - False -> do_undigits(numbers, base, 0) - } -} - -fn do_undigits( - numbers: List(Int), - base: Int, - acc: Int, -) -> Result(Int, InvalidBase) { - case numbers { - [] -> Ok(acc) - [digit, ..] if digit >= base -> Error(InvalidBase) - [digit, ..rest] -> do_undigits(rest, base, acc * base + digit) - } -} - -/// Generates a random int between the given minimum and maximum values. -/// -/// ## Examples -/// -/// ```gleam -/// > random(1, 5) -/// 2 -/// ``` -/// -pub fn random(min: Int, max: Int) -> Int { - float.random(to_float(min), to_float(max)) - |> float.floor() - |> float.round() -} - -/// Performs a truncated integer division. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > divide(0, 1) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > divide(-99, 2) -/// Ok(-49) -/// ``` -/// -pub fn divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend / divisor) - } -} - -/// Computes the remainder of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > remainder(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > remainder(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: 3) -/// Ok(-1) -/// ``` -/// -/// ```gleam -/// > remainder(13, by: -3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > remainder(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn remainder(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> Ok(dividend % divisor) - } -} - -/// Computes the modulo of an integer division of inputs as a `Result`. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// Most the time you will want to use the `%` operator instead of this -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > modulo(3, 2) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > modulo(10, -1) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: 3) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: 3) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > modulo(13, by: -3) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > modulo(-13, by: -3) -/// Ok(-1) -/// ``` -/// -pub fn modulo(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - _ -> { - let remainder = dividend % divisor - case remainder * divisor < 0 { - True -> Ok(remainder + divisor) - False -> Ok(remainder) - } - } - } -} - -/// Performs a *floored* integer division, which means that the result will -/// always be rounded towards negative infinity. -/// -/// If you want to perform truncated integer division (rounding towards zero), -/// use `int.divide()` or the `/` operator instead. -/// -/// Returns division of the inputs as a `Result`: If the given divisor equals -/// `0`, this function returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > floor_divide(1, 0) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > floor_divide(5, 2) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > floor_divide(6, -4) -/// Ok(-2) -/// ``` -/// -/// ```gleam -/// > floor_divide(-99, 2) -/// Ok(-50) -/// ``` -/// -pub fn floor_divide(dividend: Int, by divisor: Int) -> Result(Int, Nil) { - case divisor { - 0 -> Error(Nil) - divisor -> - case dividend * divisor < 0 && dividend % divisor != 0 { - True -> Ok(dividend / divisor - 1) - False -> Ok(dividend / divisor) - } - } -} - -/// Adds two integers together. -/// -/// It's the function equivalent of the `+` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > add(1, 2) -/// 3 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 0, add) -/// 6 -/// ``` -/// -/// ```gleam -/// > 3 |> add(2) -/// 5 -/// ``` -/// -pub fn add(a: Int, b: Int) -> Int { - a + b -} - -/// Multiplies two integers together. -/// -/// It's the function equivalent of the `*` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > multiply(2, 4) -/// 8 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([2, 3, 4], 1, multiply) -/// 24 -/// ``` -/// -/// ```gleam -/// > 3 |> multiply(2) -/// 6 -/// ``` -/// -pub fn multiply(a: Int, b: Int) -> Int { - a * b -} - -/// Subtracts one int from another. -/// -/// It's the function equivalent of the `-` operator. -/// This function is useful in higher order functions or pipes. -/// -/// ## Examples -/// -/// ```gleam -/// > subtract(3, 1) -/// 2.0 -/// ``` -/// -/// ```gleam -/// import gleam/list -/// > list.fold([1, 2, 3], 10, subtract) -/// 4 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2) -/// 1 -/// ``` -/// -/// ```gleam -/// > 3 |> subtract(2, _) -/// -1 -/// ``` -/// -pub fn subtract(a: Int, b: Int) -> Int { - a - b -} - -/// Calculates the bitwise AND of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "band") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_and") -pub fn bitwise_and(x: Int, y: Int) -> Int - -/// Calculates the bitwise NOT of its argument. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bnot") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_not") -pub fn bitwise_not(x: Int) -> Int - -/// Calculates the bitwise OR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_or") -pub fn bitwise_or(x: Int, y: Int) -> Int - -/// Calculates the bitwise XOR of its arguments. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bxor") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_exclusive_or") -pub fn bitwise_exclusive_or(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic left bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsl") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_left") -pub fn bitwise_shift_left(x: Int, y: Int) -> Int - -/// Calculates the result of an arithmetic right bitshift. -/// -/// The exact behaviour of this function depends on the target platform. -/// On Erlang it is equivalent to bitwise operations on ints, on JavaScript it -/// is equivalent to bitwise operations on big-ints. -/// -@external(erlang, "erlang", "bsr") -@external(javascript, "../gleam_stdlib.mjs", "bitwise_shift_right") -pub fn bitwise_shift_right(x: Int, y: Int) -> Int diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam deleted file mode 100644 index 0c0a3ee..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/io.gleam +++ /dev/null @@ -1,117 +0,0 @@ -import gleam/string - -/// Writes a string to standard output. -/// -/// If you want your output to be printed on its own line see `println`. -/// -/// ## Example -/// -/// ```gleam -/// > io.print("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn print(string: String) -> Nil { - do_print(string) -} - -@external(erlang, "gleam_stdlib", "print") -@external(javascript, "../gleam_stdlib.mjs", "print") -fn do_print(string string: String) -> Nil - -/// Writes a string to standard error. -/// -/// If you want your output to be printed on its own line see `println_error`. -/// -/// ## Example -/// -/// ``` -/// > io.print_error("Hi pop") -/// // -> Hi pop -/// Nil -/// ``` -/// -pub fn print_error(string: String) -> Nil { - do_print_error(string) -} - -@external(erlang, "gleam_stdlib", "print_error") -@external(javascript, "../gleam_stdlib.mjs", "print_error") -fn do_print_error(string string: String) -> Nil - -/// Writes a string to standard output, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println("Hi mum") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println(string: String) -> Nil { - do_println(string) -} - -@external(erlang, "gleam_stdlib", "println") -@external(javascript, "../gleam_stdlib.mjs", "console_log") -fn do_println(string string: String) -> Nil - -/// Writes a string to standard error, appending a newline to the end. -/// -/// ## Example -/// -/// ```gleam -/// > io.println_error("Hi pop") -/// // -> Hi mum -/// Nil -/// ``` -/// -pub fn println_error(string: String) -> Nil { - do_println_error(string) -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "console_error") -fn do_println_error(string string: String) -> Nil - -/// Prints a value to standard error (stderr) yielding Gleam syntax. -/// -/// The value is returned after being printed so it can be used in pipelines. -/// -/// ## Example -/// -/// ```gleam -/// > debug("Hi mum") -/// // -> <<"Hi mum">> -/// "Hi mum" -/// ``` -/// -/// ```gleam -/// > debug(Ok(1)) -/// // -> {ok, 1} -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > import list -/// > [1, 2] -/// > |> list.map(fn(x) { x + 1 }) -/// > |> debug -/// > |> list.map(fn(x) { x * 2 }) -/// // -> [2, 3] -/// [4, 6] -/// ``` -/// -pub fn debug(term: anything) -> anything { - term - |> string.inspect - |> do_debug_println - - term -} - -@external(erlang, "gleam_stdlib", "println_error") -@external(javascript, "../gleam_stdlib.mjs", "print_debug") -fn do_debug_println(string string: String) -> Nil diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam deleted file mode 100644 index c57e7fd..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/iterator.gleam +++ /dev/null @@ -1,1530 +0,0 @@ -import gleam/result -import gleam/int -import gleam/list -import gleam/dict.{type Dict} -import gleam/option.{type Option, None, Some} -import gleam/order - -// Internal private representation of an Iterator -type Action(element) { - // Dedicated to Electric Six - // https://youtu.be/_30t2dzEgiw?t=162 - Stop - Continue(element, fn() -> Action(element)) -} - -/// An iterator is a lazily evaluated sequence of element. -/// -/// Iterators are useful when working with collections that are too large to -/// fit in memory (or those that are infinite in size) as they only require the -/// elements currently being processed to be in memory. -/// -/// As a lazy data structure no work is done when an iterator is filters, -/// mapped, etc, instead a new iterator is returned with these transformations -/// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `to_list`. -/// -pub opaque type Iterator(element) { - Iterator(continuation: fn() -> Action(element)) -} - -// Public API for iteration -pub type Step(element, accumulator) { - Next(element: element, accumulator: accumulator) - Done -} - -// Shortcut for an empty iterator. -fn stop() -> Action(element) { - Stop -} - -// Creating Iterators -fn do_unfold( - initial: acc, - f: fn(acc) -> Step(element, acc), -) -> fn() -> Action(element) { - fn() { - case f(initial) { - Next(x, acc) -> Continue(x, do_unfold(acc, f)) - Done -> Stop - } - } -} - -/// Creates an iterator from a given function and accumulator. -/// -/// The function is called on the accumulator and returns either `Done`, -/// indicating the iterator has no more elements, or `Next` which contains a -/// new element and accumulator. The element is yielded by the iterator and the -/// new accumulator is used with the function to compute the next element in -/// the sequence. -/// -/// ## Examples -/// -/// ```gleam -/// > unfold(from: 5, with: fn(n) { -/// > case n { -/// > 0 -> Done -/// > n -> Next(element: n, accumulator: n - 1) -/// > } -/// > }) -/// > |> to_list -/// [5, 4, 3, 2, 1] -/// ``` -/// -pub fn unfold( - from initial: acc, - with f: fn(acc) -> Step(element, acc), -) -> Iterator(element) { - initial - |> do_unfold(f) - |> Iterator -} - -// TODO: test -/// Creates an iterator that yields values created by calling a given function -/// repeatedly. -/// -pub fn repeatedly(f: fn() -> element) -> Iterator(element) { - unfold(Nil, fn(_) { Next(f(), Nil) }) -} - -/// Creates an iterator that returns the same value infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat(10) -/// > |> take(4) -/// > |> to_list -/// [10, 10, 10, 10] -/// ``` -/// -pub fn repeat(x: element) -> Iterator(element) { - repeatedly(fn() { x }) -} - -/// Creates an iterator that yields each element from the given list. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn from_list(list: List(element)) -> Iterator(element) { - let yield = fn(acc) { - case acc { - [] -> Done - [head, ..tail] -> Next(head, tail) - } - } - unfold(list, yield) -} - -// Consuming Iterators -fn do_transform( - continuation: fn() -> Action(a), - state: acc, - f: fn(acc, a) -> Step(b, acc), -) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> - case f(state, el) { - Done -> Stop - Next(yield, next_state) -> - Continue(yield, do_transform(next, next_state, f)) - } - } - } -} - -/// Creates an iterator from an existing iterator -/// and a stateful function that may short-circuit. -/// -/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, -/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. -/// -/// ## Examples -/// -/// Approximate implementation of `index` in terms of `transform`: -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) -/// > |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -pub fn transform( - over iterator: Iterator(a), - from initial: acc, - with f: fn(acc, a) -> Step(b, acc), -) -> Iterator(b) { - do_transform(iterator.continuation, initial, f) - |> Iterator -} - -fn do_fold( - continuation: fn() -> Action(e), - f: fn(acc, e) -> acc, - accumulator: acc, -) -> acc { - case continuation() { - Continue(elem, next) -> do_fold(next, f, f(accumulator, elem)) - Stop -> accumulator - } -} - -/// Reduces an iterator of elements into a single value by calling a given -/// function on each element in turn. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// If you do not care about the end value and only wish to evaluate the -/// iterator for side effects consider using the `run` function instead. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold(from: 0, with: fn(acc, element) { element + acc }) -/// 10 -/// ``` -/// -pub fn fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> acc, -) -> acc { - iterator.continuation - |> do_fold(f, initial) -} - -// TODO: test -/// Evaluates all elements emitted by the given iterator. This function is useful for when -/// you wish to trigger any side effects that would occur when evaluating -/// the iterator. -/// -pub fn run(iterator: Iterator(e)) -> Nil { - fold(iterator, Nil, fn(_, _) { Nil }) -} - -/// Evaluates an iterator and returns all the elements as a list. -/// -/// If called on an iterator of infinite length then this function will never -/// return. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn to_list(iterator: Iterator(element)) -> List(element) { - iterator - |> fold([], fn(acc, e) { [e, ..acc] }) - |> list.reverse -} - -/// Eagerly accesses the first value of an iterator, returning a `Next` -/// that contains the first value and the rest of the iterator. -/// -/// If called on an empty iterator, `Done` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Next(first, rest) = [1, 2, 3, 4] -/// > |> from_list -/// > |> step -/// > first -/// 1 -/// ``` -/// -/// ```gleam -/// > rest |> to_list -/// [2, 3, 4] -/// ``` -/// -/// ```gleam -/// > empty() |> step -/// Done -/// ``` -/// -pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { - case iterator.continuation() { - Stop -> Done - Continue(e, a) -> Next(e, Iterator(a)) - } -} - -fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { - fn() { - case desired > 0 { - False -> Stop - True -> - case continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, do_take(next, desired - 1)) - } - } - } -} - -/// Creates an iterator that only yields the first `desired` elements. -/// -/// If the iterator does not have enough elements all of them are yielded. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2, 3] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> take(up_to: 3) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - iterator.continuation - |> do_take(desired) - |> Iterator -} - -fn do_drop(continuation: fn() -> Action(e), desired: Int) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case desired > 0 { - True -> do_drop(next, desired - 1) - False -> Continue(e, next) - } - } -} - -/// Evaluates and discards the first N elements in an iterator, returning a new -/// iterator. -/// -/// If the iterator does not have enough elements an empty iterator is -/// returned. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [4, 5] -/// ``` -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> drop(up_to: 3) -/// > |> to_list -/// [] -/// ``` -/// -pub fn drop(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { - fn() { do_drop(iterator.continuation, desired) } - |> Iterator -} - -fn do_map(continuation: fn() -> Action(a), f: fn(a) -> b) -> fn() -> Action(b) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> Continue(f(e), do_map(continuation, f)) - } - } -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3] -/// > |> from_list -/// > |> map(fn(x) { x * 2 }) -/// > |> to_list -/// [2, 4, 6] -/// ``` -/// -pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { - iterator.continuation - |> do_map(f) - |> Iterator -} - -fn do_map2( - continuation1: fn() -> Action(a), - continuation2: fn() -> Action(b), - with fun: fn(a, b) -> c, -) -> fn() -> Action(c) { - fn() { - case continuation1() { - Stop -> Stop - Continue(a, next_a) -> - case continuation2() { - Stop -> Stop - Continue(b, next_b) -> - Continue(fun(a, b), do_map2(next_a, next_b, fun)) - } - } - } -} - -/// Combines two interators into a single one using the given function. -/// -/// If an iterator is longer than the other the extra elements are dropped. -/// -/// This function does not evaluate the elements of the two iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// let first = from_list([1, 2, 3]) -/// let second = from_list([4, 5, 6]) -/// map2(first, second, fn(x, y) { x + y }) |> to_list -/// // -> [5, 7, 9] -/// ``` -/// -/// ```gleam -/// let first = from_list([1, 2]) -/// let second = from_list(["a", "b", "c"]) -/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list -/// // -> [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2( - iterator1: Iterator(a), - iterator2: Iterator(b), - with fun: fn(a, b) -> c, -) -> Iterator(c) { - do_map2(iterator1.continuation, iterator2.continuation, fun) - |> Iterator -} - -fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { - case first() { - Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) - Stop -> second() - } -} - -/// Appends two iterators, producing a new iterator. -/// -/// This function does not evaluate the elements of the iterators, the -/// computation is performed when the resulting iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> append([3, 4] |> from_list) -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn append(to first: Iterator(a), suffix second: Iterator(a)) -> Iterator(a) { - fn() { do_append(first.continuation, second.continuation) } - |> Iterator -} - -fn do_flatten(flattened: fn() -> Action(Iterator(a))) -> Action(a) { - case flattened() { - Stop -> Stop - Continue(it, next_iterator) -> - do_append(it.continuation, fn() { do_flatten(next_iterator) }) - } -} - -/// Flattens an iterator of iterators, creating a new iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([[1, 2], [3, 4]]) -/// > |> map(from_list) -/// > |> flatten -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn flatten(iterator: Iterator(Iterator(a))) -> Iterator(a) { - fn() { do_flatten(iterator.continuation) } - |> Iterator -} - -/// Joins a list of iterators into a single iterator. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [[1, 2], [3, 4]] -/// > |> map(from_list) -/// > |> concat -/// > |> to_list -/// [1, 2, 3, 4] -/// ``` -/// -pub fn concat(iterators: List(Iterator(a))) -> Iterator(a) { - flatten(from_list(iterators)) -} - -/// Creates an iterator from an existing iterator and a transformation function. -/// -/// Each element in the new iterator will be the result of calling the given -/// function on the elements in the given iterator and then flattening the -/// results. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> flat_map(fn(x) { from_list([x, x + 1]) }) -/// > |> to_list -/// [1, 2, 2, 3] -/// ``` -/// -pub fn flat_map( - over iterator: Iterator(a), - with f: fn(a) -> Iterator(b), -) -> Iterator(b) { - iterator - |> map(f) - |> flatten -} - -fn do_filter( - continuation: fn() -> Action(e), - predicate: fn(e) -> Bool, -) -> Action(e) { - case continuation() { - Stop -> Stop - Continue(e, iterator) -> - case predicate(e) { - True -> Continue(e, fn() { do_filter(iterator, predicate) }) - False -> do_filter(iterator, predicate) - } - } -} - -/// Creates an iterator from an existing iterator and a predicate function. -/// -/// The new iterator will contain elements from the first iterator for which -/// the given function returns `True`. -/// -/// This function does not evaluate the elements of the iterator, the -/// computation is performed when the iterator is later run. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> filter(int.is_even) -/// > |> to_list -/// [2, 4] -/// ``` -/// -pub fn filter( - iterator: Iterator(a), - keeping predicate: fn(a) -> Bool, -) -> Iterator(a) { - fn() { do_filter(iterator.continuation, predicate) } - |> Iterator -} - -/// Creates an iterator that repeats a given iterator infinitely. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2] -/// > |> from_list -/// > |> cycle -/// > |> take(6) -/// > |> to_list -/// [1, 2, 1, 2, 1, 2] -/// ``` -/// -pub fn cycle(iterator: Iterator(a)) -> Iterator(a) { - repeat(iterator) - |> flatten -} - -/// Creates an iterator of ints, starting at a given start int and stepping by -/// one to a given end int. -/// -/// ## Examples -/// -/// ```gleam -/// > range(from: 1, to: 5) |> to_list -/// [1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(from: 1, to: -2) |> to_list -/// [1, 0, -1, -2] -/// ``` -/// -/// ```gleam -/// > range(from: 0, to: 0) |> to_list -/// [0] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> Iterator(Int) { - case int.compare(start, stop) { - order.Eq -> once(fn() { start }) - order.Gt -> - unfold( - from: start, - with: fn(current) { - case current < stop { - False -> Next(current, current - 1) - True -> Done - } - }, - ) - - order.Lt -> - unfold( - from: start, - with: fn(current) { - case current > stop { - False -> Next(current, current + 1) - True -> Done - } - }, - ) - } -} - -fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) { - case continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - case f(e) { - True -> Ok(e) - False -> do_find(next, f) - } - } -} - -/// Finds the first element in a given iterator for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if the function does not return `True` for any of the -/// elements. -/// -/// ## Examples -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find(from_list([1, 2, 3]), fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find(empty(), fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: Iterator(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - haystack.continuation - |> do_find(is_desired) -} - -fn do_index( - continuation: fn() -> Action(element), - next: Int, -) -> fn() -> Action(#(Int, element)) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, continuation) -> - Continue(#(next, e), do_index(continuation, next + 1)) - } - } -} - -/// Wraps values yielded from an iterator with indices, starting from 0. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) |> index |> to_list -/// [#(0, "a"), #(1, "b"), #(2, "c")] -/// ``` -/// -pub fn index(over iterator: Iterator(element)) -> Iterator(#(Int, element)) { - iterator.continuation - |> do_index(0) - |> Iterator -} - -/// Creates an iterator that inifinitely applies a function to a value. -/// -/// ## Examples -/// -/// ```gleam -/// > iterate(1, fn(n) { n * 3 }) |> take(5) |> to_list -/// [1, 3, 9, 27, 81] -/// ``` -/// -pub fn iterate( - from initial: element, - with f: fn(element) -> element, -) -> Iterator(element) { - unfold(initial, fn(element) { Next(element, f(element)) }) -} - -fn do_take_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> fn() -> Action(element) { - fn() { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Stop - True -> Continue(e, do_take_while(next, predicate)) - } - } - } -} - -/// Creates an iterator that yields elements while the predicate returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 2, 4]) -/// > |> take_while(satisfying: fn(x) { x < 3 }) -/// > |> to_list -/// [1, 2] -/// ``` -/// -pub fn take_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - iterator.continuation - |> do_take_while(predicate) - |> Iterator -} - -fn do_drop_while( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> - case predicate(e) { - False -> Continue(e, next) - True -> do_drop_while(next, predicate) - } - } -} - -/// Creates an iterator that drops elements while the predicate returns `True`, -/// and then yields the remaining elements. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 2, 5]) -/// > |> drop_while(satisfying: fn(x) { x < 4 }) -/// > |> to_list -/// [4, 2, 5] -/// ``` -/// -pub fn drop_while( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Iterator(element) { - fn() { do_drop_while(iterator.continuation, predicate) } - |> Iterator -} - -fn do_scan( - continuation: fn() -> Action(element), - f: fn(acc, element) -> acc, - accumulator: acc, -) -> fn() -> Action(acc) { - fn() { - case continuation() { - Stop -> Stop - Continue(el, next) -> { - let accumulated = f(accumulator, el) - Continue(accumulated, do_scan(next, f, accumulated)) - } - } - } -} - -/// Creates an iterator from an existing iterator and a stateful function. -/// -/// Specifically, this behaves like `fold`, but yields intermediate results. -/// -/// ## Examples -/// -/// ```gleam -/// // Generate a sequence of partial sums -/// > from_list([1, 2, 3, 4, 5]) -/// > |> scan(from: 0, with: fn(acc, el) { acc + el }) -/// > |> to_list -/// [1, 3, 6, 10, 15] -/// ``` -/// -pub fn scan( - over iterator: Iterator(element), - from initial: acc, - with f: fn(acc, element) -> acc, -) -> Iterator(acc) { - iterator.continuation - |> do_scan(f, initial) - |> Iterator -} - -fn do_zip( - left: fn() -> Action(a), - right: fn() -> Action(b), -) -> fn() -> Action(#(a, b)) { - fn() { - case left() { - Stop -> Stop - Continue(el_left, next_left) -> - case right() { - Stop -> Stop - Continue(el_right, next_right) -> - Continue(#(el_left, el_right), do_zip(next_left, next_right)) - } - } - } -} - -/// Zips two iterators together, emitting values from both -/// until the shorter one runs out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list(["a", "b", "c"]) -/// > |> zip(range(20, 30)) -/// > |> to_list -/// [#("a", 20), #("b", 21), #("c", 22)] -/// ``` -/// -pub fn zip(left: Iterator(a), right: Iterator(b)) -> Iterator(#(a, b)) { - do_zip(left.continuation, right.continuation) - |> Iterator -} - -// Result of collecting a single chunk by key -type Chunk(element, key) { - AnotherBy(List(element), key, element, fn() -> Action(element)) - LastBy(List(element)) -} - -fn next_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - current_chunk: List(element), -) -> Chunk(element, key) { - case continuation() { - Stop -> LastBy(list.reverse(current_chunk)) - Continue(e, next) -> { - let key = f(e) - case key == previous_key { - True -> next_chunk(next, f, key, [e, ..current_chunk]) - False -> AnotherBy(list.reverse(current_chunk), key, e, next) - } - } - } -} - -fn do_chunk( - continuation: fn() -> Action(element), - f: fn(element) -> key, - previous_key: key, - previous_element: element, -) -> Action(List(element)) { - case next_chunk(continuation, f, previous_key, [previous_element]) { - LastBy(chunk) -> Continue(chunk, stop) - AnotherBy(chunk, key, el, next) -> - Continue(chunk, fn() { do_chunk(next, f, key, el) }) - } -} - -/// Creates an iterator that emits chunks of elements -/// for which `f` returns the same value. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 2, 3, 4, 4, 6, 7, 7]) -/// > |> chunk(by: fn(n) { n % 2 }) -/// > |> to_list -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk( - over iterator: Iterator(element), - by f: fn(element) -> key, -) -> Iterator(List(element)) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> do_chunk(next, f, f(e), e) - } - } - |> Iterator -} - -// Result of collecting a single sized chunk -type SizedChunk(element) { - Another(List(element), fn() -> Action(element)) - Last(List(element)) - NoMore -} - -fn next_sized_chunk( - continuation: fn() -> Action(element), - left: Int, - current_chunk: List(element), -) -> SizedChunk(element) { - case continuation() { - Stop -> - case current_chunk { - [] -> NoMore - remaining -> Last(list.reverse(remaining)) - } - Continue(e, next) -> { - let chunk = [e, ..current_chunk] - case left > 1 { - False -> Another(list.reverse(chunk), next) - True -> next_sized_chunk(next, left - 1, chunk) - } - } - } -} - -fn do_sized_chunk( - continuation: fn() -> Action(element), - count: Int, -) -> fn() -> Action(List(element)) { - fn() { - case next_sized_chunk(continuation, count, []) { - NoMore -> Stop - Last(chunk) -> Continue(chunk, stop) - Another(chunk, next_element) -> - Continue(chunk, do_sized_chunk(next_element, count)) - } - } -} - -/// Creates an iterator that emits chunks of given size. -/// -/// If the last chunk does not have `count` elements, it is yielded -/// as a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) -/// > |> sized_chunk(into: 2) -/// > |> to_list -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6, 7, 8]) -/// > |> sized_chunk(into: 3) -/// > |> to_list -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk( - over iterator: Iterator(element), - into count: Int, -) -> Iterator(List(element)) { - iterator.continuation - |> do_sized_chunk(count) - |> Iterator -} - -fn do_intersperse( - continuation: fn() -> Action(element), - separator: element, -) -> Action(element) { - case continuation() { - Stop -> Stop - Continue(e, next) -> { - let next_interspersed = fn() { do_intersperse(next, separator) } - Continue(separator, fn() { Continue(e, next_interspersed) }) - } - } -} - -/// Creates an iterator that yields the given `elem` element -/// between elements emitted by the underlying iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() -/// > |> intersperse(with: 0) -/// > |> to_list -/// [] -/// -/// > from_list([1]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1] -/// -/// > from_list([1, 2, 3, 4, 5]) -/// > |> intersperse(with: 0) -/// > |> to_list -/// [1, 0, 2, 0, 3, 0, 4, 0, 5] -/// ``` -/// -pub fn intersperse( - over iterator: Iterator(element), - with elem: element, -) -> Iterator(element) { - fn() { - case iterator.continuation() { - Stop -> Stop - Continue(e, next) -> Continue(e, fn() { do_intersperse(next, elem) }) - } - } - |> Iterator -} - -fn do_any( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> False - Continue(e, next) -> - case predicate(e) { - True -> True - False -> do_any(next, predicate) - } - } -} - -/// Returns `True` if any element emitted by the iterator satisfies the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a satisfying element. -/// -/// An empty iterator results in `False`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([1, 3, 5, 7, 9]) |> any(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn any( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_any(predicate) -} - -fn do_all( - continuation: fn() -> Action(element), - predicate: fn(element) -> Bool, -) -> Bool { - case continuation() { - Stop -> True - Continue(e, next) -> - case predicate(e) { - True -> do_all(next, predicate) - False -> False - } - } -} - -/// Returns `True` if all elements emitted by the iterator satisfy the given predicate, -/// `False` otherwise. -/// -/// This function short-circuits once it finds a non-satisfying element. -/// -/// An empty iterator results in `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 6, 8]) |> all(fn(n) { n % 2 == 0 }) -/// True -/// ``` -/// -/// ```gleam -/// > from_list([2, 4, 5, 8]) |> all(fn(n) { n % 2 == 0 }) -/// False -/// ``` -/// -pub fn all( - in iterator: Iterator(element), - satisfying predicate: fn(element) -> Bool, -) -> Bool { - iterator.continuation - |> do_all(predicate) -} - -fn update_group_with(el: element) -> fn(Option(List(element))) -> List(element) { - fn(maybe_group) { - case maybe_group { - Some(group) -> [el, ..group] - None -> [el] - } - } -} - -fn group_updater( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - groups - |> dict.update(f(elem), update_group_with(elem)) - } -} - -/// Returns a `Dict(k, List(element))` of elements from the given iterator -/// grouped with the given key function. -/// -/// The order within each group is preserved from the iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5, 6]) |> group(by: fn(n) { n % 3 }) -/// dict.from_list([#(0, [3, 6]), #(1, [1, 4]), #(2, [2, 5])]) -/// ``` -/// -pub fn group( - in iterator: Iterator(element), - by key: fn(element) -> key, -) -> Dict(key, List(element)) { - iterator - |> fold(dict.new(), group_updater(key)) - |> dict.map_values(fn(_, group) { list.reverse(group) }) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first yielded element -/// and combines it with each subsequent element in turn using the given function. -/// The function is called as `f(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an empty iterator. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([]) |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4, 5]) |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce( - over iterator: Iterator(e), - with f: fn(e, e) -> e, -) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, next) -> - do_fold(next, f, e) - |> Ok - } -} - -/// Returns the last element in the given iterator. -/// -/// Returns `Error(Nil)` if the iterator is empty. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> last -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > range(1, 10) |> last -/// Ok(9) -/// ``` -/// -pub fn last(iterator: Iterator(element)) -> Result(element, Nil) { - iterator - |> reduce(fn(_, elem) { elem }) -} - -/// Creates an iterator that yields no elements. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> to_list -/// [] -/// ``` -/// -pub fn empty() -> Iterator(element) { - Iterator(stop) -} - -/// Creates an iterator that yields exactly one element provided by calling the given function. -/// -/// ## Examples -/// -/// ```gleam -/// > once(fn() { 1 }) |> to_list -/// [1] -/// ``` -/// -pub fn once(f: fn() -> element) -> Iterator(element) { - fn() { Continue(f(), stop) } - |> Iterator -} - -/// Creates an iterator that yields the given element exactly once. -/// -/// ## Examples -/// -/// ```gleam -/// > single(1) |> to_list -/// [1] -/// ``` -/// -pub fn single(elem: element) -> Iterator(element) { - once(fn() { elem }) -} - -fn do_interleave( - current: fn() -> Action(element), - next: fn() -> Action(element), -) -> Action(element) { - case current() { - Stop -> next() - Continue(e, next_other) -> - Continue(e, fn() { do_interleave(next, next_other) }) - } -} - -/// Creates an iterator that alternates between the two given iterators -/// until both have run out. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([11, 12, 13, 14])) |> to_list -/// [1, 11, 2, 12, 3, 13, 4, 14] -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> interleave(from_list([100])) |> to_list -/// [1, 100, 2, 3, 4] -/// ``` -/// -pub fn interleave( - left: Iterator(element), - with right: Iterator(element), -) -> Iterator(element) { - fn() { do_interleave(left.continuation, right.continuation) } - |> Iterator -} - -fn do_fold_until( - continuation: fn() -> Action(e), - f: fn(acc, e) -> list.ContinueOrStop(acc), - accumulator: acc, -) -> acc { - case continuation() { - Stop -> accumulator - Continue(elem, next) -> - case f(accumulator, elem) { - list.Continue(accumulator) -> do_fold_until(next, f, accumulator) - list.Stop(accumulator) -> accumulator - } - } -} - -/// Like `fold`, `fold_until` reduces an iterator of elements into a single value by calling a given -/// function on each element in turn, but uses `list.ContinueOrStop` to determine -/// whether or not to keep iterating. -/// -/// If called on an iterator of infinite length then this function will only ever -/// return if the function returns `list.Stop`. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > let f = fn(acc, e) { -/// > case e { -/// > _ if e < 4 -> list.Continue(e + acc) -/// > _ -> list.Stop(acc) -/// > } -/// > } -/// > -/// > [1, 2, 3, 4] -/// > |> from_list -/// > |> fold_until(from: acc, with: f) -/// 6 -/// ``` -/// -pub fn fold_until( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> list.ContinueOrStop(acc), -) -> acc { - iterator.continuation - |> do_fold_until(f, initial) -} - -fn do_try_fold( - over continuation: fn() -> Action(a), - with f: fn(acc, a) -> Result(acc, err), - from accumulator: acc, -) -> Result(acc, err) { - case continuation() { - Stop -> Ok(accumulator) - Continue(elem, next) -> { - use accumulator <- result.try(f(accumulator, elem)) - do_try_fold(next, f, accumulator) - } - } -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the iterator. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4] -/// > |> iterator.from_list() -/// > |> try_fold(0, fn(acc, i) { -/// > case i < 3 { -/// > True -> Ok(acc + i) -/// > False -> Error(Nil) -/// > } -/// > }) -/// Error(Nil) -/// ``` -/// -pub fn try_fold( - over iterator: Iterator(e), - from initial: acc, - with f: fn(acc, e) -> Result(acc, err), -) -> Result(acc, err) { - iterator.continuation - |> do_try_fold(f, initial) -} - -/// Returns the first element yielded by the given iterator, if it exists, -/// or `Error(Nil)` otherwise. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) |> first -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > empty() |> first -/// Error(Nil) -/// ``` -pub fn first(from iterator: Iterator(e)) -> Result(e, Nil) { - case iterator.continuation() { - Stop -> Error(Nil) - Continue(e, _) -> Ok(e) - } -} - -/// Returns nth element yielded by the given iterator, where `0` means the first element. -/// -/// If there are not enough elements in the iterator, `Error(Nil)` is returned. -/// -/// For any `index` less than `0` this function behaves as if it was set to `0`. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(2) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> at(4) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > empty() |> at(0) -/// Error(Nil) -/// ``` -/// -pub fn at(in iterator: Iterator(e), get index: Int) -> Result(e, Nil) { - iterator - |> drop(index) - |> first -} - -fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int { - case continuation() { - Stop -> length - Continue(_, next) -> do_length(next, length + 1) - } -} - -/// Counts the number of elements in the given iterator. -/// -/// This function has to traverse the entire iterator to count its elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> length -/// 0 -/// ``` -/// -/// ```gleam -/// > from_list([1, 2, 3, 4]) |> length -/// 4 -/// ``` -/// -pub fn length(over iterator: Iterator(e)) -> Int { - iterator.continuation - |> do_length(0) -} - -/// Traverse an iterator, calling a function on each element. -/// -/// ## Examples -/// -/// ```gleam -/// > empty() |> each(io.println) -/// Nil -/// ``` -/// -/// ```gleam -/// > from_list(["Tom", "Malory", "Louis"]) |> each(io.println) -/// // -> Tom -/// // -> Malory -/// // -> Louis -/// Nil -/// ``` -/// -pub fn each(over iterator: Iterator(a), with f: fn(a) -> b) -> Nil { - iterator - |> map(f) - |> run -} - -/// Add a new element to the start of an iterator. -/// -/// This function is for use with `use` expressions, to replicate the behaviour -/// of the `yield` keyword found in other languages. -/// -/// ## Examples -/// -/// ```gleam -/// > use <- iterator.yield(1) -/// > use <- iterator.yield(2) -/// > use <- iterator.yield(3) -/// > iterator.empty() -/// iterator.from_list([1, 2, 3]) -/// ``` -/// -pub fn yield(element: a, next: fn() -> Iterator(a)) -> Iterator(a) { - Iterator(fn() { Continue(element, next().continuation) }) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam deleted file mode 100644 index a5cffa9..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/list.gleam +++ /dev/null @@ -1,2154 +0,0 @@ -//// Lists are an ordered sequence of elements and are one of the most common -//// data types in Gleam. -//// -//// New elements can be added and removed from the front of a list in -//// constant time, while adding and removing from the end requires traversing -//// the copying the whole list, so keep this in mind when designing your -//// programs. -//// -//// There is a dedicated syntax for prefixing to a list: -//// -//// ```gleam -//// let new_list = [1, 2, ..existing_list] -//// ``` -//// -//// And a matching syntax for getting the first elements of a list: -//// -//// ```gleam -//// case list { -//// [first_element, ..rest] -> first_element -//// _ -> "this pattern matches when the list is empty" -//// } -//// ``` -//// - -import gleam/int -import gleam/float -import gleam/order.{type Order} -import gleam/pair -import gleam/dict.{type Dict} - -/// An error value returned by the `strict_zip` function. -/// -pub type LengthMismatch { - LengthMismatch -} - -/// Counts the number of elements in a given list. -/// -/// This function has to traverse the list to determine the number of elements, -/// so it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > length([]) -/// 0 -/// ``` -/// -/// ```gleam -/// > length([1]) -/// 1 -/// ``` -/// -/// ```gleam -/// > length([1, 2]) -/// 2 -/// ``` -/// -pub fn length(of list: List(a)) -> Int { - do_length(list) -} - -@target(erlang) -@external(erlang, "erlang", "length") -fn do_length(a: List(a)) -> Int - -@target(javascript) -fn do_length(list: List(a)) -> Int { - do_length_acc(list, 0) -} - -@target(javascript) -fn do_length_acc(list: List(a), count: Int) -> Int { - case list { - [_, ..list] -> do_length_acc(list, count + 1) - _ -> count - } -} - -/// Creates a new list from a given list containing the same elements but in the -/// opposite order. -/// -/// This function has to traverse the list to create the new reversed list, so -/// it runs in linear time. -/// -/// This function is natively implemented by the virtual machine and is highly -/// optimised. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse([]) -/// [] -/// ``` -/// -/// ```gleam -/// > reverse([1]) -/// [1] -/// ``` -/// -/// ```gleam -/// > reverse([1, 2]) -/// [2, 1] -/// ``` -/// -pub fn reverse(xs: List(a)) -> List(a) { - do_reverse(xs) -} - -@target(erlang) -@external(erlang, "lists", "reverse") -fn do_reverse(a: List(a)) -> List(a) - -@target(javascript) -fn do_reverse(list) { - do_reverse_acc(list, []) -} - -@target(javascript) -fn do_reverse_acc(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> do_reverse_acc(rest, [item, ..accumulator]) - } -} - -/// Determines whether or not the list is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty([]) -/// True -/// ``` -/// -/// ```gleam -/// > is_empty([1]) -/// False -/// ``` -/// -/// ```gleam -/// > is_empty([1, 1]) -/// False -/// ``` -/// -pub fn is_empty(list: List(a)) -> Bool { - list == [] -} - -/// Determines whether or not a given element exists within a given list. -/// -/// This function traverses the list to find the element, so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [0] |> contains(any: 0) -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 1] |> contains(any: 0) -/// False -/// ``` -/// -/// ```gleam -/// > [1, 0] |> contains(any: 0) -/// True -/// ``` -/// -pub fn contains(list: List(a), any elem: a) -> Bool { - case list { - [] -> False - [first, ..] if first == elem -> True - [_, ..rest] -> contains(rest, elem) - } -} - -/// Gets the first element from the start of the list, if there is one. -/// -/// ## Examples -/// -/// ```gleam -/// > first([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first([0]) -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > first([1, 2]) -/// Ok(1) -/// ``` -/// -pub fn first(list: List(a)) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [x, ..] -> Ok(x) - } -} - -/// Returns the list minus the first element. If the list is empty, `Error(Nil)` is -/// returned. -/// -/// This function runs in constant time and does not make a copy of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > rest([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > rest([0]) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > rest([1, 2]) -/// Ok([2]) -/// ``` -/// -pub fn rest(list: List(a)) -> Result(List(a), Nil) { - case list { - [] -> Error(Nil) - [_, ..xs] -> Ok(xs) - } -} - -fn update_group( - f: fn(element) -> key, -) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) { - fn(groups, elem) { - case dict.get(groups, f(elem)) { - Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing]) - Error(_) -> dict.insert(groups, f(elem), [elem]) - } - } -} - -/// Takes a list and groups the values by a key -/// which is built from a key function. -/// -/// Does not preserve the initial value order. -/// -/// ## Examples -/// -/// ```gleam -/// > [Ok(3), Error("Wrong"), Ok(200), Ok(73)] -/// |> group(by: fn(i) { -/// case i { -/// Ok(_) -> "Successful" -/// Error(_) -> "Failed" -/// } -/// }) -/// |> dict.to_list -/// -/// [ -/// #("Failed", [Error("Wrong")]), -/// #("Successful", [Ok(73), Ok(200), Ok(3)]) -/// ] -/// -/// > group([1,2,3,4,5], by: fn(i) { i - i / 3 * 3 }) -/// |> dict.to_list -/// [#(0, [3]), #(1, [4, 1]), #(2, [5, 2])] -/// ``` -/// -pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) { - fold(list, dict.new(), update_group(key)) -} - -fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - True -> [x, ..acc] - False -> acc - } - do_filter(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 2 }) -/// [4, 6] -/// ``` -/// -/// ```gleam -/// > filter([2, 4, 6, 1], fn(x) { x > 6 }) -/// [] -/// ``` -/// -pub fn filter(list: List(a), keeping predicate: fn(a) -> Bool) -> List(a) { - do_filter(list, predicate, []) -} - -fn do_filter_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let new_acc = case fun(x) { - Ok(x) -> [x, ..acc] - Error(_) -> acc - } - do_filter_map(xs, fun, new_acc) - } - } -} - -/// Returns a new list containing only the elements from the first list for -/// which the given functions returns `Ok(_)`. -/// -/// ## Examples -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], Error) -/// [] -/// ``` -/// -/// ```gleam -/// > filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) }) -/// [3, 5, 7, 2] -/// ``` -/// -pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) { - do_filter_map(list, fun, []) -} - -fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc]) - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one. -/// -/// ## Examples -/// -/// ```gleam -/// > map([2, 4, 6], fn(x) { x * 2 }) -/// [4, 8, 12] -/// ``` -/// -pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b) { - do_map(list, fun, []) -} - -/// Combines two lists into a single list using the given function. -/// -/// If a list is longer than the other the extra elements are dropped. -/// -/// ## Examples -/// -/// ```gleam -/// > map2([1, 2, 3], [4, 5, 6], fn(x, y) { x + y }) -/// [5, 7, 9] -/// ``` -/// -/// ```gleam -/// > map2([1, 2], ["a", "b", "c"], fn(i, x) { #(i, x) }) -/// [#(1, "a"), #(2, "b")] -/// ``` -/// -pub fn map2(list1: List(a), list2: List(b), with fun: fn(a, b) -> c) -> List(c) { - do_map2(list1, list2, fun, []) -} - -fn do_map2( - list1: List(a), - list2: List(b), - fun: fn(a, b) -> c, - acc: List(c), -) -> List(c) { - case list1, list2 { - [], _ | _, [] -> reverse(acc) - [a, ..as_], [b, ..bs] -> do_map2(as_, bs, fun, [fun(a, b), ..acc]) - } -} - -/// Similar to `map` but also lets you pass around an accumulated value. -/// -/// ## Examples -/// -/// ```gleam -/// > map_fold( -/// over: [1, 2, 3], -/// from: 100, -/// with: fn(memo, i) { #(memo + i, i * 2) } -/// ) -/// #(106, [2, 4, 6]) -/// ``` -/// -pub fn map_fold( - over list: List(a), - from acc: acc, - with fun: fn(acc, a) -> #(acc, b), -) -> #(acc, List(b)) { - fold( - over: list, - from: #(acc, []), - with: fn(acc, item) { - let #(current_acc, items) = acc - let #(next_acc, next_item) = fun(current_acc, item) - #(next_acc, [next_item, ..items]) - }, - ) - |> pair.map_second(reverse) -} - -fn do_index_map( - list: List(a), - fun: fn(Int, a) -> b, - index: Int, - acc: List(b), -) -> List(b) { - case list { - [] -> reverse(acc) - [x, ..xs] -> { - let acc = [fun(index, x), ..acc] - do_index_map(xs, fun, index + 1, acc) - } - } -} - -/// Returns a new list containing only the elements of the first list after the -/// function has been applied to each one and their index. -/// -/// The index starts at 0, so the first element is 0, the second is 1, and so -/// on. -/// -/// ## Examples -/// -/// ```gleam -/// > index_map(["a", "b"], fn(i, x) { #(i, x) }) -/// [#(0, "a"), #(1, "b")] -/// ``` -/// -pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(b) { - do_index_map(list, fun, 0, []) -} - -fn do_try_map( - list: List(a), - fun: fn(a) -> Result(b, e), - acc: List(b), -) -> Result(List(b), e) { - case list { - [] -> Ok(reverse(acc)) - [x, ..xs] -> - case fun(x) { - Ok(y) -> do_try_map(xs, fun, [y, ..acc]) - Error(error) -> Error(error) - } - } -} - -/// Takes a function that returns a `Result` and applies it to each element in a -/// given list in turn. -/// -/// If the function returns `Ok(new_value)` for all elements in the list then a -/// list of the new values is returned. -/// -/// If the function returns `Error(reason)` for any of the elements then it is -/// returned immediately. None of the elements in the list are processed after -/// one returns an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(x) { Ok(x + 2) }) -/// Ok([3, 4, 5]) -/// ``` -/// -/// ```gleam -/// > try_map([1, 2, 3], fn(_) { Error(0) }) -/// Error(0) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [2, 3]], first) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > try_map([[1], [], [2]], first) -/// Error(Nil) -/// ``` -/// -pub fn try_map( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(List(b), e) { - do_try_map(list, fun, []) -} - -/// Returns a list that is the given list with up to the given number of -/// elements removed from the front of the list. -/// -/// If the element has less than the number of elements an empty list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 2) -/// [3, 4] -/// ``` -/// -/// ```gleam -/// > drop([1, 2, 3, 4], 9) -/// [] -/// ``` -/// -pub fn drop(from list: List(a), up_to n: Int) -> List(a) { - case n <= 0 { - True -> list - False -> - case list { - [] -> [] - [_, ..xs] -> drop(xs, n - 1) - } - } -} - -fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) { - case n <= 0 { - True -> reverse(acc) - False -> - case list { - [] -> reverse(acc) - [x, ..xs] -> do_take(xs, n - 1, [x, ..acc]) - } - } -} - -/// Returns a list containing the first given number of elements from the given -/// list. -/// -/// If the element has less than the number of elements then the full list is -/// returned. -/// -/// This function runs in linear time but does not copy the list. -/// -/// ## Examples -/// -/// ```gleam -/// > take([1, 2, 3, 4], 2) -/// [1, 2] -/// ``` -/// -/// ```gleam -/// > take([1, 2, 3, 4], 9) -/// [1, 2, 3, 4] -/// ``` -/// -pub fn take(from list: List(a), up_to n: Int) -> List(a) { - do_take(list, n, []) -} - -/// Returns a new empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// [] -/// ``` -/// -pub fn new() -> List(a) { - [] -} - -/// Joins one list onto the end of another. -/// -/// This function runs in linear time, and it traverses and copies the first -/// list. -/// -/// ## Examples -/// -/// ```gleam -/// > append([1, 2], [3]) -/// [1, 2, 3] -/// ``` -/// -pub fn append(first: List(a), second: List(a)) -> List(a) { - do_append(first, second) -} - -@target(erlang) -@external(erlang, "lists", "append") -fn do_append(a: List(a), b: List(a)) -> List(a) - -@target(javascript) -fn do_append(first: List(a), second: List(a)) -> List(a) { - do_append_acc(reverse(first), second) -} - -@target(javascript) -fn do_append_acc(first: List(a), second: List(a)) -> List(a) { - case first { - [] -> second - [item, ..rest] -> do_append_acc(rest, [item, ..second]) - } -} - -/// Prefixes an item to a list. This can also be done using the dedicated -/// syntax instead -/// -/// ```gleam -/// let new_list = [1, ..existing_list] -/// ``` -/// -pub fn prepend(to list: List(a), this item: a) -> List(a) { - [item, ..list] -} - -// Reverses a list and prepends it to another list -fn reverse_and_prepend(list prefix: List(a), to suffix: List(a)) -> List(a) { - case prefix { - [] -> suffix - [first, ..rest] -> reverse_and_prepend(list: rest, to: [first, ..suffix]) - } -} - -fn do_concat(lists: List(List(a)), acc: List(a)) -> List(a) { - case lists { - [] -> reverse(acc) - [list, ..further_lists] -> - do_concat(further_lists, reverse_and_prepend(list: list, to: acc)) - } -} - -/// Joins a list of lists into a single list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > concat([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn concat(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// This is the same as `concat`: it joins a list of lists into a single -/// list. -/// -/// This function traverses all elements twice. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten([[1], [2, 3], []]) -/// [1, 2, 3] -/// ``` -/// -pub fn flatten(lists: List(List(a))) -> List(a) { - do_concat(lists, []) -} - -/// Maps the list with the given function into a list of lists, and then flattens it. -/// -/// ## Examples -/// -/// ```gleam -/// > flat_map([2, 4, 6], fn(x) { [x, x + 1] }) -/// [2, 3, 4, 5, 6, 7] -/// ``` -/// -pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(b) { - map(list, fun) - |> concat -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from left to right. -/// -/// `fold([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 1), 2), 3)`. -/// -/// This function runs in linear time. -/// -pub fn fold( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fold(rest, fun(initial, x), fun) - } -} - -/// Reduces a list of elements into a single value by calling a given function -/// on each element, going from right to left. -/// -/// `fold_right([1, 2, 3], 0, add)` is the equivalent of -/// `add(add(add(0, 3), 2), 1)`. -/// -/// This function runs in linear time. -/// -/// Unlike `fold` this function is not tail recursive. Where possible use -/// `fold` instead as it will use less memory. -/// -pub fn fold_right( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> acc { - case list { - [] -> initial - [x, ..rest] -> fun(fold_right(rest, initial, fun), x) - } -} - -fn do_index_fold( - over: List(a), - acc: acc, - with: fn(acc, a, Int) -> acc, - index: Int, -) -> acc { - case over { - [] -> acc - [first, ..rest] -> - do_index_fold(rest, with(acc, first, index), with, index + 1) - } -} - -/// Like fold but the folding function also receives the index of the current element. -/// -/// ## Examples -/// -/// ```gleam -/// ["a", "b", "c"] -/// |> index_fold([], fn(acc, item, index) { ... }) -/// ``` -/// -pub fn index_fold( - over over: List(a), - from initial: acc, - with fun: fn(acc, a, Int) -> acc, -) -> acc { - do_index_fold(over, initial, fun, 0) -} - -/// A variant of fold that might fail. -/// -/// The folding function should return `Result(accumulator, error)`. -/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. -/// If the returned value is `Error(error)` try_fold will stop and return that error. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> try_fold(0, fn(acc, i) { -/// case i < 3 { -/// True -> Ok(acc + i) -/// False -> Error(Nil) -/// } -/// }) -/// ``` -/// -pub fn try_fold( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> Result(acc, e), -) -> Result(acc, e) { - case collection { - [] -> Ok(accumulator) - [first, ..rest] -> - case fun(accumulator, first) { - Ok(result) -> try_fold(rest, result, fun) - Error(_) as error -> error - } - } -} - -pub type ContinueOrStop(a) { - Continue(a) - Stop(a) -} - -/// A variant of fold that allows to stop folding earlier. -/// -/// The folding function should return `ContinueOrStop(accumulator)`. -/// If the returned value is `Continue(accumulator)` fold_until will try the next value in the list. -/// If the returned value is `Stop(accumulator)` fold_until will stop and return that accumulator. -/// -/// ## Examples -/// -/// ```gleam -/// [1, 2, 3, 4] -/// |> fold_until(0, fn(acc, i) { -/// case i < 3 { -/// True -> Continue(acc + i) -/// False -> Stop(acc) -/// } -/// }) -/// ``` -/// -pub fn fold_until( - over collection: List(a), - from accumulator: acc, - with fun: fn(acc, a) -> ContinueOrStop(acc), -) -> acc { - case collection { - [] -> accumulator - [first, ..rest] -> - case fun(accumulator, first) { - Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun) - Stop(b) -> b - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 2 }) -/// Ok(3) -/// ``` -/// -/// ```gleam -/// > find([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn find( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(a, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case is_desired(x) { - True -> Ok(x) - _ -> find(in: rest, one_that: is_desired) - } - } -} - -/// Finds the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > find_map([[], [2], [3]], first) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > find_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > find_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn find_map( - in haystack: List(a), - with fun: fn(a) -> Result(b, c), -) -> Result(b, Nil) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case fun(x) { - Ok(x) -> Ok(x) - _ -> find_map(in: rest, with: fun) - } - } -} - -/// Returns `True` if the given function returns `True` for all the elements in -/// the given list. If the function returns `False` for any of the elements it -/// immediately returns `False` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > all([], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > all([4, 3], fn(x) { x > 3 }) -/// False -/// ``` -/// -pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> True - [first, ..rest] -> - case predicate(first) { - True -> all(rest, predicate) - False -> False - } - } -} - -/// Returns `True` if the given function returns `True` for any the elements in -/// the given list. If the function returns `True` for any of the elements it -/// immediately returns `True` without checking the rest of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > any([], fn(x) { x > 3 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([4, 5], fn(x) { x > 3 }) -/// True -/// ``` -/// -/// ```gleam -/// > any([4, 3], fn(x) { x > 4 }) -/// False -/// ``` -/// -/// ```gleam -/// > any([3, 4], fn(x) { x > 3 }) -/// True -/// ``` -/// -pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool { - case list { - [] -> False - [first, ..rest] -> - case predicate(first) { - True -> True - False -> any(rest, predicate) - } - } -} - -fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) { - case xs, ys { - [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc]) - _, _ -> reverse(acc) - } -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, the remaining elements from -/// the longer list are not used. -/// -/// ## Examples -/// -/// ```gleam -/// > zip([], []) -/// [] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1], [3, 4]) -/// [#(1, 3)] -/// ``` -/// -/// ```gleam -/// > zip([1, 2], [3, 4]) -/// [#(1, 3), #(2, 4)] -/// ``` -/// -pub fn zip(list: List(a), with other: List(b)) -> List(#(a, b)) { - do_zip(list, other, []) -} - -/// Takes two lists and returns a single list of 2-element tuples. -/// -/// If one of the lists is longer than the other, an `Error` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > strict_zip([], []) -/// Ok([]) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1], [3, 4]) -/// Error(LengthMismatch) -/// ``` -/// -/// ```gleam -/// > strict_zip([1, 2], [3, 4]) -/// Ok([#(1, 3), #(2, 4)]) -/// ``` -/// -pub fn strict_zip( - list: List(a), - with other: List(b), -) -> Result(List(#(a, b)), LengthMismatch) { - case length(of: list) == length(of: other) { - True -> Ok(zip(list, other)) - False -> Error(LengthMismatch) - } -} - -fn do_unzip(input, xs, ys) { - case input { - [] -> #(reverse(xs), reverse(ys)) - [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys]) - } -} - -/// Takes a single list of 2-element tuples and returns two lists. -/// -/// ## Examples -/// -/// ```gleam -/// > unzip([#(1, 2), #(3, 4)]) -/// #([1, 3], [2, 4]) -/// ``` -/// -/// ```gleam -/// > unzip([]) -/// #([], []) -/// ``` -/// -pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b)) { - do_unzip(input, [], []) -} - -fn do_intersperse(list: List(a), separator: a, acc: List(a)) -> List(a) { - case list { - [] -> reverse(acc) - [x, ..rest] -> do_intersperse(rest, separator, [x, separator, ..acc]) - } -} - -/// Inserts a given value between each existing element in a given list. -/// -/// This function runs in linear time and copies the list. -/// -/// ## Examples -/// -/// ```gleam -/// > intersperse([1, 1, 1], 2) -/// [1, 2, 1, 2, 1] -/// ``` -/// -/// ```gleam -/// > intersperse([], 2) -/// [] -/// ``` -/// -pub fn intersperse(list: List(a), with elem: a) -> List(a) { - case list { - [] | [_] -> list - [x, ..rest] -> do_intersperse(rest, elem, [x]) - } -} - -/// Returns the element in the Nth position in the list, with 0 being the first -/// position. -/// -/// `Error(Nil)` is returned if the list is not long enough for the given index -/// or if the index is less than 0. -/// -/// ## Examples -/// -/// ```gleam -/// > at([1, 2, 3], 1) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > at([1, 2, 3], 5) -/// Error(Nil) -/// ``` -/// -pub fn at(in list: List(a), get index: Int) -> Result(a, Nil) { - case index >= 0 { - True -> - list - |> drop(index) - |> first - False -> Error(Nil) - } -} - -/// Removes any duplicate elements from a given list. -/// -/// This function returns in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > unique([1, 1, 1, 4, 7, 3, 3, 4]) -/// [1, 4, 7, 3] -/// ``` -/// -pub fn unique(list: List(a)) -> List(a) { - case list { - [] -> [] - [x, ..rest] -> [x, ..unique(filter(rest, fn(y) { y != x }))] - } -} - -/// Merge lists `a` and `b` in ascending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_up( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(ax, bx) { - order.Gt -> merge_up(na, nb - 1, a, br, [bx, ..acc], compare) - _ -> merge_up(na - 1, nb, ar, b, [ax, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge lists `a` and `b` in descending order -/// but only up to `na` and `nb` number of items respectively. -/// -fn merge_down( - na: Int, - nb: Int, - a: List(a), - b: List(a), - acc: List(a), - compare: fn(a, a) -> Order, -) { - case na, nb, a, b { - 0, 0, _, _ -> acc - _, 0, [ax, ..ar], _ -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - 0, _, _, [bx, ..br] -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - _, _, [ax, ..ar], [bx, ..br] -> - case compare(bx, ax) { - order.Lt -> merge_down(na - 1, nb, ar, b, [ax, ..acc], compare) - _ -> merge_down(na, nb - 1, a, br, [bx, ..acc], compare) - } - _, _, _, _ -> acc - } -} - -/// Merge sort that alternates merging in ascending and descending order -/// because the merge process also reverses the list. -/// -/// Some copying is avoided by merging only a subset of the lists -/// instead of creating and merging new smaller lists. -/// -fn merge_sort( - l: List(a), - ln: Int, - compare: fn(a, a) -> Order, - down: Bool, -) -> List(a) { - let n = ln / 2 - let a = l - let b = drop(l, n) - case ln < 3 { - True -> - case down { - True -> merge_down(n, ln - n, a, b, [], compare) - False -> merge_up(n, ln - n, a, b, [], compare) - } - False -> - case down { - True -> - merge_down( - n, - ln - n, - merge_sort(a, n, compare, False), - merge_sort(b, ln - n, compare, False), - [], - compare, - ) - False -> - merge_up( - n, - ln - n, - merge_sort(a, n, compare, True), - merge_sort(b, ln - n, compare, True), - [], - compare, - ) - } - } -} - -/// Sorts from smallest to largest based upon the ordering specified by a given -/// function. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare) -/// [1, 2, 3, 4, 4, 5, 6] -/// ``` -/// -pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { - merge_sort(list, length(list), compare, True) -} - -/// Creates a list of ints ranging from a given start and finish. -/// -/// ## Examples -/// -/// ```gleam -/// > range(0, 0) -/// [0] -/// ``` -/// -/// ```gleam -/// > range(0, 5) -/// [0, 1, 2, 3, 4, 5] -/// ``` -/// -/// ```gleam -/// > range(1, -5) -/// [1, 0, -1, -2, -3, -4, -5] -/// ``` -/// -pub fn range(from start: Int, to stop: Int) -> List(Int) { - tail_recursive_range(start, stop, []) -} - -fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { - case int.compare(start, stop) { - order.Eq -> [stop, ..acc] - order.Gt -> tail_recursive_range(start, stop + 1, [stop, ..acc]) - order.Lt -> tail_recursive_range(start, stop - 1, [stop, ..acc]) - } -} - -fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) { - case times <= 0 { - True -> acc - False -> do_repeat(a, times - 1, [a, ..acc]) - } -} - -/// Builds a list of a given value a given number of times. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("a", times: 0) -/// [] -/// ``` -/// -/// ```gleam -/// > repeat("a", times: 5) -/// ["a", "a", "a", "a", "a"] -/// ``` -/// -pub fn repeat(item a: a, times times: Int) -> List(a) { - do_repeat(a, times, []) -} - -fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) { - case n <= 0 { - True -> #(reverse(taken), list) - False -> - case list { - [] -> #(reverse(taken), []) - [x, ..xs] -> do_split(xs, n - 1, [x, ..taken]) - } - } -} - -/// Splits a list in two before the given index. -/// -/// If the list is not long enough to have the given index the before list will -/// be the input list, and the after list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split([6, 7, 8, 9], 0) -/// #([], [6, 7, 8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 2) -/// #([6, 7], [8, 9]) -/// ``` -/// -/// ```gleam -/// > split([6, 7, 8, 9], 4) -/// #([6, 7, 8, 9], []) -/// ``` -/// -pub fn split(list list: List(a), at index: Int) -> #(List(a), List(a)) { - do_split(list, index, []) -} - -fn do_split_while( - list: List(a), - f: fn(a) -> Bool, - acc: List(a), -) -> #(List(a), List(a)) { - case list { - [] -> #(reverse(acc), []) - [x, ..xs] -> - case f(x) { - False -> #(reverse(acc), list) - _ -> do_split_while(xs, f, [x, ..acc]) - } - } -} - -/// Splits a list in two before the first element that a given function returns -/// `False` for. -/// -/// If the function returns `True` for all elements the first list will be the -/// input list, and the second list will be empty. -/// -/// ## Examples -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 }) -/// #([1, 2, 3], [4, 5]) -/// ``` -/// -/// ```gleam -/// > split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 }) -/// #([1, 2, 3, 4, 5], []) -/// ``` -/// -pub fn split_while( - list list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_split_while(list, predicate, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element and returns the second element. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "a") -/// Ok(0) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "b") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > key_find([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_find( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> Result(v, Nil) { - find_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, finds all tuples that have a given -/// key as the first element and returns the second element. -/// -/// This function may be useful for interacting with Erlang code where lists of -/// tuples are common. -/// -/// ## Examples -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1), #("a", 2)], "a") -/// [0, 2] -/// ``` -/// -/// ```gleam -/// > key_filter([#("a", 0), #("b", 1)], "c") -/// [] -/// ``` -/// -pub fn key_filter( - in keyword_list: List(#(k, v)), - find desired_key: k, -) -> List(v) { - filter_map( - keyword_list, - fn(keyword) { - let #(key, value) = keyword - case key == desired_key { - True -> Ok(value) - False -> Error(Nil) - } - }, - ) -} - -fn do_pop(haystack, predicate, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case predicate(x) { - True -> Ok(#(x, append(reverse(checked), rest))) - False -> do_pop(rest, predicate, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the predicate function returns `True`. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 2 }) -/// Ok(#(3, [1, 2])) -/// ``` -/// -/// ```gleam -/// > pop([1, 2, 3], fn(x) { x > 4 }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop([], fn(_) { True }) -/// Error(Nil) -/// ``` -/// -pub fn pop( - in haystack: List(a), - one_that is_desired: fn(a) -> Bool, -) -> Result(#(a, List(a)), Nil) { - do_pop(haystack, is_desired, []) -} - -fn do_pop_map(haystack, mapper, checked) { - case haystack { - [] -> Error(Nil) - [x, ..rest] -> - case mapper(x) { - Ok(y) -> Ok(#(y, append(reverse(checked), rest))) - Error(_) -> do_pop_map(rest, mapper, [x, ..checked]) - } - } -} - -/// Removes the first element in a given list for which the given function returns -/// `Ok(new_value)`, then returns the wrapped `new_value` as well as list with the value removed. -/// -/// Returns `Error(Nil)` if no such element is found. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_map([[], [2], [3]], first) -/// Ok(#(2, [[], [3]])) -/// ``` -/// -/// ```gleam -/// > pop_map([[], []], first) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > pop_map([], first) -/// Error(Nil) -/// ``` -/// -pub fn pop_map( - in haystack: List(a), - one_that is_desired: fn(a) -> Result(b, c), -) -> Result(#(b, List(a)), Nil) { - do_pop_map(haystack, is_desired, []) -} - -/// Given a list of 2-element tuples, finds the first tuple that has a given -/// key as the first element. This function will return the second element -/// of the found tuple and list with tuple removed. -/// -/// If no tuple is found with the given key then `Error(Nil)` is returned. -/// -/// ## Examples -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "a") -/// Ok(#(0, [#("b", 1)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "b") -/// Ok(#(1, [#("a", 0)])) -/// ``` -/// -/// ```gleam -/// > key_pop([#("a", 0), #("b", 1)], "c") -/// Error(Nil) -/// ``` -/// -pub fn key_pop( - haystack: List(#(k, v)), - key: k, -) -> Result(#(v, List(#(k, v))), Nil) { - pop_map( - haystack, - fn(entry) { - let #(k, v) = entry - case k { - k if k == key -> Ok(v) - _ -> Error(Nil) - } - }, - ) -} - -/// Given a list of 2-element tuples, inserts a key and value into the list. -/// -/// If there was already a tuple with the key then it is replaced, otherwise it -/// is added to the end of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 4, 100) -/// [#(5, 0), #(4, 100)] -/// ``` -/// -/// ```gleam -/// > key_set([#(5, 0), #(4, 1)], 1, 100) -/// [#(5, 0), #(4, 1), #(1, 100)] -/// ``` -/// -pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) { - case list { - [] -> [#(key, value)] - [#(k, _), ..rest] if k == key -> [#(key, value), ..rest] - [first, ..rest] -> [first, ..key_set(rest, key, value)] - } -} - -/// Calls a function for each element in a list, discarding the return value. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ```gleam -/// > list.each([1, 2, 3], io.println) -/// Nil -/// ``` -/// -pub fn each(list: List(a), f: fn(a) -> b) -> Nil { - case list { - [] -> Nil - [x, ..xs] -> { - f(x) - each(xs, f) - } - } -} - -/// Calls a `Result` returning function for each element in a list, discarding -/// the return value. If the function returns `Error` then the iteration is -/// stopped and the error is returned. -/// -/// Useful for calling a side effect for every item of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > try_each( -/// > over: [1, 2, 3], -/// > with: function_that_might_fail, -/// > ) -/// Ok(Nil) -/// ``` -/// -pub fn try_each( - over list: List(a), - with fun: fn(a) -> Result(b, e), -) -> Result(Nil, e) { - case list { - [] -> Ok(Nil) - [x, ..xs] -> - case fun(x) { - Ok(_) -> try_each(over: xs, with: fun) - Error(e) -> Error(e) - } - } -} - -fn do_partition(list, categorise, trues, falses) { - case list { - [] -> #(reverse(trues), reverse(falses)) - [x, ..xs] -> - case categorise(x) { - True -> do_partition(xs, categorise, [x, ..trues], falses) - False -> do_partition(xs, categorise, trues, [x, ..falses]) - } - } -} - -/// Partitions a list into a tuple/pair of lists -/// by a given categorisation function. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> list.partition(int.is_odd) -/// #([1, 3, 5], [2, 4]) -/// ``` -/// -pub fn partition( - list: List(a), - with categorise: fn(a) -> Bool, -) -> #(List(a), List(a)) { - do_partition(list, categorise, [], []) -} - -/// Returns all the permutations of a list. -/// -/// ## Examples -/// -/// ```gleam -/// > permutations([1, 2]) -/// [[1, 2], [2, 1]] -/// ``` -/// -pub fn permutations(l: List(a)) -> List(List(a)) { - case l { - [] -> [[]] - _ -> - l - |> index_map(fn(i_idx, i) { - l - |> index_fold( - [], - fn(acc, j, j_idx) { - case i_idx == j_idx { - True -> acc - False -> [j, ..acc] - } - }, - ) - |> reverse - |> permutations - |> map(fn(permutation) { [i, ..permutation] }) - }) - |> concat - } -} - -fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) { - let window = take(l, n) - - case length(window) == n { - True -> do_window([window, ..acc], drop(l, 1), n) - False -> acc - } -} - -/// Returns a list of sliding windows. -/// -/// ## Examples -/// -/// ```gleam -/// > window([1,2,3,4,5], 3) -/// [[1, 2, 3], [2, 3, 4], [3, 4, 5]] -/// ``` -/// -/// ```gleam -/// > window([1, 2], 4) -/// [] -/// ``` -/// -pub fn window(l: List(a), by n: Int) -> List(List(a)) { - do_window([], l, n) - |> reverse -} - -/// Returns a list of tuples containing two contiguous elements. -/// -/// ## Examples -/// -/// ```gleam -/// > window_by_2([1,2,3,4]) -/// [#(1, 2), #(2, 3), #(3, 4)] -/// ``` -/// -/// ```gleam -/// > window_by_2([1]) -/// [] -/// ``` -/// -pub fn window_by_2(l: List(a)) -> List(#(a, a)) { - zip(l, drop(l, 1)) -} - -/// Drops the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_while([1, 2, 3, 4], fn (x) { x < 3 }) -/// [3, 4] -/// ``` -/// -pub fn drop_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - case list { - [] -> [] - [x, ..xs] -> - case predicate(x) { - True -> drop_while(xs, predicate) - False -> [x, ..xs] - } - } -} - -fn do_take_while( - list: List(a), - predicate: fn(a) -> Bool, - acc: List(a), -) -> List(a) { - case list { - [] -> reverse(acc) - [first, ..rest] -> - case predicate(first) { - True -> do_take_while(rest, predicate, [first, ..acc]) - False -> reverse(acc) - } - } -} - -/// Takes the first elements in a given list for which the predicate function returns `True`. -/// -/// ## Examples -/// -/// ```gleam -/// > take_while([1, 2, 3, 2, 4], fn (x) { x < 3 }) -/// [1, 2] -/// ``` -/// -pub fn take_while( - in list: List(a), - satisfying predicate: fn(a) -> Bool, -) -> List(a) { - do_take_while(list, predicate, []) -} - -fn do_chunk( - list: List(a), - f: fn(a) -> key, - previous_key: key, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [first, ..rest] -> { - let key = f(first) - case key == previous_key { - False -> { - let new_acc = [reverse(current_chunk), ..acc] - do_chunk(rest, f, key, [first], new_acc) - } - _true -> do_chunk(rest, f, key, [first, ..current_chunk], acc) - } - } - _empty -> reverse([reverse(current_chunk), ..acc]) - } -} - -/// Returns a list of chunks in which -/// the return value of calling `f` on each element is the same. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 }) -/// [[1], [2, 2], [3], [4, 4, 6], [7, 7]] -/// ``` -/// -pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) { - case list { - [] -> [] - [first, ..rest] -> do_chunk(rest, f, f(first), [first], []) - } -} - -fn do_sized_chunk( - list: List(a), - count: Int, - left: Int, - current_chunk: List(a), - acc: List(List(a)), -) -> List(List(a)) { - case list { - [] -> - case current_chunk { - [] -> reverse(acc) - remaining -> reverse([reverse(remaining), ..acc]) - } - [first, ..rest] -> { - let chunk = [first, ..current_chunk] - case left > 1 { - False -> do_sized_chunk(rest, count, count, [], [reverse(chunk), ..acc]) - True -> do_sized_chunk(rest, count, left - 1, chunk, acc) - } - } - } -} - -/// Returns a list of chunks containing `count` elements each. -/// -/// If the last chunk does not have `count` elements, it is instead -/// a partial chunk, with less than `count` elements. -/// -/// For any `count` less than 1 this function behaves as if it was set to 1. -/// -/// ## Examples -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2) -/// [[1, 2], [3, 4], [5, 6]] -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3) -/// [[1, 2, 3], [4, 5, 6], [7, 8]] -/// ``` -/// -pub fn sized_chunk(in list: List(a), into count: Int) -> List(List(a)) { - do_sized_chunk(list, count, count, [], []) -} - -/// This function acts similar to fold, but does not take an initial state. -/// Instead, it starts from the first element in the list -/// and combines it with each subsequent element in turn using the given -/// function. The function is called as `fun(accumulator, current_element)`. -/// -/// Returns `Ok` to indicate a successful run, and `Error` if called on an -/// empty list. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> reduce(fn(acc, x) { acc + x }) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x }) -/// Ok(15) -/// ``` -/// -pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(a, Nil) { - case list { - [] -> Error(Nil) - [first, ..rest] -> Ok(fold(rest, first, fun)) - } -} - -fn do_scan( - list: List(a), - accumulator: acc, - accumulated: List(acc), - fun: fn(acc, a) -> acc, -) -> List(acc) { - case list { - [] -> reverse(accumulated) - [x, ..xs] -> { - let next = fun(accumulator, x) - do_scan(xs, next, [next, ..accumulated], fun) - } - } -} - -/// Similar to `fold`, but yields the state of the accumulator at each stage. -/// -/// ## Examples -/// -/// ```gleam -/// > scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i }) -/// [101, 103, 106] -/// ``` -/// -pub fn scan( - over list: List(a), - from initial: acc, - with fun: fn(acc, a) -> acc, -) -> List(acc) { - do_scan(list, initial, [], fun) -} - -/// Returns the last element in the given list. -/// -/// Returns `Error(Nil)` if the list is empty. -/// -/// This function runs in linear time. -/// For a collection oriented around performant access at either end, -/// see `gleam/queue.Queue`. -/// -/// ## Examples -/// -/// ```gleam -/// > last([]) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last([1, 2, 3, 4, 5]) -/// Ok(5) -/// ``` -/// -pub fn last(list: List(a)) -> Result(a, Nil) { - list - |> reduce(fn(_, elem) { elem }) -} - -/// Return unique combinations of elements in the list. -/// -/// ## Examples -/// -/// ```gleam -/// > combinations([1, 2, 3], 2) -/// [[1, 2], [1, 3], [2, 3]] -/// ``` -/// -/// ```gleam -/// > combinations([1, 2, 3, 4], 3) -/// [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]] -/// ``` -/// -pub fn combinations(items: List(a), by n: Int) -> List(List(a)) { - case n { - 0 -> [[]] - _ -> - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = - map(combinations(xs, n - 1), with: fn(com) { [x, ..com] }) - |> reverse - fold( - first_combinations, - combinations(xs, n), - fn(acc, c) { [c, ..acc] }, - ) - } - } - } -} - -fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) { - case items { - [] -> [] - [x, ..xs] -> { - let first_combinations = map(xs, with: fn(other) { #(x, other) }) - [first_combinations, ..do_combination_pairs(xs)] - } - } -} - -/// Return unique pair combinations of elements in the list -/// -/// ## Examples -/// -/// ```gleam -/// > combination_pairs([1, 2, 3]) -/// [#(1, 2), #(1, 3), #(2, 3)] -/// ``` -/// -pub fn combination_pairs(items: List(a)) -> List(#(a, a)) { - do_combination_pairs(items) - |> concat -} - -/// Make a list alternating the elements from the given lists -/// -/// ## Examples -/// -/// ```gleam -/// > list.interleave([[1, 2], [101, 102], [201, 202]]) -/// [1, 101, 201, 2, 102, 202] -/// ``` -/// -pub fn interleave(list: List(List(a))) -> List(a) { - transpose(list) - |> concat -} - -/// Transpose rows and columns of the list of lists. -/// -/// Notice: This function is not tail recursive, -/// and thus may exceed stack size if called, -/// with large lists (on target JavaScript). -/// -/// ## Examples -/// -/// ```gleam -/// > transpose([[1, 2, 3], [101, 102, 103]]) -/// [[1, 101], [2, 102], [3, 103]] -/// ``` -/// -pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) { - let take_first = fn(list) { - case list { - [] -> [] - [f] -> [f] - [f, ..] -> [f] - } - } - - case list_of_list { - [] -> [] - [[], ..xss] -> transpose(xss) - rows -> { - let firsts = - rows - |> map(take_first) - |> concat - let rest = transpose(map(rows, drop(_, 1))) - [firsts, ..rest] - } - } -} - -fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [elem_pair, ..enumerable] -> - do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc]) - } -} - -fn do_shuffle_by_pair_indexes( - list_of_pairs: List(#(Float, a)), -) -> List(#(Float, a)) { - sort( - list_of_pairs, - fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order { - float.compare(a_pair.0, b_pair.0) - }, - ) -} - -/// Takes a list, randomly sorts all items and returns the shuffled list. -/// -/// This function uses Erlang's `:rand` module or Javascript's -/// `Math.random()` to calculate the index shuffling. -/// -/// ## Example -/// -/// ```gleam -/// > range(1, 10) -/// > |> shuffle() -/// [1, 6, 9, 10, 3, 8, 4, 2, 7, 5] -/// ``` -/// -pub fn shuffle(list: List(a)) -> List(a) { - list - |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] }) - |> do_shuffle_by_pair_indexes() - |> do_shuffle_pair_unwrap([]) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam deleted file mode 100644 index 1f8b228..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/map.gleam +++ /dev/null @@ -1,127 +0,0 @@ -import gleam/option.{type Option} -import gleam/dict - -@deprecated("Please use the `gleam/dict` module instead") -pub type Map(key, value) = - dict.Dict(key, value) - -@deprecated("Please use the `gleam/dict` module instead") -pub fn size(map) -> Int { - dict.size(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn to_list(map) -> List(#(key, value)) { - dict.to_list(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn from_list(list: List(#(k, v))) { - dict.from_list(list) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn has_key(map, key: k) -> Bool { - dict.has_key(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn new() { - dict.new() -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn get(from, get: key) -> Result(value, Nil) { - dict.get(from, get) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn insert(into map, for key: k, insert value: v) { - dict.insert(map, key, value) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn map_values(in map, with fun: fn(k, v) -> w) { - dict.map_values(map, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn keys(map) -> List(keys) { - dict.keys(map) -} - -@target(javascript) -fn reverse_and_concat(remaining, accumulator) { - case remaining { - [] -> accumulator - [item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator]) - } -} - -@target(javascript) -fn do_keys_acc(list: List(#(k, v)), acc: List(k)) -> List(k) { - case list { - [] -> reverse_and_concat(acc, []) - [x, ..xs] -> do_keys_acc(xs, [x.0, ..acc]) - } -} - -@target(javascript) -fn do_keys(map) -> List(k) { - let list_of_pairs = - map - |> to_list - do_keys_acc(list_of_pairs, []) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn values(map) -> List(values) { - dict.values(map) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn filter(in map, keeping predicate: fn(k, v) -> Bool) { - dict.filter(map, predicate) -} - -@target(javascript) -fn do_filter(f: fn(key, value) -> Bool, map) { - let insert = fn(map, k, v) { - case f(k, v) { - True -> insert(map, k, v) - _ -> map - } - } - map - |> fold(from: new(), with: insert) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn take(from map, keeping desired_keys: List(k)) { - dict.take(map, desired_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn merge(into map, from new_entries) { - dict.merge(map, new_entries) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn delete(from map, delete key: k) { - dict.delete(map, key) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn drop(from map, drop disallowed_keys: List(k)) { - dict.drop(map, disallowed_keys) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn update(in map, update key: k, with fun: fn(Option(v)) -> v) { - dict.update(map, key, fun) -} - -@deprecated("Please use the `gleam/dict` module instead") -pub fn fold(over map, from initial: acc, with fun: fn(acc, k, v) -> acc) -> acc { - dict.fold(map, initial, fun) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam deleted file mode 100644 index 6015c0f..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/option.gleam +++ /dev/null @@ -1,346 +0,0 @@ -/// `Option` represents a value that may be present or not. `Some` means the value is -/// present, `None` means the value is not. -/// -/// This is Gleam's alternative to having a value that could be Null, as is -/// possible in some other languages. -/// -pub type Option(a) { - Some(a) - None -} - -fn do_all(list: List(Option(a)), acc: List(a)) -> Option(List(a)) { - case list { - [] -> Some(acc) - [x, ..rest] -> { - let accumulate = fn(acc, item) { - case acc, item { - Some(values), Some(value) -> Some([value, ..values]) - _, _ -> None - } - } - accumulate(do_all(rest, acc), x) - } - } -} - -/// Combines a list of `Option`s into a single `Option`. -/// If all elements in the list are `Some` then returns a `Some` holding the list of values. -/// If any element is `None` then returns`None`. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Some(1), Some(2)]) -/// Some([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Some(1), None]) -/// None -/// ``` -/// -pub fn all(list: List(Option(a))) -> Option(List(a)) { - do_all(list, []) -} - -/// Checks whether the `Option` is a `Some` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_some(Some(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_some(None) -/// False -/// ``` -/// -pub fn is_some(option: Option(a)) -> Bool { - option != None -} - -/// Checks whether the `Option` is a `None` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_none(Some(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_none(None) -/// True -/// ``` -/// -pub fn is_none(option: Option(a)) -> Bool { - option == None -} - -/// Converts an `Option` type to a `Result` type. -/// -/// ## Examples -/// -/// ```gleam -/// > to_result(Some(1), "some_error") -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > to_result(None, "some_error") -/// Error("some_error") -/// ``` -/// -pub fn to_result(option: Option(a), e) -> Result(a, e) { - case option { - Some(a) -> Ok(a) - _ -> Error(e) - } -} - -/// Converts a `Result` type to an `Option` type. -/// -/// ## Examples -/// -/// ```gleam -/// > from_result(Ok(1)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > from_result(Error("some_error")) -/// None -/// ``` -/// -pub fn from_result(result: Result(a, e)) -> Option(a) { - case result { - Ok(a) -> Some(a) - _ -> None - } -} - -/// Extracts the value from an `Option`, returning a default value if there is none. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Some(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(None, 0) -/// 0 -/// ``` -/// -pub fn unwrap(option: Option(a), or default: a) -> a { - case option { - Some(x) -> x - None -> default - } -} - -/// Extracts the value from an `Option`, evaluating the default function if the option is `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Some(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(None, fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(option: Option(a), or default: fn() -> a) -> a { - case option { - Some(x) -> x - None -> default() - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it. -/// -/// If the `Option` is a `None` rather than `Some`, the function is not called and the -/// `Option` stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Some(1), with: fn(x) { x + 1 }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > map(over: None, with: fn(x) { x + 1 }) -/// None -/// ``` -/// -pub fn map(over option: Option(a), with fun: fn(a) -> b) -> Option(b) { - case option { - Some(x) -> Some(fun(x)) - None -> None - } -} - -/// Merges a nested `Option` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Some(Some(1))) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > flatten(Some(None)) -/// None -/// ``` -/// -/// ```gleam -/// > flatten(None) -/// None -/// ``` -/// -pub fn flatten(option: Option(Option(a))) -> Option(a) { - case option { - Some(x) -> x - None -> None - } -} - -/// Updates a value held within the `Some` of an `Option` by calling a given function -/// on it, where the given function also returns an `Option`. The two options are -/// then merged together into one `Option`. -/// -/// If the `Option` is a `None` rather than `Some` the function is not called and the -/// option stays the same. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that return `Option`. -/// -/// ## Examples -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(x + 1) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(x) { Some(#("a", x)) }) -/// Some(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > then(Some(1), fn(_) { None }) -/// None -/// ``` -/// -/// ```gleam -/// > then(None, fn(x) { Some(x + 1) }) -/// None -/// ``` -/// -pub fn then(option: Option(a), apply fun: fn(a) -> Option(b)) -> Option(b) { - case option { - Some(x) -> fun(x) - None -> None - } -} - -/// Returns the first value if it is `Some`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Some(1), Some(2)) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(Some(1), None) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > or(None, Some(2)) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > or(None, None) -/// None -/// ``` -/// -pub fn or(first: Option(a), second: Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second - } -} - -/// Returns the first value if it is `Some`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { Some(2) }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Some(1), fn() { None }) -/// Some(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { Some(2) }) -/// Some(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(None, fn() { None }) -/// None -/// ``` -/// -pub fn lazy_or(first: Option(a), second: fn() -> Option(a)) -> Option(a) { - case first { - Some(_) -> first - None -> second() - } -} - -fn do_values(list: List(Option(a)), acc: List(a)) -> List(a) { - case list { - [] -> acc - [x, ..xs] -> { - let accumulate = fn(acc, item) { - case item { - Some(value) -> [value, ..acc] - None -> acc - } - } - accumulate(do_values(xs, acc), x) - } - } -} - -/// Given a list of `Option`s, -/// returns only the values inside `Some`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Some(1), None, Some(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(options: List(Option(a))) -> List(a) { - do_values(options, []) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam deleted file mode 100644 index 12ce011..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/order.gleam +++ /dev/null @@ -1,133 +0,0 @@ -/// Represents the result of a single comparison to determine the precise -/// ordering of two values. -/// -pub type Order { - /// Less-than - Lt - - /// Equal - Eq - - /// Greater than - Gt -} - -/// Inverts an order, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -/// ```gleam -/// > negate(Eq) -/// Eq -/// ``` -/// -/// ```gleam -/// > negate(Lt) -/// Gt -/// ``` -/// -pub fn negate(order: Order) -> Order { - case order { - Lt -> Gt - Eq -> Eq - Gt -> Lt - } -} - -/// Produces a numeric representation of the order. -/// -/// ## Examples -/// -/// ```gleam -/// > to_int(Lt) -/// -1 -/// ``` -/// -/// ```gleam -/// > to_int(Eq) -/// 0 -/// ``` -/// -/// ```gleam -/// > to_int(Gt) -/// 1 -/// ``` -/// -pub fn to_int(order: Order) -> Int { - case order { - Lt -> -1 - Eq -> 0 - Gt -> 1 - } -} - -/// Compares two `Order` values to one another, producing a new `Order`. -/// -/// ## Examples -/// -/// ```gleam -/// > compare(Eq, with: Lt) -/// Gt -/// ``` -/// -pub fn compare(a: Order, with b: Order) -> Order { - case a, b { - x, y if x == y -> Eq - Lt, _ | Eq, Gt -> Lt - _, _ -> Gt - } -} - -/// Returns the largest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > max(Eq, Lt) -/// Eq -/// ``` -/// -pub fn max(a: Order, b: Order) -> Order { - case a, b { - Gt, _ -> Gt - Eq, Lt -> Eq - _, _ -> b - } -} - -/// Returns the smallest of two orders given that `Gt > Eq > Lt`. -/// -/// ## Examples -/// -/// ```gleam -/// > min(Eq, Lt) -/// Lt -/// ``` -/// -pub fn min(a: Order, b: Order) -> Order { - case a, b { - Lt, _ -> Lt - Eq, Gt -> Eq - _, _ -> b - } -} - -/// Inverts an ordering function, so less-than becomes greater-than and greater-than -/// becomes less-than. -/// -/// ## Examples -/// -/// ```gleam -/// > list.sort([1, 5, 4], by: reverse(int.compare)) -/// [5, 4, 1] -/// ``` -/// -pub fn reverse(orderer: fn(a, a) -> Order) -> fn(a, a) -> Order { - fn(a, b) { orderer(b, a) } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam deleted file mode 100644 index 894e6a8..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/pair.gleam +++ /dev/null @@ -1,85 +0,0 @@ -/// Returns the first element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > first(#(1, 2)) -/// 1 -/// ``` -/// -pub fn first(pair: #(a, b)) -> a { - let #(a, _) = pair - a -} - -/// Returns the second element in a pair. -/// -/// ## Examples -/// -/// ```gleam -/// > second(#(1, 2)) -/// 2 -/// ``` -/// -pub fn second(pair: #(a, b)) -> b { - let #(_, a) = pair - a -} - -/// Returns a new pair with the elements swapped. -/// -/// ## Examples -/// -/// ```gleam -/// > swap(#(1, 2)) -/// #(2, 1) -/// ``` -/// -pub fn swap(pair: #(a, b)) -> #(b, a) { - let #(a, b) = pair - #(b, a) -} - -/// Returns a new pair with the first element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_first(fn(n) { n * 2 }) -/// #(2, 2) -/// ``` -/// -pub fn map_first(of pair: #(a, b), with fun: fn(a) -> c) -> #(c, b) { - let #(a, b) = pair - #(fun(a), b) -} - -/// Returns a new pair with the second element having had `with` applied to -/// it. -/// -/// ## Examples -/// -/// ```gleam -/// > #(1, 2) |> map_second(fn(n) { n * 2 }) -/// #(1, 4) -/// ``` -/// -pub fn map_second(of pair: #(a, b), with fun: fn(b) -> c) -> #(a, c) { - let #(a, b) = pair - #(a, fun(b)) -} - -/// Returns a new pair with the given elements. This can also be done using the dedicated -/// syntax instead: `new(1, 2) == #(1, 2)`. -/// -/// ## Examples -/// -/// ```gleam -/// > new(1, 2) -/// #(1, 2) -/// ``` -/// -pub fn new(first: a, second: b) -> #(a, b) { - #(first, second) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam deleted file mode 100644 index 5bf60c8..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/queue.gleam +++ /dev/null @@ -1,292 +0,0 @@ -import gleam/list - -/// A queue is an ordered collection of elements. It is similar to a list, but -/// unlike a list elements can be added to or removed from either the front or -/// the back in a performant fashion. -/// -/// The internal representation may be different for two queues with the same -/// elements in the same order if the queues were constructed in different -/// ways. This is the price paid for a queue's fast access at both the front -/// and the back. -/// -/// Because of unpredictable internal representation the equality operator `==` -/// may return surprising results, and the `is_equal` and `is_logically_equal` -/// functions are the recommended way to test queues for equality. -/// -pub opaque type Queue(element) { - Queue(in: List(element), out: List(element)) -} - -/// Creates a fresh queue that contains no values. -/// -pub fn new() -> Queue(a) { - Queue(in: [], out: []) -} - -/// Converts a list of elements into a queue of the same elements in the same -/// order. The first element in the list becomes the front element in the queue. -/// -/// This function runs in constant time. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2, 3] |> from_list |> length -/// 3 -/// ``` -/// -pub fn from_list(list: List(a)) -> Queue(a) { - Queue(in: [], out: list) -} - -/// Converts a queue of elements into a list of the same elements in the same -/// order. The front element in the queue becomes the first element in the list. -/// -/// This function runs in linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() |> push_back(1) |> push_back(2) |> to_list -/// [1, 2] -/// ``` -/// -pub fn to_list(queue: Queue(a)) -> List(a) { - queue.out - |> list.append(list.reverse(queue.in)) -} - -/// Determines whether or not the queue is empty. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> is_empty -/// False -/// ``` -/// -pub fn is_empty(queue: Queue(a)) -> Bool { - queue.in == [] && queue.out == [] -} - -/// Counts the number of elements in a given queue. -/// -/// This function has to traverse the queue to determine the number of elements, -/// so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length(from_list([])) -/// 0 -/// ``` -/// -/// ```gleam -/// > length(from_list([1])) -/// 1 -/// ``` -/// -/// ```gleam -/// > length(from_list([1, 2])) -/// 2 -/// ``` -/// -pub fn length(queue: Queue(a)) -> Int { - list.length(queue.in) + list.length(queue.out) -} - -/// Pushes an element onto the back of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [1, 2] |> from_list |> push_back(3) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn push_back(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: [item, ..queue.in], out: queue.out) -} - -/// Pushes an element onto the front of the queue. -/// -/// # Examples -/// -/// ```gleam -/// > [0, 0] |> from_list |> push_front(1) |> to_list -/// [1, 0, 0] -/// ``` -/// -pub fn push_front(onto queue: Queue(a), this item: a) -> Queue(a) { - Queue(in: queue.in, out: [item, ..queue.out]) -} - -/// Gets the last element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > new() -/// > |> push_back(0) -/// > |> push_back(1) -/// > |> pop_back() -/// Ok(#(1, push_front(new(), 0))) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> push_front(0) -/// > |> pop_back() -/// Ok(#(0, new())) -/// ``` -/// -/// ```gleam -/// > new() -/// > |> pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_back(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: [], out: out) -> pop_back(Queue(in: list.reverse(out), out: [])) - Queue(in: [first, ..rest], out: out) -> { - let queue = Queue(in: rest, out: out) - Ok(#(first, queue)) - } - } -} - -/// Gets the first element from the queue, returning the -/// element and a new queue without that element. -/// -/// This function typically runs in constant time, but will occasionally run in -/// linear time. -/// -/// # Examples -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_front(1) -/// > |> queue.push_front(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.push_back(queue.new(), 1))) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.push_back(0) -/// > |> queue.pop_front() -/// Ok(#(0, queue.new())) -/// ``` -/// -/// ```gleam -/// > queue.new() -/// > |> queue.pop_back() -/// Error(Nil) -/// ``` -/// -pub fn pop_front(from queue: Queue(a)) -> Result(#(a, Queue(a)), Nil) { - case queue { - Queue(in: [], out: []) -> Error(Nil) - Queue(in: in, out: []) -> pop_front(Queue(in: [], out: list.reverse(in))) - Queue(in: in, out: [first, ..rest]) -> { - let queue = Queue(in: in, out: rest) - Ok(#(first, queue)) - } - } -} - -/// Creates a new queue from a given queue containing the same elements, but in -/// the opposite order. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > [] |> from_list |> reverse |> to_list -/// [] -/// ``` -/// -/// ```gleam -/// > [1] |> from_list |> reverse |> to_list -/// [1] -/// ``` -/// -/// ```gleam -/// > [1, 2] |> from_list |> reverse |> to_list -/// [2, 1] -/// ``` -/// -pub fn reverse(queue: Queue(a)) -> Queue(a) { - Queue(in: queue.out, out: queue.in) -} - -fn check_equal( - xs: List(t), - x_tail: List(t), - ys: List(t), - y_tail: List(t), - eq: fn(t, t) -> Bool, -) -> Bool { - case xs, x_tail, ys, y_tail { - [], [], [], [] -> True - [x, ..xs], _, [y, ..ys], _ -> - case eq(x, y) { - False -> False - True -> check_equal(xs, x_tail, ys, y_tail, eq) - } - [], [_, ..], _, _ -> check_equal(list.reverse(x_tail), [], ys, y_tail, eq) - _, _, [], [_, ..] -> check_equal(xs, x_tail, list.reverse(y_tail), [], eq) - _, _, _, _ -> False - } -} - -/// Checks whether two queues have equal elements in the same order, where the -/// equality of elements is determined by a given equality checking function. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time multiplied by the time taken by the -/// element equality checking function. -/// -pub fn is_logically_equal( - a: Queue(t), - to b: Queue(t), - checking element_is_equal: fn(t, t) -> Bool, -) -> Bool { - check_equal(a.out, a.in, b.out, b.in, element_is_equal) -} - -/// Checks whether two queues have the same elements in the same order. -/// -/// This function is useful as the internal representation may be different for -/// two queues with the same elements in the same order depending on how they -/// were constructed, so the equality operator `==` may return surprising -/// results. -/// -/// This function runs in linear time. -/// -pub fn is_equal(a: Queue(t), to b: Queue(t)) -> Bool { - check_equal(a.out, a.in, b.out, b.in, fn(a, b) { a == b }) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam deleted file mode 100644 index 9ffda78..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/regex.gleam +++ /dev/null @@ -1,214 +0,0 @@ -//// This module contains regular expression matching functions for strings. -//// The matching algorithms of the library are based on the PCRE library, but not -//// all of the PCRE library is interfaced and some parts of the library go beyond -//// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. - -import gleam/option.{type Option} - -pub type Regex - -/// The details about a particular match: -/// -pub type Match { - Match( - /// The full string of the match. - content: String, - /// A `Regex` can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) -} - -/// When a regular expression fails to compile: -/// -pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - /// This value may not be correct in JavaScript environments. - byte_index: Int, - ) -} - -pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) -} - -/// Creates a `Regex` with some additional options. -/// -/// ## Examples -/// -/// ```gleam -/// > let options = Options(case_insensitive: False, multi_line: True) -/// > let assert Ok(re) = compile("^[0-9]", with: options) -/// > check(re, "abc\n123") -/// True -/// ``` -/// -/// ```gleam -/// > let options = Options(case_insensitive: True, multi_line: False) -/// > let assert Ok(re) = compile("[A-Z]", with: options) -/// > check(re, "abc123") -/// True -/// ``` -/// -pub fn compile( - pattern: String, - with options: Options, -) -> Result(Regex, CompileError) { - do_compile(pattern, options) -} - -@external(erlang, "gleam_stdlib", "compile_regex") -@external(javascript, "../gleam_stdlib.mjs", "compile_regex") -fn do_compile(a: String, with with: Options) -> Result(Regex, CompileError) - -/// Creates a new `Regex`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[0-9]") -/// > check(re, "abc123") -/// True -/// ``` -/// -/// ```gleam -/// > check(re, "abcxyz") -/// False -/// ``` -/// -/// ```gleam -/// > from_string("[0-9") -/// Error( -/// CompileError( -/// error: "missing terminating ] for character class", -/// byte_index: 4 -/// ) -/// ) -/// ``` -/// -pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) -} - -/// Returns a boolean indicating whether there was a match or not. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("^f.o.?") -/// > check(with: re, content: "foo") -/// True -/// ``` -/// -/// ```gleam -/// > check(with: re, content: "boo") -/// False -/// ``` -/// -pub fn check(with regex: Regex, content content: String) -> Bool { - do_check(regex, content) -} - -@external(erlang, "gleam_stdlib", "regex_check") -@external(javascript, "../gleam_stdlib.mjs", "regex_check") -fn do_check(a: Regex, b: String) -> Bool - -/// Splits a string. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string(" *, *") -/// > split(with: re, content: "foo,32, 4, 9 ,0") -/// ["foo", "32", "4", "9", "0"] -/// ``` -/// -pub fn split(with regex: Regex, content string: String) -> List(String) { - do_split(regex, string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "regex_split") -fn do_split(a: Regex, b: String) -> List(String) - -@target(javascript) -fn do_split(regex, string) -> List(String) { - js_split(string, regex) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn js_split(a: String, b: Regex) -> List(String) - -/// Collects all matches of the regular expression. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(re) = from_string("[oi]n a (\\w+)") -/// > scan(with: re, content: "I am on a boat in a lake.") -/// [ -/// Match( -/// content: "on a boat", -/// submatches: [Some("boat")] -/// ), -/// Match( -/// content: "in a lake", -/// submatches: [Some("lake")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("([+|\\-])?(\\d+)(\\w+)?") -/// > scan(with: re, content: "-36") -/// [ -/// Match( -/// content: "-36", -/// submatches: [Some("-"), Some("36")] -/// ) -/// ] -/// -/// > scan(with: re, content: "36") -/// [ -/// Match( -/// content: "36", -/// submatches: [None, Some("36")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("var\\s*(\\w+)\\s*(int|string)?\\s*=\\s*(.*)") -/// > scan(with: re, content: "var age = 32") -/// [ -/// Match( -/// content: "var age = 32", -/// submatches: [Some("age"), None, Some("32")] -/// ) -/// ] -/// ``` -/// -/// ```gleam -/// > let assert Ok(re) = regex.from_string("let (\\w+) = (\\w+)") -/// > scan(with: re, content: "let age = 32") -/// [ -/// Match( -/// content: "let age = 32", -/// submatches: [Some("age"), Some("32")] -/// ) -/// ] -/// -/// > scan(with: re, content: "const age = 32") -/// [] -/// ``` -/// -pub fn scan(with regex: Regex, content string: String) -> List(Match) { - do_scan(regex, string) -} - -@external(erlang, "gleam_stdlib", "regex_scan") -@external(javascript, "../gleam_stdlib.mjs", "regex_scan") -fn do_scan(a: Regex, b: String) -> List(Match) diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam deleted file mode 100644 index fb6dddb..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/result.gleam +++ /dev/null @@ -1,482 +0,0 @@ -//// Result represents the result of something that may succeed or not. -//// `Ok` means it was successful, `Error` means it was not successful. - -import gleam/list - -/// Checks whether the result is an `Ok` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_ok(Ok(1)) -/// True -/// ``` -/// -/// ```gleam -/// > is_ok(Error(Nil)) -/// False -/// ``` -/// -pub fn is_ok(result: Result(a, e)) -> Bool { - case result { - Error(_) -> False - Ok(_) -> True - } -} - -/// Checks whether the result is an `Error` value. -/// -/// ## Examples -/// -/// ```gleam -/// > is_error(Ok(1)) -/// False -/// ``` -/// -/// ```gleam -/// > is_error(Error(Nil)) -/// True -/// ``` -/// -pub fn is_error(result: Result(a, e)) -> Bool { - case result { - Ok(_) -> False - Error(_) -> True - } -} - -/// Updates a value held within the `Ok` of a result by calling a given function -/// on it. -/// -/// If the result is an `Error` rather than `Ok` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > map(over: Error(1), with: fn(x) { x + 1 }) -/// Error(1) -/// ``` -/// -pub fn map(over result: Result(a, e), with fun: fn(a) -> b) -> Result(b, e) { - case result { - Ok(x) -> Ok(fun(x)) - Error(e) -> Error(e) - } -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it. -/// -/// If the result is `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// ## Examples -/// -/// ```gleam -/// > map_error(over: Error(1), with: fn(x) { x + 1 }) -/// Error(2) -/// ``` -/// -/// ```gleam -/// > map_error(over: Ok(1), with: fn(x) { x + 1 }) -/// Ok(1) -/// ``` -/// -pub fn map_error( - over result: Result(a, e), - with fun: fn(e) -> f, -) -> Result(a, f) { - case result { - Ok(x) -> Ok(x) - Error(error) -> Error(fun(error)) - } -} - -/// Merges a nested `Result` into a single layer. -/// -/// ## Examples -/// -/// ```gleam -/// > flatten(Ok(Ok(1))) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > flatten(Ok(Error(""))) -/// Error("") -/// ``` -/// -/// ```gleam -/// > flatten(Error(Nil)) -/// Error(Nil) -/// ``` -/// -pub fn flatten(result: Result(Result(a, e), e)) -> Result(a, e) { - case result { - Ok(x) -> x - Error(error) -> Error(error) - } -} - -/// "Updates" an `Ok` result by passing its value to a function that yields a result, -/// and returning the yielded result. (This may "replace" the `Ok` with an `Error`.) -/// -/// If the input is an `Error` rather than an `Ok`, the function is not called and -/// the original `Error` is returned. -/// -/// This function is the equivalent of calling `map` followed by `flatten`, and -/// it is useful for chaining together multiple functions that may fail. -/// -/// ## Examples -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(x + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(x) { Ok(#("a", x)) }) -/// Ok(#("a", 1)) -/// ``` -/// -/// ```gleam -/// > try(Ok(1), fn(_) { Error("Oh no") }) -/// Error("Oh no") -/// ``` -/// -/// ```gleam -/// > try(Error(Nil), fn(x) { Ok(x + 1) }) -/// Error(Nil) -/// ``` -/// -pub fn try( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - case result { - Ok(x) -> fun(x) - Error(e) -> Error(e) - } -} - -/// An alias for `try`. See the documentation for that function for more information. -/// -pub fn then( - result: Result(a, e), - apply fun: fn(a) -> Result(b, e), -) -> Result(b, e) { - try(result, fun) -} - -/// Extracts the `Ok` value from a result, returning a default value if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap(Ok(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap(Error(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap(result: Result(a, e), or default: a) -> a { - case result { - Ok(v) -> v - Error(_) -> default - } -} - -/// Extracts the `Ok` value from a result, evaluating the default function if the result -/// is an `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_unwrap(Ok(1), fn() { 0 }) -/// 1 -/// ``` -/// -/// ```gleam -/// > lazy_unwrap(Error(""), fn() { 0 }) -/// 0 -/// ``` -/// -pub fn lazy_unwrap(result: Result(a, e), or default: fn() -> a) -> a { - case result { - Ok(v) -> v - Error(_) -> default() - } -} - -/// Extracts the `Error` value from a result, returning a default value if the result -/// is an `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_error(Error(1), 0) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_error(Ok(""), 0) -/// 0 -/// ``` -/// -pub fn unwrap_error(result: Result(a, e), or default: e) -> e { - case result { - Ok(_) -> default - Error(e) -> e - } -} - -/// Extracts the inner value from a result. Both the value and error must be of -/// the same type. -/// -/// ## Examples -/// -/// ```gleam -/// > unwrap_both(Error(1)) -/// 1 -/// ``` -/// -/// ```gleam -/// > unwrap_both(Ok(2)) -/// 2 -/// ``` -/// -pub fn unwrap_both(result: Result(a, a)) -> a { - case result { - Ok(a) -> a - Error(a) -> a - } -} - -/// Transforms any error into `Error(Nil)`. -/// -/// ## Examples -/// -/// ```gleam -/// > nil_error(Error(1)) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > nil_error(Ok(1)) -/// Ok(1) -/// ``` -/// -pub fn nil_error(result: Result(a, e)) -> Result(a, Nil) { - map_error(result, fn(_) { Nil }) -} - -/// Returns the first value if it is `Ok`, otherwise returns the second value. -/// -/// ## Examples -/// -/// ```gleam -/// > or(Ok(1), Ok(2)) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Ok(1), Error("Error 2")) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Ok(2)) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > or(Error("Error 1"), Error("Error 2")) -/// Error("Error 2") -/// ``` -/// -pub fn or(first: Result(a, e), second: Result(a, e)) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second - } -} - -/// Returns the first value if it is `Ok`, otherwise evaluates the given function for a fallback value. -/// -/// ## Examples -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Ok(2) }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Ok(1), fn() { Error("Error 2") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Ok(2) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > lazy_or(Error("Error 1"), fn() { Error("Error 2") }) -/// Error("Error 2") -/// ``` -/// -pub fn lazy_or( - first: Result(a, e), - second: fn() -> Result(a, e), -) -> Result(a, e) { - case first { - Ok(_) -> first - Error(_) -> second() - } -} - -/// Combines a list of results into a single result. -/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values. -/// If any element is `Error` then returns the first error. -/// -/// ## Examples -/// -/// ```gleam -/// > all([Ok(1), Ok(2)]) -/// Ok([1, 2]) -/// ``` -/// -/// ```gleam -/// > all([Ok(1), Error("e")]) -/// Error("e") -/// ``` -/// -pub fn all(results: List(Result(a, e))) -> Result(List(a), e) { - list.try_map(results, fn(x) { x }) -} - -/// Given a list of results, returns a pair where the first element is a list -/// of all the values inside `Ok` and the second element is a list with all the -/// values inside `Error`. The values in both lists appear in reverse order with -/// respect to their position in the original list of results. -/// -/// ## Examples -/// -/// ```gleam -/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)]) -/// #([2, 1], ["b", "a"]) -/// ``` -/// -pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) { - do_partition(results, [], []) -} - -fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) { - case results { - [] -> #(oks, errors) - [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors) - [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors]) - } -} - -/// Replace the value within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace(Ok(1), Nil) -/// Ok(Nil) -/// ``` -/// -/// ```gleam -/// > replace(Error(1), Nil) -/// Error(1) -/// ``` -/// -pub fn replace(result: Result(a, e), value: b) -> Result(b, e) { - case result { - Ok(_) -> Ok(value) - Error(error) -> Error(error) - } -} - -/// Replace the error within a result -/// -/// ## Examples -/// -/// ```gleam -/// > replace_error(Error(1), Nil) -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > replace_error(Ok(1), Nil) -/// Ok(1) -/// ``` -/// -pub fn replace_error(result: Result(a, e1), error: e2) -> Result(a, e2) { - case result { - Ok(x) -> Ok(x) - Error(_) -> Error(error) - } -} - -/// Given a list of results, returns only the values inside `Ok`. -/// -/// ## Examples -/// -/// ```gleam -/// > values([Ok(1), Error("a"), Ok(3)]) -/// [1, 3] -/// ``` -/// -pub fn values(results: List(Result(a, e))) -> List(a) { - list.filter_map(results, fn(r) { r }) -} - -/// Updates a value held within the `Error` of a result by calling a given function -/// on it, where the given function also returns a result. The two results are -/// then merged together into one result. -/// -/// If the result is an `Ok` rather than `Error` the function is not called and the -/// result stays the same. -/// -/// This function is useful for chaining together computations that may fail -/// and trying to recover from possible errors. -/// -/// ## Examples -/// -/// ```gleam -/// > Ok(1) |> try_recover(with: fn(_) { Error("failed to recover") }) -/// Ok(1) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Ok(error + 1) }) -/// Ok(2) -/// ``` -/// -/// ```gleam -/// > Error(1) |> try_recover(with: fn(error) { Error("failed to recover") }) -/// Error("failed to recover") -/// ``` -/// -pub fn try_recover( - result: Result(a, e), - with fun: fn(e) -> Result(a, f), -) -> Result(a, f) { - case result { - Ok(value) -> Ok(value) - Error(error) -> fun(error) - } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam deleted file mode 100644 index df8d500..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/set.gleam +++ /dev/null @@ -1,264 +0,0 @@ -import gleam/list -import gleam/dict.{type Dict} -import gleam/result - -// A list is used as the map value as an empty list has the smallest -// representation in Erlang's binary format -@target(erlang) -type Token = - List(Nil) - -@target(erlang) -const token = [] - -@target(javascript) -type Token = - Nil - -@target(javascript) -const token = Nil - -/// A set is a collection of unique members of the same type. -/// -/// It is implemented using the `gleam/map` module, so inserts and lookups have -/// logarithmic time complexity. -/// -pub opaque type Set(member) { - Set(map: Dict(member, Token)) -} - -/// Creates a new empty set. -/// -pub fn new() -> Set(member) { - Set(dict.new()) -} - -/// Gets the number of members in a set. -/// -/// This function runs in constant time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn size(set: Set(member)) -> Int { - dict.size(set.map) -} - -/// Inserts an member into the set. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(1) -/// > |> insert(2) -/// > |> size -/// 2 -/// ``` -/// -pub fn insert(into set: Set(member), this member: member) -> Set(member) { - Set(map: dict.insert(set.map, member, token)) -} - -/// Checks whether a set contains a given member. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(2) -/// True -/// ``` -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn contains(in set: Set(member), this member: member) -> Bool { - set.map - |> dict.get(member) - |> result.is_ok -} - -/// Removes a member from a set. If the set does not contain the member then -/// the set is returned unchanged. -/// -/// This function runs in logarithmic time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() -/// > |> insert(2) -/// > |> delete(2) -/// > |> contains(1) -/// False -/// ``` -/// -pub fn delete(from set: Set(member), this member: member) -> Set(member) { - Set(map: dict.delete(set.map, member)) -} - -/// Converts the set into a list of the contained members. -/// -/// The list has no specific ordering, any unintentional ordering may change in -/// future versions of Gleam or Erlang. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > new() |> insert(2) |> to_list -/// [2] -/// ``` -/// -pub fn to_list(set: Set(member)) -> List(member) { - dict.keys(set.map) -} - -/// Creates a new set of the members in a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/list -/// > [1, 1, 2, 4, 3, 2] |> from_list |> to_list |> list.sort -/// [1, 3, 3, 4] -/// ``` -/// -pub fn from_list(members: List(member)) -> Set(member) { - let map = - list.fold( - over: members, - from: dict.new(), - with: fn(m, k) { dict.insert(m, k, token) }, - ) - Set(map) -} - -/// Combines all entries into a single value by calling a given function on each -/// one. -/// -/// Sets are not ordered so the values are not returned in any specific order. -/// Do not write code that relies on the order entries are used by this -/// function as it may change in later versions of Gleam or Erlang. -/// -/// # Examples -/// -/// ```gleam -/// > from_list([1, 3, 9]) -/// > |> fold(0, fn(member, accumulator) { accumulator + member }) -/// 13 -/// ``` -/// -pub fn fold( - over set: Set(member), - from initial: acc, - with reducer: fn(acc, member) -> acc, -) -> acc { - dict.fold(over: set.map, from: initial, with: fn(a, k, _) { reducer(a, k) }) -} - -/// Creates a new set from an existing set, minus any members that a given -/// function returns `False` for. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > import gleam/int -/// > from_list([1, 4, 6, 3, 675, 44, 67]) -/// > |> filter(for: int.is_even) -/// > |> to_list -/// [4, 6, 44] -/// ``` -/// -pub fn filter( - in set: Set(member), - keeping predicate: fn(member) -> Bool, -) -> Set(member) { - Set(dict.filter(in: set.map, keeping: fn(m, _) { predicate(m) })) -} - -pub fn drop(from set: Set(member), drop disallowed: List(member)) -> Set(member) { - list.fold(over: disallowed, from: set, with: delete) -} - -/// Creates a new map from a given map, only including any members which are in -/// a given list. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > from_list([1, 2, 3]) -/// > |> take([1, 3, 5]) -/// > |> to_list -/// [1, 3] -/// ``` -/// -pub fn take(from set: Set(member), keeping desired: List(member)) -> Set(member) { - Set(dict.take(from: set.map, keeping: desired)) -} - -fn order(first: Set(member), second: Set(member)) -> #(Set(member), Set(member)) { - case dict.size(first.map) > dict.size(second.map) { - True -> #(first, second) - False -> #(second, first) - } -} - -/// Creates a new set that contains all members of both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > union(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [1, 2, 3] -/// ``` -/// -pub fn union(of first: Set(member), and second: Set(member)) -> Set(member) { - let #(larger, smaller) = order(first, second) - fold(over: smaller, from: larger, with: insert) -} - -/// Creates a new set that contains members that are present in both given sets. -/// -/// This function runs in loglinear time. -/// -/// ## Examples -/// -/// ```gleam -/// > intersection(from_list([1, 2]), from_list([2, 3])) |> to_list -/// [2] -/// ``` -/// -pub fn intersection( - of first: Set(member), - and second: Set(member), -) -> Set(member) { - let #(larger, smaller) = order(first, second) - take(from: larger, keeping: to_list(smaller)) -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam deleted file mode 100644 index d4496f3..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/string.gleam +++ /dev/null @@ -1,906 +0,0 @@ -//// Strings in Gleam are UTF-8 binaries. They can be written in your code as -//// text surrounded by `"double quotes"`. - -import gleam/iterator.{type Iterator} -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/order -import gleam/string_builder.{type StringBuilder} - -/// Determines if a `String` is empty. -/// -/// ## Examples -/// -/// ```gleam -/// > is_empty("") -/// True -/// ``` -/// -/// ```gleam -/// > is_empty("the world") -/// False -/// ``` -/// -pub fn is_empty(str: String) -> Bool { - str == "" -} - -/// Gets the number of grapheme clusters in a given `String`. -/// -/// This function has to iterate across the whole string to count the number of -/// graphemes, so it runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > length("Gleam") -/// 5 -/// ``` -/// -/// ```gleam -/// > length("ß↑e̊") -/// 3 -/// ``` -/// -/// ```gleam -/// > length("") -/// 0 -/// ``` -/// -pub fn length(string: String) -> Int { - do_length(string) -} - -@external(erlang, "string", "length") -@external(javascript, "../gleam_stdlib.mjs", "string_length") -fn do_length(a: String) -> Int - -/// Reverses a `String`. -/// -/// This function has to iterate across the whole `String` so it runs in linear -/// time. -/// -/// ## Examples -/// -/// ```gleam -/// > reverse("stressed") -/// "desserts" -/// ``` -/// -pub fn reverse(string: String) -> String { - do_reverse(string) -} - -@target(erlang) -fn do_reverse(string: String) -> String { - string - |> string_builder.from_string - |> string_builder.reverse - |> string_builder.to_string -} - -@target(javascript) -fn do_reverse(string: String) -> String { - string - |> to_graphemes - |> list.reverse - |> concat -} - -/// Creates a new `String` by replacing all occurrences of a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > replace("www.example.com", each: ".", with: "-") -/// "www-example-com" -/// ``` -/// -/// ```gleam -/// > replace("a,b,c,d,e", each: ",", with: "/") -/// "a/b/c/d/e" -/// ``` -/// -pub fn replace( - in string: String, - each pattern: String, - with substitute: String, -) -> String { - string - |> string_builder.from_string - |> string_builder.replace(each: pattern, with: substitute) - |> string_builder.to_string -} - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// lowercase. -/// -/// Useful for case-insensitive comparisons. -/// -/// ## Examples -/// -/// ```gleam -/// > lowercase("X-FILES") -/// "x-files" -/// ``` -/// -pub fn lowercase(string: String) -> String { - do_lowercase(string) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: String) -> String - -/// Creates a new `String` with all the graphemes in the input `String` converted to -/// uppercase. -/// -/// Useful for case-insensitive comparisons and VIRTUAL YELLING. -/// -/// ## Examples -/// -/// ```gleam -/// > uppercase("skinner") -/// "SKINNER" -/// ``` -/// -pub fn uppercase(string: String) -> String { - do_uppercase(string) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: String) -> String - -/// Compares two `String`s to see which is "larger" by comparing their graphemes. -/// -/// This does not compare the size or length of the given `String`s. -/// -/// ## Examples -/// -/// ```gleam -/// > compare("Anthony", "Anthony") -/// order.Eq -/// ``` -/// -/// ```gleam -/// > compare("A", "B") -/// order.Lt -/// ``` -/// -pub fn compare(a: String, b: String) -> order.Order { - case a == b { - True -> order.Eq - _ -> - case less_than(a, b) { - True -> order.Lt - _ -> order.Gt - } - } -} - -@external(erlang, "gleam_stdlib", "less_than") -@external(javascript, "../gleam_stdlib.mjs", "less_than") -fn less_than(a: String, b: String) -> Bool - -/// Takes a substring given a start grapheme index and a length. Negative indexes -/// are taken starting from the *end* of the list. -/// -/// ## Examples -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 2) -/// "le" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 1, length: 10) -/// "leam" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: 10, length: 3) -/// "" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -2, length: 2) -/// "am" -/// ``` -/// -/// ```gleam -/// > slice(from: "gleam", at_index: -12, length: 2) -/// "" -/// ``` -/// -pub fn slice(from string: String, at_index idx: Int, length len: Int) -> String { - case len < 0 { - True -> "" - False -> - case idx < 0 { - True -> { - let translated_idx = length(string) + idx - case translated_idx < 0 { - True -> "" - False -> do_slice(string, translated_idx, len) - } - } - False -> do_slice(string, idx, len) - } - } -} - -@target(erlang) -@external(erlang, "string", "slice") -fn do_slice(a: String, b: Int, c: Int) -> String - -@target(javascript) -fn do_slice(string: String, idx: Int, len: Int) -> String { - string - |> to_graphemes - |> list.drop(idx) - |> list.take(len) - |> concat -} - -/// Drops contents of the first `String` that occur before the second `String`. -/// If the `from` string does not contain the `before` string, `from` is returned unchanged. -/// -/// ## Examples -/// -/// ```gleam -/// > crop(from: "The Lone Gunmen", before: "Lone") -/// "Lone Gunmen" -/// ``` -/// -@external(erlang, "gleam_stdlib", "crop_string") -@external(javascript, "../gleam_stdlib.mjs", "crop_string") -pub fn crop(from string: String, before substring: String) -> String - -/// Drops *n* graphemes from the left side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_left(from: "The Lone Gunmen", up_to: 2) -/// "e Lone Gunmen" -/// ``` -/// -pub fn drop_left(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, num_graphemes, length(string) - num_graphemes) - } -} - -/// Drops *n* graphemes from the right side of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > drop_right(from: "Cigarette Smoking Man", up_to: 2) -/// "Cigarette Smoking M" -/// ``` -/// -pub fn drop_right(from string: String, up_to num_graphemes: Int) -> String { - case num_graphemes < 0 { - True -> string - False -> slice(string, 0, length(string) - num_graphemes) - } -} - -/// Checks if the first `String` contains the second. -/// -/// ## Examples -/// -/// ```gleam -/// > contains(does: "theory", contain: "ory") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "the") -/// True -/// ``` -/// -/// ```gleam -/// > contains(does: "theory", contain: "THE") -/// False -/// ``` -/// -@external(erlang, "gleam_stdlib", "contains_string") -@external(javascript, "../gleam_stdlib.mjs", "contains_string") -pub fn contains(does haystack: String, contain needle: String) -> Bool - -/// Checks whether the first `String` starts with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > starts_with("theory", "ory") -/// False -/// ``` -/// -pub fn starts_with(string: String, prefix: String) -> Bool { - do_starts_with(string, prefix) -} - -@external(erlang, "gleam_stdlib", "string_starts_with") -@external(javascript, "../gleam_stdlib.mjs", "starts_with") -fn do_starts_with(a: String, b: String) -> Bool - -/// Checks whether the first `String` ends with the second one. -/// -/// ## Examples -/// -/// ```gleam -/// > ends_with("theory", "ory") -/// True -/// ``` -/// -pub fn ends_with(string: String, suffix: String) -> Bool { - do_ends_with(string, suffix) -} - -@external(erlang, "gleam_stdlib", "string_ends_with") -@external(javascript, "../gleam_stdlib.mjs", "ends_with") -fn do_ends_with(a: String, b: String) -> Bool - -/// Creates a list of `String`s by splitting a given string on a given substring. -/// -/// ## Examples -/// -/// ```gleam -/// > split("home/gleam/desktop/", on: "/") -/// ["home", "gleam", "desktop", ""] -/// ``` -/// -pub fn split(x: String, on substring: String) -> List(String) { - case substring { - "" -> to_graphemes(x) - _ -> - x - |> string_builder.from_string - |> string_builder.split(on: substring) - |> list.map(with: string_builder.to_string) - } -} - -/// Splits a `String` a single time on the given substring. -/// -/// Returns an `Error` if substring not present. -/// -/// ## Examples -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "/") -/// Ok(#("home", "gleam/desktop/")) -/// ``` -/// -/// ```gleam -/// > split_once("home/gleam/desktop/", on: "?") -/// Error(Nil) -/// ``` -/// -pub fn split_once( - x: String, - on substring: String, -) -> Result(#(String, String), Nil) { - do_split_once(x, substring) -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: String, b: String) -> List(String) - -@target(erlang) -fn do_split_once(x: String, substring: String) -> Result(#(String, String), Nil) { - case erl_split(x, substring) { - [first, rest] -> Ok(#(first, rest)) - _ -> Error(Nil) - } -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split_once") -fn do_split_once( - x x: String, - substring substring: String, -) -> Result(#(String, String), Nil) - -/// Creates a new `String` by joining two `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > append(to: "butter", suffix: "fly") -/// "butterfly" -/// ``` -/// -pub fn append(to first: String, suffix second: String) -> String { - first - |> string_builder.from_string - |> string_builder.append(second) - |> string_builder.to_string -} - -/// Creates a new `String` by joining many `String`s together. -/// -/// This function copies both `String`s and runs in linear time. If you find -/// yourself joining `String`s frequently consider using the [`string_builder`](../gleam/string_builder.html) -/// module as it can append `String`s much faster! -/// -/// ## Examples -/// -/// ```gleam -/// > concat(["never", "the", "less"]) -/// "nevertheless" -/// ``` -/// -pub fn concat(strings: List(String)) -> String { - strings - |> string_builder.from_strings - |> string_builder.to_string -} - -/// Creates a new `String` by repeating a `String` a given number of times. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > repeat("ha", times: 3) -/// "hahaha" -/// ``` -/// -pub fn repeat(string: String, times times: Int) -> String { - iterator.repeat(string) - |> iterator.take(times) - |> iterator.to_list - |> concat -} - -/// Joins many `String`s together with a given separator. -/// -/// This function runs in linear time. -/// -/// ## Examples -/// -/// ```gleam -/// > join(["home","evan","Desktop"], with: "/") -/// "home/evan/Desktop" -/// ``` -/// -pub fn join(strings: List(String), with separator: String) -> String { - do_join(strings, separator) -} - -@target(erlang) -fn do_join(strings: List(String), separator: String) -> String { - strings - |> list.intersperse(with: separator) - |> concat -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "join") -fn do_join(strings strings: List(String), string string: String) -> String - -/// Pads a `String` on the left until it has at least given number of graphemes. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_left("121", to: 5, with: ".") -/// "..121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 3, with: ".") -/// "121" -/// ``` -/// -/// ```gleam -/// > pad_left("121", to: 2, with: ".") -/// "121" -/// ``` -/// -pub fn pad_left(string: String, to desired_length: Int, with pad_string: String) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - padding(to_pad_length, pad_string) - |> iterator.append(iterator.single(string)) - |> iterator.to_list - |> concat -} - -/// Pads a `String` on the right until it has a given length. -/// -/// ## Examples -/// -/// ```gleam -/// > pad_right("123", to: 5, with: ".") -/// "123.." -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 3, with: ".") -/// "123" -/// ``` -/// -/// ```gleam -/// > pad_right("123", to: 2, with: ".") -/// "123" -/// ``` -/// -pub fn pad_right( - string: String, - to desired_length: Int, - with pad_string: String, -) { - let current_length = length(string) - let to_pad_length = desired_length - current_length - iterator.single(string) - |> iterator.append(padding(to_pad_length, pad_string)) - |> iterator.to_list - |> concat -} - -fn padding(size: Int, pad_string: String) -> Iterator(String) { - let pad_length = length(pad_string) - let num_pads = size / pad_length - let extra = size % pad_length - iterator.repeat(pad_string) - |> iterator.take(num_pads) - |> iterator.append(iterator.single(slice(pad_string, 0, extra))) -} - -/// Removes whitespace on both sides of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim(" hats \n") -/// "hats" -/// ``` -/// -pub fn trim(string: String) -> String { - do_trim(string) -} - -@target(erlang) -fn do_trim(string: String) -> String { - erl_trim(string, Both) -} - -@target(erlang) -type Direction { - Leading - Trailing - Both -} - -@target(erlang) -@external(erlang, "string", "trim") -fn erl_trim(a: String, b: Direction) -> String - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim") -fn do_trim(string string: String) -> String - -/// Removes whitespace on the left of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_left(" hats \n") -/// "hats \n" -/// ``` -/// -pub fn trim_left(string: String) -> String { - do_trim_left(string) -} - -@target(erlang) -fn do_trim_left(string: String) -> String { - erl_trim(string, Leading) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_left") -fn do_trim_left(string string: String) -> String - -/// Removes whitespace on the right of a `String`. -/// -/// ## Examples -/// -/// ```gleam -/// > trim_right(" hats \n") -/// " hats" -/// ``` -/// -pub fn trim_right(string: String) -> String { - do_trim_right(string) -} - -@target(erlang) -fn do_trim_right(string: String) -> String { - erl_trim(string, Trailing) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "trim_right") -fn do_trim_right(string string: String) -> String - -/// Splits a non-empty `String` into its first element (head) and rest (tail). -/// This lets you pattern match on `String`s exactly as you would with lists. -/// -/// Note on JavaScript using the function to iterate over a string will likely -/// be slower than using `to_graphemes` due to string slicing being more -/// expensive on JavaScript than Erlang. -/// -/// ## Examples -/// -/// ```gleam -/// > pop_grapheme("gleam") -/// Ok(#("g", "leam")) -/// ``` -/// -/// ```gleam -/// > pop_grapheme("") -/// Error(Nil) -/// ``` -/// -pub fn pop_grapheme(string: String) -> Result(#(String, String), Nil) { - do_pop_grapheme(string) -} - -@external(erlang, "gleam_stdlib", "string_pop_grapheme") -@external(javascript, "../gleam_stdlib.mjs", "pop_grapheme") -fn do_pop_grapheme(string string: String) -> Result(#(String, String), Nil) - -/// Converts a `String` to a list of -/// [graphemes](https://en.wikipedia.org/wiki/Grapheme). -/// -/// ```gleam -/// > to_graphemes("abc") -/// ["a", "b", "c"] -/// ``` -/// -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -pub fn to_graphemes(string: String) -> List(String) { - do_to_graphemes(string, []) - |> list.reverse -} - -fn do_to_graphemes(string: String, acc: List(String)) -> List(String) { - case pop_grapheme(string) { - Ok(#(grapheme, rest)) -> do_to_graphemes(rest, [grapheme, ..acc]) - _ -> acc - } -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "codepoint") -fn unsafe_int_to_utf_codepoint(a: Int) -> UtfCodepoint - -/// Converts a `String` to a `List` of `UtfCodepoint`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > "a" |> to_utf_codepoints -/// [UtfCodepoint(97)] -/// ``` -/// -/// ```gleam -/// // Semantically the same as: -/// // ["🏳", "️", "", "🌈"] or: -/// // [waving_white_flag, variant_selector_16, zero_width_joiner, rainbow] -/// > "🏳️🌈" |> to_utf_codepoints -/// [UtfCodepoint(127987), UtfCodepoint(65039), UtfCodepoint(8205), UtfCodepoint(127752)] -/// ``` -/// -pub fn to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints(string) -} - -@target(erlang) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - do_to_utf_codepoints_impl(<<string:utf8>>, []) - |> list.reverse -} - -@target(erlang) -fn do_to_utf_codepoints_impl( - bit_array: BitArray, - acc: List(UtfCodepoint), -) -> List(UtfCodepoint) { - case bit_array { - <<first:utf8_codepoint, rest:bytes>> -> - do_to_utf_codepoints_impl(rest, [first, ..acc]) - _ -> acc - } -} - -@target(javascript) -fn do_to_utf_codepoints(string: String) -> List(UtfCodepoint) { - string - |> string_to_codepoint_integer_list - |> list.map(unsafe_int_to_utf_codepoint) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_to_codepoint_integer_list") -fn string_to_codepoint_integer_list(a: String) -> List(Int) - -/// Converts a `List` of `UtfCodepoint`s to a `String`. -/// -/// See <https://en.wikipedia.org/wiki/Code_point> and -/// <https://en.wikipedia.org/wiki/Unicode#Codespace_and_Code_Points> for an -/// explanation on code points. -/// -/// ## Examples -/// -/// ```gleam -/// > { -/// > let assert #(Ok(a), Ok(b), Ok(c)) = #( -/// > utf_codepoint(97), -/// > utf_codepoint(98), -/// > utf_codepoint(99), -/// > ) -/// > [a, b, c] -/// > } -/// > |> from_utf_codepoints -/// "abc" -/// ``` -/// -@external(erlang, "gleam_stdlib", "utf_codepoint_list_to_string") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_list_to_string") -pub fn from_utf_codepoints(utf_codepoints: List(UtfCodepoint)) -> String - -/// Converts an integer to a `UtfCodepoint`. -/// -/// Returns an `Error` if the integer does not represent a valid UTF codepoint. -/// -pub fn utf_codepoint(value: Int) -> Result(UtfCodepoint, Nil) { - case value { - i if i > 1_114_111 -> Error(Nil) - 65_534 | 65_535 -> Error(Nil) - i if i >= 55_296 && i <= 57_343 -> Error(Nil) - i -> Ok(unsafe_int_to_utf_codepoint(i)) - } -} - -/// Converts an UtfCodepoint to its ordinal code point value. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert [utf_codepoint, ..] = to_utf_codepoints("💜") -/// > utf_codepoint_to_int(utf_codepoint) -/// 128156 -/// ``` -/// -pub fn utf_codepoint_to_int(cp: UtfCodepoint) -> Int { - do_utf_codepoint_to_int(cp) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "utf_codepoint_to_int") -fn do_utf_codepoint_to_int(cp cp: UtfCodepoint) -> Int - -/// Converts a `String` into `Option(String)` where an empty `String` becomes -/// `None`. -/// -/// ## Examples -/// -/// ```gleam -/// > to_option("") -/// None -/// ``` -/// -/// ```gleam -/// > to_option("hats") -/// Some("hats") -/// ``` -/// -pub fn to_option(s: String) -> Option(String) { - case s { - "" -> None - _ -> Some(s) - } -} - -/// Returns the first grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > first("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > first("icecream") -/// Ok("i") -/// ``` -/// -pub fn first(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, _)) -> Ok(first) - Error(e) -> Error(e) - } -} - -/// Returns the last grapheme cluster in a given `String` and wraps it in a -/// `Result(String, Nil)`. If the `String` is empty, it returns `Error(Nil)`. -/// Otherwise, it returns `Ok(String)`. -/// -/// ## Examples -/// -/// ```gleam -/// > last("") -/// Error(Nil) -/// ``` -/// -/// ```gleam -/// > last("icecream") -/// Ok("m") -/// ``` -/// -pub fn last(s: String) -> Result(String, Nil) { - case pop_grapheme(s) { - Ok(#(first, "")) -> Ok(first) - Ok(#(_, rest)) -> Ok(slice(rest, -1, 1)) - Error(e) -> Error(e) - } -} - -/// Creates a new `String` with the first grapheme in the input `String` -/// converted to uppercase and the remaining graphemes to lowercase. -/// -/// ## Examples -/// -/// ```gleam -/// > capitalise("mamouna") -/// "Mamouna" -/// ``` -/// -pub fn capitalise(s: String) -> String { - case pop_grapheme(s) { - Ok(#(first, rest)) -> append(to: uppercase(first), suffix: lowercase(rest)) - _ -> "" - } -} - -/// Returns a `String` representation of a term in Gleam syntax. -/// -pub fn inspect(term: anything) -> String { - do_inspect(term) - |> string_builder.to_string -} - -@external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam_stdlib.mjs", "inspect") -fn do_inspect(term term: anything) -> StringBuilder - -/// Returns the number of bytes in a `String`. -/// -/// This function runs in constant time on Erlang and in linear time on -/// JavaScript. -/// -@external(erlang, "erlang", "byte_size") -@external(javascript, "../gleam_stdlib.mjs", "byte_size") -pub fn byte_size(string: String) -> Int diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam deleted file mode 100644 index 5792ca8..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/string_builder.gleam +++ /dev/null @@ -1,298 +0,0 @@ -import gleam/list - -/// `StringBuilder` is a type used for efficiently building strings. -/// -/// When we append one string to another the strings must be copied to a -/// new location in memory so that they can sit together. This behaviour -/// enables efficient reading of the string but copying can be expensive, -/// especially if we want to join many strings together. -/// -/// `StringBuilder` is different in that it can be joined together in constant time -/// using minimal memory, and then can be efficiently converted to a string -/// using the `to_string` function. -/// -/// On Erlang this type is compatible with Erlang's iodata. On JavaScript this -/// type is compatible with normal strings. -/// -pub type StringBuilder - -/// Create an empty `StringBuilder`. Useful as the start of a pipe chaining many -/// builders together. -/// -pub fn new() -> StringBuilder { - do_from_strings([]) -} - -/// Prepends a `String` onto the start of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn prepend( - to builder: StringBuilder, - prefix prefix: String, -) -> StringBuilder { - append_builder(from_string(prefix), builder) -} - -/// Appends a `String` onto the end of some `StringBuilder`. -/// -/// Runs in constant time. -/// -pub fn append(to builder: StringBuilder, suffix second: String) -> StringBuilder { - append_builder(builder, from_string(second)) -} - -/// Prepends some `StringBuilder` onto the start of another. -/// -/// Runs in constant time. -/// -pub fn prepend_builder( - to builder: StringBuilder, - prefix prefix: StringBuilder, -) -> StringBuilder { - do_append(prefix, builder) -} - -/// Appends some `StringBuilder` onto the end of another. -/// -/// Runs in constant time. -/// -pub fn append_builder( - to builder: StringBuilder, - suffix suffix: StringBuilder, -) -> StringBuilder { - do_append(builder, suffix) -} - -@external(erlang, "gleam_stdlib", "iodata_append") -@external(javascript, "../gleam_stdlib.mjs", "add") -fn do_append(a: StringBuilder, b: StringBuilder) -> StringBuilder - -/// Converts a list of strings into a builder. -/// -/// Runs in constant time. -/// -pub fn from_strings(strings: List(String)) -> StringBuilder { - do_from_strings(strings) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_from_strings(a: List(String)) -> StringBuilder - -/// Joins a list of builders into a single builder. -/// -/// Runs in constant time. -/// -pub fn concat(builders: List(StringBuilder)) -> StringBuilder { - do_concat(builders) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "concat") -fn do_concat(a: List(StringBuilder)) -> StringBuilder - -/// Converts a string into a builder. -/// -/// Runs in constant time. -/// -pub fn from_string(string: String) -> StringBuilder { - do_from_string(string) -} - -@external(erlang, "gleam_stdlib", "identity") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_from_string(a: String) -> StringBuilder - -/// Turns an `StringBuilder` into a `String` -/// -/// This function is implemented natively by the virtual machine and is highly -/// optimised. -/// -pub fn to_string(builder: StringBuilder) -> String { - do_to_string(builder) -} - -@external(erlang, "unicode", "characters_to_binary") -@external(javascript, "../gleam_stdlib.mjs", "identity") -fn do_to_string(a: StringBuilder) -> String - -/// Returns the size of the `StringBuilder` in bytes. -/// -pub fn byte_size(builder: StringBuilder) -> Int { - do_byte_size(builder) -} - -@external(erlang, "erlang", "iolist_size") -@external(javascript, "../gleam_stdlib.mjs", "length") -fn do_byte_size(a: StringBuilder) -> Int - -/// Joins the given builders into a new builder separated with the given string -/// -pub fn join(builders: List(StringBuilder), with sep: String) -> StringBuilder { - builders - |> list.intersperse(from_string(sep)) - |> concat -} - -/// Converts a builder to a new builder where the contents have been -/// lowercased. -/// -pub fn lowercase(builder: StringBuilder) -> StringBuilder { - do_lowercase(builder) -} - -@external(erlang, "string", "lowercase") -@external(javascript, "../gleam_stdlib.mjs", "lowercase") -fn do_lowercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder where the contents have been -/// uppercased. -/// -pub fn uppercase(builder: StringBuilder) -> StringBuilder { - do_uppercase(builder) -} - -@external(erlang, "string", "uppercase") -@external(javascript, "../gleam_stdlib.mjs", "uppercase") -fn do_uppercase(a: StringBuilder) -> StringBuilder - -/// Converts a builder to a new builder with the contents reversed. -/// -pub fn reverse(builder: StringBuilder) -> StringBuilder { - do_reverse(builder) -} - -@target(erlang) -@external(erlang, "string", "reverse") -fn do_reverse(a: StringBuilder) -> StringBuilder - -@target(javascript) -fn do_reverse(builder: StringBuilder) -> StringBuilder { - builder - |> to_string - |> do_to_graphemes - |> list.reverse - |> from_strings -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "graphemes") -fn do_to_graphemes(string string: String) -> List(String) - -/// Splits a builder on a given pattern into a list of builders. -/// -pub fn split(iodata: StringBuilder, on pattern: String) -> List(StringBuilder) { - do_split(iodata, pattern) -} - -@target(erlang) -type Direction { - All -} - -@target(erlang) -@external(erlang, "string", "split") -fn erl_split(a: StringBuilder, b: String, c: Direction) -> List(StringBuilder) - -@target(erlang) -fn do_split(iodata: StringBuilder, pattern: String) -> List(StringBuilder) { - erl_split(iodata, pattern, All) -} - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "split") -fn do_split( - builder builder: StringBuilder, - pattern pattern: String, -) -> List(StringBuilder) - -/// Replaces all instances of a pattern with a given string substitute. -/// -pub fn replace( - in builder: StringBuilder, - each pattern: String, - with substitute: String, -) -> StringBuilder { - do_replace(builder, pattern, substitute) -} - -@target(erlang) -fn do_replace( - iodata: StringBuilder, - pattern: String, - substitute: String, -) -> StringBuilder { - erl_replace(iodata, pattern, substitute, All) -} - -@target(erlang) -@external(erlang, "string", "replace") -fn erl_replace( - a: StringBuilder, - b: String, - c: String, - d: Direction, -) -> StringBuilder - -@target(javascript) -@external(javascript, "../gleam_stdlib.mjs", "string_replace") -fn do_replace(a: StringBuilder, b: String, c: String) -> StringBuilder - -/// Compares two builders to determine if they have the same textual content. -/// -/// Comparing two iodata using the `==` operator may return `False` even if they -/// have the same content as they may have been build in different ways, so -/// using this function is often preferred. -/// -/// ## Examples -/// -/// ```gleam -/// > from_strings(["a", "b"]) == from_string("ab") -/// False -/// ``` -/// -/// ```gleam -/// > is_equal(from_strings(["a", "b"]), from_string("ab")) -/// True -/// ``` -/// -pub fn is_equal(a: StringBuilder, b: StringBuilder) -> Bool { - do_is_equal(a, b) -} - -@external(erlang, "string", "equal") -@external(javascript, "../gleam_stdlib.mjs", "equal") -fn do_is_equal(a: StringBuilder, b: StringBuilder) -> Bool - -/// Inspects a builder to determine if it is equivalent to an empty string. -/// -/// ## Examples -/// -/// ```gleam -/// > from_string("ok") |> is_empty -/// False -/// ``` -/// -/// ```gleam -/// > from_string("") |> is_empty -/// True -/// ``` -/// -/// ```gleam -/// > from_strings([]) |> is_empty -/// True -/// ``` -/// -pub fn is_empty(builder: StringBuilder) -> Bool { - do_is_empty(builder) -} - -@target(erlang) -@external(erlang, "string", "is_empty") -fn do_is_empty(a: StringBuilder) -> Bool - -@target(javascript) -fn do_is_empty(builder: StringBuilder) -> Bool { - from_string("") == builder -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam b/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam deleted file mode 100644 index 11f6ea6..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam/uri.gleam +++ /dev/null @@ -1,462 +0,0 @@ -//// Utilities for working with URIs -//// -//// This module provides functions for working with URIs (for example, parsing -//// URIs or encoding query strings). The functions in this module are implemented -//// according to [RFC 3986](https://tools.ietf.org/html/rfc3986). -//// -//// Query encoding (Form encoding) is defined in the -//// [W3C specification](https://www.w3.org/TR/html52/sec-forms.html#urlencoded-form-data). - -import gleam/int -import gleam/list -import gleam/option.{type Option, None, Some} -import gleam/string -import gleam/string_builder.{type StringBuilder} -@target(javascript) -import gleam/pair -@target(javascript) -import gleam/regex -@target(javascript) -import gleam/result - -/// Type representing holding the parsed components of an URI. -/// All components of a URI are optional, except the path. -/// -pub type Uri { - Uri( - scheme: Option(String), - userinfo: Option(String), - host: Option(String), - port: Option(Int), - path: String, - query: Option(String), - fragment: Option(String), - ) -} - -/// Parses a compliant URI string into the `Uri` Type. -/// If the string is not a valid URI string then an error is returned. -/// -/// The opposite operation is `uri.to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse("https://example.com:1234/a/b?query=true#fragment") -/// Ok( -/// Uri( -/// scheme: Some("https"), -/// userinfo: None, -/// host: Some("example.com"), -/// port: Some(1234), -/// path: "/a/b", -/// query: Some("query=true"), -/// fragment: Some("fragment") -/// ) -/// ) -/// ``` -/// -pub fn parse(uri_string: String) -> Result(Uri, Nil) { - do_parse(uri_string) -} - -@target(erlang) -@external(erlang, "gleam_stdlib", "uri_parse") -fn do_parse(a: String) -> Result(Uri, Nil) - -@target(javascript) -fn do_parse(uri_string: String) -> Result(Uri, Nil) { - // From https://tools.ietf.org/html/rfc3986#appendix-B - let pattern = - // 12 3 4 5 6 7 8 - "^(([a-z][a-z0-9\\+\\-\\.]*):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#.*)?" - let matches = - pattern - |> regex_submatches(uri_string) - |> pad_list(8) - - let #(scheme, authority, path, query, fragment) = case matches { - [ - _scheme_with_colon, - scheme, - authority_with_slashes, - _authority, - path, - query_with_question_mark, - _query, - fragment, - ] -> #( - scheme, - authority_with_slashes, - path, - query_with_question_mark, - fragment, - ) - _ -> #(None, None, None, None, None) - } - - let scheme = noneify_empty_string(scheme) - let path = option.unwrap(path, "") - let query = noneify_query(query) - let #(userinfo, host, port) = split_authority(authority) - let fragment = - fragment - |> option.to_result(Nil) - |> result.try(string.pop_grapheme) - |> result.map(pair.second) - |> option.from_result - let scheme = - scheme - |> noneify_empty_string - |> option.map(string.lowercase) - Ok(Uri( - scheme: scheme, - userinfo: userinfo, - host: host, - port: port, - path: path, - query: query, - fragment: fragment, - )) -} - -@target(javascript) -fn regex_submatches(pattern: String, string: String) -> List(Option(String)) { - pattern - |> regex.compile(regex.Options(case_insensitive: True, multi_line: False)) - |> result.nil_error - |> result.map(regex.scan(_, string)) - |> result.try(list.first) - |> result.map(fn(m: regex.Match) { m.submatches }) - |> result.unwrap([]) -} - -@target(javascript) -fn noneify_query(x: Option(String)) -> Option(String) { - case x { - None -> None - Some(x) -> - case string.pop_grapheme(x) { - Ok(#("?", query)) -> Some(query) - _ -> None - } - } -} - -@target(javascript) -fn noneify_empty_string(x: Option(String)) -> Option(String) { - case x { - Some("") | None -> None - Some(_) -> x - } -} - -// Split an authority into its userinfo, host and port parts. -@target(javascript) -fn split_authority( - authority: Option(String), -) -> #(Option(String), Option(String), Option(Int)) { - case option.unwrap(authority, "") { - "" -> #(None, None, None) - "//" -> #(None, Some(""), None) - authority -> { - let matches = - "^(//)?((.*)@)?(\\[[a-zA-Z0-9:.]*\\]|[^:]*)(:(\\d*))?" - |> regex_submatches(authority) - |> pad_list(6) - case matches { - [_, _, userinfo, host, _, port] -> { - let userinfo = noneify_empty_string(userinfo) - let host = noneify_empty_string(host) - let port = - port - |> option.unwrap("") - |> int.parse - |> option.from_result - #(userinfo, host, port) - } - _ -> #(None, None, None) - } - } - } -} - -@target(javascript) -fn pad_list(list: List(Option(a)), size: Int) -> List(Option(a)) { - list - |> list.append(list.repeat(None, extra_required(list, size))) -} - -@target(javascript) -fn extra_required(list: List(a), remaining: Int) -> Int { - case list { - _ if remaining == 0 -> 0 - [] -> remaining - [_, ..xs] -> extra_required(xs, remaining - 1) - } -} - -/// Parses an urlencoded query string into a list of key value pairs. -/// Returns an error for invalid encoding. -/// -/// The opposite operation is `uri.query_to_string`. -/// -/// ## Examples -/// -/// ```gleam -/// > parse_query("a=1&b=2") -/// Ok([#("a", "1"), #("b", "2")]) -/// ``` -/// -pub fn parse_query(query: String) -> Result(List(#(String, String)), Nil) { - do_parse_query(query) -} - -@external(erlang, "gleam_stdlib", "parse_query") -@external(javascript, "../gleam_stdlib.mjs", "parse_query") -fn do_parse_query(a: String) -> Result(List(#(String, String)), Nil) - -/// Encodes a list of key value pairs as a URI query string. -/// -/// The opposite operation is `uri.parse_query`. -/// -/// ## Examples -/// -/// ```gleam -/// > query_to_string([#("a", "1"), #("b", "2")]) -/// "a=1&b=2" -/// ``` -/// -pub fn query_to_string(query: List(#(String, String))) -> String { - query - |> list.map(query_pair) - |> list.intersperse(string_builder.from_string("&")) - |> string_builder.concat - |> string_builder.to_string -} - -fn query_pair(pair: #(String, String)) -> StringBuilder { - string_builder.from_strings([ - percent_encode(pair.0), - "=", - percent_encode(pair.1), - ]) -} - -/// Encodes a string into a percent encoded representation. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_encode("100% great") -/// "100%25%20great" -/// ``` -/// -pub fn percent_encode(value: String) -> String { - do_percent_encode(value) -} - -@external(erlang, "gleam_stdlib", "percent_encode") -@external(javascript, "../gleam_stdlib.mjs", "percent_encode") -fn do_percent_encode(a: String) -> String - -/// Decodes a percent encoded string. -/// -/// ## Examples -/// -/// ```gleam -/// > percent_decode("100%25+great") -/// Ok("100% great") -/// ``` -/// -pub fn percent_decode(value: String) -> Result(String, Nil) { - do_percent_decode(value) -} - -@external(erlang, "gleam_stdlib", "percent_decode") -@external(javascript, "../gleam_stdlib.mjs", "percent_decode") -fn do_percent_decode(a: String) -> Result(String, Nil) - -fn do_remove_dot_segments( - input: List(String), - accumulator: List(String), -) -> List(String) { - case input { - [] -> list.reverse(accumulator) - [segment, ..rest] -> { - let accumulator = case segment, accumulator { - "", accumulator -> accumulator - ".", accumulator -> accumulator - "..", [] -> [] - "..", [_, ..accumulator] -> accumulator - segment, accumulator -> [segment, ..accumulator] - } - do_remove_dot_segments(rest, accumulator) - } - } -} - -fn remove_dot_segments(input: List(String)) -> List(String) { - do_remove_dot_segments(input, []) -} - -/// Splits the path section of a URI into it's constituent segments. -/// -/// Removes empty segments and resolves dot-segments as specified in -/// [section 5.2](https://www.ietf.org/rfc/rfc3986.html#section-5.2) of the RFC. -/// -/// ## Examples -/// -/// ```gleam -/// > path_segments("/users/1") -/// ["users" ,"1"] -/// ``` -/// -pub fn path_segments(path: String) -> List(String) { - remove_dot_segments(string.split(path, "/")) -} - -/// Encodes a `Uri` value as a URI string. -/// -/// The opposite operation is `uri.parse`. -/// -/// ## Examples -/// -/// ```gleam -/// > let uri = Uri(Some("http"), None, Some("example.com"), ...) -/// > to_string(uri) -/// "http://example.com" -/// ``` -/// -pub fn to_string(uri: Uri) -> String { - let parts = case uri.fragment { - Some(fragment) -> ["#", fragment] - _ -> [] - } - let parts = case uri.query { - Some(query) -> ["?", query, ..parts] - _ -> parts - } - let parts = [uri.path, ..parts] - let parts = case uri.host, string.starts_with(uri.path, "/") { - Some(host), False if host != "" -> ["/", ..parts] - _, _ -> parts - } - let parts = case uri.host, uri.port { - Some(_), Some(port) -> [":", int.to_string(port), ..parts] - _, _ -> parts - } - let parts = case uri.scheme, uri.userinfo, uri.host { - Some(s), Some(u), Some(h) -> [s, "://", u, "@", h, ..parts] - Some(s), None, Some(h) -> [s, "://", h, ..parts] - Some(s), Some(_), None | Some(s), None, None -> [s, ":", ..parts] - None, None, Some(h) -> ["//", h, ..parts] - _, _, _ -> parts - } - string.concat(parts) -} - -/// Fetches the origin of a URI. -/// -/// Returns the origin of a uri as defined in -/// [RFC 6454](https://tools.ietf.org/html/rfc6454) -/// -/// The supported URI schemes are `http` and `https`. -/// URLs without a scheme will return `Error`. -/// -/// ## Examples -/// -/// ```gleam -/// > let assert Ok(uri) = parse("http://example.com/path?foo#bar") -/// > origin(uri) -/// Ok("http://example.com") -/// ``` -/// -pub fn origin(uri: Uri) -> Result(String, Nil) { - let Uri(scheme: scheme, host: host, port: port, ..) = uri - case scheme { - Some("https") if port == Some(443) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some("http") if port == Some(80) -> { - let origin = Uri(scheme, None, host, None, "", None, None) - Ok(to_string(origin)) - } - Some(s) if s == "http" || s == "https" -> { - let origin = Uri(scheme, None, host, port, "", None, None) - Ok(to_string(origin)) - } - _ -> Error(Nil) - } -} - -fn drop_last(elements: List(a)) -> List(a) { - list.take(from: elements, up_to: list.length(elements) - 1) -} - -fn join_segments(segments: List(String)) -> String { - string.join(["", ..segments], "/") -} - -/// Resolves a URI with respect to the given base URI. -/// -/// The base URI must be an absolute URI or this function will return an error. -/// The algorithm for merging uris is described in -/// [RFC 3986](https://tools.ietf.org/html/rfc3986#section-5.2). -/// -pub fn merge(base: Uri, relative: Uri) -> Result(Uri, Nil) { - case base { - Uri(scheme: Some(_), host: Some(_), ..) -> - case relative { - Uri(host: Some(_), ..) -> { - let path = - string.split(relative.path, "/") - |> remove_dot_segments() - |> join_segments() - let resolved = - Uri( - option.or(relative.scheme, base.scheme), - None, - relative.host, - option.or(relative.port, base.port), - path, - relative.query, - relative.fragment, - ) - Ok(resolved) - } - _ -> { - let #(new_path, new_query) = case relative.path { - "" -> #(base.path, option.or(relative.query, base.query)) - _ -> { - let path_segments = case string.starts_with(relative.path, "/") { - True -> string.split(relative.path, "/") - False -> - string.split(base.path, "/") - |> drop_last() - |> list.append(string.split(relative.path, "/")) - } - let path = - path_segments - |> remove_dot_segments() - |> join_segments() - #(path, relative.query) - } - } - let resolved = - Uri( - base.scheme, - None, - base.host, - base.port, - new_path, - new_query, - relative.fragment, - ) - Ok(resolved) - } - } - _ -> Error(Nil) - } -} diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl deleted file mode 100644 index 65bc3f6..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@base.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(gleam@base). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([encode64/2, decode64/1, url_encode64/2, url_decode64/1]). - --spec encode64(bitstring(), boolean()) -> binary(). -encode64(Input, Padding) -> - gleam@bit_array:base64_encode(Input, Padding). - --spec decode64(binary()) -> {ok, bitstring()} | {error, nil}. -decode64(Encoded) -> - gleam@bit_array:base64_decode(Encoded). - --spec url_encode64(bitstring(), boolean()) -> binary(). -url_encode64(Input, Padding) -> - gleam@bit_array:base64_url_encode(Input, Padding). - --spec url_decode64(binary()) -> {ok, bitstring()} | {error, nil}. -url_decode64(Encoded) -> - gleam@bit_array:base64_url_decode(Encoded). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl deleted file mode 100644 index ba18dfa..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_array.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(gleam@bit_array). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, slice/3, is_utf8/1, to_string/1, concat/1, append/2, base64_encode/2, base64_decode/1, base64_url_encode/2, base64_url_decode/1, base16_encode/1, base16_decode/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec do_is_utf8(bitstring()) -> boolean(). -do_is_utf8(Bits) -> - case Bits of - <<>> -> - true; - - <<_/utf8, Rest/binary>> -> - do_is_utf8(Rest); - - _ -> - false - end. - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - do_is_utf8(Bits). - --spec do_to_string(bitstring()) -> {ok, binary()} | {error, nil}. -do_to_string(Bits) -> - case is_utf8(Bits) of - true -> - {ok, gleam_stdlib:identity(Bits)}; - - false -> - {error, nil} - end. - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - do_to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_arrays) -> - gleam_stdlib:bit_array_concat(Bit_arrays). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam_stdlib:bit_array_concat([First, Second]). - --spec base64_encode(bitstring(), boolean()) -> binary(). -base64_encode(Input, Padding) -> - Encoded = base64:encode(Input), - case Padding of - true -> - Encoded; - - false -> - gleam@string:replace(Encoded, <<"="/utf8>>, <<""/utf8>>) - end. - --spec base64_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_decode(Encoded) -> - Padded = case erlang:byte_size(gleam_stdlib:identity(Encoded)) rem 4 of - 0 -> - Encoded; - - N -> - gleam@string:append( - Encoded, - gleam@string:repeat(<<"="/utf8>>, 4 - N) - ) - end, - gleam_stdlib:base_decode64(Padded). - --spec base64_url_encode(bitstring(), boolean()) -> binary(). -base64_url_encode(Input, Padding) -> - _pipe = base64_encode(Input, Padding), - _pipe@1 = gleam@string:replace(_pipe, <<"+"/utf8>>, <<"-"/utf8>>), - gleam@string:replace(_pipe@1, <<"/"/utf8>>, <<"_"/utf8>>). - --spec base64_url_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base64_url_decode(Encoded) -> - _pipe = Encoded, - _pipe@1 = gleam@string:replace(_pipe, <<"-"/utf8>>, <<"+"/utf8>>), - _pipe@2 = gleam@string:replace(_pipe@1, <<"_"/utf8>>, <<"/"/utf8>>), - base64_decode(_pipe@2). - --spec base16_encode(bitstring()) -> binary(). -base16_encode(Input) -> - binary:encode_hex(Input). - --spec base16_decode(binary()) -> {ok, bitstring()} | {error, nil}. -base16_decode(Input) -> - gleam_stdlib:base16_decode(Input). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl deleted file mode 100644 index 284c6d4..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_builder.erl +++ /dev/null @@ -1,66 +0,0 @@ --module(gleam@bit_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, prepend/2, append/2, prepend_builder/2, append_builder/2, prepend_string/2, append_string/2, concat/1, concat_bit_strings/1, from_string/1, from_string_builder/1, from_bit_string/1, to_bit_string/1, byte_size/1]). - --spec new() -> gleam@bytes_builder:bytes_builder(). -new() -> - gleam@bytes_builder:new(). - --spec prepend(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -prepend(To, Prefix) -> - gleam@bytes_builder:prepend(To, Prefix). - --spec append(gleam@bytes_builder:bytes_builder(), bitstring()) -> gleam@bytes_builder:bytes_builder(). -append(To, Suffix) -> - gleam@bytes_builder:append(To, Suffix). - --spec prepend_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -prepend_builder(To, Prefix) -> - gleam@bytes_builder:prepend_builder(To, Prefix). - --spec append_builder( - gleam@bytes_builder:bytes_builder(), - gleam@bytes_builder:bytes_builder() -) -> gleam@bytes_builder:bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -prepend_string(To, Prefix) -> - gleam@bytes_builder:prepend_string(To, Prefix). - --spec append_string(gleam@bytes_builder:bytes_builder(), binary()) -> gleam@bytes_builder:bytes_builder(). -append_string(To, Suffix) -> - gleam@bytes_builder:append_string(To, Suffix). - --spec concat(list(gleam@bytes_builder:bytes_builder())) -> gleam@bytes_builder:bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec concat_bit_strings(list(bitstring())) -> gleam@bytes_builder:bytes_builder(). -concat_bit_strings(Bits) -> - gleam_stdlib:identity(Bits). - --spec from_string(binary()) -> gleam@bytes_builder:bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec from_string_builder(gleam@string_builder:string_builder()) -> gleam@bytes_builder:bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_string(bitstring()) -> gleam@bytes_builder:bytes_builder(). -from_bit_string(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec to_bit_string(gleam@bytes_builder:bytes_builder()) -> bitstring(). -to_bit_string(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(gleam@bytes_builder:bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl deleted file mode 100644 index 7dabaa3..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bit_string.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@bit_string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from_string/1, byte_size/1, append/2, slice/3, is_utf8/1, to_string/1, concat/1]). - --spec from_string(binary()) -> bitstring(). -from_string(X) -> - gleam_stdlib:identity(X). - --spec byte_size(bitstring()) -> integer(). -byte_size(X) -> - erlang:byte_size(X). - --spec append(bitstring(), bitstring()) -> bitstring(). -append(First, Second) -> - gleam@bit_array:append(First, Second). - --spec slice(bitstring(), integer(), integer()) -> {ok, bitstring()} | - {error, nil}. -slice(String, Position, Length) -> - gleam_stdlib:bit_array_slice(String, Position, Length). - --spec is_utf8(bitstring()) -> boolean(). -is_utf8(Bits) -> - gleam@bit_array:is_utf8(Bits). - --spec to_string(bitstring()) -> {ok, binary()} | {error, nil}. -to_string(Bits) -> - gleam@bit_array:to_string(Bits). - --spec concat(list(bitstring())) -> bitstring(). -concat(Bit_strings) -> - gleam_stdlib:bit_array_concat(Bit_strings). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl deleted file mode 100644 index cd55358..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bool.erl +++ /dev/null @@ -1,162 +0,0 @@ --module(gleam@bool). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export(['and'/2, 'or'/2, negate/1, nor/2, nand/2, exclusive_or/2, exclusive_nor/2, compare/2, max/2, min/2, to_int/1, to_string/1, guard/3, lazy_guard/3]). - --spec 'and'(boolean(), boolean()) -> boolean(). -'and'(A, B) -> - A andalso B. - --spec 'or'(boolean(), boolean()) -> boolean(). -'or'(A, B) -> - A orelse B. - --spec negate(boolean()) -> boolean(). -negate(Bool) -> - case Bool of - true -> - false; - - false -> - true - end. - --spec nor(boolean(), boolean()) -> boolean(). -nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - false - end. - --spec nand(boolean(), boolean()) -> boolean(). -nand(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_or(boolean(), boolean()) -> boolean(). -exclusive_or(A, B) -> - case {A, B} of - {false, false} -> - false; - - {false, true} -> - true; - - {true, false} -> - true; - - {true, true} -> - false - end. - --spec exclusive_nor(boolean(), boolean()) -> boolean(). -exclusive_nor(A, B) -> - case {A, B} of - {false, false} -> - true; - - {false, true} -> - false; - - {true, false} -> - false; - - {true, true} -> - true - end. - --spec compare(boolean(), boolean()) -> gleam@order:order(). -compare(A, B) -> - case {A, B} of - {true, true} -> - eq; - - {true, false} -> - gt; - - {false, false} -> - eq; - - {false, true} -> - lt - end. - --spec max(boolean(), boolean()) -> boolean(). -max(A, B) -> - case A of - true -> - true; - - false -> - B - end. - --spec min(boolean(), boolean()) -> boolean(). -min(A, B) -> - case A of - false -> - false; - - true -> - B - end. - --spec to_int(boolean()) -> integer(). -to_int(Bool) -> - case Bool of - false -> - 0; - - true -> - 1 - end. - --spec to_string(boolean()) -> binary(). -to_string(Bool) -> - case Bool of - false -> - <<"False"/utf8>>; - - true -> - <<"True"/utf8>> - end. - --spec guard(boolean(), DDZ, fun(() -> DDZ)) -> DDZ. -guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence; - - false -> - Alternative() - end. - --spec lazy_guard(boolean(), fun(() -> DEA), fun(() -> DEA)) -> DEA. -lazy_guard(Requirement, Consequence, Alternative) -> - case Requirement of - true -> - Consequence(); - - false -> - Alternative() - end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl deleted file mode 100644 index 2f6dd93..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@bytes_builder.erl +++ /dev/null @@ -1,87 +0,0 @@ --module(gleam@bytes_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([append_builder/2, prepend_builder/2, concat/1, new/0, from_string/1, prepend_string/2, append_string/2, from_string_builder/1, from_bit_array/1, prepend/2, append/2, concat_bit_arrays/1, to_bit_array/1, byte_size/1]). --export_type([bytes_builder/0]). - --opaque bytes_builder() :: {bytes, bitstring()} | - {text, gleam@string_builder:string_builder()} | - {many, list(bytes_builder())}. - --spec append_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -append_builder(First, Second) -> - gleam_stdlib:iodata_append(First, Second). - --spec prepend_builder(bytes_builder(), bytes_builder()) -> bytes_builder(). -prepend_builder(Second, First) -> - gleam_stdlib:iodata_append(First, Second). - --spec concat(list(bytes_builder())) -> bytes_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec new() -> bytes_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_string(binary()) -> bytes_builder(). -from_string(String) -> - gleam_stdlib:wrap_list(String). - --spec prepend_string(bytes_builder(), binary()) -> bytes_builder(). -prepend_string(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append_string(bytes_builder(), binary()) -> bytes_builder(). -append_string(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec from_string_builder(gleam@string_builder:string_builder()) -> bytes_builder(). -from_string_builder(Builder) -> - gleam_stdlib:wrap_list(Builder). - --spec from_bit_array(bitstring()) -> bytes_builder(). -from_bit_array(Bits) -> - gleam_stdlib:wrap_list(Bits). - --spec prepend(bytes_builder(), bitstring()) -> bytes_builder(). -prepend(Second, First) -> - gleam_stdlib:iodata_append(gleam_stdlib:wrap_list(First), Second). - --spec append(bytes_builder(), bitstring()) -> bytes_builder(). -append(First, Second) -> - gleam_stdlib:iodata_append(First, gleam_stdlib:wrap_list(Second)). - --spec concat_bit_arrays(list(bitstring())) -> bytes_builder(). -concat_bit_arrays(Bits) -> - gleam_stdlib:identity(Bits). - --spec to_list(list(list(bytes_builder())), list(bitstring())) -> list(bitstring()). -to_list(Stack, Acc) -> - case Stack of - [] -> - Acc; - - [[] | Remaining_stack] -> - to_list(Remaining_stack, Acc); - - [[{bytes, Bits} | Rest] | Remaining_stack@1] -> - to_list([Rest | Remaining_stack@1], [Bits | Acc]); - - [[{text, Builder} | Rest@1] | Remaining_stack@2] -> - Bits@1 = gleam_stdlib:identity( - gleam@string_builder:to_string(Builder) - ), - to_list([Rest@1 | Remaining_stack@2], [Bits@1 | Acc]); - - [[{many, Builders} | Rest@2] | Remaining_stack@3] -> - to_list([Builders, Rest@2 | Remaining_stack@3], Acc) - end. - --spec to_bit_array(bytes_builder()) -> bitstring(). -to_bit_array(Builder) -> - erlang:list_to_bitstring(Builder). - --spec byte_size(bytes_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl deleted file mode 100644 index 44b89ea..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@dict.erl +++ /dev/null @@ -1,97 +0,0 @@ --module(gleam@dict). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). --export_type([dict/2]). - --type dict(KS, KT) :: any() | {gleam_phantom, KS, KT}. - --spec size(dict(any(), any())) -> integer(). -size(Dict) -> - maps:size(Dict). - --spec to_list(dict(LC, LD)) -> list({LC, LD}). -to_list(Dict) -> - maps:to_list(Dict). - --spec from_list(list({LM, LN})) -> dict(LM, LN). -from_list(List) -> - maps:from_list(List). - --spec has_key(dict(LW, any()), LW) -> boolean(). -has_key(Dict, Key) -> - maps:is_key(Key, Dict). - --spec new() -> dict(any(), any()). -new() -> - maps:new(). - --spec get(dict(MM, MN), MM) -> {ok, MN} | {error, nil}. -get(From, Get) -> - gleam_stdlib:map_get(From, Get). - --spec insert(dict(MY, MZ), MY, MZ) -> dict(MY, MZ). -insert(Dict, Key, Value) -> - maps:put(Key, Value, Dict). - --spec map_values(dict(NK, NL), fun((NK, NL) -> NO)) -> dict(NK, NO). -map_values(Dict, Fun) -> - maps:map(Fun, Dict). - --spec keys(dict(NY, any())) -> list(NY). -keys(Dict) -> - maps:keys(Dict). - --spec values(dict(any(), OJ)) -> list(OJ). -values(Dict) -> - maps:values(Dict). - --spec filter(dict(OS, OT), fun((OS, OT) -> boolean())) -> dict(OS, OT). -filter(Dict, Predicate) -> - maps:filter(Predicate, Dict). - --spec take(dict(PE, PF), list(PE)) -> dict(PE, PF). -take(Dict, Desired_keys) -> - maps:with(Desired_keys, Dict). - --spec merge(dict(PS, PT), dict(PS, PT)) -> dict(PS, PT). -merge(Dict, New_entries) -> - maps:merge(Dict, New_entries). - --spec delete(dict(QI, QJ), QI) -> dict(QI, QJ). -delete(Dict, Key) -> - maps:remove(Key, Dict). - --spec drop(dict(QU, QV), list(QU)) -> dict(QU, QV). -drop(Dict, Disallowed_keys) -> - case Disallowed_keys of - [] -> - Dict; - - [X | Xs] -> - drop(delete(Dict, X), Xs) - end. - --spec update(dict(RB, RC), RB, fun((gleam@option:option(RC)) -> RC)) -> dict(RB, RC). -update(Dict, Key, Fun) -> - _pipe = Dict, - _pipe@1 = get(_pipe, Key), - _pipe@2 = gleam@option:from_result(_pipe@1), - _pipe@3 = Fun(_pipe@2), - insert(Dict, Key, _pipe@3). - --spec do_fold(list({RI, RJ}), RL, fun((RL, RI, RJ) -> RL)) -> RL. -do_fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [{K, V} | Rest] -> - do_fold(Rest, Fun(Initial, K, V), Fun) - end. - --spec fold(dict(RM, RN), RQ, fun((RQ, RM, RN) -> RQ)) -> RQ. -fold(Dict, Initial, Fun) -> - _pipe = Dict, - _pipe@1 = to_list(_pipe), - do_fold(_pipe@1, Initial, Fun). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl deleted file mode 100644 index 38f4b4e..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@dynamic.erl +++ /dev/null @@ -1,808 +0,0 @@ --module(gleam@dynamic). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([from/1, unsafe_coerce/1, dynamic/1, bit_array/1, bit_string/1, classify/1, int/1, float/1, bool/1, shallow_list/1, optional/1, any/1, decode1/2, result/2, list/1, string/1, field/2, optional_field/2, element/2, tuple2/2, tuple3/3, tuple4/4, tuple5/5, tuple6/6, dict/2, map/2, decode2/3, decode3/4, decode4/5, decode5/6, decode6/7, decode7/8, decode8/9, decode9/10]). --export_type([dynamic_/0, decode_error/0, unknown_tuple/0]). - --type dynamic_() :: any(). - --type decode_error() :: {decode_error, binary(), binary(), list(binary())}. - --type unknown_tuple() :: any(). - --spec from(any()) -> dynamic_(). -from(A) -> - gleam_stdlib:identity(A). - --spec unsafe_coerce(dynamic_()) -> any(). -unsafe_coerce(A) -> - gleam_stdlib:identity(A). - --spec dynamic(dynamic_()) -> {ok, dynamic_()} | {error, list(decode_error())}. -dynamic(Value) -> - {ok, Value}. - --spec bit_array(dynamic_()) -> {ok, bitstring()} | {error, list(decode_error())}. -bit_array(Data) -> - gleam_stdlib:decode_bit_array(Data). - --spec bit_string(dynamic_()) -> {ok, bitstring()} | - {error, list(decode_error())}. -bit_string(Data) -> - bit_array(Data). - --spec put_expected(decode_error(), binary()) -> decode_error(). -put_expected(Error, Expected) -> - erlang:setelement(2, Error, Expected). - --spec classify(dynamic_()) -> binary(). -classify(Data) -> - gleam_stdlib:classify_dynamic(Data). - --spec int(dynamic_()) -> {ok, integer()} | {error, list(decode_error())}. -int(Data) -> - gleam_stdlib:decode_int(Data). - --spec float(dynamic_()) -> {ok, float()} | {error, list(decode_error())}. -float(Data) -> - gleam_stdlib:decode_float(Data). - --spec bool(dynamic_()) -> {ok, boolean()} | {error, list(decode_error())}. -bool(Data) -> - gleam_stdlib:decode_bool(Data). - --spec shallow_list(dynamic_()) -> {ok, list(dynamic_())} | - {error, list(decode_error())}. -shallow_list(Value) -> - gleam_stdlib:decode_list(Value). - --spec optional(fun((dynamic_()) -> {ok, DZX} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - gleam@option:option(DZX)} | - {error, list(decode_error())}). -optional(Decode) -> - fun(Value) -> gleam_stdlib:decode_option(Value, Decode) end. - --spec at_least_decode_tuple_error(integer(), dynamic_()) -> {ok, any()} | - {error, list(decode_error())}. -at_least_decode_tuple_error(Size, Data) -> - S = case Size of - 1 -> - <<""/utf8>>; - - _ -> - <<"s"/utf8>> - end, - Error = begin - _pipe = [<<"Tuple of at least "/utf8>>, - gleam@int:to_string(Size), - <<" element"/utf8>>, - S], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - _pipe@2 = gleam@string_builder:to_string(_pipe@1), - {decode_error, _pipe@2, classify(Data), []} - end, - {error, [Error]}. - --spec any(list(fun((dynamic_()) -> {ok, EEE} | {error, list(decode_error())}))) -> fun((dynamic_()) -> {ok, - EEE} | - {error, list(decode_error())}). -any(Decoders) -> - fun(Data) -> case Decoders of - [] -> - {error, - [{decode_error, <<"another type"/utf8>>, classify(Data), []}]}; - - [Decoder | Decoders@1] -> - case Decoder(Data) of - {ok, Decoded} -> - {ok, Decoded}; - - {error, _} -> - (any(Decoders@1))(Data) - end - end end. - --spec all_errors({ok, any()} | {error, list(decode_error())}) -> list(decode_error()). -all_errors(Result) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - Errors - end. - --spec decode1( - fun((EEI) -> EEJ), - fun((dynamic_()) -> {ok, EEI} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EEJ} | {error, list(decode_error())}). -decode1(Constructor, T1) -> - fun(Value) -> case T1(Value) of - {ok, A} -> - {ok, Constructor(A)}; - - A@1 -> - {error, all_errors(A@1)} - end end. - --spec push_path(decode_error(), any()) -> decode_error(). -push_path(Error, Name) -> - Name@1 = from(Name), - Decoder = any( - [fun string/1, - fun(X) -> gleam@result:map(int(X), fun gleam@int:to_string/1) end] - ), - Name@3 = case Decoder(Name@1) of - {ok, Name@2} -> - Name@2; - - {error, _} -> - _pipe = [<<"<"/utf8>>, classify(Name@1), <<">"/utf8>>], - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1) - end, - erlang:setelement(4, Error, [Name@3 | erlang:element(4, Error)]). - --spec result( - fun((dynamic_()) -> {ok, DZL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, DZN} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ok, DZL} | {error, DZN}} | - {error, list(decode_error())}). -result(Decode_ok, Decode_error) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_result(Value), - fun(Inner_result) -> case Inner_result of - {ok, Raw} -> - gleam@result:'try'( - begin - _pipe = Decode_ok(Raw), - map_errors( - _pipe, - fun(_capture) -> - push_path(_capture, <<"ok"/utf8>>) - end - ) - end, - fun(Value@1) -> {ok, {ok, Value@1}} end - ); - - {error, Raw@1} -> - gleam@result:'try'( - begin - _pipe@1 = Decode_error(Raw@1), - map_errors( - _pipe@1, - fun(_capture@1) -> - push_path(_capture@1, <<"error"/utf8>>) - end - ) - end, - fun(Value@2) -> {ok, {error, Value@2}} end - ) - end end - ) - end. - --spec list(fun((dynamic_()) -> {ok, DZS} | {error, list(decode_error())})) -> fun((dynamic_()) -> {ok, - list(DZS)} | - {error, list(decode_error())}). -list(Decoder_type) -> - fun(Dynamic) -> - gleam@result:'try'(shallow_list(Dynamic), fun(List) -> _pipe = List, - _pipe@1 = gleam@list:try_map(_pipe, Decoder_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, <<"*"/utf8>>) end - ) end) - end. - --spec map_errors( - {ok, DYG} | {error, list(decode_error())}, - fun((decode_error()) -> decode_error()) -) -> {ok, DYG} | {error, list(decode_error())}. -map_errors(Result, F) -> - gleam@result:map_error( - Result, - fun(_capture) -> gleam@list:map(_capture, F) end - ). - --spec decode_string(dynamic_()) -> {ok, binary()} | - {error, list(decode_error())}. -decode_string(Data) -> - _pipe = bit_array(Data), - _pipe@1 = map_errors( - _pipe, - fun(_capture) -> put_expected(_capture, <<"String"/utf8>>) end - ), - gleam@result:'try'( - _pipe@1, - fun(Raw) -> case gleam@bit_array:to_string(Raw) of - {ok, String} -> - {ok, String}; - - {error, nil} -> - {error, - [{decode_error, - <<"String"/utf8>>, - <<"BitArray"/utf8>>, - []}]} - end end - ). - --spec string(dynamic_()) -> {ok, binary()} | {error, list(decode_error())}. -string(Data) -> - decode_string(Data). - --spec field( - any(), - fun((dynamic_()) -> {ok, EAH} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EAH} | {error, list(decode_error())}). -field(Name, Inner_type) -> - fun(Value) -> - Missing_field_error = {decode_error, - <<"field"/utf8>>, - <<"nothing"/utf8>>, - []}, - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> _pipe = Maybe_inner, - _pipe@1 = gleam@option:to_result(_pipe, [Missing_field_error]), - _pipe@2 = gleam@result:'try'(_pipe@1, Inner_type), - map_errors( - _pipe@2, - fun(_capture) -> push_path(_capture, Name) end - ) end - ) - end. - --spec optional_field( - any(), - fun((dynamic_()) -> {ok, EAL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@option:option(EAL)} | - {error, list(decode_error())}). -optional_field(Name, Inner_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_field(Value, Name), - fun(Maybe_inner) -> case Maybe_inner of - none -> - {ok, none}; - - {some, Dynamic_inner} -> - _pipe = Dynamic_inner, - _pipe@1 = gleam_stdlib:decode_option(_pipe, Inner_type), - map_errors( - _pipe@1, - fun(_capture) -> push_path(_capture, Name) end - ) - end end - ) - end. - --spec element( - integer(), - fun((dynamic_()) -> {ok, EAT} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EAT} | {error, list(decode_error())}). -element(Index, Inner_type) -> - fun(Data) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple(Data), - fun(Tuple) -> - Size = gleam_stdlib:size_of_tuple(Tuple), - gleam@result:'try'(case Index >= 0 of - true -> - case Index < Size of - true -> - gleam_stdlib:tuple_get(Tuple, Index); - - false -> - at_least_decode_tuple_error(Index + 1, Data) - end; - - false -> - case gleam@int:absolute_value(Index) =< Size of - true -> - gleam_stdlib:tuple_get(Tuple, Size + Index); - - false -> - at_least_decode_tuple_error( - gleam@int:absolute_value(Index), - Data - ) - end - end, fun(Data@1) -> _pipe = Inner_type(Data@1), - map_errors( - _pipe, - fun(_capture) -> push_path(_capture, Index) end - ) end) - end - ) - end. - --spec tuple_errors({ok, any()} | {error, list(decode_error())}, binary()) -> list(decode_error()). -tuple_errors(Result, Name) -> - case Result of - {ok, _} -> - []; - - {error, Errors} -> - gleam@list:map( - Errors, - fun(_capture) -> push_path(_capture, Name) end - ) - end. - --spec tuple2( - fun((dynamic_()) -> {ok, EBT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EBV} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {EBT, EBV}} | {error, list(decode_error())}). -tuple2(Decode1, Decode2) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple2(Value), - fun(_use0) -> - {A, B} = _use0, - case {Decode1(A), Decode2(B)} of - {{ok, A@1}, {ok, B@1}} -> - {ok, {A@1, B@1}}; - - {A@2, B@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - {error, _pipe@1} - end - end - ) - end. - --spec tuple3( - fun((dynamic_()) -> {ok, EBY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECC} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {EBY, ECA, ECC}} | {error, list(decode_error())}). -tuple3(Decode1, Decode2, Decode3) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple3(Value), - fun(_use0) -> - {A, B, C} = _use0, - case {Decode1(A), Decode2(B), Decode3(C)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}} -> - {ok, {A@1, B@1, C@1}}; - - {A@2, B@2, C@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - {error, _pipe@2} - end - end - ) - end. - --spec tuple4( - fun((dynamic_()) -> {ok, ECF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECJ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECL} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ECF, ECH, ECJ, ECL}} | - {error, list(decode_error())}). -tuple4(Decode1, Decode2, Decode3, Decode4) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple4(Value), - fun(_use0) -> - {A, B, C, D} = _use0, - case {Decode1(A), Decode2(B), Decode3(C), Decode4(D)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}} -> - {ok, {A@1, B@1, C@1, D@1}}; - - {A@2, B@2, C@2, D@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - {error, _pipe@3} - end - end - ) - end. - --spec tuple5( - fun((dynamic_()) -> {ok, ECO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECQ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, ECW} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ECO, ECQ, ECS, ECU, ECW}} | - {error, list(decode_error())}). -tuple5(Decode1, Decode2, Decode3, Decode4, Decode5) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple5(Value), - fun(_use0) -> - {A, B, C, D, E} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E)} of - {{ok, A@1}, {ok, B@1}, {ok, C@1}, {ok, D@1}, {ok, E@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1}}; - - {A@2, B@2, C@2, D@2, E@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - {error, _pipe@4} - end - end - ) - end. - --spec tuple6( - fun((dynamic_()) -> {ok, ECZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDH} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDJ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, {ECZ, EDB, EDD, EDF, EDH, EDJ}} | - {error, list(decode_error())}). -tuple6(Decode1, Decode2, Decode3, Decode4, Decode5, Decode6) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_tuple6(Value), - fun(_use0) -> - {A, B, C, D, E, F} = _use0, - case {Decode1(A), - Decode2(B), - Decode3(C), - Decode4(D), - Decode5(E), - Decode6(F)} of - {{ok, A@1}, - {ok, B@1}, - {ok, C@1}, - {ok, D@1}, - {ok, E@1}, - {ok, F@1}} -> - {ok, {A@1, B@1, C@1, D@1, E@1, F@1}}; - - {A@2, B@2, C@2, D@2, E@2, F@2} -> - _pipe = tuple_errors(A@2, <<"0"/utf8>>), - _pipe@1 = gleam@list:append( - _pipe, - tuple_errors(B@2, <<"1"/utf8>>) - ), - _pipe@2 = gleam@list:append( - _pipe@1, - tuple_errors(C@2, <<"2"/utf8>>) - ), - _pipe@3 = gleam@list:append( - _pipe@2, - tuple_errors(D@2, <<"3"/utf8>>) - ), - _pipe@4 = gleam@list:append( - _pipe@3, - tuple_errors(E@2, <<"4"/utf8>>) - ), - _pipe@5 = gleam@list:append( - _pipe@4, - tuple_errors(F@2, <<"5"/utf8>>) - ), - {error, _pipe@5} - end - end - ) - end. - --spec dict( - fun((dynamic_()) -> {ok, EDM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDO} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(EDM, EDO)} | - {error, list(decode_error())}). -dict(Key_type, Value_type) -> - fun(Value) -> - gleam@result:'try'( - gleam_stdlib:decode_map(Value), - fun(Map) -> - gleam@result:'try'( - begin - _pipe = Map, - _pipe@1 = gleam@dict:to_list(_pipe), - gleam@list:try_map( - _pipe@1, - fun(Pair) -> - {K, V} = Pair, - gleam@result:'try'( - begin - _pipe@2 = Key_type(K), - map_errors( - _pipe@2, - fun(_capture) -> - push_path( - _capture, - <<"keys"/utf8>> - ) - end - ) - end, - fun(K@1) -> - gleam@result:'try'( - begin - _pipe@3 = Value_type(V), - map_errors( - _pipe@3, - fun(_capture@1) -> - push_path( - _capture@1, - <<"values"/utf8>> - ) - end - ) - end, - fun(V@1) -> {ok, {K@1, V@1}} end - ) - end - ) - end - ) - end, - fun(Pairs) -> {ok, gleam@dict:from_list(Pairs)} end - ) - end - ) - end. - --spec map( - fun((dynamic_()) -> {ok, EDT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EDV} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, gleam@dict:dict(EDT, EDV)} | - {error, list(decode_error())}). -map(Key_type, Value_type) -> - dict(Key_type, Value_type). - --spec decode2( - fun((EEM, EEN) -> EEO), - fun((dynamic_()) -> {ok, EEM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EEN} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EEO} | {error, list(decode_error())}). -decode2(Constructor, T1, T2) -> - fun(Value) -> case {T1(Value), T2(Value)} of - {{ok, A}, {ok, B}} -> - {ok, Constructor(A, B)}; - - {A@1, B@1} -> - {error, gleam@list:concat([all_errors(A@1), all_errors(B@1)])} - end end. - --spec decode3( - fun((EES, EET, EEU) -> EEV), - fun((dynamic_()) -> {ok, EES} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EET} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EEU} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EEV} | {error, list(decode_error())}). -decode3(Constructor, T1, T2, T3) -> - fun(Value) -> case {T1(Value), T2(Value), T3(Value)} of - {{ok, A}, {ok, B}, {ok, C}} -> - {ok, Constructor(A, B, C)}; - - {A@1, B@1, C@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), all_errors(B@1), all_errors(C@1)] - )} - end end. - --spec decode4( - fun((EFA, EFB, EFC, EFD) -> EFE), - fun((dynamic_()) -> {ok, EFA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFD} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EFE} | {error, list(decode_error())}). -decode4(Constructor, T1, T2, T3, T4) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}} -> - {ok, Constructor(A, B, C, D)}; - - {A@1, B@1, C@1, D@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1)] - )} - end end. - --spec decode5( - fun((EFK, EFL, EFM, EFN, EFO) -> EFP), - fun((dynamic_()) -> {ok, EFK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFO} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EFP} | {error, list(decode_error())}). -decode5(Constructor, T1, T2, T3, T4, T5) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}} -> - {ok, Constructor(A, B, C, D, E)}; - - {A@1, B@1, C@1, D@1, E@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1)] - )} - end end. - --spec decode6( - fun((EFW, EFX, EFY, EFZ, EGA, EGB) -> EGC), - fun((dynamic_()) -> {ok, EFW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFX} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EFZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGB} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EGC} | {error, list(decode_error())}). -decode6(Constructor, T1, T2, T3, T4, T5, T6) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}} -> - {ok, Constructor(A, B, C, D, E, F)}; - - {A@1, B@1, C@1, D@1, E@1, F@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1)] - )} - end end. - --spec decode7( - fun((EGK, EGL, EGM, EGN, EGO, EGP, EGQ) -> EGR), - fun((dynamic_()) -> {ok, EGK} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGL} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGM} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGN} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGO} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGP} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EGQ} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EGR} | {error, list(decode_error())}). -decode7(Constructor, T1, T2, T3, T4, T5, T6, T7) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X)} of - {{ok, A}, {ok, B}, {ok, C}, {ok, D}, {ok, E}, {ok, F}, {ok, G}} -> - {ok, Constructor(A, B, C, D, E, F, G)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1)] - )} - end end. - --spec decode8( - fun((EHA, EHB, EHC, EHD, EHE, EHF, EHG, EHH) -> EHI), - fun((dynamic_()) -> {ok, EHA} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHB} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHC} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHD} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHE} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHF} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHG} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHH} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EHI} | {error, list(decode_error())}). -decode8(Constructor, T1, T2, T3, T4, T5, T6, T7, T8) -> - fun(X) -> case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}} -> - {ok, Constructor(A, B, C, D, E, F, G, H)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1)] - )} - end end. - --spec decode9( - fun((EHS, EHT, EHU, EHV, EHW, EHX, EHY, EHZ, EIA) -> EIB), - fun((dynamic_()) -> {ok, EHS} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHT} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHU} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHV} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHW} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHX} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHY} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EHZ} | {error, list(decode_error())}), - fun((dynamic_()) -> {ok, EIA} | {error, list(decode_error())}) -) -> fun((dynamic_()) -> {ok, EIB} | {error, list(decode_error())}). -decode9(Constructor, T1, T2, T3, T4, T5, T6, T7, T8, T9) -> - fun(X) -> - case {T1(X), T2(X), T3(X), T4(X), T5(X), T6(X), T7(X), T8(X), T9(X)} of - {{ok, A}, - {ok, B}, - {ok, C}, - {ok, D}, - {ok, E}, - {ok, F}, - {ok, G}, - {ok, H}, - {ok, I}} -> - {ok, Constructor(A, B, C, D, E, F, G, H, I)}; - - {A@1, B@1, C@1, D@1, E@1, F@1, G@1, H@1, I@1} -> - {error, - gleam@list:concat( - [all_errors(A@1), - all_errors(B@1), - all_errors(C@1), - all_errors(D@1), - all_errors(E@1), - all_errors(F@1), - all_errors(G@1), - all_errors(H@1), - all_errors(I@1)] - )} - end - end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl deleted file mode 100644 index 33b3d4a..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@float.erl +++ /dev/null @@ -1,181 +0,0 @@ --module(gleam@float). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, to_string/1, compare/2, min/2, max/2, clamp/3, ceiling/1, floor/1, round/1, truncate/1, absolute_value/1, loosely_compare/3, loosely_equals/3, power/2, square_root/1, negate/1, sum/1, product/1, random/2, divide/2, add/2, multiply/2, subtract/2]). - --spec parse(binary()) -> {ok, float()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_float(String). - --spec to_string(float()) -> binary(). -to_string(X) -> - gleam_stdlib:float_to_string(X). - --spec compare(float(), float()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(float(), float()) -> float(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(float(), float()) -> float(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(float(), float(), float()) -> float(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec ceiling(float()) -> float(). -ceiling(X) -> - math:ceil(X). - --spec floor(float()) -> float(). -floor(X) -> - math:floor(X). - --spec round(float()) -> integer(). -round(X) -> - erlang:round(X). - --spec truncate(float()) -> integer(). -truncate(X) -> - erlang:trunc(X). - --spec absolute_value(float()) -> float(). -absolute_value(X) -> - case X >= +0.0 of - true -> - X; - - _ -> - +0.0 - X - end. - --spec loosely_compare(float(), float(), float()) -> gleam@order:order(). -loosely_compare(A, B, Tolerance) -> - Difference = absolute_value(A - B), - case Difference =< Tolerance of - true -> - eq; - - false -> - compare(A, B) - end. - --spec loosely_equals(float(), float(), float()) -> boolean(). -loosely_equals(A, B, Tolerance) -> - Difference = absolute_value(A - B), - Difference =< Tolerance. - --spec power(float(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - Fractional = (ceiling(Exponent) - Exponent) > +0.0, - case ((Base < +0.0) andalso Fractional) orelse ((Base =:= +0.0) andalso (Exponent - < +0.0)) of - true -> - {error, nil}; - - false -> - {ok, math:pow(Base, Exponent)} - end. - --spec square_root(float()) -> {ok, float()} | {error, nil}. -square_root(X) -> - power(X, 0.5). - --spec negate(float()) -> float(). -negate(X) -> - -1.0 * X. - --spec do_sum(list(float()), float()) -> float(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(float())) -> float(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, +0.0). - --spec do_product(list(float()), float()) -> float(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(float())) -> float(). -product(Numbers) -> - case Numbers of - [] -> - 1.0; - - _ -> - do_product(Numbers, 1.0) - end. - --spec random(float(), float()) -> float(). -random(Min, Max) -> - (rand:uniform() * (Max - Min)) + Min. - --spec divide(float(), float()) -> {ok, float()} | {error, nil}. -divide(A, B) -> - case B of - +0.0 -> - {error, nil}; - - B@1 -> - {ok, case B@1 of - +0.0 -> +0.0; - -0.0 -> -0.0; - Gleam@denominator -> A / Gleam@denominator - end} - end. - --spec add(float(), float()) -> float(). -add(A, B) -> - A + B. - --spec multiply(float(), float()) -> float(). -multiply(A, B) -> - A * B. - --spec subtract(float(), float()) -> float(). -subtract(A, B) -> - A - B. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl deleted file mode 100644 index 3496318..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@function.erl +++ /dev/null @@ -1,67 +0,0 @@ --module(gleam@function). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compose/2, curry2/1, curry3/1, curry4/1, curry5/1, curry6/1, flip/1, identity/1, constant/1, tap/2, apply1/2, apply2/3, apply3/4]). - --spec compose(fun((DOO) -> DOP), fun((DOP) -> DOQ)) -> fun((DOO) -> DOQ). -compose(Fun1, Fun2) -> - fun(A) -> Fun2(Fun1(A)) end. - --spec curry2(fun((DOR, DOS) -> DOT)) -> fun((DOR) -> fun((DOS) -> DOT)). -curry2(Fun) -> - fun(A) -> fun(B) -> Fun(A, B) end end. - --spec curry3(fun((DOV, DOW, DOX) -> DOY)) -> fun((DOV) -> fun((DOW) -> fun((DOX) -> DOY))). -curry3(Fun) -> - fun(A) -> fun(B) -> fun(C) -> Fun(A, B, C) end end end. - --spec curry4(fun((DPA, DPB, DPC, DPD) -> DPE)) -> fun((DPA) -> fun((DPB) -> fun((DPC) -> fun((DPD) -> DPE)))). -curry4(Fun) -> - fun(A) -> fun(B) -> fun(C) -> fun(D) -> Fun(A, B, C, D) end end end end. - --spec curry5(fun((DPG, DPH, DPI, DPJ, DPK) -> DPL)) -> fun((DPG) -> fun((DPH) -> fun((DPI) -> fun((DPJ) -> fun((DPK) -> DPL))))). -curry5(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> fun(D) -> fun(E) -> Fun(A, B, C, D, E) end end end - end - end. - --spec curry6(fun((DPN, DPO, DPP, DPQ, DPR, DPS) -> DPT)) -> fun((DPN) -> fun((DPO) -> fun((DPP) -> fun((DPQ) -> fun((DPR) -> fun((DPS) -> DPT)))))). -curry6(Fun) -> - fun(A) -> - fun(B) -> - fun(C) -> - fun(D) -> fun(E) -> fun(F) -> Fun(A, B, C, D, E, F) end end end - end - end - end. - --spec flip(fun((DPV, DPW) -> DPX)) -> fun((DPW, DPV) -> DPX). -flip(Fun) -> - fun(B, A) -> Fun(A, B) end. - --spec identity(DPY) -> DPY. -identity(X) -> - X. - --spec constant(DPZ) -> fun((any()) -> DPZ). -constant(Value) -> - fun(_) -> Value end. - --spec tap(DQB, fun((DQB) -> any())) -> DQB. -tap(Arg, Effect) -> - Effect(Arg), - Arg. - --spec apply1(fun((DQD) -> DQE), DQD) -> DQE. -apply1(Fun, Arg1) -> - Fun(Arg1). - --spec apply2(fun((DQF, DQG) -> DQH), DQF, DQG) -> DQH. -apply2(Fun, Arg1, Arg2) -> - Fun(Arg1, Arg2). - --spec apply3(fun((DQI, DQJ, DQK) -> DQL), DQI, DQJ, DQK) -> DQL. -apply3(Fun, Arg1, Arg2, Arg3) -> - Fun(Arg1, Arg2, Arg3). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl deleted file mode 100644 index 2a5dd2c..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@int.erl +++ /dev/null @@ -1,332 +0,0 @@ --module(gleam@int). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([absolute_value/1, parse/1, base_parse/2, to_string/1, to_base_string/2, to_base2/1, to_base8/1, to_base16/1, to_base36/1, to_float/1, power/2, square_root/1, compare/2, min/2, max/2, clamp/3, is_even/1, is_odd/1, negate/1, sum/1, product/1, digits/2, undigits/2, random/2, divide/2, remainder/2, modulo/2, floor_divide/2, add/2, multiply/2, subtract/2, bitwise_and/2, bitwise_not/1, bitwise_or/2, bitwise_exclusive_or/2, bitwise_shift_left/2, bitwise_shift_right/2]). --export_type([invalid_base/0]). - --type invalid_base() :: invalid_base. - --spec absolute_value(integer()) -> integer(). -absolute_value(X) -> - case X >= 0 of - true -> - X; - - false -> - X * -1 - end. - --spec parse(binary()) -> {ok, integer()} | {error, nil}. -parse(String) -> - gleam_stdlib:parse_int(String). - --spec base_parse(binary(), integer()) -> {ok, integer()} | {error, nil}. -base_parse(String, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - gleam_stdlib:int_from_base_string(String, Base); - - false -> - {error, nil} - end. - --spec to_string(integer()) -> binary(). -to_string(X) -> - erlang:integer_to_binary(X). - --spec to_base_string(integer(), integer()) -> {ok, binary()} | - {error, invalid_base()}. -to_base_string(X, Base) -> - case (Base >= 2) andalso (Base =< 36) of - true -> - {ok, erlang:integer_to_binary(X, Base)}; - - false -> - {error, invalid_base} - end. - --spec to_base2(integer()) -> binary(). -to_base2(X) -> - erlang:integer_to_binary(X, 2). - --spec to_base8(integer()) -> binary(). -to_base8(X) -> - erlang:integer_to_binary(X, 8). - --spec to_base16(integer()) -> binary(). -to_base16(X) -> - erlang:integer_to_binary(X, 16). - --spec to_base36(integer()) -> binary(). -to_base36(X) -> - erlang:integer_to_binary(X, 36). - --spec to_float(integer()) -> float(). -to_float(X) -> - erlang:float(X). - --spec power(integer(), float()) -> {ok, float()} | {error, nil}. -power(Base, Exponent) -> - _pipe = Base, - _pipe@1 = to_float(_pipe), - gleam@float:power(_pipe@1, Exponent). - --spec square_root(integer()) -> {ok, float()} | {error, nil}. -square_root(X) -> - _pipe = X, - _pipe@1 = to_float(_pipe), - gleam@float:square_root(_pipe@1). - --spec compare(integer(), integer()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - false -> - case A < B of - true -> - lt; - - false -> - gt - end - end. - --spec min(integer(), integer()) -> integer(). -min(A, B) -> - case A < B of - true -> - A; - - false -> - B - end. - --spec max(integer(), integer()) -> integer(). -max(A, B) -> - case A > B of - true -> - A; - - false -> - B - end. - --spec clamp(integer(), integer(), integer()) -> integer(). -clamp(X, Min_bound, Max_bound) -> - _pipe = X, - _pipe@1 = min(_pipe, Max_bound), - max(_pipe@1, Min_bound). - --spec is_even(integer()) -> boolean(). -is_even(X) -> - (X rem 2) =:= 0. - --spec is_odd(integer()) -> boolean(). -is_odd(X) -> - (X rem 2) /= 0. - --spec negate(integer()) -> integer(). -negate(X) -> - -1 * X. - --spec do_sum(list(integer()), integer()) -> integer(). -do_sum(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_sum(Rest, X + Initial) - end. - --spec sum(list(integer())) -> integer(). -sum(Numbers) -> - _pipe = Numbers, - do_sum(_pipe, 0). - --spec do_product(list(integer()), integer()) -> integer(). -do_product(Numbers, Initial) -> - case Numbers of - [] -> - Initial; - - [X | Rest] -> - do_product(Rest, X * Initial) - end. - --spec product(list(integer())) -> integer(). -product(Numbers) -> - case Numbers of - [] -> - 1; - - _ -> - do_product(Numbers, 1) - end. - --spec do_digits(integer(), integer(), list(integer())) -> list(integer()). -do_digits(X, Base, Acc) -> - case absolute_value(X) < Base of - true -> - [X | Acc]; - - false -> - do_digits(case Base of - 0 -> 0; - Gleam@denominator -> X div Gleam@denominator - end, Base, [case Base of - 0 -> 0; - Gleam@denominator@1 -> X rem Gleam@denominator@1 - end | Acc]) - end. - --spec digits(integer(), integer()) -> {ok, list(integer())} | - {error, invalid_base()}. -digits(X, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - {ok, do_digits(X, Base, [])} - end. - --spec do_undigits(list(integer()), integer(), integer()) -> {ok, integer()} | - {error, invalid_base()}. -do_undigits(Numbers, Base, Acc) -> - case Numbers of - [] -> - {ok, Acc}; - - [Digit | _] when Digit >= Base -> - {error, invalid_base}; - - [Digit@1 | Rest] -> - do_undigits(Rest, Base, (Acc * Base) + Digit@1) - end. - --spec undigits(list(integer()), integer()) -> {ok, integer()} | - {error, invalid_base()}. -undigits(Numbers, Base) -> - case Base < 2 of - true -> - {error, invalid_base}; - - false -> - do_undigits(Numbers, Base, 0) - end. - --spec random(integer(), integer()) -> integer(). -random(Min, Max) -> - _pipe = gleam@float:random(to_float(Min), to_float(Max)), - _pipe@1 = gleam@float:floor(_pipe), - gleam@float:round(_pipe@1). - --spec divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend div Gleam@denominator - end} - end. - --spec remainder(integer(), integer()) -> {ok, integer()} | {error, nil}. -remainder(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end} - end. - --spec modulo(integer(), integer()) -> {ok, integer()} | {error, nil}. -modulo(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - _ -> - Remainder = case Divisor of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end, - case (Remainder * Divisor) < 0 of - true -> - {ok, Remainder + Divisor}; - - false -> - {ok, Remainder} - end - end. - --spec floor_divide(integer(), integer()) -> {ok, integer()} | {error, nil}. -floor_divide(Dividend, Divisor) -> - case Divisor of - 0 -> - {error, nil}; - - Divisor@1 -> - case ((Dividend * Divisor@1) < 0) andalso ((case Divisor@1 of - 0 -> 0; - Gleam@denominator -> Dividend rem Gleam@denominator - end) /= 0) of - true -> - {ok, (case Divisor@1 of - 0 -> 0; - Gleam@denominator@1 -> Dividend div Gleam@denominator@1 - end) - 1}; - - false -> - {ok, case Divisor@1 of - 0 -> 0; - Gleam@denominator@2 -> Dividend div Gleam@denominator@2 - end} - end - end. - --spec add(integer(), integer()) -> integer(). -add(A, B) -> - A + B. - --spec multiply(integer(), integer()) -> integer(). -multiply(A, B) -> - A * B. - --spec subtract(integer(), integer()) -> integer(). -subtract(A, B) -> - A - B. - --spec bitwise_and(integer(), integer()) -> integer(). -bitwise_and(X, Y) -> - erlang:'band'(X, Y). - --spec bitwise_not(integer()) -> integer(). -bitwise_not(X) -> - erlang:'bnot'(X). - --spec bitwise_or(integer(), integer()) -> integer(). -bitwise_or(X, Y) -> - erlang:'bor'(X, Y). - --spec bitwise_exclusive_or(integer(), integer()) -> integer(). -bitwise_exclusive_or(X, Y) -> - erlang:'bxor'(X, Y). - --spec bitwise_shift_left(integer(), integer()) -> integer(). -bitwise_shift_left(X, Y) -> - erlang:'bsl'(X, Y). - --spec bitwise_shift_right(integer(), integer()) -> integer(). -bitwise_shift_right(X, Y) -> - erlang:'bsr'(X, Y). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl deleted file mode 100644 index a46eae3..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@io.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(gleam@io). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([print/1, print_error/1, println/1, println_error/1, debug/1]). - --spec print(binary()) -> nil. -print(String) -> - gleam_stdlib:print(String). - --spec print_error(binary()) -> nil. -print_error(String) -> - gleam_stdlib:print_error(String). - --spec println(binary()) -> nil. -println(String) -> - gleam_stdlib:println(String). - --spec println_error(binary()) -> nil. -println_error(String) -> - gleam_stdlib:println_error(String). - --spec debug(CZT) -> CZT. -debug(Term) -> - _pipe = Term, - _pipe@1 = gleam@string:inspect(_pipe), - gleam_stdlib:println_error(_pipe@1), - Term. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl deleted file mode 100644 index aa84139..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@iterator.erl +++ /dev/null @@ -1,744 +0,0 @@ --module(gleam@iterator). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([unfold/2, repeatedly/1, repeat/1, from_list/1, transform/3, fold/3, run/1, to_list/1, step/1, take/2, drop/2, map/2, map2/3, append/2, flatten/1, concat/1, flat_map/2, filter/2, cycle/1, find/2, index/1, iterate/2, take_while/2, drop_while/2, scan/3, zip/2, chunk/2, sized_chunk/2, intersperse/2, any/2, all/2, group/2, reduce/2, last/1, empty/0, once/1, range/2, single/1, interleave/2, fold_until/3, try_fold/3, first/1, at/2, length/1, each/2, yield/2]). --export_type([action/1, iterator/1, step/2, chunk/2, sized_chunk/1]). - --type action(BPF) :: stop | {continue, BPF, fun(() -> action(BPF))}. - --opaque iterator(BPG) :: {iterator, fun(() -> action(BPG))}. - --type step(BPH, BPI) :: {next, BPH, BPI} | done. - --type chunk(BPJ, BPK) :: {another_by, - list(BPJ), - BPK, - BPJ, - fun(() -> action(BPJ))} | - {last_by, list(BPJ)}. - --type sized_chunk(BPL) :: {another, list(BPL), fun(() -> action(BPL))} | - {last, list(BPL)} | - no_more. - --spec stop() -> action(any()). -stop() -> - stop. - --spec do_unfold(BPO, fun((BPO) -> step(BPP, BPO))) -> fun(() -> action(BPP)). -do_unfold(Initial, F) -> - fun() -> case F(Initial) of - {next, X, Acc} -> - {continue, X, do_unfold(Acc, F)}; - - done -> - stop - end end. - --spec unfold(BPT, fun((BPT) -> step(BPU, BPT))) -> iterator(BPU). -unfold(Initial, F) -> - _pipe = Initial, - _pipe@1 = do_unfold(_pipe, F), - {iterator, _pipe@1}. - --spec repeatedly(fun(() -> BPY)) -> iterator(BPY). -repeatedly(F) -> - unfold(nil, fun(_) -> {next, F(), nil} end). - --spec repeat(BQA) -> iterator(BQA). -repeat(X) -> - repeatedly(fun() -> X end). - --spec from_list(list(BQC)) -> iterator(BQC). -from_list(List) -> - Yield = fun(Acc) -> case Acc of - [] -> - done; - - [Head | Tail] -> - {next, Head, Tail} - end end, - unfold(List, Yield). - --spec do_transform( - fun(() -> action(BQF)), - BQH, - fun((BQH, BQF) -> step(BQI, BQH)) -) -> fun(() -> action(BQI)). -do_transform(Continuation, State, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - case F(State, El) of - done -> - stop; - - {next, Yield, Next_state} -> - {continue, Yield, do_transform(Next, Next_state, F)} - end - end end. - --spec transform(iterator(BQM), BQO, fun((BQO, BQM) -> step(BQP, BQO))) -> iterator(BQP). -transform(Iterator, Initial, F) -> - _pipe = do_transform(erlang:element(2, Iterator), Initial, F), - {iterator, _pipe}. - --spec do_fold(fun(() -> action(BQT)), fun((BQV, BQT) -> BQV), BQV) -> BQV. -do_fold(Continuation, F, Accumulator) -> - case Continuation() of - {continue, Elem, Next} -> - do_fold(Next, F, F(Accumulator, Elem)); - - stop -> - Accumulator - end. - --spec fold(iterator(BQW), BQY, fun((BQY, BQW) -> BQY)) -> BQY. -fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold(_pipe, F, Initial). - --spec run(iterator(any())) -> nil. -run(Iterator) -> - fold(Iterator, nil, fun(_, _) -> nil end). - --spec to_list(iterator(BRB)) -> list(BRB). -to_list(Iterator) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, [], fun(Acc, E) -> [E | Acc] end), - gleam@list:reverse(_pipe@1). - --spec step(iterator(BRE)) -> step(BRE, iterator(BRE)). -step(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - done; - - {continue, E, A} -> - {next, E, {iterator, A}} - end. - --spec do_take(fun(() -> action(BRJ)), integer()) -> fun(() -> action(BRJ)). -do_take(Continuation, Desired) -> - fun() -> case Desired > 0 of - false -> - stop; - - true -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, do_take(Next, Desired - 1)} - end - end end. - --spec take(iterator(BRM), integer()) -> iterator(BRM). -take(Iterator, Desired) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take(_pipe, Desired), - {iterator, _pipe@1}. - --spec do_drop(fun(() -> action(BRP)), integer()) -> action(BRP). -do_drop(Continuation, Desired) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Desired > 0 of - true -> - do_drop(Next, Desired - 1); - - false -> - {continue, E, Next} - end - end. - --spec drop(iterator(BRS), integer()) -> iterator(BRS). -drop(Iterator, Desired) -> - _pipe = fun() -> do_drop(erlang:element(2, Iterator), Desired) end, - {iterator, _pipe}. - --spec do_map(fun(() -> action(BRV)), fun((BRV) -> BRX)) -> fun(() -> action(BRX)). -do_map(Continuation, F) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, F(E), do_map(Continuation@1, F)} - end end. - --spec map(iterator(BRZ), fun((BRZ) -> BSB)) -> iterator(BSB). -map(Iterator, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_map(_pipe, F), - {iterator, _pipe@1}. - --spec do_map2( - fun(() -> action(BSD)), - fun(() -> action(BSF)), - fun((BSD, BSF) -> BSH) -) -> fun(() -> action(BSH)). -do_map2(Continuation1, Continuation2, Fun) -> - fun() -> case Continuation1() of - stop -> - stop; - - {continue, A, Next_a} -> - case Continuation2() of - stop -> - stop; - - {continue, B, Next_b} -> - {continue, Fun(A, B), do_map2(Next_a, Next_b, Fun)} - end - end end. - --spec map2(iterator(BSJ), iterator(BSL), fun((BSJ, BSL) -> BSN)) -> iterator(BSN). -map2(Iterator1, Iterator2, Fun) -> - _pipe = do_map2( - erlang:element(2, Iterator1), - erlang:element(2, Iterator2), - Fun - ), - {iterator, _pipe}. - --spec do_append(fun(() -> action(BSP)), fun(() -> action(BSP))) -> action(BSP). -do_append(First, Second) -> - case First() of - {continue, E, First@1} -> - {continue, E, fun() -> do_append(First@1, Second) end}; - - stop -> - Second() - end. - --spec append(iterator(BST), iterator(BST)) -> iterator(BST). -append(First, Second) -> - _pipe = fun() -> - do_append(erlang:element(2, First), erlang:element(2, Second)) - end, - {iterator, _pipe}. - --spec do_flatten(fun(() -> action(iterator(BSX)))) -> action(BSX). -do_flatten(Flattened) -> - case Flattened() of - stop -> - stop; - - {continue, It, Next_iterator} -> - do_append( - erlang:element(2, It), - fun() -> do_flatten(Next_iterator) end - ) - end. - --spec flatten(iterator(iterator(BTB))) -> iterator(BTB). -flatten(Iterator) -> - _pipe = fun() -> do_flatten(erlang:element(2, Iterator)) end, - {iterator, _pipe}. - --spec concat(list(iterator(BTF))) -> iterator(BTF). -concat(Iterators) -> - flatten(from_list(Iterators)). - --spec flat_map(iterator(BTJ), fun((BTJ) -> iterator(BTL))) -> iterator(BTL). -flat_map(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - flatten(_pipe@1). - --spec do_filter(fun(() -> action(BTO)), fun((BTO) -> boolean())) -> action(BTO). -do_filter(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Iterator} -> - case Predicate(E) of - true -> - {continue, E, fun() -> do_filter(Iterator, Predicate) end}; - - false -> - do_filter(Iterator, Predicate) - end - end. - --spec filter(iterator(BTR), fun((BTR) -> boolean())) -> iterator(BTR). -filter(Iterator, Predicate) -> - _pipe = fun() -> do_filter(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec cycle(iterator(BTU)) -> iterator(BTU). -cycle(Iterator) -> - _pipe = repeat(Iterator), - flatten(_pipe). - --spec do_find(fun(() -> action(BTY)), fun((BTY) -> boolean())) -> {ok, BTY} | - {error, nil}. -do_find(Continuation, F) -> - case Continuation() of - stop -> - {error, nil}; - - {continue, E, Next} -> - case F(E) of - true -> - {ok, E}; - - false -> - do_find(Next, F) - end - end. - --spec find(iterator(BUC), fun((BUC) -> boolean())) -> {ok, BUC} | {error, nil}. -find(Haystack, Is_desired) -> - _pipe = erlang:element(2, Haystack), - do_find(_pipe, Is_desired). - --spec do_index(fun(() -> action(BUG)), integer()) -> fun(() -> action({integer(), - BUG})). -do_index(Continuation, Next) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Continuation@1} -> - {continue, {Next, E}, do_index(Continuation@1, Next + 1)} - end end. - --spec index(iterator(BUJ)) -> iterator({integer(), BUJ}). -index(Iterator) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_index(_pipe, 0), - {iterator, _pipe@1}. - --spec iterate(BUM, fun((BUM) -> BUM)) -> iterator(BUM). -iterate(Initial, F) -> - unfold(Initial, fun(Element) -> {next, Element, F(Element)} end). - --spec do_take_while(fun(() -> action(BUO)), fun((BUO) -> boolean())) -> fun(() -> action(BUO)). -do_take_while(Continuation, Predicate) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - stop; - - true -> - {continue, E, do_take_while(Next, Predicate)} - end - end end. - --spec take_while(iterator(BUR), fun((BUR) -> boolean())) -> iterator(BUR). -take_while(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_take_while(_pipe, Predicate), - {iterator, _pipe@1}. - --spec do_drop_while(fun(() -> action(BUU)), fun((BUU) -> boolean())) -> action(BUU). -do_drop_while(Continuation, Predicate) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - case Predicate(E) of - false -> - {continue, E, Next}; - - true -> - do_drop_while(Next, Predicate) - end - end. - --spec drop_while(iterator(BUX), fun((BUX) -> boolean())) -> iterator(BUX). -drop_while(Iterator, Predicate) -> - _pipe = fun() -> do_drop_while(erlang:element(2, Iterator), Predicate) end, - {iterator, _pipe}. - --spec do_scan(fun(() -> action(BVA)), fun((BVC, BVA) -> BVC), BVC) -> fun(() -> action(BVC)). -do_scan(Continuation, F, Accumulator) -> - fun() -> case Continuation() of - stop -> - stop; - - {continue, El, Next} -> - Accumulated = F(Accumulator, El), - {continue, Accumulated, do_scan(Next, F, Accumulated)} - end end. - --spec scan(iterator(BVE), BVG, fun((BVG, BVE) -> BVG)) -> iterator(BVG). -scan(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_scan(_pipe, F, Initial), - {iterator, _pipe@1}. - --spec do_zip(fun(() -> action(BVI)), fun(() -> action(BVK))) -> fun(() -> action({BVI, - BVK})). -do_zip(Left, Right) -> - fun() -> case Left() of - stop -> - stop; - - {continue, El_left, Next_left} -> - case Right() of - stop -> - stop; - - {continue, El_right, Next_right} -> - {continue, - {El_left, El_right}, - do_zip(Next_left, Next_right)} - end - end end. - --spec zip(iterator(BVN), iterator(BVP)) -> iterator({BVN, BVP}). -zip(Left, Right) -> - _pipe = do_zip(erlang:element(2, Left), erlang:element(2, Right)), - {iterator, _pipe}. - --spec next_chunk(fun(() -> action(BVS)), fun((BVS) -> BVU), BVU, list(BVS)) -> chunk(BVS, BVU). -next_chunk(Continuation, F, Previous_key, Current_chunk) -> - case Continuation() of - stop -> - {last_by, gleam@list:reverse(Current_chunk)}; - - {continue, E, Next} -> - Key = F(E), - case Key =:= Previous_key of - true -> - next_chunk(Next, F, Key, [E | Current_chunk]); - - false -> - {another_by, - gleam@list:reverse(Current_chunk), - Key, - E, - Next} - end - end. - --spec do_chunk(fun(() -> action(BVY)), fun((BVY) -> BWA), BWA, BVY) -> action(list(BVY)). -do_chunk(Continuation, F, Previous_key, Previous_element) -> - case next_chunk(Continuation, F, Previous_key, [Previous_element]) of - {last_by, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another_by, Chunk@1, Key, El, Next} -> - {continue, Chunk@1, fun() -> do_chunk(Next, F, Key, El) end} - end. - --spec chunk(iterator(BWD), fun((BWD) -> any())) -> iterator(list(BWD)). -chunk(Iterator, F) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - do_chunk(Next, F, F(E), E) - end end, - {iterator, _pipe}. - --spec next_sized_chunk(fun(() -> action(BWI)), integer(), list(BWI)) -> sized_chunk(BWI). -next_sized_chunk(Continuation, Left, Current_chunk) -> - case Continuation() of - stop -> - case Current_chunk of - [] -> - no_more; - - Remaining -> - {last, gleam@list:reverse(Remaining)} - end; - - {continue, E, Next} -> - Chunk = [E | Current_chunk], - case Left > 1 of - false -> - {another, gleam@list:reverse(Chunk), Next}; - - true -> - next_sized_chunk(Next, Left - 1, Chunk) - end - end. - --spec do_sized_chunk(fun(() -> action(BWM)), integer()) -> fun(() -> action(list(BWM))). -do_sized_chunk(Continuation, Count) -> - fun() -> case next_sized_chunk(Continuation, Count, []) of - no_more -> - stop; - - {last, Chunk} -> - {continue, Chunk, fun stop/0}; - - {another, Chunk@1, Next_element} -> - {continue, Chunk@1, do_sized_chunk(Next_element, Count)} - end end. - --spec sized_chunk(iterator(BWQ), integer()) -> iterator(list(BWQ)). -sized_chunk(Iterator, Count) -> - _pipe = erlang:element(2, Iterator), - _pipe@1 = do_sized_chunk(_pipe, Count), - {iterator, _pipe@1}. - --spec do_intersperse(fun(() -> action(BWU)), BWU) -> action(BWU). -do_intersperse(Continuation, Separator) -> - case Continuation() of - stop -> - stop; - - {continue, E, Next} -> - Next_interspersed = fun() -> do_intersperse(Next, Separator) end, - {continue, Separator, fun() -> {continue, E, Next_interspersed} end} - end. - --spec intersperse(iterator(BWX), BWX) -> iterator(BWX). -intersperse(Iterator, Elem) -> - _pipe = fun() -> case (erlang:element(2, Iterator))() of - stop -> - stop; - - {continue, E, Next} -> - {continue, E, fun() -> do_intersperse(Next, Elem) end} - end end, - {iterator, _pipe}. - --spec do_any(fun(() -> action(BXA)), fun((BXA) -> boolean())) -> boolean(). -do_any(Continuation, Predicate) -> - case Continuation() of - stop -> - false; - - {continue, E, Next} -> - case Predicate(E) of - true -> - true; - - false -> - do_any(Next, Predicate) - end - end. - --spec any(iterator(BXC), fun((BXC) -> boolean())) -> boolean(). -any(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_any(_pipe, Predicate). - --spec do_all(fun(() -> action(BXE)), fun((BXE) -> boolean())) -> boolean(). -do_all(Continuation, Predicate) -> - case Continuation() of - stop -> - true; - - {continue, E, Next} -> - case Predicate(E) of - true -> - do_all(Next, Predicate); - - false -> - false - end - end. - --spec all(iterator(BXG), fun((BXG) -> boolean())) -> boolean(). -all(Iterator, Predicate) -> - _pipe = erlang:element(2, Iterator), - do_all(_pipe, Predicate). - --spec update_group_with(BXI) -> fun((gleam@option:option(list(BXI))) -> list(BXI)). -update_group_with(El) -> - fun(Maybe_group) -> case Maybe_group of - {some, Group} -> - [El | Group]; - - none -> - [El] - end end. - --spec group_updater(fun((BXM) -> BXN)) -> fun((gleam@dict:dict(BXN, list(BXM)), BXM) -> gleam@dict:dict(BXN, list(BXM))). -group_updater(F) -> - fun(Groups, Elem) -> _pipe = Groups, - gleam@dict:update(_pipe, F(Elem), update_group_with(Elem)) end. - --spec group(iterator(BXU), fun((BXU) -> BXW)) -> gleam@dict:dict(BXW, list(BXU)). -group(Iterator, Key) -> - _pipe = Iterator, - _pipe@1 = fold(_pipe, gleam@dict:new(), group_updater(Key)), - gleam@dict:map_values( - _pipe@1, - fun(_, Group) -> gleam@list:reverse(Group) end - ). - --spec reduce(iterator(BYA), fun((BYA, BYA) -> BYA)) -> {ok, BYA} | {error, nil}. -reduce(Iterator, F) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, Next} -> - _pipe = do_fold(Next, F, E), - {ok, _pipe} - end. - --spec last(iterator(BYE)) -> {ok, BYE} | {error, nil}. -last(Iterator) -> - _pipe = Iterator, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec empty() -> iterator(any()). -empty() -> - {iterator, fun stop/0}. - --spec once(fun(() -> BYK)) -> iterator(BYK). -once(F) -> - _pipe = fun() -> {continue, F(), fun stop/0} end, - {iterator, _pipe}. - --spec range(integer(), integer()) -> iterator(integer()). -range(Start, Stop) -> - case gleam@int:compare(Start, Stop) of - eq -> - once(fun() -> Start end); - - gt -> - unfold(Start, fun(Current) -> case Current < Stop of - false -> - {next, Current, Current - 1}; - - true -> - done - end end); - - lt -> - unfold(Start, fun(Current@1) -> case Current@1 > Stop of - false -> - {next, Current@1, Current@1 + 1}; - - true -> - done - end end) - end. - --spec single(BYM) -> iterator(BYM). -single(Elem) -> - once(fun() -> Elem end). - --spec do_interleave(fun(() -> action(BYO)), fun(() -> action(BYO))) -> action(BYO). -do_interleave(Current, Next) -> - case Current() of - stop -> - Next(); - - {continue, E, Next_other} -> - {continue, E, fun() -> do_interleave(Next, Next_other) end} - end. - --spec interleave(iterator(BYS), iterator(BYS)) -> iterator(BYS). -interleave(Left, Right) -> - _pipe = fun() -> - do_interleave(erlang:element(2, Left), erlang:element(2, Right)) - end, - {iterator, _pipe}. - --spec do_fold_until( - fun(() -> action(BYW)), - fun((BYY, BYW) -> gleam@list:continue_or_stop(BYY)), - BYY -) -> BYY. -do_fold_until(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - Accumulator; - - {continue, Elem, Next} -> - case F(Accumulator, Elem) of - {continue, Accumulator@1} -> - do_fold_until(Next, F, Accumulator@1); - - {stop, Accumulator@2} -> - Accumulator@2 - end - end. - --spec fold_until( - iterator(BZA), - BZC, - fun((BZC, BZA) -> gleam@list:continue_or_stop(BZC)) -) -> BZC. -fold_until(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_fold_until(_pipe, F, Initial). - --spec do_try_fold( - fun(() -> action(BZE)), - fun((BZG, BZE) -> {ok, BZG} | {error, BZH}), - BZG -) -> {ok, BZG} | {error, BZH}. -do_try_fold(Continuation, F, Accumulator) -> - case Continuation() of - stop -> - {ok, Accumulator}; - - {continue, Elem, Next} -> - gleam@result:'try'( - F(Accumulator, Elem), - fun(Accumulator@1) -> do_try_fold(Next, F, Accumulator@1) end - ) - end. - --spec try_fold(iterator(BZM), BZO, fun((BZO, BZM) -> {ok, BZO} | {error, BZP})) -> {ok, - BZO} | - {error, BZP}. -try_fold(Iterator, Initial, F) -> - _pipe = erlang:element(2, Iterator), - do_try_fold(_pipe, F, Initial). - --spec first(iterator(BZU)) -> {ok, BZU} | {error, nil}. -first(Iterator) -> - case (erlang:element(2, Iterator))() of - stop -> - {error, nil}; - - {continue, E, _} -> - {ok, E} - end. - --spec at(iterator(BZY), integer()) -> {ok, BZY} | {error, nil}. -at(Iterator, Index) -> - _pipe = Iterator, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1). - --spec do_length(fun(() -> action(any())), integer()) -> integer(). -do_length(Continuation, Length) -> - case Continuation() of - stop -> - Length; - - {continue, _, Next} -> - do_length(Next, Length + 1) - end. - --spec length(iterator(any())) -> integer(). -length(Iterator) -> - _pipe = erlang:element(2, Iterator), - do_length(_pipe, 0). - --spec each(iterator(CAG), fun((CAG) -> any())) -> nil. -each(Iterator, F) -> - _pipe = Iterator, - _pipe@1 = map(_pipe, F), - run(_pipe@1). - --spec yield(CAJ, fun(() -> iterator(CAJ))) -> iterator(CAJ). -yield(Element, Next) -> - {iterator, fun() -> {continue, Element, erlang:element(2, Next())} end}. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl deleted file mode 100644 index 6c2e684..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@list.erl +++ /dev/null @@ -1,1129 +0,0 @@ --module(gleam@list). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([length/1, reverse/1, is_empty/1, contains/2, first/1, rest/1, filter/2, filter_map/2, map/2, map2/3, index_map/2, try_map/2, drop/2, take/2, new/0, append/2, prepend/2, concat/1, flatten/1, flat_map/2, fold/3, group/2, map_fold/3, fold_right/3, index_fold/3, try_fold/3, fold_until/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, unzip/1, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2, key_filter/2, pop/2, pop_map/2, key_pop/2, key_set/3, each/2, try_each/2, partition/2, permutations/1, window/2, window_by_2/1, drop_while/2, take_while/2, chunk/2, sized_chunk/2, reduce/2, scan/3, last/1, combinations/2, combination_pairs/1, transpose/1, interleave/1, shuffle/1]). --export_type([length_mismatch/0, continue_or_stop/1]). - --type length_mismatch() :: length_mismatch. - --type continue_or_stop(UD) :: {continue, UD} | {stop, UD}. - --spec length(list(any())) -> integer(). -length(List) -> - erlang:length(List). - --spec reverse(list(UI)) -> list(UI). -reverse(Xs) -> - lists:reverse(Xs). - --spec is_empty(list(any())) -> boolean(). -is_empty(List) -> - List =:= []. - --spec contains(list(UQ), UQ) -> boolean(). -contains(List, Elem) -> - case List of - [] -> - false; - - [First | _] when First =:= Elem -> - true; - - [_ | Rest] -> - contains(Rest, Elem) - end. - --spec first(list(US)) -> {ok, US} | {error, nil}. -first(List) -> - case List of - [] -> - {error, nil}; - - [X | _] -> - {ok, X} - end. - --spec rest(list(UW)) -> {ok, list(UW)} | {error, nil}. -rest(List) -> - case List of - [] -> - {error, nil}; - - [_ | Xs] -> - {ok, Xs} - end. - --spec update_group(fun((VB) -> VC)) -> fun((gleam@dict:dict(VC, list(VB)), VB) -> gleam@dict:dict(VC, list(VB))). -update_group(F) -> - fun(Groups, Elem) -> case gleam@dict:get(Groups, F(Elem)) of - {ok, Existing} -> - gleam@dict:insert(Groups, F(Elem), [Elem | Existing]); - - {error, _} -> - gleam@dict:insert(Groups, F(Elem), [Elem]) - end end. - --spec do_filter(list(VP), fun((VP) -> boolean()), list(VP)) -> list(VP). -do_filter(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - true -> - [X | Acc]; - - false -> - Acc - end, - do_filter(Xs, Fun, New_acc) - end. - --spec filter(list(VT), fun((VT) -> boolean())) -> list(VT). -filter(List, Predicate) -> - do_filter(List, Predicate, []). - --spec do_filter_map(list(VW), fun((VW) -> {ok, VY} | {error, any()}), list(VY)) -> list(VY). -do_filter_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - New_acc = case Fun(X) of - {ok, X@1} -> - [X@1 | Acc]; - - {error, _} -> - Acc - end, - do_filter_map(Xs, Fun, New_acc) - end. - --spec filter_map(list(WE), fun((WE) -> {ok, WG} | {error, any()})) -> list(WG). -filter_map(List, Fun) -> - do_filter_map(List, Fun, []). - --spec do_map(list(WL), fun((WL) -> WN), list(WN)) -> list(WN). -do_map(List, Fun, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_map(Xs, Fun, [Fun(X) | Acc]) - end. - --spec map(list(WQ), fun((WQ) -> WS)) -> list(WS). -map(List, Fun) -> - do_map(List, Fun, []). - --spec do_map2(list(XA), list(XC), fun((XA, XC) -> XE), list(XE)) -> list(XE). -do_map2(List1, List2, Fun, Acc) -> - case {List1, List2} of - {[], _} -> - reverse(Acc); - - {_, []} -> - reverse(Acc); - - {[A | As_], [B | Bs]} -> - do_map2(As_, Bs, Fun, [Fun(A, B) | Acc]) - end. - --spec map2(list(WU), list(WW), fun((WU, WW) -> WY)) -> list(WY). -map2(List1, List2, Fun) -> - do_map2(List1, List2, Fun, []). - --spec do_index_map(list(XM), fun((integer(), XM) -> XO), integer(), list(XO)) -> list(XO). -do_index_map(List, Fun, Index, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - Acc@1 = [Fun(Index, X) | Acc], - do_index_map(Xs, Fun, Index + 1, Acc@1) - end. - --spec index_map(list(XR), fun((integer(), XR) -> XT)) -> list(XT). -index_map(List, Fun) -> - do_index_map(List, Fun, 0, []). - --spec do_try_map(list(XV), fun((XV) -> {ok, XX} | {error, XY}), list(XX)) -> {ok, - list(XX)} | - {error, XY}. -do_try_map(List, Fun, Acc) -> - case List of - [] -> - {ok, reverse(Acc)}; - - [X | Xs] -> - case Fun(X) of - {ok, Y} -> - do_try_map(Xs, Fun, [Y | Acc]); - - {error, Error} -> - {error, Error} - end - end. - --spec try_map(list(YF), fun((YF) -> {ok, YH} | {error, YI})) -> {ok, list(YH)} | - {error, YI}. -try_map(List, Fun) -> - do_try_map(List, Fun, []). - --spec drop(list(YO), integer()) -> list(YO). -drop(List, N) -> - case N =< 0 of - true -> - List; - - false -> - case List of - [] -> - []; - - [_ | Xs] -> - drop(Xs, N - 1) - end - end. - --spec do_take(list(YR), integer(), list(YR)) -> list(YR). -do_take(List, N, Acc) -> - case N =< 0 of - true -> - reverse(Acc); - - false -> - case List of - [] -> - reverse(Acc); - - [X | Xs] -> - do_take(Xs, N - 1, [X | Acc]) - end - end. - --spec take(list(YV), integer()) -> list(YV). -take(List, N) -> - do_take(List, N, []). - --spec new() -> list(any()). -new() -> - []. - --spec append(list(AAA), list(AAA)) -> list(AAA). -append(First, Second) -> - lists:append(First, Second). - --spec prepend(list(AAI), AAI) -> list(AAI). -prepend(List, Item) -> - [Item | List]. - --spec reverse_and_prepend(list(AAL), list(AAL)) -> list(AAL). -reverse_and_prepend(Prefix, Suffix) -> - case Prefix of - [] -> - Suffix; - - [First | Rest] -> - reverse_and_prepend(Rest, [First | Suffix]) - end. - --spec do_concat(list(list(AAP)), list(AAP)) -> list(AAP). -do_concat(Lists, Acc) -> - case Lists of - [] -> - reverse(Acc); - - [List | Further_lists] -> - do_concat(Further_lists, reverse_and_prepend(List, Acc)) - end. - --spec concat(list(list(AAU))) -> list(AAU). -concat(Lists) -> - do_concat(Lists, []). - --spec flatten(list(list(AAY))) -> list(AAY). -flatten(Lists) -> - do_concat(Lists, []). - --spec flat_map(list(ABC), fun((ABC) -> list(ABE))) -> list(ABE). -flat_map(List, Fun) -> - _pipe = map(List, Fun), - concat(_pipe). - --spec fold(list(ABH), ABJ, fun((ABJ, ABH) -> ABJ)) -> ABJ. -fold(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - fold(Rest, Fun(Initial, X), Fun) - end. - --spec group(list(VJ), fun((VJ) -> VL)) -> gleam@dict:dict(VL, list(VJ)). -group(List, Key) -> - fold(List, gleam@dict:new(), update_group(Key)). - --spec map_fold(list(XH), XJ, fun((XJ, XH) -> {XJ, XK})) -> {XJ, list(XK)}. -map_fold(List, Acc, Fun) -> - _pipe = fold( - List, - {Acc, []}, - fun(Acc@1, Item) -> - {Current_acc, Items} = Acc@1, - {Next_acc, Next_item} = Fun(Current_acc, Item), - {Next_acc, [Next_item | Items]} - end - ), - gleam@pair:map_second(_pipe, fun reverse/1). - --spec fold_right(list(ABK), ABM, fun((ABM, ABK) -> ABM)) -> ABM. -fold_right(List, Initial, Fun) -> - case List of - [] -> - Initial; - - [X | Rest] -> - Fun(fold_right(Rest, Initial, Fun), X) - end. - --spec do_index_fold( - list(ABN), - ABP, - fun((ABP, ABN, integer()) -> ABP), - integer() -) -> ABP. -do_index_fold(Over, Acc, With, Index) -> - case Over of - [] -> - Acc; - - [First | Rest] -> - do_index_fold(Rest, With(Acc, First, Index), With, Index + 1) - end. - --spec index_fold(list(ABQ), ABS, fun((ABS, ABQ, integer()) -> ABS)) -> ABS. -index_fold(Over, Initial, Fun) -> - do_index_fold(Over, Initial, Fun, 0). - --spec try_fold(list(ABT), ABV, fun((ABV, ABT) -> {ok, ABV} | {error, ABW})) -> {ok, - ABV} | - {error, ABW}. -try_fold(Collection, Accumulator, Fun) -> - case Collection of - [] -> - {ok, Accumulator}; - - [First | Rest] -> - case Fun(Accumulator, First) of - {ok, Result} -> - try_fold(Rest, Result, Fun); - - {error, _} = Error -> - Error - end - end. - --spec fold_until(list(ACB), ACD, fun((ACD, ACB) -> continue_or_stop(ACD))) -> ACD. -fold_until(Collection, Accumulator, Fun) -> - case Collection of - [] -> - Accumulator; - - [First | Rest] -> - case Fun(Accumulator, First) of - {continue, Next_accumulator} -> - fold_until(Rest, Next_accumulator, Fun); - - {stop, B} -> - B - end - end. - --spec find(list(ACF), fun((ACF) -> boolean())) -> {ok, ACF} | {error, nil}. -find(Haystack, Is_desired) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Is_desired(X) of - true -> - {ok, X}; - - _ -> - find(Rest, Is_desired) - end - end. - --spec find_map(list(ACJ), fun((ACJ) -> {ok, ACL} | {error, any()})) -> {ok, ACL} | - {error, nil}. -find_map(Haystack, Fun) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Fun(X) of - {ok, X@1} -> - {ok, X@1}; - - _ -> - find_map(Rest, Fun) - end - end. - --spec all(list(ACR), fun((ACR) -> boolean())) -> boolean(). -all(List, Predicate) -> - case List of - [] -> - true; - - [First | Rest] -> - case Predicate(First) of - true -> - all(Rest, Predicate); - - false -> - false - end - end. - --spec any(list(ACT), fun((ACT) -> boolean())) -> boolean(). -any(List, Predicate) -> - case List of - [] -> - false; - - [First | Rest] -> - case Predicate(First) of - true -> - true; - - false -> - any(Rest, Predicate) - end - end. - --spec do_zip(list(ACV), list(ACX), list({ACV, ACX})) -> list({ACV, ACX}). -do_zip(Xs, Ys, Acc) -> - case {Xs, Ys} of - {[X | Xs@1], [Y | Ys@1]} -> - do_zip(Xs@1, Ys@1, [{X, Y} | Acc]); - - {_, _} -> - reverse(Acc) - end. - --spec zip(list(ADB), list(ADD)) -> list({ADB, ADD}). -zip(List, Other) -> - do_zip(List, Other, []). - --spec strict_zip(list(ADG), list(ADI)) -> {ok, list({ADG, ADI})} | - {error, length_mismatch()}. -strict_zip(List, Other) -> - case length(List) =:= length(Other) of - true -> - {ok, zip(List, Other)}; - - false -> - {error, length_mismatch} - end. - --spec do_unzip(list({ATA, ATB}), list(ATA), list(ATB)) -> {list(ATA), list(ATB)}. -do_unzip(Input, Xs, Ys) -> - case Input of - [] -> - {reverse(Xs), reverse(Ys)}; - - [{X, Y} | Rest] -> - do_unzip(Rest, [X | Xs], [Y | Ys]) - end. - --spec unzip(list({ADR, ADS})) -> {list(ADR), list(ADS)}. -unzip(Input) -> - do_unzip(Input, [], []). - --spec do_intersperse(list(ADW), ADW, list(ADW)) -> list(ADW). -do_intersperse(List, Separator, Acc) -> - case List of - [] -> - reverse(Acc); - - [X | Rest] -> - do_intersperse(Rest, Separator, [X, Separator | Acc]) - end. - --spec intersperse(list(AEA), AEA) -> list(AEA). -intersperse(List, Elem) -> - case List of - [] -> - List; - - [_] -> - List; - - [X | Rest] -> - do_intersperse(Rest, Elem, [X]) - end. - --spec at(list(AED), integer()) -> {ok, AED} | {error, nil}. -at(List, Index) -> - case Index >= 0 of - true -> - _pipe = List, - _pipe@1 = drop(_pipe, Index), - first(_pipe@1); - - false -> - {error, nil} - end. - --spec unique(list(AEH)) -> list(AEH). -unique(List) -> - case List of - [] -> - []; - - [X | Rest] -> - [X | unique(filter(Rest, fun(Y) -> Y /= X end))] - end. - --spec merge_up( - integer(), - integer(), - list(AEK), - list(AEK), - list(AEK), - fun((AEK, AEK) -> gleam@order:order()) -) -> list(AEK). -merge_up(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_up(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_up(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Ax@1, Bx@1) of - gt -> - merge_up(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare); - - _ -> - merge_up(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_down( - integer(), - integer(), - list(AEP), - list(AEP), - list(AEP), - fun((AEP, AEP) -> gleam@order:order()) -) -> list(AEP). -merge_down(Na, Nb, A, B, Acc, Compare) -> - case {Na, Nb, A, B} of - {0, 0, _, _} -> - Acc; - - {_, 0, [Ax | Ar], _} -> - merge_down(Na - 1, Nb, Ar, B, [Ax | Acc], Compare); - - {0, _, _, [Bx | Br]} -> - merge_down(Na, Nb - 1, A, Br, [Bx | Acc], Compare); - - {_, _, [Ax@1 | Ar@1], [Bx@1 | Br@1]} -> - case Compare(Bx@1, Ax@1) of - lt -> - merge_down(Na - 1, Nb, Ar@1, B, [Ax@1 | Acc], Compare); - - _ -> - merge_down(Na, Nb - 1, A, Br@1, [Bx@1 | Acc], Compare) - end; - - {_, _, _, _} -> - Acc - end. - --spec merge_sort( - list(AEU), - integer(), - fun((AEU, AEU) -> gleam@order:order()), - boolean() -) -> list(AEU). -merge_sort(L, Ln, Compare, Down) -> - N = Ln div 2, - A = L, - B = drop(L, N), - case Ln < 3 of - true -> - case Down of - true -> - merge_down(N, Ln - N, A, B, [], Compare); - - false -> - merge_up(N, Ln - N, A, B, [], Compare) - end; - - false -> - case Down of - true -> - merge_down( - N, - Ln - N, - merge_sort(A, N, Compare, false), - merge_sort(B, Ln - N, Compare, false), - [], - Compare - ); - - false -> - merge_up( - N, - Ln - N, - merge_sort(A, N, Compare, true), - merge_sort(B, Ln - N, Compare, true), - [], - Compare - ) - end - end. - --spec sort(list(AEX), fun((AEX, AEX) -> gleam@order:order())) -> list(AEX). -sort(List, Compare) -> - merge_sort(List, length(List), Compare, true). - --spec tail_recursive_range(integer(), integer(), list(integer())) -> list(integer()). -tail_recursive_range(Start, Stop, Acc) -> - case gleam@int:compare(Start, Stop) of - eq -> - [Stop | Acc]; - - gt -> - tail_recursive_range(Start, Stop + 1, [Stop | Acc]); - - lt -> - tail_recursive_range(Start, Stop - 1, [Stop | Acc]) - end. - --spec range(integer(), integer()) -> list(integer()). -range(Start, Stop) -> - tail_recursive_range(Start, Stop, []). - --spec do_repeat(AFD, integer(), list(AFD)) -> list(AFD). -do_repeat(A, Times, Acc) -> - case Times =< 0 of - true -> - Acc; - - false -> - do_repeat(A, Times - 1, [A | Acc]) - end. - --spec repeat(AFG, integer()) -> list(AFG). -repeat(A, Times) -> - do_repeat(A, Times, []). - --spec do_split(list(AFI), integer(), list(AFI)) -> {list(AFI), list(AFI)}. -do_split(List, N, Taken) -> - case N =< 0 of - true -> - {reverse(Taken), List}; - - false -> - case List of - [] -> - {reverse(Taken), []}; - - [X | Xs] -> - do_split(Xs, N - 1, [X | Taken]) - end - end. - --spec split(list(AFN), integer()) -> {list(AFN), list(AFN)}. -split(List, Index) -> - do_split(List, Index, []). - --spec do_split_while(list(AFR), fun((AFR) -> boolean()), list(AFR)) -> {list(AFR), - list(AFR)}. -do_split_while(List, F, Acc) -> - case List of - [] -> - {reverse(Acc), []}; - - [X | Xs] -> - case F(X) of - false -> - {reverse(Acc), List}; - - _ -> - do_split_while(Xs, F, [X | Acc]) - end - end. - --spec split_while(list(AFW), fun((AFW) -> boolean())) -> {list(AFW), list(AFW)}. -split_while(List, Predicate) -> - do_split_while(List, Predicate, []). - --spec key_find(list({AGA, AGB}), AGA) -> {ok, AGB} | {error, nil}. -key_find(Keyword_list, Desired_key) -> - find_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec key_filter(list({AGF, AGG}), AGF) -> list(AGG). -key_filter(Keyword_list, Desired_key) -> - filter_map( - Keyword_list, - fun(Keyword) -> - {Key, Value} = Keyword, - case Key =:= Desired_key of - true -> - {ok, Value}; - - false -> - {error, nil} - end - end - ). - --spec do_pop(list(AWT), fun((AWT) -> boolean()), list(AWT)) -> {ok, - {AWT, list(AWT)}} | - {error, nil}. -do_pop(Haystack, Predicate, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Predicate(X) of - true -> - {ok, {X, append(reverse(Checked), Rest)}}; - - false -> - do_pop(Rest, Predicate, [X | Checked]) - end - end. - --spec pop(list(AGN), fun((AGN) -> boolean())) -> {ok, {AGN, list(AGN)}} | - {error, nil}. -pop(Haystack, Is_desired) -> - do_pop(Haystack, Is_desired, []). - --spec do_pop_map(list(AXH), fun((AXH) -> {ok, AXU} | {error, any()}), list(AXH)) -> {ok, - {AXU, list(AXH)}} | - {error, nil}. -do_pop_map(Haystack, Mapper, Checked) -> - case Haystack of - [] -> - {error, nil}; - - [X | Rest] -> - case Mapper(X) of - {ok, Y} -> - {ok, {Y, append(reverse(Checked), Rest)}}; - - {error, _} -> - do_pop_map(Rest, Mapper, [X | Checked]) - end - end. - --spec pop_map(list(AGW), fun((AGW) -> {ok, AGY} | {error, any()})) -> {ok, - {AGY, list(AGW)}} | - {error, nil}. -pop_map(Haystack, Is_desired) -> - do_pop_map(Haystack, Is_desired, []). - --spec key_pop(list({AHF, AHG}), AHF) -> {ok, {AHG, list({AHF, AHG})}} | - {error, nil}. -key_pop(Haystack, Key) -> - pop_map( - Haystack, - fun(Entry) -> - {K, V} = Entry, - case K of - K@1 when K@1 =:= Key -> - {ok, V}; - - _ -> - {error, nil} - end - end - ). - --spec key_set(list({AHL, AHM}), AHL, AHM) -> list({AHL, AHM}). -key_set(List, Key, Value) -> - case List of - [] -> - [{Key, Value}]; - - [{K, _} | Rest] when K =:= Key -> - [{Key, Value} | Rest]; - - [First | Rest@1] -> - [First | key_set(Rest@1, Key, Value)] - end. - --spec each(list(AHP), fun((AHP) -> any())) -> nil. -each(List, F) -> - case List of - [] -> - nil; - - [X | Xs] -> - F(X), - each(Xs, F) - end. - --spec try_each(list(AHS), fun((AHS) -> {ok, any()} | {error, AHV})) -> {ok, nil} | - {error, AHV}. -try_each(List, Fun) -> - case List of - [] -> - {ok, nil}; - - [X | Xs] -> - case Fun(X) of - {ok, _} -> - try_each(Xs, Fun); - - {error, E} -> - {error, E} - end - end. - --spec do_partition(list(AZB), fun((AZB) -> boolean()), list(AZB), list(AZB)) -> {list(AZB), - list(AZB)}. -do_partition(List, Categorise, Trues, Falses) -> - case List of - [] -> - {reverse(Trues), reverse(Falses)}; - - [X | Xs] -> - case Categorise(X) of - true -> - do_partition(Xs, Categorise, [X | Trues], Falses); - - false -> - do_partition(Xs, Categorise, Trues, [X | Falses]) - end - end. - --spec partition(list(AIF), fun((AIF) -> boolean())) -> {list(AIF), list(AIF)}. -partition(List, Categorise) -> - do_partition(List, Categorise, [], []). - --spec permutations(list(AIJ)) -> list(list(AIJ)). -permutations(L) -> - case L of - [] -> - [[]]; - - _ -> - _pipe = L, - _pipe@5 = index_map(_pipe, fun(I_idx, I) -> _pipe@1 = L, - _pipe@2 = index_fold( - _pipe@1, - [], - fun(Acc, J, J_idx) -> case I_idx =:= J_idx of - true -> - Acc; - - false -> - [J | Acc] - end end - ), - _pipe@3 = reverse(_pipe@2), - _pipe@4 = permutations(_pipe@3), - map(_pipe@4, fun(Permutation) -> [I | Permutation] end) end), - concat(_pipe@5) - end. - --spec do_window(list(list(AIN)), list(AIN), integer()) -> list(list(AIN)). -do_window(Acc, L, N) -> - Window = take(L, N), - case length(Window) =:= N of - true -> - do_window([Window | Acc], drop(L, 1), N); - - false -> - Acc - end. - --spec window(list(AIT), integer()) -> list(list(AIT)). -window(L, N) -> - _pipe = do_window([], L, N), - reverse(_pipe). - --spec window_by_2(list(AIX)) -> list({AIX, AIX}). -window_by_2(L) -> - zip(L, drop(L, 1)). - --spec drop_while(list(AJA), fun((AJA) -> boolean())) -> list(AJA). -drop_while(List, Predicate) -> - case List of - [] -> - []; - - [X | Xs] -> - case Predicate(X) of - true -> - drop_while(Xs, Predicate); - - false -> - [X | Xs] - end - end. - --spec do_take_while(list(AJD), fun((AJD) -> boolean()), list(AJD)) -> list(AJD). -do_take_while(List, Predicate, Acc) -> - case List of - [] -> - reverse(Acc); - - [First | Rest] -> - case Predicate(First) of - true -> - do_take_while(Rest, Predicate, [First | Acc]); - - false -> - reverse(Acc) - end - end. - --spec take_while(list(AJH), fun((AJH) -> boolean())) -> list(AJH). -take_while(List, Predicate) -> - do_take_while(List, Predicate, []). - --spec do_chunk(list(AJK), fun((AJK) -> AJM), AJM, list(AJK), list(list(AJK))) -> list(list(AJK)). -do_chunk(List, F, Previous_key, Current_chunk, Acc) -> - case List of - [First | Rest] -> - Key = F(First), - case Key =:= Previous_key of - false -> - New_acc = [reverse(Current_chunk) | Acc], - do_chunk(Rest, F, Key, [First], New_acc); - - _ -> - do_chunk(Rest, F, Key, [First | Current_chunk], Acc) - end; - - _ -> - reverse([reverse(Current_chunk) | Acc]) - end. - --spec chunk(list(AJS), fun((AJS) -> any())) -> list(list(AJS)). -chunk(List, F) -> - case List of - [] -> - []; - - [First | Rest] -> - do_chunk(Rest, F, F(First), [First], []) - end. - --spec do_sized_chunk( - list(AJX), - integer(), - integer(), - list(AJX), - list(list(AJX)) -) -> list(list(AJX)). -do_sized_chunk(List, Count, Left, Current_chunk, Acc) -> - case List of - [] -> - case Current_chunk of - [] -> - reverse(Acc); - - Remaining -> - reverse([reverse(Remaining) | Acc]) - end; - - [First | Rest] -> - Chunk = [First | Current_chunk], - case Left > 1 of - false -> - do_sized_chunk( - Rest, - Count, - Count, - [], - [reverse(Chunk) | Acc] - ); - - true -> - do_sized_chunk(Rest, Count, Left - 1, Chunk, Acc) - end - end. - --spec sized_chunk(list(AKE), integer()) -> list(list(AKE)). -sized_chunk(List, Count) -> - do_sized_chunk(List, Count, Count, [], []). - --spec reduce(list(AKI), fun((AKI, AKI) -> AKI)) -> {ok, AKI} | {error, nil}. -reduce(List, Fun) -> - case List of - [] -> - {error, nil}; - - [First | Rest] -> - {ok, fold(Rest, First, Fun)} - end. - --spec do_scan(list(AKM), AKO, list(AKO), fun((AKO, AKM) -> AKO)) -> list(AKO). -do_scan(List, Accumulator, Accumulated, Fun) -> - case List of - [] -> - reverse(Accumulated); - - [X | Xs] -> - Next = Fun(Accumulator, X), - do_scan(Xs, Next, [Next | Accumulated], Fun) - end. - --spec scan(list(AKR), AKT, fun((AKT, AKR) -> AKT)) -> list(AKT). -scan(List, Initial, Fun) -> - do_scan(List, Initial, [], Fun). - --spec last(list(AKV)) -> {ok, AKV} | {error, nil}. -last(List) -> - _pipe = List, - reduce(_pipe, fun(_, Elem) -> Elem end). - --spec combinations(list(AKZ), integer()) -> list(list(AKZ)). -combinations(Items, N) -> - case N of - 0 -> - [[]]; - - _ -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = begin - _pipe = map( - combinations(Xs, N - 1), - fun(Com) -> [X | Com] end - ), - reverse(_pipe) - end, - fold( - First_combinations, - combinations(Xs, N), - fun(Acc, C) -> [C | Acc] end - ) - end - end. - --spec do_combination_pairs(list(ALD)) -> list(list({ALD, ALD})). -do_combination_pairs(Items) -> - case Items of - [] -> - []; - - [X | Xs] -> - First_combinations = map(Xs, fun(Other) -> {X, Other} end), - [First_combinations | do_combination_pairs(Xs)] - end. - --spec combination_pairs(list(ALH)) -> list({ALH, ALH}). -combination_pairs(Items) -> - _pipe = do_combination_pairs(Items), - concat(_pipe). - --spec transpose(list(list(ALO))) -> list(list(ALO)). -transpose(List_of_list) -> - Take_first = fun(List) -> case List of - [] -> - []; - - [F] -> - [F]; - - [F@1 | _] -> - [F@1] - end end, - case List_of_list of - [] -> - []; - - [[] | Xss] -> - transpose(Xss); - - Rows -> - Firsts = begin - _pipe = Rows, - _pipe@1 = map(_pipe, Take_first), - concat(_pipe@1) - end, - Rest = transpose(map(Rows, fun(_capture) -> drop(_capture, 1) end)), - [Firsts | Rest] - end. - --spec interleave(list(list(ALK))) -> list(ALK). -interleave(List) -> - _pipe = transpose(List), - concat(_pipe). - --spec do_shuffle_pair_unwrap(list({float(), ALT}), list(ALT)) -> list(ALT). -do_shuffle_pair_unwrap(List, Acc) -> - case List of - [] -> - Acc; - - [Elem_pair | Enumerable] -> - do_shuffle_pair_unwrap( - Enumerable, - [erlang:element(2, Elem_pair) | Acc] - ) - end. - --spec do_shuffle_by_pair_indexes(list({float(), ALX})) -> list({float(), ALX}). -do_shuffle_by_pair_indexes(List_of_pairs) -> - sort( - List_of_pairs, - fun(A_pair, B_pair) -> - gleam@float:compare( - erlang:element(1, A_pair), - erlang:element(1, B_pair) - ) - end - ). - --spec shuffle(list(AMA)) -> list(AMA). -shuffle(List) -> - _pipe = List, - _pipe@1 = fold( - _pipe, - [], - fun(Acc, A) -> [{gleam@float:random(+0.0, 1.0), A} | Acc] end - ), - _pipe@2 = do_shuffle_by_pair_indexes(_pipe@1), - do_shuffle_pair_unwrap(_pipe@2, []). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl deleted file mode 100644 index 33e89a9..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@map.erl +++ /dev/null @@ -1,76 +0,0 @@ --module(gleam@map). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([size/1, to_list/1, from_list/1, has_key/2, new/0, get/2, insert/3, map_values/2, keys/1, values/1, filter/2, take/2, merge/2, delete/2, drop/2, update/3, fold/3]). - --spec size(gleam@dict:dict(any(), any())) -> integer(). -size(Map) -> - gleam@dict:size(Map). - --spec to_list(gleam@dict:dict(DAJ, DAK)) -> list({DAJ, DAK}). -to_list(Map) -> - gleam@dict:to_list(Map). - --spec from_list(list({DAM, DAN})) -> gleam@dict:dict(DAM, DAN). -from_list(List) -> - gleam@dict:from_list(List). - --spec has_key(gleam@dict:dict(DAR, any()), DAR) -> boolean(). -has_key(Map, Key) -> - gleam@dict:has_key(Map, Key). - --spec new() -> gleam@dict:dict(any(), any()). -new() -> - gleam@dict:new(). - --spec get(gleam@dict:dict(DAU, DAV), DAU) -> {ok, DAV} | {error, nil}. -get(From, Get) -> - gleam@dict:get(From, Get). - --spec insert(gleam@dict:dict(DAZ, DBA), DAZ, DBA) -> gleam@dict:dict(DAZ, DBA). -insert(Map, Key, Value) -> - gleam@dict:insert(Map, Key, Value). - --spec map_values(gleam@dict:dict(DBD, DBE), fun((DBD, DBE) -> DBF)) -> gleam@dict:dict(DBD, DBF). -map_values(Map, Fun) -> - gleam@dict:map_values(Map, Fun). - --spec keys(gleam@dict:dict(DBI, any())) -> list(DBI). -keys(Map) -> - gleam@dict:keys(Map). - --spec values(gleam@dict:dict(any(), DBL)) -> list(DBL). -values(Map) -> - gleam@dict:values(Map). - --spec filter(gleam@dict:dict(DBO, DBP), fun((DBO, DBP) -> boolean())) -> gleam@dict:dict(DBO, DBP). -filter(Map, Predicate) -> - gleam@dict:filter(Map, Predicate). - --spec take(gleam@dict:dict(DBS, DDM), list(DBS)) -> gleam@dict:dict(DBS, DDM). -take(Map, Desired_keys) -> - gleam@dict:take(Map, Desired_keys). - --spec merge(gleam@dict:dict(DDN, DDO), gleam@dict:dict(DDN, DDO)) -> gleam@dict:dict(DDN, DDO). -merge(Map, New_entries) -> - gleam@dict:merge(Map, New_entries). - --spec delete(gleam@dict:dict(DBZ, DDQ), DBZ) -> gleam@dict:dict(DBZ, DDQ). -delete(Map, Key) -> - gleam@dict:delete(Map, Key). - --spec drop(gleam@dict:dict(DCC, DDS), list(DCC)) -> gleam@dict:dict(DCC, DDS). -drop(Map, Disallowed_keys) -> - gleam@dict:drop(Map, Disallowed_keys). - --spec update( - gleam@dict:dict(DCG, DCH), - DCG, - fun((gleam@option:option(DCH)) -> DCH) -) -> gleam@dict:dict(DCG, DCH). -update(Map, Key, Fun) -> - gleam@dict:update(Map, Key, Fun). - --spec fold(gleam@dict:dict(DCM, DCN), DCL, fun((DCL, DCM, DCN) -> DCL)) -> DCL. -fold(Map, Initial, Fun) -> - gleam@dict:fold(Map, Initial, Fun). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl deleted file mode 100644 index 5c20713..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@option.erl +++ /dev/null @@ -1,147 +0,0 @@ --module(gleam@option). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([all/1, is_some/1, is_none/1, to_result/2, from_result/1, unwrap/2, lazy_unwrap/2, map/2, flatten/1, then/2, 'or'/2, lazy_or/2, values/1]). --export_type([option/1]). - --type option(GB) :: {some, GB} | none. - --spec do_all(list(option(GC)), list(GC)) -> option(list(GC)). -do_all(List, Acc) -> - case List of - [] -> - {some, Acc}; - - [X | Rest] -> - Accumulate = fun(Acc@1, Item) -> case {Acc@1, Item} of - {{some, Values}, {some, Value}} -> - {some, [Value | Values]}; - - {_, _} -> - none - end end, - Accumulate(do_all(Rest, Acc), X) - end. - --spec all(list(option(GI))) -> option(list(GI)). -all(List) -> - do_all(List, []). - --spec is_some(option(any())) -> boolean(). -is_some(Option) -> - Option /= none. - --spec is_none(option(any())) -> boolean(). -is_none(Option) -> - Option =:= none. - --spec to_result(option(GR), GU) -> {ok, GR} | {error, GU}. -to_result(Option, E) -> - case Option of - {some, A} -> - {ok, A}; - - _ -> - {error, E} - end. - --spec from_result({ok, GX} | {error, any()}) -> option(GX). -from_result(Result) -> - case Result of - {ok, A} -> - {some, A}; - - _ -> - none - end. - --spec unwrap(option(HC), HC) -> HC. -unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default - end. - --spec lazy_unwrap(option(HE), fun(() -> HE)) -> HE. -lazy_unwrap(Option, Default) -> - case Option of - {some, X} -> - X; - - none -> - Default() - end. - --spec map(option(HG), fun((HG) -> HI)) -> option(HI). -map(Option, Fun) -> - case Option of - {some, X} -> - {some, Fun(X)}; - - none -> - none - end. - --spec flatten(option(option(HK))) -> option(HK). -flatten(Option) -> - case Option of - {some, X} -> - X; - - none -> - none - end. - --spec then(option(HO), fun((HO) -> option(HQ))) -> option(HQ). -then(Option, Fun) -> - case Option of - {some, X} -> - Fun(X); - - none -> - none - end. - --spec 'or'(option(HT), option(HT)) -> option(HT). -'or'(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second - end. - --spec lazy_or(option(HX), fun(() -> option(HX))) -> option(HX). -lazy_or(First, Second) -> - case First of - {some, _} -> - First; - - none -> - Second() - end. - --spec do_values(list(option(IB)), list(IB)) -> list(IB). -do_values(List, Acc) -> - case List of - [] -> - Acc; - - [X | Xs] -> - Accumulate = fun(Acc@1, Item) -> case Item of - {some, Value} -> - [Value | Acc@1]; - - none -> - Acc@1 - end end, - Accumulate(do_values(Xs, Acc), X) - end. - --spec values(list(option(IG))) -> list(IG). -values(Options) -> - do_values(Options, []). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl deleted file mode 100644 index 61649b9..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@order.erl +++ /dev/null @@ -1,79 +0,0 @@ --module(gleam@order). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([negate/1, to_int/1, compare/2, max/2, min/2, reverse/1]). --export_type([order/0]). - --type order() :: lt | eq | gt. - --spec negate(order()) -> order(). -negate(Order) -> - case Order of - lt -> - gt; - - eq -> - eq; - - gt -> - lt - end. - --spec to_int(order()) -> integer(). -to_int(Order) -> - case Order of - lt -> - -1; - - eq -> - 0; - - gt -> - 1 - end. - --spec compare(order(), order()) -> order(). -compare(A, B) -> - case {A, B} of - {X, Y} when X =:= Y -> - eq; - - {lt, _} -> - lt; - - {eq, gt} -> - lt; - - {_, _} -> - gt - end. - --spec max(order(), order()) -> order(). -max(A, B) -> - case {A, B} of - {gt, _} -> - gt; - - {eq, lt} -> - eq; - - {_, _} -> - B - end. - --spec min(order(), order()) -> order(). -min(A, B) -> - case {A, B} of - {lt, _} -> - lt; - - {eq, gt} -> - eq; - - {_, _} -> - B - end. - --spec reverse(fun((I, I) -> order())) -> fun((I, I) -> order()). -reverse(Orderer) -> - fun(A, B) -> Orderer(B, A) end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl deleted file mode 100644 index f4eff52..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@pair.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@pair). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([first/1, second/1, swap/1, map_first/2, map_second/2, new/2]). - --spec first({FM, any()}) -> FM. -first(Pair) -> - {A, _} = Pair, - A. - --spec second({any(), FP}) -> FP. -second(Pair) -> - {_, A} = Pair, - A. - --spec swap({FQ, FR}) -> {FR, FQ}. -swap(Pair) -> - {A, B} = Pair, - {B, A}. - --spec map_first({FS, FT}, fun((FS) -> FU)) -> {FU, FT}. -map_first(Pair, Fun) -> - {A, B} = Pair, - {Fun(A), B}. - --spec map_second({FV, FW}, fun((FW) -> FX)) -> {FV, FX}. -map_second(Pair, Fun) -> - {A, B} = Pair, - {A, Fun(B)}. - --spec new(FY, FZ) -> {FY, FZ}. -new(First, Second) -> - {First, Second}. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl deleted file mode 100644 index 6b587e7..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@queue.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(gleam@queue). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, from_list/1, to_list/1, is_empty/1, length/1, push_back/2, push_front/2, pop_back/1, pop_front/1, reverse/1, is_logically_equal/3, is_equal/2]). --export_type([queue/1]). - --opaque queue(DRL) :: {queue, list(DRL), list(DRL)}. - --spec new() -> queue(any()). -new() -> - {queue, [], []}. - --spec from_list(list(DRO)) -> queue(DRO). -from_list(List) -> - {queue, [], List}. - --spec to_list(queue(DRR)) -> list(DRR). -to_list(Queue) -> - _pipe = erlang:element(3, Queue), - gleam@list:append(_pipe, gleam@list:reverse(erlang:element(2, Queue))). - --spec is_empty(queue(any())) -> boolean(). -is_empty(Queue) -> - (erlang:element(2, Queue) =:= []) andalso (erlang:element(3, Queue) =:= []). - --spec length(queue(any())) -> integer(). -length(Queue) -> - gleam@list:length(erlang:element(2, Queue)) + gleam@list:length( - erlang:element(3, Queue) - ). - --spec push_back(queue(DRY), DRY) -> queue(DRY). -push_back(Queue, Item) -> - {queue, [Item | erlang:element(2, Queue)], erlang:element(3, Queue)}. - --spec push_front(queue(DSB), DSB) -> queue(DSB). -push_front(Queue, Item) -> - {queue, erlang:element(2, Queue), [Item | erlang:element(3, Queue)]}. - --spec pop_back(queue(DSE)) -> {ok, {DSE, queue(DSE)}} | {error, nil}. -pop_back(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, [], Out} -> - pop_back({queue, gleam@list:reverse(Out), []}); - - {queue, [First | Rest], Out@1} -> - Queue@1 = {queue, Rest, Out@1}, - {ok, {First, Queue@1}} - end. - --spec pop_front(queue(DSJ)) -> {ok, {DSJ, queue(DSJ)}} | {error, nil}. -pop_front(Queue) -> - case Queue of - {queue, [], []} -> - {error, nil}; - - {queue, In, []} -> - pop_front({queue, [], gleam@list:reverse(In)}); - - {queue, In@1, [First | Rest]} -> - Queue@1 = {queue, In@1, Rest}, - {ok, {First, Queue@1}} - end. - --spec reverse(queue(DSO)) -> queue(DSO). -reverse(Queue) -> - {queue, erlang:element(3, Queue), erlang:element(2, Queue)}. - --spec check_equal( - list(DSR), - list(DSR), - list(DSR), - list(DSR), - fun((DSR, DSR) -> boolean()) -) -> boolean(). -check_equal(Xs, X_tail, Ys, Y_tail, Eq) -> - case {Xs, X_tail, Ys, Y_tail} of - {[], [], [], []} -> - true; - - {[X | Xs@1], _, [Y | Ys@1], _} -> - case Eq(X, Y) of - false -> - false; - - true -> - check_equal(Xs@1, X_tail, Ys@1, Y_tail, Eq) - end; - - {[], [_ | _], _, _} -> - check_equal(gleam@list:reverse(X_tail), [], Ys, Y_tail, Eq); - - {_, _, [], [_ | _]} -> - check_equal(Xs, X_tail, gleam@list:reverse(Y_tail), [], Eq); - - {_, _, _, _} -> - false - end. - --spec is_logically_equal(queue(DSW), queue(DSW), fun((DSW, DSW) -> boolean())) -> boolean(). -is_logically_equal(A, B, Element_is_equal) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - Element_is_equal - ). - --spec is_equal(queue(DSZ), queue(DSZ)) -> boolean(). -is_equal(A, B) -> - check_equal( - erlang:element(3, A), - erlang:element(2, A), - erlang:element(3, B), - erlang:element(2, B), - fun(A@1, B@1) -> A@1 =:= B@1 end - ). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl deleted file mode 100644 index 2d1c5fc..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@regex.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(gleam@regex). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([compile/2, from_string/1, check/2, split/2, scan/2]). --export_type([regex/0, match/0, compile_error/0, options/0]). - --type regex() :: any(). - --type match() :: {match, binary(), list(gleam@option:option(binary()))}. - --type compile_error() :: {compile_error, binary(), integer()}. - --type options() :: {options, boolean(), boolean()}. - --spec compile(binary(), options()) -> {ok, regex()} | {error, compile_error()}. -compile(Pattern, Options) -> - gleam_stdlib:compile_regex(Pattern, Options). - --spec from_string(binary()) -> {ok, regex()} | {error, compile_error()}. -from_string(Pattern) -> - compile(Pattern, {options, false, false}). - --spec check(regex(), binary()) -> boolean(). -check(Regex, Content) -> - gleam_stdlib:regex_check(Regex, Content). - --spec split(regex(), binary()) -> list(binary()). -split(Regex, String) -> - gleam_stdlib:regex_split(Regex, String). - --spec scan(regex(), binary()) -> list(match()). -scan(Regex, String) -> - gleam_stdlib:regex_scan(Regex, String). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl deleted file mode 100644 index 7324e45..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@result.erl +++ /dev/null @@ -1,201 +0,0 @@ --module(gleam@result). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_ok/1, is_error/1, map/2, map_error/2, flatten/1, 'try'/2, then/2, unwrap/2, lazy_unwrap/2, unwrap_error/2, unwrap_both/1, nil_error/1, 'or'/2, lazy_or/2, all/1, partition/1, replace/2, replace_error/2, values/1, try_recover/2]). - --spec is_ok({ok, any()} | {error, any()}) -> boolean(). -is_ok(Result) -> - case Result of - {error, _} -> - false; - - {ok, _} -> - true - end. - --spec is_error({ok, any()} | {error, any()}) -> boolean(). -is_error(Result) -> - case Result of - {ok, _} -> - false; - - {error, _} -> - true - end. - --spec map({ok, BFM} | {error, BFN}, fun((BFM) -> BFQ)) -> {ok, BFQ} | - {error, BFN}. -map(Result, Fun) -> - case Result of - {ok, X} -> - {ok, Fun(X)}; - - {error, E} -> - {error, E} - end. - --spec map_error({ok, BFT} | {error, BFU}, fun((BFU) -> BFX)) -> {ok, BFT} | - {error, BFX}. -map_error(Result, Fun) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, Error} -> - {error, Fun(Error)} - end. - --spec flatten({ok, {ok, BGA} | {error, BGB}} | {error, BGB}) -> {ok, BGA} | - {error, BGB}. -flatten(Result) -> - case Result of - {ok, X} -> - X; - - {error, Error} -> - {error, Error} - end. - --spec 'try'({ok, BGI} | {error, BGJ}, fun((BGI) -> {ok, BGM} | {error, BGJ})) -> {ok, - BGM} | - {error, BGJ}. -'try'(Result, Fun) -> - case Result of - {ok, X} -> - Fun(X); - - {error, E} -> - {error, E} - end. - --spec then({ok, BGR} | {error, BGS}, fun((BGR) -> {ok, BGV} | {error, BGS})) -> {ok, - BGV} | - {error, BGS}. -then(Result, Fun) -> - 'try'(Result, Fun). - --spec unwrap({ok, BHA} | {error, any()}, BHA) -> BHA. -unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default - end. - --spec lazy_unwrap({ok, BHE} | {error, any()}, fun(() -> BHE)) -> BHE. -lazy_unwrap(Result, Default) -> - case Result of - {ok, V} -> - V; - - {error, _} -> - Default() - end. - --spec unwrap_error({ok, any()} | {error, BHJ}, BHJ) -> BHJ. -unwrap_error(Result, Default) -> - case Result of - {ok, _} -> - Default; - - {error, E} -> - E - end. - --spec unwrap_both({ok, BHM} | {error, BHM}) -> BHM. -unwrap_both(Result) -> - case Result of - {ok, A} -> - A; - - {error, A@1} -> - A@1 - end. - --spec nil_error({ok, BHP} | {error, any()}) -> {ok, BHP} | {error, nil}. -nil_error(Result) -> - map_error(Result, fun(_) -> nil end). - --spec 'or'({ok, BHV} | {error, BHW}, {ok, BHV} | {error, BHW}) -> {ok, BHV} | - {error, BHW}. -'or'(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second - end. - --spec lazy_or({ok, BID} | {error, BIE}, fun(() -> {ok, BID} | {error, BIE})) -> {ok, - BID} | - {error, BIE}. -lazy_or(First, Second) -> - case First of - {ok, _} -> - First; - - {error, _} -> - Second() - end. - --spec all(list({ok, BIL} | {error, BIM})) -> {ok, list(BIL)} | {error, BIM}. -all(Results) -> - gleam@list:try_map(Results, fun(X) -> X end). - --spec do_partition(list({ok, BJA} | {error, BJB}), list(BJA), list(BJB)) -> {list(BJA), - list(BJB)}. -do_partition(Results, Oks, Errors) -> - case Results of - [] -> - {Oks, Errors}; - - [{ok, A} | Rest] -> - do_partition(Rest, [A | Oks], Errors); - - [{error, E} | Rest@1] -> - do_partition(Rest@1, Oks, [E | Errors]) - end. - --spec partition(list({ok, BIT} | {error, BIU})) -> {list(BIT), list(BIU)}. -partition(Results) -> - do_partition(Results, [], []). - --spec replace({ok, any()} | {error, BJJ}, BJM) -> {ok, BJM} | {error, BJJ}. -replace(Result, Value) -> - case Result of - {ok, _} -> - {ok, Value}; - - {error, Error} -> - {error, Error} - end. - --spec replace_error({ok, BJP} | {error, any()}, BJT) -> {ok, BJP} | {error, BJT}. -replace_error(Result, Error) -> - case Result of - {ok, X} -> - {ok, X}; - - {error, _} -> - {error, Error} - end. - --spec values(list({ok, BJW} | {error, any()})) -> list(BJW). -values(Results) -> - gleam@list:filter_map(Results, fun(R) -> R end). - --spec try_recover( - {ok, BKC} | {error, BKD}, - fun((BKD) -> {ok, BKC} | {error, BKG}) -) -> {ok, BKC} | {error, BKG}. -try_recover(Result, Fun) -> - case Result of - {ok, Value} -> - {ok, Value}; - - {error, Error} -> - Fun(Error) - end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl deleted file mode 100644 index df87b13..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@set.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(gleam@set). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([new/0, size/1, insert/2, contains/2, delete/2, to_list/1, from_list/1, fold/3, filter/2, drop/2, take/2, union/2, intersection/2]). --export_type([set/1]). - --opaque set(DJZ) :: {set, gleam@dict:dict(DJZ, list(nil))}. - --spec new() -> set(any()). -new() -> - {set, gleam@dict:new()}. - --spec size(set(any())) -> integer(). -size(Set) -> - gleam@dict:size(erlang:element(2, Set)). - --spec insert(set(DKF), DKF) -> set(DKF). -insert(Set, Member) -> - {set, gleam@dict:insert(erlang:element(2, Set), Member, [])}. - --spec contains(set(DKI), DKI) -> boolean(). -contains(Set, Member) -> - _pipe = erlang:element(2, Set), - _pipe@1 = gleam@dict:get(_pipe, Member), - gleam@result:is_ok(_pipe@1). - --spec delete(set(DKK), DKK) -> set(DKK). -delete(Set, Member) -> - {set, gleam@dict:delete(erlang:element(2, Set), Member)}. - --spec to_list(set(DKN)) -> list(DKN). -to_list(Set) -> - gleam@dict:keys(erlang:element(2, Set)). - --spec from_list(list(DKQ)) -> set(DKQ). -from_list(Members) -> - Map = gleam@list:fold( - Members, - gleam@dict:new(), - fun(M, K) -> gleam@dict:insert(M, K, []) end - ), - {set, Map}. - --spec fold(set(DKT), DKV, fun((DKV, DKT) -> DKV)) -> DKV. -fold(Set, Initial, Reducer) -> - gleam@dict:fold( - erlang:element(2, Set), - Initial, - fun(A, K, _) -> Reducer(A, K) end - ). - --spec filter(set(DKW), fun((DKW) -> boolean())) -> set(DKW). -filter(Set, Predicate) -> - {set, - gleam@dict:filter(erlang:element(2, Set), fun(M, _) -> Predicate(M) end)}. - --spec drop(set(DKZ), list(DKZ)) -> set(DKZ). -drop(Set, Disallowed) -> - gleam@list:fold(Disallowed, Set, fun delete/2). - --spec take(set(DLD), list(DLD)) -> set(DLD). -take(Set, Desired) -> - {set, gleam@dict:take(erlang:element(2, Set), Desired)}. - --spec order(set(DLH), set(DLH)) -> {set(DLH), set(DLH)}. -order(First, Second) -> - case gleam@dict:size(erlang:element(2, First)) > gleam@dict:size( - erlang:element(2, Second) - ) of - true -> - {First, Second}; - - false -> - {Second, First} - end. - --spec union(set(DLM), set(DLM)) -> set(DLM). -union(First, Second) -> - {Larger, Smaller} = order(First, Second), - fold(Smaller, Larger, fun insert/2). - --spec intersection(set(DLQ), set(DLQ)) -> set(DLQ). -intersection(First, Second) -> - {Larger, Smaller} = order(First, Second), - take(Larger, to_list(Smaller)). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl deleted file mode 100644 index 6cba31d..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@string.erl +++ /dev/null @@ -1,352 +0,0 @@ --module(gleam@string). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([is_empty/1, length/1, reverse/1, replace/3, lowercase/1, uppercase/1, compare/2, slice/3, crop/2, drop_left/2, drop_right/2, contains/2, starts_with/2, ends_with/2, split_once/2, append/2, concat/1, repeat/2, join/2, pad_left/3, pad_right/3, trim/1, trim_left/1, trim_right/1, pop_grapheme/1, to_graphemes/1, split/2, to_utf_codepoints/1, from_utf_codepoints/1, utf_codepoint/1, utf_codepoint_to_int/1, to_option/1, first/1, last/1, capitalise/1, inspect/1, byte_size/1]). --export_type([direction/0]). - --type direction() :: leading | trailing | both. - --spec is_empty(binary()) -> boolean(). -is_empty(Str) -> - Str =:= <<""/utf8>>. - --spec length(binary()) -> integer(). -length(String) -> - string:length(String). - --spec do_reverse(binary()) -> binary(). -do_reverse(String) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:reverse(_pipe@1), - gleam@string_builder:to_string(_pipe@2). - --spec reverse(binary()) -> binary(). -reverse(String) -> - do_reverse(String). - --spec replace(binary(), binary(), binary()) -> binary(). -replace(String, Pattern, Substitute) -> - _pipe = String, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:replace(_pipe@1, Pattern, Substitute), - gleam@string_builder:to_string(_pipe@2). - --spec lowercase(binary()) -> binary(). -lowercase(String) -> - string:lowercase(String). - --spec uppercase(binary()) -> binary(). -uppercase(String) -> - string:uppercase(String). - --spec compare(binary(), binary()) -> gleam@order:order(). -compare(A, B) -> - case A =:= B of - true -> - eq; - - _ -> - case gleam_stdlib:less_than(A, B) of - true -> - lt; - - _ -> - gt - end - end. - --spec slice(binary(), integer(), integer()) -> binary(). -slice(String, Idx, Len) -> - case Len < 0 of - true -> - <<""/utf8>>; - - false -> - case Idx < 0 of - true -> - Translated_idx = length(String) + Idx, - case Translated_idx < 0 of - true -> - <<""/utf8>>; - - false -> - string:slice(String, Translated_idx, Len) - end; - - false -> - string:slice(String, Idx, Len) - end - end. - --spec crop(binary(), binary()) -> binary(). -crop(String, Substring) -> - gleam_stdlib:crop_string(String, Substring). - --spec drop_left(binary(), integer()) -> binary(). -drop_left(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, Num_graphemes, length(String) - Num_graphemes) - end. - --spec drop_right(binary(), integer()) -> binary(). -drop_right(String, Num_graphemes) -> - case Num_graphemes < 0 of - true -> - String; - - false -> - slice(String, 0, length(String) - Num_graphemes) - end. - --spec contains(binary(), binary()) -> boolean(). -contains(Haystack, Needle) -> - gleam_stdlib:contains_string(Haystack, Needle). - --spec starts_with(binary(), binary()) -> boolean(). -starts_with(String, Prefix) -> - gleam_stdlib:string_starts_with(String, Prefix). - --spec ends_with(binary(), binary()) -> boolean(). -ends_with(String, Suffix) -> - gleam_stdlib:string_ends_with(String, Suffix). - --spec do_split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -do_split_once(X, Substring) -> - case string:split(X, Substring) of - [First, Rest] -> - {ok, {First, Rest}}; - - _ -> - {error, nil} - end. - --spec split_once(binary(), binary()) -> {ok, {binary(), binary()}} | - {error, nil}. -split_once(X, Substring) -> - do_split_once(X, Substring). - --spec append(binary(), binary()) -> binary(). -append(First, Second) -> - _pipe = First, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:append(_pipe@1, Second), - gleam@string_builder:to_string(_pipe@2). - --spec concat(list(binary())) -> binary(). -concat(Strings) -> - _pipe = Strings, - _pipe@1 = gleam@string_builder:from_strings(_pipe), - gleam@string_builder:to_string(_pipe@1). - --spec repeat(binary(), integer()) -> binary(). -repeat(String, Times) -> - _pipe = gleam@iterator:repeat(String), - _pipe@1 = gleam@iterator:take(_pipe, Times), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_join(list(binary()), binary()) -> binary(). -do_join(Strings, Separator) -> - _pipe = Strings, - _pipe@1 = gleam@list:intersperse(_pipe, Separator), - concat(_pipe@1). - --spec join(list(binary()), binary()) -> binary(). -join(Strings, Separator) -> - do_join(Strings, Separator). - --spec padding(integer(), binary()) -> gleam@iterator:iterator(binary()). -padding(Size, Pad_string) -> - Pad_length = length(Pad_string), - Num_pads = case Pad_length of - 0 -> 0; - Gleam@denominator -> Size div Gleam@denominator - end, - Extra = case Pad_length of - 0 -> 0; - Gleam@denominator@1 -> Size rem Gleam@denominator@1 - end, - _pipe = gleam@iterator:repeat(Pad_string), - _pipe@1 = gleam@iterator:take(_pipe, Num_pads), - gleam@iterator:append( - _pipe@1, - gleam@iterator:single(slice(Pad_string, 0, Extra)) - ). - --spec pad_left(binary(), integer(), binary()) -> binary(). -pad_left(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = padding(To_pad_length, Pad_string), - _pipe@1 = gleam@iterator:append(_pipe, gleam@iterator:single(String)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec pad_right(binary(), integer(), binary()) -> binary(). -pad_right(String, Desired_length, Pad_string) -> - Current_length = length(String), - To_pad_length = Desired_length - Current_length, - _pipe = gleam@iterator:single(String), - _pipe@1 = gleam@iterator:append(_pipe, padding(To_pad_length, Pad_string)), - _pipe@2 = gleam@iterator:to_list(_pipe@1), - concat(_pipe@2). - --spec do_trim(binary()) -> binary(). -do_trim(String) -> - string:trim(String, both). - --spec trim(binary()) -> binary(). -trim(String) -> - do_trim(String). - --spec do_trim_left(binary()) -> binary(). -do_trim_left(String) -> - string:trim(String, leading). - --spec trim_left(binary()) -> binary(). -trim_left(String) -> - do_trim_left(String). - --spec do_trim_right(binary()) -> binary(). -do_trim_right(String) -> - string:trim(String, trailing). - --spec trim_right(binary()) -> binary(). -trim_right(String) -> - do_trim_right(String). - --spec pop_grapheme(binary()) -> {ok, {binary(), binary()}} | {error, nil}. -pop_grapheme(String) -> - gleam_stdlib:string_pop_grapheme(String). - --spec do_to_graphemes(binary(), list(binary())) -> list(binary()). -do_to_graphemes(String, Acc) -> - case pop_grapheme(String) of - {ok, {Grapheme, Rest}} -> - do_to_graphemes(Rest, [Grapheme | Acc]); - - _ -> - Acc - end. - --spec to_graphemes(binary()) -> list(binary()). -to_graphemes(String) -> - _pipe = do_to_graphemes(String, []), - gleam@list:reverse(_pipe). - --spec split(binary(), binary()) -> list(binary()). -split(X, Substring) -> - case Substring of - <<""/utf8>> -> - to_graphemes(X); - - _ -> - _pipe = X, - _pipe@1 = gleam@string_builder:from_string(_pipe), - _pipe@2 = gleam@string_builder:split(_pipe@1, Substring), - gleam@list:map(_pipe@2, fun gleam@string_builder:to_string/1) - end. - --spec do_to_utf_codepoints_impl(bitstring(), list(integer())) -> list(integer()). -do_to_utf_codepoints_impl(Bit_array, Acc) -> - case Bit_array of - <<First/utf8, Rest/binary>> -> - do_to_utf_codepoints_impl(Rest, [First | Acc]); - - _ -> - Acc - end. - --spec do_to_utf_codepoints(binary()) -> list(integer()). -do_to_utf_codepoints(String) -> - _pipe = do_to_utf_codepoints_impl(<<String/binary>>, []), - gleam@list:reverse(_pipe). - --spec to_utf_codepoints(binary()) -> list(integer()). -to_utf_codepoints(String) -> - do_to_utf_codepoints(String). - --spec from_utf_codepoints(list(integer())) -> binary(). -from_utf_codepoints(Utf_codepoints) -> - gleam_stdlib:utf_codepoint_list_to_string(Utf_codepoints). - --spec utf_codepoint(integer()) -> {ok, integer()} | {error, nil}. -utf_codepoint(Value) -> - case Value of - I when I > 1114111 -> - {error, nil}; - - 65534 -> - {error, nil}; - - 65535 -> - {error, nil}; - - I@1 when (I@1 >= 55296) andalso (I@1 =< 57343) -> - {error, nil}; - - I@2 -> - {ok, gleam_stdlib:identity(I@2)} - end. - --spec utf_codepoint_to_int(integer()) -> integer(). -utf_codepoint_to_int(Cp) -> - gleam_stdlib:identity(Cp). - --spec to_option(binary()) -> gleam@option:option(binary()). -to_option(S) -> - case S of - <<""/utf8>> -> - none; - - _ -> - {some, S} - end. - --spec first(binary()) -> {ok, binary()} | {error, nil}. -first(S) -> - case pop_grapheme(S) of - {ok, {First, _}} -> - {ok, First}; - - {error, E} -> - {error, E} - end. - --spec last(binary()) -> {ok, binary()} | {error, nil}. -last(S) -> - case pop_grapheme(S) of - {ok, {First, <<""/utf8>>}} -> - {ok, First}; - - {ok, {_, Rest}} -> - {ok, slice(Rest, -1, 1)}; - - {error, E} -> - {error, E} - end. - --spec capitalise(binary()) -> binary(). -capitalise(S) -> - case pop_grapheme(S) of - {ok, {First, Rest}} -> - append(uppercase(First), lowercase(Rest)); - - _ -> - <<""/utf8>> - end. - --spec inspect(any()) -> binary(). -inspect(Term) -> - _pipe = gleam_stdlib:inspect(Term), - gleam@string_builder:to_string(_pipe). - --spec byte_size(binary()) -> integer(). -byte_size(String) -> - erlang:byte_size(String). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl deleted file mode 100644 index 693e840..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@string_builder.erl +++ /dev/null @@ -1,91 +0,0 @@ --module(gleam@string_builder). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([prepend_builder/2, append_builder/2, new/0, from_strings/1, concat/1, from_string/1, prepend/2, append/2, to_string/1, byte_size/1, join/2, lowercase/1, uppercase/1, reverse/1, split/2, replace/3, is_equal/2, is_empty/1]). --export_type([string_builder/0, direction/0]). - --type string_builder() :: any(). - --type direction() :: all. - --spec prepend_builder(string_builder(), string_builder()) -> string_builder(). -prepend_builder(Builder, Prefix) -> - gleam_stdlib:iodata_append(Prefix, Builder). - --spec append_builder(string_builder(), string_builder()) -> string_builder(). -append_builder(Builder, Suffix) -> - gleam_stdlib:iodata_append(Builder, Suffix). - --spec new() -> string_builder(). -new() -> - gleam_stdlib:identity([]). - --spec from_strings(list(binary())) -> string_builder(). -from_strings(Strings) -> - gleam_stdlib:identity(Strings). - --spec concat(list(string_builder())) -> string_builder(). -concat(Builders) -> - gleam_stdlib:identity(Builders). - --spec from_string(binary()) -> string_builder(). -from_string(String) -> - gleam_stdlib:identity(String). - --spec prepend(string_builder(), binary()) -> string_builder(). -prepend(Builder, Prefix) -> - append_builder(from_string(Prefix), Builder). - --spec append(string_builder(), binary()) -> string_builder(). -append(Builder, Second) -> - append_builder(Builder, from_string(Second)). - --spec to_string(string_builder()) -> binary(). -to_string(Builder) -> - unicode:characters_to_binary(Builder). - --spec byte_size(string_builder()) -> integer(). -byte_size(Builder) -> - erlang:iolist_size(Builder). - --spec join(list(string_builder()), binary()) -> string_builder(). -join(Builders, Sep) -> - _pipe = Builders, - _pipe@1 = gleam@list:intersperse(_pipe, from_string(Sep)), - concat(_pipe@1). - --spec lowercase(string_builder()) -> string_builder(). -lowercase(Builder) -> - string:lowercase(Builder). - --spec uppercase(string_builder()) -> string_builder(). -uppercase(Builder) -> - string:uppercase(Builder). - --spec reverse(string_builder()) -> string_builder(). -reverse(Builder) -> - string:reverse(Builder). - --spec do_split(string_builder(), binary()) -> list(string_builder()). -do_split(Iodata, Pattern) -> - string:split(Iodata, Pattern, all). - --spec split(string_builder(), binary()) -> list(string_builder()). -split(Iodata, Pattern) -> - do_split(Iodata, Pattern). - --spec do_replace(string_builder(), binary(), binary()) -> string_builder(). -do_replace(Iodata, Pattern, Substitute) -> - string:replace(Iodata, Pattern, Substitute, all). - --spec replace(string_builder(), binary(), binary()) -> string_builder(). -replace(Builder, Pattern, Substitute) -> - do_replace(Builder, Pattern, Substitute). - --spec is_equal(string_builder(), string_builder()) -> boolean(). -is_equal(A, B) -> - string:equal(A, B). - --spec is_empty(string_builder()) -> boolean(). -is_empty(Builder) -> - string:is_empty(Builder). diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl deleted file mode 100644 index 7ec4fe7..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam@uri.erl +++ /dev/null @@ -1,252 +0,0 @@ --module(gleam@uri). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([parse/1, parse_query/1, percent_encode/1, query_to_string/1, percent_decode/1, path_segments/1, to_string/1, origin/1, merge/2]). --export_type([uri/0]). - --type uri() :: {uri, - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(binary()), - gleam@option:option(integer()), - binary(), - gleam@option:option(binary()), - gleam@option:option(binary())}. - --spec parse(binary()) -> {ok, uri()} | {error, nil}. -parse(Uri_string) -> - gleam_stdlib:uri_parse(Uri_string). - --spec parse_query(binary()) -> {ok, list({binary(), binary()})} | {error, nil}. -parse_query(Query) -> - gleam_stdlib:parse_query(Query). - --spec percent_encode(binary()) -> binary(). -percent_encode(Value) -> - gleam_stdlib:percent_encode(Value). - --spec query_pair({binary(), binary()}) -> gleam@string_builder:string_builder(). -query_pair(Pair) -> - gleam@string_builder:from_strings( - [percent_encode(erlang:element(1, Pair)), - <<"="/utf8>>, - percent_encode(erlang:element(2, Pair))] - ). - --spec query_to_string(list({binary(), binary()})) -> binary(). -query_to_string(Query) -> - _pipe = Query, - _pipe@1 = gleam@list:map(_pipe, fun query_pair/1), - _pipe@2 = gleam@list:intersperse( - _pipe@1, - gleam@string_builder:from_string(<<"&"/utf8>>) - ), - _pipe@3 = gleam@string_builder:concat(_pipe@2), - gleam@string_builder:to_string(_pipe@3). - --spec percent_decode(binary()) -> {ok, binary()} | {error, nil}. -percent_decode(Value) -> - gleam_stdlib:percent_decode(Value). - --spec do_remove_dot_segments(list(binary()), list(binary())) -> list(binary()). -do_remove_dot_segments(Input, Accumulator) -> - case Input of - [] -> - gleam@list:reverse(Accumulator); - - [Segment | Rest] -> - Accumulator@5 = case {Segment, Accumulator} of - {<<""/utf8>>, Accumulator@1} -> - Accumulator@1; - - {<<"."/utf8>>, Accumulator@2} -> - Accumulator@2; - - {<<".."/utf8>>, []} -> - []; - - {<<".."/utf8>>, [_ | Accumulator@3]} -> - Accumulator@3; - - {Segment@1, Accumulator@4} -> - [Segment@1 | Accumulator@4] - end, - do_remove_dot_segments(Rest, Accumulator@5) - end. - --spec remove_dot_segments(list(binary())) -> list(binary()). -remove_dot_segments(Input) -> - do_remove_dot_segments(Input, []). - --spec path_segments(binary()) -> list(binary()). -path_segments(Path) -> - remove_dot_segments(gleam@string:split(Path, <<"/"/utf8>>)). - --spec to_string(uri()) -> binary(). -to_string(Uri) -> - Parts = case erlang:element(8, Uri) of - {some, Fragment} -> - [<<"#"/utf8>>, Fragment]; - - _ -> - [] - end, - Parts@1 = case erlang:element(7, Uri) of - {some, Query} -> - [<<"?"/utf8>>, Query | Parts]; - - _ -> - Parts - end, - Parts@2 = [erlang:element(6, Uri) | Parts@1], - Parts@3 = case {erlang:element(4, Uri), - gleam@string:starts_with(erlang:element(6, Uri), <<"/"/utf8>>)} of - {{some, Host}, false} when Host =/= <<""/utf8>> -> - [<<"/"/utf8>> | Parts@2]; - - {_, _} -> - Parts@2 - end, - Parts@4 = case {erlang:element(4, Uri), erlang:element(5, Uri)} of - {{some, _}, {some, Port}} -> - [<<":"/utf8>>, gleam@int:to_string(Port) | Parts@3]; - - {_, _} -> - Parts@3 - end, - Parts@5 = case {erlang:element(2, Uri), - erlang:element(3, Uri), - erlang:element(4, Uri)} of - {{some, S}, {some, U}, {some, H}} -> - [S, <<"://"/utf8>>, U, <<"@"/utf8>>, H | Parts@4]; - - {{some, S@1}, none, {some, H@1}} -> - [S@1, <<"://"/utf8>>, H@1 | Parts@4]; - - {{some, S@2}, {some, _}, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {{some, S@2}, none, none} -> - [S@2, <<":"/utf8>> | Parts@4]; - - {none, none, {some, H@2}} -> - [<<"//"/utf8>>, H@2 | Parts@4]; - - {_, _, _} -> - Parts@4 - end, - gleam@string:concat(Parts@5). - --spec origin(uri()) -> {ok, binary()} | {error, nil}. -origin(Uri) -> - {uri, Scheme, _, Host, Port, _, _, _} = Uri, - case Scheme of - {some, <<"https"/utf8>>} when Port =:= {some, 443} -> - Origin = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin)}; - - {some, <<"http"/utf8>>} when Port =:= {some, 80} -> - Origin@1 = {uri, Scheme, none, Host, none, <<""/utf8>>, none, none}, - {ok, to_string(Origin@1)}; - - {some, S} when (S =:= <<"http"/utf8>>) orelse (S =:= <<"https"/utf8>>) -> - Origin@2 = {uri, Scheme, none, Host, Port, <<""/utf8>>, none, none}, - {ok, to_string(Origin@2)}; - - _ -> - {error, nil} - end. - --spec drop_last(list(DFL)) -> list(DFL). -drop_last(Elements) -> - gleam@list:take(Elements, gleam@list:length(Elements) - 1). - --spec join_segments(list(binary())) -> binary(). -join_segments(Segments) -> - gleam@string:join([<<""/utf8>> | Segments], <<"/"/utf8>>). - --spec merge(uri(), uri()) -> {ok, uri()} | {error, nil}. -merge(Base, Relative) -> - case Base of - {uri, {some, _}, _, {some, _}, _, _, _, _} -> - case Relative of - {uri, _, _, {some, _}, _, _, _, _} -> - Path = begin - _pipe = gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ), - _pipe@1 = remove_dot_segments(_pipe), - join_segments(_pipe@1) - end, - Resolved = {uri, - gleam@option:'or'( - erlang:element(2, Relative), - erlang:element(2, Base) - ), - none, - erlang:element(4, Relative), - gleam@option:'or'( - erlang:element(5, Relative), - erlang:element(5, Base) - ), - Path, - erlang:element(7, Relative), - erlang:element(8, Relative)}, - {ok, Resolved}; - - _ -> - {New_path, New_query} = case erlang:element(6, Relative) of - <<""/utf8>> -> - {erlang:element(6, Base), - gleam@option:'or'( - erlang:element(7, Relative), - erlang:element(7, Base) - )}; - - _ -> - Path_segments = case gleam@string:starts_with( - erlang:element(6, Relative), - <<"/"/utf8>> - ) of - true -> - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ); - - false -> - _pipe@2 = gleam@string:split( - erlang:element(6, Base), - <<"/"/utf8>> - ), - _pipe@3 = drop_last(_pipe@2), - gleam@list:append( - _pipe@3, - gleam@string:split( - erlang:element(6, Relative), - <<"/"/utf8>> - ) - ) - end, - Path@1 = begin - _pipe@4 = Path_segments, - _pipe@5 = remove_dot_segments(_pipe@4), - join_segments(_pipe@5) - end, - {Path@1, erlang:element(7, Relative)} - end, - Resolved@1 = {uri, - erlang:element(2, Base), - none, - erlang:element(4, Base), - erlang:element(5, Base), - New_path, - New_query, - erlang:element(8, Relative)}, - {ok, Resolved@1} - end; - - _ -> - {error, nil} - end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src deleted file mode 100644 index bcf08e2..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.app.src +++ /dev/null @@ -1,31 +0,0 @@ -{application, gleam_stdlib, [ - {vsn, "0.33.0"}, - {applications, []}, - {description, "A standard library for the Gleam programming language"}, - {modules, [gleam@base, - gleam@bit_array, - gleam@bit_builder, - gleam@bit_string, - gleam@bool, - gleam@bytes_builder, - gleam@dict, - gleam@dynamic, - gleam@float, - gleam@function, - gleam@int, - gleam@io, - gleam@iterator, - gleam@list, - gleam@map, - gleam@option, - gleam@order, - gleam@pair, - gleam@queue, - gleam@regex, - gleam@result, - gleam@set, - gleam@string, - gleam@string_builder, - gleam@uri]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl deleted file mode 100644 index c6ea125..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.erl +++ /dev/null @@ -1,529 +0,0 @@ --module(gleam_stdlib). - --export([ - map_get/2, iodata_append/2, identity/1, decode_int/1, decode_bool/1, - decode_float/1, decode_list/1, decode_option/2, decode_field/2, parse_int/1, - parse_float/1, less_than/2, string_pop_grapheme/1, string_starts_with/2, - wrap_list/1, string_ends_with/2, string_pad/4, decode_map/1, uri_parse/1, - bit_array_int_to_u32/1, bit_array_int_from_u32/1, decode_result/1, - bit_array_slice/3, decode_bit_array/1, compile_regex/2, regex_scan/2, - percent_encode/1, percent_decode/1, regex_check/2, regex_split/2, - base_decode64/1, parse_query/1, bit_array_concat/1, size_of_tuple/1, - decode_tuple/1, decode_tuple2/1, decode_tuple3/1, decode_tuple4/1, - decode_tuple5/1, decode_tuple6/1, tuple_get/2, classify_dynamic/1, print/1, - println/1, print_error/1, println_error/1, inspect/1, float_to_string/1, - int_from_base_string/2, utf_codepoint_list_to_string/1, contains_string/2, - crop_string/2, base16_decode/1 -]). - -%% Taken from OTP's uri_string module --define(DEC2HEX(X), - if ((X) >= 0) andalso ((X) =< 9) -> (X) + $0; - ((X) >= 10) andalso ((X) =< 15) -> (X) + $A - 10 - end). - -%% Taken from OTP's uri_string module --define(HEX2DEC(X), - if ((X) >= $0) andalso ((X) =< $9) -> (X) - $0; - ((X) >= $A) andalso ((X) =< $F) -> (X) - $A + 10; - ((X) >= $a) andalso ((X) =< $f) -> (X) - $a + 10 - end). - --define(is_lowercase_char(X), (X > 96 andalso X < 123)). --define(is_underscore_char(X), (X == 95)). --define(is_digit_char(X), (X > 47 andalso X < 58)). - -uppercase(X) -> X - 32. - -map_get(Map, Key) -> - case maps:find(Key, Map) of - error -> {error, nil}; - OkFound -> OkFound - end. - -iodata_append(Iodata, String) -> [Iodata, String]. - -identity(X) -> X. - -decode_error_msg(Expected, Data) when is_binary(Expected) -> - decode_error(Expected, classify_dynamic(Data)). -decode_error(Expected, Got) when is_binary(Expected) andalso is_binary(Got) -> - {error, [{decode_error, Expected, Got, []}]}. - -classify_dynamic(nil) -> <<"Nil">>; -classify_dynamic(X) when is_atom(X) -> <<"Atom">>; -classify_dynamic(X) when is_binary(X) -> <<"String">>; -classify_dynamic(X) when is_bitstring(X) -> <<"BitArray">>; -classify_dynamic(X) when is_integer(X) -> <<"Int">>; -classify_dynamic(X) when is_float(X) -> <<"Float">>; -classify_dynamic(X) when is_list(X) -> <<"List">>; -classify_dynamic(X) when is_boolean(X) -> <<"Bool">>; -classify_dynamic(X) when is_map(X) -> <<"Map">>; -classify_dynamic(X) when is_tuple(X) -> - iolist_to_binary(["Tuple of ", integer_to_list(tuple_size(X)), " elements"]); -classify_dynamic(X) when - is_function(X, 0) orelse is_function(X, 1) orelse is_function(X, 2) orelse - is_function(X, 3) orelse is_function(X, 4) orelse is_function(X, 5) orelse - is_function(X, 6) orelse is_function(X, 7) orelse is_function(X, 8) orelse - is_function(X, 9) orelse is_function(X, 10) orelse is_function(X, 11) orelse - is_function(X, 12) -> <<"Function">>; -classify_dynamic(_) -> <<"Some other type">>. - -decode_map(Data) when is_map(Data) -> {ok, Data}; -decode_map(Data) -> decode_error_msg(<<"Map">>, Data). - -decode_bit_array(Data) when is_bitstring(Data) -> {ok, Data}; -decode_bit_array(Data) -> decode_error_msg(<<"BitArray">>, Data). - -decode_int(Data) when is_integer(Data) -> {ok, Data}; -decode_int(Data) -> decode_error_msg(<<"Int">>, Data). - -decode_float(Data) when is_float(Data) -> {ok, Data}; -decode_float(Data) -> decode_error_msg(<<"Float">>, Data). - -decode_bool(Data) when is_boolean(Data) -> {ok, Data}; -decode_bool(Data) -> decode_error_msg(<<"Bool">>, Data). - -decode_list(Data) when is_list(Data) -> {ok, Data}; -decode_list(Data) -> decode_error_msg(<<"List">>, Data). - -decode_field(Data, Key) when is_map(Data) -> - case Data of - #{Key := Value} -> {ok, {some, Value}}; - _ -> - {ok, none} - end; -decode_field(Data, _) -> - decode_error_msg(<<"Map">>, Data). - -size_of_tuple(Data) -> tuple_size(Data). - -tuple_get(_tup, Index) when Index < 0 -> {error, nil}; -tuple_get(Data, Index) when Index >= tuple_size(Data) -> {error, nil}; -tuple_get(Data, Index) -> {ok, element(Index + 1, Data)}. - -decode_tuple(Data) when is_tuple(Data) -> {ok, Data}; -decode_tuple(Data) -> decode_error_msg(<<"Tuple">>, Data). - -decode_tuple2({_,_} = A) -> {ok, A}; -decode_tuple2([A,B]) -> {ok, {A,B}}; -decode_tuple2(Data) -> decode_error_msg(<<"Tuple of 2 elements">>, Data). - -decode_tuple3({_,_,_} = A) -> {ok, A}; -decode_tuple3([A,B,C]) -> {ok, {A,B,C}}; -decode_tuple3(Data) -> decode_error_msg(<<"Tuple of 3 elements">>, Data). - -decode_tuple4({_,_,_,_} = A) -> {ok, A}; -decode_tuple4([A,B,C,D]) -> {ok, {A,B,C,D}}; -decode_tuple4(Data) -> decode_error_msg(<<"Tuple of 4 elements">>, Data). - -decode_tuple5({_,_,_,_,_} = A) -> {ok, A}; -decode_tuple5([A,B,C,D,E]) -> {ok, {A,B,C,D,E}}; -decode_tuple5(Data) -> decode_error_msg(<<"Tuple of 5 elements">>, Data). - -decode_tuple6({_,_,_,_,_,_} = A) -> {ok, A}; -decode_tuple6([A,B,C,D,E,F]) -> {ok, {A,B,C,D,E,F}}; -decode_tuple6(Data) -> decode_error_msg(<<"Tuple of 6 elements">>, Data). - -decode_option(Term, F) -> - Decode = fun(Inner) -> - case F(Inner) of - {ok, Decoded} -> {ok, {some, Decoded}}; - Error -> Error - end - end, - case Term of - undefined -> {ok, none}; - error -> {ok, none}; - null -> {ok, none}; - none -> {ok, none}; - nil -> {ok, none}; - {some, Inner} -> Decode(Inner); - _ -> Decode(Term) - end. - -decode_result(Term) -> - case Term of - {ok, Inner} -> {ok, {ok, Inner}}; - ok -> {ok, {ok, nil}}; - {error, Inner} -> {ok, {error, Inner}}; - error -> {ok, {error, nil}}; - _ -> decode_error_msg(<<"Result">>, Term) - end. - -int_from_base_string(String, Base) -> - case catch binary_to_integer(String, Base) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_int(String) -> - case catch binary_to_integer(String) of - Int when is_integer(Int) -> {ok, Int}; - _ -> {error, nil} - end. - -parse_float(String) -> - case catch binary_to_float(String) of - Float when is_float(Float) -> {ok, Float}; - _ -> {error, nil} - end. - -less_than(Lhs, Rhs) -> - Lhs < Rhs. - -string_starts_with(_, <<>>) -> true; -string_starts_with(String, Prefix) when byte_size(Prefix) > byte_size(String) -> false; -string_starts_with(String, Prefix) -> - PrefixSize = byte_size(Prefix), - Prefix == binary_part(String, 0, PrefixSize). - -string_ends_with(_, <<>>) -> true; -string_ends_with(String, Suffix) when byte_size(Suffix) > byte_size(String) -> false; -string_ends_with(String, Suffix) -> - SuffixSize = byte_size(Suffix), - Suffix == binary_part(String, byte_size(String) - SuffixSize, SuffixSize). - -string_pad(String, Length, Dir, PadString) -> - Chars = string:pad(String, Length, Dir, binary_to_list(PadString)), - case unicode:characters_to_binary(Chars) of - Bin when is_binary(Bin) -> Bin; - Error -> erlang:error({gleam_error, {string_invalid_utf8, Error}}) - end. - -string_pop_grapheme(String) -> - case string:next_grapheme(String) of - [ Next | Rest ] -> - {ok, {unicode:characters_to_binary([Next]), unicode:characters_to_binary(Rest)}}; - _ -> {error, nil} - end. - -bit_array_concat(BitArrays) -> - list_to_bitstring(BitArrays). - -bit_array_slice(Bin, Pos, Len) -> - try {ok, binary:part(Bin, Pos, Len)} - catch error:badarg -> {error, nil} - end. - -bit_array_int_to_u32(I) when 0 =< I, I < 4294967296 -> - {ok, <<I:32>>}; -bit_array_int_to_u32(_) -> - {error, nil}. - -bit_array_int_from_u32(<<I:32>>) -> - {ok, I}; -bit_array_int_from_u32(_) -> - {error, nil}. - -compile_regex(String, Options) -> - {options, Caseless, Multiline} = Options, - OptionsList = [ - unicode, - ucp, - Caseless andalso caseless, - Multiline andalso multiline - ], - FilteredOptions = [Option || Option <- OptionsList, Option /= false], - case re:compile(String, FilteredOptions) of - {ok, MP} -> {ok, MP}; - {error, {Str, Pos}} -> - {error, {compile_error, unicode:characters_to_binary(Str), Pos}} - end. - -regex_check(Regex, String) -> - re:run(String, Regex) /= nomatch. - -regex_split(Regex, String) -> - re:split(String, Regex). - -regex_submatches(_, {-1, 0}) -> none; -regex_submatches(String, {Start, Length}) -> - BinarySlice = binary:part(String, {Start, Length}), - case string:is_empty(binary_to_list(BinarySlice)) of - true -> none; - false -> {some, BinarySlice} - end. - -regex_matches(String, [{Start, Length} | Submatches]) -> - Submatches1 = lists:map(fun(X) -> regex_submatches(String, X) end, Submatches), - {match, binary:part(String, Start, Length), Submatches1}. - -regex_scan(Regex, String) -> - case re:run(String, Regex, [global]) of - {match, Captured} -> lists:map(fun(X) -> regex_matches(String, X) end, Captured); - nomatch -> [] - end. - -base_decode64(S) -> - try {ok, base64:decode(S)} - catch error:_ -> {error, nil} - end. - -wrap_list(X) when is_list(X) -> X; -wrap_list(X) -> [X]. - -parse_query(Query) -> - case uri_string:dissect_query(Query) of - {error, _, _} -> {error, nil}; - Pairs -> - Pairs1 = lists:map(fun - ({K, true}) -> {K, <<"">>}; - (Pair) -> Pair - end, Pairs), - {ok, Pairs1} - end. - -percent_encode(B) -> percent_encode(B, <<>>). -percent_encode(<<>>, Acc) -> - Acc; -percent_encode(<<H,T/binary>>, Acc) -> - case percent_ok(H) of - true -> - percent_encode(T, <<Acc/binary,H>>); - false -> - <<A:4,B:4>> = <<H>>, - percent_encode(T, <<Acc/binary,$%,(?DEC2HEX(A)),(?DEC2HEX(B))>>) - end. - -percent_decode(Cs) -> percent_decode(Cs, <<>>). -percent_decode(<<$%, C0, C1, Cs/binary>>, Acc) -> - case is_hex_digit(C0) andalso is_hex_digit(C1) of - true -> - B = ?HEX2DEC(C0)*16+?HEX2DEC(C1), - percent_decode(Cs, <<Acc/binary, B>>); - false -> - {error, nil} - end; -percent_decode(<<C,Cs/binary>>, Acc) -> - percent_decode(Cs, <<Acc/binary, C>>); -percent_decode(<<>>, Acc) -> - check_utf8(Acc). - -percent_ok($!) -> true; -percent_ok($$) -> true; -percent_ok($') -> true; -percent_ok($() -> true; -percent_ok($)) -> true; -percent_ok($*) -> true; -percent_ok($+) -> true; -percent_ok($-) -> true; -percent_ok($.) -> true; -percent_ok($_) -> true; -percent_ok($~) -> true; -percent_ok(C) when $0 =< C, C =< $9 -> true; -percent_ok(C) when $A =< C, C =< $Z -> true; -percent_ok(C) when $a =< C, C =< $z -> true; -percent_ok(_) -> false. - -is_hex_digit(C) -> - ($0 =< C andalso C =< $9) orelse ($a =< C andalso C =< $f) orelse ($A =< C andalso C =< $F). - -check_utf8(Cs) -> - case unicode:characters_to_list(Cs) of - {incomplete, _, _} -> {error, nil}; - {error, _, _} -> {error, nil}; - _ -> {ok, Cs} - end. - -uri_parse(String) -> - case uri_string:parse(String) of - {error, _, _} -> {error, nil}; - Uri -> - {ok, {uri, - maps_get_optional(Uri, scheme), - maps_get_optional(Uri, userinfo), - maps_get_optional(Uri, host), - maps_get_optional(Uri, port), - maps_get_or(Uri, path, <<>>), - maps_get_optional(Uri, query), - maps_get_optional(Uri, fragment) - }} - end. - -maps_get_optional(Map, Key) -> - try {some, maps:get(Key, Map)} - catch _:_ -> none - end. - -maps_get_or(Map, Key, Default) -> - try maps:get(Key, Map) - catch _:_ -> Default - end. - -print(String) -> - io:put_chars(String), - nil. - -println(String) -> - io:put_chars([String, $\n]), - nil. - -print_error(String) -> - io:put_chars(standard_error, String), - nil. - -println_error(String) -> - io:put_chars(standard_error, [String, $\n]), - nil. - -inspect(true) -> - "True"; -inspect(false) -> - "False"; -inspect(nil) -> - "Nil"; -inspect(Data) when is_map(Data) -> - Fields = [ - [<<"#(">>, inspect(Key), <<", ">>, inspect(Value), <<")">>] - || {Key, Value} <- maps:to_list(Data) - ], - ["dict.from_list([", lists:join(", ", Fields), "])"]; -inspect(Atom) when is_atom(Atom) -> - Binary = erlang:atom_to_binary(Atom), - case inspect_maybe_gleam_atom(Binary, none, <<>>) of - {ok, Inspected} -> Inspected; - {error, _} -> ["atom.create_from_string(\"", Binary, "\")"] - end; -inspect(Any) when is_integer(Any) -> - erlang:integer_to_list(Any); -inspect(Any) when is_float(Any) -> - io_lib_format:fwrite_g(Any); -inspect(Binary) when is_binary(Binary) -> - case inspect_maybe_utf8_string(Binary, <<>>) of - {ok, InspectedUtf8String} -> InspectedUtf8String; - {error, not_a_utf8_string} -> - Segments = [erlang:integer_to_list(X) || <<X>> <= Binary], - ["<<", lists:join(", ", Segments), ">>"] - end; -inspect(Bits) when is_bitstring(Bits) -> - inspect_bit_array(Bits); -inspect(List) when is_list(List) -> - case inspect_list(List) of - {proper, Elements} -> ["[", Elements, "]"]; - {improper, Elements} -> ["//erl([", Elements, "])"] - end; -inspect(Any) when is_tuple(Any) % Record constructors - andalso is_atom(element(1, Any)) - andalso element(1, Any) =/= false - andalso element(1, Any) =/= true - andalso element(1, Any) =/= nil --> - [Atom | ArgsList] = erlang:tuple_to_list(Any), - Args = lists:join(<<", ">>, - lists:map(fun inspect/1, ArgsList) - ), - [inspect(Atom), "(", Args, ")"]; -inspect(Tuple) when is_tuple(Tuple) -> - Elements = lists:map(fun inspect/1, erlang:tuple_to_list(Tuple)), - ["#(", lists:join(", ", Elements), ")"]; -inspect(Any) when is_function(Any) -> - {arity, Arity} = erlang:fun_info(Any, arity), - ArgsAsciiCodes = lists:seq($a, $a + Arity - 1), - Args = lists:join(<<", ">>, - lists:map(fun(Arg) -> <<Arg>> end, ArgsAsciiCodes) - ), - ["//fn(", Args, ") { ... }"]; -inspect(Any) -> - ["//erl(", io_lib:format("~p", [Any]), ")"]. - - -inspect_maybe_gleam_atom(<<>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, none, _) when ?is_digit_char(First) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, none, _) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_">>, _PrevChar, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<"_", _Rest/binary>>, $_, _Acc) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, _Rest/binary>>, _PrevChar, _Acc) - when not (?is_lowercase_char(First) orelse ?is_underscore_char(First) orelse ?is_digit_char(First)) -> - {error, nil}; -inspect_maybe_gleam_atom(<<First, Rest/binary>>, none, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<"_", Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, $_, Acc); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, $_, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, (uppercase(First))>>); -inspect_maybe_gleam_atom(<<First, Rest/binary>>, _PrevChar, Acc) -> - inspect_maybe_gleam_atom(Rest, First, <<Acc/binary, First>>); -inspect_maybe_gleam_atom(<<>>, _PrevChar, Acc) -> - {ok, Acc}; -inspect_maybe_gleam_atom(A, B, C) -> - erlang:display({A, B, C}), - throw({gleam_error, A, B, C}). - -inspect_list([]) -> - {proper, []}; -inspect_list([First]) -> - {proper, [inspect(First)]}; -inspect_list([First | Rest]) when is_list(Rest) -> - {Kind, Inspected} = inspect_list(Rest), - {Kind, [inspect(First), <<", ">> | Inspected]}; -inspect_list([First | ImproperTail]) -> - {improper, [inspect(First), <<" | ">>, inspect(ImproperTail)]}. - -inspect_bit_array(Bits) -> - Text = inspect_bit_array(Bits, <<"<<">>), - <<Text/binary, ">>">>. - -inspect_bit_array(<<>>, Acc) -> - Acc; -inspect_bit_array(<<X, Rest/bitstring>>, Acc) -> - inspect_bit_array(Rest, append_segment(Acc, erlang:integer_to_binary(X))); -inspect_bit_array(Rest, Acc) -> - Size = bit_size(Rest), - <<X:Size>> = Rest, - X1 = erlang:integer_to_binary(X), - Size1 = erlang:integer_to_binary(Size), - Segment = <<X1/binary, ":size(", Size1/binary, ")">>, - inspect_bit_array(<<>>, append_segment(Acc, Segment)). - -append_segment(<<"<<">>, Segment) -> - <<"<<", Segment/binary>>; -append_segment(Acc, Segment) -> - <<Acc/binary, ", ", Segment/binary>>. - - -inspect_maybe_utf8_string(Binary, Acc) -> - case Binary of - <<>> -> {ok, <<$", Acc/binary, $">>}; - <<First/utf8, Rest/binary>> -> - Escaped = case First of - $" -> <<$\\, $">>; - $\\ -> <<$\\, $\\>>; - $\r -> <<$\\, $r>>; - $\n -> <<$\\, $n>>; - $\t -> <<$\\, $t>>; - Other -> <<Other/utf8>> - end, - inspect_maybe_utf8_string(Rest, <<Acc/binary, Escaped/binary>>); - _ -> {error, not_a_utf8_string} - end. - -float_to_string(Float) when is_float(Float) -> - erlang:iolist_to_binary(io_lib_format:fwrite_g(Float)). - -utf_codepoint_list_to_string(List) -> - case unicode:characters_to_binary(List) of - {error, _} -> erlang:error({gleam_error, {string_invalid_utf8, List}}); - Binary -> Binary - end. - -crop_string(String, Prefix) -> - case string:find(String, Prefix) of - nomatch -> String; - New -> New - end. - -contains_string(String, Substring) -> - is_bitstring(string:find(String, Substring)). - -base16_decode(String) -> - try - {ok, binary:decode_hex(String)} - catch - _:_ -> {error, nil} - end. diff --git a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs b/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs deleted file mode 100644 index a908b23..0000000 --- a/aoc2023/build/packages/gleam_stdlib/src/gleam_stdlib.mjs +++ /dev/null @@ -1,875 +0,0 @@ -import { - BitArray, - Error, - List, - Ok, - Result, - UtfCodepoint, - stringBits, - toBitArray, - NonEmpty, - CustomType, -} from "./gleam.mjs"; -import { - CompileError as RegexCompileError, - Match as RegexMatch, -} from "./gleam/regex.mjs"; -import { DecodeError } from "./gleam/dynamic.mjs"; -import { Some, None } from "./gleam/option.mjs"; -import Dict from "./dict.mjs"; - -const Nil = undefined; -const NOT_FOUND = {}; - -export function identity(x) { - return x; -} - -export function parse_int(value) { - if (/^[-+]?(\d+)$/.test(value)) { - return new Ok(parseInt(value)); - } else { - return new Error(Nil); - } -} - -export function parse_float(value) { - if (/^[-+]?(\d+)\.(\d+)$/.test(value)) { - return new Ok(parseFloat(value)); - } else { - return new Error(Nil); - } -} - -export function to_string(term) { - return term.toString(); -} - -export function float_to_string(float) { - const string = float.toString(); - if (string.indexOf(".") >= 0) { - return string; - } else { - return string + ".0"; - } -} - -export function int_to_base_string(int, base) { - return int.toString(base).toUpperCase(); -} - -const int_base_patterns = { - 2: /[^0-1]/, - 3: /[^0-2]/, - 4: /[^0-3]/, - 5: /[^0-4]/, - 6: /[^0-5]/, - 7: /[^0-6]/, - 8: /[^0-7]/, - 9: /[^0-8]/, - 10: /[^0-9]/, - 11: /[^0-9a]/, - 12: /[^0-9a-b]/, - 13: /[^0-9a-c]/, - 14: /[^0-9a-d]/, - 15: /[^0-9a-e]/, - 16: /[^0-9a-f]/, - 17: /[^0-9a-g]/, - 18: /[^0-9a-h]/, - 19: /[^0-9a-i]/, - 20: /[^0-9a-j]/, - 21: /[^0-9a-k]/, - 22: /[^0-9a-l]/, - 23: /[^0-9a-m]/, - 24: /[^0-9a-n]/, - 25: /[^0-9a-o]/, - 26: /[^0-9a-p]/, - 27: /[^0-9a-q]/, - 28: /[^0-9a-r]/, - 29: /[^0-9a-s]/, - 30: /[^0-9a-t]/, - 31: /[^0-9a-u]/, - 32: /[^0-9a-v]/, - 33: /[^0-9a-w]/, - 34: /[^0-9a-x]/, - 35: /[^0-9a-y]/, - 36: /[^0-9a-z]/, -}; - -export function int_from_base_string(string, base) { - if (int_base_patterns[base].test(string.replace(/^-/, "").toLowerCase())) { - return new Error(Nil); - } - - const result = parseInt(string, base); - - if (isNaN(result)) { - return new Error(Nil); - } - - return new Ok(result); -} - -export function string_replace(string, target, substitute) { - if (typeof string.replaceAll !== "undefined") { - return string.replaceAll(target, substitute); - } - // Fallback for older Node.js versions: - // 1. <https://stackoverflow.com/a/1144788> - // 2. <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping> - // TODO: This fallback could be remove once Node.js 14 is EOL - // aka <https://nodejs.org/en/about/releases/> on or after 2024-04-30 - return string.replace( - // $& means the whole matched string - new RegExp(target.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), - substitute - ); -} - -export function string_reverse(string) { - return [...string].reverse().join(""); -} - -export function string_length(string) { - if (string === "") { - return 0; - } - const iterator = graphemes_iterator(string); - if (iterator) { - let i = 0; - for (const _ of iterator) { - i++; - } - return i; - } else { - return string.match(/./gsu).length; - } -} - -export function graphemes(string) { - return List.fromArray( - Array.from(graphemes_iterator(string)).map((item) => item.segment) - ); -} - -function graphemes_iterator(string) { - if (Intl && Intl.Segmenter) { - return new Intl.Segmenter().segment(string)[Symbol.iterator](); - } -} - -export function pop_grapheme(string) { - let first; - const iterator = graphemes_iterator(string); - if (iterator) { - first = iterator.next().value?.segment; - } else { - first = string.match(/./su)?.[0]; - } - if (first) { - return new Ok([first, string.slice(first.length)]); - } else { - return new Error(Nil); - } -} - -export function lowercase(string) { - return string.toLowerCase(); -} - -export function uppercase(string) { - return string.toUpperCase(); -} - -export function less_than(a, b) { - return a < b; -} - -export function add(a, b) { - return a + b; -} - -export function equal(a, b) { - return a === b; -} - -export function split(xs, pattern) { - return List.fromArray(xs.split(pattern)); -} - -export function join(xs, separator) { - const iterator = xs[Symbol.iterator](); - let result = iterator.next().value || ""; - let current = iterator.next(); - while (!current.done) { - result = result + separator + current.value; - current = iterator.next(); - } - return result; -} - -export function concat(xs) { - let result = ""; - for (const x of xs) { - result = result + x; - } - return result; -} - -export function length(data) { - return data.length; -} - -export function crop_string(string, substring) { - return string.substring(string.indexOf(substring)); -} - -export function contains_string(haystack, needle) { - return haystack.indexOf(needle) >= 0; -} - -export function starts_with(haystack, needle) { - return haystack.startsWith(needle); -} - -export function ends_with(haystack, needle) { - return haystack.endsWith(needle); -} - -export function split_once(haystack, needle) { - const index = haystack.indexOf(needle); - if (index >= 0) { - const before = haystack.slice(0, index); - const after = haystack.slice(index + needle.length); - return new Ok([before, after]); - } else { - return new Error(Nil); - } -} - -export function trim(string) { - return string.trim(); -} - -export function trim_left(string) { - return string.trimLeft(); -} - -export function trim_right(string) { - return string.trimRight(); -} - -export function bit_array_from_string(string) { - return toBitArray([stringBits(string)]); -} - -export function bit_array_concat(bit_arrays) { - return toBitArray(bit_arrays.toArray().map((b) => b.buffer)); -} - -export function console_log(term) { - console.log(term); -} - -export function console_error(term) { - console.error(term); -} - -export function crash(message) { - throw new globalThis.Error(message); -} - -export function bit_array_to_string(bit_array) { - try { - const decoder = new TextDecoder("utf-8", { fatal: true }); - return new Ok(decoder.decode(bit_array.buffer)); - } catch (_error) { - return new Error(Nil); - } -} - -export function print(string) { - if (typeof process === "object") { - process.stdout.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stdout.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.log(string); // We're in a browser. Newlines are mandated - } -} - -export function print_error(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string); // We can write without a trailing newline - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string)); // We can write without a trailing newline - } else { - console.error(string); // We're in a browser. Newlines are mandated - } -} - -export function print_debug(string) { - if (typeof process === "object" && process.stderr?.write) { - process.stderr.write(string + "\n"); // If we're in Node.js, use `stderr` - } else if (typeof Deno === "object") { - Deno.stderr.writeSync(new TextEncoder().encode(string + "\n")); // If we're in Deno, use `stderr` - } else { - console.log(string); // Otherwise, use `console.log` (so that it doesn't look like an error) - } -} - -export function ceiling(float) { - return Math.ceil(float); -} - -export function floor(float) { - return Math.floor(float); -} - -export function round(float) { - return Math.round(float); -} - -export function truncate(float) { - return Math.trunc(float); -} - -export function power(base, exponent) { - // It is checked in Gleam that: - // - The base is non-negative and that the exponent is not fractional. - // - The base is non-zero and the exponent is non-negative (otherwise - // the result will essentially be division by zero). - // It can thus be assumed that valid input is passed to the Math.pow - // function and a NaN or Infinity value will not be produced. - return Math.pow(base, exponent); -} - -export function random_uniform() { - const random_uniform_result = Math.random(); - // With round-to-nearest-even behavior, the ranges claimed for the functions below - // (excluding the one for Math.random() itself) aren't exact. - // If extremely large bounds are chosen (2^53 or higher), - // it's possible in extremely rare cases to calculate the usually-excluded upper bound. - // Note that as numbers in JavaScript are IEEE 754 floating point numbers - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random> - // Because of this, we just loop 'until' we get a valid result where 0.0 <= x < 1.0: - if (random_uniform_result === 1.0) { - return random_uniform(); - } - return random_uniform_result; -} - -export function bit_array_slice(bits, position, length) { - const start = Math.min(position, position + length); - const end = Math.max(position, position + length); - if (start < 0 || end > bits.length) return new Error(Nil); - const buffer = new Uint8Array(bits.buffer.buffer, start, Math.abs(length)); - return new Ok(new BitArray(buffer)); -} - -export function codepoint(int) { - return new UtfCodepoint(int); -} - -export function string_to_codepoint_integer_list(string) { - return List.fromArray(Array.from(string).map((item) => item.codePointAt(0))); -} - -export function utf_codepoint_list_to_string(utf_codepoint_integer_list) { - return utf_codepoint_integer_list - .toArray() - .map((x) => String.fromCodePoint(x.value)) - .join(""); -} - -export function utf_codepoint_to_int(utf_codepoint) { - return utf_codepoint.value; -} - -export function regex_check(regex, string) { - regex.lastIndex = 0; - return regex.test(string); -} - -export function compile_regex(pattern, options) { - try { - let flags = "gu"; - if (options.case_insensitive) flags += "i"; - if (options.multi_line) flags += "m"; - return new Ok(new RegExp(pattern, flags)); - } catch (error) { - const number = (error.columnNumber || 0) | 0; - return new Error(new RegexCompileError(error.message, number)); - } -} - -export function regex_scan(regex, string) { - const matches = Array.from(string.matchAll(regex)).map((match) => { - const content = match[0]; - const submatches = []; - for (let n = match.length - 1; n > 0; n--) { - if (match[n]) { - submatches[n - 1] = new Some(match[n]); - continue; - } - if (submatches.length > 0) { - submatches[n - 1] = new None(); - } - } - return new RegexMatch(content, List.fromArray(submatches)); - }); - return List.fromArray(matches); -} - -export function new_map() { - return Dict.new(); -} - -export function map_size(map) { - return map.size; -} - -export function map_to_list(map) { - return List.fromArray(map.entries()); -} - -export function map_remove(key, map) { - return map.delete(key); -} - -export function map_get(map, key) { - const value = map.get(key, NOT_FOUND); - if (value === NOT_FOUND) { - return new Error(Nil); - } - return new Ok(value); -} - -export function map_insert(key, value, map) { - return map.set(key, value); -} - -function unsafe_percent_decode(string) { - return decodeURIComponent((string || "").replace("+", " ")); -} - -export function percent_decode(string) { - try { - return new Ok(unsafe_percent_decode(string)); - } catch (_error) { - return new Error(Nil); - } -} - -export function percent_encode(string) { - return encodeURIComponent(string); -} - -export function parse_query(query) { - try { - const pairs = []; - for (const section of query.split("&")) { - const [key, value] = section.split("="); - if (!key) continue; - pairs.push([unsafe_percent_decode(key), unsafe_percent_decode(value)]); - } - return new Ok(List.fromArray(pairs)); - } catch (_error) { - return new Error(Nil); - } -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function encode64(bit_array) { - const aBytes = bit_array.buffer; - let nMod3 = 2; - let sB64Enc = ""; - - for (let nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) { - nMod3 = nIdx % 3; - if (nIdx > 0 && ((nIdx * 4) / 3) % 76 === 0) { - sB64Enc += "\r\n"; - } - nUint24 |= aBytes[nIdx] << ((16 >>> nMod3) & 24); - if (nMod3 === 2 || aBytes.length - nIdx === 1) { - sB64Enc += String.fromCharCode( - uint6ToB64((nUint24 >>> 18) & 63), - uint6ToB64((nUint24 >>> 12) & 63), - uint6ToB64((nUint24 >>> 6) & 63), - uint6ToB64(nUint24 & 63) - ); - nUint24 = 0; - } - } - - return ( - sB64Enc.substr(0, sB64Enc.length - 2 + nMod3) + - (nMod3 === 2 ? "" : nMod3 === 1 ? "=" : "==") - ); -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function uint6ToB64(nUint6) { - return nUint6 < 26 - ? nUint6 + 65 - : nUint6 < 52 - ? nUint6 + 71 - : nUint6 < 62 - ? nUint6 - 4 - : nUint6 === 62 - ? 43 - : nUint6 === 63 - ? 47 - : 65; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64ToUint6(nChr) { - return nChr > 64 && nChr < 91 - ? nChr - 65 - : nChr > 96 && nChr < 123 - ? nChr - 71 - : nChr > 47 && nChr < 58 - ? nChr + 4 - : nChr === 43 - ? 62 - : nChr === 47 - ? 63 - : 0; -} - -// From https://developer.mozilla.org/en-US/docs/Glossary/Base64#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -export function decode64(sBase64) { - if (sBase64.match(/[^A-Za-z0-9\+\/=]/g)) return new Error(Nil); - const sB64Enc = sBase64.replace(/=/g, ""); - const nInLen = sB64Enc.length; - const nOutLen = (nInLen * 3 + 1) >> 2; - const taBytes = new Uint8Array(nOutLen); - - for ( - let nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; - nInIdx < nInLen; - nInIdx++ - ) { - nMod4 = nInIdx & 3; - nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << (6 * (3 - nMod4)); - if (nMod4 === 3 || nInLen - nInIdx === 1) { - for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) { - taBytes[nOutIdx] = (nUint24 >>> ((16 >>> nMod3) & 24)) & 255; - } - nUint24 = 0; - } - } - - return new Ok(new BitArray(taBytes)); -} - -export function classify_dynamic(data) { - if (typeof data === "string") { - return "String"; - } else if (data instanceof Result) { - return "Result"; - } else if (data instanceof List) { - return "List"; - } else if (data instanceof BitArray) { - return "BitArray"; - } else if (data instanceof Dict) { - return "Map"; - } else if (Number.isInteger(data)) { - return "Int"; - } else if (Array.isArray(data)) { - return `Tuple of ${data.length} elements`; - } else if (typeof data === "number") { - return "Float"; - } else if (data === null) { - return "Null"; - } else if (data === undefined) { - return "Nil"; - } else { - const type = typeof data; - return type.charAt(0).toUpperCase() + type.slice(1); - } -} - -function decoder_error(expected, got) { - return decoder_error_no_classify(expected, classify_dynamic(got)); -} - -function decoder_error_no_classify(expected, got) { - return new Error( - List.fromArray([new DecodeError(expected, got, List.fromArray([]))]) - ); -} - -export function decode_string(data) { - return typeof data === "string" - ? new Ok(data) - : decoder_error("String", data); -} - -export function decode_int(data) { - return Number.isInteger(data) ? new Ok(data) : decoder_error("Int", data); -} - -export function decode_float(data) { - return typeof data === "number" ? new Ok(data) : decoder_error("Float", data); -} - -export function decode_bool(data) { - return typeof data === "boolean" ? new Ok(data) : decoder_error("Bool", data); -} - -export function decode_bit_array(data) { - if (data instanceof BitArray) { - return new Ok(data); - } - if (data instanceof Uint8Array) { - return new Ok(new BitArray(data)); - } - return decoder_error("BitArray", data); -} - -export function decode_tuple(data) { - return Array.isArray(data) ? new Ok(data) : decoder_error("Tuple", data); -} - -export function decode_tuple2(data) { - return decode_tupleN(data, 2); -} - -export function decode_tuple3(data) { - return decode_tupleN(data, 3); -} - -export function decode_tuple4(data) { - return decode_tupleN(data, 4); -} - -export function decode_tuple5(data) { - return decode_tupleN(data, 5); -} - -export function decode_tuple6(data) { - return decode_tupleN(data, 6); -} - -function decode_tupleN(data, n) { - if (Array.isArray(data) && data.length == n) { - return new Ok(data); - } - - const list = decode_exact_length_list(data, n); - if (list) return new Ok(list); - - return decoder_error(`Tuple of ${n} elements`, data); -} - -function decode_exact_length_list(data, n) { - if (!(data instanceof List)) return; - - const elements = []; - let current = data; - - for (let i = 0; i < n; i++) { - if (!(current instanceof NonEmpty)) break; - elements.push(current.head); - current = current.tail; - } - - if (elements.length === n && !(current instanceof NonEmpty)) return elements; -} - -export function tuple_get(data, index) { - return index >= 0 && data.length > index - ? new Ok(data[index]) - : new Error(Nil); -} - -export function decode_list(data) { - if (Array.isArray(data)) { - return new Ok(List.fromArray(data)); - } - return data instanceof List ? new Ok(data) : decoder_error("List", data); -} - -export function decode_result(data) { - return data instanceof Result ? new Ok(data) : decoder_error("Result", data); -} - -export function decode_map(data) { - if (data instanceof Dict) { - return new Ok(Dict.fromMap(data)); - } - if (data == null) { - return decoder_error("Map", data); - } - if (typeof data !== "object") { - return decoder_error("Map", data); - } - const proto = Object.getPrototypeOf(data); - if (proto === Object.prototype || proto === null) { - return new Ok(Dict.fromObject(data)); - } - return decoder_error("Map", data); -} - -export function decode_option(data, decoder) { - if (data === null || data === undefined || data instanceof None) - return new Ok(new None()); - if (data instanceof Some) data = data[0]; - const result = decoder(data); - if (result.isOk()) { - return new Ok(new Some(result[0])); - } else { - return result; - } -} - -export function decode_field(value, name) { - const not_a_map_error = () => decoder_error("Map", value); - - if ( - value instanceof Dict || - value instanceof WeakMap || - value instanceof Map - ) { - const entry = map_get(value, name); - return new Ok(entry.isOk() ? new Some(entry[0]) : new None()); - } else if (Object.getPrototypeOf(value) == Object.prototype) { - return try_get_field(value, name, () => new Ok(new None())); - } else { - return try_get_field(value, name, not_a_map_error); - } -} - -function try_get_field(value, field, or_else) { - try { - return field in value ? new Ok(new Some(value[field])) : or_else(); - } catch { - return or_else(); - } -} - -export function byte_size(string) { - return new TextEncoder().encode(string).length; -} - -// In Javascript bitwise operations convert numbers to a sequence of 32 bits -// while Erlang uses arbitrary precision. -// To get around this problem and get consistent results use BigInt and then -// downcast the value back to a Number value. - -export function bitwise_and(x, y) { - return Number(BigInt(x) & BigInt(y)); -} - -export function bitwise_not(x) { - return Number(~BigInt(x)); -} - -export function bitwise_or(x, y) { - return Number(BigInt(x) | BigInt(y)); -} - -export function bitwise_exclusive_or(x, y) { - return Number(BigInt(x) ^ BigInt(y)); -} - -export function bitwise_shift_left(x, y) { - return Number(BigInt(x) << BigInt(y)); -} - -export function bitwise_shift_right(x, y) { - return Number(BigInt(x) >> BigInt(y)); -} - -export function inspect(v) { - const t = typeof v; - if (v === true) return "True"; - if (v === false) return "False"; - if (v === null) return "//js(null)"; - if (v === undefined) return "Nil"; - if (t === "string") return JSON.stringify(v); - if (t === "bigint" || t === "number") return v.toString(); - if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; - if (v instanceof List) return inspectList(v); - if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); - if (v instanceof BitArray) return inspectBitArray(v); - if (v instanceof CustomType) return inspectCustomType(v); - if (v instanceof Dict) return inspectDict(v); - if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; - if (v instanceof RegExp) return `//js(${v})`; - if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; - if (v instanceof Function) { - const args = []; - for (const i of Array(v.length).keys()) - args.push(String.fromCharCode(i + 97)); - return `//fn(${args.join(", ")}) { ... }`; - } - return inspectObject(v); -} - -function inspectDict(map) { - let body = "dict.from_list(["; - let first = true; - map.forEach((value, key) => { - if (!first) body = body + ", "; - body = body + "#(" + inspect(key) + ", " + inspect(value) + ")"; - first = false; - }); - return body + "])"; -} - -function inspectObject(v) { - const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; - const props = []; - for (const k of Object.keys(v)) { - props.push(`${inspect(k)}: ${inspect(v[k])}`); - } - const body = props.length ? " " + props.join(", ") + " " : ""; - const head = name === "Object" ? "" : name + " "; - return `//js(${head}{${body}})`; -} - -function inspectCustomType(record) { - const props = Object.keys(record) - .map((label) => { - const value = inspect(record[label]); - return isNaN(parseInt(label)) ? `${label}: ${value}` : value; - }) - .join(", "); - return props - ? `${record.constructor.name}(${props})` - : record.constructor.name; -} - -export function inspectList(list) { - return `[${list.toArray().map(inspect).join(", ")}]`; -} - -export function inspectBitArray(bits) { - return `<<${Array.from(bits.buffer).join(", ")}>>`; -} - -export function inspectUtfCodepoint(codepoint) { - return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; -} - -export function base16_encode(bit_array) { - let result = ""; - for (const byte of bit_array.buffer) { - result += byte.toString(16).padStart(2, "0").toUpperCase(); - } - return result; -} - -export function base16_decode(string) { - const bytes = new Uint8Array(string.length / 2); - for (let i = 0; i < string.length; i += 2) { - const a = parseInt(string[i], 16); - const b = parseInt(string[i + 1], 16); - if (isNaN(a) || isNaN(b)) return new Error(Nil); - bytes[i / 2] = a * 16 + b; - } - return new Ok(new BitArray(bytes)); -} diff --git a/aoc2023/build/packages/glint/LICENSE b/aoc2023/build/packages/glint/LICENSE deleted file mode 100644 index 261eeb9..0000000 --- a/aoc2023/build/packages/glint/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/aoc2023/build/packages/glint/README.md b/aoc2023/build/packages/glint/README.md deleted file mode 100644 index d6d5821..0000000 --- a/aoc2023/build/packages/glint/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# glint - -[](https://hex.pm/packages/glint) -[](https://hex.pm/packages/glint) -[](https://hexdocs.pm/glint/) -[](https://github.com/tanklesxl/glint/actions) - -Gleam command line argument parsing with basic flag support. - -## Installation - -To install from hex: - -```sh -gleam add glint -``` - -## Usage - -### Glint's Core - -`glint` is conceptually quite small, your general flow will be: - -1. create a new glint instance with `glint.new` -1. configure it with `glint.with_pretty_help` and other configuration functions -1. add commands with `glint.add` - 1. create a new command with `glint.cmd` - 1. assign that command any flags required - 1. assign the command a custom description -1. run your cli with `glnt.run`, run with a function to handle command output with `glint.run_and_handle` - -### Mini Example - -You can import `glint` as a dependency and use it to build simple command-line applications like the following simplified version of the [the hello world example](https://github.com/TanklesXL/glint/tree/main/examples/hello/README.md) - -```gleam -// stdlib imports -import gleam/io -import gleam/list -import gleam/result -import gleam/string.{uppercase} -// external dep imports -import snag -// glint imports -import glint -import glint/flag -// erlang-specific imports - -@target(erlang) -import gleam/erlang.{start_arguments} - -/// the key for the caps flag -const caps = "caps" - -/// a boolean flag with default False to control message capitalization. -/// -fn caps_flag() -> flag.FlagBuilder(Bool) { - flag.bool() - |> flag.default(False) - |> flag.description("Capitalize the provided name") -} - -/// the command function that will be executed -/// -fn hello(input: glint.CommandInput) -> Nil { - let assert Ok(caps) = flag.get_bool(from: input.flags, for: caps) - - let name = - case input.args { - [] -> "Joe" - [name,..] -> name - } - - let msg = "Hello, " <> name <> "!" - - - case caps { - True -> uppercase(msg) - False -> msg - } - |> io.println -} - -pub fn main() { - // create a new glint instance - glint.new() - // with an app name of "hello", this is used when printing help text - |> glint.with_name("hello") - // with pretty help enabled, using the built-in colours - |> glint.with_pretty_help(glint.default_pretty_help()) - // with a root command that executes the `hello` function - |> glint.add( - // add the command to the root - at: [], - // create the command, add any flags - do: glint.command(hello) - // with flag `caps` - |> glint.flag(caps, caps_flag()) - // with a short description - |> glint.description("Prints Hello, <NAME>!"), - ) - |> glint.run(start_arguments()) -} -``` diff --git a/aoc2023/build/packages/glint/gleam.toml b/aoc2023/build/packages/glint/gleam.toml deleted file mode 100644 index e8ac4ae..0000000 --- a/aoc2023/build/packages/glint/gleam.toml +++ /dev/null @@ -1,23 +0,0 @@ -name = "glint" -version = "0.13.0" - -# Fill out these fields if you intend to generate HTML documentation or publishname = "glint" -# your project to the Hex package manager. -# -licences = ["Apache-2.0"] -description = "Gleam command line argument parsing with basic flag support." -repository = { type = "github", user = "TanklesXL", repo = "glint" } -links = [ - { title = "Hex", href = "https://hex.pm/packages/glint" }, - { title = "Docs", href = "https://hexdocs.pm/glint/" }, -] -gleam = ">= 0.32.0" - -[dependencies] -gleam_stdlib = "~> 0.19" -snag = "~> 0.2" -gleam_community_ansi = "~> 1.0" -gleam_community_colour = "~> 1.0" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/aoc2023/build/packages/glint/include/glint@flag_Flag.hrl b/aoc2023/build/packages/glint/include/glint@flag_Flag.hrl deleted file mode 100644 index 645cb12..0000000 --- a/aoc2023/build/packages/glint/include/glint@flag_Flag.hrl +++ /dev/null @@ -1 +0,0 @@ --record(flag, {value :: glint@flag:value(), description :: binary()}). diff --git a/aoc2023/build/packages/glint/include/glint@flag_FlagBuilder.hrl b/aoc2023/build/packages/glint/include/glint@flag_FlagBuilder.hrl deleted file mode 100644 index b5e21a2..0000000 --- a/aoc2023/build/packages/glint/include/glint@flag_FlagBuilder.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(flag_builder, { - desc :: binary(), - parser :: fun((binary()) -> {ok, any()} | {error, snag:snag()}), - value :: fun((glint@flag:internal(any())) -> glint@flag:value()), - default :: gleam@option:option(any()) -}). diff --git a/aoc2023/build/packages/glint/include/glint@flag_Internal.hrl b/aoc2023/build/packages/glint/include/glint@flag_Internal.hrl deleted file mode 100644 index 281bbd0..0000000 --- a/aoc2023/build/packages/glint/include/glint@flag_Internal.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(internal, { - value :: gleam@option:option(any()), - parser :: fun((binary()) -> {ok, any()} | {error, snag:snag()}) -}). diff --git a/aoc2023/build/packages/glint/include/glint_Command.hrl b/aoc2023/build/packages/glint/include/glint_Command.hrl deleted file mode 100644 index 00a03e3..0000000 --- a/aoc2023/build/packages/glint/include/glint_Command.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(command, { - do :: fun((glint:command_input()) -> any()), - flags :: gleam@map:map_(binary(), glint@flag:flag()), - description :: binary() -}). diff --git a/aoc2023/build/packages/glint/include/glint_CommandInput.hrl b/aoc2023/build/packages/glint/include/glint_CommandInput.hrl deleted file mode 100644 index 72c9641..0000000 --- a/aoc2023/build/packages/glint/include/glint_CommandInput.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(command_input, { - args :: list(binary()), - flags :: gleam@map:map_(binary(), glint@flag:flag()) -}). diff --git a/aoc2023/build/packages/glint/include/glint_Config.hrl b/aoc2023/build/packages/glint/include/glint_Config.hrl deleted file mode 100644 index 70cf645..0000000 --- a/aoc2023/build/packages/glint/include/glint_Config.hrl +++ /dev/null @@ -1,4 +0,0 @@ --record(config, { - pretty_help :: gleam@option:option(glint:pretty_help()), - name :: gleam@option:option(binary()) -}). diff --git a/aoc2023/build/packages/glint/include/glint_Glint.hrl b/aoc2023/build/packages/glint/include/glint_Glint.hrl deleted file mode 100644 index 7ece11d..0000000 --- a/aoc2023/build/packages/glint/include/glint_Glint.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(glint, { - config :: glint:config(), - cmd :: glint:command_node(any()), - global_flags :: gleam@map:map_(binary(), glint@flag:flag()) -}). diff --git a/aoc2023/build/packages/glint/include/glint_PrettyHelp.hrl b/aoc2023/build/packages/glint/include/glint_PrettyHelp.hrl deleted file mode 100644 index 79bd887..0000000 --- a/aoc2023/build/packages/glint/include/glint_PrettyHelp.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(pretty_help, { - usage :: gleam_community@colour:colour(), - flags :: gleam_community@colour:colour(), - subcommands :: gleam_community@colour:colour() -}). diff --git a/aoc2023/build/packages/glint/include/glint_Stub.hrl b/aoc2023/build/packages/glint/include/glint_Stub.hrl deleted file mode 100644 index 5aa5d83..0000000 --- a/aoc2023/build/packages/glint/include/glint_Stub.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(stub, { - path :: list(binary()), - run :: fun((glint:command_input()) -> any()), - flags :: list({binary(), glint@flag:flag()}), - description :: binary() -}). diff --git a/aoc2023/build/packages/glint/src/glint.app.src b/aoc2023/build/packages/glint/src/glint.app.src deleted file mode 100644 index 7eb7649..0000000 --- a/aoc2023/build/packages/glint/src/glint.app.src +++ /dev/null @@ -1,13 +0,0 @@ -{application, glint, [ - {vsn, "0.13.0"}, - {applications, [gleam_community_ansi, - gleam_community_colour, - gleam_stdlib, - gleeunit, - snag]}, - {description, "Gleam command line argument parsing with basic flag support."}, - {modules, [glint, - glint@flag, - glint@flag@constraint]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/glint/src/glint.erl b/aoc2023/build/packages/glint/src/glint.erl deleted file mode 100644 index 0501cc6..0000000 --- a/aoc2023/build/packages/glint/src/glint.erl +++ /dev/null @@ -1,513 +0,0 @@ --module(glint). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([with_config/2, with_pretty_help/2, without_pretty_help/1, with_name/2, new/0, command/1, description/2, flag/3, flag_tuple/2, flags/2, global_flag/3, global_flag_tuple/2, global_flags/2, default_pretty_help/0, add/3, help_flag/0, execute/2, run_and_handle/3, run/2, add_command_from_stub/2]). --export_type([config/0, pretty_help/0, glint/1, command/1, command_input/0, command_node/1, out/1, stub/1]). - --type config() :: {config, - gleam@option:option(pretty_help()), - gleam@option:option(binary())}. - --type pretty_help() :: {pretty_help, - gleam_community@colour:colour(), - gleam_community@colour:colour(), - gleam_community@colour:colour()}. - --opaque glint(GHR) :: {glint, - config(), - command_node(GHR), - gleam@map:map_(binary(), glint@flag:flag())}. - --opaque command(GHS) :: {command, - fun((command_input()) -> GHS), - gleam@map:map_(binary(), glint@flag:flag()), - binary()}. - --type command_input() :: {command_input, - list(binary()), - gleam@map:map_(binary(), glint@flag:flag())}. - --type command_node(GHT) :: {command_node, - gleam@option:option(command(GHT)), - gleam@map:map_(binary(), command_node(GHT))}. - --type out(GHU) :: {out, GHU} | {help, binary()}. - --type stub(GHV) :: {stub, - list(binary()), - fun((command_input()) -> GHV), - list({binary(), glint@flag:flag()}), - binary()}. - --spec with_config(glint(GIA), config()) -> glint(GIA). -with_config(Glint, Config) -> - erlang:setelement(2, Glint, Config). - --spec with_pretty_help(glint(GID), pretty_help()) -> glint(GID). -with_pretty_help(Glint, Pretty) -> - _pipe = erlang:setelement(2, erlang:element(2, Glint), {some, Pretty}), - with_config(Glint, _pipe). - --spec without_pretty_help(glint(GIG)) -> glint(GIG). -without_pretty_help(Glint) -> - _pipe = erlang:setelement(2, erlang:element(2, Glint), none), - with_config(Glint, _pipe). - --spec with_name(glint(GIJ), binary()) -> glint(GIJ). -with_name(Glint, Name) -> - _pipe = erlang:setelement(3, erlang:element(2, Glint), {some, Name}), - with_config(Glint, _pipe). - --spec empty_command() -> command_node(any()). -empty_command() -> - {command_node, none, gleam@map:new()}. - --spec new() -> glint(any()). -new() -> - {glint, {config, none, none}, empty_command(), gleam@map:new()}. - --spec do_add(command_node(GIT), list(binary()), command(GIT)) -> command_node(GIT). -do_add(Root, Path, Contents) -> - case Path of - [] -> - erlang:setelement(2, Root, {some, Contents}); - - [X | Xs] -> - erlang:setelement( - 3, - Root, - (gleam@map:update( - erlang:element(3, Root), - X, - fun(Node) -> _pipe = Node, - _pipe@1 = gleam@option:lazy_unwrap( - _pipe, - fun empty_command/0 - ), - do_add(_pipe@1, Xs, Contents) end - )) - ) - end. - --spec command(fun((command_input()) -> GJC)) -> command(GJC). -command(Runner) -> - {command, Runner, gleam@map:new(), <<""/utf8>>}. - --spec description(command(GJF), binary()) -> command(GJF). -description(Cmd, Description) -> - erlang:setelement(4, Cmd, Description). - --spec flag(command(GJI), binary(), glint@flag:flag_builder(any())) -> command(GJI). -flag(Cmd, Key, Flag) -> - erlang:setelement( - 3, - Cmd, - gleam@map:insert(erlang:element(3, Cmd), Key, glint@flag:build(Flag)) - ). - --spec flag_tuple(command(GJN), {binary(), glint@flag:flag_builder(any())}) -> command(GJN). -flag_tuple(Cmd, Tup) -> - flag(Cmd, erlang:element(1, Tup), erlang:element(2, Tup)). - --spec flags(command(GJS), list({binary(), glint@flag:flag()})) -> command(GJS). -flags(Cmd, Flags) -> - gleam@list:fold( - Flags, - Cmd, - fun(Cmd@1, _use1) -> - {Key, Flag} = _use1, - erlang:setelement( - 3, - Cmd@1, - gleam@map:insert(erlang:element(3, Cmd@1), Key, Flag) - ) - end - ). - --spec global_flag(glint(GJW), binary(), glint@flag:flag_builder(any())) -> glint(GJW). -global_flag(Glint, Key, Flag) -> - erlang:setelement( - 4, - Glint, - gleam@map:insert(erlang:element(4, Glint), Key, glint@flag:build(Flag)) - ). - --spec global_flag_tuple(glint(GKB), {binary(), glint@flag:flag_builder(any())}) -> glint(GKB). -global_flag_tuple(Glint, Tup) -> - global_flag(Glint, erlang:element(1, Tup), erlang:element(2, Tup)). - --spec global_flags(glint(GKG), list({binary(), glint@flag:flag()})) -> glint(GKG). -global_flags(Glint, Flags) -> - erlang:setelement( - 4, - Glint, - (gleam@list:fold( - Flags, - erlang:element(4, Glint), - fun(Acc, Tup) -> - gleam@map:insert( - Acc, - erlang:element(1, Tup), - erlang:element(2, Tup) - ) - end - )) - ). - --spec execute_root( - command_node(GKU), - gleam@map:map_(binary(), glint@flag:flag()), - list(binary()), - list(binary()) -) -> {ok, out(GKU)} | {error, snag:snag()}. -execute_root(Cmd, Global_flags, Args, Flag_inputs) -> - _pipe@3 = case erlang:element(2, Cmd) of - {some, Contents} -> - gleam@result:'try'( - gleam@list:try_fold( - Flag_inputs, - gleam@map:merge(Global_flags, erlang:element(3, Contents)), - fun glint@flag:update_flags/2 - ), - fun(New_flags) -> _pipe = {command_input, Args, New_flags}, - _pipe@1 = (erlang:element(2, Contents))(_pipe), - _pipe@2 = {out, _pipe@1}, - {ok, _pipe@2} end - ); - - none -> - snag:error(<<"command not found"/utf8>>) - end, - snag:context(_pipe@3, <<"failed to run command"/utf8>>). - --spec default_pretty_help() -> pretty_help(). -default_pretty_help() -> - _assert_subject = gleam_community@colour:from_rgb255(182, 255, 234), - {ok, Usage_colour} = case _assert_subject of - {ok, _} -> _assert_subject; - _assert_fail -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail, - module => <<"glint"/utf8>>, - function => <<"default_pretty_help"/utf8>>, - line => 404}) - end, - _assert_subject@1 = gleam_community@colour:from_rgb255(255, 175, 243), - {ok, Flags_colour} = case _assert_subject@1 of - {ok, _} -> _assert_subject@1; - _assert_fail@1 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@1, - module => <<"glint"/utf8>>, - function => <<"default_pretty_help"/utf8>>, - line => 405}) - end, - _assert_subject@2 = gleam_community@colour:from_rgb255(252, 226, 174), - {ok, Subcommands_colour} = case _assert_subject@2 of - {ok, _} -> _assert_subject@2; - _assert_fail@2 -> - erlang:error(#{gleam_error => let_assert, - message => <<"Assertion pattern match failed"/utf8>>, - value => _assert_fail@2, - module => <<"glint"/utf8>>, - function => <<"default_pretty_help"/utf8>>, - line => 406}) - end, - {pretty_help, Usage_colour, Flags_colour, Subcommands_colour}. - --spec is_not_empty(binary()) -> boolean(). -is_not_empty(S) -> - S /= <<""/utf8>>. - --spec sanitize_path(list(binary())) -> list(binary()). -sanitize_path(Path) -> - _pipe = Path, - _pipe@1 = gleam@list:map(_pipe, fun gleam@string:trim/1), - gleam@list:filter(_pipe@1, fun is_not_empty/1). - --spec add(glint(GIO), list(binary()), command(GIO)) -> glint(GIO). -add(Glint, Path, Contents) -> - erlang:setelement( - 3, - Glint, - begin - _pipe = Path, - _pipe@1 = sanitize_path(_pipe), - do_add(erlang:element(3, Glint), _pipe@1, Contents) - end - ). - --spec help_flag() -> binary(). -help_flag() -> - <<(<<"--"/utf8>>)/binary, "help"/utf8>>. - --spec wrap_with_space(binary()) -> binary(). -wrap_with_space(S) -> - case S of - <<""/utf8>> -> - <<" "/utf8>>; - - _ -> - <<<<" "/utf8, S/binary>>/binary, " "/utf8>> - end. - --spec subcommand_help(binary(), command_node(any())) -> binary(). -subcommand_help(Name, Cmd) -> - case erlang:element(2, Cmd) of - none -> - Name; - - {some, Contents} -> - <<<<Name/binary, "\t\t"/utf8>>/binary, - (erlang:element(4, Contents))/binary>> - end. - --spec subcommands_help(gleam@map:map_(binary(), command_node(any()))) -> binary(). -subcommands_help(Cmds) -> - _pipe = Cmds, - _pipe@1 = gleam@map:map_values(_pipe, fun subcommand_help/2), - _pipe@2 = gleam@map:values(_pipe@1), - _pipe@3 = gleam@list:sort(_pipe@2, fun gleam@string:compare/2), - gleam@string:join(_pipe@3, <<"\n\t"/utf8>>). - --spec heading_style(binary(), gleam_community@colour:colour()) -> binary(). -heading_style(Heading, Colour) -> - _pipe = Heading, - _pipe@1 = gleam_community@ansi:bold(_pipe), - _pipe@2 = gleam_community@ansi:underline(_pipe@1), - _pipe@3 = gleam_community@ansi:italic(_pipe@2), - _pipe@4 = gleam_community@ansi:hex( - _pipe@3, - gleam_community@colour:to_rgb_hex(Colour) - ), - gleam_community@ansi:reset(_pipe@4). - --spec usage_help( - binary(), - gleam@map:map_(binary(), glint@flag:flag()), - config() -) -> binary(). -usage_help(Cmd_name, Flags, Config) -> - App_name = gleam@option:unwrap( - erlang:element(3, Config), - <<"gleam run"/utf8>> - ), - Flags@1 = begin - _pipe = Flags, - _pipe@1 = gleam@map:to_list(_pipe), - _pipe@2 = gleam@list:map(_pipe@1, fun glint@flag:flag_type_help/1), - gleam@list:sort(_pipe@2, fun gleam@string:compare/2) - end, - Flag_sb = case Flags@1 of - [] -> - gleam@string_builder:new(); - - _ -> - _pipe@3 = Flags@1, - _pipe@4 = gleam@list:intersperse(_pipe@3, <<" "/utf8>>), - _pipe@5 = gleam@string_builder:from_strings(_pipe@4), - _pipe@6 = gleam@string_builder:prepend(_pipe@5, <<" [ "/utf8>>), - gleam@string_builder:append(_pipe@6, <<" ]"/utf8>>) - end, - _pipe@7 = [App_name, wrap_with_space(Cmd_name), <<"[ ARGS ]"/utf8>>], - _pipe@8 = gleam@string_builder:from_strings(_pipe@7), - _pipe@9 = gleam@string_builder:append_builder(_pipe@8, Flag_sb), - _pipe@12 = gleam@string_builder:prepend( - _pipe@9, - <<(begin - _pipe@10 = erlang:element(2, Config), - _pipe@11 = gleam@option:map( - _pipe@10, - fun(Styling) -> - heading_style( - <<"USAGE:"/utf8>>, - erlang:element(2, Styling) - ) - end - ), - gleam@option:unwrap(_pipe@11, <<"USAGE:"/utf8>>) - end)/binary, - "\n\t"/utf8>> - ), - gleam@string_builder:to_string(_pipe@12). - --spec cmd_help( - list(binary()), - command_node(any()), - config(), - gleam@map:map_(binary(), glint@flag:flag()) -) -> binary(). -cmd_help(Path, Cmd, Config, Global_flags) -> - Name = begin - _pipe = Path, - _pipe@1 = gleam@list:reverse(_pipe), - gleam@string:join(_pipe@1, <<" "/utf8>>) - end, - Flags = begin - _pipe@2 = gleam@option:map( - erlang:element(2, Cmd), - fun(Contents) -> erlang:element(3, Contents) end - ), - _pipe@3 = gleam@option:lazy_unwrap(_pipe@2, fun gleam@map:new/0), - gleam@map:merge(Global_flags, _pipe@3) - end, - Flags_help_body = <<<<(begin - _pipe@4 = erlang:element(2, Config), - _pipe@5 = gleam@option:map( - _pipe@4, - fun(P) -> - heading_style(<<"FLAGS:"/utf8>>, erlang:element(3, P)) - end - ), - gleam@option:unwrap(_pipe@5, <<"FLAGS:"/utf8>>) - end)/binary, - "\n\t"/utf8>>/binary, - (gleam@string:join( - gleam@list:sort( - [<<"--help\t\t\tPrint help information"/utf8>> | - glint@flag:flags_help(Flags)], - fun gleam@string:compare/2 - ), - <<"\n\t"/utf8>> - ))/binary>>, - Usage = usage_help(Name, Flags, Config), - Description = begin - _pipe@6 = erlang:element(2, Cmd), - _pipe@7 = gleam@option:map( - _pipe@6, - fun(Contents@1) -> erlang:element(4, Contents@1) end - ), - gleam@option:unwrap(_pipe@7, <<""/utf8>>) - end, - Header_items = begin - _pipe@8 = [Name, Description], - _pipe@9 = gleam@list:filter(_pipe@8, fun is_not_empty/1), - gleam@string:join(_pipe@9, <<"\n"/utf8>>) - end, - Subcommands = case subcommands_help(erlang:element(3, Cmd)) of - <<""/utf8>> -> - <<""/utf8>>; - - Subcommands_help_body -> - <<<<(begin - _pipe@10 = erlang:element(2, Config), - _pipe@11 = gleam@option:map( - _pipe@10, - fun(P@1) -> - heading_style( - <<"SUBCOMMANDS:"/utf8>>, - erlang:element(4, P@1) - ) - end - ), - gleam@option:unwrap(_pipe@11, <<"SUBCOMMANDS:"/utf8>>) - end)/binary, - "\n\t"/utf8>>/binary, - Subcommands_help_body/binary>> - end, - _pipe@12 = [Header_items, Usage, Flags_help_body, Subcommands], - _pipe@13 = gleam@list:filter(_pipe@12, fun is_not_empty/1), - gleam@string:join(_pipe@13, <<"\n\n"/utf8>>). - --spec do_execute( - command_node(GKO), - config(), - gleam@map:map_(binary(), glint@flag:flag()), - list(binary()), - list(binary()), - boolean(), - list(binary()) -) -> {ok, out(GKO)} | {error, snag:snag()}. -do_execute(Cmd, Config, Global_flags, Args, Flags, Help, Command_path) -> - case Args of - [] when Help -> - _pipe = Command_path, - _pipe@1 = cmd_help(_pipe, Cmd, Config, Global_flags), - _pipe@2 = {help, _pipe@1}, - {ok, _pipe@2}; - - [] -> - execute_root(Cmd, Global_flags, [], Flags); - - [Arg | Rest] -> - case gleam@map:get(erlang:element(3, Cmd), Arg) of - {ok, Cmd@1} -> - do_execute( - Cmd@1, - Config, - Global_flags, - Rest, - Flags, - Help, - [Arg | Command_path] - ); - - _ when Help -> - _pipe@3 = Command_path, - _pipe@4 = cmd_help(_pipe@3, Cmd, Config, Global_flags), - _pipe@5 = {help, _pipe@4}, - {ok, _pipe@5}; - - _ -> - execute_root(Cmd, Global_flags, Args, Flags) - end - end. - --spec execute(glint(GKK), list(binary())) -> {ok, out(GKK)} | - {error, snag:snag()}. -execute(Glint, Args) -> - Help_flag = help_flag(), - {Help, Args@2} = case gleam@list:pop(Args, fun(S) -> S =:= Help_flag end) of - {ok, {_, Args@1}} -> - {true, Args@1}; - - _ -> - {false, Args} - end, - {Flags, Args@3} = gleam@list:partition( - Args@2, - fun(_capture) -> gleam@string:starts_with(_capture, <<"--"/utf8>>) end - ), - do_execute( - erlang:element(3, Glint), - erlang:element(2, Glint), - erlang:element(4, Glint), - Args@3, - Flags, - Help, - [] - ). - --spec run_and_handle(glint(GLC), list(binary()), fun((GLC) -> any())) -> nil. -run_and_handle(Glint, Args, Handle) -> - case execute(Glint, Args) of - {error, Err} -> - _pipe = Err, - _pipe@1 = snag:pretty_print(_pipe), - gleam@io:println(_pipe@1); - - {ok, {help, Help}} -> - gleam@io:println(Help); - - {ok, {out, Out}} -> - Handle(Out), - nil - end. - --spec run(glint(any()), list(binary())) -> nil. -run(Glint, Args) -> - run_and_handle(Glint, Args, gleam@function:constant(nil)). - --spec add_command_from_stub(glint(GLP), stub(GLP)) -> glint(GLP). -add_command_from_stub(Glint, Stub) -> - add( - Glint, - erlang:element(2, Stub), - begin - _pipe = command(erlang:element(3, Stub)), - _pipe@1 = flags(_pipe, erlang:element(4, Stub)), - description(_pipe@1, erlang:element(5, Stub)) - end - ). diff --git a/aoc2023/build/packages/glint/src/glint.gleam b/aoc2023/build/packages/glint/src/glint.gleam deleted file mode 100644 index b159016..0000000 --- a/aoc2023/build/packages/glint/src/glint.gleam +++ /dev/null @@ -1,588 +0,0 @@ -import gleam/map.{type Map} -import gleam/option.{type Option, None, Some} -import gleam/list -import gleam/io -import gleam/string -import snag.{type Result} -import glint/flag.{type Flag, type Map as FlagMap} -import gleam/string_builder as sb -import gleam_community/ansi -import gleam_community/colour.{type Colour} -import gleam/result -import gleam/function - -// --- CONFIGURATION --- - -// -- CONFIGURATION: TYPES -- - -/// Config for glint -/// -pub type Config { - Config(pretty_help: Option(PrettyHelp), name: Option(String)) -} - -/// PrettyHelp defines the header colours to be used when styling help text -/// -pub type PrettyHelp { - PrettyHelp(usage: Colour, flags: Colour, subcommands: Colour) -} - -// -- CONFIGURATION: CONSTANTS -- - -/// Default config -/// -pub const default_config = Config(pretty_help: None, name: None) - -// -- CONFIGURATION: FUNCTIONS -- - -/// Add the provided config to the existing command tree -/// -pub fn with_config(glint: Glint(a), config: Config) -> Glint(a) { - Glint(..glint, config: config) -} - -/// Enable custom colours for help text headers -/// For a pre-made colouring use `default_pretty_help()` -/// -pub fn with_pretty_help(glint: Glint(a), pretty: PrettyHelp) -> Glint(a) { - Config(..glint.config, pretty_help: Some(pretty)) - |> with_config(glint, _) -} - -/// Disable custom colours for help text headers -/// -pub fn without_pretty_help(glint: Glint(a)) -> Glint(a) { - Config(..glint.config, pretty_help: None) - |> with_config(glint, _) -} - -pub fn with_name(glint: Glint(a), name: String) -> Glint(a) { - Config(..glint.config, name: Some(name)) - |> with_config(glint, _) -} - -// --- CORE --- - -// -- CORE: TYPES -- - -/// Glint container type for config and commands -/// -pub opaque type Glint(a) { - Glint(config: Config, cmd: CommandNode(a), global_flags: FlagMap) -} - -/// CommandNode contents -/// -pub opaque type Command(a) { - Command(do: Runner(a), flags: FlagMap, description: String) -} - -/// Input type for `Runner`. -/// -pub type CommandInput { - CommandInput(args: List(String), flags: FlagMap) -} - -/// Function type to be run by `glint`. -/// -pub type Runner(a) = - fn(CommandInput) -> a - -/// CommandNode tree representation. -/// -type CommandNode(a) { - CommandNode( - contents: Option(Command(a)), - subcommands: Map(String, CommandNode(a)), - ) -} - -/// Ok type for command execution -/// -pub type Out(a) { - /// Container for the command return value - Out(a) - /// Container for the generated help string - Help(String) -} - -/// Result type for command execution -/// -pub type CmdResult(a) = - Result(Out(a)) - -// -- CORE: BUILDER FUNCTIONS -- - -/// Creates a new command tree. -/// -pub fn new() -> Glint(a) { - Glint(config: default_config, cmd: empty_command(), global_flags: map.new()) -} - -/// Adds a new command to be run at the specified path. -/// -/// If the path is `[]`, the root command is set with the provided function and -/// flags. -/// -/// Note: all command paths are sanitized by stripping whitespace and removing any empty string elements. -/// -pub fn add( - to glint: Glint(a), - at path: List(String), - do contents: Command(a), -) -> Glint(a) { - Glint( - ..glint, - cmd: path - |> sanitize_path - |> do_add(to: glint.cmd, put: contents), - ) -} - -/// Recursive traversal of the command tree to find where to puth the provided command -/// -fn do_add( - to root: CommandNode(a), - at path: List(String), - put contents: Command(a), -) -> CommandNode(a) { - case path { - // update current command with provided contents - [] -> CommandNode(..root, contents: Some(contents)) - // continue down the path, creating empty command nodes along the way - [x, ..xs] -> - CommandNode( - ..root, - subcommands: { - use node <- map.update(root.subcommands, x) - node - |> option.lazy_unwrap(empty_command) - |> do_add(xs, contents) - }, - ) - } -} - -/// Helper for initializing empty commands -/// -fn empty_command() -> CommandNode(a) { - CommandNode(contents: None, subcommands: map.new()) -} - -/// Trim each path element and remove any resulting empty strings. -/// -fn sanitize_path(path: List(String)) -> List(String) { - path - |> list.map(string.trim) - |> list.filter(is_not_empty) -} - -/// Create a Command(a) from a Runner(a) -/// -pub fn command(do runner: Runner(a)) -> Command(a) { - Command(do: runner, flags: map.new(), description: "") -} - -/// Attach a description to a Command(a) -/// -pub fn description(cmd: Command(a), description: String) -> Command(a) { - Command(..cmd, description: description) -} - -/// add a `flag.Flag` to a `Command` -/// -pub fn flag( - cmd: Command(a), - at key: String, - of flag: flag.FlagBuilder(_), -) -> Command(a) { - Command(..cmd, flags: map.insert(cmd.flags, key, flag.build(flag))) -} - -/// Add a `flag.Flag to a `Command` when the flag name and builder are bundled as a #(String, flag.FlagBuilder(a)). -/// -/// This is merely a convenience function and calls `glint.flag` under the hood. -/// -pub fn flag_tuple( - cmd: Command(a), - with tup: #(String, flag.FlagBuilder(_)), -) -> Command(a) { - flag(cmd, tup.0, tup.1) -} - -/// Add multiple `Flag`s to a `Command`, note that this function uses `Flag` and not `FlagBuilder(_)`, so the user will need to call `flag.build` before providing the flags here. -/// -/// It is recommended to call `glint.flag` instead. -/// -pub fn flags(cmd: Command(a), with flags: List(#(String, Flag))) -> Command(a) { - use cmd, #(key, flag) <- list.fold(flags, cmd) - Command(..cmd, flags: map.insert(cmd.flags, key, flag)) -} - -/// Add global flags to the existing command tree -/// -pub fn global_flag( - glint: Glint(a), - at key: String, - of flag: flag.FlagBuilder(_), -) -> Glint(a) { - Glint( - ..glint, - global_flags: map.insert(glint.global_flags, key, flag.build(flag)), - ) -} - -/// Add global flags to the existing command tree. -/// -pub fn global_flag_tuple( - glint: Glint(a), - with tup: #(String, flag.FlagBuilder(_)), -) -> Glint(a) { - global_flag(glint, tup.0, tup.1) -} - -/// Add global flags to the existing command tree. -/// -/// Like `glint.flags`, this function requires `Flag`s insead of `FlagBuilder(_)`. -/// -/// It is recommended to use `glint.global_flag` instead. -/// -pub fn global_flags(glint: Glint(a), flags: List(#(String, Flag))) -> Glint(a) { - Glint( - ..glint, - global_flags: { - list.fold( - flags, - glint.global_flags, - fn(acc, tup) { map.insert(acc, tup.0, tup.1) }, - ) - }, - ) -} - -// -- CORE: EXECUTION FUNCTIONS -- - -/// Determines which command to run and executes it. -/// -/// Sets any provided flags if necessary. -/// -/// Each value prefixed with `--` is parsed as a flag. -/// -/// This function does not print its output and is mainly intended for use within `glint` itself. -/// If you would like to print or handle the output of a command please see the `run_and_handle` function. -/// -pub fn execute(glint: Glint(a), args: List(String)) -> CmdResult(a) { - // create help flag to check for - let help_flag = help_flag() - - // check if help flag is present - let #(help, args) = case list.pop(args, fn(s) { s == help_flag }) { - Ok(#(_, args)) -> #(True, args) - _ -> #(False, args) - } - - // split flags out from the args list - let #(flags, args) = list.partition(args, string.starts_with(_, flag.prefix)) - - // search for command and execute - do_execute(glint.cmd, glint.config, glint.global_flags, args, flags, help, []) -} - -/// Find which command to execute and run it with computed flags and args -/// -fn do_execute( - cmd: CommandNode(a), - config: Config, - global_flags: FlagMap, - args: List(String), - flags: List(String), - help: Bool, - command_path: List(String), -) -> CmdResult(a) { - case args { - // when there are no more available arguments - // and help flag has been passed, generate help message - [] if help -> - command_path - |> cmd_help(cmd, config, global_flags) - |> Help - |> Ok - - // when there are no more available arguments - // run the current command - [] -> execute_root(cmd, global_flags, [], flags) - - // when there are arguments remaining - // check if the next one is a subcommand of the current command - [arg, ..rest] -> - case map.get(cmd.subcommands, arg) { - // subcommand found, continue - Ok(cmd) -> - do_execute( - cmd, - config, - global_flags, - rest, - flags, - help, - [arg, ..command_path], - ) - // subcommand not found, but help flag has been passed - // generate and return help message - _ if help -> - command_path - |> cmd_help(cmd, config, global_flags) - |> Help - |> Ok - // subcommand not found, but help flag has not been passed - // execute the current command - _ -> execute_root(cmd, global_flags, args, flags) - } - } -} - -/// Executes the current root command. -/// -fn execute_root( - cmd: CommandNode(a), - global_flags: FlagMap, - args: List(String), - flag_inputs: List(String), -) -> CmdResult(a) { - case cmd.contents { - Some(contents) -> { - use new_flags <- result.try(list.try_fold( - over: flag_inputs, - from: map.merge(global_flags, contents.flags), - with: flag.update_flags, - )) - CommandInput(args, new_flags) - |> contents.do - |> Out - |> Ok - } - None -> snag.error("command not found") - } - |> snag.context("failed to run command") -} - -/// A wrapper for `execute` that prints any errors enountered or the help text if requested. -/// This function ignores any value returned by the command that was run. -/// If you would like to do something with the command output please see the run_and_handle function. -/// -pub fn run(from glint: Glint(a), for args: List(String)) -> Nil { - run_and_handle(from: glint, for: args, with: function.constant(Nil)) -} - -/// A wrapper for `execute` that prints any errors enountered or the help text if requested. -/// This function calls the provided handler with the value returned by the command that was run. -/// -pub fn run_and_handle( - from glint: Glint(a), - for args: List(String), - with handle: fn(a) -> _, -) -> Nil { - case execute(glint, args) { - Error(err) -> - err - |> snag.pretty_print - |> io.println - Ok(Help(help)) -> io.println(help) - Ok(Out(out)) -> { - handle(out) - Nil - } - } -} - -/// Default pretty help heading colouring -/// mint (r: 182, g: 255, b: 234) colour for usage -/// pink (r: 255, g: 175, b: 243) colour for flags -/// buttercup (r: 252, g: 226, b: 174) colour for subcommands -/// -pub fn default_pretty_help() -> PrettyHelp { - let assert Ok(usage_colour) = colour.from_rgb255(182, 255, 234) - let assert Ok(flags_colour) = colour.from_rgb255(255, 175, 243) - let assert Ok(subcommands_colour) = colour.from_rgb255(252, 226, 174) - - PrettyHelp( - usage: usage_colour, - flags: flags_colour, - subcommands: subcommands_colour, - ) -} - -// constants for setting up sections of the help message -const flags_heading = "FLAGS:" - -const subcommands_heading = "SUBCOMMANDS:" - -const usage_heading = "USAGE:" - -/// Helper for filtering out empty strings -/// -fn is_not_empty(s: String) -> Bool { - s != "" -} - -const help_flag_name = "help" - -const help_flag_message = "--help\t\t\tPrint help information" - -/// Function to create the help flag string -/// Exported for testing purposes only -/// -pub fn help_flag() -> String { - flag.prefix <> help_flag_name -} - -// -- HELP: FUNCTIONS -- - -fn wrap_with_space(s: String) -> String { - case s { - "" -> " " - _ -> " " <> s <> " " - } -} - -/// generate the usage help string for a command -fn usage_help(cmd_name: String, flags: FlagMap, config: Config) -> String { - let app_name = option.unwrap(config.name, "gleam run") - let flags = - flags - |> map.to_list - |> list.map(flag.flag_type_help) - |> list.sort(string.compare) - - let flag_sb = case flags { - [] -> sb.new() - _ -> - flags - |> list.intersperse(" ") - |> sb.from_strings() - |> sb.prepend(prefix: " [ ") - |> sb.append(suffix: " ]") - } - - [app_name, wrap_with_space(cmd_name), "[ ARGS ]"] - |> sb.from_strings - |> sb.append_builder(flag_sb) - |> sb.prepend( - config.pretty_help - |> option.map(fn(styling) { heading_style(usage_heading, styling.usage) }) - |> option.unwrap(usage_heading) <> "\n\t", - ) - |> sb.to_string -} - -/// generate the help text for a command -fn cmd_help( - path: List(String), - cmd: CommandNode(a), - config: Config, - global_flags: FlagMap, -) -> String { - // recreate the path of the current command - // reverse the path because it is created by prepending each section as do_execute walks down the tree - let name = - path - |> list.reverse - |> string.join(" ") - - let flags = - option.map(cmd.contents, fn(contents) { contents.flags }) - |> option.lazy_unwrap(map.new) - |> map.merge(global_flags, _) - - let flags_help_body = - config.pretty_help - |> option.map(fn(p) { heading_style(flags_heading, p.flags) }) - |> option.unwrap(flags_heading) <> "\n\t" <> string.join( - list.sort([help_flag_message, ..flag.flags_help(flags)], string.compare), - "\n\t", - ) - - let usage = usage_help(name, flags, config) - - let description = - cmd.contents - |> option.map(fn(contents) { contents.description }) - |> option.unwrap("") - - // create the header block from the name and description - let header_items = - [name, description] - |> list.filter(is_not_empty) - |> string.join("\n") - - // create the subcommands help block - let subcommands = case subcommands_help(cmd.subcommands) { - "" -> "" - subcommands_help_body -> - config.pretty_help - |> option.map(fn(p) { heading_style(subcommands_heading, p.subcommands) }) - |> option.unwrap(subcommands_heading) <> "\n\t" <> subcommands_help_body - } - - // join the resulting help blocks into the final help message - [header_items, usage, flags_help_body, subcommands] - |> list.filter(is_not_empty) - |> string.join("\n\n") -} - -// create the help text for subcommands -fn subcommands_help(cmds: Map(String, CommandNode(a))) -> String { - cmds - |> map.map_values(subcommand_help) - |> map.values - |> list.sort(string.compare) - |> string.join("\n\t") -} - -// generate the help text for a subcommand -fn subcommand_help(name: String, cmd: CommandNode(_)) -> String { - case cmd.contents { - None -> name - Some(contents) -> name <> "\t\t" <> contents.description - } -} - -/// Style heading text with the provided rgb colouring -/// this is only intended for use within glint itself. -/// -fn heading_style(heading: String, colour: Colour) -> String { - heading - |> ansi.bold - |> ansi.underline - |> ansi.italic - |> ansi.hex(colour.to_rgb_hex(colour)) - |> ansi.reset -} - -// -- DEPRECATED: STUBS -- - -/// DEPRECATED: use `glint.cmd` and related new functions instead to create a Command -/// -/// Create command stubs to be used in `add_command_from_stub` -/// -pub type Stub(a) { - Stub( - path: List(String), - run: Runner(a), - flags: List(#(String, Flag)), - description: String, - ) -} - -/// Add a command to the root given a stub -/// -@deprecated("use `glint.cmd` and related new functions instead to create a Command") -pub fn add_command_from_stub(to glint: Glint(a), with stub: Stub(a)) -> Glint(a) { - add( - to: glint, - at: stub.path, - do: command(stub.run) - |> flags(stub.flags) - |> description(stub.description), - ) -} diff --git a/aoc2023/build/packages/glint/src/glint/flag.gleam b/aoc2023/build/packages/glint/src/glint/flag.gleam deleted file mode 100644 index 0a6cae1..0000000 --- a/aoc2023/build/packages/glint/src/glint/flag.gleam +++ /dev/null @@ -1,478 +0,0 @@ -import gleam/map -import gleam/string -import gleam/result -import gleam/int -import gleam/list -import gleam/float -import snag.{type Result, type Snag} -import gleam/option.{type Option, None, Some} -import glint/flag/constraint.{type Constraint} -import gleam - -/// Flag inputs must start with this prefix -/// -pub const prefix = "--" - -/// The separation character for flag names and their values -const delimiter = "=" - -/// Supported flag types. -/// -pub type Value { - /// Boolean flags, to be passed in as `--flag=true` or `--flag=false`. - /// Can be toggled by omitting the desired value like `--flag`. - /// Toggling will negate the existing value. - /// - B(Internal(Bool)) - - /// Int flags, to be passed in as `--flag=1` - /// - I(Internal(Int)) - - /// List(Int) flags, to be passed in as `--flag=1,2,3` - /// - LI(Internal(List(Int))) - - /// Float flags, to be passed in as `--flag=1.0` - /// - F(Internal(Float)) - - /// List(Float) flags, to be passed in as `--flag=1.0,2.0` - /// - LF(Internal(List(Float))) - - /// String flags, to be passed in as `--flag=hello` - /// - S(Internal(String)) - - /// List(String) flags, to be passed in as `--flag=hello,world` - /// - LS(Internal(List(String))) -} - -/// A type that facilitates the creation of `Flag`s -/// -pub opaque type FlagBuilder(a) { - FlagBuilder( - desc: Description, - parser: Parser(a, Snag), - value: fn(Internal(a)) -> Value, - default: Option(a), - ) -} - -/// An internal representation of flag contents -/// -pub opaque type Internal(a) { - Internal(value: Option(a), parser: Parser(a, Snag)) -} - -// Builder initializers - -type Parser(a, b) = - fn(String) -> gleam.Result(a, b) - -/// initialise an int flag builder -/// -pub fn int() -> FlagBuilder(Int) { - use input <- new(I) - input - |> int.parse - |> result.replace_error(cannot_parse(input, "int")) -} - -/// initialise an int list flag builder -/// -pub fn int_list() -> FlagBuilder(List(Int)) { - use input <- new(LI) - input - |> string.split(",") - |> list.try_map(int.parse) - |> result.replace_error(cannot_parse(input, "int list")) -} - -/// initialise a float flag builder -/// -pub fn float() -> FlagBuilder(Float) { - use input <- new(F) - input - |> float.parse - |> result.replace_error(cannot_parse(input, "float")) -} - -/// initialise a float list flag builder -/// -pub fn float_list() -> FlagBuilder(List(Float)) { - use input <- new(LF) - input - |> string.split(",") - |> list.try_map(float.parse) - |> result.replace_error(cannot_parse(input, "float list")) -} - -/// initialise a string flag builder -/// -pub fn string() -> FlagBuilder(String) { - new(S, fn(s) { Ok(s) }) -} - -/// intitialise a string list flag builder -/// -pub fn string_list() -> FlagBuilder(List(String)) { - use input <- new(LS) - input - |> string.split(",") - |> Ok -} - -/// initialise a bool flag builder -/// -pub fn bool() -> FlagBuilder(Bool) { - use input <- new(B) - case string.lowercase(input) { - "true" | "t" -> Ok(True) - "false" | "f" -> Ok(False) - _ -> Error(cannot_parse(input, "bool")) - } -} - -/// initialize custom builders using a Value constructor and a parsing function -/// -fn new(valuer: fn(Internal(a)) -> Value, p: Parser(a, Snag)) -> FlagBuilder(a) { - FlagBuilder(desc: "", parser: p, value: valuer, default: None) -} - -/// convert a FlagBuilder(a) into its corresponding Flag representation -/// -pub fn build(fb: FlagBuilder(a)) -> Flag { - Flag( - value: fb.value(Internal(value: fb.default, parser: fb.parser)), - description: fb.desc, - ) -} - -/// attach a constraint to a `Flag` -/// -pub fn constraint( - builder: FlagBuilder(a), - constraint: Constraint(a), -) -> FlagBuilder(a) { - FlagBuilder( - ..builder, - parser: wrap_with_constraint(builder.parser, constraint), - ) -} - -/// attach a Constraint(a) to a Parser(a,Snag) -/// this function should not be used directly unless -fn wrap_with_constraint( - p: Parser(a, Snag), - constraint: Constraint(a), -) -> Parser(a, Snag) { - fn(input: String) -> Result(a) { attempt(p(input), constraint) } -} - -fn attempt( - val: gleam.Result(a, e), - f: fn(a) -> gleam.Result(_, e), -) -> gleam.Result(a, e) { - use a <- result.try(val) - result.replace(f(a), a) -} - -/// Flag descriptions -/// -pub type Description = - String - -/// Flag data and descriptions -/// -pub type Flag { - Flag(value: Value, description: Description) -} - -/// attach a description to a `Flag` -/// -pub fn description( - for builder: FlagBuilder(a), - of description: Description, -) -> FlagBuilder(a) { - FlagBuilder(..builder, desc: description) -} - -/// Set the default value for a flag `Value` -/// -pub fn default(for builder: FlagBuilder(a), of default: a) -> FlagBuilder(a) { - FlagBuilder(..builder, default: Some(default)) -} - -/// Associate flag names to their current values. -/// -pub type Map = - map.Map(String, Flag) - -/// Convert a list of flags to a Map. -/// -pub fn build_map(flags: List(#(String, Flag))) -> Map { - map.from_list(flags) -} - -/// Updates a flag value, ensuring that the new value can satisfy the required type. -/// Assumes that all flag inputs passed in start with -- -/// This function is only intended to be used from glint.execute_root -/// -pub fn update_flags(in flags: Map, with flag_input: String) -> Result(Map) { - let flag_input = string.drop_left(flag_input, string.length(prefix)) - - case string.split_once(flag_input, delimiter) { - Ok(data) -> update_flag_value(flags, data) - Error(_) -> attempt_toggle_flag(flags, flag_input) - } -} - -fn update_flag_value(in flags: Map, with data: #(String, String)) -> Result(Map) { - let #(key, input) = data - use contents <- result.try(access(flags, key)) - use value <- result.map( - compute_flag(with: input, given: contents.value) - |> result.map_error(layer_invalid_flag(_, key)), - ) - map.insert(flags, key, Flag(..contents, value: value)) -} - -fn attempt_toggle_flag(in flags: Map, at key: String) -> Result(Map) { - use contents <- result.try(access(flags, key)) - case contents.value { - B(Internal(None, ..) as internal) -> - Internal(..internal, value: Some(True)) - |> B - |> fn(val) { Flag(..contents, value: val) } - |> map.insert(into: flags, for: key) - |> Ok() - B(Internal(Some(val), ..) as internal) -> - Internal(..internal, value: Some(!val)) - |> B - |> fn(val) { Flag(..contents, value: val) } - |> map.insert(into: flags, for: key) - |> Ok() - _ -> Error(no_value_flag_err(key)) - } -} - -fn access_type_error(flag_type) { - snag.error("cannot access flag as " <> flag_type) -} - -fn flag_not_provided_error() { - snag.error("no value provided") -} - -fn construct_value( - input: String, - internal: Internal(a), - constructor: fn(Internal(a)) -> Value, -) -> Result(Value) { - use val <- result.map(internal.parser(input)) - constructor(Internal(..internal, value: Some(val))) -} - -/// Computes the new flag value given the input and the expected flag type -/// -fn compute_flag(with input: String, given current: Value) -> Result(Value) { - input - |> case current { - I(internal) -> construct_value(_, internal, I) - LI(internal) -> construct_value(_, internal, LI) - F(internal) -> construct_value(_, internal, F) - LF(internal) -> construct_value(_, internal, LF) - S(internal) -> construct_value(_, internal, S) - LS(internal) -> construct_value(_, internal, LS) - B(internal) -> construct_value(_, internal, B) - } - |> snag.context("failed to compute value for flag") -} - -// Error creation and manipulation functions -fn layer_invalid_flag(err: Snag, flag: String) -> Snag { - snag.layer(err, "invalid flag '" <> flag <> "'") -} - -fn no_value_flag_err(flag_input: String) -> Snag { - { "flag '" <> flag_input <> "' has no assigned value" } - |> snag.new() - |> layer_invalid_flag(flag_input) -} - -fn undefined_flag_err(key: String) -> Snag { - "flag provided but not defined" - |> snag.new() - |> layer_invalid_flag(key) -} - -fn cannot_parse(with value: String, is kind: String) -> Snag { - { "cannot parse value '" <> value <> "' as " <> kind } - |> snag.new() -} - -// Help Message Functions -/// Generate the help message contents for a single flag -/// -pub fn flag_type_help(flag: #(String, Flag)) { - let #(name, contents) = flag - let kind = case contents.value { - I(_) -> "INT" - B(_) -> "BOOL" - F(_) -> "FLOAT" - LF(_) -> "FLOAT_LIST" - LI(_) -> "INT_LIST" - LS(_) -> "STRING_LIST" - S(_) -> "STRING" - } - - prefix <> name <> delimiter <> "<" <> kind <> ">" -} - -/// Generate help message line for a single flag -/// -fn flag_help(flag: #(String, Flag)) -> String { - flag_type_help(flag) <> "\t\t" <> { flag.1 }.description -} - -/// Generate help messages for all flags -/// -pub fn flags_help(flags: Map) -> List(String) { - flags - |> map.to_list - |> list.map(flag_help) -} - -// -- FLAG ACCESS FUNCTIONS -- - -/// Access the contents for the associated flag -/// -fn access(flags: Map, name: String) -> Result(Flag) { - map.get(flags, name) - |> result.replace_error(undefined_flag_err(name)) -} - -fn get_value( - from flags: Map, - at key: String, - expecting kind: fn(Flag) -> Result(a), -) -> Result(a) { - access(flags, key) - |> result.try(kind) - |> snag.context("failed to retrieve value for flag '" <> key <> "'") -} - -/// Gets the current value for the provided int flag -/// -pub fn get_int_value(from flag: Flag) -> Result(Int) { - case flag.value { - I(Internal(value: Some(val), ..)) -> Ok(val) - I(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("int") - } -} - -/// Gets the current value for the associated int flag -/// -pub fn get_int(from flags: Map, for name: String) -> Result(Int) { - get_value(flags, name, get_int_value) -} - -/// Gets the current value for the provided ints flag -/// -pub fn get_ints_value(from flag: Flag) -> Result(List(Int)) { - case flag.value { - LI(Internal(value: Some(val), ..)) -> Ok(val) - LI(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("int list") - } -} - -/// Gets the current value for the associated ints flag -/// -pub fn get_ints(from flags: Map, for name: String) -> Result(List(Int)) { - get_value(flags, name, get_ints_value) -} - -/// Gets the current value for the provided bool flag -/// -pub fn get_bool_value(from flag: Flag) -> Result(Bool) { - case flag.value { - B(Internal(Some(val), ..)) -> Ok(val) - B(Internal(None, ..)) -> flag_not_provided_error() - _ -> access_type_error("bool") - } -} - -/// Gets the current value for the associated bool flag -/// -pub fn get_bool(from flags: Map, for name: String) -> Result(Bool) { - get_value(flags, name, get_bool_value) -} - -/// Gets the current value for the provided string flag -/// -pub fn get_string_value(from flag: Flag) -> Result(String) { - case flag.value { - S(Internal(value: Some(val), ..)) -> Ok(val) - S(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("string") - } -} - -/// Gets the current value for the associated string flag -/// -pub fn get_string(from flags: Map, for name: String) -> Result(String) { - get_value(flags, name, get_string_value) -} - -/// Gets the current value for the provided strings flag -/// -pub fn get_strings_value(from flag: Flag) -> Result(List(String)) { - case flag.value { - LS(Internal(value: Some(val), ..)) -> Ok(val) - LS(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("string list") - } -} - -/// Gets the current value for the associated strings flag -/// -pub fn get_strings(from flags: Map, for name: String) -> Result(List(String)) { - get_value(flags, name, get_strings_value) -} - -/// Gets the current value for the provided float flag -/// -pub fn get_float_value(from flag: Flag) -> Result(Float) { - case flag.value { - F(Internal(value: Some(val), ..)) -> Ok(val) - F(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("float") - } -} - -/// Gets the current value for the associated float flag -/// -pub fn get_float(from flags: Map, for name: String) -> Result(Float) { - get_value(flags, name, get_float_value) -} - -/// Gets the current value for the provided floats flag -/// -pub fn get_floats_value(from flag: Flag) -> Result(List(Float)) { - case flag.value { - LF(Internal(value: Some(val), ..)) -> Ok(val) - LF(Internal(value: None, ..)) -> flag_not_provided_error() - _ -> access_type_error("float list") - } -} - -/// Gets the current value for the associated floats flag -/// -pub fn get_floats(from flags: Map, for name: String) -> Result(List(Float)) { - get_value(flags, name, get_floats_value) -} diff --git a/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam b/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam deleted file mode 100644 index e474bc2..0000000 --- a/aoc2023/build/packages/glint/src/glint/flag/constraint.gleam +++ /dev/null @@ -1,66 +0,0 @@ -import gleam/list -import gleam/result -import gleam/string -import gleam/set -import snag.{type Result} - -/// Constraint type for verifying flag values -/// -pub type Constraint(a) = - fn(a) -> Result(Nil) - -/// one_of returns a Constraint that ensures the parsed flag value is -/// one of the allowed values. -/// -pub fn one_of(allowed: List(a)) -> Constraint(a) { - let allowed_set = set.from_list(allowed) - fn(val: a) -> Result(Nil) { - case set.contains(allowed_set, val) { - True -> Ok(Nil) - False -> - snag.error( - "invalid value '" <> string.inspect(val) <> "', must be one of: [" <> { - allowed - |> list.map(fn(a) { "'" <> string.inspect(a) <> "'" }) - |> string.join(", ") <> "]" - }, - ) - } - } -} - -/// none_of returns a Constraint that ensures the parsed flag value is not one of the disallowed values. -/// -pub fn none_of(disallowed: List(a)) -> Constraint(a) { - let disallowed_set = set.from_list(disallowed) - fn(val: a) -> Result(Nil) { - case set.contains(disallowed_set, val) { - False -> Ok(Nil) - True -> - snag.error( - "invalid value '" <> string.inspect(val) <> "', must not be one of: [" <> { - { - disallowed - |> list.map(fn(a) { "'" <> string.inspect(a) <> "'" }) - |> string.join(", ") <> "]" - } - }, - ) - } - } -} - -/// each is a convenience function for applying a Constraint(a) to a List(a). -/// This is useful because the default behaviour for constraints on lists is that they will apply to the list as a whole. -/// -/// For example, to apply one_of to all items in a `List(Int)`: -/// ```gleam -/// [1, 2, 3, 4] |> one_of |> each -/// ``` -pub fn each(constraint: Constraint(a)) -> Constraint(List(a)) { - fn(l: List(a)) -> Result(Nil) { - l - |> list.try_map(constraint) - |> result.replace(Nil) - } -} diff --git a/aoc2023/build/packages/glint/src/glint@flag.erl b/aoc2023/build/packages/glint/src/glint@flag.erl deleted file mode 100644 index bcce6db..0000000 --- a/aoc2023/build/packages/glint/src/glint@flag.erl +++ /dev/null @@ -1,523 +0,0 @@ --module(glint@flag). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([string/0, string_list/0, build/1, constraint/2, description/2, default/2, build_map/1, int/0, int_list/0, float/0, float_list/0, bool/0, flag_type_help/1, flags_help/1, update_flags/2, get_int_value/1, get_int/2, get_ints_value/1, get_ints/2, get_bool_value/1, get_bool/2, get_string_value/1, get_string/2, get_strings_value/1, get_strings/2, get_float_value/1, get_float/2, get_floats_value/1, get_floats/2]). --export_type([value/0, flag_builder/1, internal/1, flag/0]). - --type value() :: {b, internal(boolean())} | - {i, internal(integer())} | - {li, internal(list(integer()))} | - {f, internal(float())} | - {lf, internal(list(float()))} | - {s, internal(binary())} | - {ls, internal(list(binary()))}. - --opaque flag_builder(FTZ) :: {flag_builder, - binary(), - fun((binary()) -> {ok, FTZ} | {error, snag:snag()}), - fun((internal(FTZ)) -> value()), - gleam@option:option(FTZ)}. - --opaque internal(FUA) :: {internal, - gleam@option:option(FUA), - fun((binary()) -> {ok, FUA} | {error, snag:snag()})}. - --type flag() :: {flag, value(), binary()}. - --spec new( - fun((internal(FUR)) -> value()), - fun((binary()) -> {ok, FUR} | {error, snag:snag()}) -) -> flag_builder(FUR). -new(Valuer, P) -> - {flag_builder, <<""/utf8>>, P, Valuer, none}. - --spec string() -> flag_builder(binary()). -string() -> - new(fun(Field@0) -> {s, Field@0} end, fun(S) -> {ok, S} end). - --spec string_list() -> flag_builder(list(binary())). -string_list() -> - new(fun(Field@0) -> {ls, Field@0} end, fun(Input) -> _pipe = Input, - _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>), - {ok, _pipe@1} end). - --spec build(flag_builder(any())) -> flag(). -build(Fb) -> - {flag, - (erlang:element(4, Fb))( - {internal, erlang:element(5, Fb), erlang:element(3, Fb)} - ), - erlang:element(2, Fb)}. - --spec attempt( - {ok, FVI} | {error, FVJ}, - fun((FVI) -> {ok, any()} | {error, FVJ}) -) -> {ok, FVI} | {error, FVJ}. -attempt(Val, F) -> - gleam@result:'try'(Val, fun(A) -> gleam@result:replace(F(A), A) end). - --spec wrap_with_constraint( - fun((binary()) -> {ok, FVC} | {error, snag:snag()}), - fun((FVC) -> {ok, nil} | {error, snag:snag()}) -) -> fun((binary()) -> {ok, FVC} | {error, snag:snag()}). -wrap_with_constraint(P, Constraint) -> - fun(Input) -> attempt(P(Input), Constraint) end. - --spec constraint( - flag_builder(FUY), - fun((FUY) -> {ok, nil} | {error, snag:snag()}) -) -> flag_builder(FUY). -constraint(Builder, Constraint) -> - erlang:setelement( - 3, - Builder, - wrap_with_constraint(erlang:element(3, Builder), Constraint) - ). - --spec description(flag_builder(FVR), binary()) -> flag_builder(FVR). -description(Builder, Description) -> - erlang:setelement(2, Builder, Description). - --spec default(flag_builder(FVU), FVU) -> flag_builder(FVU). -default(Builder, Default) -> - erlang:setelement(5, Builder, {some, Default}). - --spec build_map(list({binary(), flag()})) -> gleam@map:map_(binary(), flag()). -build_map(Flags) -> - gleam@map:from_list(Flags). - --spec access_type_error(binary()) -> {ok, any()} | {error, snag:snag()}. -access_type_error(Flag_type) -> - snag:error(<<"cannot access flag as "/utf8, Flag_type/binary>>). - --spec flag_not_provided_error() -> {ok, any()} | {error, snag:snag()}. -flag_not_provided_error() -> - snag:error(<<"no value provided"/utf8>>). - --spec construct_value(binary(), internal(FWE), fun((internal(FWE)) -> value())) -> {ok, - value()} | - {error, snag:snag()}. -construct_value(Input, Internal, Constructor) -> - gleam@result:map( - (erlang:element(3, Internal))(Input), - fun(Val) -> Constructor(erlang:setelement(2, Internal, {some, Val})) end - ). - --spec compute_flag(binary(), value()) -> {ok, value()} | {error, snag:snag()}. -compute_flag(Input, Current) -> - _pipe = Input, - _pipe@1 = case Current of - {i, Internal} -> - fun(_capture) -> - construct_value( - _capture, - Internal, - fun(Field@0) -> {i, Field@0} end - ) - end; - - {li, Internal@1} -> - fun(_capture@1) -> - construct_value( - _capture@1, - Internal@1, - fun(Field@0) -> {li, Field@0} end - ) - end; - - {f, Internal@2} -> - fun(_capture@2) -> - construct_value( - _capture@2, - Internal@2, - fun(Field@0) -> {f, Field@0} end - ) - end; - - {lf, Internal@3} -> - fun(_capture@3) -> - construct_value( - _capture@3, - Internal@3, - fun(Field@0) -> {lf, Field@0} end - ) - end; - - {s, Internal@4} -> - fun(_capture@4) -> - construct_value( - _capture@4, - Internal@4, - fun(Field@0) -> {s, Field@0} end - ) - end; - - {ls, Internal@5} -> - fun(_capture@5) -> - construct_value( - _capture@5, - Internal@5, - fun(Field@0) -> {ls, Field@0} end - ) - end; - - {b, Internal@6} -> - fun(_capture@6) -> - construct_value( - _capture@6, - Internal@6, - fun(Field@0) -> {b, Field@0} end - ) - end - end(_pipe), - snag:context(_pipe@1, <<"failed to compute value for flag"/utf8>>). - --spec layer_invalid_flag(snag:snag(), binary()) -> snag:snag(). -layer_invalid_flag(Err, Flag) -> - snag:layer(Err, <<<<"invalid flag '"/utf8, Flag/binary>>/binary, "'"/utf8>>). - --spec no_value_flag_err(binary()) -> snag:snag(). -no_value_flag_err(Flag_input) -> - _pipe = (<<<<"flag '"/utf8, Flag_input/binary>>/binary, - "' has no assigned value"/utf8>>), - _pipe@1 = snag:new(_pipe), - layer_invalid_flag(_pipe@1, Flag_input). - --spec undefined_flag_err(binary()) -> snag:snag(). -undefined_flag_err(Key) -> - _pipe = <<"flag provided but not defined"/utf8>>, - _pipe@1 = snag:new(_pipe), - layer_invalid_flag(_pipe@1, Key). - --spec cannot_parse(binary(), binary()) -> snag:snag(). -cannot_parse(Value, Kind) -> - _pipe = (<<<<<<"cannot parse value '"/utf8, Value/binary>>/binary, - "' as "/utf8>>/binary, - Kind/binary>>), - snag:new(_pipe). - --spec int() -> flag_builder(integer()). -int() -> - new(fun(Field@0) -> {i, Field@0} end, fun(Input) -> _pipe = Input, - _pipe@1 = gleam@int:parse(_pipe), - gleam@result:replace_error( - _pipe@1, - cannot_parse(Input, <<"int"/utf8>>) - ) end). - --spec int_list() -> flag_builder(list(integer())). -int_list() -> - new(fun(Field@0) -> {li, Field@0} end, fun(Input) -> _pipe = Input, - _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>), - _pipe@2 = gleam@list:try_map(_pipe@1, fun gleam@int:parse/1), - gleam@result:replace_error( - _pipe@2, - cannot_parse(Input, <<"int list"/utf8>>) - ) end). - --spec float() -> flag_builder(float()). -float() -> - new(fun(Field@0) -> {f, Field@0} end, fun(Input) -> _pipe = Input, - _pipe@1 = gleam@float:parse(_pipe), - gleam@result:replace_error( - _pipe@1, - cannot_parse(Input, <<"float"/utf8>>) - ) end). - --spec float_list() -> flag_builder(list(float())). -float_list() -> - new(fun(Field@0) -> {lf, Field@0} end, fun(Input) -> _pipe = Input, - _pipe@1 = gleam@string:split(_pipe, <<","/utf8>>), - _pipe@2 = gleam@list:try_map(_pipe@1, fun gleam@float:parse/1), - gleam@result:replace_error( - _pipe@2, - cannot_parse(Input, <<"float list"/utf8>>) - ) end). - --spec bool() -> flag_builder(boolean()). -bool() -> - new( - fun(Field@0) -> {b, Field@0} end, - fun(Input) -> case gleam@string:lowercase(Input) of - <<"true"/utf8>> -> - {ok, true}; - - <<"t"/utf8>> -> - {ok, true}; - - <<"false"/utf8>> -> - {ok, false}; - - <<"f"/utf8>> -> - {ok, false}; - - _ -> - {error, cannot_parse(Input, <<"bool"/utf8>>)} - end end - ). - --spec flag_type_help({binary(), flag()}) -> binary(). -flag_type_help(Flag) -> - {Name, Contents} = Flag, - Kind = case erlang:element(2, Contents) of - {i, _} -> - <<"INT"/utf8>>; - - {b, _} -> - <<"BOOL"/utf8>>; - - {f, _} -> - <<"FLOAT"/utf8>>; - - {lf, _} -> - <<"FLOAT_LIST"/utf8>>; - - {li, _} -> - <<"INT_LIST"/utf8>>; - - {ls, _} -> - <<"STRING_LIST"/utf8>>; - - {s, _} -> - <<"STRING"/utf8>> - end, - <<<<<<<<<<"--"/utf8, Name/binary>>/binary, "="/utf8>>/binary, "<"/utf8>>/binary, - Kind/binary>>/binary, - ">"/utf8>>. - --spec flag_help({binary(), flag()}) -> binary(). -flag_help(Flag) -> - <<<<(flag_type_help(Flag))/binary, "\t\t"/utf8>>/binary, - (erlang:element(3, (erlang:element(2, Flag))))/binary>>. - --spec flags_help(gleam@map:map_(binary(), flag())) -> list(binary()). -flags_help(Flags) -> - _pipe = Flags, - _pipe@1 = gleam@map:to_list(_pipe), - gleam@list:map(_pipe@1, fun flag_help/1). - --spec access(gleam@map:map_(binary(), flag()), binary()) -> {ok, flag()} | - {error, snag:snag()}. -access(Flags, Name) -> - _pipe = gleam@map:get(Flags, Name), - gleam@result:replace_error(_pipe, undefined_flag_err(Name)). - --spec update_flag_value(gleam@map:map_(binary(), flag()), {binary(), binary()}) -> {ok, - gleam@map:map_(binary(), flag())} | - {error, snag:snag()}. -update_flag_value(Flags, Data) -> - {Key, Input} = Data, - gleam@result:'try'( - access(Flags, Key), - fun(Contents) -> - gleam@result:map( - begin - _pipe = compute_flag(Input, erlang:element(2, Contents)), - gleam@result:map_error( - _pipe, - fun(_capture) -> layer_invalid_flag(_capture, Key) end - ) - end, - fun(Value) -> - gleam@map:insert( - Flags, - Key, - erlang:setelement(2, Contents, Value) - ) - end - ) - end - ). - --spec attempt_toggle_flag(gleam@map:map_(binary(), flag()), binary()) -> {ok, - gleam@map:map_(binary(), flag())} | - {error, snag:snag()}. -attempt_toggle_flag(Flags, Key) -> - gleam@result:'try'( - access(Flags, Key), - fun(Contents) -> case erlang:element(2, Contents) of - {b, {internal, none, _} = Internal} -> - _pipe = erlang:setelement(2, Internal, {some, true}), - _pipe@1 = {b, _pipe}, - _pipe@2 = (fun(Val) -> - erlang:setelement(2, Contents, Val) - end)(_pipe@1), - _pipe@3 = gleam@map:insert(Flags, Key, _pipe@2), - {ok, _pipe@3}; - - {b, {internal, {some, Val@1}, _} = Internal@1} -> - _pipe@4 = erlang:setelement( - 2, - Internal@1, - {some, not Val@1} - ), - _pipe@5 = {b, _pipe@4}, - _pipe@6 = (fun(Val@2) -> - erlang:setelement(2, Contents, Val@2) - end)(_pipe@5), - _pipe@7 = gleam@map:insert(Flags, Key, _pipe@6), - {ok, _pipe@7}; - - _ -> - {error, no_value_flag_err(Key)} - end end - ). - --spec update_flags(gleam@map:map_(binary(), flag()), binary()) -> {ok, - gleam@map:map_(binary(), flag())} | - {error, snag:snag()}. -update_flags(Flags, Flag_input) -> - Flag_input@1 = gleam@string:drop_left( - Flag_input, - gleam@string:length(<<"--"/utf8>>) - ), - case gleam@string:split_once(Flag_input@1, <<"="/utf8>>) of - {ok, Data} -> - update_flag_value(Flags, Data); - - {error, _} -> - attempt_toggle_flag(Flags, Flag_input@1) - end. - --spec get_value( - gleam@map:map_(binary(), flag()), - binary(), - fun((flag()) -> {ok, FWM} | {error, snag:snag()}) -) -> {ok, FWM} | {error, snag:snag()}. -get_value(Flags, Key, Kind) -> - _pipe = access(Flags, Key), - _pipe@1 = gleam@result:'try'(_pipe, Kind), - snag:context( - _pipe@1, - <<<<"failed to retrieve value for flag '"/utf8, Key/binary>>/binary, - "'"/utf8>> - ). - --spec get_int_value(flag()) -> {ok, integer()} | {error, snag:snag()}. -get_int_value(Flag) -> - case erlang:element(2, Flag) of - {i, {internal, {some, Val}, _}} -> - {ok, Val}; - - {i, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"int"/utf8>>) - end. - --spec get_int(gleam@map:map_(binary(), flag()), binary()) -> {ok, integer()} | - {error, snag:snag()}. -get_int(Flags, Name) -> - get_value(Flags, Name, fun get_int_value/1). - --spec get_ints_value(flag()) -> {ok, list(integer())} | {error, snag:snag()}. -get_ints_value(Flag) -> - case erlang:element(2, Flag) of - {li, {internal, {some, Val}, _}} -> - {ok, Val}; - - {li, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"int list"/utf8>>) - end. - --spec get_ints(gleam@map:map_(binary(), flag()), binary()) -> {ok, - list(integer())} | - {error, snag:snag()}. -get_ints(Flags, Name) -> - get_value(Flags, Name, fun get_ints_value/1). - --spec get_bool_value(flag()) -> {ok, boolean()} | {error, snag:snag()}. -get_bool_value(Flag) -> - case erlang:element(2, Flag) of - {b, {internal, {some, Val}, _}} -> - {ok, Val}; - - {b, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"bool"/utf8>>) - end. - --spec get_bool(gleam@map:map_(binary(), flag()), binary()) -> {ok, boolean()} | - {error, snag:snag()}. -get_bool(Flags, Name) -> - get_value(Flags, Name, fun get_bool_value/1). - --spec get_string_value(flag()) -> {ok, binary()} | {error, snag:snag()}. -get_string_value(Flag) -> - case erlang:element(2, Flag) of - {s, {internal, {some, Val}, _}} -> - {ok, Val}; - - {s, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"string"/utf8>>) - end. - --spec get_string(gleam@map:map_(binary(), flag()), binary()) -> {ok, binary()} | - {error, snag:snag()}. -get_string(Flags, Name) -> - get_value(Flags, Name, fun get_string_value/1). - --spec get_strings_value(flag()) -> {ok, list(binary())} | {error, snag:snag()}. -get_strings_value(Flag) -> - case erlang:element(2, Flag) of - {ls, {internal, {some, Val}, _}} -> - {ok, Val}; - - {ls, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"string list"/utf8>>) - end. - --spec get_strings(gleam@map:map_(binary(), flag()), binary()) -> {ok, - list(binary())} | - {error, snag:snag()}. -get_strings(Flags, Name) -> - get_value(Flags, Name, fun get_strings_value/1). - --spec get_float_value(flag()) -> {ok, float()} | {error, snag:snag()}. -get_float_value(Flag) -> - case erlang:element(2, Flag) of - {f, {internal, {some, Val}, _}} -> - {ok, Val}; - - {f, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"float"/utf8>>) - end. - --spec get_float(gleam@map:map_(binary(), flag()), binary()) -> {ok, float()} | - {error, snag:snag()}. -get_float(Flags, Name) -> - get_value(Flags, Name, fun get_float_value/1). - --spec get_floats_value(flag()) -> {ok, list(float())} | {error, snag:snag()}. -get_floats_value(Flag) -> - case erlang:element(2, Flag) of - {lf, {internal, {some, Val}, _}} -> - {ok, Val}; - - {lf, {internal, none, _}} -> - flag_not_provided_error(); - - _ -> - access_type_error(<<"float list"/utf8>>) - end. - --spec get_floats(gleam@map:map_(binary(), flag()), binary()) -> {ok, - list(float())} | - {error, snag:snag()}. -get_floats(Flags, Name) -> - get_value(Flags, Name, fun get_floats_value/1). diff --git a/aoc2023/build/packages/glint/src/glint@flag@constraint.erl b/aoc2023/build/packages/glint/src/glint@flag@constraint.erl deleted file mode 100644 index 2978be0..0000000 --- a/aoc2023/build/packages/glint/src/glint@flag@constraint.erl +++ /dev/null @@ -1,68 +0,0 @@ --module(glint@flag@constraint). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([one_of/1, none_of/1, each/1]). - --spec one_of(list(FSI)) -> fun((FSI) -> {ok, nil} | {error, snag:snag()}). -one_of(Allowed) -> - Allowed_set = gleam@set:from_list(Allowed), - fun(Val) -> case gleam@set:contains(Allowed_set, Val) of - true -> - {ok, nil}; - - false -> - snag:error( - <<<<<<"invalid value '"/utf8, - (gleam@string:inspect(Val))/binary>>/binary, - "', must be one of: ["/utf8>>/binary, - ((<<(begin - _pipe = Allowed, - _pipe@1 = gleam@list:map( - _pipe, - fun(A) -> - <<<<"'"/utf8, - (gleam@string:inspect(A))/binary>>/binary, - "'"/utf8>> - end - ), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end)/binary, - "]"/utf8>>))/binary>> - ) - end end. - --spec none_of(list(FSL)) -> fun((FSL) -> {ok, nil} | {error, snag:snag()}). -none_of(Disallowed) -> - Disallowed_set = gleam@set:from_list(Disallowed), - fun(Val) -> case gleam@set:contains(Disallowed_set, Val) of - false -> - {ok, nil}; - - true -> - snag:error( - <<<<<<"invalid value '"/utf8, - (gleam@string:inspect(Val))/binary>>/binary, - "', must not be one of: ["/utf8>>/binary, - (((<<(begin - _pipe = Disallowed, - _pipe@1 = gleam@list:map( - _pipe, - fun(A) -> - <<<<"'"/utf8, - (gleam@string:inspect(A))/binary>>/binary, - "'"/utf8>> - end - ), - gleam@string:join(_pipe@1, <<", "/utf8>>) - end)/binary, - "]"/utf8>>)))/binary>> - ) - end end. - --spec each(fun((FSO) -> {ok, nil} | {error, snag:snag()})) -> fun((list(FSO)) -> {ok, - nil} | - {error, snag:snag()}). -each(Constraint) -> - fun(L) -> _pipe = L, - _pipe@1 = gleam@list:try_map(_pipe, Constraint), - gleam@result:replace(_pipe@1, nil) end. diff --git a/aoc2023/build/packages/packages.toml b/aoc2023/build/packages/packages.toml deleted file mode 100644 index d4c7b69..0000000 --- a/aoc2023/build/packages/packages.toml +++ /dev/null @@ -1,16 +0,0 @@ -[packages] -simplifile = "1.0.0" -gleam_community_ansi = "1.2.0" -glint = "0.13.0" -gleam_community_colour = "1.2.0" -gleam_erlang = "0.23.1" -tom = "0.2.1" -gleam_httpc = "2.1.1" -adglent = "1.2.0" -gap = "1.0.1" -gleam_community_maths = "1.0.1" -gleam_otp = "0.8.0" -gleam_stdlib = "0.33.0" -pqueue = "2.0.7" -snag = "0.2.1" -gleam_http = "3.5.2" diff --git a/aoc2023/build/packages/pqueue/LICENSE b/aoc2023/build/packages/pqueue/LICENSE deleted file mode 100644 index 5697803..0000000 --- a/aoc2023/build/packages/pqueue/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License
-
-Copyright (c) 2011-2023 Michael Truog <mjtruog at protonmail dot com>
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
diff --git a/aoc2023/build/packages/pqueue/README.markdown b/aoc2023/build/packages/pqueue/README.markdown deleted file mode 100644 index 77aaf1c..0000000 --- a/aoc2023/build/packages/pqueue/README.markdown +++ /dev/null @@ -1,31 +0,0 @@ -Erlang Priority Queue Implementation -==================================== - -The priority queue implementations implement a subset of the stdlib Erlang queue interface as seen in the implementation used by both [Riak and RabbitMQ](https://github.com/basho/riak_core/blob/master/src/riak_core_priority_queue.erl). - -The implementations: - -* `priority_queue` (fastest for any priorities when only using a single priority at a time) -* `pqueue` (fastest for 41 priorities, -20 (high) to 20 (low), when using 2 or more priorities at the same time) -* `pqueue2` (slower heap implementation) -* `pqueue3` (faster than `pqueue2` and `priority_queue` when using 64 or more priorities at the same time) -* `pqueue4` (slightly slower than `pqueue` but fastest for allowing 257 priorities, -128 (high) to 128 (low), i.e., fastest when using 42 or more priorities at the same time) - -[The latest results are here](http://okeuday.livejournal.com/19539.html), with [the benchmark here](http://github.com/okeuday/erlbench). - -Author ------- - -Michael Truog (mjtruog at protonmail dot com) - -Thanks ------- - -* Jesper Louis andersen (PropEr integration and testing) -* Ulf Wiger (suggestions and insight) - -License -------- - -MIT License - diff --git a/aoc2023/build/packages/pqueue/doc/edoc-info b/aoc2023/build/packages/pqueue/doc/edoc-info deleted file mode 100644 index 5e5a8d3..0000000 --- a/aoc2023/build/packages/pqueue/doc/edoc-info +++ /dev/null @@ -1,3 +0,0 @@ -%% encoding: UTF-8 -{application,pqueue}. -{modules,[pqueue,pqueue2,pqueue3,pqueue4]}. diff --git a/aoc2023/build/packages/pqueue/doc/erlang.png b/aoc2023/build/packages/pqueue/doc/erlang.png Binary files differdeleted file mode 100644 index 987a618..0000000 --- a/aoc2023/build/packages/pqueue/doc/erlang.png +++ /dev/null diff --git a/aoc2023/build/packages/pqueue/doc/index.html b/aoc2023/build/packages/pqueue/doc/index.html deleted file mode 100644 index d55b5e6..0000000 --- a/aoc2023/build/packages/pqueue/doc/index.html +++ /dev/null @@ -1,17 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>The pqueue application</title> -</head> -<frameset cols="20%,80%"> -<frame src="modules-frame.html" name="modulesFrame" title=""> - -<frame src="overview-summary.html" name="overviewFrame" title=""> -<noframes> -<h2>This page uses frames</h2> -<p>Your browser does not accept frames. -<br>You should go to the <a href="overview-summary.html">non-frame version</a> instead. -</p> -</noframes> -</frameset> -</html>
\ No newline at end of file diff --git a/aoc2023/build/packages/pqueue/doc/modules-frame.html b/aoc2023/build/packages/pqueue/doc/modules-frame.html deleted file mode 100644 index 5a87cc4..0000000 --- a/aoc2023/build/packages/pqueue/doc/modules-frame.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>The pqueue application</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<h2 class="indextitle">Modules</h2> -<table width="100%" border="0" summary="list of modules"> -<tr><td><a href="pqueue.html" target="overviewFrame" class="module">pqueue</a></td></tr> -<tr><td><a href="pqueue2.html" target="overviewFrame" class="module">pqueue2</a></td></tr> -<tr><td><a href="pqueue3.html" target="overviewFrame" class="module">pqueue3</a></td></tr> -<tr><td><a href="pqueue4.html" target="overviewFrame" class="module">pqueue4</a></td></tr></table> -</body> -</html>
\ No newline at end of file diff --git a/aoc2023/build/packages/pqueue/doc/overview-summary.html b/aoc2023/build/packages/pqueue/doc/overview-summary.html deleted file mode 100644 index e2f8906..0000000 --- a/aoc2023/build/packages/pqueue/doc/overview-summary.html +++ /dev/null @@ -1,16 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>The pqueue application</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<h1>The pqueue application</h1> - -<hr> -<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<p><i>Generated by EDoc</i></p> -</body> -</html> diff --git a/aoc2023/build/packages/pqueue/doc/pqueue.html b/aoc2023/build/packages/pqueue/doc/pqueue.html deleted file mode 100644 index 40b05ac..0000000 --- a/aoc2023/build/packages/pqueue/doc/pqueue.html +++ /dev/null @@ -1,166 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>Module pqueue</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<hr> - -<h1>Module pqueue</h1> -<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul> - <h3><a name="Static_Priority_Queue.">Static Priority Queue.</a></h3> - This priority queue implementation depends on a static number of priorities - (-20 (high) to 20 (low)) so that tuple access times can be exploited for - quick in/out priority queue operations. -<p>Copyright © 2011-2020 Michael Truog</p> - -<p><b>Version:</b> 2.0.1 Nov 26 2020 14:55:34 - ------------------------------------------------------------------------</p> -<p><b>Authors:</b> Michael Truog (<a href="mailto:mjtruog at protonmail dot com"><tt>mjtruog at protonmail dot com</tt></a>).</p> - -<h2><a name="description">Description</a></h2> - <h3><a name="Static_Priority_Queue.">Static Priority Queue.</a></h3> - This priority queue implementation depends on a static number of priorities - (-20 (high) to 20 (low)) so that tuple access times can be exploited for - quick in/out priority queue operations. This implementation was created to - avoid the slowness within the priority queue used by both RabbitMQ and Riak - (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -<h2><a name="types">Data Types</a></h2> - -<h3 class="typedecl"><a name="type-pqueue">pqueue()</a></h3> -<p><tt>pqueue() = {integer(), {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, <a href="queue.html#type-queue">queue:queue()</a>, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}} | {empty, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, <a href="queue.html#type-queue">queue:queue()</a>, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}, {<a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>, <a href="queue.html#type-queue">queue:queue()</a>}}</tt></p> - - -<h2><a name="index">Function Index</a></h2> -<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#in-2">in/2</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#in-3">in/3</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_empty-1">is_empty/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_queue-1">is_queue/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#join-2">join/2</a></td><td> - <h4><a name="Join_two_priority_queues.">Join two priority queues.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#len-1">len/1</a></td><td> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#new-0">new/0</a></td><td> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#out-1">out/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#out-2">out/2</a></td><td> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#pout-1">pout/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value.</td></tr> -<tr><td valign="top"><a href="#test-0">test/0</a></td><td> - <h4><a name="Regression_test.">Regression test.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#to_list-1">to_list/1</a></td><td> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N).</td></tr> -</table> - -<h2><a name="functions">Function Details</a></h2> - -<h3 class="function"><a name="in-2">in/2</a></h3> -<div class="spec"> -<p><tt>in(X::term(), Q::<a href="#type-pqueue">pqueue()</a>) -> <a href="#type-pqueue">pqueue()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="in-3">in/3</a></h3> -<div class="spec"> -<p><tt>in(X::term(), P::integer(), Q::<a href="#type-pqueue">pqueue()</a>) -> <a href="#type-pqueue">pqueue()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_empty-1">is_empty/1</a></h3> -<div class="spec"> -<p><tt>is_empty(X1::<a href="#type-pqueue">pqueue()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_queue-1">is_queue/1</a></h3> -<div class="spec"> -<p><tt>is_queue(X1::<a href="#type-pqueue">pqueue()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1)</p> - -<h3 class="function"><a name="join-2">join/2</a></h3> -<div class="spec"> -<p><tt>join(X1::<a href="#type-pqueue">pqueue()</a>, X2::<a href="#type-pqueue">pqueue()</a>) -> <a href="#type-pqueue">pqueue()</a></tt><br></p> -</div><p> - <h4><a name="Join_two_priority_queues.">Join two priority queues.</a></h4> - O(N)</p> - -<h3 class="function"><a name="len-1">len/1</a></h3> -<div class="spec"> -<p><tt>len(X1::<a href="#type-pqueue">pqueue()</a>) -> non_neg_integer()</tt><br></p> -</div><p> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(N)</p> - -<h3 class="function"><a name="new-0">new/0</a></h3> -<div class="spec"> -<p><tt>new() -> <a href="#type-pqueue">pqueue()</a></tt><br></p> -</div><p> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="out-1">out/1</a></h3> -<div class="spec"> -<p><tt>out(Q::<a href="#type-pqueue">pqueue()</a>) -> {{value, term()}, <a href="#type-pqueue">pqueue()</a>} | {empty, <a href="#type-pqueue">pqueue()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="out-2">out/2</a></h3> -<div class="spec"> -<p><tt>out(P::integer(), Q::<a href="#type-pqueue">pqueue()</a>) -> {{value, term()}, <a href="#type-pqueue">pqueue()</a>} | {empty, <a href="#type-pqueue">pqueue()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="pout-1">pout/1</a></h3> -<div class="spec"> -<p><tt>pout(Q::<a href="#type-pqueue">pqueue()</a>) -> {{value, term(), integer()}, <a href="#type-pqueue">pqueue()</a>} | {empty, <a href="#type-pqueue">pqueue()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value. - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="test-0">test/0</a></h3> -<div class="spec"> -<p><tt>test() -> any()</tt></p> -</div><p> - <h4><a name="Regression_test.">Regression test.</a></h4> -</p> - -<h3 class="function"><a name="to_list-1">to_list/1</a></h3> -<div class="spec"> -<p><tt>to_list(X1::<a href="#type-pqueue">pqueue()</a>) -> [term()]</tt><br></p> -</div><p> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N)</p> -<hr> - -<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<p><i>Generated by EDoc</i></p> -</body> -</html> diff --git a/aoc2023/build/packages/pqueue/doc/pqueue2.html b/aoc2023/build/packages/pqueue/doc/pqueue2.html deleted file mode 100644 index 2942b84..0000000 --- a/aoc2023/build/packages/pqueue/doc/pqueue2.html +++ /dev/null @@ -1,143 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>Module pqueue2</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<hr> - -<h1>Module pqueue2</h1> -<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul> - <h3><a name="Skew_Heap_Priority_Queue.">Skew Heap Priority Queue.</a></h3> - Ulf Wiger suggested pursuing a skew heap as an optimal Erlang priority - queue implementation. -<p>Copyright © 2011-2020 Michael Truog</p> - -<p><b>Version:</b> 2.0.1 Nov 26 2020 14:55:32 - ------------------------------------------------------------------------</p> -<p><b>Authors:</b> Michael Truog (<a href="mailto:mjtruog at protonmail dot com"><tt>mjtruog at protonmail dot com</tt></a>).</p> - -<h2><a name="description">Description</a></h2> - <h3><a name="Skew_Heap_Priority_Queue.">Skew Heap Priority Queue.</a></h3> - Ulf Wiger suggested pursuing a skew heap as an optimal Erlang priority - queue implementation. Unfortunately, testing has shown this solution to - be more than 2 times slower than pqueue. -<h2><a name="types">Data Types</a></h2> - -<h3 class="typedecl"><a name="type-pqueue2">pqueue2()</a></h3> -<p><tt>pqueue2() = empty | {integer(), <a href="#type-pqueue2">pqueue2()</a>, <a href="#type-pqueue2">pqueue2()</a>, element, term()} | {integer(), <a href="#type-pqueue2">pqueue2()</a>, <a href="#type-pqueue2">pqueue2()</a>, queue, <a href="queue.html#type-queue">queue:queue()</a>}</tt></p> - - -<h2><a name="index">Function Index</a></h2> -<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#in-2">in/2</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#in-3">in/3</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#is_empty-1">is_empty/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#is_queue-1">is_queue/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#len-1">len/1</a></td><td> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#new-0">new/0</a></td><td> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#out-1">out/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#out-2">out/2</a></td><td> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#pout-1">pout/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value.</td></tr> -<tr><td valign="top"><a href="#test-0">test/0</a></td><td> - <h4><a name="Regression_test.">Regression test.</a></h4>.</td></tr> -<tr><td valign="top"><a href="#to_list-1">to_list/1</a></td><td> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4>.</td></tr> -</table> - -<h2><a name="functions">Function Details</a></h2> - -<h3 class="function"><a name="in-2">in/2</a></h3> -<div class="spec"> -<p><tt>in(Value::term(), H::<a href="#type-pqueue2">pqueue2()</a>) -> <a href="#type-pqueue2">pqueue2()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> -</p> - -<h3 class="function"><a name="in-3">in/3</a></h3> -<div class="spec"> -<p><tt>in(Value::term(), P::integer(), H::<a href="#type-pqueue2">pqueue2()</a>) -> <a href="#type-pqueue2">pqueue2()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> -</p> - -<h3 class="function"><a name="is_empty-1">is_empty/1</a></h3> -<div class="spec"> -<p><tt>is_empty(X1::<a href="#type-pqueue2">pqueue2()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> -</p> - -<h3 class="function"><a name="is_queue-1">is_queue/1</a></h3> -<div class="spec"> -<p><tt>is_queue(X1::<a href="#type-pqueue2">pqueue2()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> -</p> - -<h3 class="function"><a name="len-1">len/1</a></h3> -<div class="spec"> -<p><tt>len(H::<a href="#type-pqueue2">pqueue2()</a>) -> non_neg_integer()</tt><br></p> -</div><p> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> -</p> - -<h3 class="function"><a name="new-0">new/0</a></h3> -<div class="spec"> -<p><tt>new() -> <a href="#type-pqueue2">pqueue2()</a></tt><br></p> -</div><p> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> -</p> - -<h3 class="function"><a name="out-1">out/1</a></h3> -<div class="spec"> -<p><tt>out(X1::<a href="#type-pqueue2">pqueue2()</a>) -> {{value, term()}, <a href="#type-pqueue2">pqueue2()</a>} | {empty, <a href="#type-pqueue2">pqueue2()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> -</p> - -<h3 class="function"><a name="out-2">out/2</a></h3> -<div class="spec"> -<p><tt>out(P::integer(), H::<a href="#type-pqueue2">pqueue2()</a>) -> {{value, term()}, <a href="#type-pqueue2">pqueue2()</a>} | {empty, <a href="#type-pqueue2">pqueue2()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> -</p> - -<h3 class="function"><a name="pout-1">pout/1</a></h3> -<div class="spec"> -<p><tt>pout(X1::<a href="#type-pqueue2">pqueue2()</a>) -> {{value, term(), integer()}, <a href="#type-pqueue2">pqueue2()</a>} | {empty, <a href="#type-pqueue2">pqueue2()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value.</p> - -<h3 class="function"><a name="test-0">test/0</a></h3> -<div class="spec"> -<p><tt>test() -> any()</tt></p> -</div><p> - <h4><a name="Regression_test.">Regression test.</a></h4> -</p> - -<h3 class="function"><a name="to_list-1">to_list/1</a></h3> -<div class="spec"> -<p><tt>to_list(H::<a href="#type-pqueue2">pqueue2()</a>) -> [term()]</tt><br></p> -</div><p> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> -</p> -<hr> - -<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<p><i>Generated by EDoc</i></p> -</body> -</html> diff --git a/aoc2023/build/packages/pqueue/doc/pqueue3.html b/aoc2023/build/packages/pqueue/doc/pqueue3.html deleted file mode 100644 index 35f1a7b..0000000 --- a/aoc2023/build/packages/pqueue/doc/pqueue3.html +++ /dev/null @@ -1,162 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>Module pqueue3</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<hr> - -<h1>Module pqueue3</h1> -<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul> - <h3><a name="A_Large_Priority_Queue.">A Large Priority Queue.</a></h3> - This priority queue implementation depends on layered tuples, so that tuple - access times can be exploited for quick in/out priority queue operations - when using 64 or more total priorities. -<p>Copyright © 2011-2020 Michael Truog</p> - -<p><b>Version:</b> 2.0.1 Nov 26 2020 14:55:32 - ------------------------------------------------------------------------</p> -<p><b>Authors:</b> Michael Truog (<a href="mailto:mjtruog at protonmail dot com"><tt>mjtruog at protonmail dot com</tt></a>).</p> - -<h2><a name="description">Description</a></h2> - <h3><a name="A_Large_Priority_Queue.">A Large Priority Queue.</a></h3> - This priority queue implementation depends on layered tuples, so that tuple - access times can be exploited for quick in/out priority queue operations - when using 64 or more total priorities. This implementation was created - to avoid the slowness within the priority queue used by - both RabbitMQ and Riak - (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -<h2><a name="types">Data Types</a></h2> - -<h3 class="typedecl"><a name="type-pqueue3">pqueue3()</a></h3> -<p><tt>pqueue3() = {integer(), integer(), empty | integer(), tuple()}</tt></p> - - -<h3 class="typedecl"><a name="type-pqueue3_empty">pqueue3_empty()</a></h3> -<p><tt>pqueue3_empty() = {integer(), integer(), empty, tuple()}</tt></p> - - -<h2><a name="index">Function Index</a></h2> -<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#in-2">in/2</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#in-3">in/3</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_empty-1">is_empty/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_queue-1">is_queue/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#len-1">len/1</a></td><td> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#new-0">new/0</a></td><td> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#new-1">new/1</a></td><td> - <h4><a name="Create_a_new_priority_queue_with_customization_options.">Create a new priority queue with customization options.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#out-1">out/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#out-2">out/2</a></td><td> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#pout-1">pout/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value.</td></tr> -<tr><td valign="top"><a href="#to_list-1">to_list/1</a></td><td> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N).</td></tr> -</table> - -<h2><a name="functions">Function Details</a></h2> - -<h3 class="function"><a name="in-2">in/2</a></h3> -<div class="spec"> -<p><tt>in(Value::term(), Q::<a href="#type-pqueue3">pqueue3()</a>) -> <a href="#type-pqueue3">pqueue3()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="in-3">in/3</a></h3> -<div class="spec"> -<p><tt>in(Value::term(), P::integer(), X3::<a href="#type-pqueue3">pqueue3()</a>) -> <a href="#type-pqueue3">pqueue3()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_empty-1">is_empty/1</a></h3> -<div class="spec"> -<p><tt>is_empty(Q::<a href="#type-pqueue3">pqueue3()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_queue-1">is_queue/1</a></h3> -<div class="spec"> -<p><tt>is_queue(X1::<a href="#type-pqueue3">pqueue3()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1)</p> - -<h3 class="function"><a name="len-1">len/1</a></h3> -<div class="spec"> -<p><tt>len(Q::<a href="#type-pqueue3">pqueue3()</a>) -> non_neg_integer()</tt><br></p> -</div><p> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(N)</p> - -<h3 class="function"><a name="new-0">new/0</a></h3> -<div class="spec"> -<p><tt>new() -> <a href="#type-pqueue3_empty">pqueue3_empty()</a></tt><br></p> -</div><p> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="new-1">new/1</a></h3> -<div class="spec"> -<p><tt>new(Options::[{atom(), term()}]) -> <a href="#type-pqueue3">pqueue3()</a></tt><br></p> -</div><p> - <h4><a name="Create_a_new_priority_queue_with_customization_options.">Create a new priority queue with customization options.</a></h4> - O(1)</p> - -<h3 class="function"><a name="out-1">out/1</a></h3> -<div class="spec"> -<p><tt>out(Q::<a href="#type-pqueue3">pqueue3()</a>) -> {{value, term()}, <a href="#type-pqueue3">pqueue3()</a>} | {empty, <a href="#type-pqueue3">pqueue3()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="out-2">out/2</a></h3> -<div class="spec"> -<p><tt>out(P::integer(), Q::<a href="#type-pqueue3">pqueue3()</a>) -> {{value, term()}, <a href="#type-pqueue3">pqueue3()</a>} | {empty, <a href="#type-pqueue3">pqueue3()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="pout-1">pout/1</a></h3> -<div class="spec"> -<p><tt>pout(Q::<a href="#type-pqueue3">pqueue3()</a>) -> {{value, term(), integer()}, <a href="#type-pqueue3">pqueue3()</a>} | {empty, <a href="#type-pqueue3">pqueue3()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value. - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="to_list-1">to_list/1</a></h3> -<div class="spec"> -<p><tt>to_list(Q::<a href="#type-pqueue3">pqueue3()</a>) -> [term()]</tt><br></p> -</div><p> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N)</p> -<hr> - -<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<p><i>Generated by EDoc</i></p> -</body> -</html> diff --git a/aoc2023/build/packages/pqueue/doc/pqueue4.html b/aoc2023/build/packages/pqueue/doc/pqueue4.html deleted file mode 100644 index edcdb6e..0000000 --- a/aoc2023/build/packages/pqueue/doc/pqueue4.html +++ /dev/null @@ -1,205 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<title>Module pqueue4</title> -<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc"> -</head> -<body bgcolor="white"> -<div class="navbar"><a name="#navbar_top"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<hr> - -<h1>Module pqueue4</h1> -<ul class="index"><li><a href="#description">Description</a></li><li><a href="#types">Data Types</a></li><li><a href="#index">Function Index</a></li><li><a href="#functions">Function Details</a></li></ul> - <h3><a name="Static_Priority_Queue.">Static Priority Queue.</a></h3> - This priority queue implementation depends on a static number of priorities - (-128 (high) to 128 (low)) so that tuple access times can be exploited for - quick in/out priority queue operations. -<p>Copyright © 2011-2020 Michael Truog</p> - -<p><b>Version:</b> 2.0.1 Nov 26 2020 14:55:34 - ------------------------------------------------------------------------</p> -<p><b>Authors:</b> Michael Truog (<a href="mailto:mjtruog at protonmail dot com"><tt>mjtruog at protonmail dot com</tt></a>).</p> - -<h2><a name="description">Description</a></h2> - <h3><a name="Static_Priority_Queue.">Static Priority Queue.</a></h3> - This priority queue implementation depends on a static number of priorities - (-128 (high) to 128 (low)) so that tuple access times can be exploited for - quick in/out priority queue operations. This implementation was created to - avoid the slowness within the priority queue used by both RabbitMQ and Riak - (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -<h2><a name="types">Data Types</a></h2> - -<h3 class="typedecl"><a name="type-pqueue4">pqueue4()</a></h3> -<p><tt>pqueue4() = <a href="#type-pqueue4">pqueue4</a>(any())</tt></p> - - -<h3 class="typedecl"><a name="type-pqueue4">pqueue4()</a></h3> -<p><tt>pqueue4(T) = {<a href="#type-priority">priority()</a> | empty, non_neg_integer(), {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, <a href="queue.html#type-queue">queue:queue</a>(T), {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}, {<a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T), <a href="queue.html#type-queue">queue:queue</a>(T)}}</tt></p> - - -<h3 class="typedecl"><a name="type-priority">priority()</a></h3> -<p><tt>priority() = -128..128</tt></p> - - -<h2><a name="index">Function Index</a></h2> -<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#filter-2">filter/2</a></td><td> - <h4><a name="Filter_the_priority_queue.">Filter the priority queue.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#filter-3">filter/3</a></td><td> - <h4><a name="Filter_a_specific_priority_within_the_priority_queue.">Filter a specific priority within the priority queue.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#in-2">in/2</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#in-3">in/3</a></td><td> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_empty-1">is_empty/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#is_queue-1">is_queue/1</a></td><td> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#len-1">len/1</a></td><td> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#new-0">new/0</a></td><td> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1).</td></tr> -<tr><td valign="top"><a href="#out-1">out/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#out-2">out/2</a></td><td> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case.</td></tr> -<tr><td valign="top"><a href="#pout-1">pout/1</a></td><td> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value.</td></tr> -<tr><td valign="top"><a href="#remove_unique-2">remove_unique/2</a></td><td> - <h4><a name="Remove_a_unique_value_from_the_priority_queue_with_a_binary_predicate.">Remove a unique value from the priority queue with a binary predicate.</a></h4> - O(N) but smaller constant than filter/2.</td></tr> -<tr><td valign="top"><a href="#remove_unique-3">remove_unique/3</a></td><td> - <h4><a name="Remove_a_unique_value_in_a_specific_priority_within_the_priority_queue_with_a_binary_predicate.">Remove a unique value in a specific priority within the priority queue with a binary predicate.</a></h4> - O(N) but smaller constant than filter/3.</td></tr> -<tr><td valign="top"><a href="#to_list-1">to_list/1</a></td><td> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N).</td></tr> -<tr><td valign="top"><a href="#to_plist-1">to_plist/1</a></td><td> - <h4><a name="Convert_the_priority_queue_to_a_list_with_priorities.">Convert the priority queue to a list with priorities.</a></h4> - O(N).</td></tr> -</table> - -<h2><a name="functions">Function Details</a></h2> - -<h3 class="function"><a name="filter-2">filter/2</a></h3> -<div class="spec"> -<p><tt>filter(F::fun((any()) -> boolean()), Q::<a href="#type-pqueue4">pqueue4()</a>) -> <a href="#type-pqueue4">pqueue4()</a></tt><br></p> -</div><p> - <h4><a name="Filter_the_priority_queue.">Filter the priority queue.</a></h4> - O(N)</p> - -<h3 class="function"><a name="filter-3">filter/3</a></h3> -<div class="spec"> -<p><tt>filter(F::fun((any()) -> boolean()), P::integer(), Q::<a href="#type-pqueue4">pqueue4()</a>) -> <a href="#type-pqueue4">pqueue4()</a></tt><br></p> -</div><p> - <h4><a name="Filter_a_specific_priority_within_the_priority_queue.">Filter a specific priority within the priority queue.</a></h4> - O(N)</p> - -<h3 class="function"><a name="in-2">in/2</a></h3> -<div class="spec"> -<p><tt>in(X::any(), Q::<a href="#type-pqueue4">pqueue4()</a>) -> <a href="#type-pqueue4">pqueue4()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_the_0_priority_queue.">Append an item to the tail of the 0 priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="in-3">in/3</a></h3> -<div class="spec"> -<p><tt>in(X::any(), P::integer(), Q::<a href="#type-pqueue4">pqueue4()</a>) -> <a href="#type-pqueue4">pqueue4()</a></tt><br></p> -</div><p> - <h4><a name="Append_an_item_to_the_tail_of_a_specific_priority_queue.">Append an item to the tail of a specific priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_empty-1">is_empty/1</a></h3> -<div class="spec"> -<p><tt>is_empty(X1::<a href="#type-pqueue4">pqueue4()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_is_empty.">Check if the priority queue is empty.</a></h4> - O(1)</p> - -<h3 class="function"><a name="is_queue-1">is_queue/1</a></h3> -<div class="spec"> -<p><tt>is_queue(X1::<a href="#type-pqueue4">pqueue4()</a>) -> true | false</tt><br></p> -</div><p> - <h4><a name="Check_if_the_priority_queue_type_is_as_expected.">Check if the priority queue type is as expected.</a></h4> - O(1)</p> - -<h3 class="function"><a name="len-1">len/1</a></h3> -<div class="spec"> -<p><tt>len(X1::<a href="#type-pqueue4">pqueue4()</a>) -> non_neg_integer()</tt><br></p> -</div><p> - <h4><a name="Determine_the_length_of_a_priority_queue.">Determine the length of a priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="new-0">new/0</a></h3> -<div class="spec"> -<p><tt>new() -> <a href="#type-pqueue4">pqueue4()</a></tt><br></p> -</div><p> - <h4><a name="Create_a_new_priority_queue.">Create a new priority queue.</a></h4> - O(1)</p> - -<h3 class="function"><a name="out-1">out/1</a></h3> -<div class="spec"> -<p><tt>out(Q::<a href="#type-pqueue4">pqueue4()</a>) -> {{value, any()}, <a href="#type-pqueue4">pqueue4()</a>} | {empty, <a href="#type-pqueue4">pqueue4()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="out-2">out/2</a></h3> -<div class="spec"> -<p><tt>out(P::integer(), Q::<a href="#type-pqueue4">pqueue4()</a>) -> {{value, any()}, <a href="#type-pqueue4">pqueue4()</a>} | {empty, <a href="#type-pqueue4">pqueue4()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_of_a_specific_priority_from_the_head_of_the_queue.">Take an item of a specific priority from the head of the queue.</a></h4> - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="pout-1">pout/1</a></h3> -<div class="spec"> -<p><tt>pout(Q::<a href="#type-pqueue4">pqueue4()</a>) -> {{value, any(), integer()}, <a href="#type-pqueue4">pqueue4()</a>} | {empty, <a href="#type-pqueue4">pqueue4()</a>}</tt><br></p> -</div><p> - <h4><a name="Take_an_item_from_the_head_of_the_priority_queue.">Take an item from the head of the priority queue.</a></h4> - Includes the priority in the return value. - O(1) amortized, O(N) worst case</p> - -<h3 class="function"><a name="remove_unique-2">remove_unique/2</a></h3> -<div class="spec"> -<p><tt>remove_unique(F::fun((any()) -> boolean()), Q::<a href="#type-pqueue4">pqueue4()</a>) -> {boolean(), <a href="#type-pqueue4">pqueue4()</a>}</tt><br></p> -</div><p> - <h4><a name="Remove_a_unique_value_from_the_priority_queue_with_a_binary_predicate.">Remove a unique value from the priority queue with a binary predicate.</a></h4> - O(N) but smaller constant than filter/2</p> - -<h3 class="function"><a name="remove_unique-3">remove_unique/3</a></h3> -<div class="spec"> -<p><tt>remove_unique(F::fun((any()) -> boolean()), P::integer(), Q::<a href="#type-pqueue4">pqueue4()</a>) -> {boolean(), <a href="#type-pqueue4">pqueue4()</a>}</tt><br></p> -</div><p> - <h4><a name="Remove_a_unique_value_in_a_specific_priority_within_the_priority_queue_with_a_binary_predicate.">Remove a unique value in a specific priority within the priority queue with a binary predicate.</a></h4> - O(N) but smaller constant than filter/3</p> - -<h3 class="function"><a name="to_list-1">to_list/1</a></h3> -<div class="spec"> -<p><tt>to_list(Q::<a href="#type-pqueue4">pqueue4()</a>) -> list()</tt><br></p> -</div><p> - <h4><a name="Convert_the_priority_queue_to_a_list.">Convert the priority queue to a list.</a></h4> - O(N)</p> - -<h3 class="function"><a name="to_plist-1">to_plist/1</a></h3> -<div class="spec"> -<p><tt>to_plist(Q::<a href="#type-pqueue4">pqueue4()</a>) -> [{<a href="#type-priority">priority()</a>, list()}]</tt><br></p> -</div><p> - <h4><a name="Convert_the_priority_queue_to_a_list_with_priorities.">Convert the priority queue to a list with priorities.</a></h4> - O(N)</p> -<hr> - -<div class="navbar"><a name="#navbar_bottom"></a><table width="100%" border="0" cellspacing="0" cellpadding="2" summary="navigation bar"><tr><td><a href="overview-summary.html" target="overviewFrame">Overview</a></td><td><a href="http://www.erlang.org/"><img src="erlang.png" align="right" border="0" alt="erlang logo"></a></td></tr></table></div> -<p><i>Generated by EDoc</i></p> -</body> -</html> diff --git a/aoc2023/build/packages/pqueue/doc/stylesheet.css b/aoc2023/build/packages/pqueue/doc/stylesheet.css deleted file mode 100644 index ab170c0..0000000 --- a/aoc2023/build/packages/pqueue/doc/stylesheet.css +++ /dev/null @@ -1,55 +0,0 @@ -/* standard EDoc style sheet */ -body { - font-family: Verdana, Arial, Helvetica, sans-serif; - margin-left: .25in; - margin-right: .2in; - margin-top: 0.2in; - margin-bottom: 0.2in; - color: #000000; - background-color: #ffffff; -} -h1,h2 { - margin-left: -0.2in; -} -div.navbar { - background-color: #add8e6; - padding: 0.2em; -} -h2.indextitle { - padding: 0.4em; - background-color: #add8e6; -} -h3.function,h3.typedecl { - background-color: #add8e6; - padding-left: 1em; -} -div.spec { - margin-left: 2em; - background-color: #eeeeee; -} -a.module { - text-decoration:none -} -a.module:hover { - background-color: #eeeeee; -} -ul.definitions { - list-style-type: none; -} -ul.index { - list-style-type: none; - background-color: #eeeeee; -} - -/* - * Minor style tweaks - */ -ul { - list-style-type: square; -} -table { - border-collapse: collapse; -} -td { - padding: 3 -} diff --git a/aoc2023/build/packages/pqueue/rebar.config b/aoc2023/build/packages/pqueue/rebar.config deleted file mode 100644 index f8022f0..0000000 --- a/aoc2023/build/packages/pqueue/rebar.config +++ /dev/null @@ -1,14 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: - -{erl_opts, - [{platform_define, "^R16", 'ERLANG_OTP_VERSION_16'}, - {platform_define, "^17\.", 'ERLANG_OTP_VERSION_17'}, - {platform_define, "^18\.", 'ERLANG_OTP_VERSION_18'}, - {platform_define, "^19\.", 'ERLANG_OTP_VERSION_19'}, - {platform_define, "^20\.", 'ERLANG_OTP_VERSION_20'}, - warn_export_vars, - warn_unused_import, - %warn_missing_spec, - warnings_as_errors]}. -{edoc_opts, [{preprocess, true}]}. diff --git a/aoc2023/build/packages/pqueue/src/pqueue.app.src b/aoc2023/build/packages/pqueue/src/pqueue.app.src deleted file mode 100644 index b153ad1..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue.app.src +++ /dev/null @@ -1,10 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: - -{application, pqueue, - [{description, "Priority Queue Data Structures"}, - {vsn, "2.0.7"}, - {modules, [pqueue, pqueue2, pqueue3, pqueue4]}, - {registered, []}, - {applications, [stdlib, kernel]}]}. - diff --git a/aoc2023/build/packages/pqueue/src/pqueue.erl b/aoc2023/build/packages/pqueue/src/pqueue.erl deleted file mode 100644 index 2c57fa2..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue.erl +++ /dev/null @@ -1,2246 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: -%%% -%%%------------------------------------------------------------------------ -%%% @doc -%%% ==Static Priority Queue.== -%%% This priority queue implementation depends on a static number of priorities -%%% (-20 (high) to 20 (low)) so that tuple access times can be exploited for -%%% quick in/out priority queue operations. This implementation was created to -%%% avoid the slowness within the priority queue used by both RabbitMQ and Riak -%%% (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -%%% @end -%%% -%%% MIT License -%%% -%%% Copyright (c) 2011-2020 Michael Truog <mjtruog at protonmail dot com> -%%% -%%% Permission is hereby granted, free of charge, to any person obtaining a -%%% copy of this software and associated documentation files (the "Software"), -%%% to deal in the Software without restriction, including without limitation -%%% the rights to use, copy, modify, merge, publish, distribute, sublicense, -%%% and/or sell copies of the Software, and to permit persons to whom the -%%% Software is furnished to do so, subject to the following conditions: -%%% -%%% The above copyright notice and this permission notice shall be included in -%%% all copies or substantial portions of the Software. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -%%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -%%% DEALINGS IN THE SOFTWARE. -%%% -%%% @author Michael Truog <mjtruog at protonmail dot com> -%%% @copyright 2011-2020 Michael Truog -%%% @version 2.0.1 {@date} {@time} -%%%------------------------------------------------------------------------ - --module(pqueue). --author('mjtruog at protonmail dot com'). - -%% external interface --export([in/2, % O(1) - in/3, % O(1) - is_empty/1, % O(1) - is_queue/1, % O(1) - join/2, % O(N) typically (?) - len/1, % O(N) - new/0, % O(1) - out/1, % O(1) amortized, O(N) worst case - out/2, % O(1) amortized, O(N) worst case - pout/1, % O(1) amortized, O(N) worst case - to_list/1, % O(N) - test/0]). - -%%%------------------------------------------------------------------------ -%%% External interface functions -%%%------------------------------------------------------------------------ - --ifdef(ERLANG_OTP_VERSION_16). --type pqueue() :: - {integer(), - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue()}, - queue(), - {queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}} | - {'empty', - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue()}, - queue(), - {queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue()}}. --else. --type pqueue() :: - {integer(), - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue()}, - queue:queue(), - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}} | - {'empty', - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue()}, - queue:queue(), - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}, - {queue:queue(), queue:queue(), queue:queue(), queue:queue(), - queue:queue(), queue:queue(), queue:queue()}}. --endif. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of the 0 priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), pqueue()) -> pqueue(). - -in(X, Q) -> - in(X, 0, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of a specific priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), integer(), pqueue()) -> pqueue(). - -in(_, P, _) - when P < -20; P > 20 -> - erlang:exit(badarg); -in(X, P, {empty, _, _, _, _, _, _, _} = Q) -> - in_higher(P, Q, X); -in(X, P, {Pc, _, _, _, _, _, _, _} = Q) - when P < Pc -> - in_higher(P, Q, X); -in(X, P, Q) -> - in_lower(P, Q, X). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue is empty.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_empty(pqueue()) -> 'true' | 'false'. - -is_empty({empty, _, _, _, _, _, _, _}) -> - true; -is_empty({_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - queue:is_empty(Qn20) and queue:is_empty(Qn19) and queue:is_empty(Qn18) and - queue:is_empty(Qn17) and queue:is_empty(Qn16) and queue:is_empty(Qn15) and - queue:is_empty(Qn14) and - queue:is_empty(Qn13) and queue:is_empty(Qn12) and queue:is_empty(Qn11) and - queue:is_empty(Qn10) and queue:is_empty(Qn9) and queue:is_empty(Qn8) and - queue:is_empty(Qn7) and - queue:is_empty(Qn6) and queue:is_empty(Qn5) and queue:is_empty(Qn4) and - queue:is_empty(Qn3) and queue:is_empty(Qn2) and queue:is_empty(Qn1) and - queue:is_empty(Q0) and - queue:is_empty(Qp1) and queue:is_empty(Qp2) and queue:is_empty(Qp3) and - queue:is_empty(Qp4) and queue:is_empty(Qp5) and queue:is_empty(Qp6) and - queue:is_empty(Qp7) and queue:is_empty(Qp8) and queue:is_empty(Qp9) and - queue:is_empty(Qp10) and queue:is_empty(Qp11) and queue:is_empty(Qp12) and - queue:is_empty(Qp13) and - queue:is_empty(Qp14) and queue:is_empty(Qp15) and queue:is_empty(Qp16) and - queue:is_empty(Qp17) and queue:is_empty(Qp18) and queue:is_empty(Qp19) and - queue:is_empty(Qp20). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue type is as expected.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_queue(pqueue()) -> 'true' | 'false'. - -is_queue({Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) - when tuple_size(Qsn14) == 7, tuple_size(Qsn7) == 7, tuple_size(Qsn1) == 6, - tuple_size(Qsp14) == 7, tuple_size(Qsp7) == 7, tuple_size(Qsp1) == 6 -> - (((Pc =:= empty) or is_integer(Pc)) and queue:is_queue(Q0)); -is_queue(_) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Join two priority queues.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec join(pqueue(), pqueue()) -> pqueue(). - -join({P1c, - {Q1_n20, Q1_n19, Q1_n18, Q1_n17, Q1_n16, Q1_n15, Q1_n14}, - {Q1_n13, Q1_n12, Q1_n11, Q1_n10, Q1_n9, Q1_n8, Q1_n7}, - {Q1_n6, Q1_n5, Q1_n4, Q1_n3, Q1_n2, Q1_n1}, - Q1_0, - {Q1_p1, Q1_p2, Q1_p3, Q1_p4, Q1_p5, Q1_p6}, - {Q1_p7, Q1_p8, Q1_p9, Q1_p10, Q1_p11, Q1_p12, Q1_p13}, - {Q1_p14, Q1_p15, Q1_p16, Q1_p17, Q1_p18, Q1_p19, Q1_p20}}, - {P2c, - {Q2_n20, Q2_n19, Q2_n18, Q2_n17, Q2_n16, Q2_n15, Q2_n14}, - {Q2_n13, Q2_n12, Q2_n11, Q2_n10, Q2_n9, Q2_n8, Q2_n7}, - {Q2_n6, Q2_n5, Q2_n4, Q2_n3, Q2_n2, Q2_n1}, - Q2_0, - {Q2_p1, Q2_p2, Q2_p3, Q2_p4, Q2_p5, Q2_p6}, - {Q2_p7, Q2_p8, Q2_p9, Q2_p10, Q2_p11, Q2_p12, Q2_p13}, - {Q2_p14, Q2_p15, Q2_p16, Q2_p17, Q2_p18, Q2_p19, Q2_p20}}) -> - {erlang:min(P1c, P2c), - {queue:join(Q1_n20, Q2_n20), queue:join(Q1_n19, Q2_n19), - queue:join(Q1_n18, Q2_n18), queue:join(Q1_n17, Q2_n17), - queue:join(Q1_n16, Q2_n16), queue:join(Q1_n15, Q2_n15), - queue:join(Q1_n14, Q2_n14)}, - {queue:join(Q1_n13, Q2_n13), queue:join(Q1_n12, Q2_n12), - queue:join(Q1_n11, Q2_n11), queue:join(Q1_n10, Q2_n10), - queue:join(Q1_n9, Q2_n9), queue:join(Q1_n8, Q2_n8), - queue:join(Q1_n7, Q2_n7)}, - {queue:join(Q1_n6, Q2_n6), queue:join(Q1_n5, Q2_n5), - queue:join(Q1_n4, Q2_n4), queue:join(Q1_n3, Q2_n3), - queue:join(Q1_n2, Q2_n2), queue:join(Q1_n1, Q2_n1)}, - queue:join(Q1_0, Q2_0), - {queue:join(Q1_p1, Q2_p1), queue:join(Q1_p2, Q2_p2), - queue:join(Q1_p3, Q2_p3), queue:join(Q1_p4, Q2_p4), - queue:join(Q1_p5, Q2_p5), queue:join(Q1_p6, Q2_p6)}, - {queue:join(Q1_p7, Q2_p7), queue:join(Q1_p8, Q2_p8), - queue:join(Q1_p9, Q2_p9), queue:join(Q1_p10, Q2_p10), - queue:join(Q1_p11, Q2_p11), queue:join(Q1_p12, Q2_p12), - queue:join(Q1_p13, Q2_p13)}, - {queue:join(Q1_p14, Q2_p14), queue:join(Q1_p15, Q2_p15), - queue:join(Q1_p16, Q2_p16), queue:join(Q1_p17, Q2_p17), - queue:join(Q1_p18, Q2_p18), queue:join(Q1_p19, Q2_p19), - queue:join(Q1_p20, Q2_p20)}}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Determine the length of a priority queue.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec len(pqueue()) -> non_neg_integer(). - -len({_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - queue:len(Qn20) + queue:len(Qn19) + queue:len(Qn18) + queue:len(Qn17) + - queue:len(Qn16) + queue:len(Qn15) + queue:len(Qn14) + - queue:len(Qn13) + queue:len(Qn12) + queue:len(Qn11) + queue:len(Qn10) + - queue:len(Qn9) + queue:len(Qn8) + queue:len(Qn7) + - queue:len(Qn6) + queue:len(Qn5) + queue:len(Qn4) + queue:len(Qn3) + - queue:len(Qn2) + queue:len(Qn1) + - queue:len(Q0) + - queue:len(Qp1) + queue:len(Qp2) + queue:len(Qp3) + queue:len(Qp4) + - queue:len(Qp5) + queue:len(Qp6) + - queue:len(Qp7) + queue:len(Qp8) + queue:len(Qp9) + queue:len(Qp10) + - queue:len(Qp11) + queue:len(Qp12) + queue:len(Qp13) + - queue:len(Qp14) + queue:len(Qp15) + queue:len(Qp16) + queue:len(Qp17) + - queue:len(Qp18) + queue:len(Qp19) + queue:len(Qp20). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Create a new priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec new() -> pqueue(). - -new() -> - {empty, % current priority - erlang:make_tuple(7, queue:new()), % priority [-20..-14] - erlang:make_tuple(7, queue:new()), % priority [-13.. -7] - erlang:make_tuple(6, queue:new()), % priority [ -6.. -1] - queue:new(), % priority 0 (default) - erlang:make_tuple(6, queue:new()), % priority [ 1.. 6] - erlang:make_tuple(7, queue:new()), % priority [ 7.. 13] - erlang:make_tuple(7, queue:new())}. % priority [ 14.. 20] - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(pqueue()) -> - {{'value', term()}, pqueue()} | {'empty', pqueue()}. - -out({empty, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -out({Pc, _, _, _, _, _, _, _} = Q) -> - out_current(Pc, Q, nopriority). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item of a specific priority from the head of the queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(integer(), pqueue()) -> - {{'value', term()}, pqueue()} | {'empty', pqueue()}. - -out(P, _) - when P < -20; P > 20 -> - erlang:exit(badarg); -out(_, {empty, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -out(P, Q) -> - out_specific(P, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% Includes the priority in the return value. -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec pout(pqueue()) -> - {{'value', term(), integer()}, pqueue()} | {'empty', pqueue()}. - -pout({empty, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -pout({Pc, _, _, _, _, _, _, _} = Q) -> - out_current(Pc, Q, priority). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Convert the priority queue to a list.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec to_list(pqueue()) -> list(term()). - -to_list({_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - queue:to_list(Qn20) ++ queue:to_list(Qn19) ++ queue:to_list(Qn18) ++ - queue:to_list(Qn17) ++ queue:to_list(Qn16) ++ queue:to_list(Qn15) ++ - queue:to_list(Qn14) ++ - queue:to_list(Qn13) ++ queue:to_list(Qn12) ++ queue:to_list(Qn11) ++ - queue:to_list(Qn10) ++ queue:to_list(Qn9) ++ queue:to_list(Qn8) ++ - queue:to_list(Qn7) ++ - queue:to_list(Qn6) ++ queue:to_list(Qn5) ++ queue:to_list(Qn4) ++ - queue:to_list(Qn3) ++ queue:to_list(Qn2) ++ queue:to_list(Qn1) ++ - queue:to_list(Q0) ++ - queue:to_list(Qp1) ++ queue:to_list(Qp2) ++ queue:to_list(Qp3) ++ - queue:to_list(Qp4) ++ queue:to_list(Qp5) ++ queue:to_list(Qp6) ++ - queue:to_list(Qp7) ++ queue:to_list(Qp8) ++ queue:to_list(Qp9) ++ - queue:to_list(Qp10) ++ queue:to_list(Qp11) ++ queue:to_list(Qp12) ++ - queue:to_list(Qp13) ++ - queue:to_list(Qp14) ++ queue:to_list(Qp15) ++ queue:to_list(Qp16) ++ - queue:to_list(Qp17) ++ queue:to_list(Qp18) ++ queue:to_list(Qp19) ++ - queue:to_list(Qp20). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Regression test.=== -%% @end -%%------------------------------------------------------------------------- - -test() -> - Q0 = pqueue:new(), - true = pqueue:is_queue(Q0), - Q1 = pqueue:in(20, 20, Q0), - Q2 = pqueue:in(19, 19, Q1), - Q3 = pqueue:in(18, 18, Q2), - Q4 = pqueue:in(17, 17, Q3), - Q5 = pqueue:in(16, 16, Q4), - Q6 = pqueue:in(15, 15, Q5), - Q7 = pqueue:in(14, 14, Q6), - Q8 = pqueue:in(13, 13, Q7), - Q9 = pqueue:in(12, 12, Q8), - Q10 = pqueue:in(11, 11, Q9), - Q11 = pqueue:in(10, 10, Q10), - Q12 = pqueue:in(9, 9, Q11), - Q13 = pqueue:in(8, 8, Q12), - Q14 = pqueue:in(7, 7, Q13), - Q15 = pqueue:in(6, 6, Q14), - Q16 = pqueue:in(5, 5, Q15), - Q17 = pqueue:in(4, 4, Q16), - Q18 = pqueue:in(3, 3, Q17), - Q19 = pqueue:in(2, 2, Q18), - Q20 = pqueue:in(1, 1, Q19), - Q21 = pqueue:in(0, 0, Q20), - Q22 = pqueue:in(-1, -1, Q21), - Q23 = pqueue:in(-2, -2, Q22), - Q24 = pqueue:in(-3, -3, Q23), - Q25 = pqueue:in(-4, -4, Q24), - Q26 = pqueue:in(-5, -5, Q25), - Q27 = pqueue:in(-6, -6, Q26), - Q28 = pqueue:in(-7, -7, Q27), - Q29 = pqueue:in(-8, -8, Q28), - Q30 = pqueue:in(-9, -9, Q29), - Q31 = pqueue:in(-10, -10, Q30), - Q32 = pqueue:in(-11, -11, Q31), - Q33 = pqueue:in(-12, -12, Q32), - Q34 = pqueue:in(-13, -13, Q33), - Q35 = pqueue:in(-14, -14, Q34), - Q36 = pqueue:in(-15, -15, Q35), - Q37 = pqueue:in(-16, -16, Q36), - Q38 = pqueue:in(-17, -17, Q37), - Q39 = pqueue:in(-18, -18, Q38), - Q40 = pqueue:in(-19, -19, Q39), - Q41 = pqueue:in(-20, -20, Q40), - Q42 = pqueue:in(-20, -20, Q41), - Q43 = pqueue:in(-19, -19, Q42), - Q44 = pqueue:in(-18, -18, Q43), - Q45 = pqueue:in(-17, -17, Q44), - Q46 = pqueue:in(-16, -16, Q45), - Q47 = pqueue:in(-15, -15, Q46), - Q48 = pqueue:in(-14, -14, Q47), - Q49 = pqueue:in(-13, -13, Q48), - Q50 = pqueue:in(-12, -12, Q49), - Q51 = pqueue:in(-11, -11, Q50), - Q52 = pqueue:in(-10, -10, Q51), - Q53 = pqueue:in(-9, -9, Q52), - Q54 = pqueue:in(-8, -8, Q53), - Q55 = pqueue:in(-7, -7, Q54), - Q56 = pqueue:in(-6, -6, Q55), - Q57 = pqueue:in(-5, -5, Q56), - Q58 = pqueue:in(-4, -4, Q57), - Q59 = pqueue:in(-3, -3, Q58), - Q60 = pqueue:in(-2, -2, Q59), - Q61 = pqueue:in(-1, -1, Q60), - Q62 = pqueue:in(0, 0, Q61), - Q63 = pqueue:in(1, 1, Q62), - Q64 = pqueue:in(2, 2, Q63), - Q65 = pqueue:in(3, 3, Q64), - Q66 = pqueue:in(4, 4, Q65), - Q67 = pqueue:in(5, 5, Q66), - Q68 = pqueue:in(6, 6, Q67), - Q69 = pqueue:in(7, 7, Q68), - Q70 = pqueue:in(8, 8, Q69), - Q71 = pqueue:in(9, 9, Q70), - Q72 = pqueue:in(10, 10, Q71), - Q73 = pqueue:in(11, 11, Q72), - Q74 = pqueue:in(12, 12, Q73), - Q75 = pqueue:in(13, 13, Q74), - Q76 = pqueue:in(14, 14, Q75), - Q77 = pqueue:in(15, 15, Q76), - Q78 = pqueue:in(16, 16, Q77), - Q79 = pqueue:in(17, 17, Q78), - Q80 = pqueue:in(18, 18, Q79), - Q81 = pqueue:in(19, 19, Q80), - Q82 = pqueue:in(20, 20, Q81), - true = pqueue:is_queue(Q82), - 82 = pqueue:len(Q82), - [-20, -20, -19, -19, -18, -18, -17, -17, -16, -16, -15, -15, -14, -14, - -13, -13, -12, -12, -11, -11, -10, -10, -9, -9, -8, -8, -7, -7, -6, -6, - -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, - 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20] = pqueue:to_list(Q82), - {{value, -20}, Q83} = pqueue:out(Q82), - {{value, -20}, Q84} = pqueue:out(Q83), - {{value, -19}, Q85} = pqueue:out(Q84), - {{value, -19}, Q86} = pqueue:out(Q85), - {{value, -18}, Q87} = pqueue:out(Q86), - {{value, -18}, Q88} = pqueue:out(Q87), - {{value, 0}, Q89} = pqueue:out(0, Q88), - {{value, 0}, Q90} = pqueue:out(0, Q89), - {empty, _} = pqueue:out(0, Q90), - {{value, -17, -17}, Q91} = pqueue:pout(Q90), - {{value, -17, -17}, Q92} = pqueue:pout(Q91), - {{value, -16, -16}, Q93} = pqueue:pout(Q92), - {{value, -16, -16}, Q94} = pqueue:pout(Q93), - {{value, -15, -15}, Q95} = pqueue:pout(Q94), - {{value, -15, -15}, Q96} = pqueue:pout(Q95), - {{value, -14, -14}, Q97} = pqueue:pout(Q96), - {{value, -14, -14}, Q98} = pqueue:pout(Q97), - {{value, -13, -13}, Q99} = pqueue:pout(Q98), - {{value, -13, -13}, Q100} = pqueue:pout(Q99), - {{value, -12, -12}, Q101} = pqueue:pout(Q100), - {{value, -12, -12}, Q102} = pqueue:pout(Q101), - {{value, -11, -11}, Q103} = pqueue:pout(Q102), - {{value, -11, -11}, Q104} = pqueue:pout(Q103), - {{value, -10, -10}, Q105} = pqueue:pout(Q104), - {{value, -10, -10}, Q106} = pqueue:pout(Q105), - {{value, -9, -9}, Q107} = pqueue:pout(Q106), - {{value, -9, -9}, Q108} = pqueue:pout(Q107), - {{value, -8, -8}, Q109} = pqueue:pout(Q108), - {{value, -8, -8}, Q110} = pqueue:pout(Q109), - {{value, -7, -7}, Q111} = pqueue:pout(Q110), - {{value, -7, -7}, Q112} = pqueue:pout(Q111), - {{value, -6, -6}, Q113} = pqueue:pout(Q112), - {{value, -6, -6}, Q114} = pqueue:pout(Q113), - {{value, -5, -5}, Q115} = pqueue:pout(Q114), - {{value, -5, -5}, Q116} = pqueue:pout(Q115), - {{value, -4, -4}, Q117} = pqueue:pout(Q116), - {{value, -4, -4}, Q118} = pqueue:pout(Q117), - {{value, -3, -3}, Q119} = pqueue:pout(Q118), - {{value, -3, -3}, Q120} = pqueue:pout(Q119), - {{value, -2, -2}, Q121} = pqueue:pout(Q120), - {{value, -2, -2}, Q122} = pqueue:pout(Q121), - {{value, -1, -1}, Q123} = pqueue:pout(Q122), - {{value, -1, -1}, Q124} = pqueue:pout(Q123), - {{value, 1, 1}, Q125} = pqueue:pout(Q124), - {{value, 1, 1}, Q126} = pqueue:pout(Q125), - {{value, 2, 2}, Q127} = pqueue:pout(Q126), - {{value, 2, 2}, Q128} = pqueue:pout(Q127), - {{value, 3, 3}, Q129} = pqueue:pout(Q128), - {{value, 3, 3}, Q130} = pqueue:pout(Q129), - {{value, 4, 4}, Q131} = pqueue:pout(Q130), - {{value, 4, 4}, Q132} = pqueue:pout(Q131), - {{value, 5, 5}, Q133} = pqueue:pout(Q132), - {{value, 5, 5}, Q134} = pqueue:pout(Q133), - {{value, 6, 6}, Q135} = pqueue:pout(Q134), - {{value, 6, 6}, Q136} = pqueue:pout(Q135), - {{value, 7, 7}, Q137} = pqueue:pout(Q136), - {{value, 7, 7}, Q138} = pqueue:pout(Q137), - {{value, 8, 8}, Q139} = pqueue:pout(Q138), - {{value, 8, 8}, Q140} = pqueue:pout(Q139), - {{value, 9, 9}, Q141} = pqueue:pout(Q140), - {{value, 9, 9}, Q142} = pqueue:pout(Q141), - {{value, 10, 10}, Q143} = pqueue:pout(Q142), - {{value, 10, 10}, Q144} = pqueue:pout(Q143), - {{value, 11, 11}, Q145} = pqueue:pout(Q144), - {{value, 11, 11}, Q146} = pqueue:pout(Q145), - {{value, 12, 12}, Q147} = pqueue:pout(Q146), - {{value, 12, 12}, Q148} = pqueue:pout(Q147), - {{value, 13, 13}, Q149} = pqueue:pout(Q148), - {{value, 13, 13}, Q150} = pqueue:pout(Q149), - {{value, 14, 14}, Q151} = pqueue:pout(Q150), - {{value, 14, 14}, Q152} = pqueue:pout(Q151), - {{value, 15, 15}, Q153} = pqueue:pout(Q152), - {{value, 15, 15}, Q154} = pqueue:pout(Q153), - {{value, 16, 16}, Q155} = pqueue:pout(Q154), - {{value, 16, 16}, Q156} = pqueue:pout(Q155), - {{value, 17, 17}, Q157} = pqueue:pout(Q156), - {{value, 17, 17}, Q158} = pqueue:pout(Q157), - {{value, 18, 18}, Q159} = pqueue:pout(Q158), - {{value, 18, 18}, Q160} = pqueue:pout(Q159), - {{value, 19, 19}, Q161} = pqueue:pout(Q160), - {{value, 19, 19}, Q162} = pqueue:pout(Q161), - {{value, 20, 20}, Q163} = pqueue:pout(Q162), - {{value, 20, 20}, Q164} = pqueue:pout(Q163), - true = pqueue:is_empty(Q164), - {empty, Q165} = pqueue:pout(Q164), - true = pqueue:is_empty(Q165), - ok. - -%%%------------------------------------------------------------------------ -%%% Private functions -%%%------------------------------------------------------------------------ - -in_higher(-20, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-20, - {queue:in(X, Qn20), Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-19, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-19, - {Qn20, queue:in(X, Qn19), Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-18, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-18, - {Qn20, Qn19, queue:in(X, Qn18), Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-17, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-17, - {Qn20, Qn19, Qn18, queue:in(X, Qn17), Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-16, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-16, - {Qn20, Qn19, Qn18, Qn17, queue:in(X, Qn16), Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-15, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-15, - {Qn20, Qn19, Qn18, Qn17, Qn16, queue:in(X, Qn15), Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-14, {_, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-14, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, queue:in(X, Qn14)}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-13, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-13, Qsn14, - {queue:in(X, Qn13), Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-12, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-12, Qsn14, - {Qn13, queue:in(X, Qn12), Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-11, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-11, Qsn14, - {Qn13, Qn12, queue:in(X, Qn11), Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-10, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-10, Qsn14, - {Qn13, Qn12, Qn11, queue:in(X, Qn10), Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-9, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-9, Qsn14, - {Qn13, Qn12, Qn11, Qn10, queue:in(X, Qn9), Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-8, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-8, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, queue:in(X, Qn8), Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-7, {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-7, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, queue:in(X, Qn7)}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-6, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-6, Qsn14, Qsn7, - {queue:in(X, Qn6), Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-5, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-5, Qsn14, Qsn7, - {Qn6, queue:in(X, Qn5), Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-4, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-4, Qsn14, Qsn7, - {Qn6, Qn5, queue:in(X, Qn4), Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-3, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-3, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, queue:in(X, Qn3), Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-2, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-2, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, queue:in(X, Qn2), Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(-1, {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {-1, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, queue:in(X, Qn1)}, - Q0, Qsp1, Qsp7, Qsp14}; -in_higher(0, {_, Qsn14, Qsn7, Qsn1, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {0, Qsn14, Qsn7, Qsn1, - queue:in(X, Q0), - Qsp1, Qsp7, Qsp14}; -in_higher(1, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {1, Qsn14, Qsn7, Qsn1, Q0, - {queue:in(X, Qp1), Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_higher(2, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {2, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, queue:in(X, Qp2), Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_higher(3, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {3, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, queue:in(X, Qp3), Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_higher(4, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {4, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, queue:in(X, Qp4), Qp5, Qp6}, - Qsp7, Qsp14}; -in_higher(5, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {5, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, queue:in(X, Qp5), Qp6}, - Qsp7, Qsp14}; -in_higher(6, {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {6, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, queue:in(X, Qp6)}, - Qsp7, Qsp14}; -in_higher(7, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {7, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {queue:in(X, Qp7), Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_higher(8, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {8, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, queue:in(X, Qp8), Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_higher(9, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {9, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, queue:in(X, Qp9), Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_higher(10, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {10, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, queue:in(X, Qp10), Qp11, Qp12, Qp13}, - Qsp14}; -in_higher(11, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {11, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, queue:in(X, Qp11), Qp12, Qp13}, - Qsp14}; -in_higher(12, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {12, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, queue:in(X, Qp12), Qp13}, - Qsp14}; -in_higher(13, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {13, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, queue:in(X, Qp13)}, - Qsp14}; -in_higher(14, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {14, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {queue:in(X, Qp14), Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}; -in_higher(15, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {15, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, queue:in(X, Qp15), Qp16, Qp17, Qp18, Qp19, Qp20}}; -in_higher(16, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {16, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, queue:in(X, Qp16), Qp17, Qp18, Qp19, Qp20}}; -in_higher(17, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {17, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, queue:in(X, Qp17), Qp18, Qp19, Qp20}}; -in_higher(18, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {18, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, queue:in(X, Qp18), Qp19, Qp20}}; -in_higher(19, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {19, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, queue:in(X, Qp19), Qp20}}; -in_higher(20, {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {20, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, queue:in(X, Qp20)}}. - -in_lower(-20, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {queue:in(X, Qn20), Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-19, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, queue:in(X, Qn19), Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-18, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, Qn19, queue:in(X, Qn18), Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-17, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, Qn19, Qn18, queue:in(X, Qn17), Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-16, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, Qn19, Qn18, Qn17, queue:in(X, Qn16), Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-15, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, queue:in(X, Qn15), Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-14, {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, queue:in(X, Qn14)}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-13, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {queue:in(X, Qn13), Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-12, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, queue:in(X, Qn12), Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-11, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, Qn12, queue:in(X, Qn11), Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-10, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, Qn12, Qn11, queue:in(X, Qn10), Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-9, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, queue:in(X, Qn9), Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-8, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, queue:in(X, Qn8), Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-7, {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, queue:in(X, Qn7)}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-6, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {queue:in(X, Qn6), Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-5, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {Qn6, queue:in(X, Qn5), Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-4, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, queue:in(X, Qn4), Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-3, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, queue:in(X, Qn3), Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-2, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, queue:in(X, Qn2), Qn1}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(-1, {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, queue:in(X, Qn1)}, - Q0, Qsp1, Qsp7, Qsp14}; -in_lower(0, {Pc, Qsn14, Qsn7, Qsn1, - Q0, Qsp1, Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, - queue:in(X, Q0), - Qsp1, Qsp7, Qsp14}; -in_lower(1, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {queue:in(X, Qp1), Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_lower(2, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, queue:in(X, Qp2), Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_lower(3, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, queue:in(X, Qp3), Qp4, Qp5, Qp6}, - Qsp7, Qsp14}; -in_lower(4, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, queue:in(X, Qp4), Qp5, Qp6}, - Qsp7, Qsp14}; -in_lower(5, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, queue:in(X, Qp5), Qp6}, - Qsp7, Qsp14}; -in_lower(6, {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, queue:in(X, Qp6)}, - Qsp7, Qsp14}; -in_lower(7, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {queue:in(X, Qp7), Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_lower(8, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, queue:in(X, Qp8), Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_lower(9, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, queue:in(X, Qp9), Qp10, Qp11, Qp12, Qp13}, - Qsp14}; -in_lower(10, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, queue:in(X, Qp10), Qp11, Qp12, Qp13}, - Qsp14}; -in_lower(11, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, queue:in(X, Qp11), Qp12, Qp13}, - Qsp14}; -in_lower(12, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, queue:in(X, Qp12), Qp13}, - Qsp14}; -in_lower(13, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, queue:in(X, Qp13)}, - Qsp14}; -in_lower(14, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {queue:in(X, Qp14), Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}; -in_lower(15, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, queue:in(X, Qp15), Qp16, Qp17, Qp18, Qp19, Qp20}}; -in_lower(16, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, queue:in(X, Qp16), Qp17, Qp18, Qp19, Qp20}}; -in_lower(17, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, queue:in(X, Qp17), Qp18, Qp19, Qp20}}; -in_lower(18, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, queue:in(X, Qp18), Qp19, Qp20}}; -in_lower(19, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, queue:in(X, Qp19), Qp20}}; -in_lower(20, {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}, X) -> - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, queue:in(X, Qp20)}}. - -out_current(-20, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn20} = queue:out(Qn20), - if - Value =:= empty -> - out_current(-19, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -20}; - true -> - Value - end, - {NewValue, - {-20, - {NewQn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-19, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn19} = queue:out(Qn19), - if - Value =:= empty -> - out_current(-18, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -19}; - true -> - Value - end, - {NewValue, - {-19, - {Qn20, NewQn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-18, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn18} = queue:out(Qn18), - if - Value =:= empty -> - out_current(-17, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -18}; - true -> - Value - end, - {NewValue, - {-18, - {Qn20, Qn19, NewQn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-17, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn17} = queue:out(Qn17), - if - Value =:= empty -> - out_current(-16, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -17}; - true -> - Value - end, - {NewValue, - {-17, - {Qn20, Qn19, Qn18, NewQn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-16, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn16} = queue:out(Qn16), - if - Value =:= empty -> - out_current(-15, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -16}; - true -> - Value - end, - {NewValue, - {-16, - {Qn20, Qn19, Qn18, Qn17, NewQn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-15, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn15} = queue:out(Qn15), - if - Value =:= empty -> - out_current(-14, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -15}; - true -> - Value - end, - {NewValue, - {-15, - {Qn20, Qn19, Qn18, Qn17, Qn16, NewQn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-14, - {_, {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn14} = queue:out(Qn14), - if - Value =:= empty -> - out_current(-13, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -14}; - true -> - Value - end, - {NewValue, - {-14, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, NewQn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-13, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn13} = queue:out(Qn13), - if - Value =:= empty -> - out_current(-12, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -13}; - true -> - Value - end, - {NewValue, - {-13, Qsn14, - {NewQn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-12, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn12} = queue:out(Qn12), - if - Value =:= empty -> - out_current(-11, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -12}; - true -> - Value - end, - {NewValue, - {-12, Qsn14, - {Qn13, NewQn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-11, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn11} = queue:out(Qn11), - if - Value =:= empty -> - out_current(-10, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -11}; - true -> - Value - end, - {NewValue, - {-11, Qsn14, - {Qn13, Qn12, NewQn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-10, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn10} = queue:out(Qn10), - if - Value =:= empty -> - out_current(-9, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -10}; - true -> - Value - end, - {NewValue, - {-10, Qsn14, - {Qn13, Qn12, Qn11, NewQn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-9, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn9} = queue:out(Qn9), - if - Value =:= empty -> - out_current(-8, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -9}; - true -> - Value - end, - {NewValue, - {-9, Qsn14, - {Qn13, Qn12, Qn11, Qn10, NewQn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-8, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn8} = queue:out(Qn8), - if - Value =:= empty -> - out_current(-7, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -8}; - true -> - Value - end, - {NewValue, - {-8, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, NewQn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-7, - {_, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn7} = queue:out(Qn7), - if - Value =:= empty -> - out_current(-6, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -7}; - true -> - Value - end, - {NewValue, - {-7, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, NewQn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-6, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn6} = queue:out(Qn6), - if - Value =:= empty -> - out_current(-5, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -6}; - true -> - Value - end, - {NewValue, - {-6, Qsn14, Qsn7, - {NewQn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-5, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn5} = queue:out(Qn5), - if - Value =:= empty -> - out_current(-4, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -5}; - true -> - Value - end, - {NewValue, - {-5, Qsn14, Qsn7, - {Qn6, NewQn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-4, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn4} = queue:out(Qn4), - if - Value =:= empty -> - out_current(-3, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -4}; - true -> - Value - end, - {NewValue, - {-4, Qsn14, Qsn7, - {Qn6, Qn5, NewQn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-3, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn3} = queue:out(Qn3), - if - Value =:= empty -> - out_current(-2, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -3}; - true -> - Value - end, - {NewValue, - {-3, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, NewQn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-2, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn2} = queue:out(Qn2), - if - Value =:= empty -> - out_current(-1, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -2}; - true -> - Value - end, - {NewValue, - {-2, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, NewQn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(-1, - {_, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQn1} = queue:out(Qn1), - if - Value =:= empty -> - out_current(0, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, -1}; - true -> - Value - end, - {NewValue, - {-1, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, NewQn1}, - Q0, Qsp1, Qsp7, Qsp14}} - end; -out_current(0, - {_, Qsn14, Qsn7, Qsn1, - Q0, Qsp1, Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQ0} = queue:out(Q0), - if - Value =:= empty -> - out_current(1, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 0}; - true -> - Value - end, - {NewValue, - {0, Qsn14, Qsn7, Qsn1, - NewQ0, - Qsp1, Qsp7, Qsp14}} - end; -out_current(1, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp1} = queue:out(Qp1), - if - Value =:= empty -> - out_current(2, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 1}; - true -> - Value - end, - {NewValue, - {1, Qsn14, Qsn7, Qsn1, Q0, - {NewQp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}} - end; -out_current(2, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp2} = queue:out(Qp2), - if - Value =:= empty -> - out_current(3, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 2}; - true -> - Value - end, - {NewValue, - {2, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, NewQp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}} - end; -out_current(3, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp3} = queue:out(Qp3), - if - Value =:= empty -> - out_current(4, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 3}; - true -> - Value - end, - {NewValue, - {3, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, NewQp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}} - end; -out_current(4, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp4} = queue:out(Qp4), - if - Value =:= empty -> - out_current(5, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 4}; - true -> - Value - end, - {NewValue, - {4, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, NewQp4, Qp5, Qp6}, - Qsp7, Qsp14}} - end; -out_current(5, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp5} = queue:out(Qp5), - if - Value =:= empty -> - out_current(6, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 5}; - true -> - Value - end, - {NewValue, - {5, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, NewQp5, Qp6}, - Qsp7, Qsp14}} - end; -out_current(6, - {_, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14} = Q, ReturnType) -> - {Value, NewQp6} = queue:out(Qp6), - if - Value =:= empty -> - out_current(7, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 6}; - true -> - Value - end, - {NewValue, - {6, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, NewQp6}, - Qsp7, Qsp14}} - end; -out_current(7, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp7} = queue:out(Qp7), - if - Value =:= empty -> - out_current(8, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 7}; - true -> - Value - end, - {NewValue, - {7, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {NewQp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}} - end; -out_current(8, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp8} = queue:out(Qp8), - if - Value =:= empty -> - out_current(9, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 8}; - true -> - Value - end, - {NewValue, - {8, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, NewQp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}} - end; -out_current(9, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp9} = queue:out(Qp9), - if - Value =:= empty -> - out_current(10, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 9}; - true -> - Value - end, - {NewValue, - {9, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, NewQp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}} - end; -out_current(10, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp10} = queue:out(Qp10), - if - Value =:= empty -> - out_current(11, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 10}; - true -> - Value - end, - {NewValue, - {10, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, NewQp10, Qp11, Qp12, Qp13}, - Qsp14}} - end; -out_current(11, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp11} = queue:out(Qp11), - if - Value =:= empty -> - out_current(12, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 11}; - true -> - Value - end, - {NewValue, - {11, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, NewQp11, Qp12, Qp13}, - Qsp14}} - end; -out_current(12, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp12} = queue:out(Qp12), - if - Value =:= empty -> - out_current(13, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 12}; - true -> - Value - end, - {NewValue, - {12, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, NewQp12, Qp13}, - Qsp14}} - end; -out_current(13, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14} = Q, ReturnType) -> - {Value, NewQp13} = queue:out(Qp13), - if - Value =:= empty -> - out_current(14, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 13}; - true -> - Value - end, - {NewValue, - {13, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, NewQp13}, - Qsp14}} - end; -out_current(14, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp14} = queue:out(Qp14), - if - Value =:= empty -> - out_current(15, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 14}; - true -> - Value - end, - {NewValue, - {14, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {NewQp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}} - end; -out_current(15, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp15} = queue:out(Qp15), - if - Value =:= empty -> - out_current(16, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 15}; - true -> - Value - end, - {NewValue, - {15, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, NewQp15, Qp16, Qp17, Qp18, Qp19, Qp20}}} - end; -out_current(16, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp16} = queue:out(Qp16), - if - Value =:= empty -> - out_current(17, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 16}; - true -> - Value - end, - {NewValue, - {16, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, NewQp16, Qp17, Qp18, Qp19, Qp20}}} - end; -out_current(17, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp17} = queue:out(Qp17), - if - Value =:= empty -> - out_current(18, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 17}; - true -> - Value - end, - {NewValue, - {17, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, NewQp17, Qp18, Qp19, Qp20}}} - end; -out_current(18, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp18} = queue:out(Qp18), - if - Value =:= empty -> - out_current(19, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 18}; - true -> - Value - end, - {NewValue, - {18, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, NewQp18, Qp19, Qp20}}} - end; -out_current(19, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}} = Q, ReturnType) -> - {Value, NewQp19} = queue:out(Qp19), - if - Value =:= empty -> - out_current(20, Q, ReturnType); - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 19}; - true -> - Value - end, - {NewValue, - {19, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, NewQp19, Qp20}}} - end; -out_current(20, - {_, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20} = Qsp14}, ReturnType) -> - {Value, NewQp20} = queue:out(Qp20), - if - Value =:= empty -> - {empty, {empty, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; - true -> - NewValue = if - ReturnType =:= priority -> - {value, Contents} = Value, - {value, Contents, 20}; - true -> - Value - end, - {NewValue, - {20, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, NewQp20}}} - end. - -out_specific(-20, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn20} = queue:out(Qn20), - {Value, - {Pc, - {NewQn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-19, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn19} = queue:out(Qn19), - {Value, - {Pc, - {Qn20, NewQn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-18, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn18} = queue:out(Qn18), - {Value, - {Pc, - {Qn20, Qn19, NewQn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-17, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn17} = queue:out(Qn17), - {Value, - {Pc, - {Qn20, Qn19, Qn18, NewQn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-16, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn16} = queue:out(Qn16), - {Value, - {Pc, - {Qn20, Qn19, Qn18, Qn17, NewQn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-15, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn15} = queue:out(Qn15), - {Value, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, NewQn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-14, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, Qn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn14} = queue:out(Qn14), - {Value, - {Pc, - {Qn20, Qn19, Qn18, Qn17, Qn16, Qn15, NewQn14}, - Qsn7, Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-13, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn13} = queue:out(Qn13), - {Value, - {Pc, Qsn14, - {NewQn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-12, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn12} = queue:out(Qn12), - {Value, - {Pc, Qsn14, - {Qn13, NewQn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-11, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn11} = queue:out(Qn11), - {Value, - {Pc, Qsn14, - {Qn13, Qn12, NewQn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-10, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn10} = queue:out(Qn10), - {Value, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, NewQn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-9, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn9} = queue:out(Qn9), - {Value, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, NewQn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-8, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn8} = queue:out(Qn8), - {Value, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, NewQn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-7, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, Qn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn7} = queue:out(Qn7), - {Value, - {Pc, Qsn14, - {Qn13, Qn12, Qn11, Qn10, Qn9, Qn8, NewQn7}, - Qsn1, Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-6, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn6} = queue:out(Qn6), - {Value, - {Pc, Qsn14, Qsn7, - {NewQn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-5, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn5} = queue:out(Qn5), - {Value, - {Pc, Qsn14, Qsn7, - {Qn6, NewQn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-4, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn4} = queue:out(Qn4), - {Value, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, NewQn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-3, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn3} = queue:out(Qn3), - {Value, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, NewQn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-2, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn2} = queue:out(Qn2), - {Value, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, NewQn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(-1, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQn1} = queue:out(Qn1), - {Value, - {Pc, Qsn14, Qsn7, - {Qn6, Qn5, Qn4, Qn3, Qn2, NewQn1}, - Q0, Qsp1, Qsp7, Qsp14}}; -out_specific(0, - {Pc, Qsn14, Qsn7, Qsn1, - Q0, Qsp1, Qsp7, Qsp14}) -> - {Value, NewQ0} = queue:out(Q0), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, - NewQ0, - Qsp1, Qsp7, Qsp14}}; -out_specific(1, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp1} = queue:out(Qp1), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {NewQp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}}; -out_specific(2, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp2} = queue:out(Qp2), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, NewQp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}}; -out_specific(3, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp3} = queue:out(Qp3), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, NewQp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}}; -out_specific(4, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp4} = queue:out(Qp4), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, NewQp4, Qp5, Qp6}, - Qsp7, Qsp14}}; -out_specific(5, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp5} = queue:out(Qp5), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, NewQp5, Qp6}, - Qsp7, Qsp14}}; -out_specific(6, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6}, - Qsp7, Qsp14}) -> - {Value, NewQp6} = queue:out(Qp6), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, NewQp6}, - Qsp7, Qsp14}}; -out_specific(7, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp7} = queue:out(Qp7), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {NewQp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}}; -out_specific(8, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp8} = queue:out(Qp8), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, NewQp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}}; -out_specific(9, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp9} = queue:out(Qp9), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, NewQp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}}; -out_specific(10, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp10} = queue:out(Qp10), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, NewQp10, Qp11, Qp12, Qp13}, - Qsp14}}; -out_specific(11, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp11} = queue:out(Qp11), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, NewQp11, Qp12, Qp13}, - Qsp14}}; -out_specific(12, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp12} = queue:out(Qp12), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, NewQp12, Qp13}, - Qsp14}}; -out_specific(13, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, Qp13}, - Qsp14}) -> - {Value, NewQp13} = queue:out(Qp13), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, - {Qp7, Qp8, Qp9, Qp10, Qp11, Qp12, NewQp13}, - Qsp14}}; -out_specific(14, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp14} = queue:out(Qp14), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {NewQp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}}; -out_specific(15, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp15} = queue:out(Qp15), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, NewQp15, Qp16, Qp17, Qp18, Qp19, Qp20}}}; -out_specific(16, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp16} = queue:out(Qp16), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, NewQp16, Qp17, Qp18, Qp19, Qp20}}}; -out_specific(17, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp17} = queue:out(Qp17), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, NewQp17, Qp18, Qp19, Qp20}}}; -out_specific(18, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp18} = queue:out(Qp18), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, NewQp18, Qp19, Qp20}}}; -out_specific(19, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp19} = queue:out(Qp19), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, NewQp19, Qp20}}}; -out_specific(20, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, Qp20}}) -> - {Value, NewQp20} = queue:out(Qp20), - {Value, - {Pc, Qsn14, Qsn7, Qsn1, Q0, Qsp1, Qsp7, - {Qp14, Qp15, Qp16, Qp17, Qp18, Qp19, NewQp20}}}. - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - --include("pqueue_test.hrl"). - -module_test_() -> - {timeout, ?TEST_TIMEOUT, [ - {"internal tests", ?_assertOk(test())} - ]}. - -long_test_() -> - test_condition([ - {"proper tests", ?_assert(pqueue_proper:qc_pq())} - ], ?CLOUDI_LONG_TEST_TIMEOUT). - --endif. - diff --git a/aoc2023/build/packages/pqueue/src/pqueue2.erl b/aoc2023/build/packages/pqueue/src/pqueue2.erl deleted file mode 100644 index bbdeaaf..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue2.erl +++ /dev/null @@ -1,483 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: -%%% -%%%------------------------------------------------------------------------ -%%% @doc -%%% ==Skew Heap Priority Queue.== -%%% Ulf Wiger suggested pursuing a skew heap as an optimal Erlang priority -%%% queue implementation. Unfortunately, testing has shown this solution to -%%% be more than 2 times slower than pqueue. -%%% @end -%%% -%%% MIT License -%%% -%%% Copyright (c) 2011-2020 Michael Truog <mjtruog at protonmail dot com> -%%% -%%% Permission is hereby granted, free of charge, to any person obtaining a -%%% copy of this software and associated documentation files (the "Software"), -%%% to deal in the Software without restriction, including without limitation -%%% the rights to use, copy, modify, merge, publish, distribute, sublicense, -%%% and/or sell copies of the Software, and to permit persons to whom the -%%% Software is furnished to do so, subject to the following conditions: -%%% -%%% The above copyright notice and this permission notice shall be included in -%%% all copies or substantial portions of the Software. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -%%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -%%% DEALINGS IN THE SOFTWARE. -%%% -%%% @author Michael Truog <mjtruog at protonmail dot com> -%%% @copyright 2011-2020 Michael Truog -%%% @version 2.0.1 {@date} {@time} -%%%------------------------------------------------------------------------ - --module(pqueue2). --author('mjtruog at protonmail dot com'). - -%% external interface --export([in/2, - in/3, - is_empty/1, - is_queue/1, - len/1, - new/0, - out/1, - out/2, - pout/1, - to_list/1, - test/0]). - -%%%------------------------------------------------------------------------ -%%% External interface functions -%%%------------------------------------------------------------------------ - --ifdef(ERLANG_OTP_VERSION_16). --type pqueue2() :: - empty | - {integer(), pqueue2(), pqueue2(), element, term()} | - {integer(), pqueue2(), pqueue2(), queue, queue()}. --else. --type pqueue2() :: - empty | - {integer(), pqueue2(), pqueue2(), element, term()} | - {integer(), pqueue2(), pqueue2(), queue, queue:queue()}. --endif. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of the 0 priority queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), pqueue2()) -> pqueue2(). - -in(Value, H) -> - in(Value, 0, H). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of a specific priority queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), integer(), pqueue2()) -> pqueue2(). - -in(Value, P, H) -> - merge({P, empty, empty, element, Value}, H). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue is empty.=== -%% @end -%%------------------------------------------------------------------------- - --spec is_empty(pqueue2()) -> 'true' | 'false'. - -is_empty(empty) -> - true; -is_empty({_, HL, HR, queue, Queue}) -> - is_empty(HL) andalso is_empty(HR) andalso queue:is_empty(Queue); -is_empty(_) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue type is as expected.=== -%% @end -%%------------------------------------------------------------------------- - --spec is_queue(pqueue2()) -> 'true' | 'false'. - -is_queue(empty) -> - true; -is_queue({P, _, _, element, _}) - when is_integer(P) -> - true; -is_queue({P, _, _, queue, Queue}) - when is_integer(P) -> - queue:is_queue(Queue); -is_queue(_) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Determine the length of a priority queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec len(pqueue2()) -> non_neg_integer(). - -len(H) -> - len(0, out(H)). -len(I, {empty, _}) -> - I; -len(I, {{value, _}, H}) -> - len(I + 1, out(H)). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Create a new priority queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec new() -> pqueue2(). - -new() -> - empty. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec out(pqueue2()) -> - {{'value', term()}, pqueue2()} | {'empty', pqueue2()}. - -out(empty) -> - {empty, empty}; -out({_, HL, HR, element, Value}) -> - {{value, Value}, merge(HL, HR)}; -out({P, HL, HR, queue, Queue}) -> - case queue:out(Queue) of - {{value, _} = Result, NewQueue} -> - {Result, {P, HL, HR, queue, NewQueue}}; - {empty, _} -> - out(merge(HL, HR)) - end. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item of a specific priority from the head of the queue.=== -%% @end -%%------------------------------------------------------------------------- - --spec out(integer(), pqueue2()) -> - {{'value', term()}, pqueue2()} | {'empty', pqueue2()}. - -out(_, empty) -> - {empty, empty}; -out(P, {P1, _, _, _, _} = H) when P < P1 -> - {empty, H}; -out(P, {P1, HL1, HR1, T, D}) when P > P1 -> - case out(P, HL1) of - {{value, _} = Result, HL2} -> - {Result, {P1, HL2, HR1, T, D}}; - {empty, HL2} -> - case out(P, HR1) of - {{value, _} = Result, HR2} -> - {Result, {P1, HL2, HR2, T, D}}; - {empty, HR2} -> - {empty, {P1, HL2, HR2, T, D}} - end - end; -out(P, {P, HL, HR, element, Value}) -> - {{value, Value}, merge(HL, HR)}; -out(P, {P, HL, HR, queue, Queue}) -> - case queue:out(Queue) of - {{value, _} = Result, NewQueue} -> - {Result, {P, HL, HR, queue, NewQueue}}; - {empty, _} -> - out(P, merge(HL, HR)) - end. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% Includes the priority in the return value. -%% @end -%%------------------------------------------------------------------------- - --spec pout(pqueue2()) -> - {{'value', term(), integer()}, pqueue2()} | {'empty', pqueue2()}. - -pout(empty) -> - {empty, empty}; -pout({P, HL, HR, element, Value}) -> - {{value, Value, P}, merge(HL, HR)}; -pout({P, HL, HR, queue, Queue}) -> - case queue:out(Queue) of - {{value, Value}, NewQueue} -> - {{value, Value, P}, {P, HL, HR, queue, NewQueue}}; - {empty, _} -> - pout(merge(HL, HR)) - end. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Convert the priority queue to a list.=== -%% @end -%%------------------------------------------------------------------------- - --spec to_list(pqueue2()) -> list(term()). - -to_list(H) -> - to_list([], out(H)). -to_list(L, {empty, _}) -> - lists:reverse(L); -to_list(L, {{value, Value}, H}) -> - to_list([Value | L], out(H)). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Regression test.=== -%% @end -%%------------------------------------------------------------------------- - -test() -> - Q0 = pqueue2:new(), - true = pqueue2:is_queue(Q0), - Q1 = pqueue2:in(20, 20, Q0), - Q2 = pqueue2:in(19, 19, Q1), - Q3 = pqueue2:in(18, 18, Q2), - Q4 = pqueue2:in(17, 17, Q3), - Q5 = pqueue2:in(16, 16, Q4), - Q6 = pqueue2:in(15, 15, Q5), - Q7 = pqueue2:in(14, 14, Q6), - Q8 = pqueue2:in(13, 13, Q7), - Q9 = pqueue2:in(12, 12, Q8), - Q10 = pqueue2:in(11, 11, Q9), - Q11 = pqueue2:in(10, 10, Q10), - Q12 = pqueue2:in(9, 9, Q11), - Q13 = pqueue2:in(8, 8, Q12), - Q14 = pqueue2:in(7, 7, Q13), - Q15 = pqueue2:in(6, 6, Q14), - Q16 = pqueue2:in(5, 5, Q15), - Q17 = pqueue2:in(4, 4, Q16), - Q18 = pqueue2:in(3, 3, Q17), - Q19 = pqueue2:in(2, 2, Q18), - Q20 = pqueue2:in(1, 1, Q19), - Q21 = pqueue2:in(0, 0, Q20), - Q22 = pqueue2:in(-1, -1, Q21), - Q23 = pqueue2:in(-2, -2, Q22), - Q24 = pqueue2:in(-3, -3, Q23), - Q25 = pqueue2:in(-4, -4, Q24), - Q26 = pqueue2:in(-5, -5, Q25), - Q27 = pqueue2:in(-6, -6, Q26), - Q28 = pqueue2:in(-7, -7, Q27), - Q29 = pqueue2:in(-8, -8, Q28), - Q30 = pqueue2:in(-9, -9, Q29), - Q31 = pqueue2:in(-10, -10, Q30), - Q32 = pqueue2:in(-11, -11, Q31), - Q33 = pqueue2:in(-12, -12, Q32), - Q34 = pqueue2:in(-13, -13, Q33), - Q35 = pqueue2:in(-14, -14, Q34), - Q36 = pqueue2:in(-15, -15, Q35), - Q37 = pqueue2:in(-16, -16, Q36), - Q38 = pqueue2:in(-17, -17, Q37), - Q39 = pqueue2:in(-18, -18, Q38), - Q40 = pqueue2:in(-19, -19, Q39), - Q41 = pqueue2:in(-20, -20, Q40), - Q42 = pqueue2:in(-20, -20, Q41), - Q43 = pqueue2:in(-19, -19, Q42), - Q44 = pqueue2:in(-18, -18, Q43), - Q45 = pqueue2:in(-17, -17, Q44), - Q46 = pqueue2:in(-16, -16, Q45), - Q47 = pqueue2:in(-15, -15, Q46), - Q48 = pqueue2:in(-14, -14, Q47), - Q49 = pqueue2:in(-13, -13, Q48), - Q50 = pqueue2:in(-12, -12, Q49), - Q51 = pqueue2:in(-11, -11, Q50), - Q52 = pqueue2:in(-10, -10, Q51), - Q53 = pqueue2:in(-9, -9, Q52), - Q54 = pqueue2:in(-8, -8, Q53), - Q55 = pqueue2:in(-7, -7, Q54), - Q56 = pqueue2:in(-6, -6, Q55), - Q57 = pqueue2:in(-5, -5, Q56), - Q58 = pqueue2:in(-4, -4, Q57), - Q59 = pqueue2:in(-3, -3, Q58), - Q60 = pqueue2:in(-2, -2, Q59), - Q61 = pqueue2:in(-1, -1, Q60), - Q62 = pqueue2:in(0, 0, Q61), - Q63 = pqueue2:in(1, 1, Q62), - Q64 = pqueue2:in(2, 2, Q63), - Q65 = pqueue2:in(3, 3, Q64), - Q66 = pqueue2:in(4, 4, Q65), - Q67 = pqueue2:in(5, 5, Q66), - Q68 = pqueue2:in(6, 6, Q67), - Q69 = pqueue2:in(7, 7, Q68), - Q70 = pqueue2:in(8, 8, Q69), - Q71 = pqueue2:in(9, 9, Q70), - Q72 = pqueue2:in(10, 10, Q71), - Q73 = pqueue2:in(11, 11, Q72), - Q74 = pqueue2:in(12, 12, Q73), - Q75 = pqueue2:in(13, 13, Q74), - Q76 = pqueue2:in(14, 14, Q75), - Q77 = pqueue2:in(15, 15, Q76), - Q78 = pqueue2:in(16, 16, Q77), - Q79 = pqueue2:in(17, 17, Q78), - Q80 = pqueue2:in(18, 18, Q79), - Q81 = pqueue2:in(19, 19, Q80), - Q82 = pqueue2:in(20, 20, Q81), - true = pqueue2:is_queue(Q82), - 82 = pqueue2:len(Q82), - [-20, -20, -19, -19, -18, -18, -17, -17, -16, -16, -15, -15, -14, -14, - -13, -13, -12, -12, -11, -11, -10, -10, -9, -9, -8, -8, -7, -7, -6, -6, - -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, - 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20] = pqueue2:to_list(Q82), - {{value, -20}, Q83} = pqueue2:out(Q82), - {{value, -20}, Q84} = pqueue2:out(Q83), - {{value, -19}, Q85} = pqueue2:out(Q84), - {{value, -19}, Q86} = pqueue2:out(Q85), - {{value, -18}, Q87} = pqueue2:out(Q86), - {{value, -18}, Q88} = pqueue2:out(Q87), - {{value, 0}, Q89} = pqueue2:out(0, Q88), - {{value, 0}, Q90} = pqueue2:out(0, Q89), - {empty, _} = pqueue2:out(0, Q90), - {{value, -17, -17}, Q91} = pqueue2:pout(Q90), - {{value, -17, -17}, Q92} = pqueue2:pout(Q91), - {{value, -16, -16}, Q93} = pqueue2:pout(Q92), - {{value, -16, -16}, Q94} = pqueue2:pout(Q93), - {{value, -15, -15}, Q95} = pqueue2:pout(Q94), - {{value, -15, -15}, Q96} = pqueue2:pout(Q95), - {{value, -14, -14}, Q97} = pqueue2:pout(Q96), - {{value, -14, -14}, Q98} = pqueue2:pout(Q97), - {{value, -13, -13}, Q99} = pqueue2:pout(Q98), - {{value, -13, -13}, Q100} = pqueue2:pout(Q99), - {{value, -12, -12}, Q101} = pqueue2:pout(Q100), - {{value, -12, -12}, Q102} = pqueue2:pout(Q101), - {{value, -11, -11}, Q103} = pqueue2:pout(Q102), - {{value, -11, -11}, Q104} = pqueue2:pout(Q103), - {{value, -10, -10}, Q105} = pqueue2:pout(Q104), - {{value, -10, -10}, Q106} = pqueue2:pout(Q105), - {{value, -9, -9}, Q107} = pqueue2:pout(Q106), - {{value, -9, -9}, Q108} = pqueue2:pout(Q107), - {{value, -8, -8}, Q109} = pqueue2:pout(Q108), - {{value, -8, -8}, Q110} = pqueue2:pout(Q109), - {{value, -7, -7}, Q111} = pqueue2:pout(Q110), - {{value, -7, -7}, Q112} = pqueue2:pout(Q111), - {{value, -6, -6}, Q113} = pqueue2:pout(Q112), - {{value, -6, -6}, Q114} = pqueue2:pout(Q113), - {{value, -5, -5}, Q115} = pqueue2:pout(Q114), - {{value, -5, -5}, Q116} = pqueue2:pout(Q115), - {{value, -4, -4}, Q117} = pqueue2:pout(Q116), - {{value, -4, -4}, Q118} = pqueue2:pout(Q117), - {{value, -3, -3}, Q119} = pqueue2:pout(Q118), - {{value, -3, -3}, Q120} = pqueue2:pout(Q119), - {{value, -2, -2}, Q121} = pqueue2:pout(Q120), - {{value, -2, -2}, Q122} = pqueue2:pout(Q121), - {{value, -1, -1}, Q123} = pqueue2:pout(Q122), - {{value, -1, -1}, Q124} = pqueue2:pout(Q123), - {{value, 1, 1}, Q125} = pqueue2:pout(Q124), - {{value, 1, 1}, Q126} = pqueue2:pout(Q125), - {{value, 2, 2}, Q127} = pqueue2:pout(Q126), - {{value, 2, 2}, Q128} = pqueue2:pout(Q127), - {{value, 3, 3}, Q129} = pqueue2:pout(Q128), - {{value, 3, 3}, Q130} = pqueue2:pout(Q129), - {{value, 4, 4}, Q131} = pqueue2:pout(Q130), - {{value, 4, 4}, Q132} = pqueue2:pout(Q131), - {{value, 5, 5}, Q133} = pqueue2:pout(Q132), - {{value, 5, 5}, Q134} = pqueue2:pout(Q133), - {{value, 6, 6}, Q135} = pqueue2:pout(Q134), - {{value, 6, 6}, Q136} = pqueue2:pout(Q135), - {{value, 7, 7}, Q137} = pqueue2:pout(Q136), - {{value, 7, 7}, Q138} = pqueue2:pout(Q137), - {{value, 8, 8}, Q139} = pqueue2:pout(Q138), - {{value, 8, 8}, Q140} = pqueue2:pout(Q139), - {{value, 9, 9}, Q141} = pqueue2:pout(Q140), - {{value, 9, 9}, Q142} = pqueue2:pout(Q141), - {{value, 10, 10}, Q143} = pqueue2:pout(Q142), - {{value, 10, 10}, Q144} = pqueue2:pout(Q143), - {{value, 11, 11}, Q145} = pqueue2:pout(Q144), - {{value, 11, 11}, Q146} = pqueue2:pout(Q145), - {{value, 12, 12}, Q147} = pqueue2:pout(Q146), - {{value, 12, 12}, Q148} = pqueue2:pout(Q147), - {{value, 13, 13}, Q149} = pqueue2:pout(Q148), - {{value, 13, 13}, Q150} = pqueue2:pout(Q149), - {{value, 14, 14}, Q151} = pqueue2:pout(Q150), - {{value, 14, 14}, Q152} = pqueue2:pout(Q151), - {{value, 15, 15}, Q153} = pqueue2:pout(Q152), - {{value, 15, 15}, Q154} = pqueue2:pout(Q153), - {{value, 16, 16}, Q155} = pqueue2:pout(Q154), - {{value, 16, 16}, Q156} = pqueue2:pout(Q155), - {{value, 17, 17}, Q157} = pqueue2:pout(Q156), - {{value, 17, 17}, Q158} = pqueue2:pout(Q157), - {{value, 18, 18}, Q159} = pqueue2:pout(Q158), - {{value, 18, 18}, Q160} = pqueue2:pout(Q159), - {{value, 19, 19}, Q161} = pqueue2:pout(Q160), - {{value, 19, 19}, Q162} = pqueue2:pout(Q161), - {{value, 20, 20}, Q163} = pqueue2:pout(Q162), - {{value, 20, 20}, Q164} = pqueue2:pout(Q163), - true = pqueue2:is_empty(Q164), - {empty, Q165} = pqueue2:pout(Q164), - true = pqueue2:is_empty(Q165), - % test case 1, based on proper testing - C1V0 = pqueue2:in(-18, pqueue2:new()), - C1V1 = pqueue2:in(9, C1V0), - C1V2 = pqueue2:in(-10, -4, C1V1), - C1V3 = pqueue2:in(-29, C1V2), - C1V4 = pqueue2:in(11, C1V3), - 5 = pqueue2:len(C1V4), - [-10, -18, 9, -29, 11] = pqueue2:to_list(C1V4), - % test case 2, based on proper testing - C2V0 = pqueue2:in(-4, -15, pqueue2:new()), - C2V1 = pqueue2:in(13, C2V0), - C2V2 = pqueue2:in(2, C2V1), - [-4, 13, 2] = to_list(C2V2), - ok. - -%%%------------------------------------------------------------------------ -%%% Private functions -%%%------------------------------------------------------------------------ - -merge(empty, empty) -> - empty; -merge(empty, {_, _, _, _, _} = H) -> - H; -merge({_, _, _, _, _} = H, empty) -> - H; -merge({P1, HL1, HR1, T, D}, {P2, _, _, _, _} = H2) when P1 < P2 -> - {P1, HL1, merge(HR1, H2), T, D}; -merge({P1, _, _, _, _} = H1, {P2, HL2, HR2, T, D}) when P1 > P2 -> - {P2, HL2, merge(H1, HR2), T, D}; -merge({P, HL1, HR1, element, Value1}, {P, HL2, HR2, element, Value2}) -> - {P, merge(HL1, HR1), merge(HL2, HR2), queue, - queue:from_list([Value2, Value1])}; -merge({P, HL1, HR1, queue, Queue}, {P, HL2, HR2, element, Value}) -> - {P, merge(HL1, HR1), merge(HL2, HR2), queue, queue:in(Value, Queue)}; -merge({P, HL1, HR1, element, Value}, {P, HL2, HR2, queue, Queue}) -> - {P, merge(HL1, HR1), merge(HL2, HR2), queue, queue:in(Value, Queue)}. - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - --include("pqueue_test.hrl"). - -module_test_() -> - {timeout, ?TEST_TIMEOUT, [ - {"internal tests", ?_assertOk(test())} - ]}. - -long_test_() -> - test_condition([ - {"proper tests", ?_assert(pqueue_proper:qc_pq2())} - ], ?CLOUDI_LONG_TEST_TIMEOUT). - --endif. - diff --git a/aoc2023/build/packages/pqueue/src/pqueue3.erl b/aoc2023/build/packages/pqueue/src/pqueue3.erl deleted file mode 100644 index 03b370a..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue3.erl +++ /dev/null @@ -1,404 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: -%%% -%%%------------------------------------------------------------------------ -%%% @doc -%%% ==A Large Priority Queue.== -%%% This priority queue implementation depends on layered tuples, so that tuple -%%% access times can be exploited for quick in/out priority queue operations -%%% when using 64 or more total priorities. This implementation was created -%%% to avoid the slowness within the priority queue used by -%%% both RabbitMQ and Riak -%%% (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -%%% @end -%%% -%%% MIT License -%%% -%%% Copyright (c) 2011-2020 Michael Truog <mjtruog at protonmail dot com> -%%% -%%% Permission is hereby granted, free of charge, to any person obtaining a -%%% copy of this software and associated documentation files (the "Software"), -%%% to deal in the Software without restriction, including without limitation -%%% the rights to use, copy, modify, merge, publish, distribute, sublicense, -%%% and/or sell copies of the Software, and to permit persons to whom the -%%% Software is furnished to do so, subject to the following conditions: -%%% -%%% The above copyright notice and this permission notice shall be included in -%%% all copies or substantial portions of the Software. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -%%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -%%% DEALINGS IN THE SOFTWARE. -%%% -%%% @author Michael Truog <mjtruog at protonmail dot com> -%%% @copyright 2011-2020 Michael Truog -%%% @version 2.0.1 {@date} {@time} -%%%------------------------------------------------------------------------ - --module(pqueue3). --author('mjtruog at protonmail dot com'). - -%% external interface --export([in/2, % O(1) - in/3, % O(1) - is_empty/1, % O(1) - is_queue/1, % O(1) - len/1, % O(N) - new/0, % O(1) - new/1, % O(1) - out/1, % O(1) amortized, O(N) worst case - out/2, % O(1) amortized, O(N) worst case - pout/1, % O(1) amortized, O(N) worst case - to_list/1]). % O(N) - -%%%------------------------------------------------------------------------ -%%% External interface functions -%%%------------------------------------------------------------------------ - --type pqueue3() :: {integer(), integer(), empty | integer(), tuple()}. --type pqueue3_empty() :: {integer(), integer(), empty, tuple()}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of the 0 priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), pqueue3()) -> pqueue3(). - -in(Value, Q) -> - in(Value, 0, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of a specific priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(term(), integer(), pqueue3()) -> pqueue3(). - -in(_, P, {Size, Offset, _, _}) - when (P + Offset) < 0; (P + Offset) > Size -> - erlang:exit(badarg); -in(Value, P, {Size, Offset, empty, Bins}) -> - PriorityIndex = P + Offset, - {Size, Offset, PriorityIndex, - in_queue(layer_indexes(Size, PriorityIndex), Value, Bins)}; -in(Value, P, {Size, Offset, I, Bins}) - when (P + Offset) < I -> - PriorityIndex = P + Offset, - {Size, Offset, PriorityIndex, - in_queue(layer_indexes(Size, PriorityIndex), Value, Bins)}; -in(Value, P, {Size, Offset, I, Bins}) -> - {Size, Offset, I, - in_queue(layer_indexes(Size, P + Offset), Value, Bins)}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue is empty.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_empty(pqueue3()) -> 'true' | 'false'. - -is_empty({_, _, empty, _}) -> - true; -is_empty({_, _, _, _} = Q) -> - case out(Q) of - {empty, _} -> - true; - {{value, _}, _} -> - false - end. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue type is as expected.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_queue(pqueue3()) -> 'true' | 'false'. - -is_queue({Size, Offset, I, Bins}) - when is_integer(Size), is_integer(Offset), is_tuple(Bins) -> - (I =:= empty) or is_integer(I); -is_queue(_) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Determine the length of a priority queue.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec len(pqueue3()) -> non_neg_integer(). - -len(Q) -> - len(0, out(Q)). -len(I, {empty, _}) -> - I; -len(I, {{value, _}, Q}) -> - len(I + 1, out(Q)). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Create a new priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec new() -> pqueue3_empty(). - -new() -> - new([]). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Create a new priority queue with customization options.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec new(list({atom(), term()})) -> pqueue3(). - -new(Options) -> - Size = proplists:get_value(priorities, Options, 256), - MiddleZero = proplists:get_value(middle_priority_zero, Options, true), - Offset = if - MiddleZero =:= true -> - erlang:round((Size / 2) + 0.5) - 1; - true -> - 0 - end, - {Size, Offset, empty, create(layer_sizes(Size))}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(pqueue3()) -> - {{'value', term()}, pqueue3()} | {'empty', pqueue3()}. - -out({_, _, empty, _} = Q) -> - {empty, Q}; -out({Size, Offset, I, Bins}) -> - {Result, NewI, NewBins} = out_check( - I, Size, out_queue(layer_indexes(Size, I), Bins) - ), - {Result, {Size, Offset, NewI, NewBins}}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item of a specific priority from the head of the queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(integer(), pqueue3()) -> - {{'value', term()}, pqueue3()} | {'empty', pqueue3()}. - -out(P, {Size, Offset, _, _}) - when (P + Offset) < 0; (P + Offset) > Size -> - erlang:exit(badarg); -out(_, {_, _, empty, _} = Q) -> - {empty, Q}; -out(P, {Size, Offset, I, Bins}) -> - {Result, NewBins} = out_queue(layer_indexes(Size, P + Offset), Bins), - {Result, {Size, Offset, I, NewBins}}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% Includes the priority in the return value. -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec pout(pqueue3()) -> - {{'value', term(), integer()}, pqueue3()} | {'empty', pqueue3()}. - -pout({_, _, empty, _} = Q) -> - {empty, Q}; -pout({Size, Offset, I, Bins}) -> - {Result, NewI, NewBins} = pout_check( - I, Size, Offset, out_queue(layer_indexes(Size, I), Bins) - ), - {Result, {Size, Offset, NewI, NewBins}}. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Convert the priority queue to a list.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec to_list(pqueue3()) -> list(term()). - -to_list(Q) -> - to_list([], out(Q)). -to_list(L, {empty, _}) -> - lists:reverse(L); -to_list(L, {{value, Value}, Q}) -> - to_list([Value | L], out(Q)). - -%%%------------------------------------------------------------------------ -%%% Private functions -%%%------------------------------------------------------------------------ - -create([]) -> - queue:new(); - -create([I | Is]) -> - erlang:make_tuple(I + 1, create(Is)). - -in_queue({I1}, Value, Bins1) -> - erlang:setelement(I1, Bins1, queue:in(Value, erlang:element(I1, Bins1))); - -in_queue({I1, I2}, Value, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, queue:in(Value, erlang:element(I2, Bins2)))); - -in_queue({I1, I2, I3}, Value, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - Bins3 = erlang:element(I2, Bins2), - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, - erlang:setelement(I3, Bins3, queue:in(Value, erlang:element(I3, Bins3))))); - -in_queue({I1, I2, I3, I4}, Value, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - Bins3 = erlang:element(I2, Bins2), - Bins4 = erlang:element(I3, Bins3), - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, - erlang:setelement(I3, Bins3, - erlang:setelement(I4, Bins4, queue:in(Value, erlang:element(I4, Bins4)))))). - -pout_check(Size, Size, _, {empty, Bins}) -> - {empty, empty, Bins}; -pout_check(I, _, Offset, {{value, Value}, Bins}) -> - {{value, Value, I - Offset}, I, Bins}; -pout_check(I, Size, Offset, {empty, Bins}) -> - NewI = I + 1, - pout_check(NewI, Size, Offset, out_queue(layer_indexes(Size, NewI), Bins)). - -out_check(Size, Size, {empty, Bins}) -> - {empty, empty, Bins}; -out_check(I, _, {{value, _} = Result, Bins}) -> - {Result, I, Bins}; -out_check(I, Size, {empty, Bins}) -> - NewI = I + 1, - out_check(NewI, Size, out_queue(layer_indexes(Size, NewI), Bins)). - -out_queue({I1}, Bins1) -> - {Result, NewQueue} = queue:out(erlang:element(I1, Bins1)), - {Result, - erlang:setelement(I1, Bins1, NewQueue)}; - -out_queue({I1, I2}, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - {Result, NewQueue} = queue:out(erlang:element(I2, Bins2)), - {Result, - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, NewQueue))}; - -out_queue({I1, I2, I3}, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - Bins3 = erlang:element(I2, Bins2), - {Result, NewQueue} = queue:out(erlang:element(I3, Bins3)), - {Result, - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, - erlang:setelement(I3, Bins3, NewQueue)))}; - -out_queue({I1, I2, I3, I4}, Bins1) -> - Bins2 = erlang:element(I1, Bins1), - Bins3 = erlang:element(I2, Bins2), - Bins4 = erlang:element(I3, Bins3), - {Result, NewQueue} = queue:out(erlang:element(I4, Bins4)), - {Result, - erlang:setelement(I1, Bins1, - erlang:setelement(I2, Bins2, - erlang:setelement(I3, Bins3, - erlang:setelement(I4, Bins4, NewQueue))))}. - -layer_indexes(Size, PriorityIndex) -> - if - Size =< 127 -> - {PriorityIndex + 1}; - Size =< 255 -> - <<I1:4, I2:4>> = <<PriorityIndex:8>>, - {I1 + 1, I2 + 1}; - Size =< 511 -> - <<I1:4, I2:5>> = <<PriorityIndex:9>>, - {I1 + 1, I2 + 1}; - Size =< 1023 -> - <<I1:3, I2:3, I3:4>> = <<PriorityIndex:10>>, - {I1 + 1, I2 + 1, I3 + 1}; - Size =< 2047 -> - <<I1:3, I2:4, I3:4>> = <<PriorityIndex:11>>, - {I1 + 1, I2 + 1, I3 + 1}; - Size =< 4095 -> - <<I1:4, I2:4, I3:4>> = <<PriorityIndex:12>>, - {I1 + 1, I2 + 1, I3 + 1}; - Size =< 8191 -> - <<I1:4, I2:4, I3:5>> = <<PriorityIndex:13>>, - {I1 + 1, I2 + 1, I3 + 1}; - Size =< 16383 -> - <<I1:4, I2:5, I3:5>> = <<PriorityIndex:14>>, - {I1 + 1, I2 + 1, I3 + 1}; - Size =< 32767 -> - <<I1:3, I2:4, I3:4, I4:4>> = <<PriorityIndex:15>>, - {I1 + 1, I2 + 1, I3 + 1, I4 + 1}; - Size =< 65535 -> - <<I1:4, I2:4, I3:4, I4:4>> = <<PriorityIndex:16>>, - {I1 + 1, I2 + 1, I3 + 1, I4 + 1} - end. - -layer_sizes(Size) -> - if - Size =< 127 -> - <<I1:7>> = <<127:7>>, - [I1]; - Size =< 255 -> - <<I1:4, I2:4>> = <<255:8>>, - [I1, I2]; - Size =< 511 -> - <<I1:4, I2:5>> = <<511:9>>, - [I1, I2]; - Size =< 1023 -> - <<I1:3, I2:3, I3:4>> = <<1023:10>>, - [I1, I2, I3]; - Size =< 2047 -> - <<I1:3, I2:4, I3:4>> = <<2047:11>>, - [I1, I2, I3]; - Size =< 4095 -> - <<I1:4, I2:4, I3:4>> = <<4095:12>>, - [I1, I2, I3]; - Size =< 8191 -> - <<I1:4, I2:4, I3:5>> = <<8191:13>>, - [I1, I2, I3]; - Size =< 16383 -> - <<I1:4, I2:5, I3:5>> = <<16383:14>>, - [I1, I2, I3]; - Size =< 32767 -> - <<I1:3, I2:4, I3:4, I4:4>> = <<32767:15>>, - [I1, I2, I3, I4]; - Size =< 65535 -> - <<I1:4, I2:4, I3:4, I4:4>> = <<65535:16>>, - [I1, I2, I3, I4] - end. - diff --git a/aoc2023/build/packages/pqueue/src/pqueue4.erl b/aoc2023/build/packages/pqueue/src/pqueue4.erl deleted file mode 100644 index 30b188d..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue4.erl +++ /dev/null @@ -1,11662 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: -%%% -%%%------------------------------------------------------------------------ -%%% @doc -%%% ==Static Priority Queue.== -%%% This priority queue implementation depends on a static number of priorities -%%% (-128 (high) to 128 (low)) so that tuple access times can be exploited for -%%% quick in/out priority queue operations. This implementation was created to -%%% avoid the slowness within the priority queue used by both RabbitMQ and Riak -%%% (https://github.com/basho/riak_core/blob/master/src/priority_queue.erl). -%%% @end -%%% -%%% MIT License -%%% -%%% Copyright (c) 2011-2020 Michael Truog <mjtruog at protonmail dot com> -%%% -%%% Permission is hereby granted, free of charge, to any person obtaining a -%%% copy of this software and associated documentation files (the "Software"), -%%% to deal in the Software without restriction, including without limitation -%%% the rights to use, copy, modify, merge, publish, distribute, sublicense, -%%% and/or sell copies of the Software, and to permit persons to whom the -%%% Software is furnished to do so, subject to the following conditions: -%%% -%%% The above copyright notice and this permission notice shall be included in -%%% all copies or substantial portions of the Software. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -%%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -%%% DEALINGS IN THE SOFTWARE. -%%% -%%% -%%% queue_remove_unique/2 is based on queue:filter/2 -%%% which is under the Apache License 2.0: -%%% -%%% Copyright Ericsson AB 1996-2016. All Rights Reserved. -%%% -%%% Licensed under the Apache License, Version 2.0 (the "License"); -%%% you may not use this file except in compliance with the License. -%%% You may obtain a copy of the License at -%%% -%%% http://www.apache.org/licenses/LICENSE-2.0 -%%% -%%% Unless required by applicable law or agreed to in writing, software -%%% distributed under the License is distributed on an "AS IS" BASIS, -%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%%% See the License for the specific language governing permissions and -%%% limitations under the License. -%%% -%%% @author Michael Truog <mjtruog at protonmail dot com> -%%% @copyright 2011-2020 Michael Truog -%%% @version 2.0.1 {@date} {@time} -%%%------------------------------------------------------------------------ - --module(pqueue4). --author('mjtruog at protonmail dot com'). - -%% external interface --export([filter/2, % O(N) - filter/3, % O(N) - in/2, % O(1) - in/3, % O(1) - is_empty/1, % O(1) - is_queue/1, % O(1) - len/1, % O(1) - new/0, % O(1) - out/1, % O(1) amortized, O(N) worst case - out/2, % O(1) amortized, O(N) worst case - pout/1, % O(1) amortized, O(N) worst case - remove_unique/2, % O(N) but smaller constant than filter/2 - remove_unique/3, % O(N) but smaller constant than filter/3 - to_list/1, % O(N) - to_plist/1, % O(N) - test/0]). - -%%%------------------------------------------------------------------------ -%%% External interface functions -%%%------------------------------------------------------------------------ - --type priority() :: -128..128. --ifdef(ERLANG_OTP_VERSION_16). --type pqueue4(_) :: - {priority() | 'empty', % current priority - non_neg_integer(), % total size - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - queue(), - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}, - {queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue(), - queue(), queue(), queue(), queue(), queue(), queue(), queue(), queue()}}. --else. --type pqueue4(T) :: - {priority() | 'empty', % current priority - non_neg_integer(), % total size - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - queue:queue(T), - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}, - {queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T), - queue:queue(T), queue:queue(T), queue:queue(T), queue:queue(T)}}. --endif. --type pqueue4() :: pqueue4(any()). --export_type([pqueue4/0, pqueue4/1]). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Filter the priority queue.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec filter(fun((any()) -> boolean()), pqueue4()) -> pqueue4(). - -filter(F, {empty, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) - when is_function(F, 1) -> - Q; -filter(F, {Pc, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) - when is_function(F, 1) -> - filter_all(Pc, F, Q). - -filter_all(_, _, {_, 0, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _} = Q) -> - Q; -filter_all(128, F, Q) -> - filter_priority(128, F, Q); -filter_all(P, F, Q) when is_integer(P) -> - filter_all(P + 1, F, filter_priority(P, F, Q)). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Filter a specific priority within the priority queue.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec filter(fun((any()) -> boolean()), integer(), pqueue4()) -> pqueue4(). - -filter(_, P, _) - when P < -128; P > 128 -> - erlang:exit(badarg); -filter(F, P, Q) when is_function(F, 1) -> - filter_priority(P, F, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of the 0 priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(any(), pqueue4()) -> pqueue4(). - -in(X, Q) -> - in(X, 0, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Append an item to the tail of a specific priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec in(any(), integer(), pqueue4()) -> pqueue4(). - -in(_, P, _) - when P < -128; P > 128 -> - erlang:exit(badarg); -in(X, P, {empty, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - in_higher(P, Q, X); % (in a higher priority) -in(X, P, {Pc, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) - when P < Pc -> - in_higher(P, Q, X); % (in a higher priority) -in(X, P, Q) -> - in_lower(P, Q, X). % (in a lower priority) - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue is empty.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_empty(pqueue4()) -> 'true' | 'false'. - -is_empty({_, 0, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> - true; -is_empty({_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Check if the priority queue type is as expected.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec is_queue(pqueue4()) -> 'true' | 'false'. - -is_queue({Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) - when is_integer(Size), - tuple_size(Qn128) == 16, tuple_size(Qn112) == 16, - tuple_size(Qn96) == 16, tuple_size(Qn80) == 16, - tuple_size(Qn64) == 16, tuple_size(Qn48) == 16, - tuple_size(Qn32) == 16, tuple_size(Qn16) == 16, - tuple_size(Qp16) == 16, tuple_size(Qp32) == 16, - tuple_size(Qp48) == 16, tuple_size(Qp64) == 16, - tuple_size(Qp80) == 16, tuple_size(Qp96) == 16, - tuple_size(Qp112) == 16, tuple_size(Qp128) == 16 -> - (((Pc =:= empty) or is_integer(Pc)) and queue:is_queue(Q0)); -is_queue(_) -> - false. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Determine the length of a priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec len(pqueue4()) -> non_neg_integer(). - -len({_, Size, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _}) -> - Size. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Create a new priority queue.=== -%% O(1) -%% @end -%%------------------------------------------------------------------------- - --spec new() -> pqueue4(). - -new() -> - {empty, % current priority - 0, % current size - erlang:make_tuple(16, queue:new()), % priority [-128..-113] - erlang:make_tuple(16, queue:new()), % priority [-112.. -97] - erlang:make_tuple(16, queue:new()), % priority [ -96.. -81] - erlang:make_tuple(16, queue:new()), % priority [ -80.. -65] - erlang:make_tuple(16, queue:new()), % priority [ -64.. -49] - erlang:make_tuple(16, queue:new()), % priority [ -48.. -33] - erlang:make_tuple(16, queue:new()), % priority [ -32.. -17] - erlang:make_tuple(16, queue:new()), % priority [ -16.. -1] - queue:new(), % priority 0 (default) - erlang:make_tuple(16, queue:new()), % priority [ 1.. 16] - erlang:make_tuple(16, queue:new()), % priority [ 17.. 32] - erlang:make_tuple(16, queue:new()), % priority [ 33.. 48] - erlang:make_tuple(16, queue:new()), % priority [ 49.. 64] - erlang:make_tuple(16, queue:new()), % priority [ 65.. 80] - erlang:make_tuple(16, queue:new()), % priority [ 81.. 96] - erlang:make_tuple(16, queue:new()), % priority [ 97.. 112] - erlang:make_tuple(16, queue:new())}. % priority [ 113.. 128] - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(pqueue4()) -> - {{'value', any()}, pqueue4()} | {'empty', pqueue4()}. - -out({empty, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -out({Pc, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - out_current(Pc, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item of a specific priority from the head of the queue.=== -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec out(integer(), pqueue4()) -> - {{'value', any()}, pqueue4()} | {'empty', pqueue4()}. - -out(P, _) - when P < -128; P > 128 -> - erlang:exit(badarg); -out(_, {empty, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -out(P, Q) -> - out_specific(P, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Take an item from the head of the priority queue.=== -%% Includes the priority in the return value. -%% O(1) amortized, O(N) worst case -%% @end -%%------------------------------------------------------------------------- - --spec pout(pqueue4()) -> - {{'value', any(), integer()}, pqueue4()} | {'empty', pqueue4()}. - -pout({empty, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - {empty, Q}; -pout({Pc, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} = Q) -> - out_current_p(Pc, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Remove a unique value from the priority queue with a binary predicate.=== -%% O(N) but smaller constant than filter/2 -%% @end -%%------------------------------------------------------------------------- - --spec remove_unique(fun((any()) -> boolean()), pqueue4()) -> - {boolean(), pqueue4()}. - -remove_unique(F, {_, 0, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _} = Q) - when is_function(F, 1) -> - {false, Q}; -remove_unique(F, {Pc, _, _, _, _, _, _, _, _, _, - _, _, _, _, _, _, _, _, _} = Q) - when is_function(F, 1) -> - remove_unique_all(Pc, F, Q). - -remove_unique_all(128, F, Q) -> - remove_unique_p(128, F, Q); -remove_unique_all(P, F, Q) when is_integer(P) -> - case remove_unique_p(P, F, Q) of - {true, _} = Result -> - Result; - {false, Q} -> - remove_unique_all(P + 1, F, Q) - end. - -%%------------------------------------------------------------------------- -%% @doc -%% ===Remove a unique value in a specific priority within the priority queue with a binary predicate.=== -%% O(N) but smaller constant than filter/3 -%% @end -%%------------------------------------------------------------------------- - --spec remove_unique(fun((any()) -> boolean()), integer(), pqueue4()) -> - {boolean(), pqueue4()}. - -remove_unique(_, P, _) - when P < -128; P > 128 -> - erlang:exit(badarg); -remove_unique(F, P, Q) when is_function(F, 1) -> - remove_unique_p(P, F, Q). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Convert the priority queue to a list.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec to_list(pqueue4()) -> list(). - -to_list(Q) -> - to_list([], out(Q)). -to_list(L, {empty, _}) -> - lists:reverse(L); -to_list(L, {{value, Value}, Q}) -> - to_list([Value | L], out(Q)). - -%%------------------------------------------------------------------------- -%% @doc -%% ===Convert the priority queue to a list with priorities.=== -%% O(N) -%% @end -%%------------------------------------------------------------------------- - --spec to_plist(pqueue4()) -> list({priority(), list()}). - -to_plist(Q) -> - to_plist([], [], undefined, pout(Q)). -to_plist(L, [], _, {empty, _}) -> - lists:reverse(L); -to_plist(L, Lp, Pc, {empty, _}) -> - lists:reverse([{Pc, lists:reverse(Lp)} | L]); -to_plist(L, Lp, Pc, {{value, Value, Pc}, Q}) -> - to_plist(L, [Value | Lp], Pc, pout(Q)); -to_plist(L, [], _, {{value, Value, Pc}, Q}) -> - to_plist(L, [Value], Pc, pout(Q)); -to_plist(L, Lp, P, {{value, Value, Pc}, Q}) -> - to_plist([{P, lists:reverse(Lp)} | L], [Value], Pc, pout(Q)). - -%%------------------------------------------------------------------------- -%% @private -%% @doc -%% ===Regression test.=== -%% @end -%%------------------------------------------------------------------------- - -test() -> - Q0 = pqueue4:new(), - true = pqueue4:is_queue(Q0), - Q1 = pqueue4:in(20, 20, Q0), - Q2 = pqueue4:in(19, 19, Q1), - Q3 = pqueue4:in(18, 18, Q2), - Q4 = pqueue4:in(17, 17, Q3), - Q5 = pqueue4:in(16, 16, Q4), - Q6 = pqueue4:in(15, 15, Q5), - Q7 = pqueue4:in(14, 14, Q6), - Q8 = pqueue4:in(13, 13, Q7), - Q9 = pqueue4:in(12, 12, Q8), - Q10 = pqueue4:in(11, 11, Q9), - Q11 = pqueue4:in(10, 10, Q10), - Q12 = pqueue4:in(9, 9, Q11), - Q13 = pqueue4:in(8, 8, Q12), - Q14 = pqueue4:in(7, 7, Q13), - Q15 = pqueue4:in(6, 6, Q14), - Q16 = pqueue4:in(5, 5, Q15), - Q17 = pqueue4:in(4, 4, Q16), - Q18 = pqueue4:in(3, 3, Q17), - Q19 = pqueue4:in(2, 2, Q18), - Q20 = pqueue4:in(1, 1, Q19), - Q21 = pqueue4:in(0, 0, Q20), - Q22 = pqueue4:in(-1, -1, Q21), - Q23 = pqueue4:in(-2, -2, Q22), - Q24 = pqueue4:in(-3, -3, Q23), - Q25 = pqueue4:in(-4, -4, Q24), - Q26 = pqueue4:in(-5, -5, Q25), - Q27 = pqueue4:in(-6, -6, Q26), - Q28 = pqueue4:in(-7, -7, Q27), - Q29 = pqueue4:in(-8, -8, Q28), - Q30 = pqueue4:in(-9, -9, Q29), - Q31 = pqueue4:in(-10, -10, Q30), - Q32 = pqueue4:in(-11, -11, Q31), - Q33 = pqueue4:in(-12, -12, Q32), - Q34 = pqueue4:in(-13, -13, Q33), - Q35 = pqueue4:in(-14, -14, Q34), - Q36 = pqueue4:in(-15, -15, Q35), - Q37 = pqueue4:in(-16, -16, Q36), - Q38 = pqueue4:in(-17, -17, Q37), - Q39 = pqueue4:in(-18, -18, Q38), - Q40 = pqueue4:in(-19, -19, Q39), - Q41 = pqueue4:in(-20, -20, Q40), - Q42 = pqueue4:in(-20, -20, Q41), - Q43 = pqueue4:in(-19, -19, Q42), - Q44 = pqueue4:in(-18, -18, Q43), - Q45 = pqueue4:in(-17, -17, Q44), - Q46 = pqueue4:in(-16, -16, Q45), - Q47 = pqueue4:in(-15, -15, Q46), - Q48 = pqueue4:in(-14, -14, Q47), - Q49 = pqueue4:in(-13, -13, Q48), - Q50 = pqueue4:in(-12, -12, Q49), - Q51 = pqueue4:in(-11, -11, Q50), - Q52 = pqueue4:in(-10, -10, Q51), - Q53 = pqueue4:in(-9, -9, Q52), - Q54 = pqueue4:in(-8, -8, Q53), - Q55 = pqueue4:in(-7, -7, Q54), - Q56 = pqueue4:in(-6, -6, Q55), - Q57 = pqueue4:in(-5, -5, Q56), - Q58 = pqueue4:in(-4, -4, Q57), - Q59 = pqueue4:in(-3, -3, Q58), - Q60 = pqueue4:in(-2, -2, Q59), - Q61 = pqueue4:in(-1, -1, Q60), - Q62 = pqueue4:in(0, 0, Q61), - Q63 = pqueue4:in(1, 1, Q62), - Q64 = pqueue4:in(2, 2, Q63), - Q65 = pqueue4:in(3, 3, Q64), - Q66 = pqueue4:in(4, 4, Q65), - Q67 = pqueue4:in(5, 5, Q66), - Q68 = pqueue4:in(6, 6, Q67), - Q69 = pqueue4:in(7, 7, Q68), - Q70 = pqueue4:in(8, 8, Q69), - Q71 = pqueue4:in(9, 9, Q70), - Q72 = pqueue4:in(10, 10, Q71), - Q73 = pqueue4:in(11, 11, Q72), - Q74 = pqueue4:in(12, 12, Q73), - Q75 = pqueue4:in(13, 13, Q74), - Q76 = pqueue4:in(14, 14, Q75), - Q77 = pqueue4:in(15, 15, Q76), - Q78 = pqueue4:in(16, 16, Q77), - Q79 = pqueue4:in(17, 17, Q78), - Q80 = pqueue4:in(18, 18, Q79), - Q81 = pqueue4:in(19, 19, Q80), - Q82 = pqueue4:in(20, 20, Q81), - true = pqueue4:is_queue(Q82), - 82 = pqueue4:len(Q82), - [-20, -20, -19, -19, -18, -18, -17, -17, -16, -16, -15, -15, -14, -14, - -13, -13, -12, -12, -11, -11, -10, -10, -9, -9, -8, -8, -7, -7, -6, -6, - -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, - 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20] = pqueue4:to_list(Q82), - [{-20, [-20, -20]}, {-19, [-19, -19]}, {-18, [-18, -18]}, - {-17, [-17, -17]}, {-16, [-16, -16]}, {-15, [-15, -15]}, - {-14, [-14, -14]}, {-13, [-13, -13]}, {-12, [-12, -12]}, - {-11, [-11, -11]}, {-10, [-10, -10]}, {-9, [-9, -9]}, - {-8, [-8, -8]}, {-7, [-7, -7]}, {-6, [-6, -6]}, - {-5, [-5, -5]}, {-4, [-4, -4]}, {-3, [-3, -3]}, - {-2, [-2, -2]}, {-1, [-1, -1]}, {0, [0, 0]}, - {1, [1, 1]}, {2, [2, 2]}, {3, [3, 3]}, - {4, [4, 4]}, {5, [5, 5]}, {6, [6, 6]}, - {7, [7, 7]}, {8, [8, 8]}, {9, [9, 9]}, - {10, [10, 10]}, {11, [11, 11]}, {12, [12, 12]}, - {13, [13, 13]}, {14, [14, 14]}, {15, [15, 15]}, - {16, [16, 16]}, {17, [17, 17]}, {18, [18, 18]}, - {19, [19, 19]}, {20, [20, 20]}] = pqueue4:to_plist(Q82), - {{value, -20}, Q83} = pqueue4:out(Q82), - {{value, -20}, Q84} = pqueue4:out(Q83), - {{value, -19}, Q85} = pqueue4:out(Q84), - {{value, -19}, Q86} = pqueue4:out(Q85), - {{value, -18}, Q87} = pqueue4:out(Q86), - {{value, -18}, Q88} = pqueue4:out(Q87), - {{value, 0}, Q89} = pqueue4:out(0, Q88), - {{value, 0}, Q90} = pqueue4:out(0, Q89), - {empty, _} = pqueue4:out(0, Q90), - {{value, -17, -17}, Q91} = pqueue4:pout(Q90), - {{value, -17, -17}, Q92} = pqueue4:pout(Q91), - {{value, -16, -16}, Q93} = pqueue4:pout(Q92), - {{value, -16, -16}, Q94} = pqueue4:pout(Q93), - {{value, -15, -15}, Q95} = pqueue4:pout(Q94), - {{value, -15, -15}, Q96} = pqueue4:pout(Q95), - {{value, -14, -14}, Q97} = pqueue4:pout(Q96), - {{value, -14, -14}, Q98} = pqueue4:pout(Q97), - {{value, -13, -13}, Q99} = pqueue4:pout(Q98), - {{value, -13, -13}, Q100} = pqueue4:pout(Q99), - {{value, -12, -12}, Q101} = pqueue4:pout(Q100), - {{value, -12, -12}, Q102} = pqueue4:pout(Q101), - {{value, -11, -11}, Q103} = pqueue4:pout(Q102), - {{value, -11, -11}, Q104} = pqueue4:pout(Q103), - {{value, -10, -10}, Q105} = pqueue4:pout(Q104), - {{value, -10, -10}, Q106} = pqueue4:pout(Q105), - {{value, -9, -9}, Q107} = pqueue4:pout(Q106), - {{value, -9, -9}, Q108} = pqueue4:pout(Q107), - {{value, -8, -8}, Q109} = pqueue4:pout(Q108), - {{value, -8, -8}, Q110} = pqueue4:pout(Q109), - {{value, -7, -7}, Q111} = pqueue4:pout(Q110), - {{value, -7, -7}, Q112} = pqueue4:pout(Q111), - {{value, -6, -6}, Q113} = pqueue4:pout(Q112), - {{value, -6, -6}, Q114} = pqueue4:pout(Q113), - {{value, -5, -5}, Q115} = pqueue4:pout(Q114), - {{value, -5, -5}, Q116} = pqueue4:pout(Q115), - {{value, -4, -4}, Q117} = pqueue4:pout(Q116), - {{value, -4, -4}, Q118} = pqueue4:pout(Q117), - {{value, -3, -3}, Q119} = pqueue4:pout(Q118), - {{value, -3, -3}, Q120} = pqueue4:pout(Q119), - {{value, -2, -2}, Q121} = pqueue4:pout(Q120), - {{value, -2, -2}, Q122} = pqueue4:pout(Q121), - {{value, -1, -1}, Q123} = pqueue4:pout(Q122), - {{value, -1, -1}, Q124} = pqueue4:pout(Q123), - {{value, 1, 1}, Q125} = pqueue4:pout(Q124), - {{value, 1, 1}, Q126} = pqueue4:pout(Q125), - {{value, 2, 2}, Q127} = pqueue4:pout(Q126), - {{value, 2, 2}, Q128} = pqueue4:pout(Q127), - {{value, 3, 3}, Q129} = pqueue4:pout(Q128), - {{value, 3, 3}, Q130} = pqueue4:pout(Q129), - {{value, 4, 4}, Q131} = pqueue4:pout(Q130), - {{value, 4, 4}, Q132} = pqueue4:pout(Q131), - {{value, 5, 5}, Q133} = pqueue4:pout(Q132), - {{value, 5, 5}, Q134} = pqueue4:pout(Q133), - {{value, 6, 6}, Q135} = pqueue4:pout(Q134), - {{value, 6, 6}, Q136} = pqueue4:pout(Q135), - {{value, 7, 7}, Q137} = pqueue4:pout(Q136), - {{value, 7, 7}, Q138} = pqueue4:pout(Q137), - {{value, 8, 8}, Q139} = pqueue4:pout(Q138), - {{value, 8, 8}, Q140} = pqueue4:pout(Q139), - {{value, 9, 9}, Q141} = pqueue4:pout(Q140), - {{value, 9, 9}, Q142} = pqueue4:pout(Q141), - {{value, 10, 10}, Q143} = pqueue4:pout(Q142), - {{value, 10, 10}, Q144} = pqueue4:pout(Q143), - {{value, 11, 11}, Q145} = pqueue4:pout(Q144), - {{value, 11, 11}, Q146} = pqueue4:pout(Q145), - {{value, 12, 12}, Q147} = pqueue4:pout(Q146), - {{value, 12, 12}, Q148} = pqueue4:pout(Q147), - {{value, 13, 13}, Q149} = pqueue4:pout(Q148), - {{value, 13, 13}, Q150} = pqueue4:pout(Q149), - {{value, 14, 14}, Q151} = pqueue4:pout(Q150), - {{value, 14, 14}, Q152} = pqueue4:pout(Q151), - {{value, 15, 15}, Q153} = pqueue4:pout(Q152), - {{value, 15, 15}, Q154} = pqueue4:pout(Q153), - {{value, 16, 16}, Q155} = pqueue4:pout(Q154), - {{value, 16, 16}, Q156} = pqueue4:pout(Q155), - {{value, 17, 17}, Q157} = pqueue4:pout(Q156), - {{value, 17, 17}, Q158} = pqueue4:pout(Q157), - {{value, 18, 18}, Q159} = pqueue4:pout(Q158), - {{value, 18, 18}, Q160} = pqueue4:pout(Q159), - {{value, 19, 19}, Q161} = pqueue4:pout(Q160), - {{value, 19, 19}, Q162} = pqueue4:pout(Q161), - {{value, 20, 20}, Q163} = pqueue4:pout(Q162), - {{value, 20, 20}, Q164} = pqueue4:pout(Q163), - {{value, 20}, Q164} = pqueue4:out(Q163), - {{value, 20}, Q164} = pqueue4:out(20, Q163), - true = pqueue4:is_empty(Q164), - empty = erlang:element(1, Q164), % current priority - 0 = erlang:element(2, Q164), % size - {empty, Q164} = pqueue4:pout(Q164), - {empty, Q164} = pqueue4:out(Q164), - {empty, Q164} = pqueue4:out(20, Q164), - - Queue0 = queue:new(), - "{[],[]}" = lists:flatten(io_lib:format("~p", [Queue0])), - Queue1 = queue:in(1, Queue0), - Queue2 = queue:in(2, Queue1), - Queue3 = queue:in(3, Queue2), - {{value, 1}, _} = queue:out(Queue2), - "{[3,2],[1]}" = lists:flatten(io_lib:format("~p", [Queue3])), - {true, {[3],[1]}} = queue_remove_unique(fun(I) -> I == 2 end, {[3,2],[1]}), - Queue4 = queue:filter(fun(I) -> not (I == 2) end, Queue3), - "{[3],[1]}" = lists:flatten(io_lib:format("~p", [Queue4])), - 2 = queue:len(Queue4), - {{value, 1}, _} = queue:out(Queue4), - [1, 3] = queue:to_list(Queue4), - - Q166 = pqueue4:new(), - true = pqueue4:is_queue(Q166), - Q167 = pqueue4:in(6, 1, Q166), - Q168 = pqueue4:in(7, 1, Q167), - Q169 = pqueue4:in(8, 1, Q168), - Q170 = pqueue4:in(3, 0, Q169), - Q171 = pqueue4:in(4, 0, Q170), - Q172 = pqueue4:in(5, 0, Q171), - Q173 = pqueue4:in(0, -1, Q172), - Q174 = pqueue4:in(1, -1, Q173), - Q175 = pqueue4:in(2, -1, Q174), - [{-1, [0, 1, 2]}, {0, [3, 4, 5]}, {1, [6, 7, 8]}] = pqueue4:to_plist(Q175), - 3 = pqueue4:len(pqueue4:filter(fun(I) -> I > 5 end, Q175)), - 3 = pqueue4:len(pqueue4:filter(fun(I) -> I < 3 end, Q175)), - 3 = pqueue4:len(pqueue4:filter(fun(I) -> (I < 1) orelse (I > 6) end, Q175)), - {true, Q176} = pqueue4:remove_unique(fun(I) -> I == 4 end, Q175), - [{-1, [0, 1, 2]}, {0, [3, 5]}, {1, [6, 7, 8]}] = pqueue4:to_plist(Q176), - {true, Q177} = pqueue4:remove_unique(fun(I) -> I == 1 end, Q176), - [{-1, [0, 2]}, {0, [3, 5]}, {1, [6, 7, 8]}] = pqueue4:to_plist(Q177), - {true, Q178} = pqueue4:remove_unique(fun(I) -> I == 7 end, Q177), - [{-1, [0, 2]}, {0, [3, 5]}, {1, [6, 8]}] = pqueue4:to_plist(Q178), - 6 = pqueue4:len(Q178), - {{value, 0, -1}, Q179} = pqueue4:pout(Q178), - {{value, 2}, Q180} = pqueue4:out(Q179), - {{value, 6}, Q181} = pqueue4:out(1, Q180), - {false, Q181} = pqueue4:remove_unique(fun(I) -> I == 7 end, Q181), - [{0, [3, 5]}, {1, [8]}] = pqueue4:to_plist(Q181), - {true, Q182} = pqueue4:remove_unique(fun(I) -> I == 5 end, Q181), - {true, Q183} = pqueue4:remove_unique(fun(I) -> I == 8 end, 1, Q182), - {true, Q184} = pqueue4:remove_unique(fun(I) -> I == 3 end, Q183), - {empty, Q184} = pqueue4:pout(Q184), - {empty, Q184} = pqueue4:out(Q184), - {empty, Q184} = pqueue4:out(0, Q184), - ok. - -%%%------------------------------------------------------------------------ -%%% Private functions -%%%------------------------------------------------------------------------ - -%% @hidden --define(FILTER_P_Qn128(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - V3, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn112(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, - V3, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn96(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, - V3, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn80(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, - V3, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn64(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, - V3, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn48(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, - V3, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn32(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V3, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qn16(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V3, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qp16(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V3, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qp32(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V3, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qp48(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V3, - Qp64, Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qp64(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V3, - Qp80, Qp96, Qp112, Qp128}). --define(FILTER_P_Qp80(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V3, - Qp96, Qp112, Qp128}). --define(FILTER_P_Qp96(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V3, - Qp112, Qp128}). --define(FILTER_P_Qp112(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V3, - Qp128}). --define(FILTER_P_Qp128(P, V1, V2, V3), -filter_priority(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}) -> - V2 = queue:filter(F, V1), - NewSize = Size - (queue:len(V1) - queue:len(V2)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V3}). - -?FILTER_P_Qn128(-128, - Qn128, NewQn128, - {NewQn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-127, - Qn127, NewQn127, - {Qn128, NewQn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-126, - Qn126, NewQn126, - {Qn128, Qn127, NewQn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-125, - Qn125, NewQn125, - {Qn128, Qn127, Qn126, NewQn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-124, - Qn124, NewQn124, - {Qn128, Qn127, Qn126, Qn125, NewQn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-123, - Qn123, NewQn123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - NewQn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-122, - Qn122, NewQn122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, NewQn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-121, - Qn121, NewQn121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, NewQn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-120, - Qn120, NewQn120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, NewQn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-119, - Qn119, NewQn119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, NewQn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-118, - Qn118, NewQn118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, NewQn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-117, - Qn117, NewQn117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - NewQn117, Qn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-116, - Qn116, NewQn116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, NewQn116, Qn115, Qn114, Qn113}); -?FILTER_P_Qn128(-115, - Qn115, NewQn115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, NewQn115, Qn114, Qn113}); -?FILTER_P_Qn128(-114, - Qn114, NewQn114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, NewQn114, Qn113}); -?FILTER_P_Qn128(-113, - Qn113, NewQn113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, NewQn113}); -?FILTER_P_Qn112(-112, - Qn112, NewQn112, - {NewQn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-111, - Qn111, NewQn111, - {Qn112, NewQn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-110, - Qn110, NewQn110, - {Qn112, Qn111, NewQn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-109, - Qn109, NewQn109, - {Qn112, Qn111, Qn110, NewQn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-108, - Qn108, NewQn108, - {Qn112, Qn111, Qn110, Qn109, NewQn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-107, - Qn107, NewQn107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - NewQn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-106, - Qn106, NewQn106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, NewQn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-105, - Qn105, NewQn105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, NewQn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-104, - Qn104, NewQn104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, NewQn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-103, - Qn103, NewQn103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, NewQn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-102, - Qn102, NewQn102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, NewQn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-101, - Qn101, NewQn101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - NewQn101, Qn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-100, - Qn100, NewQn100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, NewQn100, Qn99, Qn98, Qn97}); -?FILTER_P_Qn112(-99, - Qn99, NewQn99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, NewQn99, Qn98, Qn97}); -?FILTER_P_Qn112(-98, - Qn98, NewQn98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, NewQn98, Qn97}); -?FILTER_P_Qn112(-97, - Qn97, NewQn97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, NewQn97}); -?FILTER_P_Qn96(-96, - Qn96, NewQn96, - {NewQn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-95, - Qn95, NewQn95, - {Qn96, NewQn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-94, - Qn94, NewQn94, - {Qn96, Qn95, NewQn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-93, - Qn93, NewQn93, - {Qn96, Qn95, Qn94, NewQn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-92, - Qn92, NewQn92, - {Qn96, Qn95, Qn94, Qn93, NewQn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-91, - Qn91, NewQn91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - NewQn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-90, - Qn90, NewQn90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, NewQn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-89, - Qn89, NewQn89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, NewQn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-88, - Qn88, NewQn88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, NewQn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-87, - Qn87, NewQn87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, NewQn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-86, - Qn86, NewQn86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, NewQn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-85, - Qn85, NewQn85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - NewQn85, Qn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-84, - Qn84, NewQn84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, NewQn84, Qn83, Qn82, Qn81}); -?FILTER_P_Qn96(-83, - Qn83, NewQn83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, NewQn83, Qn82, Qn81}); -?FILTER_P_Qn96(-82, - Qn82, NewQn82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, NewQn82, Qn81}); -?FILTER_P_Qn96(-81, - Qn81, NewQn81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, NewQn81}); -?FILTER_P_Qn80(-80, - Qn80, NewQn80, - {NewQn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-79, - Qn79, NewQn79, - {Qn80, NewQn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-78, - Qn78, NewQn78, - {Qn80, Qn79, NewQn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-77, - Qn77, NewQn77, - {Qn80, Qn79, Qn78, NewQn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-76, - Qn76, NewQn76, - {Qn80, Qn79, Qn78, Qn77, NewQn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-75, - Qn75, NewQn75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - NewQn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-74, - Qn74, NewQn74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, NewQn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-73, - Qn73, NewQn73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, NewQn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-72, - Qn72, NewQn72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, NewQn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-71, - Qn71, NewQn71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, NewQn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-70, - Qn70, NewQn70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, NewQn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-69, - Qn69, NewQn69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - NewQn69, Qn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-68, - Qn68, NewQn68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, NewQn68, Qn67, Qn66, Qn65}); -?FILTER_P_Qn80(-67, - Qn67, NewQn67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, NewQn67, Qn66, Qn65}); -?FILTER_P_Qn80(-66, - Qn66, NewQn66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, NewQn66, Qn65}); -?FILTER_P_Qn80(-65, - Qn65, NewQn65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, NewQn65}); -?FILTER_P_Qn64(-64, - Qn64, NewQn64, - {NewQn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-63, - Qn63, NewQn63, - {Qn64, NewQn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-62, - Qn62, NewQn62, - {Qn64, Qn63, NewQn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-61, - Qn61, NewQn61, - {Qn64, Qn63, Qn62, NewQn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-60, - Qn60, NewQn60, - {Qn64, Qn63, Qn62, Qn61, NewQn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-59, - Qn59, NewQn59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - NewQn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-58, - Qn58, NewQn58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, NewQn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-57, - Qn57, NewQn57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, NewQn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-56, - Qn56, NewQn56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, NewQn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-55, - Qn55, NewQn55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, NewQn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-54, - Qn54, NewQn54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, NewQn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-53, - Qn53, NewQn53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - NewQn53, Qn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-52, - Qn52, NewQn52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, NewQn52, Qn51, Qn50, Qn49}); -?FILTER_P_Qn64(-51, - Qn51, NewQn51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, NewQn51, Qn50, Qn49}); -?FILTER_P_Qn64(-50, - Qn50, NewQn50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, NewQn50, Qn49}); -?FILTER_P_Qn64(-49, - Qn49, NewQn49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, NewQn49}); -?FILTER_P_Qn48(-48, - Qn48, NewQn48, - {NewQn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-47, - Qn47, NewQn47, - {Qn48, NewQn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-46, - Qn46, NewQn46, - {Qn48, Qn47, NewQn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-45, - Qn45, NewQn45, - {Qn48, Qn47, Qn46, NewQn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-44, - Qn44, NewQn44, - {Qn48, Qn47, Qn46, Qn45, NewQn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-43, - Qn43, NewQn43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - NewQn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-42, - Qn42, NewQn42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, NewQn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-41, - Qn41, NewQn41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, NewQn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-40, - Qn40, NewQn40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, NewQn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-39, - Qn39, NewQn39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, NewQn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-38, - Qn38, NewQn38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, NewQn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-37, - Qn37, NewQn37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - NewQn37, Qn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-36, - Qn36, NewQn36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, NewQn36, Qn35, Qn34, Qn33}); -?FILTER_P_Qn48(-35, - Qn35, NewQn35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, NewQn35, Qn34, Qn33}); -?FILTER_P_Qn48(-34, - Qn34, NewQn34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, NewQn34, Qn33}); -?FILTER_P_Qn48(-33, - Qn33, NewQn33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, NewQn33}); -?FILTER_P_Qn32(-32, - Qn32, NewQn32, - {NewQn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-31, - Qn31, NewQn31, - {Qn32, NewQn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-30, - Qn30, NewQn30, - {Qn32, Qn31, NewQn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-29, - Qn29, NewQn29, - {Qn32, Qn31, Qn30, NewQn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-28, - Qn28, NewQn28, - {Qn32, Qn31, Qn30, Qn29, NewQn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-27, - Qn27, NewQn27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - NewQn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-26, - Qn26, NewQn26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, NewQn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-25, - Qn25, NewQn25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, NewQn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-24, - Qn24, NewQn24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, NewQn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-23, - Qn23, NewQn23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, NewQn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-22, - Qn22, NewQn22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, NewQn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-21, - Qn21, NewQn21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - NewQn21, Qn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-20, - Qn20, NewQn20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, NewQn20, Qn19, Qn18, Qn17}); -?FILTER_P_Qn32(-19, - Qn19, NewQn19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, NewQn19, Qn18, Qn17}); -?FILTER_P_Qn32(-18, - Qn18, NewQn18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, NewQn18, Qn17}); -?FILTER_P_Qn32(-17, - Qn17, NewQn17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, NewQn17}); -?FILTER_P_Qn16(-16, - Qn16, NewQn16, - {NewQn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-15, - Qn15, NewQn15, - {Qn16, NewQn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-14, - Qn14, NewQn14, - {Qn16, Qn15, NewQn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-13, - Qn13, NewQn13, - {Qn16, Qn15, Qn14, NewQn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-12, - Qn12, NewQn12, - {Qn16, Qn15, Qn14, Qn13, NewQn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-11, - Qn11, NewQn11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - NewQn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-10, - Qn10, NewQn10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, NewQn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-9, - Qn9, NewQn9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, NewQn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-8, - Qn8, NewQn8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, NewQn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-7, - Qn7, NewQn7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, NewQn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-6, - Qn6, NewQn6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, NewQn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-5, - Qn5, NewQn5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - NewQn5, Qn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-4, - Qn4, NewQn4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, NewQn4, Qn3, Qn2, Qn1}); -?FILTER_P_Qn16(-3, - Qn3, NewQn3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, NewQn3, Qn2, Qn1}); -?FILTER_P_Qn16(-2, - Qn2, NewQn2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, NewQn2, Qn1}); -?FILTER_P_Qn16(-1, - Qn1, NewQn1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, NewQn1}); -filter_priority(0, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - NewQ0 = queue:filter(F, Q0), - NewSize = Size - (queue:len(Q0) - queue:len(NewQ0)), - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - NewQ0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}; -?FILTER_P_Qp16(1, - Qp1, NewQp1, - {NewQp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(2, - Qp2, NewQp2, - {Qp1, NewQp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(3, - Qp3, NewQp3, - {Qp1, Qp2, NewQp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(4, - Qp4, NewQp4, - {Qp1, Qp2, Qp3, NewQp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(5, - Qp5, NewQp5, - {Qp1, Qp2, Qp3, Qp4, NewQp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(6, - Qp6, NewQp6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - NewQp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(7, - Qp7, NewQp7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, NewQp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(8, - Qp8, NewQp8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, NewQp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(9, - Qp9, NewQp9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, NewQp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(10, - Qp10, NewQp10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, NewQp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(11, - Qp11, NewQp11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, NewQp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(12, - Qp12, NewQp12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - NewQp12, Qp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(13, - Qp13, NewQp13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, NewQp13, Qp14, Qp15, Qp16}); -?FILTER_P_Qp16(14, - Qp14, NewQp14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, NewQp14, Qp15, Qp16}); -?FILTER_P_Qp16(15, - Qp15, NewQp15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, NewQp15, Qp16}); -?FILTER_P_Qp16(16, - Qp16, NewQp16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, NewQp16}); -?FILTER_P_Qp32(17, - Qp17, NewQp17, - {NewQp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(18, - Qp18, NewQp18, - {Qp17, NewQp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(19, - Qp19, NewQp19, - {Qp17, Qp18, NewQp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(20, - Qp20, NewQp20, - {Qp17, Qp18, Qp19, NewQp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(21, - Qp21, NewQp21, - {Qp17, Qp18, Qp19, Qp20, NewQp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(22, - Qp22, NewQp22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - NewQp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(23, - Qp23, NewQp23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, NewQp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(24, - Qp24, NewQp24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, NewQp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(25, - Qp25, NewQp25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, NewQp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(26, - Qp26, NewQp26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, NewQp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(27, - Qp27, NewQp27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, NewQp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(28, - Qp28, NewQp28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - NewQp28, Qp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(29, - Qp29, NewQp29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, NewQp29, Qp30, Qp31, Qp32}); -?FILTER_P_Qp32(30, - Qp30, NewQp30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, NewQp30, Qp31, Qp32}); -?FILTER_P_Qp32(31, - Qp31, NewQp31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, NewQp31, Qp32}); -?FILTER_P_Qp32(32, - Qp32, NewQp32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, NewQp32}); -?FILTER_P_Qp48(33, - Qp33, NewQp33, - {NewQp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(34, - Qp34, NewQp34, - {Qp33, NewQp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(35, - Qp35, NewQp35, - {Qp33, Qp34, NewQp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(36, - Qp36, NewQp36, - {Qp33, Qp34, Qp35, NewQp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(37, - Qp37, NewQp37, - {Qp33, Qp34, Qp35, Qp36, NewQp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(38, - Qp38, NewQp38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - NewQp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(39, - Qp39, NewQp39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, NewQp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(40, - Qp40, NewQp40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, NewQp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(41, - Qp41, NewQp41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, NewQp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(42, - Qp42, NewQp42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, NewQp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(43, - Qp43, NewQp43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, NewQp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(44, - Qp44, NewQp44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - NewQp44, Qp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(45, - Qp45, NewQp45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, NewQp45, Qp46, Qp47, Qp48}); -?FILTER_P_Qp48(46, - Qp46, NewQp46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, NewQp46, Qp47, Qp48}); -?FILTER_P_Qp48(47, - Qp47, NewQp47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, NewQp47, Qp48}); -?FILTER_P_Qp48(48, - Qp48, NewQp48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, NewQp48}); -?FILTER_P_Qp64(49, - Qp49, NewQp49, - {NewQp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(50, - Qp50, NewQp50, - {Qp49, NewQp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(51, - Qp51, NewQp51, - {Qp49, Qp50, NewQp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(52, - Qp52, NewQp52, - {Qp49, Qp50, Qp51, NewQp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(53, - Qp53, NewQp53, - {Qp49, Qp50, Qp51, Qp52, NewQp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(54, - Qp54, NewQp54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - NewQp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(55, - Qp55, NewQp55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, NewQp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(56, - Qp56, NewQp56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, NewQp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(57, - Qp57, NewQp57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, NewQp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(58, - Qp58, NewQp58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, NewQp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(59, - Qp59, NewQp59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, NewQp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(60, - Qp60, NewQp60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - NewQp60, Qp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(61, - Qp61, NewQp61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, NewQp61, Qp62, Qp63, Qp64}); -?FILTER_P_Qp64(62, - Qp62, NewQp62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, NewQp62, Qp63, Qp64}); -?FILTER_P_Qp64(63, - Qp63, NewQp63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, NewQp63, Qp64}); -?FILTER_P_Qp64(64, - Qp64, NewQp64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, NewQp64}); -?FILTER_P_Qp80(65, - Qp65, NewQp65, - {NewQp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(66, - Qp66, NewQp66, - {Qp65, NewQp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(67, - Qp67, NewQp67, - {Qp65, Qp66, NewQp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(68, - Qp68, NewQp68, - {Qp65, Qp66, Qp67, NewQp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(69, - Qp69, NewQp69, - {Qp65, Qp66, Qp67, Qp68, NewQp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(70, - Qp70, NewQp70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - NewQp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(71, - Qp71, NewQp71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, NewQp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(72, - Qp72, NewQp72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, NewQp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(73, - Qp73, NewQp73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, NewQp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(74, - Qp74, NewQp74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, NewQp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(75, - Qp75, NewQp75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, NewQp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(76, - Qp76, NewQp76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - NewQp76, Qp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(77, - Qp77, NewQp77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, NewQp77, Qp78, Qp79, Qp80}); -?FILTER_P_Qp80(78, - Qp78, NewQp78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, NewQp78, Qp79, Qp80}); -?FILTER_P_Qp80(79, - Qp79, NewQp79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, NewQp79, Qp80}); -?FILTER_P_Qp80(80, - Qp80, NewQp80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, NewQp80}); -?FILTER_P_Qp96(81, - Qp81, NewQp81, - {NewQp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(82, - Qp82, NewQp82, - {Qp81, NewQp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(83, - Qp83, NewQp83, - {Qp81, Qp82, NewQp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(84, - Qp84, NewQp84, - {Qp81, Qp82, Qp83, NewQp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(85, - Qp85, NewQp85, - {Qp81, Qp82, Qp83, Qp84, NewQp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(86, - Qp86, NewQp86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - NewQp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(87, - Qp87, NewQp87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, NewQp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(88, - Qp88, NewQp88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, NewQp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(89, - Qp89, NewQp89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, NewQp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(90, - Qp90, NewQp90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, NewQp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(91, - Qp91, NewQp91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, NewQp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(92, - Qp92, NewQp92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - NewQp92, Qp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(93, - Qp93, NewQp93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, NewQp93, Qp94, Qp95, Qp96}); -?FILTER_P_Qp96(94, - Qp94, NewQp94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, NewQp94, Qp95, Qp96}); -?FILTER_P_Qp96(95, - Qp95, NewQp95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, NewQp95, Qp96}); -?FILTER_P_Qp96(96, - Qp96, NewQp96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, NewQp96}); -?FILTER_P_Qp112(97, - Qp97, NewQp97, - {NewQp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(98, - Qp98, NewQp98, - {Qp97, NewQp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(99, - Qp99, NewQp99, - {Qp97, Qp98, NewQp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(100, - Qp100, NewQp100, - {Qp97, Qp98, Qp99, NewQp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(101, - Qp101, NewQp101, - {Qp97, Qp98, Qp99, Qp100, NewQp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(102, - Qp102, NewQp102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - NewQp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(103, - Qp103, NewQp103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, NewQp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(104, - Qp104, NewQp104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, NewQp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(105, - Qp105, NewQp105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, NewQp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(106, - Qp106, NewQp106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, NewQp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(107, - Qp107, NewQp107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, NewQp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(108, - Qp108, NewQp108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - NewQp108, Qp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(109, - Qp109, NewQp109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, NewQp109, Qp110, Qp111, Qp112}); -?FILTER_P_Qp112(110, - Qp110, NewQp110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, NewQp110, Qp111, Qp112}); -?FILTER_P_Qp112(111, - Qp111, NewQp111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, NewQp111, Qp112}); -?FILTER_P_Qp112(112, - Qp112, NewQp112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, NewQp112}); -?FILTER_P_Qp128(113, - Qp113, NewQp113, - {NewQp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(114, - Qp114, NewQp114, - {Qp113, NewQp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(115, - Qp115, NewQp115, - {Qp113, Qp114, NewQp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(116, - Qp116, NewQp116, - {Qp113, Qp114, Qp115, NewQp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(117, - Qp117, NewQp117, - {Qp113, Qp114, Qp115, Qp116, NewQp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(118, - Qp118, NewQp118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - NewQp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(119, - Qp119, NewQp119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, NewQp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(120, - Qp120, NewQp120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, NewQp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(121, - Qp121, NewQp121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, NewQp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(122, - Qp122, NewQp122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, NewQp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(123, - Qp123, NewQp123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, NewQp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(124, - Qp124, NewQp124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - NewQp124, Qp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(125, - Qp125, NewQp125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, NewQp125, Qp126, Qp127, Qp128}); -?FILTER_P_Qp128(126, - Qp126, NewQp126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, NewQp126, Qp127, Qp128}); -?FILTER_P_Qp128(127, - Qp127, NewQp127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, NewQp127, Qp128}); -?FILTER_P_Qp128(128, - Qp128, NewQp128, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, NewQp128}). - -%% @hidden --define(IN_HIGHER_Qn128(P, V), -in_higher(P, - {_, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - V, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn112(P, V), -in_higher(P, - {_, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, - V, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn96(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, - V, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn80(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, - V, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn64(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, - V, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn48(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, - V, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn32(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qn16(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp16(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp32(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp48(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V, - Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp64(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V, - Qp80, Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp80(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V, - Qp96, Qp112, Qp128}). --define(IN_HIGHER_Qp96(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V, - Qp112, Qp128}). --define(IN_HIGHER_Qp112(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V, - Qp128}). --define(IN_HIGHER_Qp128(P, V), -in_higher(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}, X) -> - {P, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V}). - -?IN_HIGHER_Qn128(-128, - {queue:in(X, Qn128), Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-127, - {Qn128, queue:in(X, Qn127), Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-126, - {Qn128, Qn127, queue:in(X, Qn126), Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-125, - {Qn128, Qn127, Qn126, queue:in(X, Qn125), Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-124, - {Qn128, Qn127, Qn126, Qn125, queue:in(X, Qn124), - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - queue:in(X, Qn123), Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, queue:in(X, Qn122), Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, queue:in(X, Qn121), Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, queue:in(X, Qn120), Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, queue:in(X, Qn119), Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, queue:in(X, Qn118), - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - queue:in(X, Qn117), Qn116, Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, queue:in(X, Qn116), Qn115, Qn114, Qn113}); -?IN_HIGHER_Qn128(-115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, queue:in(X, Qn115), Qn114, Qn113}); -?IN_HIGHER_Qn128(-114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, queue:in(X, Qn114), Qn113}); -?IN_HIGHER_Qn128(-113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, queue:in(X, Qn113)}); -?IN_HIGHER_Qn112(-112, - {queue:in(X, Qn112), Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-111, - {Qn112, queue:in(X, Qn111), Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-110, - {Qn112, Qn111, queue:in(X, Qn110), Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-109, - {Qn112, Qn111, Qn110, queue:in(X, Qn109), Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-108, - {Qn112, Qn111, Qn110, Qn109, queue:in(X, Qn108), - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - queue:in(X, Qn107), Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, queue:in(X, Qn106), Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, queue:in(X, Qn105), Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, queue:in(X, Qn104), Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, queue:in(X, Qn103), Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, queue:in(X, Qn102), - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - queue:in(X, Qn101), Qn100, Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, queue:in(X, Qn100), Qn99, Qn98, Qn97}); -?IN_HIGHER_Qn112(-99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, queue:in(X, Qn99), Qn98, Qn97}); -?IN_HIGHER_Qn112(-98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, queue:in(X, Qn98), Qn97}); -?IN_HIGHER_Qn112(-97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, queue:in(X, Qn97)}); -?IN_HIGHER_Qn96(-96, - {queue:in(X, Qn96), Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-95, - {Qn96, queue:in(X, Qn95), Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-94, - {Qn96, Qn95, queue:in(X, Qn94), Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-93, - {Qn96, Qn95, Qn94, queue:in(X, Qn93), Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-92, - {Qn96, Qn95, Qn94, Qn93, queue:in(X, Qn92), - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - queue:in(X, Qn91), Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, queue:in(X, Qn90), Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, queue:in(X, Qn89), Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, queue:in(X, Qn88), Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, queue:in(X, Qn87), Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, queue:in(X, Qn86), - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - queue:in(X, Qn85), Qn84, Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, queue:in(X, Qn84), Qn83, Qn82, Qn81}); -?IN_HIGHER_Qn96(-83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, queue:in(X, Qn83), Qn82, Qn81}); -?IN_HIGHER_Qn96(-82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, queue:in(X, Qn82), Qn81}); -?IN_HIGHER_Qn96(-81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, queue:in(X, Qn81)}); -?IN_HIGHER_Qn80(-80, - {queue:in(X, Qn80), Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-79, - {Qn80, queue:in(X, Qn79), Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-78, - {Qn80, Qn79, queue:in(X, Qn78), Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-77, - {Qn80, Qn79, Qn78, queue:in(X, Qn77), Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-76, - {Qn80, Qn79, Qn78, Qn77, queue:in(X, Qn76), - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - queue:in(X, Qn75), Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, queue:in(X, Qn74), Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, queue:in(X, Qn73), Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, queue:in(X, Qn72), Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, queue:in(X, Qn71), Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, queue:in(X, Qn70), - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - queue:in(X, Qn69), Qn68, Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, queue:in(X, Qn68), Qn67, Qn66, Qn65}); -?IN_HIGHER_Qn80(-67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, queue:in(X, Qn67), Qn66, Qn65}); -?IN_HIGHER_Qn80(-66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, queue:in(X, Qn66), Qn65}); -?IN_HIGHER_Qn80(-65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, queue:in(X, Qn65)}); -?IN_HIGHER_Qn64(-64, - {queue:in(X, Qn64), Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-63, - {Qn64, queue:in(X, Qn63), Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-62, - {Qn64, Qn63, queue:in(X, Qn62), Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-61, - {Qn64, Qn63, Qn62, queue:in(X, Qn61), Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-60, - {Qn64, Qn63, Qn62, Qn61, queue:in(X, Qn60), - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - queue:in(X, Qn59), Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, queue:in(X, Qn58), Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, queue:in(X, Qn57), Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, queue:in(X, Qn56), Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, queue:in(X, Qn55), Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, queue:in(X, Qn54), - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - queue:in(X, Qn53), Qn52, Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, queue:in(X, Qn52), Qn51, Qn50, Qn49}); -?IN_HIGHER_Qn64(-51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, queue:in(X, Qn51), Qn50, Qn49}); -?IN_HIGHER_Qn64(-50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, queue:in(X, Qn50), Qn49}); -?IN_HIGHER_Qn64(-49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, queue:in(X, Qn49)}); -?IN_HIGHER_Qn48(-48, - {queue:in(X, Qn48), Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-47, - {Qn48, queue:in(X, Qn47), Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-46, - {Qn48, Qn47, queue:in(X, Qn46), Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-45, - {Qn48, Qn47, Qn46, queue:in(X, Qn45), Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-44, - {Qn48, Qn47, Qn46, Qn45, queue:in(X, Qn44), - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - queue:in(X, Qn43), Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, queue:in(X, Qn42), Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, queue:in(X, Qn41), Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, queue:in(X, Qn40), Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, queue:in(X, Qn39), Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, queue:in(X, Qn38), - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - queue:in(X, Qn37), Qn36, Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, queue:in(X, Qn36), Qn35, Qn34, Qn33}); -?IN_HIGHER_Qn48(-35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, queue:in(X, Qn35), Qn34, Qn33}); -?IN_HIGHER_Qn48(-34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, queue:in(X, Qn34), Qn33}); -?IN_HIGHER_Qn48(-33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, queue:in(X, Qn33)}); -?IN_HIGHER_Qn32(-32, - {queue:in(X, Qn32), Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-31, - {Qn32, queue:in(X, Qn31), Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-30, - {Qn32, Qn31, queue:in(X, Qn30), Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-29, - {Qn32, Qn31, Qn30, queue:in(X, Qn29), Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-28, - {Qn32, Qn31, Qn30, Qn29, queue:in(X, Qn28), - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - queue:in(X, Qn27), Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, queue:in(X, Qn26), Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, queue:in(X, Qn25), Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, queue:in(X, Qn24), Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, queue:in(X, Qn23), Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, queue:in(X, Qn22), - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - queue:in(X, Qn21), Qn20, Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, queue:in(X, Qn20), Qn19, Qn18, Qn17}); -?IN_HIGHER_Qn32(-19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, queue:in(X, Qn19), Qn18, Qn17}); -?IN_HIGHER_Qn32(-18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, queue:in(X, Qn18), Qn17}); -?IN_HIGHER_Qn32(-17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, queue:in(X, Qn17)}); -?IN_HIGHER_Qn16(-16, - {queue:in(X, Qn16), Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-15, - {Qn16, queue:in(X, Qn15), Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-14, - {Qn16, Qn15, queue:in(X, Qn14), Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-13, - {Qn16, Qn15, Qn14, queue:in(X, Qn13), Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-12, - {Qn16, Qn15, Qn14, Qn13, queue:in(X, Qn12), - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - queue:in(X, Qn11), Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, queue:in(X, Qn10), Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, queue:in(X, Qn9), Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, queue:in(X, Qn8), Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, queue:in(X, Qn7), Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, queue:in(X, Qn6), - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - queue:in(X, Qn5), Qn4, Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, queue:in(X, Qn4), Qn3, Qn2, Qn1}); -?IN_HIGHER_Qn16(-3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, queue:in(X, Qn3), Qn2, Qn1}); -?IN_HIGHER_Qn16(-2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, queue:in(X, Qn2), Qn1}); -?IN_HIGHER_Qn16(-1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, queue:in(X, Qn1)}); -in_higher(0, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {0, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - queue:in(X, Q0), - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}; -?IN_HIGHER_Qp16(1, - {queue:in(X, Qp1), Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(2, - {Qp1, queue:in(X, Qp2), Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(3, - {Qp1, Qp2, queue:in(X, Qp3), Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(4, - {Qp1, Qp2, Qp3, queue:in(X, Qp4), Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(5, - {Qp1, Qp2, Qp3, Qp4, queue:in(X, Qp5), - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - queue:in(X, Qp6), Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, queue:in(X, Qp7), Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, queue:in(X, Qp8), Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, queue:in(X, Qp9), Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, queue:in(X, Qp10), Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, queue:in(X, Qp11), - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - queue:in(X, Qp12), Qp13, Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, queue:in(X, Qp13), Qp14, Qp15, Qp16}); -?IN_HIGHER_Qp16(14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, queue:in(X, Qp14), Qp15, Qp16}); -?IN_HIGHER_Qp16(15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, queue:in(X, Qp15), Qp16}); -?IN_HIGHER_Qp16(16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, queue:in(X, Qp16)}); -?IN_HIGHER_Qp32(17, - {queue:in(X, Qp17), Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(18, - {Qp17, queue:in(X, Qp18), Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(19, - {Qp17, Qp18, queue:in(X, Qp19), Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(20, - {Qp17, Qp18, Qp19, queue:in(X, Qp20), Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(21, - {Qp17, Qp18, Qp19, Qp20, queue:in(X, Qp21), - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - queue:in(X, Qp22), Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, queue:in(X, Qp23), Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, queue:in(X, Qp24), Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, queue:in(X, Qp25), Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, queue:in(X, Qp26), Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, queue:in(X, Qp27), - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - queue:in(X, Qp28), Qp29, Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, queue:in(X, Qp29), Qp30, Qp31, Qp32}); -?IN_HIGHER_Qp32(30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, queue:in(X, Qp30), Qp31, Qp32}); -?IN_HIGHER_Qp32(31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, queue:in(X, Qp31), Qp32}); -?IN_HIGHER_Qp32(32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, queue:in(X, Qp32)}); -?IN_HIGHER_Qp48(33, - {queue:in(X, Qp33), Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(34, - {Qp33, queue:in(X, Qp34), Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(35, - {Qp33, Qp34, queue:in(X, Qp35), Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(36, - {Qp33, Qp34, Qp35, queue:in(X, Qp36), Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(37, - {Qp33, Qp34, Qp35, Qp36, queue:in(X, Qp37), - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - queue:in(X, Qp38), Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, queue:in(X, Qp39), Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, queue:in(X, Qp40), Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, queue:in(X, Qp41), Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, queue:in(X, Qp42), Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, queue:in(X, Qp43), - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - queue:in(X, Qp44), Qp45, Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, queue:in(X, Qp45), Qp46, Qp47, Qp48}); -?IN_HIGHER_Qp48(46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, queue:in(X, Qp46), Qp47, Qp48}); -?IN_HIGHER_Qp48(47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, queue:in(X, Qp47), Qp48}); -?IN_HIGHER_Qp48(48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, queue:in(X, Qp48)}); -?IN_HIGHER_Qp64(49, - {queue:in(X, Qp49), Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(50, - {Qp49, queue:in(X, Qp50), Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(51, - {Qp49, Qp50, queue:in(X, Qp51), Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(52, - {Qp49, Qp50, Qp51, queue:in(X, Qp52), Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(53, - {Qp49, Qp50, Qp51, Qp52, queue:in(X, Qp53), - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - queue:in(X, Qp54), Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, queue:in(X, Qp55), Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, queue:in(X, Qp56), Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, queue:in(X, Qp57), Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, queue:in(X, Qp58), Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, queue:in(X, Qp59), - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - queue:in(X, Qp60), Qp61, Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, queue:in(X, Qp61), Qp62, Qp63, Qp64}); -?IN_HIGHER_Qp64(62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, queue:in(X, Qp62), Qp63, Qp64}); -?IN_HIGHER_Qp64(63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, queue:in(X, Qp63), Qp64}); -?IN_HIGHER_Qp64(64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, queue:in(X, Qp64)}); -?IN_HIGHER_Qp80(65, - {queue:in(X, Qp65), Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(66, - {Qp65, queue:in(X, Qp66), Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(67, - {Qp65, Qp66, queue:in(X, Qp67), Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(68, - {Qp65, Qp66, Qp67, queue:in(X, Qp68), Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(69, - {Qp65, Qp66, Qp67, Qp68, queue:in(X, Qp69), - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - queue:in(X, Qp70), Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, queue:in(X, Qp71), Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, queue:in(X, Qp72), Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, queue:in(X, Qp73), Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, queue:in(X, Qp74), Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, queue:in(X, Qp75), - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - queue:in(X, Qp76), Qp77, Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, queue:in(X, Qp77), Qp78, Qp79, Qp80}); -?IN_HIGHER_Qp80(78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, queue:in(X, Qp78), Qp79, Qp80}); -?IN_HIGHER_Qp80(79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, queue:in(X, Qp79), Qp80}); -?IN_HIGHER_Qp80(80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, queue:in(X, Qp80)}); -?IN_HIGHER_Qp96(81, - {queue:in(X, Qp81), Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(82, - {Qp81, queue:in(X, Qp82), Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(83, - {Qp81, Qp82, queue:in(X, Qp83), Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(84, - {Qp81, Qp82, Qp83, queue:in(X, Qp84), Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(85, - {Qp81, Qp82, Qp83, Qp84, queue:in(X, Qp85), - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - queue:in(X, Qp86), Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, queue:in(X, Qp87), Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, queue:in(X, Qp88), Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, queue:in(X, Qp89), Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, queue:in(X, Qp90), Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, queue:in(X, Qp91), - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - queue:in(X, Qp92), Qp93, Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, queue:in(X, Qp93), Qp94, Qp95, Qp96}); -?IN_HIGHER_Qp96(94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, queue:in(X, Qp94), Qp95, Qp96}); -?IN_HIGHER_Qp96(95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, queue:in(X, Qp95), Qp96}); -?IN_HIGHER_Qp96(96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, queue:in(X, Qp96)}); -?IN_HIGHER_Qp112(97, - {queue:in(X, Qp97), Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(98, - {Qp97, queue:in(X, Qp98), Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(99, - {Qp97, Qp98, queue:in(X, Qp99), Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(100, - {Qp97, Qp98, Qp99, queue:in(X, Qp100), Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(101, - {Qp97, Qp98, Qp99, Qp100, queue:in(X, Qp101), - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - queue:in(X, Qp102), Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, queue:in(X, Qp103), Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, queue:in(X, Qp104), Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, queue:in(X, Qp105), Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, queue:in(X, Qp106), Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, queue:in(X, Qp107), - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - queue:in(X, Qp108), Qp109, Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, queue:in(X, Qp109), Qp110, Qp111, Qp112}); -?IN_HIGHER_Qp112(110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, queue:in(X, Qp110), Qp111, Qp112}); -?IN_HIGHER_Qp112(111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, queue:in(X, Qp111), Qp112}); -?IN_HIGHER_Qp112(112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, queue:in(X, Qp112)}); -?IN_HIGHER_Qp128(113, - {queue:in(X, Qp113), Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(114, - {Qp113, queue:in(X, Qp114), Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(115, - {Qp113, Qp114, queue:in(X, Qp115), Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(116, - {Qp113, Qp114, Qp115, queue:in(X, Qp116), Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(117, - {Qp113, Qp114, Qp115, Qp116, queue:in(X, Qp117), - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - queue:in(X, Qp118), Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, queue:in(X, Qp119), Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, queue:in(X, Qp120), Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, queue:in(X, Qp121), Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, queue:in(X, Qp122), Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, queue:in(X, Qp123), - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - queue:in(X, Qp124), Qp125, Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, queue:in(X, Qp125), Qp126, Qp127, Qp128}); -?IN_HIGHER_Qp128(126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, queue:in(X, Qp126), Qp127, Qp128}); -?IN_HIGHER_Qp128(127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, queue:in(X, Qp127), Qp128}); -?IN_HIGHER_Qp128(128, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, queue:in(X, Qp128)}). - -%% @hidden --define(IN_LOWER_Qn128(P, V), -in_lower(P, - {Pc, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - V, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn112(P, V), -in_lower(P, - {Pc, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, - V, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn96(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, - V, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn80(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, - V, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn64(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, - V, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn48(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, - V, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn32(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qn16(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp16(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp32(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp48(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V, - Qp64, Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp64(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V, - Qp80, Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp80(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V, - Qp96, Qp112, Qp128}). --define(IN_LOWER_Qp96(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V, - Qp112, Qp128}). --define(IN_LOWER_Qp112(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V, - Qp128}). --define(IN_LOWER_Qp128(P, V), -in_lower(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V}). - -?IN_LOWER_Qn128(-128, - {queue:in(X, Qn128), Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-127, - {Qn128, queue:in(X, Qn127), Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-126, - {Qn128, Qn127, queue:in(X, Qn126), Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-125, - {Qn128, Qn127, Qn126, queue:in(X, Qn125), Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-124, - {Qn128, Qn127, Qn126, Qn125, queue:in(X, Qn124), - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - queue:in(X, Qn123), Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, queue:in(X, Qn122), Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, queue:in(X, Qn121), Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, queue:in(X, Qn120), Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, queue:in(X, Qn119), Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, queue:in(X, Qn118), - Qn117, Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - queue:in(X, Qn117), Qn116, Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, queue:in(X, Qn116), Qn115, Qn114, Qn113}); -?IN_LOWER_Qn128(-115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, queue:in(X, Qn115), Qn114, Qn113}); -?IN_LOWER_Qn128(-114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, queue:in(X, Qn114), Qn113}); -?IN_LOWER_Qn128(-113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, queue:in(X, Qn113)}); -?IN_LOWER_Qn112(-112, - {queue:in(X, Qn112), Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-111, - {Qn112, queue:in(X, Qn111), Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-110, - {Qn112, Qn111, queue:in(X, Qn110), Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-109, - {Qn112, Qn111, Qn110, queue:in(X, Qn109), Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-108, - {Qn112, Qn111, Qn110, Qn109, queue:in(X, Qn108), - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - queue:in(X, Qn107), Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, queue:in(X, Qn106), Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, queue:in(X, Qn105), Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, queue:in(X, Qn104), Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, queue:in(X, Qn103), Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, queue:in(X, Qn102), - Qn101, Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - queue:in(X, Qn101), Qn100, Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, queue:in(X, Qn100), Qn99, Qn98, Qn97}); -?IN_LOWER_Qn112(-99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, queue:in(X, Qn99), Qn98, Qn97}); -?IN_LOWER_Qn112(-98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, queue:in(X, Qn98), Qn97}); -?IN_LOWER_Qn112(-97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, queue:in(X, Qn97)}); -?IN_LOWER_Qn96(-96, - {queue:in(X, Qn96), Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-95, - {Qn96, queue:in(X, Qn95), Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-94, - {Qn96, Qn95, queue:in(X, Qn94), Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-93, - {Qn96, Qn95, Qn94, queue:in(X, Qn93), Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-92, - {Qn96, Qn95, Qn94, Qn93, queue:in(X, Qn92), - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - queue:in(X, Qn91), Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, queue:in(X, Qn90), Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, queue:in(X, Qn89), Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, queue:in(X, Qn88), Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, queue:in(X, Qn87), Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, queue:in(X, Qn86), - Qn85, Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - queue:in(X, Qn85), Qn84, Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, queue:in(X, Qn84), Qn83, Qn82, Qn81}); -?IN_LOWER_Qn96(-83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, queue:in(X, Qn83), Qn82, Qn81}); -?IN_LOWER_Qn96(-82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, queue:in(X, Qn82), Qn81}); -?IN_LOWER_Qn96(-81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, queue:in(X, Qn81)}); -?IN_LOWER_Qn80(-80, - {queue:in(X, Qn80), Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-79, - {Qn80, queue:in(X, Qn79), Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-78, - {Qn80, Qn79, queue:in(X, Qn78), Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-77, - {Qn80, Qn79, Qn78, queue:in(X, Qn77), Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-76, - {Qn80, Qn79, Qn78, Qn77, queue:in(X, Qn76), - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - queue:in(X, Qn75), Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, queue:in(X, Qn74), Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, queue:in(X, Qn73), Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, queue:in(X, Qn72), Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, queue:in(X, Qn71), Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, queue:in(X, Qn70), - Qn69, Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - queue:in(X, Qn69), Qn68, Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, queue:in(X, Qn68), Qn67, Qn66, Qn65}); -?IN_LOWER_Qn80(-67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, queue:in(X, Qn67), Qn66, Qn65}); -?IN_LOWER_Qn80(-66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, queue:in(X, Qn66), Qn65}); -?IN_LOWER_Qn80(-65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, queue:in(X, Qn65)}); -?IN_LOWER_Qn64(-64, - {queue:in(X, Qn64), Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-63, - {Qn64, queue:in(X, Qn63), Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-62, - {Qn64, Qn63, queue:in(X, Qn62), Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-61, - {Qn64, Qn63, Qn62, queue:in(X, Qn61), Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-60, - {Qn64, Qn63, Qn62, Qn61, queue:in(X, Qn60), - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - queue:in(X, Qn59), Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, queue:in(X, Qn58), Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, queue:in(X, Qn57), Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, queue:in(X, Qn56), Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, queue:in(X, Qn55), Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, queue:in(X, Qn54), - Qn53, Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - queue:in(X, Qn53), Qn52, Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, queue:in(X, Qn52), Qn51, Qn50, Qn49}); -?IN_LOWER_Qn64(-51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, queue:in(X, Qn51), Qn50, Qn49}); -?IN_LOWER_Qn64(-50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, queue:in(X, Qn50), Qn49}); -?IN_LOWER_Qn64(-49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, queue:in(X, Qn49)}); -?IN_LOWER_Qn48(-48, - {queue:in(X, Qn48), Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-47, - {Qn48, queue:in(X, Qn47), Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-46, - {Qn48, Qn47, queue:in(X, Qn46), Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-45, - {Qn48, Qn47, Qn46, queue:in(X, Qn45), Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-44, - {Qn48, Qn47, Qn46, Qn45, queue:in(X, Qn44), - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - queue:in(X, Qn43), Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, queue:in(X, Qn42), Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, queue:in(X, Qn41), Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, queue:in(X, Qn40), Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, queue:in(X, Qn39), Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, queue:in(X, Qn38), - Qn37, Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - queue:in(X, Qn37), Qn36, Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, queue:in(X, Qn36), Qn35, Qn34, Qn33}); -?IN_LOWER_Qn48(-35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, queue:in(X, Qn35), Qn34, Qn33}); -?IN_LOWER_Qn48(-34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, queue:in(X, Qn34), Qn33}); -?IN_LOWER_Qn48(-33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, queue:in(X, Qn33)}); -?IN_LOWER_Qn32(-32, - {queue:in(X, Qn32), Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-31, - {Qn32, queue:in(X, Qn31), Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-30, - {Qn32, Qn31, queue:in(X, Qn30), Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-29, - {Qn32, Qn31, Qn30, queue:in(X, Qn29), Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-28, - {Qn32, Qn31, Qn30, Qn29, queue:in(X, Qn28), - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - queue:in(X, Qn27), Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, queue:in(X, Qn26), Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, queue:in(X, Qn25), Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, queue:in(X, Qn24), Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, queue:in(X, Qn23), Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, queue:in(X, Qn22), - Qn21, Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - queue:in(X, Qn21), Qn20, Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, queue:in(X, Qn20), Qn19, Qn18, Qn17}); -?IN_LOWER_Qn32(-19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, queue:in(X, Qn19), Qn18, Qn17}); -?IN_LOWER_Qn32(-18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, queue:in(X, Qn18), Qn17}); -?IN_LOWER_Qn32(-17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, queue:in(X, Qn17)}); -?IN_LOWER_Qn16(-16, - {queue:in(X, Qn16), Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-15, - {Qn16, queue:in(X, Qn15), Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-14, - {Qn16, Qn15, queue:in(X, Qn14), Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-13, - {Qn16, Qn15, Qn14, queue:in(X, Qn13), Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-12, - {Qn16, Qn15, Qn14, Qn13, queue:in(X, Qn12), - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - queue:in(X, Qn11), Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, queue:in(X, Qn10), Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, queue:in(X, Qn9), Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, queue:in(X, Qn8), Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, queue:in(X, Qn7), Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, queue:in(X, Qn6), - Qn5, Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - queue:in(X, Qn5), Qn4, Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, queue:in(X, Qn4), Qn3, Qn2, Qn1}); -?IN_LOWER_Qn16(-3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, queue:in(X, Qn3), Qn2, Qn1}); -?IN_LOWER_Qn16(-2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, queue:in(X, Qn2), Qn1}); -?IN_LOWER_Qn16(-1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, queue:in(X, Qn1)}); -in_lower(0, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}, X) -> - {Pc, - Size + 1, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - queue:in(X, Q0), - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}; -?IN_LOWER_Qp16(1, - {queue:in(X, Qp1), Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(2, - {Qp1, queue:in(X, Qp2), Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(3, - {Qp1, Qp2, queue:in(X, Qp3), Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(4, - {Qp1, Qp2, Qp3, queue:in(X, Qp4), Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(5, - {Qp1, Qp2, Qp3, Qp4, queue:in(X, Qp5), - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - queue:in(X, Qp6), Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, queue:in(X, Qp7), Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, queue:in(X, Qp8), Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, queue:in(X, Qp9), Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, queue:in(X, Qp10), Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, queue:in(X, Qp11), - Qp12, Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - queue:in(X, Qp12), Qp13, Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, queue:in(X, Qp13), Qp14, Qp15, Qp16}); -?IN_LOWER_Qp16(14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, queue:in(X, Qp14), Qp15, Qp16}); -?IN_LOWER_Qp16(15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, queue:in(X, Qp15), Qp16}); -?IN_LOWER_Qp16(16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, queue:in(X, Qp16)}); -?IN_LOWER_Qp32(17, - {queue:in(X, Qp17), Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(18, - {Qp17, queue:in(X, Qp18), Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(19, - {Qp17, Qp18, queue:in(X, Qp19), Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(20, - {Qp17, Qp18, Qp19, queue:in(X, Qp20), Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(21, - {Qp17, Qp18, Qp19, Qp20, queue:in(X, Qp21), - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - queue:in(X, Qp22), Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, queue:in(X, Qp23), Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, queue:in(X, Qp24), Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, queue:in(X, Qp25), Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, queue:in(X, Qp26), Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, queue:in(X, Qp27), - Qp28, Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - queue:in(X, Qp28), Qp29, Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, queue:in(X, Qp29), Qp30, Qp31, Qp32}); -?IN_LOWER_Qp32(30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, queue:in(X, Qp30), Qp31, Qp32}); -?IN_LOWER_Qp32(31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, queue:in(X, Qp31), Qp32}); -?IN_LOWER_Qp32(32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, queue:in(X, Qp32)}); -?IN_LOWER_Qp48(33, - {queue:in(X, Qp33), Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(34, - {Qp33, queue:in(X, Qp34), Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(35, - {Qp33, Qp34, queue:in(X, Qp35), Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(36, - {Qp33, Qp34, Qp35, queue:in(X, Qp36), Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(37, - {Qp33, Qp34, Qp35, Qp36, queue:in(X, Qp37), - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - queue:in(X, Qp38), Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, queue:in(X, Qp39), Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, queue:in(X, Qp40), Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, queue:in(X, Qp41), Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, queue:in(X, Qp42), Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, queue:in(X, Qp43), - Qp44, Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - queue:in(X, Qp44), Qp45, Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, queue:in(X, Qp45), Qp46, Qp47, Qp48}); -?IN_LOWER_Qp48(46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, queue:in(X, Qp46), Qp47, Qp48}); -?IN_LOWER_Qp48(47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, queue:in(X, Qp47), Qp48}); -?IN_LOWER_Qp48(48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, queue:in(X, Qp48)}); -?IN_LOWER_Qp64(49, - {queue:in(X, Qp49), Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(50, - {Qp49, queue:in(X, Qp50), Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(51, - {Qp49, Qp50, queue:in(X, Qp51), Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(52, - {Qp49, Qp50, Qp51, queue:in(X, Qp52), Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(53, - {Qp49, Qp50, Qp51, Qp52, queue:in(X, Qp53), - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - queue:in(X, Qp54), Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, queue:in(X, Qp55), Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, queue:in(X, Qp56), Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, queue:in(X, Qp57), Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, queue:in(X, Qp58), Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, queue:in(X, Qp59), - Qp60, Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - queue:in(X, Qp60), Qp61, Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, queue:in(X, Qp61), Qp62, Qp63, Qp64}); -?IN_LOWER_Qp64(62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, queue:in(X, Qp62), Qp63, Qp64}); -?IN_LOWER_Qp64(63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, queue:in(X, Qp63), Qp64}); -?IN_LOWER_Qp64(64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, queue:in(X, Qp64)}); -?IN_LOWER_Qp80(65, - {queue:in(X, Qp65), Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(66, - {Qp65, queue:in(X, Qp66), Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(67, - {Qp65, Qp66, queue:in(X, Qp67), Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(68, - {Qp65, Qp66, Qp67, queue:in(X, Qp68), Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(69, - {Qp65, Qp66, Qp67, Qp68, queue:in(X, Qp69), - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - queue:in(X, Qp70), Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, queue:in(X, Qp71), Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, queue:in(X, Qp72), Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, queue:in(X, Qp73), Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, queue:in(X, Qp74), Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, queue:in(X, Qp75), - Qp76, Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - queue:in(X, Qp76), Qp77, Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, queue:in(X, Qp77), Qp78, Qp79, Qp80}); -?IN_LOWER_Qp80(78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, queue:in(X, Qp78), Qp79, Qp80}); -?IN_LOWER_Qp80(79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, queue:in(X, Qp79), Qp80}); -?IN_LOWER_Qp80(80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, queue:in(X, Qp80)}); -?IN_LOWER_Qp96(81, - {queue:in(X, Qp81), Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(82, - {Qp81, queue:in(X, Qp82), Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(83, - {Qp81, Qp82, queue:in(X, Qp83), Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(84, - {Qp81, Qp82, Qp83, queue:in(X, Qp84), Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(85, - {Qp81, Qp82, Qp83, Qp84, queue:in(X, Qp85), - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - queue:in(X, Qp86), Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, queue:in(X, Qp87), Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, queue:in(X, Qp88), Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, queue:in(X, Qp89), Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, queue:in(X, Qp90), Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, queue:in(X, Qp91), - Qp92, Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - queue:in(X, Qp92), Qp93, Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, queue:in(X, Qp93), Qp94, Qp95, Qp96}); -?IN_LOWER_Qp96(94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, queue:in(X, Qp94), Qp95, Qp96}); -?IN_LOWER_Qp96(95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, queue:in(X, Qp95), Qp96}); -?IN_LOWER_Qp96(96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, queue:in(X, Qp96)}); -?IN_LOWER_Qp112(97, - {queue:in(X, Qp97), Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(98, - {Qp97, queue:in(X, Qp98), Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(99, - {Qp97, Qp98, queue:in(X, Qp99), Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(100, - {Qp97, Qp98, Qp99, queue:in(X, Qp100), Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(101, - {Qp97, Qp98, Qp99, Qp100, queue:in(X, Qp101), - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - queue:in(X, Qp102), Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, queue:in(X, Qp103), Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, queue:in(X, Qp104), Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, queue:in(X, Qp105), Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, queue:in(X, Qp106), Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, queue:in(X, Qp107), - Qp108, Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - queue:in(X, Qp108), Qp109, Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, queue:in(X, Qp109), Qp110, Qp111, Qp112}); -?IN_LOWER_Qp112(110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, queue:in(X, Qp110), Qp111, Qp112}); -?IN_LOWER_Qp112(111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, queue:in(X, Qp111), Qp112}); -?IN_LOWER_Qp112(112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, queue:in(X, Qp112)}); -?IN_LOWER_Qp128(113, - {queue:in(X, Qp113), Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(114, - {Qp113, queue:in(X, Qp114), Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(115, - {Qp113, Qp114, queue:in(X, Qp115), Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(116, - {Qp113, Qp114, Qp115, queue:in(X, Qp116), Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(117, - {Qp113, Qp114, Qp115, Qp116, queue:in(X, Qp117), - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - queue:in(X, Qp118), Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, queue:in(X, Qp119), Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, queue:in(X, Qp120), Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, queue:in(X, Qp121), Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, queue:in(X, Qp122), Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, queue:in(X, Qp123), - Qp124, Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - queue:in(X, Qp124), Qp125, Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, queue:in(X, Qp125), Qp126, Qp127, Qp128}); -?IN_LOWER_Qp128(126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, queue:in(X, Qp126), Qp127, Qp128}); -?IN_LOWER_Qp128(127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, queue:in(X, Qp127), Qp128}); -?IN_LOWER_Qp128(128, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, queue:in(X, Qp128)}). - -%% @hidden --define(OUT_CURRENT_Qn128(P, V1, V2, V3), -out_current(P, - {_, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - V3, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn112(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, - V3, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn96(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, - V3, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn80(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, - V3, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn64(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, - V3, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn48(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, - V3, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn32(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V3, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qn16(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V3, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp16(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V3, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp32(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V3, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp48(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V3, - Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp64(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V3, - Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp80(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V3, - Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp96(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V3, - Qp112, Qp128}} - end). --define(OUT_CURRENT_Qp112(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V3, - Qp128}} - end). --define(OUT_CURRENT_Qp128(P, V1, V2, V3), -out_current(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}} = Q) -> - {Value, V2} = queue:out(V1), - if - Value =:= empty -> - out_current(P + 1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V3}} - end). - -?OUT_CURRENT_Qn128(-128, - Qn128, NewQn128, - {NewQn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-127, - Qn127, NewQn127, - {Qn128, NewQn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-126, - Qn126, NewQn126, - {Qn128, Qn127, NewQn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-125, - Qn125, NewQn125, - {Qn128, Qn127, Qn126, NewQn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-124, - Qn124, NewQn124, - {Qn128, Qn127, Qn126, Qn125, NewQn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-123, - Qn123, NewQn123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - NewQn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-122, - Qn122, NewQn122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, NewQn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-121, - Qn121, NewQn121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, NewQn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-120, - Qn120, NewQn120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, NewQn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-119, - Qn119, NewQn119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, NewQn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-118, - Qn118, NewQn118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, NewQn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-117, - Qn117, NewQn117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - NewQn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-116, - Qn116, NewQn116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, NewQn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-115, - Qn115, NewQn115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, NewQn115, Qn114, Qn113}); -?OUT_CURRENT_Qn128(-114, - Qn114, NewQn114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, NewQn114, Qn113}); -?OUT_CURRENT_Qn128(-113, - Qn113, NewQn113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, NewQn113}); -?OUT_CURRENT_Qn112(-112, - Qn112, NewQn112, - {NewQn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-111, - Qn111, NewQn111, - {Qn112, NewQn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-110, - Qn110, NewQn110, - {Qn112, Qn111, NewQn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-109, - Qn109, NewQn109, - {Qn112, Qn111, Qn110, NewQn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-108, - Qn108, NewQn108, - {Qn112, Qn111, Qn110, Qn109, NewQn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-107, - Qn107, NewQn107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - NewQn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-106, - Qn106, NewQn106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, NewQn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-105, - Qn105, NewQn105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, NewQn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-104, - Qn104, NewQn104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, NewQn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-103, - Qn103, NewQn103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, NewQn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-102, - Qn102, NewQn102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, NewQn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-101, - Qn101, NewQn101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - NewQn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-100, - Qn100, NewQn100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, NewQn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-99, - Qn99, NewQn99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, NewQn99, Qn98, Qn97}); -?OUT_CURRENT_Qn112(-98, - Qn98, NewQn98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, NewQn98, Qn97}); -?OUT_CURRENT_Qn112(-97, - Qn97, NewQn97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, NewQn97}); -?OUT_CURRENT_Qn96(-96, - Qn96, NewQn96, - {NewQn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-95, - Qn95, NewQn95, - {Qn96, NewQn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-94, - Qn94, NewQn94, - {Qn96, Qn95, NewQn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-93, - Qn93, NewQn93, - {Qn96, Qn95, Qn94, NewQn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-92, - Qn92, NewQn92, - {Qn96, Qn95, Qn94, Qn93, NewQn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-91, - Qn91, NewQn91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - NewQn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-90, - Qn90, NewQn90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, NewQn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-89, - Qn89, NewQn89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, NewQn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-88, - Qn88, NewQn88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, NewQn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-87, - Qn87, NewQn87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, NewQn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-86, - Qn86, NewQn86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, NewQn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-85, - Qn85, NewQn85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - NewQn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-84, - Qn84, NewQn84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, NewQn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-83, - Qn83, NewQn83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, NewQn83, Qn82, Qn81}); -?OUT_CURRENT_Qn96(-82, - Qn82, NewQn82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, NewQn82, Qn81}); -?OUT_CURRENT_Qn96(-81, - Qn81, NewQn81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, NewQn81}); -?OUT_CURRENT_Qn80(-80, - Qn80, NewQn80, - {NewQn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-79, - Qn79, NewQn79, - {Qn80, NewQn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-78, - Qn78, NewQn78, - {Qn80, Qn79, NewQn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-77, - Qn77, NewQn77, - {Qn80, Qn79, Qn78, NewQn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-76, - Qn76, NewQn76, - {Qn80, Qn79, Qn78, Qn77, NewQn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-75, - Qn75, NewQn75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - NewQn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-74, - Qn74, NewQn74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, NewQn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-73, - Qn73, NewQn73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, NewQn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-72, - Qn72, NewQn72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, NewQn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-71, - Qn71, NewQn71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, NewQn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-70, - Qn70, NewQn70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, NewQn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-69, - Qn69, NewQn69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - NewQn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-68, - Qn68, NewQn68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, NewQn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-67, - Qn67, NewQn67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, NewQn67, Qn66, Qn65}); -?OUT_CURRENT_Qn80(-66, - Qn66, NewQn66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, NewQn66, Qn65}); -?OUT_CURRENT_Qn80(-65, - Qn65, NewQn65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, NewQn65}); -?OUT_CURRENT_Qn64(-64, - Qn64, NewQn64, - {NewQn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-63, - Qn63, NewQn63, - {Qn64, NewQn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-62, - Qn62, NewQn62, - {Qn64, Qn63, NewQn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-61, - Qn61, NewQn61, - {Qn64, Qn63, Qn62, NewQn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-60, - Qn60, NewQn60, - {Qn64, Qn63, Qn62, Qn61, NewQn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-59, - Qn59, NewQn59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - NewQn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-58, - Qn58, NewQn58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, NewQn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-57, - Qn57, NewQn57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, NewQn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-56, - Qn56, NewQn56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, NewQn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-55, - Qn55, NewQn55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, NewQn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-54, - Qn54, NewQn54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, NewQn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-53, - Qn53, NewQn53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - NewQn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-52, - Qn52, NewQn52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, NewQn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-51, - Qn51, NewQn51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, NewQn51, Qn50, Qn49}); -?OUT_CURRENT_Qn64(-50, - Qn50, NewQn50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, NewQn50, Qn49}); -?OUT_CURRENT_Qn64(-49, - Qn49, NewQn49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, NewQn49}); -?OUT_CURRENT_Qn48(-48, - Qn48, NewQn48, - {NewQn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-47, - Qn47, NewQn47, - {Qn48, NewQn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-46, - Qn46, NewQn46, - {Qn48, Qn47, NewQn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-45, - Qn45, NewQn45, - {Qn48, Qn47, Qn46, NewQn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-44, - Qn44, NewQn44, - {Qn48, Qn47, Qn46, Qn45, NewQn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-43, - Qn43, NewQn43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - NewQn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-42, - Qn42, NewQn42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, NewQn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-41, - Qn41, NewQn41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, NewQn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-40, - Qn40, NewQn40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, NewQn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-39, - Qn39, NewQn39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, NewQn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-38, - Qn38, NewQn38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, NewQn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-37, - Qn37, NewQn37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - NewQn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-36, - Qn36, NewQn36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, NewQn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-35, - Qn35, NewQn35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, NewQn35, Qn34, Qn33}); -?OUT_CURRENT_Qn48(-34, - Qn34, NewQn34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, NewQn34, Qn33}); -?OUT_CURRENT_Qn48(-33, - Qn33, NewQn33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, NewQn33}); -?OUT_CURRENT_Qn32(-32, - Qn32, NewQn32, - {NewQn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-31, - Qn31, NewQn31, - {Qn32, NewQn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-30, - Qn30, NewQn30, - {Qn32, Qn31, NewQn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-29, - Qn29, NewQn29, - {Qn32, Qn31, Qn30, NewQn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-28, - Qn28, NewQn28, - {Qn32, Qn31, Qn30, Qn29, NewQn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-27, - Qn27, NewQn27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - NewQn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-26, - Qn26, NewQn26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, NewQn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-25, - Qn25, NewQn25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, NewQn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-24, - Qn24, NewQn24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, NewQn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-23, - Qn23, NewQn23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, NewQn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-22, - Qn22, NewQn22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, NewQn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-21, - Qn21, NewQn21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - NewQn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-20, - Qn20, NewQn20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, NewQn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-19, - Qn19, NewQn19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, NewQn19, Qn18, Qn17}); -?OUT_CURRENT_Qn32(-18, - Qn18, NewQn18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, NewQn18, Qn17}); -?OUT_CURRENT_Qn32(-17, - Qn17, NewQn17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, NewQn17}); -?OUT_CURRENT_Qn16(-16, - Qn16, NewQn16, - {NewQn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-15, - Qn15, NewQn15, - {Qn16, NewQn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-14, - Qn14, NewQn14, - {Qn16, Qn15, NewQn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-13, - Qn13, NewQn13, - {Qn16, Qn15, Qn14, NewQn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-12, - Qn12, NewQn12, - {Qn16, Qn15, Qn14, Qn13, NewQn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-11, - Qn11, NewQn11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - NewQn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-10, - Qn10, NewQn10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, NewQn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-9, - Qn9, NewQn9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, NewQn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-8, - Qn8, NewQn8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, NewQn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-7, - Qn7, NewQn7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, NewQn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-6, - Qn6, NewQn6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, NewQn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-5, - Qn5, NewQn5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - NewQn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-4, - Qn4, NewQn4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, NewQn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-3, - Qn3, NewQn3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, NewQn3, Qn2, Qn1}); -?OUT_CURRENT_Qn16(-2, - Qn2, NewQn2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, NewQn2, Qn1}); -?OUT_CURRENT_Qn16(-1, - Qn1, NewQn1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, NewQn1}); -out_current(0, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - {Value, NewQ0} = queue:out(Q0), - if - Value =:= empty -> - out_current(1, Q); - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> 0 end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - NewQ0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end; -?OUT_CURRENT_Qp16(1, - Qp1, NewQp1, - {NewQp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(2, - Qp2, NewQp2, - {Qp1, NewQp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(3, - Qp3, NewQp3, - {Qp1, Qp2, NewQp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(4, - Qp4, NewQp4, - {Qp1, Qp2, Qp3, NewQp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(5, - Qp5, NewQp5, - {Qp1, Qp2, Qp3, Qp4, NewQp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(6, - Qp6, NewQp6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - NewQp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(7, - Qp7, NewQp7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, NewQp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(8, - Qp8, NewQp8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, NewQp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(9, - Qp9, NewQp9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, NewQp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(10, - Qp10, NewQp10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, NewQp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(11, - Qp11, NewQp11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, NewQp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(12, - Qp12, NewQp12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - NewQp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(13, - Qp13, NewQp13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, NewQp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(14, - Qp14, NewQp14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, NewQp14, Qp15, Qp16}); -?OUT_CURRENT_Qp16(15, - Qp15, NewQp15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, NewQp15, Qp16}); -?OUT_CURRENT_Qp16(16, - Qp16, NewQp16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, NewQp16}); -?OUT_CURRENT_Qp32(17, - Qp17, NewQp17, - {NewQp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(18, - Qp18, NewQp18, - {Qp17, NewQp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(19, - Qp19, NewQp19, - {Qp17, Qp18, NewQp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(20, - Qp20, NewQp20, - {Qp17, Qp18, Qp19, NewQp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(21, - Qp21, NewQp21, - {Qp17, Qp18, Qp19, Qp20, NewQp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(22, - Qp22, NewQp22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - NewQp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(23, - Qp23, NewQp23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, NewQp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(24, - Qp24, NewQp24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, NewQp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(25, - Qp25, NewQp25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, NewQp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(26, - Qp26, NewQp26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, NewQp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(27, - Qp27, NewQp27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, NewQp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(28, - Qp28, NewQp28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - NewQp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(29, - Qp29, NewQp29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, NewQp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(30, - Qp30, NewQp30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, NewQp30, Qp31, Qp32}); -?OUT_CURRENT_Qp32(31, - Qp31, NewQp31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, NewQp31, Qp32}); -?OUT_CURRENT_Qp32(32, - Qp32, NewQp32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, NewQp32}); -?OUT_CURRENT_Qp48(33, - Qp33, NewQp33, - {NewQp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(34, - Qp34, NewQp34, - {Qp33, NewQp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(35, - Qp35, NewQp35, - {Qp33, Qp34, NewQp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(36, - Qp36, NewQp36, - {Qp33, Qp34, Qp35, NewQp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(37, - Qp37, NewQp37, - {Qp33, Qp34, Qp35, Qp36, NewQp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(38, - Qp38, NewQp38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - NewQp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(39, - Qp39, NewQp39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, NewQp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(40, - Qp40, NewQp40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, NewQp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(41, - Qp41, NewQp41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, NewQp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(42, - Qp42, NewQp42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, NewQp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(43, - Qp43, NewQp43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, NewQp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(44, - Qp44, NewQp44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - NewQp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(45, - Qp45, NewQp45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, NewQp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(46, - Qp46, NewQp46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, NewQp46, Qp47, Qp48}); -?OUT_CURRENT_Qp48(47, - Qp47, NewQp47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, NewQp47, Qp48}); -?OUT_CURRENT_Qp48(48, - Qp48, NewQp48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, NewQp48}); -?OUT_CURRENT_Qp64(49, - Qp49, NewQp49, - {NewQp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(50, - Qp50, NewQp50, - {Qp49, NewQp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(51, - Qp51, NewQp51, - {Qp49, Qp50, NewQp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(52, - Qp52, NewQp52, - {Qp49, Qp50, Qp51, NewQp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(53, - Qp53, NewQp53, - {Qp49, Qp50, Qp51, Qp52, NewQp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(54, - Qp54, NewQp54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - NewQp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(55, - Qp55, NewQp55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, NewQp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(56, - Qp56, NewQp56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, NewQp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(57, - Qp57, NewQp57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, NewQp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(58, - Qp58, NewQp58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, NewQp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(59, - Qp59, NewQp59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, NewQp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(60, - Qp60, NewQp60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - NewQp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(61, - Qp61, NewQp61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, NewQp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(62, - Qp62, NewQp62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, NewQp62, Qp63, Qp64}); -?OUT_CURRENT_Qp64(63, - Qp63, NewQp63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, NewQp63, Qp64}); -?OUT_CURRENT_Qp64(64, - Qp64, NewQp64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, NewQp64}); -?OUT_CURRENT_Qp80(65, - Qp65, NewQp65, - {NewQp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(66, - Qp66, NewQp66, - {Qp65, NewQp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(67, - Qp67, NewQp67, - {Qp65, Qp66, NewQp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(68, - Qp68, NewQp68, - {Qp65, Qp66, Qp67, NewQp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(69, - Qp69, NewQp69, - {Qp65, Qp66, Qp67, Qp68, NewQp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(70, - Qp70, NewQp70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - NewQp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(71, - Qp71, NewQp71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, NewQp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(72, - Qp72, NewQp72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, NewQp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(73, - Qp73, NewQp73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, NewQp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(74, - Qp74, NewQp74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, NewQp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(75, - Qp75, NewQp75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, NewQp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(76, - Qp76, NewQp76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - NewQp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(77, - Qp77, NewQp77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, NewQp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(78, - Qp78, NewQp78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, NewQp78, Qp79, Qp80}); -?OUT_CURRENT_Qp80(79, - Qp79, NewQp79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, NewQp79, Qp80}); -?OUT_CURRENT_Qp80(80, - Qp80, NewQp80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, NewQp80}); -?OUT_CURRENT_Qp96(81, - Qp81, NewQp81, - {NewQp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(82, - Qp82, NewQp82, - {Qp81, NewQp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(83, - Qp83, NewQp83, - {Qp81, Qp82, NewQp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(84, - Qp84, NewQp84, - {Qp81, Qp82, Qp83, NewQp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(85, - Qp85, NewQp85, - {Qp81, Qp82, Qp83, Qp84, NewQp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(86, - Qp86, NewQp86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - NewQp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(87, - Qp87, NewQp87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, NewQp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(88, - Qp88, NewQp88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, NewQp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(89, - Qp89, NewQp89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, NewQp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(90, - Qp90, NewQp90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, NewQp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(91, - Qp91, NewQp91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, NewQp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(92, - Qp92, NewQp92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - NewQp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(93, - Qp93, NewQp93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, NewQp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(94, - Qp94, NewQp94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, NewQp94, Qp95, Qp96}); -?OUT_CURRENT_Qp96(95, - Qp95, NewQp95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, NewQp95, Qp96}); -?OUT_CURRENT_Qp96(96, - Qp96, NewQp96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, NewQp96}); -?OUT_CURRENT_Qp112(97, - Qp97, NewQp97, - {NewQp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(98, - Qp98, NewQp98, - {Qp97, NewQp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(99, - Qp99, NewQp99, - {Qp97, Qp98, NewQp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(100, - Qp100, NewQp100, - {Qp97, Qp98, Qp99, NewQp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(101, - Qp101, NewQp101, - {Qp97, Qp98, Qp99, Qp100, NewQp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(102, - Qp102, NewQp102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - NewQp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(103, - Qp103, NewQp103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, NewQp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(104, - Qp104, NewQp104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, NewQp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(105, - Qp105, NewQp105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, NewQp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(106, - Qp106, NewQp106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, NewQp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(107, - Qp107, NewQp107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, NewQp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(108, - Qp108, NewQp108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - NewQp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(109, - Qp109, NewQp109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, NewQp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(110, - Qp110, NewQp110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, NewQp110, Qp111, Qp112}); -?OUT_CURRENT_Qp112(111, - Qp111, NewQp111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, NewQp111, Qp112}); -?OUT_CURRENT_Qp112(112, - Qp112, NewQp112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, NewQp112}); -?OUT_CURRENT_Qp128(113, - Qp113, NewQp113, - {NewQp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(114, - Qp114, NewQp114, - {Qp113, NewQp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(115, - Qp115, NewQp115, - {Qp113, Qp114, NewQp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(116, - Qp116, NewQp116, - {Qp113, Qp114, Qp115, NewQp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(117, - Qp117, NewQp117, - {Qp113, Qp114, Qp115, Qp116, NewQp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(118, - Qp118, NewQp118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - NewQp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(119, - Qp119, NewQp119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, NewQp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(120, - Qp120, NewQp120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, NewQp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(121, - Qp121, NewQp121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, NewQp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(122, - Qp122, NewQp122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, NewQp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(123, - Qp123, NewQp123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, NewQp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(124, - Qp124, NewQp124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - NewQp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(125, - Qp125, NewQp125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, NewQp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(126, - Qp126, NewQp126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, NewQp126, Qp127, Qp128}); -?OUT_CURRENT_Qp128(127, - Qp127, NewQp127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, NewQp127, Qp128}); -out_current(128, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}) -> - {Value, NewQp128} = queue:out(Qp128), - if - Value =:= empty -> - {empty, - {empty, - 0, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, NewQp128}}}; - true -> - NewSize = Size - 1, - {Value, - {if NewSize == 0 -> empty; true -> 128 end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, NewQp128}}} - end. - -%% @hidden --define(OUT_CURRENT_P_Qn128(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - V3, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn112(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, - V3, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn96(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, - V3, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn80(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, - V3, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn64(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, - V3, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn48(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, - V3, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn32(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V3, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qn16(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V3, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp16(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V3, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp32(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V3, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp48(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V3, - Qp64, Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp64(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V3, - Qp80, Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp80(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V3, - Qp96, Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp96(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V3, - Qp112, Qp128}} - end). --define(OUT_CURRENT_P_Qp112(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V3, - Qp128}} - end). --define(OUT_CURRENT_P_Qp128(P, V1, V2, V3), -out_current_p(P, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}} = Q) -> - case queue:out(V1) of - {empty, _} -> - out_current_p(P + 1, Q); - {{value, X}, V2} -> - NewSize = Size - 1, - {{value, X, P}, - {if NewSize == 0 -> empty; true -> P end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V3}} - end). - -?OUT_CURRENT_P_Qn128(-128, - Qn128, NewQn128, - {NewQn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-127, - Qn127, NewQn127, - {Qn128, NewQn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-126, - Qn126, NewQn126, - {Qn128, Qn127, NewQn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-125, - Qn125, NewQn125, - {Qn128, Qn127, Qn126, NewQn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-124, - Qn124, NewQn124, - {Qn128, Qn127, Qn126, Qn125, NewQn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-123, - Qn123, NewQn123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - NewQn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-122, - Qn122, NewQn122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, NewQn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-121, - Qn121, NewQn121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, NewQn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-120, - Qn120, NewQn120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, NewQn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-119, - Qn119, NewQn119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, NewQn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-118, - Qn118, NewQn118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, NewQn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-117, - Qn117, NewQn117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - NewQn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-116, - Qn116, NewQn116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, NewQn116, Qn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-115, - Qn115, NewQn115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, NewQn115, Qn114, Qn113}); -?OUT_CURRENT_P_Qn128(-114, - Qn114, NewQn114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, NewQn114, Qn113}); -?OUT_CURRENT_P_Qn128(-113, - Qn113, NewQn113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, NewQn113}); -?OUT_CURRENT_P_Qn112(-112, - Qn112, NewQn112, - {NewQn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-111, - Qn111, NewQn111, - {Qn112, NewQn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-110, - Qn110, NewQn110, - {Qn112, Qn111, NewQn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-109, - Qn109, NewQn109, - {Qn112, Qn111, Qn110, NewQn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-108, - Qn108, NewQn108, - {Qn112, Qn111, Qn110, Qn109, NewQn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-107, - Qn107, NewQn107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - NewQn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-106, - Qn106, NewQn106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, NewQn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-105, - Qn105, NewQn105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, NewQn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-104, - Qn104, NewQn104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, NewQn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-103, - Qn103, NewQn103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, NewQn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-102, - Qn102, NewQn102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, NewQn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-101, - Qn101, NewQn101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - NewQn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-100, - Qn100, NewQn100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, NewQn100, Qn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-99, - Qn99, NewQn99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, NewQn99, Qn98, Qn97}); -?OUT_CURRENT_P_Qn112(-98, - Qn98, NewQn98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, NewQn98, Qn97}); -?OUT_CURRENT_P_Qn112(-97, - Qn97, NewQn97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, NewQn97}); -?OUT_CURRENT_P_Qn96(-96, - Qn96, NewQn96, - {NewQn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-95, - Qn95, NewQn95, - {Qn96, NewQn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-94, - Qn94, NewQn94, - {Qn96, Qn95, NewQn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-93, - Qn93, NewQn93, - {Qn96, Qn95, Qn94, NewQn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-92, - Qn92, NewQn92, - {Qn96, Qn95, Qn94, Qn93, NewQn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-91, - Qn91, NewQn91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - NewQn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-90, - Qn90, NewQn90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, NewQn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-89, - Qn89, NewQn89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, NewQn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-88, - Qn88, NewQn88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, NewQn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-87, - Qn87, NewQn87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, NewQn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-86, - Qn86, NewQn86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, NewQn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-85, - Qn85, NewQn85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - NewQn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-84, - Qn84, NewQn84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, NewQn84, Qn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-83, - Qn83, NewQn83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, NewQn83, Qn82, Qn81}); -?OUT_CURRENT_P_Qn96(-82, - Qn82, NewQn82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, NewQn82, Qn81}); -?OUT_CURRENT_P_Qn96(-81, - Qn81, NewQn81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, NewQn81}); -?OUT_CURRENT_P_Qn80(-80, - Qn80, NewQn80, - {NewQn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-79, - Qn79, NewQn79, - {Qn80, NewQn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-78, - Qn78, NewQn78, - {Qn80, Qn79, NewQn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-77, - Qn77, NewQn77, - {Qn80, Qn79, Qn78, NewQn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-76, - Qn76, NewQn76, - {Qn80, Qn79, Qn78, Qn77, NewQn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-75, - Qn75, NewQn75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - NewQn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-74, - Qn74, NewQn74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, NewQn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-73, - Qn73, NewQn73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, NewQn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-72, - Qn72, NewQn72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, NewQn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-71, - Qn71, NewQn71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, NewQn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-70, - Qn70, NewQn70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, NewQn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-69, - Qn69, NewQn69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - NewQn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-68, - Qn68, NewQn68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, NewQn68, Qn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-67, - Qn67, NewQn67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, NewQn67, Qn66, Qn65}); -?OUT_CURRENT_P_Qn80(-66, - Qn66, NewQn66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, NewQn66, Qn65}); -?OUT_CURRENT_P_Qn80(-65, - Qn65, NewQn65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, NewQn65}); -?OUT_CURRENT_P_Qn64(-64, - Qn64, NewQn64, - {NewQn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-63, - Qn63, NewQn63, - {Qn64, NewQn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-62, - Qn62, NewQn62, - {Qn64, Qn63, NewQn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-61, - Qn61, NewQn61, - {Qn64, Qn63, Qn62, NewQn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-60, - Qn60, NewQn60, - {Qn64, Qn63, Qn62, Qn61, NewQn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-59, - Qn59, NewQn59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - NewQn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-58, - Qn58, NewQn58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, NewQn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-57, - Qn57, NewQn57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, NewQn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-56, - Qn56, NewQn56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, NewQn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-55, - Qn55, NewQn55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, NewQn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-54, - Qn54, NewQn54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, NewQn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-53, - Qn53, NewQn53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - NewQn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-52, - Qn52, NewQn52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, NewQn52, Qn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-51, - Qn51, NewQn51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, NewQn51, Qn50, Qn49}); -?OUT_CURRENT_P_Qn64(-50, - Qn50, NewQn50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, NewQn50, Qn49}); -?OUT_CURRENT_P_Qn64(-49, - Qn49, NewQn49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, NewQn49}); -?OUT_CURRENT_P_Qn48(-48, - Qn48, NewQn48, - {NewQn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-47, - Qn47, NewQn47, - {Qn48, NewQn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-46, - Qn46, NewQn46, - {Qn48, Qn47, NewQn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-45, - Qn45, NewQn45, - {Qn48, Qn47, Qn46, NewQn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-44, - Qn44, NewQn44, - {Qn48, Qn47, Qn46, Qn45, NewQn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-43, - Qn43, NewQn43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - NewQn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-42, - Qn42, NewQn42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, NewQn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-41, - Qn41, NewQn41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, NewQn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-40, - Qn40, NewQn40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, NewQn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-39, - Qn39, NewQn39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, NewQn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-38, - Qn38, NewQn38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, NewQn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-37, - Qn37, NewQn37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - NewQn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-36, - Qn36, NewQn36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, NewQn36, Qn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-35, - Qn35, NewQn35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, NewQn35, Qn34, Qn33}); -?OUT_CURRENT_P_Qn48(-34, - Qn34, NewQn34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, NewQn34, Qn33}); -?OUT_CURRENT_P_Qn48(-33, - Qn33, NewQn33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, NewQn33}); -?OUT_CURRENT_P_Qn32(-32, - Qn32, NewQn32, - {NewQn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-31, - Qn31, NewQn31, - {Qn32, NewQn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-30, - Qn30, NewQn30, - {Qn32, Qn31, NewQn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-29, - Qn29, NewQn29, - {Qn32, Qn31, Qn30, NewQn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-28, - Qn28, NewQn28, - {Qn32, Qn31, Qn30, Qn29, NewQn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-27, - Qn27, NewQn27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - NewQn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-26, - Qn26, NewQn26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, NewQn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-25, - Qn25, NewQn25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, NewQn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-24, - Qn24, NewQn24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, NewQn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-23, - Qn23, NewQn23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, NewQn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-22, - Qn22, NewQn22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, NewQn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-21, - Qn21, NewQn21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - NewQn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-20, - Qn20, NewQn20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, NewQn20, Qn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-19, - Qn19, NewQn19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, NewQn19, Qn18, Qn17}); -?OUT_CURRENT_P_Qn32(-18, - Qn18, NewQn18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, NewQn18, Qn17}); -?OUT_CURRENT_P_Qn32(-17, - Qn17, NewQn17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, NewQn17}); -?OUT_CURRENT_P_Qn16(-16, - Qn16, NewQn16, - {NewQn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-15, - Qn15, NewQn15, - {Qn16, NewQn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-14, - Qn14, NewQn14, - {Qn16, Qn15, NewQn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-13, - Qn13, NewQn13, - {Qn16, Qn15, Qn14, NewQn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-12, - Qn12, NewQn12, - {Qn16, Qn15, Qn14, Qn13, NewQn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-11, - Qn11, NewQn11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - NewQn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-10, - Qn10, NewQn10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, NewQn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-9, - Qn9, NewQn9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, NewQn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-8, - Qn8, NewQn8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, NewQn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-7, - Qn7, NewQn7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, NewQn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-6, - Qn6, NewQn6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, NewQn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-5, - Qn5, NewQn5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - NewQn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-4, - Qn4, NewQn4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, NewQn4, Qn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-3, - Qn3, NewQn3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, NewQn3, Qn2, Qn1}); -?OUT_CURRENT_P_Qn16(-2, - Qn2, NewQn2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, NewQn2, Qn1}); -?OUT_CURRENT_P_Qn16(-1, - Qn1, NewQn1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, NewQn1}); -out_current_p(0, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128} = Q) -> - case queue:out(Q0) of - {empty, _} -> - out_current_p(1, Q); - {{value, X}, NewQ0} -> - NewSize = Size - 1, - {{value, X, 0}, - {if NewSize == 0 -> empty; true -> 0 end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - NewQ0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}} - end; -?OUT_CURRENT_P_Qp16(1, - Qp1, NewQp1, - {NewQp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(2, - Qp2, NewQp2, - {Qp1, NewQp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(3, - Qp3, NewQp3, - {Qp1, Qp2, NewQp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(4, - Qp4, NewQp4, - {Qp1, Qp2, Qp3, NewQp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(5, - Qp5, NewQp5, - {Qp1, Qp2, Qp3, Qp4, NewQp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(6, - Qp6, NewQp6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - NewQp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(7, - Qp7, NewQp7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, NewQp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(8, - Qp8, NewQp8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, NewQp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(9, - Qp9, NewQp9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, NewQp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(10, - Qp10, NewQp10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, NewQp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(11, - Qp11, NewQp11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, NewQp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(12, - Qp12, NewQp12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - NewQp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(13, - Qp13, NewQp13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, NewQp13, Qp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(14, - Qp14, NewQp14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, NewQp14, Qp15, Qp16}); -?OUT_CURRENT_P_Qp16(15, - Qp15, NewQp15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, NewQp15, Qp16}); -?OUT_CURRENT_P_Qp16(16, - Qp16, NewQp16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, NewQp16}); -?OUT_CURRENT_P_Qp32(17, - Qp17, NewQp17, - {NewQp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(18, - Qp18, NewQp18, - {Qp17, NewQp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(19, - Qp19, NewQp19, - {Qp17, Qp18, NewQp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(20, - Qp20, NewQp20, - {Qp17, Qp18, Qp19, NewQp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(21, - Qp21, NewQp21, - {Qp17, Qp18, Qp19, Qp20, NewQp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(22, - Qp22, NewQp22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - NewQp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(23, - Qp23, NewQp23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, NewQp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(24, - Qp24, NewQp24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, NewQp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(25, - Qp25, NewQp25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, NewQp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(26, - Qp26, NewQp26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, NewQp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(27, - Qp27, NewQp27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, NewQp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(28, - Qp28, NewQp28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - NewQp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(29, - Qp29, NewQp29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, NewQp29, Qp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(30, - Qp30, NewQp30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, NewQp30, Qp31, Qp32}); -?OUT_CURRENT_P_Qp32(31, - Qp31, NewQp31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, NewQp31, Qp32}); -?OUT_CURRENT_P_Qp32(32, - Qp32, NewQp32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, NewQp32}); -?OUT_CURRENT_P_Qp48(33, - Qp33, NewQp33, - {NewQp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(34, - Qp34, NewQp34, - {Qp33, NewQp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(35, - Qp35, NewQp35, - {Qp33, Qp34, NewQp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(36, - Qp36, NewQp36, - {Qp33, Qp34, Qp35, NewQp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(37, - Qp37, NewQp37, - {Qp33, Qp34, Qp35, Qp36, NewQp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(38, - Qp38, NewQp38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - NewQp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(39, - Qp39, NewQp39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, NewQp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(40, - Qp40, NewQp40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, NewQp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(41, - Qp41, NewQp41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, NewQp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(42, - Qp42, NewQp42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, NewQp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(43, - Qp43, NewQp43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, NewQp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(44, - Qp44, NewQp44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - NewQp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(45, - Qp45, NewQp45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, NewQp45, Qp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(46, - Qp46, NewQp46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, NewQp46, Qp47, Qp48}); -?OUT_CURRENT_P_Qp48(47, - Qp47, NewQp47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, NewQp47, Qp48}); -?OUT_CURRENT_P_Qp48(48, - Qp48, NewQp48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, NewQp48}); -?OUT_CURRENT_P_Qp64(49, - Qp49, NewQp49, - {NewQp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(50, - Qp50, NewQp50, - {Qp49, NewQp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(51, - Qp51, NewQp51, - {Qp49, Qp50, NewQp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(52, - Qp52, NewQp52, - {Qp49, Qp50, Qp51, NewQp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(53, - Qp53, NewQp53, - {Qp49, Qp50, Qp51, Qp52, NewQp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(54, - Qp54, NewQp54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - NewQp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(55, - Qp55, NewQp55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, NewQp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(56, - Qp56, NewQp56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, NewQp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(57, - Qp57, NewQp57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, NewQp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(58, - Qp58, NewQp58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, NewQp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(59, - Qp59, NewQp59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, NewQp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(60, - Qp60, NewQp60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - NewQp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(61, - Qp61, NewQp61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, NewQp61, Qp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(62, - Qp62, NewQp62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, NewQp62, Qp63, Qp64}); -?OUT_CURRENT_P_Qp64(63, - Qp63, NewQp63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, NewQp63, Qp64}); -?OUT_CURRENT_P_Qp64(64, - Qp64, NewQp64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, NewQp64}); -?OUT_CURRENT_P_Qp80(65, - Qp65, NewQp65, - {NewQp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(66, - Qp66, NewQp66, - {Qp65, NewQp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(67, - Qp67, NewQp67, - {Qp65, Qp66, NewQp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(68, - Qp68, NewQp68, - {Qp65, Qp66, Qp67, NewQp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(69, - Qp69, NewQp69, - {Qp65, Qp66, Qp67, Qp68, NewQp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(70, - Qp70, NewQp70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - NewQp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(71, - Qp71, NewQp71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, NewQp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(72, - Qp72, NewQp72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, NewQp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(73, - Qp73, NewQp73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, NewQp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(74, - Qp74, NewQp74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, NewQp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(75, - Qp75, NewQp75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, NewQp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(76, - Qp76, NewQp76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - NewQp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(77, - Qp77, NewQp77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, NewQp77, Qp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(78, - Qp78, NewQp78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, NewQp78, Qp79, Qp80}); -?OUT_CURRENT_P_Qp80(79, - Qp79, NewQp79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, NewQp79, Qp80}); -?OUT_CURRENT_P_Qp80(80, - Qp80, NewQp80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, NewQp80}); -?OUT_CURRENT_P_Qp96(81, - Qp81, NewQp81, - {NewQp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(82, - Qp82, NewQp82, - {Qp81, NewQp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(83, - Qp83, NewQp83, - {Qp81, Qp82, NewQp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(84, - Qp84, NewQp84, - {Qp81, Qp82, Qp83, NewQp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(85, - Qp85, NewQp85, - {Qp81, Qp82, Qp83, Qp84, NewQp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(86, - Qp86, NewQp86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - NewQp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(87, - Qp87, NewQp87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, NewQp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(88, - Qp88, NewQp88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, NewQp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(89, - Qp89, NewQp89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, NewQp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(90, - Qp90, NewQp90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, NewQp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(91, - Qp91, NewQp91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, NewQp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(92, - Qp92, NewQp92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - NewQp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(93, - Qp93, NewQp93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, NewQp93, Qp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(94, - Qp94, NewQp94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, NewQp94, Qp95, Qp96}); -?OUT_CURRENT_P_Qp96(95, - Qp95, NewQp95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, NewQp95, Qp96}); -?OUT_CURRENT_P_Qp96(96, - Qp96, NewQp96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, NewQp96}); -?OUT_CURRENT_P_Qp112(97, - Qp97, NewQp97, - {NewQp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(98, - Qp98, NewQp98, - {Qp97, NewQp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(99, - Qp99, NewQp99, - {Qp97, Qp98, NewQp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(100, - Qp100, NewQp100, - {Qp97, Qp98, Qp99, NewQp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(101, - Qp101, NewQp101, - {Qp97, Qp98, Qp99, Qp100, NewQp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(102, - Qp102, NewQp102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - NewQp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(103, - Qp103, NewQp103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, NewQp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(104, - Qp104, NewQp104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, NewQp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(105, - Qp105, NewQp105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, NewQp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(106, - Qp106, NewQp106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, NewQp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(107, - Qp107, NewQp107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, NewQp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(108, - Qp108, NewQp108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - NewQp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(109, - Qp109, NewQp109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, NewQp109, Qp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(110, - Qp110, NewQp110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, NewQp110, Qp111, Qp112}); -?OUT_CURRENT_P_Qp112(111, - Qp111, NewQp111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, NewQp111, Qp112}); -?OUT_CURRENT_P_Qp112(112, - Qp112, NewQp112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, NewQp112}); -?OUT_CURRENT_P_Qp128(113, - Qp113, NewQp113, - {NewQp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(114, - Qp114, NewQp114, - {Qp113, NewQp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(115, - Qp115, NewQp115, - {Qp113, Qp114, NewQp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(116, - Qp116, NewQp116, - {Qp113, Qp114, Qp115, NewQp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(117, - Qp117, NewQp117, - {Qp113, Qp114, Qp115, Qp116, NewQp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(118, - Qp118, NewQp118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - NewQp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(119, - Qp119, NewQp119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, NewQp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(120, - Qp120, NewQp120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, NewQp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(121, - Qp121, NewQp121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, NewQp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(122, - Qp122, NewQp122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, NewQp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(123, - Qp123, NewQp123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, NewQp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(124, - Qp124, NewQp124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - NewQp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(125, - Qp125, NewQp125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, NewQp125, Qp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(126, - Qp126, NewQp126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, NewQp126, Qp127, Qp128}); -?OUT_CURRENT_P_Qp128(127, - Qp127, NewQp127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, NewQp127, Qp128}); -out_current_p(128, - {_, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}) -> - case queue:out(Qp128) of - {empty, _} -> - {empty, - {empty, - 0, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}}; - {{value, X}, NewQp128} -> - NewSize = Size - 1, - {{value, X, 128}, - {if NewSize == 0 -> empty; true -> 128 end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, NewQp128}}} - end. - -%% @hidden --define(OUT_SPECIFIC_Qn128(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - V3, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn112(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, - V3, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn96(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, - V3, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn80(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, - V3, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn64(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, - V3, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn48(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, - V3, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn32(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V3, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qn16(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V3, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp16(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V3, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp32(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V3, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp48(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V3, - Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp64(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V3, - Qp80, Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp80(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V3, - Qp96, Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp96(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V3, - Qp112, Qp128}}). --define(OUT_SPECIFIC_Qp112(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V3, - Qp128}}). --define(OUT_SPECIFIC_Qp128(P, V1, V2, V3), -out_specific(P, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}) -> - {Value, V2} = queue:out(V1), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V3}}). - -?OUT_SPECIFIC_Qn128(-128, - Qn128, NewQn128, - {NewQn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-127, - Qn127, NewQn127, - {Qn128, NewQn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-126, - Qn126, NewQn126, - {Qn128, Qn127, NewQn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-125, - Qn125, NewQn125, - {Qn128, Qn127, Qn126, NewQn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-124, - Qn124, NewQn124, - {Qn128, Qn127, Qn126, Qn125, NewQn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-123, - Qn123, NewQn123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - NewQn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-122, - Qn122, NewQn122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, NewQn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-121, - Qn121, NewQn121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, NewQn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-120, - Qn120, NewQn120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, NewQn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-119, - Qn119, NewQn119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, NewQn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-118, - Qn118, NewQn118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, NewQn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-117, - Qn117, NewQn117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - NewQn117, Qn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-116, - Qn116, NewQn116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, NewQn116, Qn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-115, - Qn115, NewQn115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, NewQn115, Qn114, Qn113}); -?OUT_SPECIFIC_Qn128(-114, - Qn114, NewQn114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, NewQn114, Qn113}); -?OUT_SPECIFIC_Qn128(-113, - Qn113, NewQn113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, NewQn113}); -?OUT_SPECIFIC_Qn112(-112, - Qn112, NewQn112, - {NewQn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-111, - Qn111, NewQn111, - {Qn112, NewQn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-110, - Qn110, NewQn110, - {Qn112, Qn111, NewQn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-109, - Qn109, NewQn109, - {Qn112, Qn111, Qn110, NewQn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-108, - Qn108, NewQn108, - {Qn112, Qn111, Qn110, Qn109, NewQn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-107, - Qn107, NewQn107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - NewQn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-106, - Qn106, NewQn106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, NewQn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-105, - Qn105, NewQn105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, NewQn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-104, - Qn104, NewQn104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, NewQn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-103, - Qn103, NewQn103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, NewQn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-102, - Qn102, NewQn102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, NewQn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-101, - Qn101, NewQn101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - NewQn101, Qn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-100, - Qn100, NewQn100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, NewQn100, Qn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-99, - Qn99, NewQn99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, NewQn99, Qn98, Qn97}); -?OUT_SPECIFIC_Qn112(-98, - Qn98, NewQn98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, NewQn98, Qn97}); -?OUT_SPECIFIC_Qn112(-97, - Qn97, NewQn97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, NewQn97}); -?OUT_SPECIFIC_Qn96(-96, - Qn96, NewQn96, - {NewQn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-95, - Qn95, NewQn95, - {Qn96, NewQn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-94, - Qn94, NewQn94, - {Qn96, Qn95, NewQn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-93, - Qn93, NewQn93, - {Qn96, Qn95, Qn94, NewQn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-92, - Qn92, NewQn92, - {Qn96, Qn95, Qn94, Qn93, NewQn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-91, - Qn91, NewQn91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - NewQn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-90, - Qn90, NewQn90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, NewQn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-89, - Qn89, NewQn89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, NewQn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-88, - Qn88, NewQn88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, NewQn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-87, - Qn87, NewQn87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, NewQn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-86, - Qn86, NewQn86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, NewQn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-85, - Qn85, NewQn85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - NewQn85, Qn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-84, - Qn84, NewQn84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, NewQn84, Qn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-83, - Qn83, NewQn83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, NewQn83, Qn82, Qn81}); -?OUT_SPECIFIC_Qn96(-82, - Qn82, NewQn82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, NewQn82, Qn81}); -?OUT_SPECIFIC_Qn96(-81, - Qn81, NewQn81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, NewQn81}); -?OUT_SPECIFIC_Qn80(-80, - Qn80, NewQn80, - {NewQn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-79, - Qn79, NewQn79, - {Qn80, NewQn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-78, - Qn78, NewQn78, - {Qn80, Qn79, NewQn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-77, - Qn77, NewQn77, - {Qn80, Qn79, Qn78, NewQn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-76, - Qn76, NewQn76, - {Qn80, Qn79, Qn78, Qn77, NewQn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-75, - Qn75, NewQn75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - NewQn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-74, - Qn74, NewQn74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, NewQn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-73, - Qn73, NewQn73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, NewQn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-72, - Qn72, NewQn72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, NewQn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-71, - Qn71, NewQn71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, NewQn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-70, - Qn70, NewQn70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, NewQn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-69, - Qn69, NewQn69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - NewQn69, Qn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-68, - Qn68, NewQn68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, NewQn68, Qn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-67, - Qn67, NewQn67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, NewQn67, Qn66, Qn65}); -?OUT_SPECIFIC_Qn80(-66, - Qn66, NewQn66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, NewQn66, Qn65}); -?OUT_SPECIFIC_Qn80(-65, - Qn65, NewQn65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, NewQn65}); -?OUT_SPECIFIC_Qn64(-64, - Qn64, NewQn64, - {NewQn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-63, - Qn63, NewQn63, - {Qn64, NewQn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-62, - Qn62, NewQn62, - {Qn64, Qn63, NewQn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-61, - Qn61, NewQn61, - {Qn64, Qn63, Qn62, NewQn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-60, - Qn60, NewQn60, - {Qn64, Qn63, Qn62, Qn61, NewQn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-59, - Qn59, NewQn59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - NewQn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-58, - Qn58, NewQn58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, NewQn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-57, - Qn57, NewQn57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, NewQn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-56, - Qn56, NewQn56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, NewQn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-55, - Qn55, NewQn55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, NewQn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-54, - Qn54, NewQn54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, NewQn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-53, - Qn53, NewQn53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - NewQn53, Qn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-52, - Qn52, NewQn52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, NewQn52, Qn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-51, - Qn51, NewQn51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, NewQn51, Qn50, Qn49}); -?OUT_SPECIFIC_Qn64(-50, - Qn50, NewQn50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, NewQn50, Qn49}); -?OUT_SPECIFIC_Qn64(-49, - Qn49, NewQn49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, NewQn49}); -?OUT_SPECIFIC_Qn48(-48, - Qn48, NewQn48, - {NewQn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-47, - Qn47, NewQn47, - {Qn48, NewQn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-46, - Qn46, NewQn46, - {Qn48, Qn47, NewQn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-45, - Qn45, NewQn45, - {Qn48, Qn47, Qn46, NewQn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-44, - Qn44, NewQn44, - {Qn48, Qn47, Qn46, Qn45, NewQn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-43, - Qn43, NewQn43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - NewQn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-42, - Qn42, NewQn42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, NewQn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-41, - Qn41, NewQn41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, NewQn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-40, - Qn40, NewQn40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, NewQn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-39, - Qn39, NewQn39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, NewQn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-38, - Qn38, NewQn38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, NewQn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-37, - Qn37, NewQn37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - NewQn37, Qn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-36, - Qn36, NewQn36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, NewQn36, Qn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-35, - Qn35, NewQn35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, NewQn35, Qn34, Qn33}); -?OUT_SPECIFIC_Qn48(-34, - Qn34, NewQn34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, NewQn34, Qn33}); -?OUT_SPECIFIC_Qn48(-33, - Qn33, NewQn33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, NewQn33}); -?OUT_SPECIFIC_Qn32(-32, - Qn32, NewQn32, - {NewQn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-31, - Qn31, NewQn31, - {Qn32, NewQn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-30, - Qn30, NewQn30, - {Qn32, Qn31, NewQn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-29, - Qn29, NewQn29, - {Qn32, Qn31, Qn30, NewQn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-28, - Qn28, NewQn28, - {Qn32, Qn31, Qn30, Qn29, NewQn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-27, - Qn27, NewQn27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - NewQn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-26, - Qn26, NewQn26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, NewQn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-25, - Qn25, NewQn25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, NewQn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-24, - Qn24, NewQn24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, NewQn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-23, - Qn23, NewQn23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, NewQn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-22, - Qn22, NewQn22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, NewQn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-21, - Qn21, NewQn21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - NewQn21, Qn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-20, - Qn20, NewQn20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, NewQn20, Qn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-19, - Qn19, NewQn19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, NewQn19, Qn18, Qn17}); -?OUT_SPECIFIC_Qn32(-18, - Qn18, NewQn18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, NewQn18, Qn17}); -?OUT_SPECIFIC_Qn32(-17, - Qn17, NewQn17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, NewQn17}); -?OUT_SPECIFIC_Qn16(-16, - Qn16, NewQn16, - {NewQn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-15, - Qn15, NewQn15, - {Qn16, NewQn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-14, - Qn14, NewQn14, - {Qn16, Qn15, NewQn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-13, - Qn13, NewQn13, - {Qn16, Qn15, Qn14, NewQn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-12, - Qn12, NewQn12, - {Qn16, Qn15, Qn14, Qn13, NewQn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-11, - Qn11, NewQn11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - NewQn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-10, - Qn10, NewQn10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, NewQn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-9, - Qn9, NewQn9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, NewQn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-8, - Qn8, NewQn8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, NewQn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-7, - Qn7, NewQn7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, NewQn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-6, - Qn6, NewQn6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, NewQn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-5, - Qn5, NewQn5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - NewQn5, Qn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-4, - Qn4, NewQn4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, NewQn4, Qn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-3, - Qn3, NewQn3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, NewQn3, Qn2, Qn1}); -?OUT_SPECIFIC_Qn16(-2, - Qn2, NewQn2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, NewQn2, Qn1}); -?OUT_SPECIFIC_Qn16(-1, - Qn1, NewQn1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, NewQn1}); -out_specific(0, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, NewQ0} = queue:out(Q0), - NewSize = if Value =/= empty -> Size - 1; true -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - NewQ0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}; -?OUT_SPECIFIC_Qp16(1, - Qp1, NewQp1, - {NewQp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(2, - Qp2, NewQp2, - {Qp1, NewQp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(3, - Qp3, NewQp3, - {Qp1, Qp2, NewQp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(4, - Qp4, NewQp4, - {Qp1, Qp2, Qp3, NewQp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(5, - Qp5, NewQp5, - {Qp1, Qp2, Qp3, Qp4, NewQp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(6, - Qp6, NewQp6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - NewQp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(7, - Qp7, NewQp7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, NewQp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(8, - Qp8, NewQp8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, NewQp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(9, - Qp9, NewQp9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, NewQp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(10, - Qp10, NewQp10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, NewQp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(11, - Qp11, NewQp11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, NewQp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(12, - Qp12, NewQp12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - NewQp12, Qp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(13, - Qp13, NewQp13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, NewQp13, Qp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(14, - Qp14, NewQp14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, NewQp14, Qp15, Qp16}); -?OUT_SPECIFIC_Qp16(15, - Qp15, NewQp15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, NewQp15, Qp16}); -?OUT_SPECIFIC_Qp16(16, - Qp16, NewQp16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, NewQp16}); -?OUT_SPECIFIC_Qp32(17, - Qp17, NewQp17, - {NewQp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(18, - Qp18, NewQp18, - {Qp17, NewQp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(19, - Qp19, NewQp19, - {Qp17, Qp18, NewQp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(20, - Qp20, NewQp20, - {Qp17, Qp18, Qp19, NewQp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(21, - Qp21, NewQp21, - {Qp17, Qp18, Qp19, Qp20, NewQp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(22, - Qp22, NewQp22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - NewQp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(23, - Qp23, NewQp23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, NewQp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(24, - Qp24, NewQp24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, NewQp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(25, - Qp25, NewQp25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, NewQp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(26, - Qp26, NewQp26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, NewQp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(27, - Qp27, NewQp27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, NewQp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(28, - Qp28, NewQp28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - NewQp28, Qp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(29, - Qp29, NewQp29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, NewQp29, Qp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(30, - Qp30, NewQp30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, NewQp30, Qp31, Qp32}); -?OUT_SPECIFIC_Qp32(31, - Qp31, NewQp31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, NewQp31, Qp32}); -?OUT_SPECIFIC_Qp32(32, - Qp32, NewQp32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, NewQp32}); -?OUT_SPECIFIC_Qp48(33, - Qp33, NewQp33, - {NewQp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(34, - Qp34, NewQp34, - {Qp33, NewQp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(35, - Qp35, NewQp35, - {Qp33, Qp34, NewQp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(36, - Qp36, NewQp36, - {Qp33, Qp34, Qp35, NewQp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(37, - Qp37, NewQp37, - {Qp33, Qp34, Qp35, Qp36, NewQp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(38, - Qp38, NewQp38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - NewQp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(39, - Qp39, NewQp39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, NewQp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(40, - Qp40, NewQp40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, NewQp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(41, - Qp41, NewQp41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, NewQp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(42, - Qp42, NewQp42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, NewQp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(43, - Qp43, NewQp43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, NewQp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(44, - Qp44, NewQp44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - NewQp44, Qp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(45, - Qp45, NewQp45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, NewQp45, Qp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(46, - Qp46, NewQp46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, NewQp46, Qp47, Qp48}); -?OUT_SPECIFIC_Qp48(47, - Qp47, NewQp47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, NewQp47, Qp48}); -?OUT_SPECIFIC_Qp48(48, - Qp48, NewQp48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, NewQp48}); -?OUT_SPECIFIC_Qp64(49, - Qp49, NewQp49, - {NewQp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(50, - Qp50, NewQp50, - {Qp49, NewQp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(51, - Qp51, NewQp51, - {Qp49, Qp50, NewQp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(52, - Qp52, NewQp52, - {Qp49, Qp50, Qp51, NewQp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(53, - Qp53, NewQp53, - {Qp49, Qp50, Qp51, Qp52, NewQp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(54, - Qp54, NewQp54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - NewQp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(55, - Qp55, NewQp55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, NewQp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(56, - Qp56, NewQp56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, NewQp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(57, - Qp57, NewQp57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, NewQp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(58, - Qp58, NewQp58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, NewQp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(59, - Qp59, NewQp59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, NewQp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(60, - Qp60, NewQp60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - NewQp60, Qp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(61, - Qp61, NewQp61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, NewQp61, Qp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(62, - Qp62, NewQp62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, NewQp62, Qp63, Qp64}); -?OUT_SPECIFIC_Qp64(63, - Qp63, NewQp63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, NewQp63, Qp64}); -?OUT_SPECIFIC_Qp64(64, - Qp64, NewQp64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, NewQp64}); -?OUT_SPECIFIC_Qp80(65, - Qp65, NewQp65, - {NewQp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(66, - Qp66, NewQp66, - {Qp65, NewQp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(67, - Qp67, NewQp67, - {Qp65, Qp66, NewQp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(68, - Qp68, NewQp68, - {Qp65, Qp66, Qp67, NewQp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(69, - Qp69, NewQp69, - {Qp65, Qp66, Qp67, Qp68, NewQp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(70, - Qp70, NewQp70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - NewQp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(71, - Qp71, NewQp71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, NewQp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(72, - Qp72, NewQp72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, NewQp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(73, - Qp73, NewQp73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, NewQp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(74, - Qp74, NewQp74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, NewQp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(75, - Qp75, NewQp75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, NewQp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(76, - Qp76, NewQp76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - NewQp76, Qp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(77, - Qp77, NewQp77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, NewQp77, Qp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(78, - Qp78, NewQp78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, NewQp78, Qp79, Qp80}); -?OUT_SPECIFIC_Qp80(79, - Qp79, NewQp79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, NewQp79, Qp80}); -?OUT_SPECIFIC_Qp80(80, - Qp80, NewQp80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, NewQp80}); -?OUT_SPECIFIC_Qp96(81, - Qp81, NewQp81, - {NewQp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(82, - Qp82, NewQp82, - {Qp81, NewQp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(83, - Qp83, NewQp83, - {Qp81, Qp82, NewQp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(84, - Qp84, NewQp84, - {Qp81, Qp82, Qp83, NewQp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(85, - Qp85, NewQp85, - {Qp81, Qp82, Qp83, Qp84, NewQp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(86, - Qp86, NewQp86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - NewQp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(87, - Qp87, NewQp87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, NewQp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(88, - Qp88, NewQp88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, NewQp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(89, - Qp89, NewQp89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, NewQp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(90, - Qp90, NewQp90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, NewQp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(91, - Qp91, NewQp91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, NewQp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(92, - Qp92, NewQp92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - NewQp92, Qp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(93, - Qp93, NewQp93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, NewQp93, Qp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(94, - Qp94, NewQp94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, NewQp94, Qp95, Qp96}); -?OUT_SPECIFIC_Qp96(95, - Qp95, NewQp95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, NewQp95, Qp96}); -?OUT_SPECIFIC_Qp96(96, - Qp96, NewQp96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, NewQp96}); -?OUT_SPECIFIC_Qp112(97, - Qp97, NewQp97, - {NewQp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(98, - Qp98, NewQp98, - {Qp97, NewQp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(99, - Qp99, NewQp99, - {Qp97, Qp98, NewQp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(100, - Qp100, NewQp100, - {Qp97, Qp98, Qp99, NewQp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(101, - Qp101, NewQp101, - {Qp97, Qp98, Qp99, Qp100, NewQp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(102, - Qp102, NewQp102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - NewQp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(103, - Qp103, NewQp103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, NewQp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(104, - Qp104, NewQp104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, NewQp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(105, - Qp105, NewQp105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, NewQp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(106, - Qp106, NewQp106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, NewQp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(107, - Qp107, NewQp107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, NewQp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(108, - Qp108, NewQp108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - NewQp108, Qp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(109, - Qp109, NewQp109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, NewQp109, Qp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(110, - Qp110, NewQp110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, NewQp110, Qp111, Qp112}); -?OUT_SPECIFIC_Qp112(111, - Qp111, NewQp111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, NewQp111, Qp112}); -?OUT_SPECIFIC_Qp112(112, - Qp112, NewQp112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, NewQp112}); -?OUT_SPECIFIC_Qp128(113, - Qp113, NewQp113, - {NewQp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(114, - Qp114, NewQp114, - {Qp113, NewQp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(115, - Qp115, NewQp115, - {Qp113, Qp114, NewQp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(116, - Qp116, NewQp116, - {Qp113, Qp114, Qp115, NewQp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(117, - Qp117, NewQp117, - {Qp113, Qp114, Qp115, Qp116, NewQp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(118, - Qp118, NewQp118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - NewQp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(119, - Qp119, NewQp119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, NewQp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(120, - Qp120, NewQp120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, NewQp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(121, - Qp121, NewQp121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, NewQp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(122, - Qp122, NewQp122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, NewQp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(123, - Qp123, NewQp123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, NewQp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(124, - Qp124, NewQp124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - NewQp124, Qp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(125, - Qp125, NewQp125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, NewQp125, Qp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(126, - Qp126, NewQp126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, NewQp126, Qp127, Qp128}); -?OUT_SPECIFIC_Qp128(127, - Qp127, NewQp127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, NewQp127, Qp128}); -?OUT_SPECIFIC_Qp128(128, - Qp128, NewQp128, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, NewQp128}). - -%% @hidden --define(REMOVE_UNIQ_P_Qn128(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - {Qn128, Qn127, Qn126, Qn125, Qn124, Qn123, Qn122, Qn121, - Qn120, Qn119, Qn118, Qn117, Qn116, Qn115, Qn114, Qn113}, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - V3, - Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn112(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, - {Qn112, Qn111, Qn110, Qn109, Qn108, Qn107, Qn106, Qn105, - Qn104, Qn103, Qn102, Qn101, Qn100, Qn99, Qn98, Qn97}, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, - V3, - Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn96(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, - {Qn96, Qn95, Qn94, Qn93, Qn92, Qn91, Qn90, Qn89, - Qn88, Qn87, Qn86, Qn85, Qn84, Qn83, Qn82, Qn81}, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, - V3, - Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn80(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, - {Qn80, Qn79, Qn78, Qn77, Qn76, Qn75, Qn74, Qn73, - Qn72, Qn71, Qn70, Qn69, Qn68, Qn67, Qn66, Qn65}, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, - V3, - Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn64(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, - {Qn64, Qn63, Qn62, Qn61, Qn60, Qn59, Qn58, Qn57, - Qn56, Qn55, Qn54, Qn53, Qn52, Qn51, Qn50, Qn49}, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, - V3, - Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn48(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, - {Qn48, Qn47, Qn46, Qn45, Qn44, Qn43, Qn42, Qn41, - Qn40, Qn39, Qn38, Qn37, Qn36, Qn35, Qn34, Qn33}, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, - V3, - Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn32(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - {Qn32, Qn31, Qn30, Qn29, Qn28, Qn27, Qn26, Qn25, - Qn24, Qn23, Qn22, Qn21, Qn20, Qn19, Qn18, Qn17}, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, - V3, - Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qn16(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - {Qn16, Qn15, Qn14, Qn13, Qn12, Qn11, Qn10, Qn9, - Qn8, Qn7, Qn6, Qn5, Qn4, Qn3, Qn2, Qn1}, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, - V3, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp16(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - {Qp1, Qp2, Qp3, Qp4, Qp5, Qp6, Qp7, Qp8, - Qp9, Qp10, Qp11, Qp12, Qp13, Qp14, Qp15, Qp16}, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - V3, - Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp32(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - {Qp17, Qp18, Qp19, Qp20, Qp21, Qp22, Qp23, Qp24, - Qp25, Qp26, Qp27, Qp28, Qp29, Qp30, Qp31, Qp32}, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, - V3, - Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp48(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - {Qp33, Qp34, Qp35, Qp36, Qp37, Qp38, Qp39, Qp40, - Qp41, Qp42, Qp43, Qp44, Qp45, Qp46, Qp47, Qp48}, - Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, - V3, - Qp64, Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp64(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - {Qp49, Qp50, Qp51, Qp52, Qp53, Qp54, Qp55, Qp56, - Qp57, Qp58, Qp59, Qp60, Qp61, Qp62, Qp63, Qp64}, - Qp80, Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, - V3, - Qp80, Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp80(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - {Qp65, Qp66, Qp67, Qp68, Qp69, Qp70, Qp71, Qp72, - Qp73, Qp74, Qp75, Qp76, Qp77, Qp78, Qp79, Qp80}, - Qp96, Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, - V3, - Qp96, Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp96(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - {Qp81, Qp82, Qp83, Qp84, Qp85, Qp86, Qp87, Qp88, - Qp89, Qp90, Qp91, Qp92, Qp93, Qp94, Qp95, Qp96}, - Qp112, Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, - V3, - Qp112, Qp128}}). --define(REMOVE_UNIQ_P_Qp112(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - {Qp97, Qp98, Qp99, Qp100, Qp101, Qp102, Qp103, Qp104, - Qp105, Qp106, Qp107, Qp108, Qp109, Qp110, Qp111, Qp112}, - Qp128}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, - V3, - Qp128}}). --define(REMOVE_UNIQ_P_Qp128(P, V1, V2, V3), -remove_unique_p(P, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - {Qp113, Qp114, Qp115, Qp116, Qp117, Qp118, Qp119, Qp120, - Qp121, Qp122, Qp123, Qp124, Qp125, Qp126, Qp127, Qp128}}) -> - {Value, V2} = queue_remove_unique(F, V1), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, - V3}}). - -?REMOVE_UNIQ_P_Qn128(-128, - Qn128, NewQn128, - {NewQn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-127, - Qn127, NewQn127, - {Qn128, NewQn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-126, - Qn126, NewQn126, - {Qn128, Qn127, NewQn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-125, - Qn125, NewQn125, - {Qn128, Qn127, Qn126, NewQn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-124, - Qn124, NewQn124, - {Qn128, Qn127, Qn126, Qn125, NewQn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-123, - Qn123, NewQn123, - {Qn128, Qn127, Qn126, Qn125, Qn124, - NewQn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-122, - Qn122, NewQn122, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, NewQn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-121, - Qn121, NewQn121, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, NewQn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-120, - Qn120, NewQn120, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, NewQn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-119, - Qn119, NewQn119, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, NewQn119, Qn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-118, - Qn118, NewQn118, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, NewQn118, - Qn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-117, - Qn117, NewQn117, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - NewQn117, Qn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-116, - Qn116, NewQn116, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, NewQn116, Qn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-115, - Qn115, NewQn115, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, NewQn115, Qn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-114, - Qn114, NewQn114, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, NewQn114, Qn113}); -?REMOVE_UNIQ_P_Qn128(-113, - Qn113, NewQn113, - {Qn128, Qn127, Qn126, Qn125, Qn124, - Qn123, Qn122, Qn121, Qn120, Qn119, Qn118, - Qn117, Qn116, Qn115, Qn114, NewQn113}); -?REMOVE_UNIQ_P_Qn112(-112, - Qn112, NewQn112, - {NewQn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-111, - Qn111, NewQn111, - {Qn112, NewQn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-110, - Qn110, NewQn110, - {Qn112, Qn111, NewQn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-109, - Qn109, NewQn109, - {Qn112, Qn111, Qn110, NewQn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-108, - Qn108, NewQn108, - {Qn112, Qn111, Qn110, Qn109, NewQn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-107, - Qn107, NewQn107, - {Qn112, Qn111, Qn110, Qn109, Qn108, - NewQn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-106, - Qn106, NewQn106, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, NewQn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-105, - Qn105, NewQn105, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, NewQn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-104, - Qn104, NewQn104, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, NewQn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-103, - Qn103, NewQn103, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, NewQn103, Qn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-102, - Qn102, NewQn102, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, NewQn102, - Qn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-101, - Qn101, NewQn101, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - NewQn101, Qn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-100, - Qn100, NewQn100, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, NewQn100, Qn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-99, - Qn99, NewQn99, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, NewQn99, Qn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-98, - Qn98, NewQn98, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, NewQn98, Qn97}); -?REMOVE_UNIQ_P_Qn112(-97, - Qn97, NewQn97, - {Qn112, Qn111, Qn110, Qn109, Qn108, - Qn107, Qn106, Qn105, Qn104, Qn103, Qn102, - Qn101, Qn100, Qn99, Qn98, NewQn97}); -?REMOVE_UNIQ_P_Qn96(-96, - Qn96, NewQn96, - {NewQn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-95, - Qn95, NewQn95, - {Qn96, NewQn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-94, - Qn94, NewQn94, - {Qn96, Qn95, NewQn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-93, - Qn93, NewQn93, - {Qn96, Qn95, Qn94, NewQn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-92, - Qn92, NewQn92, - {Qn96, Qn95, Qn94, Qn93, NewQn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-91, - Qn91, NewQn91, - {Qn96, Qn95, Qn94, Qn93, Qn92, - NewQn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-90, - Qn90, NewQn90, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, NewQn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-89, - Qn89, NewQn89, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, NewQn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-88, - Qn88, NewQn88, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, NewQn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-87, - Qn87, NewQn87, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, NewQn87, Qn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-86, - Qn86, NewQn86, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, NewQn86, - Qn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-85, - Qn85, NewQn85, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - NewQn85, Qn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-84, - Qn84, NewQn84, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, NewQn84, Qn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-83, - Qn83, NewQn83, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, NewQn83, Qn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-82, - Qn82, NewQn82, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, NewQn82, Qn81}); -?REMOVE_UNIQ_P_Qn96(-81, - Qn81, NewQn81, - {Qn96, Qn95, Qn94, Qn93, Qn92, - Qn91, Qn90, Qn89, Qn88, Qn87, Qn86, - Qn85, Qn84, Qn83, Qn82, NewQn81}); -?REMOVE_UNIQ_P_Qn80(-80, - Qn80, NewQn80, - {NewQn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-79, - Qn79, NewQn79, - {Qn80, NewQn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-78, - Qn78, NewQn78, - {Qn80, Qn79, NewQn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-77, - Qn77, NewQn77, - {Qn80, Qn79, Qn78, NewQn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-76, - Qn76, NewQn76, - {Qn80, Qn79, Qn78, Qn77, NewQn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-75, - Qn75, NewQn75, - {Qn80, Qn79, Qn78, Qn77, Qn76, - NewQn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-74, - Qn74, NewQn74, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, NewQn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-73, - Qn73, NewQn73, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, NewQn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-72, - Qn72, NewQn72, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, NewQn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-71, - Qn71, NewQn71, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, NewQn71, Qn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-70, - Qn70, NewQn70, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, NewQn70, - Qn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-69, - Qn69, NewQn69, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - NewQn69, Qn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-68, - Qn68, NewQn68, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, NewQn68, Qn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-67, - Qn67, NewQn67, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, NewQn67, Qn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-66, - Qn66, NewQn66, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, NewQn66, Qn65}); -?REMOVE_UNIQ_P_Qn80(-65, - Qn65, NewQn65, - {Qn80, Qn79, Qn78, Qn77, Qn76, - Qn75, Qn74, Qn73, Qn72, Qn71, Qn70, - Qn69, Qn68, Qn67, Qn66, NewQn65}); -?REMOVE_UNIQ_P_Qn64(-64, - Qn64, NewQn64, - {NewQn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-63, - Qn63, NewQn63, - {Qn64, NewQn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-62, - Qn62, NewQn62, - {Qn64, Qn63, NewQn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-61, - Qn61, NewQn61, - {Qn64, Qn63, Qn62, NewQn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-60, - Qn60, NewQn60, - {Qn64, Qn63, Qn62, Qn61, NewQn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-59, - Qn59, NewQn59, - {Qn64, Qn63, Qn62, Qn61, Qn60, - NewQn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-58, - Qn58, NewQn58, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, NewQn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-57, - Qn57, NewQn57, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, NewQn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-56, - Qn56, NewQn56, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, NewQn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-55, - Qn55, NewQn55, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, NewQn55, Qn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-54, - Qn54, NewQn54, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, NewQn54, - Qn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-53, - Qn53, NewQn53, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - NewQn53, Qn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-52, - Qn52, NewQn52, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, NewQn52, Qn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-51, - Qn51, NewQn51, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, NewQn51, Qn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-50, - Qn50, NewQn50, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, NewQn50, Qn49}); -?REMOVE_UNIQ_P_Qn64(-49, - Qn49, NewQn49, - {Qn64, Qn63, Qn62, Qn61, Qn60, - Qn59, Qn58, Qn57, Qn56, Qn55, Qn54, - Qn53, Qn52, Qn51, Qn50, NewQn49}); -?REMOVE_UNIQ_P_Qn48(-48, - Qn48, NewQn48, - {NewQn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-47, - Qn47, NewQn47, - {Qn48, NewQn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-46, - Qn46, NewQn46, - {Qn48, Qn47, NewQn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-45, - Qn45, NewQn45, - {Qn48, Qn47, Qn46, NewQn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-44, - Qn44, NewQn44, - {Qn48, Qn47, Qn46, Qn45, NewQn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-43, - Qn43, NewQn43, - {Qn48, Qn47, Qn46, Qn45, Qn44, - NewQn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-42, - Qn42, NewQn42, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, NewQn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-41, - Qn41, NewQn41, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, NewQn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-40, - Qn40, NewQn40, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, NewQn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-39, - Qn39, NewQn39, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, NewQn39, Qn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-38, - Qn38, NewQn38, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, NewQn38, - Qn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-37, - Qn37, NewQn37, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - NewQn37, Qn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-36, - Qn36, NewQn36, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, NewQn36, Qn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-35, - Qn35, NewQn35, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, NewQn35, Qn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-34, - Qn34, NewQn34, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, NewQn34, Qn33}); -?REMOVE_UNIQ_P_Qn48(-33, - Qn33, NewQn33, - {Qn48, Qn47, Qn46, Qn45, Qn44, - Qn43, Qn42, Qn41, Qn40, Qn39, Qn38, - Qn37, Qn36, Qn35, Qn34, NewQn33}); -?REMOVE_UNIQ_P_Qn32(-32, - Qn32, NewQn32, - {NewQn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-31, - Qn31, NewQn31, - {Qn32, NewQn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-30, - Qn30, NewQn30, - {Qn32, Qn31, NewQn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-29, - Qn29, NewQn29, - {Qn32, Qn31, Qn30, NewQn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-28, - Qn28, NewQn28, - {Qn32, Qn31, Qn30, Qn29, NewQn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-27, - Qn27, NewQn27, - {Qn32, Qn31, Qn30, Qn29, Qn28, - NewQn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-26, - Qn26, NewQn26, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, NewQn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-25, - Qn25, NewQn25, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, NewQn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-24, - Qn24, NewQn24, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, NewQn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-23, - Qn23, NewQn23, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, NewQn23, Qn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-22, - Qn22, NewQn22, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, NewQn22, - Qn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-21, - Qn21, NewQn21, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - NewQn21, Qn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-20, - Qn20, NewQn20, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, NewQn20, Qn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-19, - Qn19, NewQn19, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, NewQn19, Qn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-18, - Qn18, NewQn18, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, NewQn18, Qn17}); -?REMOVE_UNIQ_P_Qn32(-17, - Qn17, NewQn17, - {Qn32, Qn31, Qn30, Qn29, Qn28, - Qn27, Qn26, Qn25, Qn24, Qn23, Qn22, - Qn21, Qn20, Qn19, Qn18, NewQn17}); -?REMOVE_UNIQ_P_Qn16(-16, - Qn16, NewQn16, - {NewQn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-15, - Qn15, NewQn15, - {Qn16, NewQn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-14, - Qn14, NewQn14, - {Qn16, Qn15, NewQn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-13, - Qn13, NewQn13, - {Qn16, Qn15, Qn14, NewQn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-12, - Qn12, NewQn12, - {Qn16, Qn15, Qn14, Qn13, NewQn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-11, - Qn11, NewQn11, - {Qn16, Qn15, Qn14, Qn13, Qn12, - NewQn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-10, - Qn10, NewQn10, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, NewQn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-9, - Qn9, NewQn9, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, NewQn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-8, - Qn8, NewQn8, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, NewQn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-7, - Qn7, NewQn7, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, NewQn7, Qn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-6, - Qn6, NewQn6, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, NewQn6, - Qn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-5, - Qn5, NewQn5, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - NewQn5, Qn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-4, - Qn4, NewQn4, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, NewQn4, Qn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-3, - Qn3, NewQn3, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, NewQn3, Qn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-2, - Qn2, NewQn2, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, NewQn2, Qn1}); -?REMOVE_UNIQ_P_Qn16(-1, - Qn1, NewQn1, - {Qn16, Qn15, Qn14, Qn13, Qn12, - Qn11, Qn10, Qn9, Qn8, Qn7, Qn6, - Qn5, Qn4, Qn3, Qn2, NewQn1}); -remove_unique_p(0, F, - {Pc, - Size, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - Q0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}) -> - {Value, NewQ0} = queue_remove_unique(F, Q0), - NewSize = if Value =:= true -> Size - 1; Value =:= false -> Size end, - {Value, - {if NewSize == 0 -> empty; true -> Pc end, - NewSize, - Qn128, Qn112, Qn96, Qn80, Qn64, Qn48, Qn32, Qn16, - NewQ0, - Qp16, Qp32, Qp48, Qp64, Qp80, Qp96, Qp112, Qp128}}; -?REMOVE_UNIQ_P_Qp16(1, - Qp1, NewQp1, - {NewQp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(2, - Qp2, NewQp2, - {Qp1, NewQp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(3, - Qp3, NewQp3, - {Qp1, Qp2, NewQp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(4, - Qp4, NewQp4, - {Qp1, Qp2, Qp3, NewQp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(5, - Qp5, NewQp5, - {Qp1, Qp2, Qp3, Qp4, NewQp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(6, - Qp6, NewQp6, - {Qp1, Qp2, Qp3, Qp4, Qp5, - NewQp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(7, - Qp7, NewQp7, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, NewQp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(8, - Qp8, NewQp8, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, NewQp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(9, - Qp9, NewQp9, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, NewQp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(10, - Qp10, NewQp10, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, NewQp10, Qp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(11, - Qp11, NewQp11, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, NewQp11, - Qp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(12, - Qp12, NewQp12, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - NewQp12, Qp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(13, - Qp13, NewQp13, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, NewQp13, Qp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(14, - Qp14, NewQp14, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, NewQp14, Qp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(15, - Qp15, NewQp15, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, NewQp15, Qp16}); -?REMOVE_UNIQ_P_Qp16(16, - Qp16, NewQp16, - {Qp1, Qp2, Qp3, Qp4, Qp5, - Qp6, Qp7, Qp8, Qp9, Qp10, Qp11, - Qp12, Qp13, Qp14, Qp15, NewQp16}); -?REMOVE_UNIQ_P_Qp32(17, - Qp17, NewQp17, - {NewQp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(18, - Qp18, NewQp18, - {Qp17, NewQp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(19, - Qp19, NewQp19, - {Qp17, Qp18, NewQp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(20, - Qp20, NewQp20, - {Qp17, Qp18, Qp19, NewQp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(21, - Qp21, NewQp21, - {Qp17, Qp18, Qp19, Qp20, NewQp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(22, - Qp22, NewQp22, - {Qp17, Qp18, Qp19, Qp20, Qp21, - NewQp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(23, - Qp23, NewQp23, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, NewQp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(24, - Qp24, NewQp24, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, NewQp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(25, - Qp25, NewQp25, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, NewQp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(26, - Qp26, NewQp26, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, NewQp26, Qp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(27, - Qp27, NewQp27, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, NewQp27, - Qp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(28, - Qp28, NewQp28, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - NewQp28, Qp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(29, - Qp29, NewQp29, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, NewQp29, Qp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(30, - Qp30, NewQp30, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, NewQp30, Qp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(31, - Qp31, NewQp31, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, NewQp31, Qp32}); -?REMOVE_UNIQ_P_Qp32(32, - Qp32, NewQp32, - {Qp17, Qp18, Qp19, Qp20, Qp21, - Qp22, Qp23, Qp24, Qp25, Qp26, Qp27, - Qp28, Qp29, Qp30, Qp31, NewQp32}); -?REMOVE_UNIQ_P_Qp48(33, - Qp33, NewQp33, - {NewQp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(34, - Qp34, NewQp34, - {Qp33, NewQp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(35, - Qp35, NewQp35, - {Qp33, Qp34, NewQp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(36, - Qp36, NewQp36, - {Qp33, Qp34, Qp35, NewQp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(37, - Qp37, NewQp37, - {Qp33, Qp34, Qp35, Qp36, NewQp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(38, - Qp38, NewQp38, - {Qp33, Qp34, Qp35, Qp36, Qp37, - NewQp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(39, - Qp39, NewQp39, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, NewQp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(40, - Qp40, NewQp40, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, NewQp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(41, - Qp41, NewQp41, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, NewQp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(42, - Qp42, NewQp42, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, NewQp42, Qp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(43, - Qp43, NewQp43, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, NewQp43, - Qp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(44, - Qp44, NewQp44, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - NewQp44, Qp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(45, - Qp45, NewQp45, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, NewQp45, Qp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(46, - Qp46, NewQp46, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, NewQp46, Qp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(47, - Qp47, NewQp47, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, NewQp47, Qp48}); -?REMOVE_UNIQ_P_Qp48(48, - Qp48, NewQp48, - {Qp33, Qp34, Qp35, Qp36, Qp37, - Qp38, Qp39, Qp40, Qp41, Qp42, Qp43, - Qp44, Qp45, Qp46, Qp47, NewQp48}); -?REMOVE_UNIQ_P_Qp64(49, - Qp49, NewQp49, - {NewQp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(50, - Qp50, NewQp50, - {Qp49, NewQp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(51, - Qp51, NewQp51, - {Qp49, Qp50, NewQp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(52, - Qp52, NewQp52, - {Qp49, Qp50, Qp51, NewQp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(53, - Qp53, NewQp53, - {Qp49, Qp50, Qp51, Qp52, NewQp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(54, - Qp54, NewQp54, - {Qp49, Qp50, Qp51, Qp52, Qp53, - NewQp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(55, - Qp55, NewQp55, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, NewQp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(56, - Qp56, NewQp56, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, NewQp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(57, - Qp57, NewQp57, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, NewQp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(58, - Qp58, NewQp58, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, NewQp58, Qp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(59, - Qp59, NewQp59, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, NewQp59, - Qp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(60, - Qp60, NewQp60, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - NewQp60, Qp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(61, - Qp61, NewQp61, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, NewQp61, Qp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(62, - Qp62, NewQp62, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, NewQp62, Qp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(63, - Qp63, NewQp63, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, NewQp63, Qp64}); -?REMOVE_UNIQ_P_Qp64(64, - Qp64, NewQp64, - {Qp49, Qp50, Qp51, Qp52, Qp53, - Qp54, Qp55, Qp56, Qp57, Qp58, Qp59, - Qp60, Qp61, Qp62, Qp63, NewQp64}); -?REMOVE_UNIQ_P_Qp80(65, - Qp65, NewQp65, - {NewQp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(66, - Qp66, NewQp66, - {Qp65, NewQp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(67, - Qp67, NewQp67, - {Qp65, Qp66, NewQp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(68, - Qp68, NewQp68, - {Qp65, Qp66, Qp67, NewQp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(69, - Qp69, NewQp69, - {Qp65, Qp66, Qp67, Qp68, NewQp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(70, - Qp70, NewQp70, - {Qp65, Qp66, Qp67, Qp68, Qp69, - NewQp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(71, - Qp71, NewQp71, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, NewQp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(72, - Qp72, NewQp72, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, NewQp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(73, - Qp73, NewQp73, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, NewQp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(74, - Qp74, NewQp74, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, NewQp74, Qp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(75, - Qp75, NewQp75, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, NewQp75, - Qp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(76, - Qp76, NewQp76, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - NewQp76, Qp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(77, - Qp77, NewQp77, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, NewQp77, Qp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(78, - Qp78, NewQp78, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, NewQp78, Qp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(79, - Qp79, NewQp79, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, NewQp79, Qp80}); -?REMOVE_UNIQ_P_Qp80(80, - Qp80, NewQp80, - {Qp65, Qp66, Qp67, Qp68, Qp69, - Qp70, Qp71, Qp72, Qp73, Qp74, Qp75, - Qp76, Qp77, Qp78, Qp79, NewQp80}); -?REMOVE_UNIQ_P_Qp96(81, - Qp81, NewQp81, - {NewQp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(82, - Qp82, NewQp82, - {Qp81, NewQp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(83, - Qp83, NewQp83, - {Qp81, Qp82, NewQp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(84, - Qp84, NewQp84, - {Qp81, Qp82, Qp83, NewQp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(85, - Qp85, NewQp85, - {Qp81, Qp82, Qp83, Qp84, NewQp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(86, - Qp86, NewQp86, - {Qp81, Qp82, Qp83, Qp84, Qp85, - NewQp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(87, - Qp87, NewQp87, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, NewQp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(88, - Qp88, NewQp88, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, NewQp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(89, - Qp89, NewQp89, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, NewQp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(90, - Qp90, NewQp90, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, NewQp90, Qp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(91, - Qp91, NewQp91, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, NewQp91, - Qp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(92, - Qp92, NewQp92, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - NewQp92, Qp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(93, - Qp93, NewQp93, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, NewQp93, Qp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(94, - Qp94, NewQp94, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, NewQp94, Qp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(95, - Qp95, NewQp95, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, NewQp95, Qp96}); -?REMOVE_UNIQ_P_Qp96(96, - Qp96, NewQp96, - {Qp81, Qp82, Qp83, Qp84, Qp85, - Qp86, Qp87, Qp88, Qp89, Qp90, Qp91, - Qp92, Qp93, Qp94, Qp95, NewQp96}); -?REMOVE_UNIQ_P_Qp112(97, - Qp97, NewQp97, - {NewQp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(98, - Qp98, NewQp98, - {Qp97, NewQp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(99, - Qp99, NewQp99, - {Qp97, Qp98, NewQp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(100, - Qp100, NewQp100, - {Qp97, Qp98, Qp99, NewQp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(101, - Qp101, NewQp101, - {Qp97, Qp98, Qp99, Qp100, NewQp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(102, - Qp102, NewQp102, - {Qp97, Qp98, Qp99, Qp100, Qp101, - NewQp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(103, - Qp103, NewQp103, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, NewQp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(104, - Qp104, NewQp104, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, NewQp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(105, - Qp105, NewQp105, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, NewQp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(106, - Qp106, NewQp106, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, NewQp106, Qp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(107, - Qp107, NewQp107, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, NewQp107, - Qp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(108, - Qp108, NewQp108, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - NewQp108, Qp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(109, - Qp109, NewQp109, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, NewQp109, Qp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(110, - Qp110, NewQp110, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, NewQp110, Qp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(111, - Qp111, NewQp111, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, NewQp111, Qp112}); -?REMOVE_UNIQ_P_Qp112(112, - Qp112, NewQp112, - {Qp97, Qp98, Qp99, Qp100, Qp101, - Qp102, Qp103, Qp104, Qp105, Qp106, Qp107, - Qp108, Qp109, Qp110, Qp111, NewQp112}); -?REMOVE_UNIQ_P_Qp128(113, - Qp113, NewQp113, - {NewQp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(114, - Qp114, NewQp114, - {Qp113, NewQp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(115, - Qp115, NewQp115, - {Qp113, Qp114, NewQp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(116, - Qp116, NewQp116, - {Qp113, Qp114, Qp115, NewQp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(117, - Qp117, NewQp117, - {Qp113, Qp114, Qp115, Qp116, NewQp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(118, - Qp118, NewQp118, - {Qp113, Qp114, Qp115, Qp116, Qp117, - NewQp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(119, - Qp119, NewQp119, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, NewQp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(120, - Qp120, NewQp120, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, NewQp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(121, - Qp121, NewQp121, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, NewQp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(122, - Qp122, NewQp122, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, NewQp122, Qp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(123, - Qp123, NewQp123, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, NewQp123, - Qp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(124, - Qp124, NewQp124, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - NewQp124, Qp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(125, - Qp125, NewQp125, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, NewQp125, Qp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(126, - Qp126, NewQp126, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, NewQp126, Qp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(127, - Qp127, NewQp127, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, NewQp127, Qp128}); -?REMOVE_UNIQ_P_Qp128(128, - Qp128, NewQp128, - {Qp113, Qp114, Qp115, Qp116, Qp117, - Qp118, Qp119, Qp120, Qp121, Qp122, Qp123, - Qp124, Qp125, Qp126, Qp127, NewQp128}). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - --include("pqueue_test.hrl"). - -module_test_() -> - {timeout, ?TEST_TIMEOUT, [ - {"internal tests", ?_assertOk(test())} - ]}. - -long_test_() -> - test_condition([ - {"proper tests", ?_assert(pqueue_proper:qc_pq4())} - ], ?CLOUDI_LONG_TEST_TIMEOUT). - --endif. - -%%------------------------------------------------------------------------- -%% @hidden -%% remove a unique value from a queue based on a binary predicate, -%% traversal order is undefined to keep it efficient (i.e., shouldn't matter) -%% (based on the implementation of queue:filter/2 -%% which is under the Apache License 2.0) -%%------------------------------------------------------------------------- - --spec queue_remove_unique(F :: fun((any()) -> boolean()), - Q :: {list(), list()}) -> - {boolean(), {list(), list()}}. - -queue_remove_unique(Fun, {R0, F0} = Q) - when is_function(Fun, 1), is_list(R0), is_list(F0) -> - case queue_remove_unique_f(Fun, F0) of - {true, []} -> - {true, queue_r2f(R0)}; - {true, F1} -> - {true, {R0, F1}}; - {false, F1} -> - %true = F1 == F0, - case queue_remove_unique_f(Fun, R0) of % backwards - {true, []} -> - {true, queue_f2r(F1)}; - {true, R1} -> - {true, {R1, F1}}; - {false, _} -> - {false, Q} - end - end; -queue_remove_unique(Fun, Q) -> - erlang:error(badarg, [Fun,Q]). - -% Call Fun in front to back order -queue_remove_unique_f(_, [] = F) -> - {false, F}; -queue_remove_unique_f(Fun, F) -> - queue_remove_unique_f(F, [], F, Fun). - -queue_remove_unique_f([], _, F, _) -> - {false, F}; -queue_remove_unique_f([X | F0], F1, F, Fun) -> - case Fun(X) of - true -> - {true, lists:reverse(F1, F0)}; - false -> - queue_remove_unique_f(F0, [X | F1], F, Fun) - end. - --compile({inline, [{queue_r2f,1},{queue_f2r,1}]}). - -% Move half of elements from R to F, if there are at least three -queue_r2f([]) -> - {[],[]}; -queue_r2f([_]=R) -> - {[],R}; -queue_r2f([X,Y]) -> - {[X],[Y]}; -queue_r2f(List) -> - {FF,RR} = lists:split(length(List) div 2 + 1, List), - {FF,lists:reverse(RR, [])}. - -% Move half of elements from F to R, if there are enough -queue_f2r([]) -> - {[],[]}; -queue_f2r([_]=F) -> - {F,[]}; -queue_f2r([X,Y]) -> - {[Y],[X]}; -queue_f2r(List) -> - {FF,RR} = lists:split(length(List) div 2 + 1, List), - {lists:reverse(RR, []),FF}. - diff --git a/aoc2023/build/packages/pqueue/src/pqueue_test.hrl b/aoc2023/build/packages/pqueue/src/pqueue_test.hrl deleted file mode 100644 index cedffe0..0000000 --- a/aoc2023/build/packages/pqueue/src/pqueue_test.hrl +++ /dev/null @@ -1,49 +0,0 @@ -%-*-Mode:erlang;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*- -% ex: set ft=erlang fenc=utf-8 sts=4 ts=4 sw=4 et nomod: -%%% -%%%------------------------------------------------------------------------ -%%% pqueue eunit common functionality -%%% -%%% MIT License -%%% -%%% Copyright (c) 2020 Michael Truog <mjtruog at protonmail dot com> -%%% -%%% Permission is hereby granted, free of charge, to any person obtaining a -%%% copy of this software and associated documentation files (the "Software"), -%%% to deal in the Software without restriction, including without limitation -%%% the rights to use, copy, modify, merge, publish, distribute, sublicense, -%%% and/or sell copies of the Software, and to permit persons to whom the -%%% Software is furnished to do so, subject to the following conditions: -%%% -%%% The above copyright notice and this permission notice shall be included in -%%% all copies or substantial portions of the Software. -%%% -%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -%%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -%%% DEALINGS IN THE SOFTWARE. -%%% -%%%------------------------------------------------------------------------ - --ifndef(_assertOk). --define(_assertOk(Expr), ?_assertEqual(ok, Expr)). --endif. - --ifdef(CLOUDI_TEST_TIMEOUT). --define(TEST_TIMEOUT, ?CLOUDI_TEST_TIMEOUT). % seconds --else. --define(TEST_TIMEOUT, 10). % seconds --endif. --ifndef(CLOUDI_LONG_TEST_TIMEOUT). --define(CLOUDI_LONG_TEST_TIMEOUT, 60). % minutes --endif. - -test_condition(_, 0) -> - []; -test_condition(L, LongTestTimeout) - when LongTestTimeout > 0 -> - {timeout, LongTestTimeout * 60, L}. - diff --git a/aoc2023/build/packages/pqueue/test/pqueue_proper.erl b/aoc2023/build/packages/pqueue/test/pqueue_proper.erl deleted file mode 100644 index 6702960..0000000 --- a/aoc2023/build/packages/pqueue/test/pqueue_proper.erl +++ /dev/null @@ -1,156 +0,0 @@ --module(pqueue_proper). --ifdef(TEST). --include_lib("proper/include/proper.hrl"). - --behaviour(proper_statem). - --export([qc_pq/0, qc_pq2/0, qc_pq3/0, qc_pq4/0, correct/1]). - --export([command/1, initial_state/0, next_state/3, postcondition/3, - precondition/2]). - --type value() :: integer(). --record(state, { in_queue :: [{value(), term()}] }). --define(SERVER, queue_srv). - -priority() -> - integer(-20, 20). - -%% Selects priorities we have added -priority(InQ) -> - elements([P || {P, _} <- InQ]). - -value() -> - integer(). - -initial_state() -> - #state { in_queue = [] }. - -command(#state { in_queue = InQ }) -> - oneof([{call, ?SERVER, in, [value()]}, - {call, ?SERVER, in, [value(), priority()]}, - {call, ?SERVER, is_empty, []}, - {call, ?SERVER, is_queue, []}, - {call, ?SERVER, len, []}, - {call, ?SERVER, out, []}] ++ - [{call, ?SERVER, out, [priority(InQ)]} || InQ =/= []] ++ - [{call, ?SERVER, pout, []}, - {call, ?SERVER, to_list, []}]). - -next_state(#state { in_queue = InQ } = S, _V, {call, _, out, []}) -> - S#state { in_queue = listq_rem(InQ) }; -next_state(#state { in_queue = InQ } = S, _V, {call, _, out, [Prio]}) -> - S#state { in_queue = listq_rem(InQ, Prio) }; -next_state(#state { in_queue = InQ } = S, _V, {call, _, pout, _}) -> - S#state { in_queue = listq_rem(InQ) }; -next_state(S, _V, {call, _, to_list, _}) -> S; -next_state(S, _V, {call, _, is_queue, _}) -> S; -next_state(S, _V, {call, _, is_empty, _}) -> S; -next_state(S, _V, {call, _, len, _}) -> S; -next_state(#state { in_queue = InQ } = S, _V, {call, _, in, [Value, Prio]}) -> - S#state { in_queue = listq_insert({Prio, Value}, InQ) }; -next_state(#state { in_queue = InQ } = S, _V, {call, _, in, [Value]}) -> - S#state { in_queue = listq_insert({0, Value}, InQ) }. - -precondition(_S, _Call) -> - true. % No limitation on the things we can call at all. - -postcondition(#state { in_queue = InQ }, {call, _, out, [Prio]}, R) -> - R == listq_prio_peek(InQ, Prio); -postcondition(#state { in_queue = InQ }, {call, _, pout, _}, R) -> - R == listq_ppeek(InQ); -postcondition(#state { in_queue = InQ }, {call, _, out, _}, R) -> - R == listq_peek(InQ); -postcondition(S, {call, _, to_list, _}, R) -> - R == listq_to_list(S#state.in_queue); -postcondition(S, {call, _, len, _}, L) -> - L == listq_length(S#state.in_queue); -postcondition(_S, {call, _, is_queue, _}, true) -> true; -postcondition(S, {call, _, is_empty, _}, Res) -> - Res == (S#state.in_queue == []); -postcondition(_S, {call, _, in, _}, _) -> - true; -postcondition(_, _, _) -> - false. - -correct(M) -> - ?FORALL(Cmds, commands(?MODULE), - ?TRAPEXIT( - begin - ?SERVER:start_link(M), - {History,State,Result} = run_commands(?MODULE, Cmds), - ?SERVER:stop(), - ?WHENFAIL(io:format("History: ~w\nState: ~w\nResult: ~w\n", - [History,State,Result]), - aggregate(command_names(Cmds), Result =:= ok)) - end)). - -qc_opts() -> - [{numtests, 10000}]. - -qc_pq() -> - proper:quickcheck(pqueue_proper:correct(pqueue), qc_opts()). - -qc_pq2() -> - proper:quickcheck(pqueue_proper:correct(pqueue2), qc_opts()). - -qc_pq3() -> - proper:quickcheck(pqueue_proper:correct(pqueue3), qc_opts()). - -qc_pq4() -> - proper:quickcheck(pqueue_proper:correct(pqueue4), qc_opts()). - -%% ---------------------------------------------------------------------- - -%% A listq is a sorted list of priorities -listq_insert({P, V}, []) -> - [{P, [V]}]; -listq_insert({P, V}, [{P1, _} | _] = LQ) when P < P1 -> - [{P, [V]} | LQ]; -listq_insert({P, V}, [{P1, Vs} | Next]) when P == P1 -> - [{P, Vs ++ [V]} | Next]; -listq_insert({P, V}, [{P1, Vs} | Next]) when P > P1 -> - [{P1, Vs} | listq_insert({P, V}, Next)]. - -listq_to_list(L) -> - lists:concat( - [ Vals || {_Prio, Vals} <- L]). - -listq_length(L) -> - lists:sum( - [ length(Vs) || {_Prio, Vs} <- L]). - -listq_rem([]) -> - []; -listq_rem([{_P, [_V]} | Next]) -> - Next; -listq_rem([{P, [_V1 | Vs]} | Next]) -> - [{P, Vs} | Next]. - -listq_rem([], _P) -> - []; -listq_rem([{P, [_]} | Next], P) -> - Next; -listq_rem([{P, [_ | Vs]} | Next], P) -> - [{P, Vs} | Next]; -listq_rem([{P1, Vs} | Next], P) -> - [{P1, Vs} | listq_rem(Next, P)]. - -listq_peek([]) -> - empty; -listq_peek([{_P, [V | _]} | _]) -> - {value, V}. - -listq_prio_peek([{P, [V | _]} | _], P) -> - {value, V}; -listq_prio_peek([{_P1, _} | Next], P) -> - listq_prio_peek(Next, P); -listq_prio_peek([], _P) -> - empty. - -listq_ppeek([]) -> - empty; -listq_ppeek([{P, [V | _]} | _]) -> - {value, V, P}. - --endif. diff --git a/aoc2023/build/packages/pqueue/test/queue_srv.erl b/aoc2023/build/packages/pqueue/test/queue_srv.erl deleted file mode 100644 index 7fcb0a1..0000000 --- a/aoc2023/build/packages/pqueue/test/queue_srv.erl +++ /dev/null @@ -1,183 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Jesper Louis andersen <> -%%% @copyright (C) 2011, Jesper Louis andersen -%%% @doc -%%% -%%% @end -%%% Created : 11 Nov 2011 by Jesper Louis andersen <> -%%%------------------------------------------------------------------- --module(queue_srv). - --behaviour(gen_server). - -%% API --export([start_link/1, stop/0, len/0, in/1, in/2, is_empty/0, - out/0, out/1, pout/0, - is_queue/0, to_list/0]). - -%% gen_server callbacks --export([init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3]). - --define(SERVER, ?MODULE). - --record(state, { mod, q }). - -%%%=================================================================== -%%% API -%%%=================================================================== - -%%-------------------------------------------------------------------- -%% @doc -%% Starts the server -%% -%% @spec start_link(Mod) -> {ok, Pid} | ignore | {error, Error} -%% @end -%%-------------------------------------------------------------------- -start_link(Mod) -> - gen_server:start_link({local, ?SERVER}, ?MODULE, [Mod], []). - -stop() -> - gen_server:stop(?SERVER). - -call(M) -> - gen_server:call(?SERVER, M, infinity). - -in(I) -> - call({in, I}). - -in(I, P) -> - call({in, I, P}). - -len() -> - call(len). - -is_empty() -> - call(is_empty). - -is_queue() -> - call(is_queue). - -to_list() -> - call(to_list). - -out() -> - call(out). - -out(P) -> - call({out, P}). - -pout() -> - call(pout). - -%%%=================================================================== -%%% gen_server callbacks -%%%=================================================================== - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% Initializes the server -%% -%% @spec init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% @end -%%-------------------------------------------------------------------- -init([Mod]) -> - {ok, #state{ mod = Mod, - q = Mod:new() }}. - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% Handling call messages -%% -%% @spec handle_call(Request, From, State) -> -%% {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% @end -%%-------------------------------------------------------------------- -handle_call({in, Item}, _F, #state { q = Q, mod = M } = S) -> - NQ = M:in(Item, Q), - {reply, ok, S#state { q = NQ }}; -handle_call({in, Item, Prio}, _F, #state { q = Q, mod = M } = S) -> - NQ = M:in(Item, Prio, Q), - {reply, ok, S#state { q = NQ }}; -handle_call({out, P}, _F, #state { q = Q, mod = M } = S) -> - {R, NQ} = M:out(P, Q), - {reply, R, S#state { q = NQ }}; -handle_call(Ty, _F, #state { q = Q, mod = M } = S) when Ty == out; - Ty == pout -> - {R, NQ} = M:Ty(Q), - {reply, R, S#state { q = NQ }}; -handle_call(Ty, _F, #state { q = Q, mod = M } = S) when Ty == is_queue; - Ty == is_empty; - Ty == len; - Ty == to_list -> - R = M:Ty(Q), - {reply, R, S}; -handle_call(Req, From, State) -> - error_logger:info_report([{handle_call, Req, From, State}]), - Reply = ok, - {reply, Reply, State}. - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% Handling cast messages -%% -%% @spec handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @end -%%-------------------------------------------------------------------- -handle_cast(_Msg, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% Handling all non call/cast messages -%% -%% @spec handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% @end -%%-------------------------------------------------------------------- -handle_info(_Info, State) -> - {noreply, State}. - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any -%% necessary cleaning up. When it returns, the gen_server terminates -%% with Reason. The return value is ignored. -%% -%% @spec terminate(Reason, State) -> void() -%% @end -%%-------------------------------------------------------------------- -terminate(_Reason, _State) -> - ok. - -%%-------------------------------------------------------------------- -%% @private -%% @doc -%% Convert process state when code is changed -%% -%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState} -%% @end -%%-------------------------------------------------------------------- -code_change(_OldVsn, State, _Extra) -> - {ok, State}. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/aoc2023/build/packages/simplifile/README.md b/aoc2023/build/packages/simplifile/README.md deleted file mode 100644 index 5e49113..0000000 --- a/aoc2023/build/packages/simplifile/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# simplifile - -[](https://hex.pm/packages/simplifile) -[](https://hexdocs.pm/simplifile/) - -Simplifile provides basic file operations (read, write, append, and delete) that work -for all targets (Erlang, Node, and Deno). It also provides functions for working with directories. - -Note: When upgrading versions, be sure to check the changelog. - -## Example -```gleam -let filepath = "./test/hello.txt" -let assert Ok(_) = "Hello, World" |> write(to: filepath) -let assert Ok(_) = "Goodbye, Mars" |> append(to: filepath) -let assert Ok("Hello, WorldGoodbye, Mars") = read(from: filepath) -let assert Ok(_) = delete(filepath) -let assert Error(_) = read(from: filepath) -``` - -## Installation - -If available on Hex this package can be added to your Gleam project: - -```sh -gleam add simplifile -``` - -and its documentation can be found at <https://hexdocs.pm/simplifile>. diff --git a/aoc2023/build/packages/simplifile/gleam.toml b/aoc2023/build/packages/simplifile/gleam.toml deleted file mode 100644 index 8e7523d..0000000 --- a/aoc2023/build/packages/simplifile/gleam.toml +++ /dev/null @@ -1,17 +0,0 @@ -name = "simplifile" -version = "1.0.0" -description = "Basic file operations that work on all targets" - -licences = ["Apache-2.0"] -repository = { type = "github", user = "bcpeinhardt", repo = "simplifile" } -gleam = ">= 0.32.0" -# links = [{ title = "Website", href = "https://gleam.run" }] - -[javascript.deno] -allow_all = true - -[dependencies] -gleam_stdlib = "~> 0.29" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/simplifile/src/simplifile.app.src b/aoc2023/build/packages/simplifile/src/simplifile.app.src deleted file mode 100644 index 5b9d6ef..0000000 --- a/aoc2023/build/packages/simplifile/src/simplifile.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, simplifile, [ - {vsn, "1.0.0"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "Basic file operations that work on all targets"}, - {modules, [simplifile]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/simplifile/src/simplifile.erl b/aoc2023/build/packages/simplifile/src/simplifile.erl deleted file mode 100644 index 0d3818c..0000000 --- a/aoc2023/build/packages/simplifile/src/simplifile.erl +++ /dev/null @@ -1,287 +0,0 @@ --module(simplifile). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([read/1, write/2, delete/1, delete_all/1, append/2, read_bits/1, write_bits/2, append_bits/2, is_directory/1, create_directory/1, read_directory/1, is_file/1, create_file/1, get_files/1, create_directory_all/1, copy_directory/2, rename_directory/2, copy_file/2, rename_file/2]). --export_type([file_error/0]). - --type file_error() :: eacces | - eagain | - ebadf | - ebadmsg | - ebusy | - edeadlk | - edeadlock | - edquot | - eexist | - efault | - efbig | - eftype | - eintr | - einval | - eio | - eisdir | - eloop | - emfile | - emlink | - emultihop | - enametoolong | - enfile | - enobufs | - enodev | - enolck | - enolink | - enoent | - enomem | - enospc | - enosr | - enostr | - enosys | - enotblk | - enotdir | - enotsup | - enxio | - eopnotsupp | - eoverflow | - eperm | - epipe | - erange | - erofs | - espipe | - esrch | - estale | - etxtbsy | - exdev | - not_utf8 | - unknown. - --spec do_append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_append(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam_stdlib:identity(_pipe), - simplifile_erl:append_file(_pipe@1, Filepath). - --spec do_write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_write(Content, Filepath) -> - _pipe = Content, - _pipe@1 = gleam_stdlib:identity(_pipe), - simplifile_erl:write_file(_pipe@1, Filepath). - --spec do_read(binary()) -> {ok, binary()} | {error, file_error()}. -do_read(Filepath) -> - case simplifile_erl:read_file(Filepath) of - {ok, Bits} -> - case gleam@bit_array:to_string(Bits) of - {ok, Str} -> - {ok, Str}; - - _ -> - {error, not_utf8} - end; - - {error, E} -> - {error, E} - end. - --spec cast_error({ok, FIL} | {error, file_error()}) -> {ok, FIL} | - {error, file_error()}. -cast_error(Input) -> - Input. - --spec read(binary()) -> {ok, binary()} | {error, file_error()}. -read(Filepath) -> - _pipe = do_read(Filepath), - cast_error(_pipe). - --spec write(binary(), binary()) -> {ok, nil} | {error, file_error()}. -write(Filepath, Contents) -> - _pipe = do_write(Contents, Filepath), - cast_error(_pipe). - --spec delete(binary()) -> {ok, nil} | {error, file_error()}. -delete(Path) -> - _pipe = simplifile_erl:recursive_delete(Path), - cast_error(_pipe). - --spec delete_all(list(binary())) -> {ok, nil} | {error, file_error()}. -delete_all(Paths) -> - case Paths of - [] -> - {ok, nil}; - - [Path | Rest] -> - case delete(Path) of - {ok, nil} -> - delete_all(Rest); - - {error, enoent} -> - delete_all(Rest); - - E -> - E - end - end. - --spec append(binary(), binary()) -> {ok, nil} | {error, file_error()}. -append(Filepath, Contents) -> - _pipe = do_append(Contents, Filepath), - cast_error(_pipe). - --spec read_bits(binary()) -> {ok, bitstring()} | {error, file_error()}. -read_bits(Filepath) -> - _pipe = simplifile_erl:read_file(Filepath), - cast_error(_pipe). - --spec write_bits(binary(), bitstring()) -> {ok, nil} | {error, file_error()}. -write_bits(Filepath, Bits) -> - _pipe = simplifile_erl:write_file(Bits, Filepath), - cast_error(_pipe). - --spec append_bits(binary(), bitstring()) -> {ok, nil} | {error, file_error()}. -append_bits(Filepath, Bits) -> - _pipe = simplifile_erl:append_file(Bits, Filepath), - cast_error(_pipe). - --spec is_directory(binary()) -> boolean(). -is_directory(Filepath) -> - filelib:is_dir(Filepath). - --spec create_directory(binary()) -> {ok, nil} | {error, file_error()}. -create_directory(Filepath) -> - _pipe = simplifile_erl:make_directory(Filepath), - cast_error(_pipe). - --spec read_directory(binary()) -> {ok, list(binary())} | {error, file_error()}. -read_directory(Path) -> - _pipe = simplifile_erl:list_directory(Path), - cast_error(_pipe). - --spec is_file(binary()) -> boolean(). -is_file(Filepath) -> - simplifile_erl:is_file(Filepath). - --spec create_file(binary()) -> {ok, nil} | {error, file_error()}. -create_file(Filepath) -> - case begin - _pipe = Filepath, - is_file(_pipe) - end - orelse begin - _pipe@1 = Filepath, - is_directory(_pipe@1) - end of - true -> - {error, eexist}; - - false -> - write_bits(Filepath, <<>>) - end. - --spec do_copy_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. -do_copy_directory(Src, Dest) -> - gleam@result:'try'( - read_directory(Src), - fun(Segments) -> - _pipe = Segments, - gleam@list:each( - _pipe, - fun(Segment) -> - Src_path = <<<<Src/binary, "/"/utf8>>/binary, - Segment/binary>>, - Dest_path = <<<<Dest/binary, "/"/utf8>>/binary, - Segment/binary>>, - case {is_file(Src_path), is_directory(Src_path)} of - {true, false} -> - gleam@result:'try'( - read_bits(Src_path), - fun(Content) -> _pipe@1 = Content, - write_bits(Dest_path, _pipe@1) end - ); - - {false, true} -> - gleam@result:'try'( - create_directory(Dest_path), - fun(_) -> - do_copy_directory(Src_path, Dest_path) - end - ); - - {_, _} -> - erlang:error(#{gleam_error => panic, - message => <<"unreachable"/utf8>>, - module => <<"simplifile"/utf8>>, - function => <<"do_copy_directory"/utf8>>, - line => 341}) - end - end - ), - {ok, nil} - end - ). - --spec get_files(binary()) -> {ok, list(binary())} | {error, file_error()}. -get_files(Directory) -> - gleam@result:'try'( - read_directory(Directory), - fun(Contents) -> - Paths = gleam@list:map( - Contents, - fun(Segment) -> - <<<<Directory/binary, "/"/utf8>>/binary, Segment/binary>> - end - ), - Files = gleam@list:filter(Paths, fun is_file/1), - case gleam@list:filter(Paths, fun is_directory/1) of - [] -> - {ok, Files}; - - Directories -> - gleam@result:'try'( - gleam@list:try_map(Directories, fun get_files/1), - fun(Nested_files) -> - {ok, - gleam@list:append( - Files, - gleam@list:flatten(Nested_files) - )} - end - ) - end - end - ). - --spec create_directory_all(binary()) -> {ok, nil} | {error, file_error()}. -create_directory_all(Dirpath) -> - Path = case begin - _pipe = Dirpath, - gleam@string:ends_with(_pipe, <<"/"/utf8>>) - end of - true -> - Dirpath; - - false -> - <<Dirpath/binary, "/"/utf8>> - end, - _pipe@1 = simplifile_erl:create_dir_all(Path), - cast_error(_pipe@1). - --spec copy_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. -copy_directory(Src, Dest) -> - gleam@result:'try'( - create_directory_all(Dest), - fun(_) -> do_copy_directory(Src, Dest) end - ). - --spec rename_directory(binary(), binary()) -> {ok, nil} | {error, file_error()}. -rename_directory(Src, Dest) -> - gleam@result:'try'(copy_directory(Src, Dest), fun(_) -> delete(Src) end). - --spec copy_file(binary(), binary()) -> {ok, nil} | {error, file_error()}. -copy_file(Src, Dest) -> - _pipe = file:copy(Src, Dest), - _pipe@1 = gleam@result:replace(_pipe, nil), - cast_error(_pipe@1). - --spec rename_file(binary(), binary()) -> {ok, nil} | {error, file_error()}. -rename_file(Src, Dest) -> - _pipe = simplifile_erl:rename_file(Src, Dest), - cast_error(_pipe). diff --git a/aoc2023/build/packages/simplifile/src/simplifile.gleam b/aoc2023/build/packages/simplifile/src/simplifile.gleam deleted file mode 100644 index eff0306..0000000 --- a/aoc2023/build/packages/simplifile/src/simplifile.gleam +++ /dev/null @@ -1,580 +0,0 @@ -import gleam/bit_array -import gleam/string -import gleam/result -import gleam/list - -/// This type represents all of the reasons for why a file system operation could fail. -/// -/// Most of these reasons are POSIX errors, which come from the operating system -/// and start with E. Others have been added to represent other issues that may -/// arise specific to this library. -/// -pub type FileError { - /// Permission denied. - Eacces - /// Resource temporarily unavailable. - Eagain - /// Bad file number - Ebadf - /// Bad message. - Ebadmsg - /// File busy. - Ebusy - /// Resource deadlock avoided. - Edeadlk - /// On most architectures, same as `Edeadlk`. On some architectures, it - /// means "File locking deadlock error." - Edeadlock - /// Disk quota exceeded. - Edquot - /// File already exists. - Eexist - /// Bad address in system call argument. - Efault - /// File too large. - Efbig - /// Inappropriate file type or format. Usually caused by trying to set the - /// "sticky bit" on a regular file (not a directory). - Eftype - /// Interrupted system call. - Eintr - /// Invalid argument. - Einval - /// I/O error. - Eio - /// Illegal operation on a directory. - Eisdir - /// Too many levels of symbolic links. - Eloop - /// Too many open files. - Emfile - /// Too many links. - Emlink - /// Multihop attempted. - Emultihop - /// Filename too long - Enametoolong - /// File table overflow - Enfile - /// No buffer space available. - Enobufs - /// No such device. - Enodev - /// No locks available. - Enolck - /// Link has been severed. - Enolink - /// No such file or directory. - Enoent - /// Not enough memory. - Enomem - /// No space left on device. - Enospc - /// No STREAM resources. - Enosr - /// Not a STREAM. - Enostr - /// Function not implemented. - Enosys - /// Block device required. - Enotblk - /// Not a directory. - Enotdir - /// Operation not supported. - Enotsup - /// No such device or address. - Enxio - /// Operation not supported on socket. - Eopnotsupp - /// Value too large to be stored in data type. - Eoverflow - /// Not owner. - Eperm - /// Broken pipe. - Epipe - /// Result too large. - Erange - /// Read-only file system. - Erofs - /// Invalid seek. - Espipe - /// No such process. - Esrch - /// Stale remote file handle. - Estale - /// Text file busy. - Etxtbsy - /// Cross-domain link. - Exdev - /// File was requested to be read as UTF-8, but is not UTF-8 encoded. - NotUtf8 - /// Any error not accounted for by this type - Unknown -} - -/// Read a files contents as a string -/// ## Example -/// ```gleam -/// let assert Ok(records) = read(from: "./users.csv") -/// ``` -/// -pub fn read(from filepath: String) -> Result(String, FileError) { - do_read(filepath) - |> cast_error -} - -/// Write a string to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write("Hello, World!", to: "./hello_world.txt") -/// ``` -/// -pub fn write( - to filepath: String, - contents contents: String, -) -> Result(Nil, FileError) { - do_write(contents, to: filepath) - |> cast_error -} - -/// Delete a file or directory at a given path. Performs a recursive -/// delete on a directory. -/// Throws an error if the path does not exist. -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = delete(file_at: "./delete_me.txt") -/// ``` -/// -pub fn delete(file_or_dir_at path: String) -> Result(Nil, FileError) { - do_delete(path) - |> cast_error -} - -/// Delete all files/directories specified in a list of paths. -/// Recursively deletes provided directories. -/// Does not return an error if one or more of the provided paths -/// do not exist. -/// -pub fn delete_all(paths paths: List(String)) -> Result(Nil, FileError) { - case paths { - [] -> Ok(Nil) - [path, ..rest] -> { - case delete(path) { - Ok(Nil) | Error(Enoent) -> delete_all(rest) - e -> e - } - } - } -} - -/// Append a string to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append("more text", to: "./needs_more_text.txt") -/// ``` -/// -pub fn append( - to filepath: String, - contents contents: String, -) -> Result(Nil, FileError) { - do_append(contents, to: filepath) - |> cast_error -} - -/// Read a files contents as a bitstring -/// ## Example -/// ```gleam -/// let assert Ok(records) = read_bits(from: "./users.csv") -/// ``` -/// -pub fn read_bits(from filepath: String) -> Result(BitArray, FileError) { - do_read_bits(filepath) - |> cast_error -} - -/// Write a bitstring to a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = write_bits(<<"Hello, World!":utf8>>, to: "./hello_world.txt") -/// ``` -/// -pub fn write_bits( - to filepath: String, - bits bits: BitArray, -) -> Result(Nil, FileError) { - do_write_bits(bits, filepath) - |> cast_error -} - -/// Append a bitstring to the contents of a file at the given path -/// ## Example -/// ```gleam -/// let assert Ok(Nil) = append_bits(<<"more text":utf8>>, to: "./needs_more_text.txt") -/// ``` -/// -pub fn append_bits( - to filepath: String, - bits bits: BitArray, -) -> Result(Nil, FileError) { - do_append_bits(bits, filepath) - |> cast_error -} - -/// Checks if the provided filepath is a directory -/// ## Example -/// ```gleam -/// let assert True = is_directory("./test") -/// ``` -pub fn is_directory(filepath: String) -> Bool { - do_is_directory(filepath) -} - -/// Create a directory at the provided filepath. Returns an error if -/// the directory already exists. -/// -/// ## Example -/// ```gleam -/// create_directory("./test") -/// ``` -pub fn create_directory(filepath: String) -> Result(Nil, FileError) { - do_make_directory(filepath) - |> cast_error -} - -/// Lists the contents of a directory. -/// The list contains directory and file names, and is not recursive. -/// -/// ## Example -/// ```gleam -/// let assert Ok(files_and_folders) = read_directory(at: "./Folder1") -/// ``` -/// -pub fn read_directory(at path: String) -> Result(List(String), FileError) { - do_read_directory(path) - |> cast_error -} - -/// Returns `True` if there is a file at the given path, false otherwise. -/// -pub fn is_file(filepath: String) -> Bool { - do_is_file(filepath) -} - -/// Creates an empty file at the given filepath. Returns an `Error(Eexist)` -/// if the file already exists. -/// -pub fn create_file(at filepath: String) -> Result(Nil, FileError) { - case - filepath - |> is_file || filepath - |> is_directory - { - True -> Error(Eexist) - False -> write_bits(<<>>, to: filepath) - } -} - -/// Recursively creates necessary directories for a given directory -/// path. Note that if you pass a path that "looks like" a file, i.e. -/// `./a/b.txt`, a folder named `b.txt` will be created, so be sure -/// to pass only the path to the required directory. -pub fn create_directory_all(dirpath: String) -> Result(Nil, FileError) { - let path = case - dirpath - |> string.ends_with("/") - { - True -> dirpath - False -> dirpath <> "/" - } - do_create_dir_all(path) - |> cast_error -} - -/// Copy a file at a given path to another path. -/// Note: destination should include the filename, not just the directory -pub fn copy_file(at src: String, to dest: String) -> Result(Nil, FileError) { - do_copy_file(src, dest) - |> result.replace(Nil) - |> cast_error -} - -/// Rename a file at a given path to another path. -/// Note: destination should include the filename, not just the directory -pub fn rename_file(at src: String, to dest: String) -> Result(Nil, FileError) { - do_rename_file(src, dest) - |> cast_error -} - -/// Copy a directory recursively -pub fn copy_directory(at src: String, to dest: String) -> Result(Nil, FileError) { - // Erlang does not provide a built in `copy_dir` function, - // and Deno doesn't support Node's `fs.cpSync`, so we'll just roll - // our own for now. - use _ <- result.try(create_directory_all(dest)) - do_copy_directory(src, dest) -} - -fn do_copy_directory(src: String, dest: String) -> Result(Nil, FileError) { - // Iterate over the segments of the file - use segments <- result.try(read_directory(src)) - segments - |> list.each(fn(segment) { - let src_path = src <> "/" <> segment - let dest_path = dest <> "/" <> segment - - case is_file(src_path), is_directory(src_path) { - True, False -> { - // For a file, create the file in the new directory - use content <- result.try(read_bits(src_path)) - content - |> write_bits(to: dest_path) - } - False, True -> { - // Create the target directory and recurs - use _ <- result.try(create_directory(dest_path)) - do_copy_directory(src_path, dest_path) - } - _, _ -> { - // This should be unreachable. The src_path can't be both a file - // and a directory, and it's definitely one of the two because it's - // coming from list_contents - panic as "unreachable" - } - } - }) - Ok(Nil) -} - -/// Copy a directory recursively and then delete the old one. -pub fn rename_directory( - at src: String, - to dest: String, -) -> Result(Nil, FileError) { - use _ <- result.try(copy_directory(src, dest)) - delete(src) -} - -/// Returns a list of filepaths for every file in the directory, including nested -/// files. -/// -pub fn get_files(in directory: String) -> Result(List(String), FileError) { - use contents <- result.try(read_directory(directory)) - let paths = list.map(contents, fn(segment) { directory <> "/" <> segment }) - let files = list.filter(paths, is_file) - case list.filter(paths, is_directory) { - [] -> Ok(files) - directories -> { - use nested_files <- result.try(list.try_map(directories, get_files)) - Ok(list.append(files, list.flatten(nested_files))) - } - } -} - -@target(javascript) -fn do_read(from filepath: String) -> Result(String, String) { - case do_read_bits(filepath) { - Ok(bits) -> { - case bit_array.to_string(bits) { - Ok(str) -> Ok(str) - _ -> Error("NOTUTF8") - } - } - Error(e) -> Error(e) - } -} - -@target(javascript) -fn do_write(content: String, to filepath: String) -> Result(Nil, String) { - content - |> bit_array.from_string - |> do_write_bits(to: filepath) -} - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "deleteFileOrDirRecursive") -fn do_delete(file_or_dir_at: String) -> Result(Nil, String) - -@target(javascript) -fn do_append(content: String, to filepath: String) -> Result(Nil, String) { - content - |> bit_array.from_string - |> do_append_bits(to: filepath) -} - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "readBits") -fn do_read_bits(from: String) -> Result(BitArray, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "writeBits") -fn do_write_bits(content: BitArray, to filepath: String) -> Result(Nil, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "appendBits") -fn do_append_bits(content: BitArray, to filepath: String) -> Result(Nil, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "isDirectory") -fn do_is_directory(filepath: String) -> Bool - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "makeDirectory") -fn do_make_directory(filepath: String) -> Result(Nil, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "createDirAll") -fn do_create_dir_all(dirpath: String) -> Result(Nil, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "listContents") -fn do_read_directory(directory_path: String) -> Result(List(String), String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "copyFile") -fn do_copy_file(at: String, to: String) -> Result(Nil, String) - -@target(javascript) -@external(javascript, "./simplifile_js.mjs", "renameFile") -fn do_rename_file(at: String, to: String) -> Result(Nil, String) - -@target(javascript) -fn cast_error(input: Result(a, String)) -> Result(a, FileError) { - result.map_error( - input, - fn(e) { - case e { - "EACCES" -> Eacces - "EAGAIN" -> Eagain - "EBADF" -> Ebadf - "EBADMSG" -> Ebadmsg - "EBUSY" -> Ebusy - "EDEADLK" -> Edeadlk - "EDEADLOCK" -> Edeadlock - "EDQUOT" -> Edquot - "EEXIST" -> Eexist - "EFAULT" -> Efault - "EFBIG" -> Efbig - "EFTYPE" -> Eftype - "EINTR" -> Eintr - "EINVAL" -> Einval - "EIO" -> Eio - "EISDIR" -> Eisdir - "ELOOP" -> Eloop - "EMFILE" -> Emfile - "EMLINK" -> Emlink - "EMULTIHOP" -> Emultihop - "ENAMETOOLONG" -> Enametoolong - "ENFILE" -> Enfile - "ENOBUFS" -> Enobufs - "ENODEV" -> Enodev - "ENOLCK" -> Enolck - "ENOLINK" -> Enolink - "ENOENT" -> Enoent - "ENOMEM" -> Enomem - "ENOSPC" -> Enospc - "ENOSR" -> Enosr - "ENOSTR" -> Enostr - "ENOSYS" -> Enosys - "ENOBLK" -> Enotblk - "ENODIR" -> Enotdir - "ENOTSUP" -> Enotsup - "ENXIO" -> Enxio - "EOPNOTSUPP" -> Eopnotsupp - "EOVERFLOW" -> Eoverflow - "EPERM" -> Eperm - "EPIPE" -> Epipe - "ERANGE" -> Erange - "EROFS" -> Erofs - "ESPIPE" -> Espipe - "ESRCH" -> Esrch - "ESTALE" -> Estale - "ETXTBSY" -> Etxtbsy - "EXDEV" -> Exdev - "NOTUTF8" -> NotUtf8 - _ -> Unknown - } - }, - ) -} - -@target(erlang) -@external(erlang, "simplifile_erl", "append_file") -fn do_append_bits( - content: BitArray, - to filepath: String, -) -> Result(Nil, FileError) - -@target(erlang) -@external(erlang, "simplifile_erl", "write_file") -fn do_write_bits( - content: BitArray, - to filepath: String, -) -> Result(Nil, FileError) - -@target(erlang) -@external(erlang, "simplifile_erl", "read_file") -fn do_read_bits(from: String) -> Result(BitArray, FileError) - -@target(erlang) -@external(erlang, "simplifile_erl", "recursive_delete") -fn do_delete(file_or_dir_at: String) -> Result(Nil, FileError) - -@target(erlang) -fn do_append(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_array.from_string - |> do_append_bits(filepath) -} - -@target(erlang) -fn do_write(content: String, to filepath: String) -> Result(Nil, FileError) { - content - |> bit_array.from_string - |> do_write_bits(filepath) -} - -@target(erlang) -fn do_read(from filepath: String) -> Result(String, FileError) { - case do_read_bits(filepath) { - Ok(bits) -> { - case bit_array.to_string(bits) { - Ok(str) -> Ok(str) - _ -> Error(NotUtf8) - } - } - Error(e) -> Error(e) - } -} - -@target(erlang) -fn cast_error(input: Result(a, FileError)) -> Result(a, FileError) { - input -} - -@target(erlang) -@external(erlang, "filelib", "is_dir") -fn do_is_directory(path: String) -> Bool - -@target(erlang) -@external(erlang, "simplifile_erl", "make_directory") -fn do_make_directory(directory: String) -> Result(Nil, FileError) - -@target(erlang) -@external(erlang, "simplifile_erl", "list_directory") -fn do_read_directory(directory: String) -> Result(List(String), FileError) - -@external(erlang, "simplifile_erl", "is_file") -@external(javascript, "./simplifile_js.mjs", "isFile") -fn do_is_file(filepath: String) -> Bool - -@target(erlang) -@external(erlang, "simplifile_erl", "create_dir_all") -fn do_create_dir_all(dirpath: String) -> Result(Nil, FileError) - -@target(erlang) -@external(erlang, "file", "copy") -fn do_copy_file(src: String, dest: String) -> Result(Int, FileError) - -@target(erlang) -@external(erlang, "simplifile_erl", "rename_file") -fn do_rename_file(src: String, dest: String) -> Result(Nil, FileError) diff --git a/aoc2023/build/packages/simplifile/src/simplifile_erl.erl b/aoc2023/build/packages/simplifile/src/simplifile_erl.erl deleted file mode 100644 index dac135a..0000000 --- a/aoc2023/build/packages/simplifile/src/simplifile_erl.erl +++ /dev/null @@ -1,70 +0,0 @@ --module(simplifile_erl). --export([ - read_file/1, - append_file/2, write_file/2, delete_file/1, delete_directory/1, recursive_delete/1, - list_directory/1, make_directory/1, is_file/1, create_dir_all/1, rename_file/2 -]). - --define(is_posix_error(Error), - Error =:= eacces orelse Error =:= eagain orelse Error =:= ebadf orelse - Error =:= ebadmsg orelse Error =:= ebusy orelse Error =:= edeadlk orelse - Error =:= edeadlock orelse Error =:= edquot orelse Error =:= eexist orelse - Error =:= efault orelse Error =:= efbig orelse Error =:= eftype orelse - Error =:= eintr orelse Error =:= einval orelse Error =:= eio orelse - Error =:= eisdir orelse Error =:= eloop orelse Error =:= emfile orelse - Error =:= emlink orelse Error =:= emultihop orelse Error =:= enametoolong orelse - Error =:= enfile orelse Error =:= enobufs orelse Error =:= enodev orelse - Error =:= enolck orelse Error =:= enolink orelse Error =:= enoent orelse - Error =:= enomem orelse Error =:= enospc orelse Error =:= enosr orelse - Error =:= enostr orelse Error =:= enosys orelse Error =:= enotblk orelse - Error =:= enotdir orelse Error =:= enotsup orelse Error =:= enxio orelse - Error =:= eopnotsupp orelse Error =:= eoverflow orelse Error =:= eperm orelse - Error =:= epipe orelse Error =:= erange orelse Error =:= erofs orelse - Error =:= espipe orelse Error =:= esrch orelse Error =:= estale orelse - Error =:= etxtbsy orelse Error =:= exdev -). - -posix_result(Result) -> - case Result of - ok -> {ok, nil}; - {ok, Value} -> {ok, Value}; - {error, Reason} when ?is_posix_error(Reason) -> {error, Reason} - end. - -read_file(Filename) -> - posix_result(file:read_file(Filename)). - -write_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents)). - -append_file(Contents, Filename) -> - posix_result(file:write_file(Filename, Contents, [append])). - -delete_file(Filename) -> - posix_result(file:delete(Filename)). - -make_directory(Dir) -> - posix_result(file:make_dir(Dir)). - -list_directory(Dir) -> - case file:list_dir(Dir) of - {ok, Filenames} -> - {ok, [list_to_binary(Filename) || Filename <- Filenames]}; - {error, Reason} when ?is_posix_error(Reason) -> - {error, Reason} - end. - -delete_directory(Dir) -> - posix_result(file:del_dir(Dir)). - -recursive_delete(Dir) -> - posix_result(file:del_dir_r(Dir)). - -is_file(Filename) -> - not (file:read_file_info(Filename) == {error, enoent}) and not filelib: is_dir(Filename). - -create_dir_all(Filename) -> - posix_result(filelib:ensure_dir(Filename)). - -rename_file(Source, Destination) -> - posix_result(file:rename(Source, Destination)). diff --git a/aoc2023/build/packages/simplifile/src/simplifile_js.mjs b/aoc2023/build/packages/simplifile/src/simplifile_js.mjs deleted file mode 100644 index faf4109..0000000 --- a/aoc2023/build/packages/simplifile/src/simplifile_js.mjs +++ /dev/null @@ -1,102 +0,0 @@ -import fs from "node:fs" -import path from "node:path" -import { BitArray, Ok, Error as GError, toList} from "./gleam.mjs"; - -export function readBits(filepath) { - try { - const contents = fs.readFileSync(path.normalize(filepath)) - return new Ok(new BitArray(new Uint8Array(contents))) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function writeBits(contents, filepath) { - try { - fs.writeFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function appendBits(contents, filepath) { - try { - fs.appendFileSync(path.normalize(filepath), contents.buffer) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -function stringifyError(e) { - return e.code -} - -export function isFile(filepath) { - let fp = path.normalize(filepath) - return fs.existsSync(fp) && fs.lstatSync(fp).isFile(); -} - -export function isDirectory(filepath) { - let fp = path.normalize(filepath) - return fs.existsSync(fp) && fs.lstatSync(fp).isDirectory(); -} - -export function makeDirectory(filepath) { - try { - fs.mkdirSync(path.normalize(filepath)) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function createDirAll(filepath) { - try { - fs.mkdirSync(filepath, { recursive: true }) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function deleteFileOrDirRecursive(fileOrDirPath) { - try { - if (isDirectory(fileOrDirPath)) { - fs.rmSync(path.normalize(fileOrDirPath), { recursive: true }) - } else { - fs.unlinkSync(path.normalize(fileOrDirPath)) - } - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function listContents(filepath) { - try { - const stuff = toList(fs.readdirSync(path.normalize(filepath))) - return new Ok(stuff) - } catch(e) { - return new GError(stringifyError(e)) - } -} - -export function copyFile(srcpath, destpath) { - try { - fs.copyFileSync(path.normalize(srcpath), path.normalize(destpath)) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -} - -export function renameFile(srcpath, destpath) { - try { - fs.renameSync(path.normalize(srcpath), path.normalize(destpath)) - return new Ok(undefined) - } catch (e) { - return new GError(stringifyError(e)) - } -}
\ No newline at end of file diff --git a/aoc2023/build/packages/snag/LICENCE b/aoc2023/build/packages/snag/LICENCE deleted file mode 100644 index b8c2e9e..0000000 --- a/aoc2023/build/packages/snag/LICENCE +++ /dev/null @@ -1,211 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2021 - present Louis Pilfold - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - -## Runtime Library Exception to the Apache 2.0 License: ## - - - As an exception, if you use this Software to compile your source code and - portions of this Software are embedded into the binary product as a result, - you may redistribute such product without providing attribution as would - otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. diff --git a/aoc2023/build/packages/snag/README.md b/aoc2023/build/packages/snag/README.md deleted file mode 100644 index aaedcf5..0000000 --- a/aoc2023/build/packages/snag/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Snag - -A Snag is a boilerplate-free ad-hoc error type. - -Use `Result(value, Snag)` (or the `snag.Result(value)` alias) in functions -that may fail. - -A low level message like "Unexpected status 401" or "No such file or -directory" can be confusing or difficult to debug, so use the `snag.context` -function to add extra contextual information. - -```gleam -import gleam/io -import my_app.{User} -import snag.{Result} - -pub fn log_in(user_id: Int) -> Result(User) { - try api_key = - my_app.read_file("api_key.txt") - |> snag.context("Could not load API key") - - try session_token = - user_id - |> my_app.create_session(api_key) - |> snag.context("Session creation failed") - - Ok(session_token) -} - -pub fn main() { - case log_in(42) { - Ok(session) -> io.println("Logged in!") - Error(snag) -> { - io.print(snag.pretty_print(snag)) - my_app.exit(1) - } - } -} -``` - -In this code when an error occurs within the `create_session` function an -error message like this is printed using the added contextual information: - -```text -error: Session creation failed - -cause: - 0: Unable to exchange token with authentication service - 1: Service authentication failed - 2: Unexpected HTTP status 401 -``` - -## When should I use Snag? - -Snag is useful in code where it must either pass or fail, and when it fails we -want good debugging information to print to the user. i.e. Command line -tools, data processing pipelines, etc. Here Snag provides a convenient way to -create errors with a reasonable amount of debugging information, without the -boilerplate of a custom error type. - -It is not suited to code where the application needs to make a decision about -what to do in the event of an error, such as whether to give up or to try -again. i.e. Libraries, web application backends, API clients, etc. In these -situations it is recommended to create a custom type for your errors as it -can be pattern matched on and have any additional detail added as fields. - -## Installation - -Add `snag` to your Gleam project - -``` -gleam add snag -``` - -## Prior art - -This library is inspired by the following projects: - -- Rust's [`anyhow`](https://github.com/dtolnay/anyhow) and - [`std::error::Error`](https://doc.rust-lang.org/std/error/trait.Error.html) -- Go's [`error`](https://golang.org/pkg/errors/). diff --git a/aoc2023/build/packages/snag/gleam.toml b/aoc2023/build/packages/snag/gleam.toml deleted file mode 100644 index 4f2d670..0000000 --- a/aoc2023/build/packages/snag/gleam.toml +++ /dev/null @@ -1,16 +0,0 @@ -name = "snag" -version = "0.2.1" -licences = ["Apache-2.0"] -description = "A boilerplate-free ad-hoc error type" - -repository = { type = "github", user = "gleam-experiments", repo = "snag" } -links = [ - { title = "Website", href = "https://gleam.run" }, - { title = "Sponsor", href = "https://github.com/sponsors/lpil" }, -] - -[dependencies] -gleam_stdlib = "~> 0.18" - -[dev-dependencies] -gleeunit = "~> 0.5" diff --git a/aoc2023/build/packages/snag/include/snag_Snag.hrl b/aoc2023/build/packages/snag/include/snag_Snag.hrl deleted file mode 100644 index 5d6614e..0000000 --- a/aoc2023/build/packages/snag/include/snag_Snag.hrl +++ /dev/null @@ -1 +0,0 @@ --record(snag, {issue :: binary(), cause :: list(binary())}). diff --git a/aoc2023/build/packages/snag/src/snag.app.src b/aoc2023/build/packages/snag/src/snag.app.src deleted file mode 100644 index 175e326..0000000 --- a/aoc2023/build/packages/snag/src/snag.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, snag, [ - {vsn, "0.2.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A boilerplate-free ad-hoc error type"}, - {modules, [snag]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/snag/src/snag.erl b/aoc2023/build/packages/snag/src/snag.erl deleted file mode 100644 index a07f242..0000000 --- a/aoc2023/build/packages/snag/src/snag.erl +++ /dev/null @@ -1,74 +0,0 @@ --module(snag). --compile([no_auto_import, nowarn_unused_vars]). - --export([new/1, error/1, layer/2, context/2, pretty_print/1, line_print/1]). --export_type([snag/0]). - --type snag() :: {snag, binary(), list(binary())}. - --spec new(binary()) -> snag(). -new(Issue) -> - {snag, Issue, []}. - --spec error(binary()) -> {ok, any()} | {error, snag()}. -error(Issue) -> - {error, new(Issue)}. - --spec layer(snag(), binary()) -> snag(). -layer(Snag, Issue) -> - {snag, Issue, [erlang:element(2, Snag) | erlang:element(3, Snag)]}. - --spec context({ok, EXX} | {error, snag()}, binary()) -> {ok, EXX} | - {error, snag()}. -context(Result, Issue) -> - case Result of - {ok, _} -> - Result; - - {error, Snag} -> - {error, layer(Snag, Issue)} - end. - --spec pretty_print_cause(list(binary())) -> gleam@string_builder:string_builder(). -pretty_print_cause(Cause) -> - _pipe = Cause, - _pipe@1 = gleam@list:index_map( - _pipe, - fun(Index, Line) -> - gleam@string:concat( - [<<" "/utf8>>, - gleam@int:to_string(Index), - <<": "/utf8>>, - Line, - <<"\n"/utf8>>] - ) - end - ), - gleam@string_builder:from_strings(_pipe@1). - --spec pretty_print(snag()) -> binary(). -pretty_print(Snag) -> - Builder = gleam@string_builder:from_strings( - [<<"error: "/utf8>>, erlang:element(2, Snag), <<"\n"/utf8>>] - ), - gleam@string_builder:to_string(case erlang:element(3, Snag) of - [] -> - Builder; - - Cause -> - _pipe = Builder, - _pipe@1 = gleam@string_builder:append( - _pipe, - <<"\ncause:\n"/utf8>> - ), - gleam@string_builder:append_builder( - _pipe@1, - pretty_print_cause(Cause) - ) - end). - --spec line_print(snag()) -> binary(). -line_print(Snag) -> - _pipe = [gleam@string:append(<<"error: "/utf8>>, erlang:element(2, Snag)) | - erlang:element(3, Snag)], - gleam@string:join(_pipe, <<" <- "/utf8>>). diff --git a/aoc2023/build/packages/snag/src/snag.gleam b/aoc2023/build/packages/snag/src/snag.gleam deleted file mode 100644 index 8d39537..0000000 --- a/aoc2023/build/packages/snag/src/snag.gleam +++ /dev/null @@ -1,141 +0,0 @@ -import gleam -import gleam/string_builder -import gleam/string -import gleam/list -import gleam/int - -/// A Snag is a boilerplate-free error type that can be used to track why an -/// error happened, though does not store as much detail on specific errors as a -/// custom error type would. -/// -/// It is useful in code where it must either pass or fail, and when it fails we -/// want good debugging information to print to the user. i.e. Command line -/// tools, data processing pipelines, etc. -/// -/// If it not suited to code where the application needs to make a decision about -/// what to do in the event of an error, such as whether to give up or to try -/// again. i.e. Libraries, web application backends, API clients, etc. -/// In these situations it is recommended to create a custom type for your errors -/// as it can be pattern matched on and have any additional detail added as -/// fields. -pub type Snag { - Snag(issue: String, cause: List(String)) -} - -/// A concise alias for a `Result` that uses a `Snag` as the error value. -pub type Result(t) = - gleam.Result(t, Snag) - -/// Create a new `Snag` with the given issue text. -/// -/// See also the `error` function for creating a `Snag` wrapped in a `Result`. -/// -/// # Example -/// -/// ```gleam -/// > new("Not enough credit") -/// > |> line_print -/// "error: Not enough credit" -/// ``` -pub fn new(issue: String) -> Snag { - Snag(issue: issue, cause: []) -} - -/// Create a new `Snag` wrapped in a `Result` with the given issue text. -/// -/// # Example -/// -/// ```gleam -/// > error("Not enough credit") -/// Error(new("Not enough credit")) -/// ``` -pub fn error(issue: String) -> Result(success) { - Error(new(issue)) -} - -/// Add additional contextual information to a `Snag`. -/// -/// See also the `context` function for adding contextual information to a `Snag` -/// wrapped in a `Result`. -/// -/// # Example -/// -/// ```gleam -/// > new("Not enough credit") -/// > |> layer("Unable to make purchase") -/// > |> line_print -/// "error: Unable to make purchase <- Not enough credit" -/// ``` -pub fn layer(snag: Snag, issue: String) -> Snag { - Snag(issue: issue, cause: [snag.issue, ..snag.cause]) -} - -/// Add additional contextual information to a `Snag` wrapped in a `Result`. -/// -/// # Example -/// -/// ```gleam -/// > error("Not enough credit") -/// > |> context("Unable to make purchase") -/// > |> result.map_error(line_print) -/// Error("error: Unable to make purchase <- Not enough credit") -/// ``` -pub fn context(result: Result(success), issue: String) -> Result(success) { - case result { - Ok(_) -> result - Error(snag) -> Error(layer(snag, issue)) - } -} - -/// Turn a snag into a multi-line string, optimised for readability. -/// -/// # Example -/// -/// ```gleam -/// > new("Not enough credit") -/// > |> layer("Unable to make purchase") -/// > |> layer("Character creation failed") -/// > |> pretty_print -/// "error: Character creation failed -/// -/// cause: -/// 0: Unable to make purchase -/// 1: Not enough credit -/// " -/// ``` -pub fn pretty_print(snag: Snag) -> String { - let builder = string_builder.from_strings(["error: ", snag.issue, "\n"]) - - string_builder.to_string(case snag.cause { - [] -> builder - cause -> - builder - |> string_builder.append("\ncause:\n") - |> string_builder.append_builder(pretty_print_cause(cause)) - }) -} - -fn pretty_print_cause(cause) { - cause - |> list.index_map(fn(index, line) { - string.concat([" ", int.to_string(index), ": ", line, "\n"]) - }) - |> string_builder.from_strings -} - -/// Turn a snag into a single-line string, optimised for compactness. This may be -/// useful for logging snags. -/// -/// # Example -/// -/// ```gleam -/// > new("Not enough credit") -/// > |> layer("Unable to make purchase") -/// > |> layer("Character creation failed") -/// > |> pretty_print -/// "error: Character creation failed <- Unable to make purchase <- Not enough credit" -/// ``` -pub fn line_print(snag: Snag) -> String { - [string.append("error: ", snag.issue), ..snag.cause] - |> string.join(" <- ") -} diff --git a/aoc2023/build/packages/tom/README.md b/aoc2023/build/packages/tom/README.md deleted file mode 100644 index e6adcbe..0000000 --- a/aoc2023/build/packages/tom/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# tom - -A Gleam TOML parser! - -[](https://hex.pm/packages/tom) -[](https://hexdocs.pm/tom/) - - -```sh -gleam add tom -``` -```gleam -import tom - -const config = " - [person] - name = \"Lucy\" - is_cool = true -" - -pub fn main() { - // Parse a string of TOML - let assert Ok(parsed) = tom.parse(config) - - // Now you can work with the data directly, or you can use the `get_*` - // functions to retrieve values. - - tom.get_string(parsed, ["person", "name"]) - // -> Ok("Lucy") - - let is_cool = tom.get_bool(parsed, ["person", "is_cool"]) - // -> Ok(True) -} -``` - -Further documentation can be found at <https://hexdocs.pm/tom>. - -## Status - -The following string escape sequences are not supported yet: - -- `\b` -- `\f` -- `\e` -- `\xHH` -- `\uHHHH` -- `\UHHHHHHHH` diff --git a/aoc2023/build/packages/tom/gleam.toml b/aoc2023/build/packages/tom/gleam.toml deleted file mode 100644 index f131d09..0000000 --- a/aoc2023/build/packages/tom/gleam.toml +++ /dev/null @@ -1,13 +0,0 @@ -name = "tom" -version = "0.2.1" - -description = "A pure Gleam TOML parser!" -licences = ["Apache-2.0"] -repository = { type = "github", user = "lpil", repo = "tom" } -links = [{ title = "TOML website", href = "https://toml.io/en/" }] - -[dependencies] -gleam_stdlib = "~> 0.32" - -[dev-dependencies] -gleeunit = "~> 1.0" diff --git a/aoc2023/build/packages/tom/include/tom_DateTimeValue.hrl b/aoc2023/build/packages/tom/include/tom_DateTimeValue.hrl deleted file mode 100644 index 3b1e660..0000000 --- a/aoc2023/build/packages/tom/include/tom_DateTimeValue.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(date_time_value, { - date :: tom:date(), - time :: tom:time(), - offset :: tom:offset() -}). diff --git a/aoc2023/build/packages/tom/include/tom_DateValue.hrl b/aoc2023/build/packages/tom/include/tom_DateValue.hrl deleted file mode 100644 index c41f901..0000000 --- a/aoc2023/build/packages/tom/include/tom_DateValue.hrl +++ /dev/null @@ -1 +0,0 @@ --record(date_value, {year :: integer(), month :: integer(), day :: integer()}). diff --git a/aoc2023/build/packages/tom/include/tom_KeyAlreadyInUse.hrl b/aoc2023/build/packages/tom/include/tom_KeyAlreadyInUse.hrl deleted file mode 100644 index 930df26..0000000 --- a/aoc2023/build/packages/tom/include/tom_KeyAlreadyInUse.hrl +++ /dev/null @@ -1 +0,0 @@ --record(key_already_in_use, {key :: list(binary())}). diff --git a/aoc2023/build/packages/tom/include/tom_NotFound.hrl b/aoc2023/build/packages/tom/include/tom_NotFound.hrl deleted file mode 100644 index 19c9a17..0000000 --- a/aoc2023/build/packages/tom/include/tom_NotFound.hrl +++ /dev/null @@ -1 +0,0 @@ --record(not_found, {key :: list(binary())}). diff --git a/aoc2023/build/packages/tom/include/tom_Offset.hrl b/aoc2023/build/packages/tom/include/tom_Offset.hrl deleted file mode 100644 index a58a8e1..0000000 --- a/aoc2023/build/packages/tom/include/tom_Offset.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(offset, { - direction :: tom:sign(), - hours :: integer(), - minutes :: integer() -}). diff --git a/aoc2023/build/packages/tom/include/tom_TimeValue.hrl b/aoc2023/build/packages/tom/include/tom_TimeValue.hrl deleted file mode 100644 index e1275de..0000000 --- a/aoc2023/build/packages/tom/include/tom_TimeValue.hrl +++ /dev/null @@ -1,6 +0,0 @@ --record(time_value, { - hour :: integer(), - minute :: integer(), - second :: integer(), - millisecond :: integer() -}). diff --git a/aoc2023/build/packages/tom/include/tom_Unexpected.hrl b/aoc2023/build/packages/tom/include/tom_Unexpected.hrl deleted file mode 100644 index ab1091c..0000000 --- a/aoc2023/build/packages/tom/include/tom_Unexpected.hrl +++ /dev/null @@ -1 +0,0 @@ --record(unexpected, {got :: binary(), expected :: binary()}). diff --git a/aoc2023/build/packages/tom/include/tom_WrongType.hrl b/aoc2023/build/packages/tom/include/tom_WrongType.hrl deleted file mode 100644 index ae57352..0000000 --- a/aoc2023/build/packages/tom/include/tom_WrongType.hrl +++ /dev/null @@ -1,5 +0,0 @@ --record(wrong_type, { - key :: list(binary()), - expected :: binary(), - got :: binary() -}). diff --git a/aoc2023/build/packages/tom/src/tom.app.src b/aoc2023/build/packages/tom/src/tom.app.src deleted file mode 100644 index 051649c..0000000 --- a/aoc2023/build/packages/tom/src/tom.app.src +++ /dev/null @@ -1,8 +0,0 @@ -{application, tom, [ - {vsn, "0.2.1"}, - {applications, [gleam_stdlib, - gleeunit]}, - {description, "A pure Gleam TOML parser!"}, - {modules, [tom]}, - {registered, []} -]}. diff --git a/aoc2023/build/packages/tom/src/tom.erl b/aoc2023/build/packages/tom/src/tom.erl deleted file mode 100644 index 4f5c071..0000000 --- a/aoc2023/build/packages/tom/src/tom.erl +++ /dev/null @@ -1,2140 +0,0 @@ --module(tom). --compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]). - --export([get/2, get_int/2, get_float/2, get_bool/2, get_string/2, get_date/2, get_time/2, get_date_time/2, get_array/2, get_table/2, get_number/2, parse/1]). --export_type([toml/0, date_time/0, date/0, time/0, offset/0, sign/0, parse_error/0, number_/0, get_error/0]). - --type toml() :: {int, integer()} | - {float, float()} | - {infinity, sign()} | - {nan, sign()} | - {bool, boolean()} | - {string, binary()} | - {date, date()} | - {time, time()} | - {date_time, date_time()} | - {array, list(toml())} | - {array_of_tables, list(gleam@map:map_(binary(), toml()))} | - {table, gleam@map:map_(binary(), toml())} | - {inline_table, gleam@map:map_(binary(), toml())}. - --type date_time() :: {date_time_value, date(), time(), offset()}. - --type date() :: {date_value, integer(), integer(), integer()}. - --type time() :: {time_value, integer(), integer(), integer(), integer()}. - --type offset() :: local | {offset, sign(), integer(), integer()}. - --type sign() :: positive | negative. - --type parse_error() :: {unexpected, binary(), binary()} | - {key_already_in_use, list(binary())}. - --type number_() :: {number_int, integer()} | - {number_float, float()} | - {number_infinity, sign()} | - {number_nan, sign()}. - --type get_error() :: {not_found, list(binary())} | - {wrong_type, list(binary()), binary(), binary()}. - --spec classify(toml()) -> binary(). -classify(Toml) -> - case Toml of - {int, _} -> - <<"Int"/utf8>>; - - {float, _} -> - <<"Float"/utf8>>; - - {nan, positive} -> - <<"NaN"/utf8>>; - - {nan, negative} -> - <<"Negative NaN"/utf8>>; - - {infinity, positive} -> - <<"Infinity"/utf8>>; - - {infinity, negative} -> - <<"Negative Infinity"/utf8>>; - - {bool, _} -> - <<"Bool"/utf8>>; - - {string, _} -> - <<"String"/utf8>>; - - {date, _} -> - <<"Date"/utf8>>; - - {time, _} -> - <<"Time"/utf8>>; - - {date_time, _} -> - <<"DateTime"/utf8>>; - - {array, _} -> - <<"Array"/utf8>>; - - {array_of_tables, _} -> - <<"Array"/utf8>>; - - {table, _} -> - <<"Table"/utf8>>; - - {inline_table, _} -> - <<"Table"/utf8>> - end. - --spec push_key({ok, FIU} | {error, get_error()}, binary()) -> {ok, FIU} | - {error, get_error()}. -push_key(Result, Key) -> - case Result of - {ok, T} -> - {ok, T}; - - {error, {not_found, Path}} -> - {error, {not_found, [Key | Path]}}; - - {error, {wrong_type, Path@1, Expected, Got}} -> - {error, {wrong_type, [Key | Path@1], Expected, Got}} - end. - --spec get(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, toml()} | - {error, get_error()}. -get(Toml, Key) -> - case Key of - [] -> - {error, {not_found, []}}; - - [K] -> - gleam@result:replace_error(gleam@map:get(Toml, K), {not_found, [K]}); - - [K@1 | Key@1] -> - case gleam@map:get(Toml, K@1) of - {ok, {table, T}} -> - push_key(get(T, Key@1), K@1); - - {ok, Other} -> - {error, - {wrong_type, [K@1], <<"Table"/utf8>>, classify(Other)}}; - - {error, _} -> - {error, {not_found, [K@1]}} - end - end. - --spec get_int(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - integer()} | - {error, get_error()}. -get_int(Toml, Key) -> - case get(Toml, Key) of - {ok, {int, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Int"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_float(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - float()} | - {error, get_error()}. -get_float(Toml, Key) -> - case get(Toml, Key) of - {ok, {float, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Float"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_bool(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - boolean()} | - {error, get_error()}. -get_bool(Toml, Key) -> - case get(Toml, Key) of - {ok, {bool, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Bool"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_string(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - binary()} | - {error, get_error()}. -get_string(Toml, Key) -> - case get(Toml, Key) of - {ok, {string, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"String"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_date(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, date()} | - {error, get_error()}. -get_date(Toml, Key) -> - case get(Toml, Key) of - {ok, {date, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Date"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_time(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, time()} | - {error, get_error()}. -get_time(Toml, Key) -> - case get(Toml, Key) of - {ok, {time, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Time"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_date_time(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - date_time()} | - {error, get_error()}. -get_date_time(Toml, Key) -> - case get(Toml, Key) of - {ok, {date_time, I}} -> - {ok, I}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"DateTime"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_array(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - list(toml())} | - {error, get_error()}. -get_array(Toml, Key) -> - case get(Toml, Key) of - {ok, {array, I}} -> - {ok, I}; - - {ok, {array_of_tables, I@1}} -> - {ok, gleam@list:map(I@1, fun(Field@0) -> {table, Field@0} end)}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Array"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_table(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - gleam@map:map_(binary(), toml())} | - {error, get_error()}. -get_table(Toml, Key) -> - case get(Toml, Key) of - {ok, {table, I}} -> - {ok, I}; - - {ok, {inline_table, I@1}} -> - {ok, I@1}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Table"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec get_number(gleam@map:map_(binary(), toml()), list(binary())) -> {ok, - number_()} | - {error, get_error()}. -get_number(Toml, Key) -> - case get(Toml, Key) of - {ok, {int, X}} -> - {ok, {number_int, X}}; - - {ok, {float, X@1}} -> - {ok, {number_float, X@1}}; - - {ok, {nan, X@2}} -> - {ok, {number_nan, X@2}}; - - {ok, {infinity, X@3}} -> - {ok, {number_infinity, X@3}}; - - {ok, Other} -> - {error, {wrong_type, Key, <<"Number"/utf8>>, classify(Other)}}; - - {error, E} -> - {error, E} - end. - --spec merge(gleam@map:map_(binary(), toml()), binary(), toml(), toml()) -> {ok, - gleam@map:map_(binary(), toml())} | - {error, list(binary())}. -merge(Table, Key, Old, New) -> - case {Old, New} of - {{array_of_tables, Tables}, {array_of_tables, New@1}} -> - {ok, - gleam@map:insert( - Table, - Key, - {array_of_tables, gleam@list:append(New@1, Tables)} - )}; - - {_, _} -> - {error, [Key]} - end. - --spec insert_loop(gleam@map:map_(binary(), toml()), list(binary()), toml()) -> {ok, - gleam@map:map_(binary(), toml())} | - {error, list(binary())}. -insert_loop(Table, Key, Value) -> - case Key of - [] -> - erlang:error(#{gleam_error => panic, - message => <<"unreachable"/utf8>>, - module => <<"tom"/utf8>>, - function => <<"insert_loop"/utf8>>, - line => 511}); - - [K] -> - case gleam@map:get(Table, K) of - {error, nil} -> - {ok, gleam@map:insert(Table, K, Value)}; - - {ok, Old} -> - merge(Table, K, Old, Value) - end; - - [K@1 | Key@1] -> - case gleam@map:get(Table, K@1) of - {error, nil} -> - case insert_loop(gleam@map:new(), Key@1, Value) of - {ok, Inner} -> - {ok, gleam@map:insert(Table, K@1, {table, Inner})}; - - {error, Path} -> - {error, [K@1 | Path]} - end; - - {ok, {array_of_tables, [Inner@1 | Rest]}} -> - case insert_loop(Inner@1, Key@1, Value) of - {ok, Inner@2} -> - {ok, - gleam@map:insert( - Table, - K@1, - {array_of_tables, [Inner@2 | Rest]} - )}; - - {error, Path@1} -> - {error, [K@1 | Path@1]} - end; - - {ok, {table, Inner@3}} -> - case insert_loop(Inner@3, Key@1, Value) of - {ok, Inner@4} -> - {ok, gleam@map:insert(Table, K@1, {table, Inner@4})}; - - {error, Path@2} -> - {error, [K@1 | Path@2]} - end; - - {ok, _} -> - {error, [K@1]} - end - end. - --spec insert(gleam@map:map_(binary(), toml()), list(binary()), toml()) -> {ok, - gleam@map:map_(binary(), toml())} | - {error, parse_error()}. -insert(Table, Key, Value) -> - case insert_loop(Table, Key, Value) of - {ok, Table@1} -> - {ok, Table@1}; - - {error, Path} -> - {error, {key_already_in_use, Path}} - end. - --spec expect_end_of_line( - list(binary()), - fun((list(binary())) -> {ok, {FKZ, list(binary())}} | {error, parse_error()}) -) -> {ok, {FKZ, list(binary())}} | {error, parse_error()}. -expect_end_of_line(Input, Next) -> - case Input of - [<<"\n"/utf8>> | Input@1] -> - Next(Input@1); - - [<<"\r\n"/utf8>> | Input@2] -> - Next(Input@2); - - [G | _] -> - {error, {unexpected, G, <<"\n"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"\n"/utf8>>}} - end. - --spec parse_key_quoted(list(binary()), binary(), binary()) -> {ok, - {binary(), list(binary())}} | - {error, parse_error()}. -parse_key_quoted(Input, Close, Name) -> - case Input of - [G | Input@1] when G =:= Close -> - {ok, {Name, Input@1}}; - - [G@1 | Input@2] -> - parse_key_quoted(Input@2, Close, <<Name/binary, G@1/binary>>); - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, Close}} - end. - --spec parse_key_bare(list(binary()), binary()) -> {ok, - {binary(), list(binary())}} | - {error, parse_error()}. -parse_key_bare(Input, Name) -> - case Input of - [<<" "/utf8>> | Input@1] when Name =/= <<""/utf8>> -> - {ok, {Name, Input@1}}; - - [<<"="/utf8>> | _] when Name =/= <<""/utf8>> -> - {ok, {Name, Input}}; - - [<<"."/utf8>> | _] when Name =/= <<""/utf8>> -> - {ok, {Name, Input}}; - - [<<"]"/utf8>> | _] when Name =/= <<""/utf8>> -> - {ok, {Name, Input}}; - - [<<","/utf8>> | _] when Name =/= <<""/utf8>> -> - {error, {unexpected, <<","/utf8>>, <<"="/utf8>>}}; - - [<<"\n"/utf8>> | _] when Name =/= <<""/utf8>> -> - {error, {unexpected, <<"\n"/utf8>>, <<"="/utf8>>}}; - - [<<"\r\n"/utf8>> | _] when Name =/= <<""/utf8>> -> - {error, {unexpected, <<"\r\n"/utf8>>, <<"="/utf8>>}}; - - [<<"\n"/utf8>> | _] -> - {error, {unexpected, <<"\n"/utf8>>, <<"key"/utf8>>}}; - - [<<"\r\n"/utf8>> | _] -> - {error, {unexpected, <<"\r\n"/utf8>>, <<"key"/utf8>>}}; - - [<<"]"/utf8>> | _] -> - {error, {unexpected, <<"]"/utf8>>, <<"key"/utf8>>}}; - - [<<","/utf8>> | _] -> - {error, {unexpected, <<","/utf8>>, <<"key"/utf8>>}}; - - [G | Input@2] -> - parse_key_bare(Input@2, <<Name/binary, G/binary>>); - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"key"/utf8>>}} - end. - --spec skip_line_whitespace(list(binary())) -> list(binary()). -skip_line_whitespace(Input) -> - gleam@list:drop_while( - Input, - fun(G) -> (G =:= <<" "/utf8>>) orelse (G =:= <<"\t"/utf8>>) end - ). - --spec parse_key_segment(list(binary())) -> {ok, {binary(), list(binary())}} | - {error, parse_error()}. -parse_key_segment(Input) -> - Input@1 = skip_line_whitespace(Input), - case Input@1 of - [<<"="/utf8>> | _] -> - {error, {unexpected, <<"="/utf8>>, <<"Key"/utf8>>}}; - - [<<"\n"/utf8>> | _] -> - {error, {unexpected, <<"\n"/utf8>>, <<"Key"/utf8>>}}; - - [<<"\r\n"/utf8>> | _] -> - {error, {unexpected, <<"\r\n"/utf8>>, <<"Key"/utf8>>}}; - - [<<"["/utf8>> | _] -> - {error, {unexpected, <<"["/utf8>>, <<"Key"/utf8>>}}; - - [<<"\""/utf8>> | Input@2] -> - parse_key_quoted(Input@2, <<"\""/utf8>>, <<""/utf8>>); - - [<<"'"/utf8>> | Input@3] -> - parse_key_quoted(Input@3, <<"'"/utf8>>, <<""/utf8>>); - - _ -> - parse_key_bare(Input@1, <<""/utf8>>) - end. - --spec skip_whitespace(list(binary())) -> list(binary()). -skip_whitespace(Input) -> - case Input of - [<<" "/utf8>> | Input@1] -> - skip_whitespace(Input@1); - - [<<"\t"/utf8>> | Input@2] -> - skip_whitespace(Input@2); - - [<<"\n"/utf8>> | Input@3] -> - skip_whitespace(Input@3); - - [<<"\r\n"/utf8>> | Input@4] -> - skip_whitespace(Input@4); - - Input@5 -> - Input@5 - end. - --spec drop_comments(list(binary()), list(binary())) -> list(binary()). -drop_comments(Input, Acc) -> - case Input of - [<<"#"/utf8>> | Input@1] -> - _pipe = Input@1, - _pipe@1 = gleam@list:drop_while( - _pipe, - fun(G) -> G /= <<"\n"/utf8>> end - ), - drop_comments(_pipe@1, Acc); - - [G@1 | Input@2] -> - drop_comments(Input@2, [G@1 | Acc]); - - [] -> - gleam@list:reverse(Acc) - end. - --spec do( - {ok, {FLK, list(binary())}} | {error, parse_error()}, - fun((FLK, list(binary())) -> {ok, FLN} | {error, parse_error()}) -) -> {ok, FLN} | {error, parse_error()}. -do(Result, Next) -> - case Result of - {ok, {A, Input}} -> - Next(A, Input); - - {error, E} -> - {error, E} - end. - --spec parse_key(list(binary()), list(binary())) -> {ok, - {list(binary()), list(binary())}} | - {error, parse_error()}. -parse_key(Input, Segments) -> - do( - parse_key_segment(Input), - fun(Segment, Input@1) -> - Segments@1 = [Segment | Segments], - Input@2 = skip_line_whitespace(Input@1), - case Input@2 of - [<<"."/utf8>> | Input@3] -> - parse_key(Input@3, Segments@1); - - _ -> - {ok, {gleam@list:reverse(Segments@1), Input@2}} - end - end - ). - --spec expect( - list(binary()), - binary(), - fun((list(binary())) -> {ok, {FLS, list(binary())}} | {error, parse_error()}) -) -> {ok, {FLS, list(binary())}} | {error, parse_error()}. -expect(Input, Expected, Next) -> - case Input of - [G | Input@1] when G =:= Expected -> - Next(Input@1); - - [G@1 | _] -> - {error, {unexpected, G@1, Expected}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, Expected}} - end. - --spec parse_table_header(list(binary())) -> {ok, - {list(binary()), list(binary())}} | - {error, parse_error()}. -parse_table_header(Input) -> - Input@1 = skip_line_whitespace(Input), - do( - parse_key(Input@1, []), - fun(Key, Input@2) -> - expect( - Input@2, - <<"]"/utf8>>, - fun(Input@3) -> - Input@4 = skip_line_whitespace(Input@3), - expect_end_of_line( - Input@4, - fun(Input@5) -> {ok, {Key, Input@5}} end - ) - end - ) - end - ). - --spec parse_hex(list(binary()), integer(), sign()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_hex(Input, Number, Sign) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_hex(Input@1, Number, Sign); - - [<<"0"/utf8>> | Input@2] -> - parse_hex(Input@2, (Number * 16) + 0, Sign); - - [<<"1"/utf8>> | Input@3] -> - parse_hex(Input@3, (Number * 16) + 1, Sign); - - [<<"2"/utf8>> | Input@4] -> - parse_hex(Input@4, (Number * 16) + 2, Sign); - - [<<"3"/utf8>> | Input@5] -> - parse_hex(Input@5, (Number * 16) + 3, Sign); - - [<<"4"/utf8>> | Input@6] -> - parse_hex(Input@6, (Number * 16) + 4, Sign); - - [<<"5"/utf8>> | Input@7] -> - parse_hex(Input@7, (Number * 16) + 5, Sign); - - [<<"6"/utf8>> | Input@8] -> - parse_hex(Input@8, (Number * 16) + 6, Sign); - - [<<"7"/utf8>> | Input@9] -> - parse_hex(Input@9, (Number * 16) + 7, Sign); - - [<<"8"/utf8>> | Input@10] -> - parse_hex(Input@10, (Number * 16) + 8, Sign); - - [<<"9"/utf8>> | Input@11] -> - parse_hex(Input@11, (Number * 16) + 9, Sign); - - [<<"a"/utf8>> | Input@12] -> - parse_hex(Input@12, (Number * 16) + 10, Sign); - - [<<"b"/utf8>> | Input@13] -> - parse_hex(Input@13, (Number * 16) + 11, Sign); - - [<<"c"/utf8>> | Input@14] -> - parse_hex(Input@14, (Number * 16) + 12, Sign); - - [<<"d"/utf8>> | Input@15] -> - parse_hex(Input@15, (Number * 16) + 13, Sign); - - [<<"e"/utf8>> | Input@16] -> - parse_hex(Input@16, (Number * 16) + 14, Sign); - - [<<"f"/utf8>> | Input@17] -> - parse_hex(Input@17, (Number * 16) + 15, Sign); - - [<<"A"/utf8>> | Input@18] -> - parse_hex(Input@18, (Number * 16) + 10, Sign); - - [<<"B"/utf8>> | Input@19] -> - parse_hex(Input@19, (Number * 16) + 11, Sign); - - [<<"C"/utf8>> | Input@20] -> - parse_hex(Input@20, (Number * 16) + 12, Sign); - - [<<"D"/utf8>> | Input@21] -> - parse_hex(Input@21, (Number * 16) + 13, Sign); - - [<<"E"/utf8>> | Input@22] -> - parse_hex(Input@22, (Number * 16) + 14, Sign); - - [<<"F"/utf8>> | Input@23] -> - parse_hex(Input@23, (Number * 16) + 15, Sign); - - Input@24 -> - Number@1 = case Sign of - positive -> - Number; - - negative -> - - Number - end, - {ok, {{int, Number@1}, Input@24}} - end. - --spec parse_octal(list(binary()), integer(), sign()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_octal(Input, Number, Sign) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_octal(Input@1, Number, Sign); - - [<<"0"/utf8>> | Input@2] -> - parse_octal(Input@2, (Number * 8) + 0, Sign); - - [<<"1"/utf8>> | Input@3] -> - parse_octal(Input@3, (Number * 8) + 1, Sign); - - [<<"2"/utf8>> | Input@4] -> - parse_octal(Input@4, (Number * 8) + 2, Sign); - - [<<"3"/utf8>> | Input@5] -> - parse_octal(Input@5, (Number * 8) + 3, Sign); - - [<<"4"/utf8>> | Input@6] -> - parse_octal(Input@6, (Number * 8) + 4, Sign); - - [<<"5"/utf8>> | Input@7] -> - parse_octal(Input@7, (Number * 8) + 5, Sign); - - [<<"6"/utf8>> | Input@8] -> - parse_octal(Input@8, (Number * 8) + 6, Sign); - - [<<"7"/utf8>> | Input@9] -> - parse_octal(Input@9, (Number * 8) + 7, Sign); - - Input@10 -> - Number@1 = case Sign of - positive -> - Number; - - negative -> - - Number - end, - {ok, {{int, Number@1}, Input@10}} - end. - --spec parse_binary(list(binary()), integer(), sign()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_binary(Input, Number, Sign) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_binary(Input@1, Number, Sign); - - [<<"0"/utf8>> | Input@2] -> - parse_binary(Input@2, (Number * 2) + 0, Sign); - - [<<"1"/utf8>> | Input@3] -> - parse_binary(Input@3, (Number * 2) + 1, Sign); - - Input@4 -> - Number@1 = case Sign of - positive -> - Number; - - negative -> - - Number - end, - {ok, {{int, Number@1}, Input@4}} - end. - --spec parse_exponent(list(binary()), float(), sign(), integer(), sign()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_exponent(Input, N, N_sign, Ex, Ex_sign) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_exponent(Input@1, N, N_sign, Ex, Ex_sign); - - [<<"0"/utf8>> | Input@2] -> - parse_exponent(Input@2, N, N_sign, Ex * 10, Ex_sign); - - [<<"1"/utf8>> | Input@3] -> - parse_exponent(Input@3, N, N_sign, (Ex * 10) + 1, Ex_sign); - - [<<"2"/utf8>> | Input@4] -> - parse_exponent(Input@4, N, N_sign, (Ex * 10) + 2, Ex_sign); - - [<<"3"/utf8>> | Input@5] -> - parse_exponent(Input@5, N, N_sign, (Ex * 10) + 3, Ex_sign); - - [<<"4"/utf8>> | Input@6] -> - parse_exponent(Input@6, N, N_sign, (Ex * 10) + 4, Ex_sign); - - [<<"5"/utf8>> | Input@7] -> - parse_exponent(Input@7, N, N_sign, (Ex * 10) + 5, Ex_sign); - - [<<"6"/utf8>> | Input@8] -> - parse_exponent(Input@8, N, N_sign, (Ex * 10) + 6, Ex_sign); - - [<<"7"/utf8>> | Input@9] -> - parse_exponent(Input@9, N, N_sign, (Ex * 10) + 7, Ex_sign); - - [<<"8"/utf8>> | Input@10] -> - parse_exponent(Input@10, N, N_sign, (Ex * 10) + 8, Ex_sign); - - [<<"9"/utf8>> | Input@11] -> - parse_exponent(Input@11, N, N_sign, (Ex * 10) + 9, Ex_sign); - - Input@12 -> - Number = case N_sign of - positive -> - N; - - negative -> - N * -1.0 - end, - Exponent = gleam@int:to_float(case Ex_sign of - positive -> - Ex; - - negative -> - - Ex - end), - Multiplier@1 = case gleam@float:power(10.0, Exponent) of - {ok, Multiplier} -> - Multiplier; - - {error, _} -> - 1.0 - end, - {ok, {{float, Number * Multiplier@1}, Input@12}} - end. - --spec parse_float(list(binary()), float(), sign(), float()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_float(Input, Number, Sign, Unit) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_float(Input@1, Number, Sign, Unit); - - [<<"0"/utf8>> | Input@2] -> - parse_float(Input@2, Number, Sign, Unit * 0.1); - - [<<"1"/utf8>> | Input@3] -> - parse_float(Input@3, Number + (1.0 * Unit), Sign, Unit * 0.1); - - [<<"2"/utf8>> | Input@4] -> - parse_float(Input@4, Number + (2.0 * Unit), Sign, Unit * 0.1); - - [<<"3"/utf8>> | Input@5] -> - parse_float(Input@5, Number + (3.0 * Unit), Sign, Unit * 0.1); - - [<<"4"/utf8>> | Input@6] -> - parse_float(Input@6, Number + (4.0 * Unit), Sign, Unit * 0.1); - - [<<"5"/utf8>> | Input@7] -> - parse_float(Input@7, Number + (5.0 * Unit), Sign, Unit * 0.1); - - [<<"6"/utf8>> | Input@8] -> - parse_float(Input@8, Number + (6.0 * Unit), Sign, Unit * 0.1); - - [<<"7"/utf8>> | Input@9] -> - parse_float(Input@9, Number + (7.0 * Unit), Sign, Unit * 0.1); - - [<<"8"/utf8>> | Input@10] -> - parse_float(Input@10, Number + (8.0 * Unit), Sign, Unit * 0.1); - - [<<"9"/utf8>> | Input@11] -> - parse_float(Input@11, Number + (9.0 * Unit), Sign, Unit * 0.1); - - [<<"e"/utf8>>, <<"+"/utf8>> | Input@12] -> - parse_exponent(Input@12, Number, Sign, 0, positive); - - [<<"e"/utf8>>, <<"-"/utf8>> | Input@13] -> - parse_exponent(Input@13, Number, Sign, 0, negative); - - [<<"e"/utf8>> | Input@14] -> - parse_exponent(Input@14, Number, Sign, 0, positive); - - [<<"E"/utf8>>, <<"+"/utf8>> | Input@15] -> - parse_exponent(Input@15, Number, Sign, 0, positive); - - [<<"E"/utf8>>, <<"-"/utf8>> | Input@16] -> - parse_exponent(Input@16, Number, Sign, 0, negative); - - [<<"E"/utf8>> | Input@17] -> - parse_exponent(Input@17, Number, Sign, 0, positive); - - Input@18 -> - Number@1 = case Sign of - positive -> - Number; - - negative -> - Number * -1.0 - end, - {ok, {{float, Number@1}, Input@18}} - end. - --spec parse_string(list(binary()), binary()) -> {ok, {toml(), list(binary())}} | - {error, parse_error()}. -parse_string(Input, String) -> - case Input of - [<<"\""/utf8>> | Input@1] -> - {ok, {{string, String}, Input@1}}; - - [<<"\\"/utf8>>, <<"t"/utf8>> | Input@2] -> - parse_string(Input@2, <<String/binary, "\t"/utf8>>); - - [<<"\\"/utf8>>, <<"n"/utf8>> | Input@3] -> - parse_string(Input@3, <<String/binary, "\n"/utf8>>); - - [<<"\\"/utf8>>, <<"r"/utf8>> | Input@4] -> - parse_string(Input@4, <<String/binary, "\r"/utf8>>); - - [<<"\\"/utf8>>, <<"\""/utf8>> | Input@5] -> - parse_string(Input@5, <<String/binary, "\""/utf8>>); - - [<<"\\"/utf8>>, <<"\\"/utf8>> | Input@6] -> - parse_string(Input@6, <<String/binary, "\\"/utf8>>); - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}}; - - [<<"\n"/utf8>> | _] -> - {error, {unexpected, <<"\n"/utf8>>, <<"\""/utf8>>}}; - - [<<"\r\n"/utf8>> | _] -> - {error, {unexpected, <<"\r\n"/utf8>>, <<"\""/utf8>>}}; - - [G | Input@7] -> - parse_string(Input@7, <<String/binary, G/binary>>) - end. - --spec parse_multi_line_string(list(binary()), binary()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_multi_line_string(Input, String) -> - case Input of - [<<"\""/utf8>>, <<"\""/utf8>>, <<"\""/utf8>> | Input@1] -> - {ok, {{string, String}, Input@1}}; - - [<<"\\"/utf8>>, <<"\n"/utf8>> | Input@2] -> - parse_multi_line_string(skip_whitespace(Input@2), String); - - [<<"\\"/utf8>>, <<"\r\n"/utf8>> | Input@3] -> - parse_multi_line_string(skip_whitespace(Input@3), String); - - [<<"\r\n"/utf8>> | Input@4] when String =:= <<""/utf8>> -> - parse_multi_line_string(Input@4, String); - - [<<"\n"/utf8>> | Input@5] when String =:= <<""/utf8>> -> - parse_multi_line_string(Input@5, String); - - [<<"\r\n"/utf8>> | Input@6] when String =:= <<""/utf8>> -> - parse_multi_line_string(Input@6, String); - - [<<"\\"/utf8>>, <<"t"/utf8>> | Input@7] -> - parse_multi_line_string(Input@7, <<String/binary, "\t"/utf8>>); - - [<<"\\"/utf8>>, <<"n"/utf8>> | Input@8] -> - parse_multi_line_string(Input@8, <<String/binary, "\n"/utf8>>); - - [<<"\\"/utf8>>, <<"r"/utf8>> | Input@9] -> - parse_multi_line_string(Input@9, <<String/binary, "\r"/utf8>>); - - [<<"\\"/utf8>>, <<"\""/utf8>> | Input@10] -> - parse_multi_line_string(Input@10, <<String/binary, "\""/utf8>>); - - [<<"\\"/utf8>>, <<"\\"/utf8>> | Input@11] -> - parse_multi_line_string(Input@11, <<String/binary, "\\"/utf8>>); - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}}; - - [G | Input@12] -> - parse_multi_line_string(Input@12, <<String/binary, G/binary>>) - end. - --spec parse_multi_line_literal_string(list(binary()), binary()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_multi_line_literal_string(Input, String) -> - case Input of - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}}; - - [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | _] -> - {error, {unexpected, <<"''''"/utf8>>, <<"'''"/utf8>>}}; - - [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | Input@1] -> - {ok, {{string, String}, Input@1}}; - - [<<"\n"/utf8>> | Input@2] when String =:= <<""/utf8>> -> - parse_multi_line_literal_string(Input@2, String); - - [<<"\r\n"/utf8>> | Input@3] when String =:= <<""/utf8>> -> - parse_multi_line_literal_string(Input@3, String); - - [G | Input@4] -> - parse_multi_line_literal_string( - Input@4, - <<String/binary, G/binary>> - ) - end. - --spec parse_literal_string(list(binary()), binary()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_literal_string(Input, String) -> - case Input of - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"\""/utf8>>}}; - - [<<"\n"/utf8>> | _] -> - {error, {unexpected, <<"\n"/utf8>>, <<"'"/utf8>>}}; - - [<<"\r\n"/utf8>> | _] -> - {error, {unexpected, <<"\r\n"/utf8>>, <<"'"/utf8>>}}; - - [<<"'"/utf8>> | Input@1] -> - {ok, {{string, String}, Input@1}}; - - [G | Input@2] -> - parse_literal_string(Input@2, <<String/binary, G/binary>>) - end. - --spec parse_time_ms(list(binary()), integer(), integer()) -> {ok, - {{integer(), integer()}, list(binary())}} | - {error, parse_error()}. -parse_time_ms(Input, Seconds, Ms) -> - case Input of - [<<"0"/utf8>> | Input@1] when Ms < 100000 -> - parse_time_ms(Input@1, Seconds, (Ms * 10) + 0); - - [<<"1"/utf8>> | Input@2] when Ms < 100000 -> - parse_time_ms(Input@2, Seconds, (Ms * 10) + 1); - - [<<"2"/utf8>> | Input@3] when Ms < 100000 -> - parse_time_ms(Input@3, Seconds, (Ms * 10) + 2); - - [<<"3"/utf8>> | Input@4] when Ms < 100000 -> - parse_time_ms(Input@4, Seconds, (Ms * 10) + 3); - - [<<"4"/utf8>> | Input@5] when Ms < 100000 -> - parse_time_ms(Input@5, Seconds, (Ms * 10) + 4); - - [<<"5"/utf8>> | Input@6] when Ms < 100000 -> - parse_time_ms(Input@6, Seconds, (Ms * 10) + 5); - - [<<"6"/utf8>> | Input@7] when Ms < 100000 -> - parse_time_ms(Input@7, Seconds, (Ms * 10) + 6); - - [<<"7"/utf8>> | Input@8] when Ms < 100000 -> - parse_time_ms(Input@8, Seconds, (Ms * 10) + 7); - - [<<"8"/utf8>> | Input@9] when Ms < 100000 -> - parse_time_ms(Input@9, Seconds, (Ms * 10) + 8); - - [<<"9"/utf8>> | Input@10] when Ms < 100000 -> - parse_time_ms(Input@10, Seconds, (Ms * 10) + 9); - - _ -> - {ok, {{Seconds, Ms}, Input}} - end. - --spec parse_number_under_60(list(binary()), binary()) -> {ok, - {integer(), list(binary())}} | - {error, parse_error()}. -parse_number_under_60(Input, Expected) -> - case Input of - [<<"0"/utf8>>, <<"0"/utf8>> | Input@1] -> - {ok, {0, Input@1}}; - - [<<"0"/utf8>>, <<"1"/utf8>> | Input@2] -> - {ok, {1, Input@2}}; - - [<<"0"/utf8>>, <<"2"/utf8>> | Input@3] -> - {ok, {2, Input@3}}; - - [<<"0"/utf8>>, <<"3"/utf8>> | Input@4] -> - {ok, {3, Input@4}}; - - [<<"0"/utf8>>, <<"4"/utf8>> | Input@5] -> - {ok, {4, Input@5}}; - - [<<"0"/utf8>>, <<"5"/utf8>> | Input@6] -> - {ok, {5, Input@6}}; - - [<<"0"/utf8>>, <<"6"/utf8>> | Input@7] -> - {ok, {6, Input@7}}; - - [<<"0"/utf8>>, <<"7"/utf8>> | Input@8] -> - {ok, {7, Input@8}}; - - [<<"0"/utf8>>, <<"8"/utf8>> | Input@9] -> - {ok, {8, Input@9}}; - - [<<"0"/utf8>>, <<"9"/utf8>> | Input@10] -> - {ok, {9, Input@10}}; - - [<<"1"/utf8>>, <<"0"/utf8>> | Input@11] -> - {ok, {10, Input@11}}; - - [<<"1"/utf8>>, <<"1"/utf8>> | Input@12] -> - {ok, {11, Input@12}}; - - [<<"1"/utf8>>, <<"2"/utf8>> | Input@13] -> - {ok, {12, Input@13}}; - - [<<"1"/utf8>>, <<"3"/utf8>> | Input@14] -> - {ok, {13, Input@14}}; - - [<<"1"/utf8>>, <<"4"/utf8>> | Input@15] -> - {ok, {14, Input@15}}; - - [<<"1"/utf8>>, <<"5"/utf8>> | Input@16] -> - {ok, {15, Input@16}}; - - [<<"1"/utf8>>, <<"6"/utf8>> | Input@17] -> - {ok, {16, Input@17}}; - - [<<"1"/utf8>>, <<"7"/utf8>> | Input@18] -> - {ok, {17, Input@18}}; - - [<<"1"/utf8>>, <<"8"/utf8>> | Input@19] -> - {ok, {18, Input@19}}; - - [<<"1"/utf8>>, <<"9"/utf8>> | Input@20] -> - {ok, {19, Input@20}}; - - [<<"2"/utf8>>, <<"0"/utf8>> | Input@21] -> - {ok, {20, Input@21}}; - - [<<"2"/utf8>>, <<"1"/utf8>> | Input@22] -> - {ok, {21, Input@22}}; - - [<<"2"/utf8>>, <<"2"/utf8>> | Input@23] -> - {ok, {22, Input@23}}; - - [<<"2"/utf8>>, <<"3"/utf8>> | Input@24] -> - {ok, {23, Input@24}}; - - [<<"2"/utf8>>, <<"4"/utf8>> | Input@25] -> - {ok, {24, Input@25}}; - - [<<"2"/utf8>>, <<"5"/utf8>> | Input@26] -> - {ok, {25, Input@26}}; - - [<<"2"/utf8>>, <<"6"/utf8>> | Input@27] -> - {ok, {26, Input@27}}; - - [<<"2"/utf8>>, <<"7"/utf8>> | Input@28] -> - {ok, {27, Input@28}}; - - [<<"2"/utf8>>, <<"8"/utf8>> | Input@29] -> - {ok, {28, Input@29}}; - - [<<"2"/utf8>>, <<"9"/utf8>> | Input@30] -> - {ok, {29, Input@30}}; - - [<<"3"/utf8>>, <<"0"/utf8>> | Input@31] -> - {ok, {30, Input@31}}; - - [<<"3"/utf8>>, <<"1"/utf8>> | Input@32] -> - {ok, {31, Input@32}}; - - [<<"3"/utf8>>, <<"2"/utf8>> | Input@33] -> - {ok, {32, Input@33}}; - - [<<"3"/utf8>>, <<"3"/utf8>> | Input@34] -> - {ok, {33, Input@34}}; - - [<<"3"/utf8>>, <<"4"/utf8>> | Input@35] -> - {ok, {34, Input@35}}; - - [<<"3"/utf8>>, <<"5"/utf8>> | Input@36] -> - {ok, {35, Input@36}}; - - [<<"3"/utf8>>, <<"6"/utf8>> | Input@37] -> - {ok, {36, Input@37}}; - - [<<"3"/utf8>>, <<"7"/utf8>> | Input@38] -> - {ok, {37, Input@38}}; - - [<<"3"/utf8>>, <<"8"/utf8>> | Input@39] -> - {ok, {38, Input@39}}; - - [<<"3"/utf8>>, <<"9"/utf8>> | Input@40] -> - {ok, {39, Input@40}}; - - [<<"4"/utf8>>, <<"0"/utf8>> | Input@41] -> - {ok, {40, Input@41}}; - - [<<"4"/utf8>>, <<"1"/utf8>> | Input@42] -> - {ok, {41, Input@42}}; - - [<<"4"/utf8>>, <<"2"/utf8>> | Input@43] -> - {ok, {42, Input@43}}; - - [<<"4"/utf8>>, <<"3"/utf8>> | Input@44] -> - {ok, {43, Input@44}}; - - [<<"4"/utf8>>, <<"4"/utf8>> | Input@45] -> - {ok, {44, Input@45}}; - - [<<"4"/utf8>>, <<"5"/utf8>> | Input@46] -> - {ok, {45, Input@46}}; - - [<<"4"/utf8>>, <<"6"/utf8>> | Input@47] -> - {ok, {46, Input@47}}; - - [<<"4"/utf8>>, <<"7"/utf8>> | Input@48] -> - {ok, {47, Input@48}}; - - [<<"4"/utf8>>, <<"8"/utf8>> | Input@49] -> - {ok, {48, Input@49}}; - - [<<"4"/utf8>>, <<"9"/utf8>> | Input@50] -> - {ok, {49, Input@50}}; - - [<<"5"/utf8>>, <<"0"/utf8>> | Input@51] -> - {ok, {50, Input@51}}; - - [<<"5"/utf8>>, <<"1"/utf8>> | Input@52] -> - {ok, {51, Input@52}}; - - [<<"5"/utf8>>, <<"2"/utf8>> | Input@53] -> - {ok, {52, Input@53}}; - - [<<"5"/utf8>>, <<"3"/utf8>> | Input@54] -> - {ok, {53, Input@54}}; - - [<<"5"/utf8>>, <<"4"/utf8>> | Input@55] -> - {ok, {54, Input@55}}; - - [<<"5"/utf8>>, <<"5"/utf8>> | Input@56] -> - {ok, {55, Input@56}}; - - [<<"5"/utf8>>, <<"6"/utf8>> | Input@57] -> - {ok, {56, Input@57}}; - - [<<"5"/utf8>>, <<"7"/utf8>> | Input@58] -> - {ok, {57, Input@58}}; - - [<<"5"/utf8>>, <<"8"/utf8>> | Input@59] -> - {ok, {58, Input@59}}; - - [<<"5"/utf8>>, <<"9"/utf8>> | Input@60] -> - {ok, {59, Input@60}}; - - [G | _] -> - {error, {unexpected, G, Expected}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, Expected}} - end. - --spec parse_hour_minute(list(binary())) -> {ok, - {{integer(), integer()}, list(binary())}} | - {error, parse_error()}. -parse_hour_minute(Input) -> - do(case Input of - [<<"0"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@1] -> - {ok, {0, Input@1}}; - - [<<"0"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@2] -> - {ok, {1, Input@2}}; - - [<<"0"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@3] -> - {ok, {2, Input@3}}; - - [<<"0"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@4] -> - {ok, {3, Input@4}}; - - [<<"0"/utf8>>, <<"4"/utf8>>, <<":"/utf8>> | Input@5] -> - {ok, {4, Input@5}}; - - [<<"0"/utf8>>, <<"5"/utf8>>, <<":"/utf8>> | Input@6] -> - {ok, {5, Input@6}}; - - [<<"0"/utf8>>, <<"6"/utf8>>, <<":"/utf8>> | Input@7] -> - {ok, {6, Input@7}}; - - [<<"0"/utf8>>, <<"7"/utf8>>, <<":"/utf8>> | Input@8] -> - {ok, {7, Input@8}}; - - [<<"0"/utf8>>, <<"8"/utf8>>, <<":"/utf8>> | Input@9] -> - {ok, {8, Input@9}}; - - [<<"0"/utf8>>, <<"9"/utf8>>, <<":"/utf8>> | Input@10] -> - {ok, {9, Input@10}}; - - [<<"1"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@11] -> - {ok, {10, Input@11}}; - - [<<"1"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@12] -> - {ok, {11, Input@12}}; - - [<<"1"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@13] -> - {ok, {12, Input@13}}; - - [<<"1"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@14] -> - {ok, {13, Input@14}}; - - [<<"1"/utf8>>, <<"4"/utf8>>, <<":"/utf8>> | Input@15] -> - {ok, {14, Input@15}}; - - [<<"1"/utf8>>, <<"5"/utf8>>, <<":"/utf8>> | Input@16] -> - {ok, {15, Input@16}}; - - [<<"1"/utf8>>, <<"6"/utf8>>, <<":"/utf8>> | Input@17] -> - {ok, {16, Input@17}}; - - [<<"1"/utf8>>, <<"7"/utf8>>, <<":"/utf8>> | Input@18] -> - {ok, {17, Input@18}}; - - [<<"1"/utf8>>, <<"8"/utf8>>, <<":"/utf8>> | Input@19] -> - {ok, {18, Input@19}}; - - [<<"1"/utf8>>, <<"9"/utf8>>, <<":"/utf8>> | Input@20] -> - {ok, {19, Input@20}}; - - [<<"2"/utf8>>, <<"0"/utf8>>, <<":"/utf8>> | Input@21] -> - {ok, {20, Input@21}}; - - [<<"2"/utf8>>, <<"1"/utf8>>, <<":"/utf8>> | Input@22] -> - {ok, {21, Input@22}}; - - [<<"2"/utf8>>, <<"2"/utf8>>, <<":"/utf8>> | Input@23] -> - {ok, {22, Input@23}}; - - [<<"2"/utf8>>, <<"3"/utf8>>, <<":"/utf8>> | Input@24] -> - {ok, {23, Input@24}}; - - [G | _] -> - {error, {unexpected, G, <<"time"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"time"/utf8>>}} - end, fun(Hours, Input@25) -> - do( - parse_number_under_60(Input@25, <<"minutes"/utf8>>), - fun(Minutes, Input@26) -> {ok, {{Hours, Minutes}, Input@26}} end - ) - end). - --spec parse_time_s_ms(list(binary())) -> {ok, - {{integer(), integer()}, list(binary())}} | - {error, parse_error()}. -parse_time_s_ms(Input) -> - case Input of - [<<":"/utf8>> | Input@1] -> - do( - parse_number_under_60(Input@1, <<"seconds"/utf8>>), - fun(Seconds, Input@2) -> case Input@2 of - [<<"."/utf8>> | Input@3] -> - parse_time_ms(Input@3, Seconds, 0); - - _ -> - {ok, {{Seconds, 0}, Input@2}} - end end - ); - - _ -> - {ok, {{0, 0}, Input}} - end. - --spec parse_time_minute(list(binary()), integer()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_time_minute(Input, Hours) -> - do( - parse_number_under_60(Input, <<"minutes"/utf8>>), - fun(Minutes, Input@1) -> - do( - parse_time_s_ms(Input@1), - fun(_use0, Input@2) -> - {Seconds, Ms} = _use0, - Time = {time_value, Hours, Minutes, Seconds, Ms}, - {ok, {{time, Time}, Input@2}} - end - ) - end - ). - --spec parse_time_value(list(binary())) -> {ok, {time(), list(binary())}} | - {error, parse_error()}. -parse_time_value(Input) -> - do( - parse_hour_minute(Input), - fun(_use0, Input@1) -> - {Hours, Minutes} = _use0, - do( - parse_time_s_ms(Input@1), - fun(_use0@1, Input@2) -> - {Seconds, Ms} = _use0@1, - Time = {time_value, Hours, Minutes, Seconds, Ms}, - {ok, {Time, Input@2}} - end - ) - end - ). - --spec parse_offset_hours(list(binary()), sign()) -> {ok, - {offset(), list(binary())}} | - {error, parse_error()}. -parse_offset_hours(Input, Sign) -> - do( - parse_hour_minute(Input), - fun(_use0, Input@1) -> - {Hours, Minutes} = _use0, - {ok, {{offset, Sign, Hours, Minutes}, Input@1}} - end - ). - --spec parse_offset(list(binary())) -> {ok, {offset(), list(binary())}} | - {error, parse_error()}. -parse_offset(Input) -> - case Input of - [<<"Z"/utf8>> | Input@1] -> - {ok, {{offset, positive, 0, 0}, Input@1}}; - - [<<"+"/utf8>> | Input@2] -> - parse_offset_hours(Input@2, positive); - - [<<"-"/utf8>> | Input@3] -> - parse_offset_hours(Input@3, negative); - - _ -> - {ok, {local, Input}} - end. - --spec parse_date_end(list(binary()), integer(), integer(), integer()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_date_end(Input, Year, Month, Day) -> - Date = {date_value, Year, Month, Day}, - case Input of - [<<" "/utf8>> | Input@1] -> - do( - parse_time_value(Input@1), - fun(Time, Input@2) -> - do( - parse_offset(Input@2), - fun(Offset, Input@3) -> - {ok, - {{date_time, - {date_time_value, Date, Time, Offset}}, - Input@3}} - end - ) - end - ); - - [<<"T"/utf8>> | Input@1] -> - do( - parse_time_value(Input@1), - fun(Time, Input@2) -> - do( - parse_offset(Input@2), - fun(Offset, Input@3) -> - {ok, - {{date_time, - {date_time_value, Date, Time, Offset}}, - Input@3}} - end - ) - end - ); - - _ -> - {ok, {{date, Date}, Input}} - end. - --spec parse_date_day(list(binary()), integer(), integer()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_date_day(Input, Year, Month) -> - case Input of - [<<"0"/utf8>>, <<"1"/utf8>> | Input@1] -> - parse_date_end(Input@1, Year, Month, 1); - - [<<"0"/utf8>>, <<"2"/utf8>> | Input@2] -> - parse_date_end(Input@2, Year, Month, 2); - - [<<"0"/utf8>>, <<"3"/utf8>> | Input@3] -> - parse_date_end(Input@3, Year, Month, 3); - - [<<"0"/utf8>>, <<"4"/utf8>> | Input@4] -> - parse_date_end(Input@4, Year, Month, 4); - - [<<"0"/utf8>>, <<"5"/utf8>> | Input@5] -> - parse_date_end(Input@5, Year, Month, 5); - - [<<"0"/utf8>>, <<"6"/utf8>> | Input@6] -> - parse_date_end(Input@6, Year, Month, 6); - - [<<"0"/utf8>>, <<"7"/utf8>> | Input@7] -> - parse_date_end(Input@7, Year, Month, 7); - - [<<"0"/utf8>>, <<"8"/utf8>> | Input@8] -> - parse_date_end(Input@8, Year, Month, 8); - - [<<"0"/utf8>>, <<"9"/utf8>> | Input@9] -> - parse_date_end(Input@9, Year, Month, 9); - - [<<"1"/utf8>>, <<"0"/utf8>> | Input@10] -> - parse_date_end(Input@10, Year, Month, 10); - - [<<"1"/utf8>>, <<"1"/utf8>> | Input@11] -> - parse_date_end(Input@11, Year, Month, 11); - - [<<"1"/utf8>>, <<"2"/utf8>> | Input@12] -> - parse_date_end(Input@12, Year, Month, 12); - - [<<"1"/utf8>>, <<"3"/utf8>> | Input@13] -> - parse_date_end(Input@13, Year, Month, 13); - - [<<"1"/utf8>>, <<"4"/utf8>> | Input@14] -> - parse_date_end(Input@14, Year, Month, 14); - - [<<"1"/utf8>>, <<"5"/utf8>> | Input@15] -> - parse_date_end(Input@15, Year, Month, 15); - - [<<"1"/utf8>>, <<"6"/utf8>> | Input@16] -> - parse_date_end(Input@16, Year, Month, 16); - - [<<"1"/utf8>>, <<"7"/utf8>> | Input@17] -> - parse_date_end(Input@17, Year, Month, 17); - - [<<"1"/utf8>>, <<"8"/utf8>> | Input@18] -> - parse_date_end(Input@18, Year, Month, 18); - - [<<"1"/utf8>>, <<"9"/utf8>> | Input@19] -> - parse_date_end(Input@19, Year, Month, 19); - - [<<"2"/utf8>>, <<"0"/utf8>> | Input@20] -> - parse_date_end(Input@20, Year, Month, 20); - - [<<"2"/utf8>>, <<"1"/utf8>> | Input@21] -> - parse_date_end(Input@21, Year, Month, 21); - - [<<"2"/utf8>>, <<"2"/utf8>> | Input@22] -> - parse_date_end(Input@22, Year, Month, 22); - - [<<"2"/utf8>>, <<"3"/utf8>> | Input@23] -> - parse_date_end(Input@23, Year, Month, 23); - - [<<"2"/utf8>>, <<"4"/utf8>> | Input@24] -> - parse_date_end(Input@24, Year, Month, 24); - - [<<"2"/utf8>>, <<"5"/utf8>> | Input@25] -> - parse_date_end(Input@25, Year, Month, 25); - - [<<"2"/utf8>>, <<"6"/utf8>> | Input@26] -> - parse_date_end(Input@26, Year, Month, 26); - - [<<"2"/utf8>>, <<"7"/utf8>> | Input@27] -> - parse_date_end(Input@27, Year, Month, 27); - - [<<"2"/utf8>>, <<"8"/utf8>> | Input@28] -> - parse_date_end(Input@28, Year, Month, 28); - - [<<"2"/utf8>>, <<"9"/utf8>> | Input@29] -> - parse_date_end(Input@29, Year, Month, 29); - - [<<"3"/utf8>>, <<"0"/utf8>> | Input@30] -> - parse_date_end(Input@30, Year, Month, 30); - - [<<"3"/utf8>>, <<"1"/utf8>> | Input@31] -> - parse_date_end(Input@31, Year, Month, 31); - - [G | _] -> - {error, {unexpected, G, <<"date day"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"date day"/utf8>>}} - end. - --spec parse_date(list(binary()), integer()) -> {ok, {toml(), list(binary())}} | - {error, parse_error()}. -parse_date(Input, Year) -> - case Input of - [<<"0"/utf8>>, <<"1"/utf8>>, <<"-"/utf8>> | Input@1] -> - parse_date_day(Input@1, Year, 1); - - [<<"0"/utf8>>, <<"2"/utf8>>, <<"-"/utf8>> | Input@2] -> - parse_date_day(Input@2, Year, 2); - - [<<"0"/utf8>>, <<"3"/utf8>>, <<"-"/utf8>> | Input@3] -> - parse_date_day(Input@3, Year, 3); - - [<<"0"/utf8>>, <<"4"/utf8>>, <<"-"/utf8>> | Input@4] -> - parse_date_day(Input@4, Year, 4); - - [<<"0"/utf8>>, <<"5"/utf8>>, <<"-"/utf8>> | Input@5] -> - parse_date_day(Input@5, Year, 5); - - [<<"0"/utf8>>, <<"6"/utf8>>, <<"-"/utf8>> | Input@6] -> - parse_date_day(Input@6, Year, 6); - - [<<"0"/utf8>>, <<"7"/utf8>>, <<"-"/utf8>> | Input@7] -> - parse_date_day(Input@7, Year, 7); - - [<<"0"/utf8>>, <<"8"/utf8>>, <<"-"/utf8>> | Input@8] -> - parse_date_day(Input@8, Year, 8); - - [<<"0"/utf8>>, <<"9"/utf8>>, <<"-"/utf8>> | Input@9] -> - parse_date_day(Input@9, Year, 9); - - [<<"1"/utf8>>, <<"0"/utf8>>, <<"-"/utf8>> | Input@10] -> - parse_date_day(Input@10, Year, 10); - - [<<"1"/utf8>>, <<"1"/utf8>>, <<"-"/utf8>> | Input@11] -> - parse_date_day(Input@11, Year, 11); - - [<<"1"/utf8>>, <<"2"/utf8>>, <<"-"/utf8>> | Input@12] -> - parse_date_day(Input@12, Year, 12); - - [G | _] -> - {error, {unexpected, G, <<"date month"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"date month"/utf8>>}} - end. - --spec parse_number(list(binary()), integer(), sign()) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_number(Input, Number, Sign) -> - case Input of - [<<"_"/utf8>> | Input@1] -> - parse_number(Input@1, Number, Sign); - - [<<"0"/utf8>> | Input@2] -> - parse_number(Input@2, (Number * 10) + 0, Sign); - - [<<"1"/utf8>> | Input@3] -> - parse_number(Input@3, (Number * 10) + 1, Sign); - - [<<"2"/utf8>> | Input@4] -> - parse_number(Input@4, (Number * 10) + 2, Sign); - - [<<"3"/utf8>> | Input@5] -> - parse_number(Input@5, (Number * 10) + 3, Sign); - - [<<"4"/utf8>> | Input@6] -> - parse_number(Input@6, (Number * 10) + 4, Sign); - - [<<"5"/utf8>> | Input@7] -> - parse_number(Input@7, (Number * 10) + 5, Sign); - - [<<"6"/utf8>> | Input@8] -> - parse_number(Input@8, (Number * 10) + 6, Sign); - - [<<"7"/utf8>> | Input@9] -> - parse_number(Input@9, (Number * 10) + 7, Sign); - - [<<"8"/utf8>> | Input@10] -> - parse_number(Input@10, (Number * 10) + 8, Sign); - - [<<"9"/utf8>> | Input@11] -> - parse_number(Input@11, (Number * 10) + 9, Sign); - - [<<"-"/utf8>> | Input@12] -> - parse_date(Input@12, Number); - - [<<":"/utf8>> | Input@13] when Number < 24 -> - parse_time_minute(Input@13, Number); - - [<<"."/utf8>> | Input@14] -> - parse_float(Input@14, gleam@int:to_float(Number), Sign, 0.1); - - [<<"e"/utf8>>, <<"+"/utf8>> | Input@15] -> - parse_exponent( - Input@15, - gleam@int:to_float(Number), - Sign, - 0, - positive - ); - - [<<"e"/utf8>>, <<"-"/utf8>> | Input@16] -> - parse_exponent( - Input@16, - gleam@int:to_float(Number), - Sign, - 0, - negative - ); - - [<<"e"/utf8>> | Input@17] -> - parse_exponent( - Input@17, - gleam@int:to_float(Number), - Sign, - 0, - positive - ); - - [<<"E"/utf8>>, <<"+"/utf8>> | Input@18] -> - parse_exponent( - Input@18, - gleam@int:to_float(Number), - Sign, - 0, - positive - ); - - [<<"E"/utf8>>, <<"-"/utf8>> | Input@19] -> - parse_exponent( - Input@19, - gleam@int:to_float(Number), - Sign, - 0, - negative - ); - - [<<"E"/utf8>> | Input@20] -> - parse_exponent( - Input@20, - gleam@int:to_float(Number), - Sign, - 0, - positive - ); - - Input@21 -> - Number@1 = case Sign of - positive -> - Number; - - negative -> - - Number - end, - {ok, {{int, Number@1}, Input@21}} - end. - --spec reverse_arrays_of_tables(toml()) -> toml(). -reverse_arrays_of_tables(Toml) -> - case Toml of - {array_of_tables, Tables} -> - {array_of_tables, reverse_arrays_of_tables_array(Tables, [])}; - - {table, Table} -> - {table, reverse_arrays_of_tables_table(Table)}; - - _ -> - Toml - end. - --spec reverse_arrays_of_tables_table(gleam@map:map_(binary(), toml())) -> gleam@map:map_(binary(), toml()). -reverse_arrays_of_tables_table(Table) -> - gleam@map:map_values(Table, fun(_, V) -> reverse_arrays_of_tables(V) end). - --spec reverse_arrays_of_tables_array( - list(gleam@map:map_(binary(), toml())), - list(gleam@map:map_(binary(), toml())) -) -> list(gleam@map:map_(binary(), toml())). -reverse_arrays_of_tables_array(Array, Acc) -> - case Array of - [] -> - Acc; - - [First | Rest] -> - First@1 = reverse_arrays_of_tables_table(First), - reverse_arrays_of_tables_array(Rest, [First@1 | Acc]) - end. - --spec parse_inline_table_property( - list(binary()), - gleam@map:map_(binary(), toml()) -) -> {ok, {gleam@map:map_(binary(), toml()), list(binary())}} | - {error, parse_error()}. -parse_inline_table_property(Input, Properties) -> - Input@1 = skip_whitespace(Input), - do( - parse_key(Input@1, []), - fun(Key, Input@2) -> - Input@3 = skip_line_whitespace(Input@2), - expect( - Input@3, - <<"="/utf8>>, - fun(Input@4) -> - Input@5 = skip_line_whitespace(Input@4), - do( - parse_value(Input@5), - fun(Value, Input@6) -> - case insert(Properties, Key, Value) of - {ok, Properties@1} -> - {ok, {Properties@1, Input@6}}; - - {error, E} -> - {error, E} - end - end - ) - end - ) - end - ). - --spec parse_value(list(binary())) -> {ok, {toml(), list(binary())}} | - {error, parse_error()}. -parse_value(Input) -> - case Input of - [<<"t"/utf8>>, <<"r"/utf8>>, <<"u"/utf8>>, <<"e"/utf8>> | Input@1] -> - {ok, {{bool, true}, Input@1}}; - - [<<"f"/utf8>>, - <<"a"/utf8>>, - <<"l"/utf8>>, - <<"s"/utf8>>, - <<"e"/utf8>> | - Input@2] -> - {ok, {{bool, false}, Input@2}}; - - [<<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@3] -> - {ok, {{nan, positive}, Input@3}}; - - [<<"+"/utf8>>, <<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@4] -> - {ok, {{nan, positive}, Input@4}}; - - [<<"-"/utf8>>, <<"n"/utf8>>, <<"a"/utf8>>, <<"n"/utf8>> | Input@5] -> - {ok, {{nan, negative}, Input@5}}; - - [<<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@6] -> - {ok, {{infinity, positive}, Input@6}}; - - [<<"+"/utf8>>, <<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@7] -> - {ok, {{infinity, positive}, Input@7}}; - - [<<"-"/utf8>>, <<"i"/utf8>>, <<"n"/utf8>>, <<"f"/utf8>> | Input@8] -> - {ok, {{infinity, negative}, Input@8}}; - - [<<"["/utf8>> | Input@9] -> - parse_array(Input@9, []); - - [<<"{"/utf8>> | Input@10] -> - parse_inline_table(Input@10, gleam@map:new()); - - [<<"0"/utf8>>, <<"x"/utf8>> | Input@11] -> - parse_hex(Input@11, 0, positive); - - [<<"+"/utf8>>, <<"0"/utf8>>, <<"x"/utf8>> | Input@12] -> - parse_hex(Input@12, 0, positive); - - [<<"-"/utf8>>, <<"0"/utf8>>, <<"x"/utf8>> | Input@13] -> - parse_hex(Input@13, 0, negative); - - [<<"0"/utf8>>, <<"o"/utf8>> | Input@14] -> - parse_octal(Input@14, 0, positive); - - [<<"+"/utf8>>, <<"0"/utf8>>, <<"o"/utf8>> | Input@15] -> - parse_octal(Input@15, 0, positive); - - [<<"-"/utf8>>, <<"0"/utf8>>, <<"o"/utf8>> | Input@16] -> - parse_octal(Input@16, 0, negative); - - [<<"0"/utf8>>, <<"b"/utf8>> | Input@17] -> - parse_binary(Input@17, 0, positive); - - [<<"+"/utf8>>, <<"0"/utf8>>, <<"b"/utf8>> | Input@18] -> - parse_binary(Input@18, 0, positive); - - [<<"-"/utf8>>, <<"0"/utf8>>, <<"b"/utf8>> | Input@19] -> - parse_binary(Input@19, 0, negative); - - [<<"+"/utf8>> | Input@20] -> - parse_number(Input@20, 0, positive); - - [<<"-"/utf8>> | Input@21] -> - parse_number(Input@21, 0, negative); - - [<<"0"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"1"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"2"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"3"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"4"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"5"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"6"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"7"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"8"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"9"/utf8>> | _] -> - parse_number(Input, 0, positive); - - [<<"\""/utf8>>, <<"\""/utf8>>, <<"\""/utf8>> | Input@22] -> - parse_multi_line_string(Input@22, <<""/utf8>>); - - [<<"\""/utf8>> | Input@23] -> - parse_string(Input@23, <<""/utf8>>); - - [<<"'"/utf8>>, <<"'"/utf8>>, <<"'"/utf8>> | Input@24] -> - parse_multi_line_literal_string(Input@24, <<""/utf8>>); - - [<<"'"/utf8>> | Input@25] -> - parse_literal_string(Input@25, <<""/utf8>>); - - [G | _] -> - {error, {unexpected, G, <<"value"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"value"/utf8>>}} - end. - --spec parse_inline_table(list(binary()), gleam@map:map_(binary(), toml())) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_inline_table(Input, Properties) -> - Input@1 = skip_whitespace(Input), - case Input@1 of - [<<"}"/utf8>> | Input@2] -> - {ok, {{inline_table, Properties}, Input@2}}; - - _ -> - case parse_inline_table_property(Input@1, Properties) of - {ok, {Properties@1, Input@3}} -> - Input@4 = skip_whitespace(Input@3), - case Input@4 of - [<<"}"/utf8>> | Input@5] -> - {ok, {{inline_table, Properties@1}, Input@5}}; - - [<<","/utf8>> | Input@6] -> - Input@7 = skip_whitespace(Input@6), - parse_inline_table(Input@7, Properties@1); - - [G | _] -> - {error, {unexpected, G, <<"}"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"}"/utf8>>}} - end; - - {error, E} -> - {error, E} - end - end. - --spec parse_key_value(list(binary()), gleam@map:map_(binary(), toml())) -> {ok, - {gleam@map:map_(binary(), toml()), list(binary())}} | - {error, parse_error()}. -parse_key_value(Input, Toml) -> - do( - parse_key(Input, []), - fun(Key, Input@1) -> - Input@2 = skip_line_whitespace(Input@1), - expect( - Input@2, - <<"="/utf8>>, - fun(Input@3) -> - Input@4 = skip_line_whitespace(Input@3), - do( - parse_value(Input@4), - fun(Value, Input@5) -> case insert(Toml, Key, Value) of - {ok, Toml@1} -> - {ok, {Toml@1, Input@5}}; - - {error, E} -> - {error, E} - end end - ) - end - ) - end - ). - --spec parse_table(list(binary()), gleam@map:map_(binary(), toml())) -> {ok, - {gleam@map:map_(binary(), toml()), list(binary())}} | - {error, parse_error()}. -parse_table(Input, Toml) -> - Input@1 = skip_whitespace(Input), - case Input@1 of - [<<"["/utf8>> | _] -> - {ok, {Toml, Input@1}}; - - [] -> - {ok, {Toml, Input@1}}; - - _ -> - case parse_key_value(Input@1, Toml) of - {ok, {Toml@1, Input@2}} -> - case skip_line_whitespace(Input@2) of - [] -> - {ok, {Toml@1, []}}; - - [<<"\n"/utf8>> | In] -> - parse_table(In, Toml@1); - - [<<"\r\n"/utf8>> | In] -> - parse_table(In, Toml@1); - - [G | _] -> - {error, {unexpected, G, <<"\n"/utf8>>}} - end; - - E -> - E - end - end. - --spec parse_array_of_tables(list(binary())) -> {ok, - {{list(binary()), gleam@map:map_(binary(), toml())}, list(binary())}} | - {error, parse_error()}. -parse_array_of_tables(Input) -> - Input@1 = skip_line_whitespace(Input), - do( - parse_key(Input@1, []), - fun(Key, Input@2) -> - expect( - Input@2, - <<"]"/utf8>>, - fun(Input@3) -> - expect( - Input@3, - <<"]"/utf8>>, - fun(Input@4) -> - do( - parse_table(Input@4, gleam@map:new()), - fun(Table, Input@5) -> - {ok, {{Key, Table}, Input@5}} - end - ) - end - ) - end - ) - end - ). - --spec parse_table_and_header(list(binary())) -> {ok, - {{list(binary()), gleam@map:map_(binary(), toml())}, list(binary())}} | - {error, parse_error()}. -parse_table_and_header(Input) -> - do( - parse_table_header(Input), - fun(Key, Input@1) -> - do( - parse_table(Input@1, gleam@map:new()), - fun(Table, Input@2) -> {ok, {{Key, Table}, Input@2}} end - ) - end - ). - --spec parse_tables(list(binary()), gleam@map:map_(binary(), toml())) -> {ok, - gleam@map:map_(binary(), toml())} | - {error, parse_error()}. -parse_tables(Input, Toml) -> - case Input of - [<<"["/utf8>>, <<"["/utf8>> | Input@1] -> - case parse_array_of_tables(Input@1) of - {error, E} -> - {error, E}; - - {ok, {{Key, Table}, Input@2}} -> - case insert(Toml, Key, {array_of_tables, [Table]}) of - {ok, Toml@1} -> - parse_tables(Input@2, Toml@1); - - {error, E@1} -> - {error, E@1} - end - end; - - [<<"["/utf8>> | Input@3] -> - case parse_table_and_header(Input@3) of - {error, E@2} -> - {error, E@2}; - - {ok, {{Key@1, Table@1}, Input@4}} -> - case insert(Toml, Key@1, {table, Table@1}) of - {ok, Toml@2} -> - parse_tables(Input@4, Toml@2); - - {error, E@3} -> - {error, E@3} - end - end; - - [G | _] -> - {error, {unexpected, G, <<"["/utf8>>}}; - - [] -> - {ok, Toml} - end. - --spec parse(binary()) -> {ok, gleam@map:map_(binary(), toml())} | - {error, parse_error()}. -parse(Input) -> - Input@1 = gleam@string:to_graphemes(Input), - Input@2 = drop_comments(Input@1, []), - Input@3 = skip_whitespace(Input@2), - do( - parse_table(Input@3, gleam@map:new()), - fun(Toml, Input@4) -> case parse_tables(Input@4, Toml) of - {ok, Toml@1} -> - {ok, reverse_arrays_of_tables_table(Toml@1)}; - - {error, E} -> - {error, E} - end end - ). - --spec parse_array(list(binary()), list(toml())) -> {ok, - {toml(), list(binary())}} | - {error, parse_error()}. -parse_array(Input, Elements) -> - Input@1 = skip_whitespace(Input), - case Input@1 of - [<<"]"/utf8>> | Input@2] -> - {ok, {{array, gleam@list:reverse(Elements)}, Input@2}}; - - _ -> - do( - parse_value(Input@1), - fun(Element, Input@3) -> - Elements@1 = [Element | Elements], - Input@4 = skip_whitespace(Input@3), - case Input@4 of - [<<"]"/utf8>> | Input@5] -> - {ok, - {{array, gleam@list:reverse(Elements@1)}, - Input@5}}; - - [<<","/utf8>> | Input@6] -> - Input@7 = skip_whitespace(Input@6), - parse_array(Input@7, Elements@1); - - [G | _] -> - {error, {unexpected, G, <<"]"/utf8>>}}; - - [] -> - {error, {unexpected, <<"EOF"/utf8>>, <<"]"/utf8>>}} - end - end - ) - end. diff --git a/aoc2023/build/packages/tom/src/tom.gleam b/aoc2023/build/packages/tom/src/tom.gleam deleted file mode 100644 index e19ce3e..0000000 --- a/aoc2023/build/packages/tom/src/tom.gleam +++ /dev/null @@ -1,1317 +0,0 @@ -//// A pure Gleam TOML parser! -//// -//// ```gleam -//// import tom -//// -//// const config = " -//// [person] -//// name = \"Lucy\" -//// is_cool = true -//// " -//// -//// pub fn main() { -//// // Parse a string of TOML -//// let assert Ok(parsed) = tom.parse(config) -//// -//// // Now you can work with the data directly, or you can use the `get_*` -//// // functions to retrieve values. -//// -//// tom.get_string(parsed, ["person", "name"]) -//// // -> Ok("Lucy") -//// -//// let is_cool = tom.get_bool(parsed, ["person", "is_cool"]) -//// // -> Ok(True) -//// } -//// ``` - -import gleam/int -import gleam/list -import gleam/float -import gleam/string -import gleam/result -import gleam/map.{type Map} - -/// A TOML document. -pub type Toml { - Int(Int) - Float(Float) - /// Infinity is a valid number in TOML but Gleam does not support it, so this - /// variant represents the infinity values. - Infinity(Sign) - /// NaN is a valid number in TOML but Gleam does not support it, so this - /// variant represents the NaN values. - Nan(Sign) - Bool(Bool) - String(String) - Date(Date) - Time(Time) - DateTime(DateTime) - Array(List(Toml)) - ArrayOfTables(List(Map(String, Toml))) - Table(Map(String, Toml)) - InlineTable(Map(String, Toml)) -} - -pub type DateTime { - DateTimeValue(date: Date, time: Time, offset: Offset) -} - -pub type Date { - DateValue(year: Int, month: Int, day: Int) -} - -pub type Time { - TimeValue(hour: Int, minute: Int, second: Int, millisecond: Int) -} - -pub type Offset { - Local - Offset(direction: Sign, hours: Int, minutes: Int) -} - -pub type Sign { - Positive - Negative -} - -/// An error that can occur when parsing a TOML document. -pub type ParseError { - /// An unexpected character was encountered when parsing the document. - Unexpected(got: String, expected: String) - /// More than one items have the same key in the document. - KeyAlreadyInUse(key: List(String)) -} - -type Tokens = - List(String) - -type Parsed(a) = - Result(#(a, Tokens), ParseError) - -/// A number of any kind, returned by the `get_number` function. -pub type Number { - NumberInt(Int) - NumberFloat(Float) - NumberInfinity(Sign) - NumberNan(Sign) -} - -/// An error that can occur when retrieving a value from a TOML document with -/// one of the `get_*` functions. -pub type GetError { - /// There was no value at the given key. - NotFound(key: List(String)) - /// The value at the given key was not of the expected type. - WrongType(key: List(String), expected: String, got: String) -} - -// TODO: test -/// Get a value of any type from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 1") -/// get(parsed, ["a", "b", "c"]) -/// // -> Ok(Int(1)) -/// ``` -/// -pub fn get(toml: Map(String, Toml), key: List(String)) -> Result(Toml, GetError) { - case key { - [] -> Error(NotFound([])) - [k] -> result.replace_error(map.get(toml, k), NotFound([k])) - [k, ..key] -> { - case map.get(toml, k) { - Ok(Table(t)) -> push_key(get(t, key), k) - Ok(other) -> Error(WrongType([k], "Table", classify(other))) - Error(_) -> Error(NotFound([k])) - } - } - } -} - -// TODO: test -/// Get an int from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 1") -/// get_int(parsed, ["a", "b", "c"]) -/// // -> Ok(1) -/// ``` -/// -pub fn get_int( - toml: Map(String, Toml), - key: List(String), -) -> Result(Int, GetError) { - case get(toml, key) { - Ok(Int(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Int", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a float from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 1.1") -/// get_float(parsed, ["a", "b", "c"]) -/// // -> Ok(1.1) -/// ``` -/// -pub fn get_float( - toml: Map(String, Toml), - key: List(String), -) -> Result(Float, GetError) { - case get(toml, key) { - Ok(Float(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Float", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a bool from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = true") -/// get_bool(parsed, ["a", "b", "c"]) -/// // -> Ok(True) -/// ``` -/// -pub fn get_bool( - toml: Map(String, Toml), - key: List(String), -) -> Result(Bool, GetError) { - case get(toml, key) { - Ok(Bool(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Bool", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a string from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = \"ok\"") -/// get_string(parsed, ["a", "b", "c"]) -/// // -> Ok("ok") -/// ``` -/// -pub fn get_string( - toml: Map(String, Toml), - key: List(String), -) -> Result(String, GetError) { - case get(toml, key) { - Ok(String(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "String", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a date from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 1979-05-27") -/// get_date(parsed, ["a", "b", "c"]) -/// // -> Ok("1979-05-27") -/// ``` -/// -pub fn get_date( - toml: Map(String, Toml), - key: List(String), -) -> Result(Date, GetError) { - case get(toml, key) { - Ok(Date(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Date", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a time from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 07:32:00") -/// get_time(parsed, ["a", "b", "c"]) -/// // -> Ok("07:32:00") -/// ``` -/// -pub fn get_time( - toml: Map(String, Toml), - key: List(String), -) -> Result(Time, GetError) { - case get(toml, key) { - Ok(Time(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Time", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a date-time from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = 1979-05-27T07:32:00") -/// get_date_time(parsed, ["a", "b", "c"]) -/// // -> Ok("1979-05-27T07:32:00") -/// ``` -/// -pub fn get_date_time( - toml: Map(String, Toml), - key: List(String), -) -> Result(DateTime, GetError) { - case get(toml, key) { - Ok(DateTime(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "DateTime", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get an array from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = [1, 2]") -/// get_array(parsed, ["a", "b", "c"]) -/// // -> Ok([Int(1), Int(2)]) -/// ``` -/// -pub fn get_array( - toml: Map(String, Toml), - key: List(String), -) -> Result(List(Toml), GetError) { - case get(toml, key) { - Ok(Array(i)) -> Ok(i) - Ok(ArrayOfTables(i)) -> Ok(list.map(i, Table)) - Ok(other) -> Error(WrongType(key, "Array", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a table from a TOML document. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = { d = 1 }") -/// get_table(parsed, ["a", "b", "c"]) -/// // -> Ok(map.from_list([#("d", Int(1))])) -/// ``` -/// -pub fn get_table( - toml: Map(String, Toml), - key: List(String), -) -> Result(Map(String, Toml), GetError) { - case get(toml, key) { - Ok(Table(i)) -> Ok(i) - Ok(InlineTable(i)) -> Ok(i) - Ok(other) -> Error(WrongType(key, "Table", classify(other))) - Error(e) -> Error(e) - } -} - -// TODO: test -/// Get a number of any kind from a TOML document. -/// This could be an int, a float, a NaN, or an infinity. -/// -/// ## Examples -/// -/// ```gleam -/// let assert Ok(parsed) = parse("a.b.c = { d = inf }") -/// get_number(parsed, ["a", "b", "c"]) -/// // -> Ok(NumberInfinity(Positive))) -/// ``` -/// -pub fn get_number( - toml: Map(String, Toml), - key: List(String), -) -> Result(Number, GetError) { - case get(toml, key) { - Ok(Int(x)) -> Ok(NumberInt(x)) - Ok(Float(x)) -> Ok(NumberFloat(x)) - Ok(Nan(x)) -> Ok(NumberNan(x)) - Ok(Infinity(x)) -> Ok(NumberInfinity(x)) - Ok(other) -> Error(WrongType(key, "Number", classify(other))) - Error(e) -> Error(e) - } -} - -fn classify(toml: Toml) -> String { - case toml { - Int(_) -> "Int" - Float(_) -> "Float" - Nan(Positive) -> "NaN" - Nan(Negative) -> "Negative NaN" - Infinity(Positive) -> "Infinity" - Infinity(Negative) -> "Negative Infinity" - Bool(_) -> "Bool" - String(_) -> "String" - Date(_) -> "Date" - Time(_) -> "Time" - DateTime(_) -> "DateTime" - Array(_) -> "Array" - ArrayOfTables(_) -> "Array" - Table(_) -> "Table" - InlineTable(_) -> "Table" - } -} - -fn push_key(result: Result(t, GetError), key: String) -> Result(t, GetError) { - case result { - Ok(t) -> Ok(t) - Error(NotFound(path)) -> Error(NotFound([key, ..path])) - Error(WrongType(path, expected, got)) -> - Error(WrongType([key, ..path], expected, got)) - } -} - -pub fn parse(input: String) -> Result(Map(String, Toml), ParseError) { - let input = string.to_graphemes(input) - let input = drop_comments(input, []) - let input = skip_whitespace(input) - use toml, input <- do(parse_table(input, map.new())) - case parse_tables(input, toml) { - Ok(toml) -> Ok(reverse_arrays_of_tables_table(toml)) - Error(e) -> Error(e) - } -} - -fn parse_tables( - input: Tokens, - toml: Map(String, Toml), -) -> Result(Map(String, Toml), ParseError) { - case input { - ["[", "[", ..input] -> { - case parse_array_of_tables(input) { - Error(e) -> Error(e) - Ok(#(#(key, table), input)) -> { - case insert(toml, key, ArrayOfTables([table])) { - Ok(toml) -> parse_tables(input, toml) - Error(e) -> Error(e) - } - } - } - } - ["[", ..input] -> { - case parse_table_and_header(input) { - Error(e) -> Error(e) - Ok(#(#(key, table), input)) -> { - case insert(toml, key, Table(table)) { - Ok(toml) -> parse_tables(input, toml) - Error(e) -> Error(e) - } - } - } - } - [g, ..] -> Error(Unexpected(g, "[")) - [] -> Ok(toml) - } -} - -fn parse_array_of_tables( - input: Tokens, -) -> Parsed(#(List(String), Map(String, Toml))) { - let input = skip_line_whitespace(input) - use key, input <- do(parse_key(input, [])) - use input <- expect(input, "]") - use input <- expect(input, "]") - use table, input <- do(parse_table(input, map.new())) - Ok(#(#(key, table), input)) -} - -fn parse_table_header(input: Tokens) -> Parsed(List(String)) { - let input = skip_line_whitespace(input) - use key, input <- do(parse_key(input, [])) - use input <- expect(input, "]") - let input = skip_line_whitespace(input) - use input <- expect_end_of_line(input) - Ok(#(key, input)) -} - -fn parse_table_and_header( - input: Tokens, -) -> Parsed(#(List(String), Map(String, Toml))) { - use key, input <- do(parse_table_header(input)) - use table, input <- do(parse_table(input, map.new())) - Ok(#(#(key, table), input)) -} - -fn parse_table( - input: Tokens, - toml: Map(String, Toml), -) -> Parsed(Map(String, Toml)) { - let input = skip_whitespace(input) - case input { - ["[", ..] | [] -> Ok(#(toml, input)) - _ -> - case parse_key_value(input, toml) { - Ok(#(toml, input)) -> - case skip_line_whitespace(input) { - [] -> Ok(#(toml, [])) - ["\n", ..in] | ["\r\n", ..in] -> parse_table(in, toml) - [g, ..] -> Error(Unexpected(g, "\n")) - } - e -> e - } - } -} - -fn parse_key_value( - input: Tokens, - toml: Map(String, Toml), -) -> Parsed(Map(String, Toml)) { - use key, input <- do(parse_key(input, [])) - let input = skip_line_whitespace(input) - use input <- expect(input, "=") - let input = skip_line_whitespace(input) - use value, input <- do(parse_value(input)) - case insert(toml, key, value) { - Ok(toml) -> Ok(#(toml, input)) - Error(e) -> Error(e) - } -} - -fn insert( - table: Map(String, Toml), - key: List(String), - value: Toml, -) -> Result(Map(String, Toml), ParseError) { - case insert_loop(table, key, value) { - Ok(table) -> Ok(table) - Error(path) -> Error(KeyAlreadyInUse(path)) - } -} - -fn insert_loop( - table: Map(String, Toml), - key: List(String), - value: Toml, -) -> Result(Map(String, Toml), List(String)) { - case key { - [] -> panic as "unreachable" - [k] -> { - case map.get(table, k) { - Error(Nil) -> Ok(map.insert(table, k, value)) - Ok(old) -> merge(table, k, old, value) - } - } - [k, ..key] -> { - case map.get(table, k) { - Error(Nil) -> { - case insert_loop(map.new(), key, value) { - Ok(inner) -> Ok(map.insert(table, k, Table(inner))) - Error(path) -> Error([k, ..path]) - } - } - Ok(ArrayOfTables([inner, ..rest])) -> { - case insert_loop(inner, key, value) { - Ok(inner) -> - Ok(map.insert(table, k, ArrayOfTables([inner, ..rest]))) - Error(path) -> Error([k, ..path]) - } - } - Ok(Table(inner)) -> { - case insert_loop(inner, key, value) { - Ok(inner) -> Ok(map.insert(table, k, Table(inner))) - Error(path) -> Error([k, ..path]) - } - } - Ok(_) -> Error([k]) - } - } - } -} - -fn merge( - table: Map(String, Toml), - key: String, - old: Toml, - new: Toml, -) -> Result(Map(String, Toml), List(String)) { - case old, new { - // When both are arrays of tables then they are merged together - ArrayOfTables(tables), ArrayOfTables(new) -> - Ok(map.insert(table, key, ArrayOfTables(list.append(new, tables)))) - - _, _ -> Error([key]) - } -} - -fn expect_end_of_line(input: Tokens, next: fn(Tokens) -> Parsed(a)) -> Parsed(a) { - case input { - ["\n", ..input] -> next(input) - ["\r\n", ..input] -> next(input) - [g, ..] -> Error(Unexpected(g, "\n")) - [] -> Error(Unexpected("EOF", "\n")) - } -} - -fn parse_value(input) -> Parsed(Toml) { - case input { - ["t", "r", "u", "e", ..input] -> Ok(#(Bool(True), input)) - ["f", "a", "l", "s", "e", ..input] -> Ok(#(Bool(False), input)) - - ["n", "a", "n", ..input] -> Ok(#(Nan(Positive), input)) - ["+", "n", "a", "n", ..input] -> Ok(#(Nan(Positive), input)) - ["-", "n", "a", "n", ..input] -> Ok(#(Nan(Negative), input)) - - ["i", "n", "f", ..input] -> Ok(#(Infinity(Positive), input)) - ["+", "i", "n", "f", ..input] -> Ok(#(Infinity(Positive), input)) - ["-", "i", "n", "f", ..input] -> Ok(#(Infinity(Negative), input)) - - ["[", ..input] -> parse_array(input, []) - ["{", ..input] -> parse_inline_table(input, map.new()) - - ["0", "x", ..input] -> parse_hex(input, 0, Positive) - ["+", "0", "x", ..input] -> parse_hex(input, 0, Positive) - ["-", "0", "x", ..input] -> parse_hex(input, 0, Negative) - - ["0", "o", ..input] -> parse_octal(input, 0, Positive) - ["+", "0", "o", ..input] -> parse_octal(input, 0, Positive) - ["-", "0", "o", ..input] -> parse_octal(input, 0, Negative) - - ["0", "b", ..input] -> parse_binary(input, 0, Positive) - ["+", "0", "b", ..input] -> parse_binary(input, 0, Positive) - ["-", "0", "b", ..input] -> parse_binary(input, 0, Negative) - - ["+", ..input] -> parse_number(input, 0, Positive) - ["-", ..input] -> parse_number(input, 0, Negative) - ["0", ..] - | ["1", ..] - | ["2", ..] - | ["3", ..] - | ["4", ..] - | ["5", ..] - | ["6", ..] - | ["7", ..] - | ["8", ..] - | ["9", ..] -> parse_number(input, 0, Positive) - - ["\"", "\"", "\"", ..input] -> parse_multi_line_string(input, "") - ["\"", ..input] -> parse_string(input, "") - - ["'", "'", "'", ..input] -> parse_multi_line_literal_string(input, "") - ["'", ..input] -> parse_literal_string(input, "") - - [g, ..] -> Error(Unexpected(g, "value")) - [] -> Error(Unexpected("EOF", "value")) - } -} - -fn parse_key(input: Tokens, segments: List(String)) -> Parsed(List(String)) { - use segment, input <- do(parse_key_segment(input)) - let segments = [segment, ..segments] - let input = skip_line_whitespace(input) - - case input { - [".", ..input] -> parse_key(input, segments) - _ -> Ok(#(list.reverse(segments), input)) - } -} - -fn parse_key_segment(input: Tokens) -> Parsed(String) { - let input = skip_line_whitespace(input) - case input { - ["=", ..] -> Error(Unexpected("=", "Key")) - ["\n", ..] -> Error(Unexpected("\n", "Key")) - ["\r\n", ..] -> Error(Unexpected("\r\n", "Key")) - ["[", ..] -> Error(Unexpected("[", "Key")) - ["\"", ..input] -> parse_key_quoted(input, "\"", "") - ["'", ..input] -> parse_key_quoted(input, "'", "") - _ -> parse_key_bare(input, "") - } -} - -fn parse_key_quoted( - input: Tokens, - close: String, - name: String, -) -> Parsed(String) { - case input { - [g, ..input] if g == close -> Ok(#(name, input)) - [g, ..input] -> parse_key_quoted(input, close, name <> g) - [] -> Error(Unexpected("EOF", close)) - } -} - -fn parse_key_bare(input: Tokens, name: String) -> Parsed(String) { - case input { - [" ", ..input] if name != "" -> Ok(#(name, input)) - ["=", ..] if name != "" -> Ok(#(name, input)) - [".", ..] if name != "" -> Ok(#(name, input)) - ["]", ..] if name != "" -> Ok(#(name, input)) - [",", ..] if name != "" -> Error(Unexpected(",", "=")) - ["\n", ..] if name != "" -> Error(Unexpected("\n", "=")) - ["\r\n", ..] if name != "" -> Error(Unexpected("\r\n", "=")) - ["\n", ..] -> Error(Unexpected("\n", "key")) - ["\r\n", ..] -> Error(Unexpected("\r\n", "key")) - ["]", ..] -> Error(Unexpected("]", "key")) - [",", ..] -> Error(Unexpected(",", "key")) - [g, ..input] -> parse_key_bare(input, name <> g) - [] -> Error(Unexpected("EOF", "key")) - } -} - -fn skip_line_whitespace(input: Tokens) -> Tokens { - list.drop_while(input, fn(g) { g == " " || g == "\t" }) -} - -fn skip_whitespace(input: Tokens) -> Tokens { - case input { - [" ", ..input] -> skip_whitespace(input) - ["\t", ..input] -> skip_whitespace(input) - ["\n", ..input] -> skip_whitespace(input) - ["\r\n", ..input] -> skip_whitespace(input) - input -> input - } -} - -fn drop_comments(input: Tokens, acc: Tokens) -> Tokens { - case input { - ["#", ..input] -> - input - |> list.drop_while(fn(g) { g != "\n" }) - |> drop_comments(acc) - [g, ..input] -> drop_comments(input, [g, ..acc]) - [] -> list.reverse(acc) - } -} - -fn do( - result: Result(#(a, Tokens), ParseError), - next: fn(a, Tokens) -> Result(b, ParseError), -) -> Result(b, ParseError) { - case result { - Ok(#(a, input)) -> next(a, input) - Error(e) -> Error(e) - } -} - -fn expect( - input: Tokens, - expected: String, - next: fn(Tokens) -> Parsed(a), -) -> Parsed(a) { - case input { - [g, ..input] if g == expected -> next(input) - [g, ..] -> Error(Unexpected(g, expected)) - [] -> Error(Unexpected("EOF", expected)) - } -} - -fn parse_inline_table( - input: Tokens, - properties: Map(String, Toml), -) -> Parsed(Toml) { - let input = skip_whitespace(input) - case input { - ["}", ..input] -> Ok(#(InlineTable(properties), input)) - _ -> - case parse_inline_table_property(input, properties) { - Ok(#(properties, input)) -> { - let input = skip_whitespace(input) - case input { - ["}", ..input] -> Ok(#(InlineTable(properties), input)) - [",", ..input] -> { - let input = skip_whitespace(input) - parse_inline_table(input, properties) - } - [g, ..] -> Error(Unexpected(g, "}")) - [] -> Error(Unexpected("EOF", "}")) - } - } - Error(e) -> Error(e) - } - } -} - -fn parse_inline_table_property( - input: Tokens, - properties: Map(String, Toml), -) -> Parsed(Map(String, Toml)) { - let input = skip_whitespace(input) - use key, input <- do(parse_key(input, [])) - let input = skip_line_whitespace(input) - use input <- expect(input, "=") - let input = skip_line_whitespace(input) - use value, input <- do(parse_value(input)) - case insert(properties, key, value) { - Ok(properties) -> Ok(#(properties, input)) - Error(e) -> Error(e) - } -} - -fn parse_array(input: Tokens, elements: List(Toml)) -> Parsed(Toml) { - let input = skip_whitespace(input) - case input { - ["]", ..input] -> Ok(#(Array(list.reverse(elements)), input)) - _ -> { - use element, input <- do(parse_value(input)) - let elements = [element, ..elements] - let input = skip_whitespace(input) - case input { - ["]", ..input] -> Ok(#(Array(list.reverse(elements)), input)) - [",", ..input] -> { - let input = skip_whitespace(input) - parse_array(input, elements) - } - [g, ..] -> Error(Unexpected(g, "]")) - [] -> Error(Unexpected("EOF", "]")) - } - } - } -} - -fn parse_hex(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_hex(input, number, sign) - ["0", ..input] -> parse_hex(input, number * 16 + 0, sign) - ["1", ..input] -> parse_hex(input, number * 16 + 1, sign) - ["2", ..input] -> parse_hex(input, number * 16 + 2, sign) - ["3", ..input] -> parse_hex(input, number * 16 + 3, sign) - ["4", ..input] -> parse_hex(input, number * 16 + 4, sign) - ["5", ..input] -> parse_hex(input, number * 16 + 5, sign) - ["6", ..input] -> parse_hex(input, number * 16 + 6, sign) - ["7", ..input] -> parse_hex(input, number * 16 + 7, sign) - ["8", ..input] -> parse_hex(input, number * 16 + 8, sign) - ["9", ..input] -> parse_hex(input, number * 16 + 9, sign) - ["a", ..input] -> parse_hex(input, number * 16 + 10, sign) - ["b", ..input] -> parse_hex(input, number * 16 + 11, sign) - ["c", ..input] -> parse_hex(input, number * 16 + 12, sign) - ["d", ..input] -> parse_hex(input, number * 16 + 13, sign) - ["e", ..input] -> parse_hex(input, number * 16 + 14, sign) - ["f", ..input] -> parse_hex(input, number * 16 + 15, sign) - ["A", ..input] -> parse_hex(input, number * 16 + 10, sign) - ["B", ..input] -> parse_hex(input, number * 16 + 11, sign) - ["C", ..input] -> parse_hex(input, number * 16 + 12, sign) - ["D", ..input] -> parse_hex(input, number * 16 + 13, sign) - ["E", ..input] -> parse_hex(input, number * 16 + 14, sign) - ["F", ..input] -> parse_hex(input, number * 16 + 15, sign) - - // Anything else and the number is terminated - input -> { - let number = case sign { - Positive -> number - Negative -> -number - } - Ok(#(Int(number), input)) - } - } -} - -fn parse_octal(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_octal(input, number, sign) - ["0", ..input] -> parse_octal(input, number * 8 + 0, sign) - ["1", ..input] -> parse_octal(input, number * 8 + 1, sign) - ["2", ..input] -> parse_octal(input, number * 8 + 2, sign) - ["3", ..input] -> parse_octal(input, number * 8 + 3, sign) - ["4", ..input] -> parse_octal(input, number * 8 + 4, sign) - ["5", ..input] -> parse_octal(input, number * 8 + 5, sign) - ["6", ..input] -> parse_octal(input, number * 8 + 6, sign) - ["7", ..input] -> parse_octal(input, number * 8 + 7, sign) - - // Anything else and the number is terminated - input -> { - let number = case sign { - Positive -> number - Negative -> -number - } - Ok(#(Int(number), input)) - } - } -} - -fn parse_binary(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_binary(input, number, sign) - ["0", ..input] -> parse_binary(input, number * 2 + 0, sign) - ["1", ..input] -> parse_binary(input, number * 2 + 1, sign) - - // Anything else and the number is terminated - input -> { - let number = case sign { - Positive -> number - Negative -> -number - } - Ok(#(Int(number), input)) - } - } -} - -fn parse_number(input: Tokens, number: Int, sign: Sign) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_number(input, number, sign) - ["0", ..input] -> parse_number(input, number * 10 + 0, sign) - ["1", ..input] -> parse_number(input, number * 10 + 1, sign) - ["2", ..input] -> parse_number(input, number * 10 + 2, sign) - ["3", ..input] -> parse_number(input, number * 10 + 3, sign) - ["4", ..input] -> parse_number(input, number * 10 + 4, sign) - ["5", ..input] -> parse_number(input, number * 10 + 5, sign) - ["6", ..input] -> parse_number(input, number * 10 + 6, sign) - ["7", ..input] -> parse_number(input, number * 10 + 7, sign) - ["8", ..input] -> parse_number(input, number * 10 + 8, sign) - ["9", ..input] -> parse_number(input, number * 10 + 9, sign) - - ["-", ..input] -> parse_date(input, number) - [":", ..input] if number < 24 -> parse_time_minute(input, number) - - [".", ..input] -> parse_float(input, int.to_float(number), sign, 0.1) - - ["e", "+", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Positive) - ["e", "-", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Negative) - ["e", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Positive) - ["E", "+", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Positive) - ["E", "-", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Negative) - ["E", ..input] -> - parse_exponent(input, int.to_float(number), sign, 0, Positive) - - // Anything else and the number is terminated - input -> { - let number = case sign { - Positive -> number - Negative -> -number - } - Ok(#(Int(number), input)) - } - } -} - -fn parse_exponent( - input: Tokens, - n: Float, - n_sign: Sign, - ex: Int, - ex_sign: Sign, -) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_exponent(input, n, n_sign, ex, ex_sign) - ["0", ..input] -> parse_exponent(input, n, n_sign, ex * 10, ex_sign) - ["1", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 1, ex_sign) - ["2", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 2, ex_sign) - ["3", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 3, ex_sign) - ["4", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 4, ex_sign) - ["5", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 5, ex_sign) - ["6", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 6, ex_sign) - ["7", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 7, ex_sign) - ["8", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 8, ex_sign) - ["9", ..input] -> parse_exponent(input, n, n_sign, ex * 10 + 9, ex_sign) - - // Anything else and the number is terminated - input -> { - let number = case n_sign { - Positive -> n - Negative -> n *. -1.0 - } - let exponent = - int.to_float(case ex_sign { - Positive -> ex - Negative -> -ex - }) - let multiplier = case float.power(10.0, exponent) { - Ok(multiplier) -> multiplier - Error(_) -> 1.0 - } - Ok(#(Float(number *. multiplier), input)) - } - } -} - -fn parse_float( - input: Tokens, - number: Float, - sign: Sign, - unit: Float, -) -> Parsed(Toml) { - case input { - ["_", ..input] -> parse_float(input, number, sign, unit) - ["0", ..input] -> parse_float(input, number, sign, unit *. 0.1) - ["1", ..input] -> - parse_float(input, number +. 1.0 *. unit, sign, unit *. 0.1) - ["2", ..input] -> - parse_float(input, number +. 2.0 *. unit, sign, unit *. 0.1) - ["3", ..input] -> - parse_float(input, number +. 3.0 *. unit, sign, unit *. 0.1) - ["4", ..input] -> - parse_float(input, number +. 4.0 *. unit, sign, unit *. 0.1) - ["5", ..input] -> - parse_float(input, number +. 5.0 *. unit, sign, unit *. 0.1) - ["6", ..input] -> - parse_float(input, number +. 6.0 *. unit, sign, unit *. 0.1) - ["7", ..input] -> - parse_float(input, number +. 7.0 *. unit, sign, unit *. 0.1) - ["8", ..input] -> - parse_float(input, number +. 8.0 *. unit, sign, unit *. 0.1) - ["9", ..input] -> - parse_float(input, number +. 9.0 *. unit, sign, unit *. 0.1) - - ["e", "+", ..input] -> parse_exponent(input, number, sign, 0, Positive) - ["e", "-", ..input] -> parse_exponent(input, number, sign, 0, Negative) - ["e", ..input] -> parse_exponent(input, number, sign, 0, Positive) - ["E", "+", ..input] -> parse_exponent(input, number, sign, 0, Positive) - ["E", "-", ..input] -> parse_exponent(input, number, sign, 0, Negative) - ["E", ..input] -> parse_exponent(input, number, sign, 0, Positive) - - // Anything else and the number is terminated - input -> { - let number = case sign { - Positive -> number - Negative -> number *. -1.0 - } - Ok(#(Float(number), input)) - } - } -} - -fn parse_string(input: Tokens, string: String) -> Parsed(Toml) { - case input { - ["\"", ..input] -> Ok(#(String(string), input)) - ["\\", "t", ..input] -> parse_string(input, string <> "\t") - ["\\", "n", ..input] -> parse_string(input, string <> "\n") - ["\\", "r", ..input] -> parse_string(input, string <> "\r") - ["\\", "\"", ..input] -> parse_string(input, string <> "\"") - ["\\", "\\", ..input] -> parse_string(input, string <> "\\") - [] -> Error(Unexpected("EOF", "\"")) - ["\n", ..] -> Error(Unexpected("\n", "\"")) - ["\r\n", ..] -> Error(Unexpected("\r\n", "\"")) - [g, ..input] -> parse_string(input, string <> g) - } -} - -fn parse_multi_line_string(input: Tokens, string: String) -> Parsed(Toml) { - case input { - ["\"", "\"", "\"", ..input] -> Ok(#(String(string), input)) - ["\\", "\n", ..input] -> - parse_multi_line_string(skip_whitespace(input), string) - ["\\", "\r\n", ..input] -> - parse_multi_line_string(skip_whitespace(input), string) - ["\r\n", ..input] if string == "" -> parse_multi_line_string(input, string) - ["\n", ..input] if string == "" -> parse_multi_line_string(input, string) - ["\r\n", ..input] if string == "" -> parse_multi_line_string(input, string) - ["\\", "t", ..input] -> parse_multi_line_string(input, string <> "\t") - ["\\", "n", ..input] -> parse_multi_line_string(input, string <> "\n") - ["\\", "r", ..input] -> parse_multi_line_string(input, string <> "\r") - ["\\", "\"", ..input] -> parse_multi_line_string(input, string <> "\"") - ["\\", "\\", ..input] -> parse_multi_line_string(input, string <> "\\") - [] -> Error(Unexpected("EOF", "\"")) - [g, ..input] -> parse_multi_line_string(input, string <> g) - } -} - -fn parse_multi_line_literal_string( - input: Tokens, - string: String, -) -> Parsed(Toml) { - case input { - [] -> Error(Unexpected("EOF", "\"")) - ["'", "'", "'", "'", ..] -> Error(Unexpected("''''", "'''")) - ["'", "'", "'", ..input] -> Ok(#(String(string), input)) - ["\n", ..input] if string == "" -> - parse_multi_line_literal_string(input, string) - ["\r\n", ..input] if string == "" -> - parse_multi_line_literal_string(input, string) - [g, ..input] -> parse_multi_line_literal_string(input, string <> g) - } -} - -fn parse_literal_string(input: Tokens, string: String) -> Parsed(Toml) { - case input { - [] -> Error(Unexpected("EOF", "\"")) - ["\n", ..] -> Error(Unexpected("\n", "'")) - ["\r\n", ..] -> Error(Unexpected("\r\n", "'")) - ["'", ..input] -> Ok(#(String(string), input)) - [g, ..input] -> parse_literal_string(input, string <> g) - } -} - -fn reverse_arrays_of_tables(toml: Toml) -> Toml { - case toml { - ArrayOfTables(tables) -> - ArrayOfTables(reverse_arrays_of_tables_array(tables, [])) - - Table(table) -> Table(reverse_arrays_of_tables_table(table)) - - _ -> toml - } -} - -fn reverse_arrays_of_tables_table(table: Map(String, Toml)) -> Map(String, Toml) { - map.map_values(table, fn(_, v) { reverse_arrays_of_tables(v) }) -} - -fn reverse_arrays_of_tables_array( - array: List(Map(String, Toml)), - acc: List(Map(String, Toml)), -) -> List(Map(String, Toml)) { - case array { - [] -> acc - [first, ..rest] -> { - let first = reverse_arrays_of_tables_table(first) - reverse_arrays_of_tables_array(rest, [first, ..acc]) - } - } -} - -fn parse_time_minute(input: Tokens, hours: Int) -> Parsed(Toml) { - use minutes, input <- do(parse_number_under_60(input, "minutes")) - use #(seconds, ms), input <- do(parse_time_s_ms(input)) - let time = TimeValue(hours, minutes, seconds, ms) - Ok(#(Time(time), input)) -} - -fn parse_hour_minute(input: Tokens) -> Parsed(#(Int, Int)) { - use hours, input <- do(case input { - ["0", "0", ":", ..input] -> Ok(#(0, input)) - ["0", "1", ":", ..input] -> Ok(#(1, input)) - ["0", "2", ":", ..input] -> Ok(#(2, input)) - ["0", "3", ":", ..input] -> Ok(#(3, input)) - ["0", "4", ":", ..input] -> Ok(#(4, input)) - ["0", "5", ":", ..input] -> Ok(#(5, input)) - ["0", "6", ":", ..input] -> Ok(#(6, input)) - ["0", "7", ":", ..input] -> Ok(#(7, input)) - ["0", "8", ":", ..input] -> Ok(#(8, input)) - ["0", "9", ":", ..input] -> Ok(#(9, input)) - ["1", "0", ":", ..input] -> Ok(#(10, input)) - ["1", "1", ":", ..input] -> Ok(#(11, input)) - ["1", "2", ":", ..input] -> Ok(#(12, input)) - ["1", "3", ":", ..input] -> Ok(#(13, input)) - ["1", "4", ":", ..input] -> Ok(#(14, input)) - ["1", "5", ":", ..input] -> Ok(#(15, input)) - ["1", "6", ":", ..input] -> Ok(#(16, input)) - ["1", "7", ":", ..input] -> Ok(#(17, input)) - ["1", "8", ":", ..input] -> Ok(#(18, input)) - ["1", "9", ":", ..input] -> Ok(#(19, input)) - ["2", "0", ":", ..input] -> Ok(#(20, input)) - ["2", "1", ":", ..input] -> Ok(#(21, input)) - ["2", "2", ":", ..input] -> Ok(#(22, input)) - ["2", "3", ":", ..input] -> Ok(#(23, input)) - [g, ..] -> Error(Unexpected(g, "time")) - [] -> Error(Unexpected("EOF", "time")) - }) - - use minutes, input <- do(parse_number_under_60(input, "minutes")) - Ok(#(#(hours, minutes), input)) -} - -fn parse_time_value(input: Tokens) -> Parsed(Time) { - use #(hours, minutes), input <- do(parse_hour_minute(input)) - use #(seconds, ms), input <- do(parse_time_s_ms(input)) - let time = TimeValue(hours, minutes, seconds, ms) - Ok(#(time, input)) -} - -fn parse_time_s_ms(input: Tokens) -> Parsed(#(Int, Int)) { - case input { - [":", ..input] -> { - use seconds, input <- do(parse_number_under_60(input, "seconds")) - case input { - [".", ..input] -> parse_time_ms(input, seconds, 0) - _ -> Ok(#(#(seconds, 0), input)) - } - } - - _ -> Ok(#(#(0, 0), input)) - } -} - -fn parse_time_ms(input: Tokens, seconds: Int, ms: Int) -> Parsed(#(Int, Int)) { - case input { - ["0", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 0) - ["1", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 1) - ["2", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 2) - ["3", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 3) - ["4", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 4) - ["5", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 5) - ["6", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 6) - ["7", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 7) - ["8", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 8) - ["9", ..input] if ms < 100_000 -> parse_time_ms(input, seconds, ms * 10 + 9) - - // Anything else and the number is terminated - _ -> Ok(#(#(seconds, ms), input)) - } -} - -fn parse_number_under_60(input: Tokens, expected: String) -> Parsed(Int) { - case input { - ["0", "0", ..input] -> Ok(#(0, input)) - ["0", "1", ..input] -> Ok(#(1, input)) - ["0", "2", ..input] -> Ok(#(2, input)) - ["0", "3", ..input] -> Ok(#(3, input)) - ["0", "4", ..input] -> Ok(#(4, input)) - ["0", "5", ..input] -> Ok(#(5, input)) - ["0", "6", ..input] -> Ok(#(6, input)) - ["0", "7", ..input] -> Ok(#(7, input)) - ["0", "8", ..input] -> Ok(#(8, input)) - ["0", "9", ..input] -> Ok(#(9, input)) - ["1", "0", ..input] -> Ok(#(10, input)) - ["1", "1", ..input] -> Ok(#(11, input)) - ["1", "2", ..input] -> Ok(#(12, input)) - ["1", "3", ..input] -> Ok(#(13, input)) - ["1", "4", ..input] -> Ok(#(14, input)) - ["1", "5", ..input] -> Ok(#(15, input)) - ["1", "6", ..input] -> Ok(#(16, input)) - ["1", "7", ..input] -> Ok(#(17, input)) - ["1", "8", ..input] -> Ok(#(18, input)) - ["1", "9", ..input] -> Ok(#(19, input)) - ["2", "0", ..input] -> Ok(#(20, input)) - ["2", "1", ..input] -> Ok(#(21, input)) - ["2", "2", ..input] -> Ok(#(22, input)) - ["2", "3", ..input] -> Ok(#(23, input)) - ["2", "4", ..input] -> Ok(#(24, input)) - ["2", "5", ..input] -> Ok(#(25, input)) - ["2", "6", ..input] -> Ok(#(26, input)) - ["2", "7", ..input] -> Ok(#(27, input)) - ["2", "8", ..input] -> Ok(#(28, input)) - ["2", "9", ..input] -> Ok(#(29, input)) - ["3", "0", ..input] -> Ok(#(30, input)) - ["3", "1", ..input] -> Ok(#(31, input)) - ["3", "2", ..input] -> Ok(#(32, input)) - ["3", "3", ..input] -> Ok(#(33, input)) - ["3", "4", ..input] -> Ok(#(34, input)) - ["3", "5", ..input] -> Ok(#(35, input)) - ["3", "6", ..input] -> Ok(#(36, input)) - ["3", "7", ..input] -> Ok(#(37, input)) - ["3", "8", ..input] -> Ok(#(38, input)) - ["3", "9", ..input] -> Ok(#(39, input)) - ["4", "0", ..input] -> Ok(#(40, input)) - ["4", "1", ..input] -> Ok(#(41, input)) - ["4", "2", ..input] -> Ok(#(42, input)) - ["4", "3", ..input] -> Ok(#(43, input)) - ["4", "4", ..input] -> Ok(#(44, input)) - ["4", "5", ..input] -> Ok(#(45, input)) - ["4", "6", ..input] -> Ok(#(46, input)) - ["4", "7", ..input] -> Ok(#(47, input)) - ["4", "8", ..input] -> Ok(#(48, input)) - ["4", "9", ..input] -> Ok(#(49, input)) - ["5", "0", ..input] -> Ok(#(50, input)) - ["5", "1", ..input] -> Ok(#(51, input)) - ["5", "2", ..input] -> Ok(#(52, input)) - ["5", "3", ..input] -> Ok(#(53, input)) - ["5", "4", ..input] -> Ok(#(54, input)) - ["5", "5", ..input] -> Ok(#(55, input)) - ["5", "6", ..input] -> Ok(#(56, input)) - ["5", "7", ..input] -> Ok(#(57, input)) - ["5", "8", ..input] -> Ok(#(58, input)) - ["5", "9", ..input] -> Ok(#(59, input)) - - [g, ..] -> Error(Unexpected(g, expected)) - [] -> Error(Unexpected("EOF", expected)) - } -} - -fn parse_date(input: Tokens, year: Int) -> Parsed(Toml) { - case input { - ["0", "1", "-", ..input] -> parse_date_day(input, year, 1) - ["0", "2", "-", ..input] -> parse_date_day(input, year, 2) - ["0", "3", "-", ..input] -> parse_date_day(input, year, 3) - ["0", "4", "-", ..input] -> parse_date_day(input, year, 4) - ["0", "5", "-", ..input] -> parse_date_day(input, year, 5) - ["0", "6", "-", ..input] -> parse_date_day(input, year, 6) - ["0", "7", "-", ..input] -> parse_date_day(input, year, 7) - ["0", "8", "-", ..input] -> parse_date_day(input, year, 8) - ["0", "9", "-", ..input] -> parse_date_day(input, year, 9) - ["1", "0", "-", ..input] -> parse_date_day(input, year, 10) - ["1", "1", "-", ..input] -> parse_date_day(input, year, 11) - ["1", "2", "-", ..input] -> parse_date_day(input, year, 12) - - [g, ..] -> Error(Unexpected(g, "date month")) - [] -> Error(Unexpected("EOF", "date month")) - } -} - -fn parse_date_day(input: Tokens, year: Int, month: Int) -> Parsed(Toml) { - case input { - ["0", "1", ..input] -> parse_date_end(input, year, month, 1) - ["0", "2", ..input] -> parse_date_end(input, year, month, 2) - ["0", "3", ..input] -> parse_date_end(input, year, month, 3) - ["0", "4", ..input] -> parse_date_end(input, year, month, 4) - ["0", "5", ..input] -> parse_date_end(input, year, month, 5) - ["0", "6", ..input] -> parse_date_end(input, year, month, 6) - ["0", "7", ..input] -> parse_date_end(input, year, month, 7) - ["0", "8", ..input] -> parse_date_end(input, year, month, 8) - ["0", "9", ..input] -> parse_date_end(input, year, month, 9) - ["1", "0", ..input] -> parse_date_end(input, year, month, 10) - ["1", "1", ..input] -> parse_date_end(input, year, month, 11) - ["1", "2", ..input] -> parse_date_end(input, year, month, 12) - ["1", "3", ..input] -> parse_date_end(input, year, month, 13) - ["1", "4", ..input] -> parse_date_end(input, year, month, 14) - ["1", "5", ..input] -> parse_date_end(input, year, month, 15) - ["1", "6", ..input] -> parse_date_end(input, year, month, 16) - ["1", "7", ..input] -> parse_date_end(input, year, month, 17) - ["1", "8", ..input] -> parse_date_end(input, year, month, 18) - ["1", "9", ..input] -> parse_date_end(input, year, month, 19) - ["2", "0", ..input] -> parse_date_end(input, year, month, 20) - ["2", "1", ..input] -> parse_date_end(input, year, month, 21) - ["2", "2", ..input] -> parse_date_end(input, year, month, 22) - ["2", "3", ..input] -> parse_date_end(input, year, month, 23) - ["2", "4", ..input] -> parse_date_end(input, year, month, 24) - ["2", "5", ..input] -> parse_date_end(input, year, month, 25) - ["2", "6", ..input] -> parse_date_end(input, year, month, 26) - ["2", "7", ..input] -> parse_date_end(input, year, month, 27) - ["2", "8", ..input] -> parse_date_end(input, year, month, 28) - ["2", "9", ..input] -> parse_date_end(input, year, month, 29) - ["3", "0", ..input] -> parse_date_end(input, year, month, 30) - ["3", "1", ..input] -> parse_date_end(input, year, month, 31) - - [g, ..] -> Error(Unexpected(g, "date day")) - [] -> Error(Unexpected("EOF", "date day")) - } -} - -fn parse_date_end( - input: Tokens, - year: Int, - month: Int, - day: Int, -) -> Parsed(Toml) { - let date = DateValue(year, month, day) - case input { - [" ", ..input] | ["T", ..input] -> { - use time, input <- do(parse_time_value(input)) - use offset, input <- do(parse_offset(input)) - Ok(#(DateTime(DateTimeValue(date, time, offset)), input)) - } - - _ -> Ok(#(Date(date), input)) - } -} - -fn parse_offset(input: Tokens) -> Parsed(Offset) { - case input { - ["Z", ..input] -> Ok(#(Offset(Positive, 0, 0), input)) - ["+", ..input] -> parse_offset_hours(input, Positive) - ["-", ..input] -> parse_offset_hours(input, Negative) - _ -> Ok(#(Local, input)) - } -} - -fn parse_offset_hours(input: Tokens, sign: Sign) -> Parsed(Offset) { - use #(hours, minutes), input <- do(parse_hour_minute(input)) - Ok(#(Offset(sign, hours, minutes), input)) -} |