├── .github ├── CODEOWNERS ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── doclint-version.yml │ └── release.yml ├── .gitignore ├── .ide ├── README.md ├── idea-settings.jar └── img │ ├── idea-reformat-code.png │ └── idea-settings.png ├── .javadoc └── stylesheet.css ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── pom.xml ├── update_copyright.sh └── vavr ├── generator └── Generator.scala ├── pom.xml ├── src-gen ├── main │ └── java │ │ └── io │ │ └── vavr │ │ ├── API.java │ │ ├── CheckedFunction0.java │ │ ├── CheckedFunction1.java │ │ ├── CheckedFunction2.java │ │ ├── CheckedFunction3.java │ │ ├── CheckedFunction4.java │ │ ├── CheckedFunction5.java │ │ ├── CheckedFunction6.java │ │ ├── CheckedFunction7.java │ │ ├── CheckedFunction8.java │ │ ├── Function0.java │ │ ├── Function1.java │ │ ├── Function2.java │ │ ├── Function3.java │ │ ├── Function4.java │ │ ├── Function5.java │ │ ├── Function6.java │ │ ├── Function7.java │ │ ├── Function8.java │ │ ├── Tuple.java │ │ ├── Tuple0.java │ │ ├── Tuple1.java │ │ ├── Tuple2.java │ │ ├── Tuple3.java │ │ ├── Tuple4.java │ │ ├── Tuple5.java │ │ ├── Tuple6.java │ │ ├── Tuple7.java │ │ ├── Tuple8.java │ │ └── collection │ │ └── ArrayType.java └── test │ └── java │ └── io │ └── vavr │ ├── APITest.java │ ├── CheckedFunction0Test.java │ ├── CheckedFunction1Test.java │ ├── CheckedFunction2Test.java │ ├── CheckedFunction3Test.java │ ├── CheckedFunction4Test.java │ ├── CheckedFunction5Test.java │ ├── CheckedFunction6Test.java │ ├── CheckedFunction7Test.java │ ├── CheckedFunction8Test.java │ ├── Function0Test.java │ ├── Function1Test.java │ ├── Function2Test.java │ ├── Function3Test.java │ ├── Function4Test.java │ ├── Function5Test.java │ ├── Function6Test.java │ ├── Function7Test.java │ ├── Function8Test.java │ ├── Tuple0Test.java │ ├── Tuple1Test.java │ ├── Tuple2Test.java │ ├── Tuple3Test.java │ ├── Tuple4Test.java │ ├── Tuple5Test.java │ ├── Tuple6Test.java │ ├── Tuple7Test.java │ ├── Tuple8Test.java │ └── collection │ ├── HashMapOfEntriesTest.java │ ├── HashMultimapOfEntriesTest.java │ ├── LinkedHashMapOfEntriesTest.java │ ├── LinkedHashMultimapOfEntriesTest.java │ ├── TreeMapOfEntriesTest.java │ └── TreeMultimapOfEntriesTest.java └── src ├── main ├── java │ └── io │ │ └── vavr │ │ ├── $.java │ │ ├── CheckedConsumer.java │ │ ├── CheckedPredicate.java │ │ ├── CheckedRunnable.java │ │ ├── GwtIncompatible.java │ │ ├── Lazy.java │ │ ├── MatchError.java │ │ ├── Memoized.java │ │ ├── NotImplementedError.java │ │ ├── PartialFunction.java │ │ ├── Predicates.java │ │ ├── Value.java │ │ ├── collection │ │ ├── AbstractIterator.java │ │ ├── AbstractMultimap.java │ │ ├── AbstractQueue.java │ │ ├── Array.java │ │ ├── BitMappedTrie.java │ │ ├── BitSet.java │ │ ├── CharSeq.java │ │ ├── Collections.java │ │ ├── Comparators.java │ │ ├── Foldable.java │ │ ├── GwtIncompatible.java │ │ ├── HashArrayMappedTrie.java │ │ ├── HashMap.java │ │ ├── HashMultimap.java │ │ ├── HashSet.java │ │ ├── IndexedSeq.java │ │ ├── Iterator.java │ │ ├── JavaConverters.java │ │ ├── LinearSeq.java │ │ ├── LinkedHashMap.java │ │ ├── LinkedHashMultimap.java │ │ ├── LinkedHashSet.java │ │ ├── List.java │ │ ├── Map.java │ │ ├── Maps.java │ │ ├── Multimap.java │ │ ├── Multimaps.java │ │ ├── Ordered.java │ │ ├── PriorityQueue.java │ │ ├── Queue.java │ │ ├── RedBlackTree.java │ │ ├── Seq.java │ │ ├── Set.java │ │ ├── SortedMap.java │ │ ├── SortedMultimap.java │ │ ├── SortedSet.java │ │ ├── Stream.java │ │ ├── Traversable.java │ │ ├── Tree.java │ │ ├── TreeMap.java │ │ ├── TreeMultimap.java │ │ ├── TreeSet.java │ │ ├── Vector.java │ │ ├── package-info.java │ │ └── readme-contributing.md │ │ ├── concurrent │ │ ├── Future.java │ │ ├── FutureImpl.java │ │ ├── GwtIncompatible.java │ │ ├── Promise.java │ │ ├── Task.java │ │ ├── package-info.java │ │ └── readme-contributing.md │ │ ├── control │ │ ├── Either.java │ │ ├── GwtIncompatible.java │ │ ├── HashCodes.java │ │ ├── Option.java │ │ ├── Try.java │ │ ├── Validation.java │ │ └── package-info.java │ │ ├── package-info.java │ │ └── readme-contributing.md └── javadoc │ └── overview.html └── test ├── java ├── io │ └── vavr │ │ ├── AbstractValueTest.java │ │ ├── AssertionsExtensions.java │ │ ├── CheckedConsumerTest.java │ │ ├── CheckedPredicateTest.java │ │ ├── CheckedRunnableTest.java │ │ ├── IterableTest.java │ │ ├── JavaCollections.java │ │ ├── LazyTest.java │ │ ├── MatchErrorTest.java │ │ ├── MatchTest.java │ │ ├── OutputTester.java │ │ ├── PartialFunctionTest.java │ │ ├── PredicatesTest.java │ │ ├── Serializables.java │ │ ├── TestComparators.java │ │ ├── TupleTest.java │ │ ├── ValueTest.java │ │ ├── collection │ │ ├── AbstractIndexedSeqTest.java │ │ ├── AbstractLinearSeqTest.java │ │ ├── AbstractMapTest.java │ │ ├── AbstractMultimapTest.java │ │ ├── AbstractSeqTest.java │ │ ├── AbstractSetTest.java │ │ ├── AbstractSortedMapTest.java │ │ ├── AbstractSortedSetTest.java │ │ ├── AbstractTraversableRangeTest.java │ │ ├── AbstractTraversableTest.java │ │ ├── ArrayTest.java │ │ ├── BitSetTest.java │ │ ├── CharSeqTest.java │ │ ├── CollectionsTest.java │ │ ├── ComparatorsTest.java │ │ ├── HashArrayMappedTrieTest.java │ │ ├── HashMapTest.java │ │ ├── HashMultimapTest.java │ │ ├── HashSetTest.java │ │ ├── IntMap.java │ │ ├── IntMod2.java │ │ ├── IntMod2Test.java │ │ ├── IntMultimap.java │ │ ├── IteratorTest.java │ │ ├── JavaConvertersTest.java │ │ ├── LinkedHashMapTest.java │ │ ├── LinkedHashMultimapTest.java │ │ ├── LinkedHashSetTest.java │ │ ├── ListTest.java │ │ ├── PriorityQueueTest.java │ │ ├── QueueTest.java │ │ ├── QuickSortTest.java │ │ ├── RedBlackTreeTest.java │ │ ├── StreamTest.java │ │ ├── StringTest.java │ │ ├── TreeMapTest.java │ │ ├── TreeMultimapTest.java │ │ ├── TreeSetTest.java │ │ ├── TreeTest.java │ │ ├── VectorPropertyTest.java │ │ ├── VectorTest.java │ │ └── euler │ │ │ ├── Euler01Test.java │ │ │ ├── Euler02Test.java │ │ │ ├── Euler03Test.java │ │ │ ├── Euler04Test.java │ │ │ ├── Euler05Test.java │ │ │ ├── Euler06Test.java │ │ │ ├── Euler07Test.java │ │ │ ├── Euler08Test.java │ │ │ ├── Euler09Test.java │ │ │ ├── Euler10Test.java │ │ │ ├── Euler11Test.java │ │ │ ├── Euler12Test.java │ │ │ ├── Euler13Test.java │ │ │ ├── Euler14Test.java │ │ │ ├── Euler15Test.java │ │ │ ├── Euler16Test.java │ │ │ ├── Euler17Test.java │ │ │ ├── Euler18Test.java │ │ │ ├── Euler19Test.java │ │ │ ├── Euler20Test.java │ │ │ ├── Euler21Test.java │ │ │ ├── Euler22Test.java │ │ │ ├── Euler23Test.java │ │ │ ├── Euler24Test.java │ │ │ ├── Euler25Test.java │ │ │ ├── Euler26Test.java │ │ │ ├── Euler27Test.java │ │ │ ├── Euler28Test.java │ │ │ ├── Euler29Test.java │ │ │ ├── Euler30Test.java │ │ │ ├── Euler31Test.java │ │ │ ├── Euler32Test.java │ │ │ ├── Euler33Test.java │ │ │ ├── Euler34Test.java │ │ │ ├── Euler35Test.java │ │ │ ├── Euler36Test.java │ │ │ ├── Euler37Test.java │ │ │ ├── Euler38Test.java │ │ │ ├── Euler39Test.java │ │ │ ├── Euler40Test.java │ │ │ ├── Euler41Test.java │ │ │ ├── Euler42Test.java │ │ │ ├── Euler43Test.java │ │ │ ├── Euler45Test.java │ │ │ ├── Euler48Test.java │ │ │ ├── Euler55Test.java │ │ │ ├── Euler57Test.java │ │ │ ├── Euler67Test.java │ │ │ ├── Euler71Test.java │ │ │ ├── Euler99Test.java │ │ │ ├── PrimeNumbers.java │ │ │ ├── Sieve.java │ │ │ └── Utils.java │ │ ├── concurrent │ │ ├── Concurrent.java │ │ ├── FutureTest.java │ │ └── PromiseTest.java │ │ ├── control │ │ ├── EitherLeftProjectionTest.java │ │ ├── EitherRightProjectionTest.java │ │ ├── EitherTest.java │ │ ├── OptionTest.java │ │ ├── TryTest.java │ │ └── ValidationTest.java │ │ └── issues │ │ └── Issue2559Test.java └── outside_of_vavr │ └── IllegalAccessErrorTest.java └── resources ├── io └── vavr │ └── collection │ └── euler │ ├── p013_numbers.txt │ ├── p018_triangle.txt │ ├── p022_names.txt │ ├── p042_words.txt │ ├── p067_triangle.txt │ ├── p099_base_exp.txt │ └── small_triangle.txt └── junit-platform.properties /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @pivovarit 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [pivovarit] 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | target-branch: "main" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | time: "02:00" 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | target-branch: "main" 12 | schedule: 13 | interval: "daily" 14 | time: "02:00" 15 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | java: [ '8', '11', '17', '21', '24'] 16 | architecture: [ 'x64' ] 17 | fail-fast: false 18 | name: Build with JDK ${{ matrix.java }} on ${{ matrix.architecture }} 19 | steps: 20 | - uses: actions/checkout@v4 21 | - name: Setup JDK 22 | uses: actions/setup-java@v4 23 | with: 24 | distribution: 'temurin' 25 | java-version: ${{ matrix.java }} 26 | architecture: ${{ matrix.architecture }} 27 | cache: 'maven' 28 | 29 | - name: Build with Maven 30 | run: mvn test 31 | 32 | deploy-snapshot: 33 | runs-on: ubuntu-latest 34 | needs: build 35 | if: github.ref == 'refs/heads/main' 36 | 37 | steps: 38 | - uses: actions/checkout@v4 39 | - name: Setup JDK 40 | uses: actions/setup-java@v4 41 | with: 42 | distribution: 'temurin' 43 | java-version: '21' 44 | cache: 'maven' 45 | server-id: central 46 | server-username: CENTRAL_USERNAME 47 | server-password: CENTRAL_PASSWORD 48 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 49 | 50 | - name: Deploy Snapshot 51 | run: mvn -B --no-transfer-progress -Psonatype-oss-release -Prelease-sign-artifacts -DskipTests=true deploy 52 | env: 53 | CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} 54 | CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} 55 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 56 | -------------------------------------------------------------------------------- /.github/workflows/doclint-version.yml: -------------------------------------------------------------------------------- 1 | name: doclint 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | doc-lint: 12 | runs-on: ubuntu-latest 13 | name: Validate JavaDocs 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Setup JDK 17 | uses: actions/setup-java@v4 18 | with: 19 | distribution: 'temurin' 20 | java-version: '21' 21 | architecture: 'x64' 22 | cache: 'maven' 23 | 24 | - name: Validate JavaDocs 25 | run: mvn javadoc:javadoc 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | release-tag: 6 | description: 'Version to release' 7 | required: true 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | java: [ '21' ] 15 | architecture: [ 'x64' ] 16 | 17 | name: Release ${{ github.event.inputs.release-tag }} 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | ref: ${{ github.event.inputs.release-tag }} 22 | 23 | - name: Setup JDK 24 | uses: actions/setup-java@v4 25 | with: 26 | distribution: 'oracle' 27 | java-version: ${{ matrix.java }} 28 | architecture: ${{ matrix.architecture }} 29 | cache: 'maven' 30 | server-id: oss.sonatype.org 31 | server-username: MAVEN_USERNAME 32 | server-password: MAVEN_PASSWORD 33 | gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} 34 | gpg-passphrase: MAVEN_GPG_PASSPHRASE 35 | 36 | 37 | - name: Release with Maven 38 | run: mvn -B --no-transfer-progress -Psonatype-oss-release -Prelease-sign-artifacts -DskipTests=true deploy 39 | env: 40 | MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} 41 | MAVEN_PASSWORD: ${{ secrets.OSSRH_TOKEN }} 42 | MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} 43 | MAVEN_OPTS: "--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED" 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # -- Maven 2 | target 3 | *.versionsBackup 4 | 5 | # -- Gradle 6 | .gradle 7 | build 8 | 9 | # -- Eclipse 10 | .classpath 11 | .project 12 | .settings 13 | bin 14 | 15 | # -- IntelliJ IDEA 16 | .idea 17 | *.iml 18 | 19 | # -- Visual Studio Code 20 | .vscode 21 | 22 | # -- Mac OS 23 | .DS_Store 24 | *.log 25 | 26 | # -- Java 27 | hs_err_pid* 28 | *.class 29 | 30 | # -- Emacs 31 | .#* 32 | -------------------------------------------------------------------------------- /.ide/README.md: -------------------------------------------------------------------------------- 1 | IntelliJ IDEA 2 | ------------- 3 | 4 | The following IntelliJ IDEA settings contained: 5 | 6 | ![Export Settings](./img/idea-settings.png) 7 | 8 | We reformat only .java files. 9 | 10 | ![Reformat Code](./img/idea-reformat-code.png) 11 | 12 | After the code is reformatted we have to generate sources: 13 | 14 | ```bash 15 | mvn clean package -DskipTests 16 | ``` 17 | -------------------------------------------------------------------------------- /.ide/idea-settings.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vavr-io/vavr/5f74ea84037efc88c58679adbe1709883b1b43ce/.ide/idea-settings.jar -------------------------------------------------------------------------------- /.ide/img/idea-reformat-code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vavr-io/vavr/5f74ea84037efc88c58679adbe1709883b1b43ce/.ide/img/idea-reformat-code.png -------------------------------------------------------------------------------- /.ide/img/idea-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vavr-io/vavr/5f74ea84037efc88c58679adbe1709883b1b43ce/.ide/img/idea-settings.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vavr 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT) 4 | [![GitHub Release](https://img.shields.io/github/release/vavr-io/vavr.svg?style=flat-square)](https://github.com/vavr-io/vavr/releases) 5 | ![Maven Central Version](https://img.shields.io/maven-central/v/io.vavr/vavr?versionPrefix=0) 6 | [![Build Status](https://github.com/vavr-io/vavr/actions/workflows/ci.yml/badge.svg)](https://github.com/vavr-io/vavr/actions/workflows/ci.yml) 7 | [![Code Coverage](https://codecov.io/gh/vavr-io/vavr/branch/master/graph/badge.svg)](https://codecov.io/gh/vavr-io/vavr) 8 | 9 | ```text 10 | ____ ______________ ________________________ __________ 11 | \ \/ / \ \/ / __/ / \ \/ / \ 12 | \______/___/\___\______/___/_____/___/\___\______/___/\___\ 13 | ``` 14 | 15 | Vavr is an **object-functional extension for Java that reduces boilerplate code and enhances code quality.** 16 | 17 | Vavr seamlessly combines object-oriented programming with the elegance and robustness of functional programming. 18 | 19 | It provides: 20 | * persistent collections 21 | * functional abstractions for error handling, concurrent programming 22 | * pattern matching 23 | * ...and more 24 | 25 | Since **Vavr has no dependencies** beyond the JVM, you can easily add it as a standalone .jar to your classpath. 26 | 27 | ### Stargazers over time 28 | [![Stargazers over time](https://starchart.cc/vavr-io/vavr.svg?variant=adaptive)](https://starchart.cc/vavr-io/vavr) 29 | 30 | ### Maven Dependency 31 | 32 | 33 | io.vavr 34 | vavr 35 | 0.10.6 36 | 37 | 38 | ### Gradle Dependency 39 | 40 | implementation 'io.vavr:vavr:0.10.6' 41 | 42 | ## Using Vavr 43 | 44 | See [User Guide](http://docs.vavr.io) and/or [Javadoc](http://www.javadoc.io/doc/io.vavr/vavr). 45 | 46 | ### Useful Maven Goals 47 | 48 | * Executing tests: `mvn clean test` 49 | * Executing doclint: `mvn javadoc:javadoc` 50 | * Executing code coverage report: `mvn -P ci clean test jacoco:report` 51 | * Create -javadoc.jar: `mvn javadoc:jar` 52 | * Create -source.jar: `mvn source:jar` 53 | 54 | ### Contributing 55 | 56 | Currently, there are two significant branches: 57 | - `main` (represents a stream of work leading to the release of a new ma version) 58 | - `version/1.x` (historical work that went into `1.0.0-alpha-3`, treat is as read-only - will be kept around for cherry-picking) 59 | 60 | A small number of users have reported problems building Vavr. Read our [contribution guide](./CONTRIBUTING.md) for details. 61 | -------------------------------------------------------------------------------- /update_copyright.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # == 4 | # == New-year script, tested on a Mac 5 | # == 6 | 7 | # Prevent sed error 'illegal byte sequence' 8 | export LC_ALL=C LC_CTYPE=C LANG=C 9 | 10 | newYear=$(date +'%Y') 11 | echo "Updating copyright notice to $newYear" 12 | 13 | # Exclude specific directories: -type d \( -path ./.git -o -path ./.ide \) -prune -o 14 | # Make sed work on Mac: sed -e 15 | # Prevent making backups: -i '' 16 | find . -type d \( -path ./.git -o -path ./.ide \) -prune -o -type f -print0 | xargs -0 sed -i '' -e "s/Copyright 2014-2025 Vavr/Copyright 2014-$newYear Vavr/" 17 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/$.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.concurrent.Future; 23 | import io.vavr.control.Either; 24 | import io.vavr.control.Option; 25 | import io.vavr.control.Try; 26 | import io.vavr.control.Validation; 27 | import io.vavr.match.annotation.Patterns; 28 | import io.vavr.match.annotation.Unapply; 29 | 30 | /** 31 | * INTERNAL TYPE - turned to io.vavr.Patterns by vavr-match annotation processor. 32 | */ 33 | @Patterns 34 | class $ { 35 | 36 | // -- io.vavr 37 | 38 | // Tuple0-N 39 | @Unapply 40 | static Tuple0 Tuple0(Tuple0 tuple0) { return tuple0; } 41 | @Unapply 42 | static Tuple1 Tuple1(Tuple1 tuple1) { return tuple1; } 43 | @Unapply 44 | static Tuple2 Tuple2(Tuple2 tuple2) { return tuple2; } 45 | @Unapply 46 | static Tuple3 Tuple3(Tuple3 tuple3) { return tuple3; } 47 | @Unapply 48 | static Tuple4 Tuple4(Tuple4 tuple4) { return tuple4; } 49 | @Unapply 50 | static Tuple5 Tuple5(Tuple5 tuple5) { return tuple5; } 51 | @Unapply 52 | static Tuple6 Tuple6(Tuple6 tuple6) { return tuple6; } 53 | @Unapply 54 | static Tuple7 Tuple7(Tuple7 tuple7) { return tuple7; } 55 | @Unapply 56 | static Tuple8 Tuple8(Tuple8 tuple8) { return tuple8; } 57 | 58 | // -- io.vavr.collection 59 | 60 | // List 61 | @Unapply 62 | static Tuple2> Cons(List.Cons cons) { return Tuple.of(cons.head(), cons.tail()); } 63 | @Unapply 64 | static Tuple0 Nil(List.Nil nil) { return Tuple.empty(); } 65 | 66 | // -- io.vavr.concurrent 67 | 68 | @Unapply 69 | static Tuple1>> Future(Future future) { return Tuple.of(future.getValue()); } 70 | 71 | // -- io.vavr.control 72 | 73 | // Either 74 | @Unapply 75 | static Tuple1 Right(Either.Right right) { return Tuple.of(right.get()); } 76 | @Unapply 77 | static Tuple1 Left(Either.Left left) { return Tuple.of(left.getLeft()); } 78 | 79 | // Option 80 | @Unapply 81 | static Tuple1 Some(Option.Some some) { return Tuple.of(some.get()); } 82 | @Unapply 83 | static Tuple0 None(Option.None none) { return Tuple.empty(); } 84 | 85 | // Try 86 | @Unapply 87 | static Tuple1 Success(Try.Success success) { return Tuple.of(success.get()); } 88 | @Unapply 89 | static Tuple1 Failure(Try.Failure failure) { return Tuple.of(failure.getCause()); } 90 | 91 | // Validation 92 | @Unapply 93 | static Tuple1 Valid(Validation.Valid valid) { return Tuple.of(valid.get()); } 94 | @Unapply 95 | static Tuple1 Invalid(Validation.Invalid invalid) { return Tuple.of(invalid.getError()); } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/CheckedConsumer.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.Objects; 22 | import java.util.function.Consumer; 23 | 24 | import static io.vavr.CheckedConsumerModule.sneakyThrow; 25 | 26 | /** 27 | * A consumer that may throw, equivalent to {@linkplain java.util.function.Consumer}. 28 | * 29 | * @param the value type supplied to this consumer. 30 | */ 31 | @FunctionalInterface 32 | public interface CheckedConsumer { 33 | 34 | /** 35 | * Creates a {@code CheckedConsumer}. 36 | * 37 | *
{@code
 38 |      * final CheckedConsumer checkedConsumer = CheckedConsumer.of(Value::stdout);
 39 |      * final Consumer consumer = checkedConsumer.unchecked();
 40 |      *
 41 |      * // prints "Hi" on the console
 42 |      * consumer.accept(CharSeq.of("Hi!"));
 43 |      *
 44 |      * // throws
 45 |      * consumer.accept(null);
 46 |      * }
47 | * 48 | * @param methodReference (typically) a method reference, e.g. {@code Type::method} 49 | * @param type of values that are accepted by the consumer 50 | * @return a new {@code CheckedConsumer} 51 | * @see CheckedFunction1#of(CheckedFunction1) 52 | */ 53 | static CheckedConsumer of(CheckedConsumer methodReference) { 54 | return methodReference; 55 | } 56 | 57 | /** 58 | * Performs side-effects. 59 | * 60 | * @param t a value of type {@code T} 61 | * @throws Throwable if an error occurs 62 | */ 63 | void accept(T t) throws Throwable; 64 | 65 | /** 66 | * Returns a chained {@code CheckedConsumer} that first executes {@code this.accept(t)} 67 | * and then {@code after.accept(t)}, for a given {@code t} of type {@code T}. 68 | * 69 | * @param after the action that will be executed after this action 70 | * @return a new {@code CheckedConsumer} that chains {@code this} and {@code after} 71 | * @throws NullPointerException if {@code after} is null 72 | */ 73 | default CheckedConsumer andThen(CheckedConsumer after) { 74 | Objects.requireNonNull(after, "after is null"); 75 | return (T t) -> { accept(t); after.accept(t); }; 76 | } 77 | 78 | /** 79 | * Returns an unchecked {@link Consumer} that will sneaky throw if an exceptions occurs when accepting a value. 80 | * 81 | * @return a new {@link Consumer} that throws a {@code Throwable}. 82 | */ 83 | default Consumer unchecked() { 84 | return t -> { 85 | try { 86 | accept(t); 87 | } catch(Throwable x) { 88 | sneakyThrow(x); 89 | } 90 | }; 91 | } 92 | } 93 | 94 | interface CheckedConsumerModule { 95 | 96 | // DEV-NOTE: we do not plan to expose this as public API 97 | @SuppressWarnings("unchecked") 98 | static R sneakyThrow(Throwable t) throws T { 99 | throw (T) t; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/CheckedPredicate.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.function.Predicate; 22 | 23 | import static io.vavr.CheckedPredicateModule.sneakyThrow; 24 | 25 | /** 26 | * A {@linkplain java.util.function.Predicate} which may throw. 27 | * 28 | * @param the type of the input to the predicate 29 | */ 30 | @FunctionalInterface 31 | public interface CheckedPredicate { 32 | 33 | /** 34 | * Creates a {@code CheckedPredicate}. 35 | * 36 | *
{@code
37 |      * final CheckedPredicate checkedPredicate = CheckedPredicate.of(Boolean::booleanValue);
38 |      * final Predicate predicate = checkedPredicate.unchecked();
39 |      *
40 |      * // = true
41 |      * predicate.test(Boolean.TRUE);
42 |      *
43 |      * // throws
44 |      * predicate.test(null);
45 |      * }
46 | * 47 | * @param methodReference (typically) a method reference, e.g. {@code Type::method} 48 | * @param type of values that are tested by the predicate 49 | * @return a new {@code CheckedPredicate} 50 | * @see CheckedFunction1#of(CheckedFunction1) 51 | */ 52 | static CheckedPredicate of(CheckedPredicate methodReference) { 53 | return methodReference; 54 | } 55 | 56 | /** 57 | * Evaluates this predicate on the given argument. 58 | * 59 | * @param t the input argument 60 | * @return {@code true} if the input argument matches the predicate, otherwise {@code false} 61 | * @throws Throwable if an error occurs 62 | */ 63 | boolean test(T t) throws Throwable; 64 | 65 | /** 66 | * Negates this predicate. 67 | * 68 | * @return A new CheckedPredicate. 69 | */ 70 | default CheckedPredicate negate() { 71 | return t -> !test(t); 72 | } 73 | 74 | /** 75 | * Returns an unchecked {@link Predicate} that will sneaky throw if an exceptions occurs when testing a value. 76 | * 77 | * @return a new {@link Predicate} that throws a {@code Throwable}. 78 | */ 79 | default Predicate unchecked() { 80 | return t -> { 81 | try { 82 | return test(t); 83 | } catch(Throwable x) { 84 | return sneakyThrow(x); 85 | } 86 | }; 87 | } 88 | } 89 | 90 | interface CheckedPredicateModule { 91 | 92 | // DEV-NOTE: we do not plan to expose this as public API 93 | @SuppressWarnings("unchecked") 94 | static R sneakyThrow(Throwable t) throws T { 95 | throw (T) t; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/CheckedRunnable.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import static io.vavr.CheckedRunnableModule.sneakyThrow; 22 | 23 | /** 24 | * A {@linkplain Runnable} which may throw. 25 | */ 26 | @FunctionalInterface 27 | public interface CheckedRunnable { 28 | 29 | /** 30 | * Creates a {@code CheckedRunnable}. 31 | * 32 | *
{@code
33 |      * // class Evil { static void sideEffect() { ... } }
34 |      * final CheckedRunnable checkedRunnable = CheckedRunnable.of(Evil::sideEffect);
35 |      * final Runnable runnable = checkedRunnable.unchecked();
36 |      *
37 |      * // may or may not perform a side-effect while not throwing
38 |      * runnable.run();
39 |      *
40 |      * // may or may not perform a side-effect while throwing
41 |      * runnable.run();
42 |      * }
43 | * 44 | * @param methodReference (typically) a method reference, e.g. {@code Type::method} 45 | * @return a new {@code CheckedRunnable} 46 | * @see CheckedFunction1#of(CheckedFunction1) 47 | */ 48 | static CheckedRunnable of(CheckedRunnable methodReference) { 49 | return methodReference; 50 | } 51 | 52 | /** 53 | * Performs side-effects. 54 | * 55 | * @throws Throwable if an error occurs 56 | */ 57 | void run() throws Throwable; 58 | 59 | /** 60 | * Returns an unchecked {@link Runnable} that will sneaky throw if an exceptions occurs when running the unit of work. 61 | * 62 | * @return a new {@link Runnable} that throws a {@code Throwable}. 63 | */ 64 | default Runnable unchecked() { 65 | return () -> { 66 | try { 67 | run(); 68 | } catch(Throwable x) { 69 | sneakyThrow(x); 70 | } 71 | }; 72 | } 73 | } 74 | 75 | interface CheckedRunnableModule { 76 | 77 | // DEV-NOTE: we do not plan to expose this as public API 78 | @SuppressWarnings("unchecked") 79 | static R sneakyThrow(Throwable t) throws T { 80 | throw (T) t; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/GwtIncompatible.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2018 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.lang.annotation.*; 22 | 23 | @Retention(RetentionPolicy.CLASS) 24 | @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD }) 25 | @Documented 26 | @interface GwtIncompatible { 27 | String value() default ""; 28 | } 29 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/MatchError.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.NoSuchElementException; 22 | 23 | /** 24 | * A {@link API.Match} throws a MatchError if no case matches the applied object. 25 | * 26 | * @author Daniel Dietrich 27 | */ 28 | public class MatchError extends NoSuchElementException { 29 | 30 | private static final long serialVersionUID = 1L; 31 | 32 | @SuppressWarnings("serial") // Conditionally serializable 33 | private final Object obj; 34 | 35 | /** 36 | * Internally called by {@link API.Match}. 37 | * 38 | * @param obj The object which could not be matched. 39 | */ 40 | MatchError(Object obj) { 41 | super((obj == null) ? "null" : "type: " + obj.getClass().getName() + ", value: " + obj); 42 | this.obj = obj; 43 | } 44 | 45 | /** 46 | * Returns the object which could not be matched. 47 | * 48 | * @return An Object. 49 | */ 50 | public Object getObject() { 51 | return obj; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/Memoized.java: -------------------------------------------------------------------------------- 1 | package io.vavr; 2 | 3 | /** 4 | * INTERNAL. Zero abstract method (ZAM) / tagging interface. 5 | */ 6 | interface Memoized { 7 | } 8 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/NotImplementedError.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | /** 22 | * This exception is temporarily used during development in order to indicate that an implementation is missing. 23 | *

24 | * The idiomatic way is to use one of {@link API#TODO()} and {@link API#TODO(String)}. 25 | */ 26 | public class NotImplementedError extends Error { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | /** 31 | * Creates a {@code NotImplementedError} containing the message "an implementation is missing". 32 | */ 33 | public NotImplementedError() { 34 | super("An implementation is missing."); 35 | } 36 | 37 | /** 38 | * Creates a {@code NotImplementedError} containing the given {@code message}. 39 | * 40 | * @param message A text that describes the error 41 | */ 42 | public NotImplementedError(String message) { 43 | super(message); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/AbstractIterator.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.util.NoSuchElementException; 22 | 23 | /** 24 | * Provides a common {@link Object#toString()} implementation. 25 | *

26 | * {@code equals(Object)} and {@code hashCode()} are intentionally not overridden in order to prevent this iterator 27 | * from being evaluated. In other words, (identity-)equals and hashCode are implemented by Object. 28 | * 29 | * @param Component type 30 | * @author Daniel Dietrich 31 | */ 32 | abstract class AbstractIterator implements Iterator { 33 | 34 | @Override 35 | public String toString() { 36 | return stringPrefix() + "(" + (isEmpty() ? "" : "?") + ")"; 37 | } 38 | 39 | protected abstract T getNext(); 40 | 41 | @Override 42 | public final T next() { 43 | if (!hasNext()) { 44 | throw new NoSuchElementException("next() on empty iterator"); 45 | } 46 | return getNext(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/Comparators.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.io.Serializable; 22 | import java.util.Comparator; 23 | 24 | /** 25 | * INTERNAL: Common {@code Comparator} related functions (not intended to be public). 26 | * 27 | * @author Daniel Dietrich 28 | */ 29 | final class Comparators { 30 | 31 | private Comparators() { 32 | } 33 | 34 | /** 35 | * Returns the natural comparator for type U, i.e. treating it as {@code Comparable}. 36 | * The returned comparator is also {@code java.io.Serializable}. 37 | *

38 | * Please note that this will lead to runtime exceptions, if U is not Comparable. 39 | * 40 | * @param The type 41 | * @return The natural Comparator of type U 42 | */ 43 | @SuppressWarnings("unchecked") 44 | static Comparator naturalComparator() { 45 | return NaturalComparator.instance(); 46 | } 47 | } 48 | 49 | final class NaturalComparator implements Comparator, Serializable { 50 | 51 | private static final long serialVersionUID = 1L; 52 | 53 | private static final NaturalComparator INSTANCE = new NaturalComparator<>(); 54 | 55 | private NaturalComparator() { 56 | } 57 | 58 | @SuppressWarnings("unchecked") 59 | static NaturalComparator instance() { 60 | return (NaturalComparator) INSTANCE; 61 | } 62 | 63 | @SuppressWarnings("unchecked") 64 | @Override 65 | public int compare(T o1, T o2) { 66 | return ((Comparable) o1).compareTo(o2); 67 | } 68 | 69 | /** @see Comparator#equals(Object) */ 70 | @Override 71 | public boolean equals(Object obj) { 72 | return obj instanceof NaturalComparator; 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | return 1; 78 | } 79 | 80 | /** 81 | * Instance control for object serialization. 82 | * 83 | * @return The singleton instance of NaturalComparator. 84 | * @see java.io.Serializable 85 | */ 86 | private Object readResolve() { 87 | return INSTANCE; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/GwtIncompatible.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.lang.annotation.*; 22 | 23 | @Retention(RetentionPolicy.CLASS) 24 | @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD }) 25 | @Documented 26 | @interface GwtIncompatible { 27 | String value() default ""; 28 | } 29 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/Multimaps.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import io.vavr.Tuple2; 22 | import java.util.Objects; 23 | import java.util.function.Function; 24 | 25 | /** 26 | * INTERNAL: Common {@code Multimap} functions (not intended to be public). 27 | * 28 | * @author Ruslan Sennov, Daniel Dietrich 29 | */ 30 | class Multimaps { 31 | 32 | @SuppressWarnings("unchecked") 33 | static > M ofJavaMap(M source, java.util.Map map) { 34 | Objects.requireNonNull(map, "map is null"); 35 | return Stream.ofAll(map.entrySet()).foldLeft(source, (m, el) -> (M) m.put(el.getKey(), el.getValue())); 36 | } 37 | 38 | @SuppressWarnings("unchecked") 39 | static > M ofStream(M source, java.util.stream.Stream stream, 40 | Function keyMapper, 41 | Function valueMapper) { 42 | Objects.requireNonNull(stream, "stream is null"); 43 | Objects.requireNonNull(keyMapper, "keyMapper is null"); 44 | Objects.requireNonNull(valueMapper, "valueMapper is null"); 45 | return Stream.ofAll(stream).foldLeft(source, (m, el) -> (M) m.put(keyMapper.apply(el), valueMapper.apply(el))); 46 | } 47 | 48 | @SuppressWarnings("unchecked") 49 | static > M ofStream(M source, java.util.stream.Stream stream, 50 | Function> entryMapper) { 51 | Objects.requireNonNull(stream, "stream is null"); 52 | Objects.requireNonNull(entryMapper, "entryMapper is null"); 53 | return Stream.ofAll(stream).foldLeft(source, (m, el) -> (M) m.put(entryMapper.apply(el))); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/Ordered.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.util.Comparator; 22 | 23 | /** 24 | * An ordered collection interface. 25 | * 26 | * @param Component type 27 | * @author Ruslan Sennov, Daniel Dietrich 28 | */ 29 | public interface Ordered { 30 | 31 | /** 32 | * Returns the comparator which defines the order of the elements contained in this collection. 33 | * 34 | * @return The comparator that defines the order of this collection's elements. 35 | */ 36 | Comparator comparator(); 37 | } 38 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/collection/readme-contributing.md: -------------------------------------------------------------------------------- 1 | We need to follow some conventions to keep the collections consistent. 2 | 3 | There are two kinds of methods 4 | 5 | - **Accessors** access some of the elements of a collection, but return a result which is unrelated to the collection. 6 | Example of accessors are: head, foldLeft, toList. 7 | 8 | - **Transformers** access elements of a collection and produce a new collection of same type as a result. 9 | Example of transformers are: filter, map, groupBy, zip. 10 | 11 | Given this, our _transformers_ should return the most specific type, e.g. `HashMap.map(...)` should return `HashMap`. E.g. `zipWithIndex` is also a transformer. 12 | 13 | Our _accessors_ should return an interface instead to keep our library extensible for future enhancements. E.g. `HashMap.groupBy` should return `Map` because we may decide in future that returning another Map implementation than HashMap is more efficient. Returning now HashMap would break API on future changes. The only disadvantage is that Map's methods have generic parameters with wildcards, which reduces usability slightly. 14 | 15 | More specific, methods like `Seq.combinations()` or `Seq.crossProduct()` should return `Seq`. This applies also to subclasses of `Seq`. E.g. `CharSeq.combinations()` should also return `Seq`. Of course the concrete object returned remains `Vector` (for CharSeq). 16 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/concurrent/GwtIncompatible.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2018 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.concurrent; 20 | 21 | import java.lang.annotation.*; 22 | 23 | @Retention(RetentionPolicy.CLASS) 24 | @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD }) 25 | @Documented 26 | @interface GwtIncompatible { 27 | String value() default ""; 28 | } 29 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/concurrent/Task.java: -------------------------------------------------------------------------------- 1 | package io.vavr.concurrent; 2 | 3 | import io.vavr.control.Try; 4 | 5 | /** 6 | * Represents a possibly asynchronous unit of work, called "Task". 7 | *

8 | * A {@code Task} is a function that takes an instance of {@link Complete} and returns nothing. 9 | *

10 | * {@code Complete} is a handler that needs to be actively called to complete the {@code Task}. 11 | * 12 | *

{@code
13 |  * Callable worker = ...;
14 |  * Future result = Future.run(complete -> complete.with(Try.of(worker::call)));
15 |  * }
16 | * 17 | * @param result type 18 | * @deprecated Experimental API 19 | */ 20 | @Deprecated 21 | @FunctionalInterface 22 | public interface Task { 23 | 24 | /** 25 | * Runs the task. Non-fatal errors are catched by a {@link Future}. 26 | * 27 | * @param complete a function that completes this task 28 | * @throws Throwable if an error occurs 29 | */ 30 | void run(Complete complete) throws Throwable; 31 | 32 | /** 33 | * Completes a task. 34 | *

35 | * @param result type 36 | */ 37 | @FunctionalInterface 38 | interface Complete { 39 | 40 | /** 41 | * A function that takes a {@link Try} (success or failure) and returns the state of completion. 42 | * 43 | * @param value the computation result 44 | * @return {@code true}, if the task could be completed, otherwise {@code false}. 45 | * Successive calls will result in {@code false}. 46 | */ 47 | boolean with(Try value); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/concurrent/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package contains basic building blocks for creating fast, asynchronous, non-blocking parallel code. 3 | *

4 | * A {@linkplain io.vavr.concurrent.Future} represents an asynchronous task. It is a placeholder for a 5 | * value that becomes available at some point. With the help of {@code Future} we efficiently perform many non-blocking 6 | * operations in parallel. The value of a Future is supplied concurrently and can subsequently be used. Multiple 7 | * concurrent tasks represented by Futures can be composed to a single Future. 8 | */ 9 | package io.vavr.concurrent; 10 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/concurrent/readme-contributing.md: -------------------------------------------------------------------------------- 1 | These are the ideas behind the implementation of Future/Promise: 2 | 3 | The design follows separation of concerns in two manners: 4 | 5 | - public interfaces vs. internal implementations (Promise/PromiseImpl, Future/FutureImpl) 6 | - Future = read-only, Promise = write-once 7 | 8 | ### Interfaces vs. internal classes 9 | 10 | Concurrent programming is all about synchronized state. To keep this as simple as possible, it is a good idea to 11 | separate readable and writable state. The internal implementations encapsulate the state. Their number of methods 12 | drill down to those which access instance variables. These classes are typically very short. They represent a 13 | clean and easy to maintain, thread-safe core. 14 | 15 | The interfaces define, beside abstract methods, static factory methods, static extension methods and default methods. 16 | The default implementations are built on top of the tread-safe core mentioned above. Typically, no additional 17 | synchronization takes place here. 18 | 19 | ### Read-only vs. write-once 20 | 21 | Separating the end-user API into the Future interface, providing the read-only API, and the Promise interface, 22 | providing the write-once API, solves a different concurrency problem than state synchronization. By separating 23 | these concerns, we define a specific _programming model_ that allows us to easily deal with common tasks in 24 | concurrent programming. 25 | 26 | ```java 27 | final Promise promise = Promise.make(); 28 | final Future future = promise.future(); 29 | 30 | // producer 31 | Future.run(() -> { 32 | promise.success(produceSomething()); 33 | continueDoingSomethingUnrelated(); 34 | }); 35 | 36 | // consumer 37 | Future.run(() -> { 38 | startDoingSomething(); 39 | future.onSuccess(doSomethingWithResult); 40 | }); 41 | ``` 42 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/control/GwtIncompatible.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2018 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.control; 20 | 21 | import java.lang.annotation.*; 22 | 23 | @Retention(RetentionPolicy.CLASS) 24 | @Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD }) 25 | @Documented 26 | @interface GwtIncompatible { 27 | String value() default ""; 28 | } 29 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/control/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Control structures like the disjoint union type {@linkplain io.vavr.control.Either}, the optional value type 3 | * {@linkplain io.vavr.control.Option} and {@linkplain io.vavr.control.Try} for exception handling. 4 | *

5 | * Either 6 | *

7 | * The control package contains an implementation of the {@linkplain io.vavr.control.Either} control which is either Left or Right. 8 | * A given Either is projected to a Left or a Right. 9 | * Both cases can be further processed with control operations map, flatMap, filter. 10 | * If a Right is projected to a Left, the Left control operations have no effect on the Right value. 11 | * If a Left is projected to a Right, the Right control operations have no effect on the Left value. 12 | *

13 | * Option 14 | *

15 | * The Option control is a replacement for {@linkplain java.util.Optional}. An Option is either 16 | * {@linkplain io.vavr.control.Option.Some} value or {@linkplain io.vavr.control.Option.None}. 17 | * In contrast to Optional, Option supports null values, i.e. it is possible to call {@code new Some(null)}. 18 | * However, {@code Option.of(null)} results in None. 19 | *

20 | * Try 21 | *

22 | * Exceptions are handled with the {@linkplain io.vavr.control.Try} control which is either a 23 | * {@linkplain io.vavr.control.Try.Success}, containing a result, or a {@linkplain io.vavr.control.Try.Failure}, 24 | * containing an Exception. 25 | */ 26 | package io.vavr.control; 27 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Beside {@link io.vavr.API} the io.vavr package contains core types like (Checked)Functions and Tuples. 3 | */ 4 | package io.vavr; 5 | -------------------------------------------------------------------------------- /vavr/src/main/java/io/vavr/readme-contributing.md: -------------------------------------------------------------------------------- 1 | Please ensure that all major types but Functions, currently Tuples, Values and Traversables, have a `transform` method. 2 | 3 | Example (`TYPE` is replaced by the actual type): 4 | 5 | ```java 6 | /** 7 | * Transforms this {@code TYPE}. 8 | * 9 | * @param f A transformation 10 | * @param Type of transformation result 11 | * @return An instance of type {@code U} 12 | * @throws NullPointerException if {@code f} is null 13 | */ 14 | default U transform(Function, ? extends U> f) { 15 | Objects.requireNonNull(f, "f is null"); 16 | return f.apply(this); 17 | } 18 | ``` 19 | 20 | See also [#716](https://github.com/vavr-io/vavr/issues/716#issuecomment-163399633). 21 | -------------------------------------------------------------------------------- /vavr/src/main/javadoc/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | API Overview 5 | 6 | 7 |

This is the documentation for the Vavr library.

8 | 9 | 10 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/AssertionsExtensions.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.lang.reflect.Constructor; 22 | import org.assertj.core.api.Assertions; 23 | 24 | public final class AssertionsExtensions { 25 | 26 | private AssertionsExtensions() { 27 | } 28 | 29 | public static ClassAssert assertThat(Class clazz) { 30 | return new ClassAssert(clazz); 31 | } 32 | 33 | public static class ClassAssert { 34 | 35 | final Class clazz; 36 | 37 | ClassAssert(Class clazz) { 38 | this.clazz = clazz; 39 | } 40 | 41 | @SuppressWarnings("deprecation") 42 | public void isNotInstantiable() { 43 | try { 44 | final Constructor cons = clazz.getDeclaredConstructor(); 45 | Assertions.assertThat(cons.isAccessible()).isFalse(); 46 | } catch (NoSuchMethodException e) { 47 | throw new AssertionError("no default constructor found"); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/CheckedPredicateTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.function.Predicate; 22 | import org.junit.jupiter.api.Assertions; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class CheckedPredicateTest { 28 | 29 | // -- of 30 | 31 | @Test 32 | public void shouldCreateCheckedPredicateUsingLambda() { 33 | final CheckedPredicate predicate = CheckedPredicate.of(obj -> true); 34 | assertThat(predicate).isNotNull(); 35 | } 36 | 37 | @Test 38 | public void shouldCreateCheckedPredicateUsingMethodReference() { 39 | final CheckedPredicate predicate = CheckedPredicate.of(CheckedPredicateTest::test); 40 | assertThat(predicate).isNotNull(); 41 | } 42 | 43 | private static boolean test(Object obj) { 44 | return true; 45 | } 46 | 47 | // -- unchecked 48 | 49 | @Test 50 | public void shouldApplyAnUncheckedFunctionThatDoesNotThrow() { 51 | final Predicate preciate = CheckedPredicate.of(obj -> true).unchecked(); 52 | try { 53 | preciate.test(null); 54 | } catch(Throwable x) { 55 | Assertions.fail("Did not excepect an exception but received: " + x.getMessage()); 56 | } 57 | } 58 | 59 | @Test 60 | public void shouldApplyAnUncheckedFunctionThatThrows() { 61 | final Predicate preciate = CheckedPredicate.of(obj -> { throw new Error(); }).unchecked(); 62 | try { 63 | preciate.test(null); 64 | Assertions.fail("Did excepect an exception."); 65 | } catch(Error x) { 66 | // ok! 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/CheckedRunnableTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import org.junit.jupiter.api.Assertions; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class CheckedRunnableTest { 27 | 28 | // -- of 29 | 30 | @Test 31 | public void shouldCreateCheckedRunnableUsingLambda() { 32 | final CheckedRunnable runnable = CheckedRunnable.of(() -> {}); 33 | assertThat(runnable).isNotNull(); 34 | } 35 | 36 | @Test 37 | public void shouldCreateCheckedRunnableUsingMethodReference() { 38 | final CheckedRunnable runnable = CheckedRunnable.of(CheckedRunnableTest::run); 39 | assertThat(runnable).isNotNull(); 40 | } 41 | 42 | private static void run() { 43 | } 44 | 45 | // -- unchecked 46 | 47 | @Test 48 | public void shouldApplyAnUncheckedFunctionThatDoesNotThrow() { 49 | final Runnable runnable = CheckedRunnable.of(() -> {}).unchecked(); 50 | try { 51 | runnable.run(); 52 | } catch(Throwable x) { 53 | Assertions.fail("Did not expect an exception but received: " + x.getMessage()); 54 | } 55 | } 56 | 57 | @Test 58 | public void shouldApplyAnUncheckedFunctionThatThrows() { 59 | final Runnable runnable = CheckedRunnable.of(() -> { throw new Error(); }).unchecked(); 60 | Assertions.assertThrows(Error.class, () -> runnable.run()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/IterableTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.collection.Queue; 23 | import io.vavr.collection.Stream; 24 | import io.vavr.control.Option; 25 | import java.util.Arrays; 26 | import java.util.Collections; 27 | import org.junit.jupiter.api.Test; 28 | 29 | import static org.assertj.core.api.Assertions.assertThat; 30 | 31 | public class IterableTest { 32 | 33 | // -- eq 34 | 35 | @Test 36 | public void shouldEqNoneAndEmptyList() { 37 | assertThat(Option.none().eq(List.empty())).isTrue(); 38 | assertThat(Option.none().eq(List.of(1))).isFalse(); 39 | } 40 | 41 | @Test 42 | public void shouldEqSomeAndNonEmptyList() { 43 | assertThat(Option.some(1).eq(List.of(1))).isTrue(); 44 | assertThat(Option.some(1).eq(List.of(2))).isFalse(); 45 | assertThat(Option.some(1).eq(List.empty())).isFalse(); 46 | } 47 | 48 | @Test 49 | public void shouldEqIterableAndJavaIterable() { 50 | assertThat(List.of(1, 2, 3).eq(Arrays.asList(1, 2, 3))).isTrue(); 51 | } 52 | 53 | @Test 54 | public void shouldEqNestedIterables() { 55 | // ((1, 2), ((3))) 56 | final Value i1 = List.of(List.of(1, 2), Collections.singletonList(List.of(3))); 57 | final Value i2 = Queue.of(Stream.of(1, 2), List.of(Lazy.of(() -> 3))); 58 | final Value i3 = Queue.of(Stream.of(1, 2), List.of(List.of())); 59 | assertThat(i1.eq(i2)).isTrue(); 60 | assertThat(i1.eq(i3)).isFalse(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/JavaCollections.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.*; 22 | 23 | final class JavaCollections { 24 | 25 | private JavaCollections() { 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | static Map javaMap(Object... pairs) { 30 | Objects.requireNonNull(pairs, "pairs is null"); 31 | if ((pairs.length & 1) != 0) { 32 | throw new IllegalArgumentException("Odd length of key-value pairs list"); 33 | } 34 | final Map map = new HashMap<>(); 35 | for (int i = 0; i < pairs.length; i += 2) { 36 | map.put((K) pairs[i], (V) pairs[i + 1]); 37 | } 38 | return map; 39 | } 40 | 41 | @SuppressWarnings("unchecked") 42 | static Set javaSet(T... elements) { 43 | Objects.requireNonNull(elements, "elements is null"); 44 | final Set set = new HashSet<>(); 45 | Collections.addAll(set, elements); 46 | return set; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/MatchErrorTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static io.vavr.API.*; 24 | import static io.vavr.API.$; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; 27 | 28 | public class MatchErrorTest { 29 | 30 | @Test 31 | public void shouldReturnCorrectObject() { 32 | final Object obj = new Object(); 33 | try { 34 | Match(obj).of( 35 | Case($(0), 0) 36 | ); 37 | failBecauseExceptionWasNotThrown(MatchError.class); 38 | } catch (MatchError matchError) { 39 | assertThat(matchError.getObject()).isEqualTo(obj); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/OutputTester.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.io.IOException; 22 | import java.io.OutputStream; 23 | import java.io.PrintStream; 24 | import java.io.PrintWriter; 25 | 26 | /** 27 | * Small utility that allows to test code which write to standard error or standard out. 28 | * 29 | * @author Sebastian Zarnekow 30 | */ 31 | public class OutputTester { 32 | 33 | private static OutputStream failingOutputStream() { 34 | return new OutputStream() { 35 | @Override 36 | public void write(int b) throws IOException { 37 | throw new IOException(); 38 | } 39 | }; 40 | } 41 | 42 | /** 43 | * Obtain a stream that fails on every attempt to write a byte. 44 | * 45 | * @return a new stram that will fail immediately. 46 | */ 47 | public static PrintStream failingPrintStream() { 48 | return new PrintStream(failingOutputStream()); 49 | } 50 | 51 | /** 52 | * Obtain a writer that fails on every attempt to write a byte. 53 | * 54 | * @return a new stram that will fail immediately. 55 | */ 56 | public static PrintWriter failingPrintWriter() { 57 | return new PrintWriter(failingOutputStream()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/PartialFunctionTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import io.vavr.collection.HashMap; 22 | import io.vavr.collection.List; 23 | import io.vavr.control.Either; 24 | import io.vavr.control.Option; 25 | import java.util.function.Predicate; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | public class PartialFunctionTest { 31 | 32 | @Test 33 | public void shouldReturnSome() { 34 | Option oneToOne = HashMap.of(1, "One").lift().apply(1); 35 | assertThat(oneToOne).isEqualTo(Option.some("One")); 36 | } 37 | 38 | @Test 39 | public void shouldReturnNone() { 40 | Option oneToOne = HashMap.empty().lift().apply(1); 41 | assertThat(oneToOne).isEqualTo(Option.none()); 42 | } 43 | 44 | @Test 45 | public void shouldUnliftTotalFunctionReturningAnOption() { 46 | final Predicate isEven = n -> n.intValue() % 2 == 0; 47 | final Function1> totalFunction = n -> isEven.test(n) ? Option.some("even") : Option.none(); 48 | 49 | final PartialFunction partialFunction = PartialFunction.unlift(totalFunction); 50 | 51 | assertThat(partialFunction.isDefinedAt(1)).isFalse(); 52 | assertThat(partialFunction.isDefinedAt(2)).isTrue(); 53 | assertThat(partialFunction.apply(2)).isEqualTo("even"); 54 | } 55 | 56 | @Test 57 | public void shouldNotBeDefinedAtLeft() { 58 | final Either left = Either.left(new RuntimeException()); 59 | 60 | assertThat(PartialFunction.getIfDefined().isDefinedAt(left)).isFalse(); 61 | } 62 | 63 | @Test 64 | public void shouldBeDefinedAtRight() { 65 | Either right = Either.right(42); 66 | 67 | PartialFunction, Number> ifDefined = PartialFunction.getIfDefined(); 68 | 69 | assertThat(ifDefined.isDefinedAt(right)).isTrue(); 70 | assertThat(ifDefined.apply(right)).isEqualTo(42); 71 | } 72 | 73 | @Test 74 | public void shouldCollectSomeValuesAndIgnoreNone() { 75 | final List evenNumbers = List.range(0, 10) 76 | .map(n -> n % 2 == 0 ? Option.some(n) : Option.none()) 77 | .collect(PartialFunction.getIfDefined()); 78 | 79 | assertThat(evenNumbers).containsExactly(0, 2, 4, 6, 8); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/Serializables.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.io.*; 22 | import java.lang.reflect.InvocationTargetException; 23 | import java.lang.reflect.Method; 24 | 25 | public final class Serializables { 26 | 27 | private Serializables() { 28 | } 29 | 30 | /** 31 | * Serializes a given object. 32 | * 33 | * @param obj An object. 34 | * @return IllegalStateException if an IOException occurs when writing the obj to the ObjectOutputStream. 35 | */ 36 | public static byte[] serialize(Object obj) { 37 | try (ByteArrayOutputStream buf = new ByteArrayOutputStream(); 38 | ObjectOutputStream stream = new ObjectOutputStream(buf)) { 39 | stream.writeObject(obj); 40 | return buf.toByteArray(); 41 | } catch (IOException x) { 42 | throw new IllegalStateException("Error serializing object", x); 43 | } 44 | } 45 | 46 | /** 47 | * Deserializes a given object, returning the correct target type of assignment or cast. 48 | *

49 | * Examples: 50 | * 51 | *

52 |      * 
53 |      * // variable assignment
54 |      * final CharSequence s = deserialize(serialize("test"));
55 |      *
56 |      * // type casting
57 |      * final int i = ((String) deserialize(serialize("test"))).length();
58 |      * 
59 |      * 
60 | * 61 | * @param Target type the deserialized object will be casted to. 62 | * @param objectData A serialized object. 63 | * @return The deserialized Object. 64 | * @throws IllegalStateException if an IOException occurs when reading from the ObjectInputStream or the serialized 65 | * class cannot be found. 66 | */ 67 | @SuppressWarnings("unchecked") 68 | public static T deserialize(byte[] objectData) { 69 | try (ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(objectData))) { 70 | return (T) stream.readObject(); 71 | } catch (IOException | ClassNotFoundException x) { 72 | throw new IllegalStateException("Error deserializing object", x); 73 | } 74 | } 75 | 76 | public static void callReadObject(Object o) throws Throwable { 77 | final byte[] objectData = Serializables.serialize(o); 78 | try (ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(objectData))) { 79 | final Method method = o.getClass().getDeclaredMethod("readObject", ObjectInputStream.class); 80 | method.setAccessible(true); 81 | try { 82 | method.invoke(o, stream); 83 | } catch (InvocationTargetException x) { 84 | throw (x.getCause() != null) ? x.getCause() : x; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/TestComparators.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import java.util.Comparator; 22 | 23 | import static java.util.Comparator.comparing; 24 | 25 | public final class TestComparators { 26 | 27 | private TestComparators() { 28 | } 29 | 30 | public static Comparator toStringComparator() { 31 | return comparing(String::valueOf); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/ValueTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.control.Option; 23 | import java.util.ArrayList; 24 | import java.util.stream.Collectors; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | public class ValueTest { 30 | 31 | @Test 32 | public void shouldNarrowValue() { 33 | final Value doubles = List.of(1.0d); 34 | final Value numbers = Value.narrow(doubles); 35 | assertThat(numbers.get()).isEqualTo(1.0d); 36 | } 37 | 38 | @Test 39 | public void collectWorkAsExpectedMultiValue() { 40 | final Value doubles = List.of(1.0d, 2.0d); 41 | final java.util.List result = doubles.collect(Collectors.toList()); 42 | assertThat(result).contains(1.0d, 2.0d); 43 | } 44 | 45 | @Test 46 | public void verboseCollectWorkAsExpectedMultiValue() { 47 | final Value doubles = List.of(1.0d, 2.0d); 48 | final java.util.List result = doubles.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 49 | assertThat(result).contains(1.0d, 2.0d); 50 | } 51 | 52 | @Test 53 | public void collectWorkAsExpectedSingleValue() { 54 | final Value doubles = Option.of(1.0d); 55 | assertThat(doubles.collect(Collectors.toList()).get(0)).isEqualTo(1.0d); 56 | } 57 | 58 | @Test 59 | public void verboseCollectWorkAsExpectedSingleValue() { 60 | final Value doubles = Option.of(1.0d); 61 | assertThat(doubles.collect(ArrayList::new, 62 | ArrayList::add, ArrayList::addAll).get(0)).isEqualTo(1.0d); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/AbstractIndexedSeqTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.math.BigDecimal; 22 | import java.util.Spliterator; 23 | import org.junit.jupiter.api.Test; 24 | 25 | public abstract class AbstractIndexedSeqTest extends AbstractSeqTest { 26 | 27 | @Override 28 | abstract protected IndexedSeq of(T element); 29 | 30 | // -- static narrow 31 | 32 | @Test 33 | public void shouldNarrowIndexedSeq() { 34 | final IndexedSeq doubles = of(1.0d); 35 | final IndexedSeq numbers = IndexedSeq.narrow(doubles); 36 | final int actual = numbers.append(new BigDecimal("2.0")).sum().intValue(); 37 | assertThat(actual).isEqualTo(3); 38 | } 39 | 40 | // -- spliterator 41 | 42 | @Test 43 | public void shouldHaveSizedSpliterator() { 44 | assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED)).isTrue(); 45 | } 46 | 47 | @Test 48 | public void shouldReturnSizeWhenSpliterator() { 49 | assertThat(of(1, 2, 3).spliterator().getExactSizeIfKnown()).isEqualTo(3); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/AbstractLinearSeqTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.math.BigDecimal; 22 | import org.junit.jupiter.api.Test; 23 | 24 | public abstract class AbstractLinearSeqTest extends AbstractSeqTest { 25 | 26 | @Override 27 | abstract protected LinearSeq of(T element); 28 | 29 | // -- static narrow 30 | 31 | @Test 32 | public void shouldNarrowIndexedSeq() { 33 | final LinearSeq doubles = of(1.0d); 34 | final LinearSeq numbers = LinearSeq.narrow(doubles); 35 | final int actual = numbers.append(new BigDecimal("2.0")).sum().intValue(); 36 | assertThat(actual).isEqualTo(3); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/AbstractSortedMapTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.math.BigDecimal; 22 | import java.util.Spliterator; 23 | import org.junit.jupiter.api.Test; 24 | 25 | public abstract class AbstractSortedMapTest extends AbstractMapTest { 26 | 27 | @Override 28 | abstract protected , V> SortedMap mapOf(K k1, V v1); 29 | 30 | // -- isOrdered 31 | 32 | @Test 33 | public void shouldReturnOrdered() { 34 | final Map actual = mapOf(1, "1", 1, "2"); 35 | assertThat(actual.isOrdered()).isTrue(); 36 | } 37 | 38 | // -- narrow 39 | 40 | @Test 41 | public void shouldNarrowMap() { 42 | final SortedMap int2doubleMap = mapOf(1, 1.0d); 43 | final SortedMap number2numberMap = SortedMap.narrow(int2doubleMap); 44 | final int actual = number2numberMap.put(2, new BigDecimal("2.0")).values().sum().intValue(); 45 | assertThat(actual).isEqualTo(3); 46 | } 47 | 48 | // -- spliterator 49 | 50 | @Test 51 | public void shouldHaveSortedSpliterator() { 52 | assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.SORTED)).isTrue(); 53 | } 54 | 55 | @Test 56 | public void shouldHaveOrderedSpliterator() { 57 | assertThat(of(1, 2, 3).spliterator().hasCharacteristics(Spliterator.ORDERED)).isTrue(); 58 | } 59 | 60 | // -- isSequential() 61 | 62 | @Test 63 | public void shouldReturnFalseWhenIsSequentialCalled() { 64 | assertThat(of(1, 2, 3).isSequential()).isFalse(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/ComparatorsTest.java: -------------------------------------------------------------------------------- 1 | package io.vavr.collection; 2 | 3 | import java.util.Comparator; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static io.vavr.collection.Comparators.naturalComparator; 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | 10 | public class ComparatorsTest { 11 | 12 | // -- naturalComparator() 13 | 14 | @Test 15 | public void shouldCompareTwoIntegersUsingNaturalOrder() { 16 | final Comparator comparator = naturalComparator(); 17 | assertThat(comparator.compare(0, 1)).isEqualTo(-1); 18 | assertThat(comparator.compare(2, -1)).isEqualTo(1); 19 | assertThat(comparator.compare(3, 3)).isEqualTo(0); 20 | } 21 | 22 | @Test 23 | public void shouldThrowNPEWhenComparingNullAndIntegerUsingNaturalOrder() { 24 | assertThrows(NullPointerException.class, () -> naturalComparator().compare(null, 1)); 25 | } 26 | 27 | @Test 28 | public void shouldThrowNPEWhenComparingIntegerAndNullUsingNaturalOrder() { 29 | assertThrows(NullPointerException.class, () -> naturalComparator().compare(1, null)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/IntMod2.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | /** 22 | * An Int wrapper that implements equality by comparing int values modulo 2. 23 | *
24 | * Examples: 25 | *
    26 | *
  • IntMod2(0) equals IntMod2(2) equals IntMod2(4) ...
  • 27 | *
  • IntMod2(1) equals IntMod2(3) equals IntMod2(5) ...
  • 28 | *
  • IntMod2(0) < IntMod2(1)
  • 29 | *
  • IntMod2(_even_int_) < IntMod2(_odd_int_)
  • 30 | *
31 | */ 32 | final class IntMod2 implements Comparable { 33 | 34 | private final int val; 35 | 36 | IntMod2(int val) { 37 | this.val = val; 38 | } 39 | 40 | @Override 41 | public int compareTo(IntMod2 that) { 42 | return this.hashCode() - that.hashCode(); 43 | } 44 | 45 | @Override 46 | public boolean equals(Object that) { 47 | return that == this || (that instanceof IntMod2 && this.hashCode() == that.hashCode()); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return val % 2; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return String.valueOf(val); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/IntMod2Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | public class IntMod2Test { 26 | 27 | private static final IntMod2 _1 = new IntMod2(1); 28 | private static final IntMod2 _2 = new IntMod2(2); 29 | private static final IntMod2 _3 = new IntMod2(3); 30 | private static final IntMod2 _4 = new IntMod2(4); 31 | 32 | @Test 33 | public void shouldBeEqualIfEven() { 34 | assertThat(_2.equals(_4)).isTrue(); 35 | assertThat(_2.compareTo(_4)).isEqualTo(0); 36 | } 37 | 38 | @Test 39 | public void shouldBeEqualIfOdd() { 40 | assertThat(_1.equals(_3)).isTrue(); 41 | assertThat(_1.compareTo(_3)).isEqualTo(0); 42 | } 43 | 44 | @Test 45 | public void shouldNotBeEqualIfEvenAndOdd() { 46 | assertThat(_1.equals(_2)).isFalse(); 47 | assertThat(_1.compareTo(_2)).isEqualTo(1); 48 | assertThat(_2.compareTo(_3)).isEqualTo(-1); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/QuickSortTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection; 20 | 21 | import java.util.function.IntFunction; 22 | import org.assertj.core.api.Assertions; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.API.List; 26 | import static java.lang.Integer.signum; 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | public class QuickSortTest { 30 | @Test 31 | public void shouldQuickSort() { 32 | final List values = List(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6); 33 | Assertions.assertThat(sort(values.shuffle())).isEqualTo(values.sorted()); 34 | assertThat(sort2(values.shuffle())).isEqualTo(values.sorted()); 35 | } 36 | 37 | /** Note: this example is only meant to show off, not to be used in reality: it can have quadratic performance and cause stack overflow */ 38 | private static Seq sort(Seq values) { 39 | if (values.size() <= 1) return values; 40 | return values.tail().partition(v -> v <= values.head()) 41 | .apply((less, more) -> sort(less).append(values.head()).appendAll(sort(more))); 42 | } 43 | private static > List sort2(List values) { 44 | if (values.size() <= 1) return values; 45 | final Map> map = values.groupBy(v -> signum(v.compareTo(values.head()))); 46 | final IntFunction> parts = signum -> map.get(signum).getOrElse(List()); 47 | return sort2(parts.apply(-1)).appendAll(parts.apply(0)).appendAll(sort2(parts.apply(1))); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler01Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * Problem 1: Multiples of 3 and 5 28 | *

29 | * If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. 30 | * The sum of these multiples is 23. 31 | *

32 | * Find the sum of all the multiples of 3 or 5 below 1000. 33 | *

34 | * See also projecteuler.net problem 1. 35 | */ 36 | public class Euler01Test { 37 | 38 | @Test 39 | public void shouldSolveProblem1() { 40 | assertThat(sumOfMultiplesOf3and5Below(10)).isEqualTo(23); 41 | assertThat(sumOfMultiplesOf3and5Below(1000)).isEqualTo(233168); 42 | } 43 | 44 | private static int sumOfMultiplesOf3and5Below(int limit) { 45 | return List.range(1, limit).filter(Euler01Test::isMultipleOf3or5).sum().intValue(); 46 | } 47 | 48 | private static boolean isMultipleOf3or5(int num) { 49 | return num % 3 == 0 || num % 5 == 0; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler02Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import java.math.BigInteger; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler02Test { 27 | 28 | /** 29 | * Problem 2: Even Fibonacci numbers 30 | *

31 | * Each new term in the Fibonacci sequence is generated by adding the previous 32 | * two terms. By starting with 1 and 2, the first 10 terms will be: 1, 2, 3, 5, 33 | * 8, 13, 21, 34, 55, 89, ... 34 | *

35 | * By considering the terms in the Fibonacci sequence whose values do not exceed 36 | * four million, find the sum of the even-valued terms. 37 | *

38 | * See also projecteuler.net problem 2. 39 | */ 40 | @Test 41 | public void shouldSolveProblem2() { 42 | assertThat(sumOfEvenFibonacciValuesNotExceeding(90)).isEqualTo(2 + 8 + 34); 43 | assertThat(sumOfEvenFibonacciValuesNotExceeding(4_000_000)).isEqualTo(4_613_732); 44 | } 45 | 46 | private static long sumOfEvenFibonacciValuesNotExceeding(final int max) { 47 | return Utils.fibonacci() 48 | .map(BigInteger::longValue) 49 | .takeWhile(f -> f <= max) 50 | .filter(f -> f % 2 == 0) 51 | .sum().longValue(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler03Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | public class Euler03Test { 26 | 27 | /** 28 | * Problem 3: Largest prime factor 29 | *

30 | * The prime factors of 13195 are 5, 7, 13 and 29. 31 | *

32 | * What is the largest prime factor of the number 600851475143? 33 | *

34 | * See also projecteuler.net problem 3. 35 | */ 36 | @Test 37 | public void shouldSolveProblem3() { 38 | assertThat(largestPrimeFactorOf(24)).isEqualTo(3); 39 | assertThat(largestPrimeFactorOf(29)).isEqualTo(29); 40 | assertThat(largestPrimeFactorOf(13195)).isEqualTo(29); 41 | assertThat(largestPrimeFactorOf(600_851_475_143L)).isEqualTo(6857); 42 | } 43 | 44 | private static long largestPrimeFactorOf(long val) { 45 | return PrimeNumbers.primeFactors(val).max().get(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler04Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler04Test { 27 | 28 | /** 29 | * Problem 4: Largest palindrome product 30 | *

31 | * A palindromic number reads the same both ways. The largest palindrome made 32 | * from the product of two 2-digit numbers is 9009 = 91 × 99. 33 | *

34 | * Find the largest palindrome made from the product of two 3-digit numbers. 35 | *

36 | * See also projecteuler.net problem 4. 37 | */ 38 | @Test 39 | public void shouldSolveProblem4() { 40 | assertThat(largestPalindromeOfProductsFromFactorsInRange(10, 99)).isEqualTo(9009); 41 | assertThat(largestPalindromeOfProductsFromFactorsInRange(100, 999)).isEqualTo(906609); 42 | } 43 | 44 | private static int largestPalindromeOfProductsFromFactorsInRange(final int min, final int max) { 45 | return List.rangeClosed(min, max) 46 | .crossProduct() 47 | .filter(t -> t._1 <= t._2) 48 | .map(t -> t._1 * t._2) 49 | .filter(Utils::isPalindrome) 50 | .max().get(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler05Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Stream; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler05Test { 27 | 28 | /** 29 | * Problem 5: Smallest multiple 30 | *

31 | * 2520 is the smallest number that can be divided by each of the numbers from 1 32 | * to 10 without any remainder. 33 | *

34 | * What is the smallest positive number that is evenly divisible by all of the 35 | * numbers from 1 to 20? 36 | *

37 | * See also projecteuler.net problem 5. 38 | */ 39 | @Test 40 | public void shouldSolveProblem5() { 41 | assertThat(smallestPositiveNumberEvenlyDivisibleByAllNumbersFrom1To(10)).isEqualTo(2_520L); 42 | assertThat(smallestPositiveNumberEvenlyDivisibleByAllNumbersFrom1To(20)).isEqualTo(232_792_560L); 43 | } 44 | 45 | private static long smallestPositiveNumberEvenlyDivisibleByAllNumbersFrom1To(int max) { 46 | return Stream.rangeClosed(2, max) 47 | .map(PrimeNumbers::factorization) 48 | .reduce((m1, m2) -> m1.merge(m2, Math::max)) 49 | .foldLeft(1L, (xs, x) -> xs * pow(x._1, x._2)); 50 | } 51 | 52 | private static long pow(long a, long p) { 53 | return Stream.rangeClosed(1, p).fold(1L, (xs, x) -> xs * a); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler06Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Stream; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler06Test { 27 | 28 | /** 29 | * Problem 6: Sum square difference 30 | *

31 | * The sum of the squares of the first ten natural numbers is, 32 | *

33 | * 1² + 2² + ... + 10² = 385 34 | *

35 | * The square of the sum of the first ten natural 36 | * numbers is, 37 | *

38 | * (1 + 2 + ... + 10)² = 55² = 3025 39 | *

40 | * Hence the difference between the sum of the 41 | * squares of the first ten natural numbers and the square of the sum is 42 | *

43 | * 3025 − 385 = 2640. 44 | *

45 | * Find the difference between the sum of the squares of the first one hundred 46 | * natural numbers and the square of the sum. 47 | *

48 | * See also projecteuler.net problem 6. 49 | */ 50 | @Test 51 | public void shouldSolveProblem6() { 52 | assertThat(differenceBetweenSumOfTheSquaresAndSquareOfTheSumFrom1UpTo(10)).isEqualTo(2640L); 53 | assertThat(differenceBetweenSumOfTheSquaresAndSquareOfTheSumFrom1UpTo(100)).isEqualTo(25164150L); 54 | } 55 | 56 | private static long differenceBetweenSumOfTheSquaresAndSquareOfTheSumFrom1UpTo(int max) { 57 | return squareOfSumFrom1UpTo(max) - sumOfSquaresFrom1UpTo(max); 58 | } 59 | 60 | private static long squareOfSumFrom1UpTo(int max) { 61 | return (long) Math.pow(Stream.rangeClosed(1, max).sum().longValue(), 2); 62 | } 63 | 64 | private static long sumOfSquaresFrom1UpTo(int max) { 65 | return Stream.rangeClosed(1, max) 66 | .map(i -> (long) Math.pow(i, 2)) 67 | .sum().longValue(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler07Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Array; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler07Test { 27 | 28 | /** 29 | * Problem 7: 10001st prime 30 | *

31 | * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. 32 | *

33 | * What is the 10 001st prime number? 34 | *

35 | * See also projecteuler.net problem 7. 36 | */ 37 | @Test 38 | public void shouldSolveProblem7() { 39 | assertThat(prime(1)).isEqualTo(2); 40 | assertThat(prime(2)).isEqualTo(3); 41 | assertThat(prime(3)).isEqualTo(5); 42 | assertThat(prime(4)).isEqualTo(7); 43 | assertThat(prime(5)).isEqualTo(11); 44 | assertThat(prime(6)).isEqualTo(13); 45 | assertThat(prime(10_001)).isEqualTo(104_743); 46 | } 47 | 48 | private static final Array PRIMES = Array.ofAll(PrimeNumbers.primes().take(10_001)); 49 | 50 | private static long prime(int index) { 51 | return PRIMES.get(index - 1); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler09Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.collection.List; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler09Test { 28 | 29 | /** 30 | * Problem 9: Special Pythagorean triplet 31 | *

32 | * A Pythagorean triplet is a set of three natural numbers, a < b < c, for which, 33 | * a2 + b2 = c2 34 | *

35 | * For example, 32 + 42 = 9 + 16 = 25 = 52. 36 | *

37 | * There exists exactly one Pythagorean triplet for which a + b + c = 1000. 38 | * Find the product abc. 39 | *

40 | * See also projecteuler.net problem 9. 41 | */ 42 | @Test 43 | public void shouldSolveProblem9() { 44 | assertThat(abc(1_000)).isEqualTo(31_875_000); 45 | } 46 | 47 | public int abc(int sum) { 48 | return List.rangeClosed(1, sum) 49 | .crossProduct() 50 | .filter(t -> t._1 + t._2 < sum) 51 | .map(t -> Tuple.of(t._1, t._2, sum - t._1 - t._2)) 52 | .filter(t -> t._1 * t._1 + t._2 * t._2 == t._3 * t._3) 53 | .map(t -> t._1 * t._2 * t._3) 54 | .head(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler10Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static org.assertj.core.api.Assertions.assertThat; 24 | 25 | public class Euler10Test { 26 | 27 | /** 28 | * Problem 10: Summation of primes 29 | *

30 | * The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17. 31 | *

32 | * Find the sum of all the primes below two million. 33 | *

34 | * See also projecteuler.net problem 10. 35 | */ 36 | @Test 37 | public void shouldSolveProblem10() { 38 | assertThat(sumPrimes(10)).isEqualTo(17); 39 | assertThat(sumPrimes(2_000_000L)).isEqualTo(142_913_828_922L); 40 | } 41 | 42 | private long sumPrimes(long max) { 43 | return PrimeNumbers.primes() 44 | .map(Long::valueOf) 45 | .takeWhile(t -> t < max) 46 | .reduce((p1, p2) -> p1 + p2); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler12Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Stream; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static io.vavr.collection.euler.Utils.factors; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler12Test { 28 | 29 | /** 30 | * Problem 12: Highly divisible triangular number 31 | *

32 | * The sequence of triangle numbers is generated by adding the natural 33 | * numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 34 | * 28. The first ten terms would be: 35 | *

36 | * 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... 37 | *

38 | * Let us list the factors of the first seven triangle numbers: 39 | *

40 |      * 1: 1
41 |      * 3: 1,3
42 |      * 6: 1,2,3,6
43 |      * 10: 1,2,5,10
44 |      * 15: 1,3,5,15
45 |      * 21: 1,3,7,21
46 |      * 28: 1,2,4,7,14,28
47 |      * 
48 | *

49 | * We can see that 28 is the first triangle number to have over five 50 | * divisors. 51 | *

52 | * What is the value of the first triangle number to have over five hundred 53 | * divisors? 54 | */ 55 | @Test 56 | public void shouldSolveProblem12() { 57 | assertThat(valueOfFirstTriangleNumberWithMoreDivisorsThan(5)).isEqualTo(28); 58 | assertThat(valueOfFirstTriangleNumberWithMoreDivisorsThan(500)).isEqualTo(76_576_500); 59 | } 60 | 61 | private static long valueOfFirstTriangleNumberWithMoreDivisorsThan(long divisorCount) { 62 | return triangleNumbers() 63 | .find(t -> divisorCount(t) > divisorCount) 64 | .get(); 65 | } 66 | 67 | private static Stream triangleNumbers() { 68 | return Stream.from(1L).scanLeft(0L, (a, l) -> a + l); 69 | } 70 | 71 | private static long divisorCount(long number) { 72 | return factors(number).length(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler13Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import java.math.BigInteger; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static io.vavr.collection.euler.Utils.file; 25 | import static io.vavr.collection.euler.Utils.readLines; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler13Test { 29 | 30 | /** 31 | * Problem 13: Large sum 32 | *

33 | * Work out the first ten digits of the sum of the following one-hundred 50-digit numbers. 34 | *

35 | * See also projecteuler.net problem 13. 36 | */ 37 | @Test 38 | public void shouldSolveProblem13() { 39 | assertThat(solve()).isEqualTo("5537376230"); 40 | } 41 | 42 | private static String solve() { 43 | return readLines(file("p013_numbers.txt")) 44 | .map(BigInteger::new) 45 | .fold(BigInteger.ZERO, BigInteger::add) 46 | .toString().substring(0, 10); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler14Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function1; 22 | import io.vavr.collection.Stream; 23 | import org.assertj.core.api.Assertions; 24 | import org.junit.jupiter.api.Test; 25 | 26 | 27 | public class Euler14Test { 28 | 29 | /** 30 | * Problem 14: Longest Collatz sequence 31 | *

32 | * The following iterative sequence is defined for the set of positive integers: 33 | *

34 |      * 
35 |      * n → n/2 (n is even)
36 |      * n → 3n + 1 (n is odd)
37 |      * 
38 |      * 
39 | * Using the rule above and starting with 13, we generate the following sequence: 40 | *
41 |      * 
42 |      * 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1
43 |      * 
44 |      * 
45 | * It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. 46 | * Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1. 47 | *

48 | * Which starting number, under one million, produces the longest chain? 49 | *

50 | * NOTE: Once the chain starts the terms are allowed to go above one million. 51 | *

52 | * See also projecteuler.net problem 14. 53 | */ 54 | @Test 55 | public void shouldSolveProblem14() { 56 | // equivalent to from(1L).take(1_000_000) 57 | Assertions.assertThat(Stream.from(500_000L) 58 | .take(500_000) 59 | .maxBy(collatzSequenceLength) 60 | .get()).isEqualTo(837799); 61 | } 62 | 63 | private final static Function1 collatzRecursive = n -> { 64 | if (n == 1) { 65 | return 1L; 66 | } else { 67 | if (n % 2 == 0) { 68 | return Euler14Test.collatzRecursive.apply(n / 2) + 1; 69 | } else { 70 | return Euler14Test.collatzRecursive.apply(3 * n + 1) + 1; 71 | } 72 | } 73 | }; 74 | 75 | private final static Function1 collatzSequenceLength = collatzRecursive.memoized(); 76 | } 77 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler15Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import java.math.BigInteger; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static io.vavr.collection.euler.Utils.factorial; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler15Test { 28 | 29 | /** 30 | * Problem 15: Lattice paths 31 | *

32 | * Starting in the top left corner of a 2x2 grid, and only being able to move to the right and down, 33 | * there are exactly 6 routes to the bottom right corner. 34 | *

35 | * How many such routes are there through a 20×20 grid? 36 | *

37 | * See also projecteuler.net problem 15. 38 | */ 39 | @Test 40 | public void shouldSolveProblem15() { 41 | assertThat(solve(2)).isEqualTo(6); 42 | assertThat(solve(20)).isEqualTo(137_846_528_820L); 43 | } 44 | 45 | private static long solve(int n) { 46 | final BigInteger f = factorial(n); 47 | return factorial(2 * n).divide(f).divide(f).longValue(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler16Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import java.math.BigInteger; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler16Test { 28 | 29 | /** 30 | * Problem 16: Power digit sum 31 | *

32 | * 215 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26. 33 | *

34 | * What is the sum of the digits of the number 21000? 35 | *

36 | * See also projecteuler.net problem 16. 37 | */ 38 | @Test 39 | public void shouldSolveProblem16() { 40 | assertThat(solve(15)).isEqualTo(26); 41 | assertThat(solve(1000)).isEqualTo(1_366); 42 | } 43 | 44 | private static long solve(int n) { 45 | return CharSeq.of(BigInteger.valueOf(2).pow(n).toString()) 46 | .map(c -> c - '0') 47 | .fold(0, (a, b) -> a + b); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler18Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function3; 22 | import io.vavr.collection.Vector; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler18Test { 28 | 29 | /** 30 | * Problem 18: Maximum path sum I 31 | *

32 | * By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. 33 | *

34 |      *        3
35 |      *       7 4
36 |      *      2 4 6
37 |      *     8 5 9 3
38 |      * 
39 | * That is, 3 + 7 + 4 + 9 = 23. 40 | *

41 | * Find the maximum total from top to bottom in p018_triangle.txt. 42 | *

43 | * NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. 44 | * However, Problem 67, is the same challenge with a triangle containing one-hundred rows; 45 | * it cannot be solved by brute force, and requires a clever method! ;o). 46 | *

47 | * See also projecteuler.net problem 18. 48 | */ 49 | @Test 50 | public void shouldSolveProblem18() { 51 | assertThat(solve("small_triangle.txt")).isEqualTo(23); 52 | assertThat(solve("p018_triangle.txt")).isEqualTo(1074); 53 | } 54 | 55 | private static int solve(String fileName) { 56 | return naive.apply(Euler67Test.loadTriangle(fileName), 0, 0); 57 | } 58 | 59 | private final static Function3>, Integer, Integer, Integer> naive = Function3.of( 60 | (Vector> tr, Integer row, Integer col) -> { 61 | int value = tr.get(row).get(col); 62 | if (row == tr.length() - 1) { 63 | return tr.get(row).get(col); 64 | } else { 65 | return value + Math.max(Euler18Test.naive.apply(tr, row + 1, col), Euler18Test.naive.apply(tr, row + 1, col + 1)); 66 | } 67 | } 68 | ); 69 | } 70 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler19Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.collection.List; 23 | import java.time.DayOfWeek; 24 | import java.time.LocalDate; 25 | import java.time.Month; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static io.vavr.API.For; 29 | import static org.assertj.core.api.Assertions.assertThat; 30 | 31 | /** 32 | * Problem 19:Counting Sundays 33 | * 34 | *

You are given the following information, but you may prefer to do some research for yourself.

35 | *
    36 | *
  • 1 Jan 1900 was a Monday.
  • 37 | *
  • Thirty days has September,
    38 | * April, June and November.
    39 | * All the rest have thirty-one,
    40 | * Saving February alone,
    41 | * Which has twenty-eight, rain or shine.
    42 | * And on leap years, twenty-nine.
  • 43 | *
  • A leap year occurs on any year evenly divisible by 4, but not on a century unless it is divisible by 400.
  • 44 | *
45 | *

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

46 | * 47 | * See also projecteuler.net problem 19. 48 | */ 49 | public class Euler19Test { 50 | 51 | @Test 52 | public void shouldSolveProblem19() { 53 | assertThat(findNumberOfFirstMonthDaysOnSunday(1901, 2000)).isEqualTo(171); 54 | } 55 | 56 | private static boolean isFirstDayOfMonthSunday(int year, Month month) { 57 | return LocalDate.of(year, month, 1).getDayOfWeek() == DayOfWeek.SUNDAY; 58 | } 59 | 60 | private static int findNumberOfFirstMonthDaysOnSunday(int startYear, int endYear) { 61 | return For(List.rangeClosed(startYear, endYear), List.of(Month.values())) 62 | .yield(Tuple::of) 63 | .filter(t -> isFirstDayOfMonthSunday(t._1, t._2)) 64 | .length(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler20Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.Stream; 23 | import java.math.BigInteger; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | /** 29 | * Problem 20:Factorial digit sum 30 | * 31 | *

n! means n × (n − 1) × ... × 3 × 2 × 1

32 | *

For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

33 | *

Find the sum of the digits in the number 100!

34 | * 35 | * See also projecteuler.net problem 20. 36 | */ 37 | 38 | public class Euler20Test { 39 | 40 | @SuppressWarnings("PointlessArithmeticExpression") 41 | @Test 42 | public void shouldSolveProblem20() { 43 | assertThat(sumOfFactorialDigits(10)).isEqualTo(3 + 6 + 2 + 8 + 8 + 0 + 0); 44 | assertThat(sumOfFactorialDigits(100)).isEqualTo(9 + 3 + 3 + 2 + 6 + 2 + 1 + 5 + 4 + 4 + 3 + 9 + 4 + 4 + 1 + 5 + 2 + 6 + 8 + 1 + 6 + 9 + 9 + 2 + 3 + 8 + 8 + 5 + 6 + 2 + 6 + 6 + 7 + 0 + 0 + 4 + 9 + 0 + 7 + 1 + 5 + 9 + 6 + 8 + 2 + 6 + 4 + 3 + 8 + 1 + 6 + 2 + 1 + 4 + 6 + 8 + 5 + 9 + 2 + 9 + 6 + 3 + 8 + 9 + 5 + 2 + 1 + 7 + 5 + 9 + 9 + 9 + 9 + 3 + 2 + 2 + 9 + 9 + 1 + 5 + 6 + 0 + 8 + 9 + 4 + 1 + 4 + 6 + 3 + 9 + 7 + 6 + 1 + 5 + 6 + 5 + 1 + 8 + 2 + 8 + 6 + 2 + 5 + 3 + 6 + 9 + 7 + 9 + 2 + 0 + 8 + 2 + 7 + 2 + 2 + 3 + 7 + 5 + 8 + 2 + 5 + 1 + 1 + 8 + 5 + 2 + 1 + 0 + 9 + 1 + 6 + 8 + 6 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0); 45 | } 46 | 47 | private static BigInteger factorial(int n) { 48 | return Stream.rangeClosed(1, n) 49 | .map(BigInteger::valueOf) 50 | .reduce(BigInteger::multiply); 51 | } 52 | 53 | private static int sumOfFactorialDigits(int n) { 54 | return CharSeq.of(factorial(n).toString()) 55 | .foldLeft(0, (sum, c) -> sum + Character.digit(c, 10)); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler21Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function1; 22 | import io.vavr.Tuple; 23 | import io.vavr.collection.Stream; 24 | import java.util.Objects; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | /** 30 | * Problem 21: Amicable numbers 31 | * 32 | *

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
33 | * If d(a) = b and d(b) = a, where ab, then a and b are an amicable pair and each of a and b are called amicable numbers.

34 | *

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

35 | *

Evaluate the sum of all the amicable numbers under 10000

36 | * See also projecteuler.net problem 21. 37 | */ 38 | 39 | public class Euler21Test { 40 | 41 | @Test 42 | public void shouldSolveProblem21() { 43 | assertThat(sumOfDivisors(220)).isEqualTo(1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110); 44 | assertThat(sumOfDivisors(284)).isEqualTo(1 + 2 + 4 + 71 + 142); 45 | assertThat(sumOfAmicablePairs(10000)).isEqualTo(31626); 46 | } 47 | 48 | private static int sumOfDivisors(int n) { 49 | return 1 + Stream.rangeClosed(2, (int) Math.sqrt(n)) 50 | .map(d -> Tuple.of(d, n / d)) 51 | .filter(t -> t._1 * t._2 == n && !Objects.equals(t._1, t._2)) 52 | .map(t -> t._1 + t._2) 53 | .foldLeft(0, (sum, x) -> sum + x); 54 | } 55 | 56 | private static int sumOfAmicablePairs(int n) { 57 | final Function1 mSumOfDivisors = Function1.of(Euler21Test::sumOfDivisors).memoized(); 58 | return Stream.range(1, n) 59 | .filter(x -> mSumOfDivisors.apply(mSumOfDivisors.apply(x)).intValue() == x && mSumOfDivisors.apply(x) > x) 60 | .foldLeft(0, (sum, x) -> sum + x + mSumOfDivisors.apply(x)); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler22Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.collection.euler.Utils.file; 26 | import static io.vavr.collection.euler.Utils.readLines; 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | /** 30 | * Problem 22: Names scores 31 | *

32 | * Using names.txt (right click and 'Save Link/Target As...'), a 46K text file 33 | * containing over five-thousand first names, begin by sorting it into 34 | * alphabetical order. Then working out the alphabetical value for each name, 35 | * multiply this value by its alphabetical position in the list to obtain a name 36 | * score. 37 | *

38 | * For example, when the list is sorted into alphabetical order, COLIN, which is 39 | * worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN 40 | * would obtain a score of 938 × 53 = 49714. 41 | *

42 | * What is the total of all the name scores in the file? 43 | *

44 | * See also projecteuler.net 45 | * problem 22. 46 | */ 47 | public class Euler22Test { 48 | 49 | @Test 50 | public void shouldSolveProblem22() { 51 | assertThat(nameScore("COLIN", 938)).isEqualTo(49714); 52 | assertThat(totalOfAllNameScores()).isEqualTo(871_198_282); 53 | } 54 | 55 | private static long nameScore(String name, long position) { 56 | return CharSeq.of(name) 57 | .map(c -> c - 'A' + 1) 58 | .sum().longValue() * position; 59 | } 60 | 61 | private static long totalOfAllNameScores() { 62 | return readLines(file("p022_names.txt")) 63 | .map(l -> l.replaceAll("\"", "")) 64 | .flatMap(l -> Stream.of(l.split(","))) 65 | .sorted() 66 | .zipWithIndex() 67 | .map(t -> nameScore(t._1, t._2 + 1)) 68 | .sum().longValue(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler24Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.API; 22 | import io.vavr.Function1; 23 | import io.vavr.collection.List; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static io.vavr.API.$; 27 | import static io.vavr.API.Case; 28 | import static io.vavr.collection.euler.Utils.factorial; 29 | import static org.assertj.core.api.Assertions.assertThat; 30 | 31 | /** 32 | * Problem 24: Lexicographic permutations 33 | *

34 | * A permutation is an ordered arrangement of objects. For example, 3124 is one 35 | * possible permutation of the digits 1, 2, 3 and 4. If all of the permutations 36 | * are listed numerically or alphabetically, we call it lexicographic order. The 37 | * lexicographic permutations of 0, 1 and 2 are: 38 | *

39 | * 012 021 102 120 201 210 40 | *

41 | * What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 42 | * 5, 6, 7, 8 and 9? 43 | *

44 | * See also projecteuler.net 45 | * problem 24. 46 | */ 47 | public class Euler24Test { 48 | 49 | @Test 50 | public void shouldSolveProblem24() { 51 | List.of("012", "021", "102", "120", "201", "210").zipWithIndex() 52 | .forEach(p -> { 53 | assertThat(lexicographicPermutationNaive(List.of("1", "0", "2"), p._2 + 1)).isEqualTo(p._1); 54 | assertThat(lexicographicPermutation(List.of("1", "0", "2"), p._2 + 1)).isEqualTo(p._1); 55 | }); 56 | 57 | assertThat(lexicographicPermutation(List.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"), 1_000_000)).isEqualTo("2783915460"); 58 | } 59 | 60 | /** 61 | * Naïve version. Very readable, but not performant enough for calculating 62 | * "the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 63 | * 6, 7, 8 and 9" (takes about 40 seconds on an average laptop). 64 | */ 65 | private static String lexicographicPermutationNaive(List stringsToPermutate, int ordinal) { 66 | return stringsToPermutate.permutations() 67 | .map(List::mkString) 68 | .sorted() 69 | .get(ordinal - 1); 70 | } 71 | 72 | /** 73 | * More performant version that uses an algorithm that calculates the number 74 | * of permutations achievable in each position instead of actually doing the permutations. 75 | */ 76 | private static String lexicographicPermutation(List stringsToPermutate, int ordinal) { 77 | return API.Match(stringsToPermutate.sorted()).of( 78 | Case($((List sx) -> sx.length() == 1), sx -> sx.mkString()), 79 | Case($(), sx -> { 80 | final int noOfPossiblePermutationsInTail = memoizedFactorial.apply(sx.length() - 1); 81 | final int headCharPosition = ((ordinal + noOfPossiblePermutationsInTail - 1) / noOfPossiblePermutationsInTail); 82 | final int ordinalRest = Integer.max(0, ordinal - ((headCharPosition - 1) * noOfPossiblePermutationsInTail)); 83 | return List.of(sx.get(headCharPosition - 1)).mkString() + lexicographicPermutation(sx.removeAt(headCharPosition - 1), ordinalRest); 84 | }) 85 | ); 86 | } 87 | 88 | private static final Function1 memoizedFactorial = Function1.of((Integer i) -> factorial(i).intValue()).memoized(); 89 | } 90 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler25Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static io.vavr.collection.euler.Utils.fibonacci; 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * Problem 25: 1000-digit Fibonacci number 28 | *

29 | * The Fibonacci sequence is defined by the recurrence relation: 30 | *

31 | * Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1. Hence the first 12 terms will be: 32 | *

33 |  * F1 = 1
34 |  * F2 = 1
35 |  * F3 = 2
36 |  * F4 = 3
37 |  * F5 = 5
38 |  * F6 = 8
39 |  * F7 = 13
40 |  * F8 = 21
41 |  * F9 = 34
42 |  * F10 = 55
43 |  * F11 = 89
44 |  * F12 = 144
45 |  * 
46 | *

47 | * The 12th term, F12, is the first term to contain three digits. 48 | *

49 | * What is the first term in the Fibonacci sequence to contain 1000 digits? 50 | *

51 | * See also projecteuler.net 52 | * problem 25. 53 | */ 54 | public class Euler25Test { 55 | 56 | @Test 57 | public void shouldSolveProblem25() { 58 | assertThat(firstFibonacciTermContaining(3)).isEqualTo(12); 59 | assertThat(firstFibonacciTermContaining(1000)).isEqualTo(4782); 60 | } 61 | 62 | private static int firstFibonacciTermContaining(int digits) { 63 | return fibonacci() 64 | .zipWithIndex() 65 | .find(t -> t._1.toString().length() == digits) 66 | .get()._2; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler27Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.API; 22 | import io.vavr.Tuple; 23 | import io.vavr.collection.List; 24 | import io.vavr.collection.Stream; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | /** 30 | * Problem 27: Quadratic primes 31 | *

32 | * Euler discovered the remarkable quadratic formula: 33 | *

34 | * n² + n + 41 35 | *

36 | * It turns out that the formula will produce 40 primes for the consecutive 37 | * values n = 0 to 39. However, when n = 40, 40^2 + 40 + 41 = 40(40 + 1) + 41 is 38 | * divisible by 41, and certainly when n = 41, 41² + 41 + 41 is clearly 39 | * divisible by 41. 40 | *

41 | * The incredible formula n² − 79n + 1601 was discovered, which produces 80 42 | * primes for the consecutive values n = 0 to 79. The product of the 43 | * coefficients, −79 and 1601, is −126479. 44 | *

45 | * Considering quadratics of the form: 46 | *

47 | * n² + an + b, where |a| < 1000 and |b| < 1000

48 | * where |n| is the modulus/absolute value of n e.g. |11| = 11 and |−4| = 4 49 | *

50 | * Find the product of the coefficients, a and b, for the quadratic expression 51 | * that produces the maximum number of primes for consecutive values of n, 52 | * starting with n = 0. 53 | *

54 | * See also 55 | * projecteuler.net problem 27 56 | * . 57 | */ 58 | public class Euler27Test { 59 | 60 | @Test 61 | public void shouldSolveProblem27() { 62 | assertThat(numberOfConsecutivePrimesProducedByFormulaWithCoefficients(1, 41)).isEqualTo(40); 63 | assertThat(numberOfConsecutivePrimesProducedByFormulaWithCoefficients(-79, 1601)).isEqualTo(80); 64 | 65 | assertThat(productOfCoefficientsWithMostConsecutivePrimes(-999, 999)).isEqualTo(-59231); 66 | } 67 | 68 | private static int productOfCoefficientsWithMostConsecutivePrimes(int coefficientsLowerBound, int coefficientsUpperBound) { 69 | final List coefficients = List.rangeClosed(coefficientsLowerBound, coefficientsUpperBound); 70 | return API.For(coefficients, coefficients).yield(Tuple::of) 71 | .map(c -> Tuple.of(c._1, c._2, numberOfConsecutivePrimesProducedByFormulaWithCoefficients(c._1, c._2))) 72 | .fold(Tuple.of(0, 0, -1), (n, m) -> n._3 >= m._3 ? n : m) 73 | .apply((a, b, p) -> a * b); 74 | } 75 | 76 | private static int numberOfConsecutivePrimesProducedByFormulaWithCoefficients(int a, int b) { 77 | return Stream.from(0L) 78 | .map(n -> (long) Math.pow(n, 2) + a * n + b) 79 | .takeWhile(Utils.MEMOIZED_IS_PRIME::apply) 80 | .length(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler28Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | /** 28 | * Problem 28: Number spiral diagonals 29 | *

30 | * Starting with the number 1 and moving to the right in a clockwise direction a 31 | * 5 by 5 spiral is formed as follows: 32 | *

33 |  *             21 22 23 24 25
34 |  *             20  7  8  9 10
35 |  *             19  6  1  2 11
36 |  *             18  5  4  3 12
37 |  *             17 16 15 14 13
38 |  * 
39 | * 40 | * It can be verified that the sum of the numbers on the diagonals is 101. 41 | *

42 | * What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral 43 | * formed in the same way? 44 | *

45 | * See also 46 | * projecteuler.net problem 28 47 | * . 48 | */ 49 | public class Euler28Test { 50 | 51 | @Test 52 | public void shouldSolveProblem28() { 53 | assertThat(sumOfDiagonalInSpiralWithSide(5)).isEqualTo(101); 54 | assertThat(sumOfDiagonalInSpiralWithSide(1001)).isEqualTo(669_171_001); 55 | } 56 | 57 | private static long sumOfDiagonalInSpiralWithSide(long maxSideLength) { 58 | return diagonalNumbersInSpiralWithSide(maxSideLength).sum().longValue(); 59 | } 60 | 61 | private static Stream diagonalNumbersInSpiralWithSide(long maxSideLength) { 62 | return Stream.iterate(Tuple.of(1, center()), t -> Tuple.of(nextSideLength(t._1), nextRoundOfCorners(t._2.last(), nextSideLength(t._1)))) 63 | .takeWhile(t -> t._1 <= maxSideLength) 64 | .flatMap(t -> t._2); 65 | } 66 | 67 | private static Stream center() { 68 | return Stream.of(1L); 69 | } 70 | 71 | private static int nextSideLength(int currentSideLength) { 72 | return currentSideLength + 2; 73 | } 74 | 75 | private static Stream nextRoundOfCorners(long previousCorner, int currentSideLength) { 76 | return Stream.iterate(previousCorner, n -> n + currentSideLength - 1) 77 | .drop(1) 78 | .take(4); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler29Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Stream; 22 | import java.math.BigInteger; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler29Test { 28 | 29 | /** 30 | * Problem 29: Distinct powers 31 | *

32 | * Consider all integer combinations of ab for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5: 33 | *

    34 | *
  • 22=4, 23=8, 24=16, 25=32
  • 35 | *
  • 32=9, 33=27, 34=81, 35=243
  • 36 | *
  • 42=16, 43=64, 44=256, 45=1024
  • 37 | *
  • 52=25, 53=125, 54=625, 55=3125
  • 38 | *
39 | * If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms: 40 | *

41 | * 4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125 42 | *

43 | * How many distinct terms are in the sequence generated by ab for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100? 44 | *

45 | * See also projecteuler.net problem 29. 46 | */ 47 | @Test 48 | public void shouldSolveProblem29() { 49 | assertThat(cnt(5)).isEqualTo(15); 50 | assertThat(cnt(100)).isEqualTo(9183); 51 | } 52 | 53 | private static int cnt(int max) { 54 | return Stream.rangeClosed(2, max) 55 | .map(BigInteger::valueOf) 56 | .flatMap(a -> Stream.rangeClosed(2, max).map(a::pow)) 57 | .distinct() 58 | .length(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler30Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.collection.CharSeq; 23 | import io.vavr.collection.List; 24 | import io.vavr.collection.Stream; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | /** 30 | * Problem 30: Digit fifth powers 31 | *

32 | * Surprisingly there are only three numbers that can be written as the sum of 33 | * fourth powers of their digits: 34 | *

35 |  * 1634 = 1^4 + 6^4 + 3^4 + 4^4
36 |  * 8208 = 8^4 + 2^4 + 0^4 + 8^4
37 |  * 9474 = 9^4 + 4^4 + 7^4 + 4^4
38 |  * 
39 | * 40 | * As 1 = 1^4 is not a sum it is not included. 41 | *

42 | * The sum of these numbers is 1634 + 8208 + 9474 = 19316. 43 | *

44 | * Find the sum of all the numbers that can be written as the sum of fifth 45 | * powers of their digits. 46 | *

47 | * See also 48 | * projecteuler.net problem 30 49 | * . 50 | */ 51 | public class Euler30Test { 52 | 53 | @Test 54 | public void shouldSolveProblem26() { 55 | assertThat(sumOfAllTheNumbersThatCanBeWrittenAsTheSumOfPowersOfTheirDigits(4)).isEqualTo(19316); 56 | assertThat(sumOfAllTheNumbersThatCanBeWrittenAsTheSumOfPowersOfTheirDigits(5)).isEqualTo(443_839); 57 | } 58 | 59 | private static long sumOfAllTheNumbersThatCanBeWrittenAsTheSumOfPowersOfTheirDigits(int powers) { 60 | return List.rangeClosed(10, maximalSumForPowers(powers)) 61 | .filter(i -> sumOfPowersOfDigits(powers, i) == i) 62 | .sum().longValue(); 63 | } 64 | 65 | private static long maximalSumForPowers(int powers) { 66 | return Stream.from(1) 67 | .map(i -> Tuple.of((long) Math.pow(10, i) - 1, List.fill(i, () -> Math.pow(9, powers)).sum().longValue())) 68 | .find(t -> t._1 > t._2) 69 | .map(t -> t._1).get(); 70 | } 71 | 72 | private static long sumOfPowersOfDigits(int powers, long num) { 73 | return CharSeq.of(Long.toString(num)) 74 | .map(c -> Character.digit(c, 10)) 75 | .map(d -> (long) Math.pow(d, powers)) 76 | .sum().longValue(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler31Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * Problem 31: Coin sums 28 | *

In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation:

29 | *
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
30 | *

It is possible to make £2 in the following way:

31 | *
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
32 | *

How many different ways can £2 be made using any number of coins?

33 | * See also projecteuler.net problem 31. 34 | */ 35 | public class Euler31Test { 36 | 37 | @Test 38 | public void shouldSolveProblem31() { 39 | final List coins = List.of(1, 2, 5, 10, 20, 50, 100, 200); 40 | assertThat(coinSums(200, coins)).isEqualTo(73682); 41 | } 42 | 43 | private static int coinSums(int n, List coins) { 44 | return (n == 0) ? 1 : 45 | (n < 0 || coins.isEmpty()) ? 0 : 46 | coinSums(n, coins.tail()) + coinSums(n - coins.head(), coins); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler32Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.Tuple3; 23 | import io.vavr.collection.CharSeq; 24 | import io.vavr.collection.List; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | public class Euler32Test { 30 | 31 | /** 32 | * Problem 23 Pandigital products 33 | *

34 | * We shall say that an n-digit number is pandigital if it makes use of all 35 | * the digits 1 to n exactly once; for example, the 5-digit number, 15234, 36 | * is 1 through 5 pandigital. 37 | *

38 | * The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing 39 | * multiplicand, multiplier, and product is 1 through 9 pandigital. 40 | *

41 | * Find the sum of all products whose multiplicand/multiplier/product 42 | * identity can be written as a 1 through 9 pandigital. 43 | *

44 | * HINT: Some products can be obtained in more than one way so be sure to 45 | * only include it once in your sum. 46 | *

47 | * See also projecteuler.net 48 | * problem 32. 49 | */ 50 | @Test 51 | public void shouldSolveProblem32() { 52 | assertThat(isPandigital(1, 5, "15234")).isTrue(); 53 | assertThat(isPandigital(1, 9, "39" + "186" + "7254")).isTrue(); 54 | assertThat(isPandigital(1, 5, "55555")).isFalse(); 55 | assertThat(isPandigital(1, 5, "12340")).isFalse(); 56 | assertThat(sumOfAllProductsPandigital1Through9()).isEqualTo(45228); 57 | } 58 | 59 | private static boolean isPandigital(int from, int to, String num) { 60 | return num.length() == to - from + 1 && List.rangeClosed(from, to).forAll(i -> num.contains(Integer.toString(i))); 61 | } 62 | 63 | private static final CharSeq DIGITS_1_9 = CharSeq.of("123456789"); 64 | 65 | private static long sumOfAllProductsPandigital1Through9() { 66 | return List.of(1, 2) 67 | .flatMap(i -> DIGITS_1_9.crossProduct(i) 68 | .flatMap(multiplicand -> DIGITS_1_9.removeAll(multiplicand).crossProduct(5 - i) 69 | .map(multiplier -> Tuple.of(multiplicand.mkString(), multiplier.mkString())) 70 | ) 71 | ) 72 | .map(t -> Tuple.of(t._1, t._2, Long.valueOf(t._1) * Long.valueOf(t._2))) 73 | .filter(t -> isPandigital(1, 9, t._1 + t._2 + Long.toString(t._3))) 74 | .map(Tuple3::_3) 75 | .distinct() 76 | .sum().longValue(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler34Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.collection.euler.Utils.MEMOIZED_FACTORIAL; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler34Test { 29 | 30 | /** 31 | * Problem 34 Digit factorials 32 | *

33 | * 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145. 34 | *

35 | * Find the sum of all numbers which are equal to the sum of the factorial 36 | * of their digits. 37 | *

38 | * F 39 | * Note: as 1! = 1 and 2! = 2 are not sums they are not included. 40 | *

41 | * See also projecteuler.net 42 | * problem 34. 43 | */ 44 | @Test 45 | public void shouldSolveProblem34() { 46 | assertThat(sumOfDigitFactorial(145)).isEqualTo(145); 47 | assertThat(sumOfOfAllNumbersWhichAreEqualToSumOfDigitFactorial()).isEqualTo(40730); 48 | } 49 | 50 | private static int sumOfOfAllNumbersWhichAreEqualToSumOfDigitFactorial() { 51 | return Stream.rangeClosed(3, 2_540_160) // 9! * 7 = 2 540 160 is a seven digit number, as is 9! * 8, therefor 9! * 7 is the definitive upper limit we have to investigate. 52 | .filter(i -> i == sumOfDigitFactorial(i)) 53 | .sum().intValue(); 54 | } 55 | 56 | private static int sumOfDigitFactorial(int num) { 57 | return CharSeq.of(Integer.toString(num)) 58 | .map(c -> Character.digit(c, 10)) 59 | .map(MEMOIZED_FACTORIAL) 60 | .sum().intValue(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler35Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function1; 22 | import io.vavr.collection.CharSeq; 23 | import io.vavr.collection.List; 24 | import io.vavr.collection.Stream; 25 | import java.util.function.Predicate; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | /** 31 | * Problem 35: Circular primes 32 | *

The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime.

33 | *

There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97.

34 | *

How many circular primes are there below one million?

35 | * See also projecteuler.net problem 35. 36 | */ 37 | public class Euler35Test { 38 | 39 | @Test 40 | public void shouldSolveProblem35() { 41 | assertThat(rotations(197)).isEqualTo(List.of(197, 971, 719)); 42 | assertThat(circularPrimes(100)).isEqualTo(13); 43 | assertThat(circularPrimes(1000000)).isEqualTo(55); 44 | } 45 | 46 | private static int circularPrimes(int n) { 47 | final Predicate memoizedIsPrime = Function1.of(Euler35Test::isPrime).memoized()::apply; 48 | return Stream.rangeClosed(2, n) 49 | .filter(memoizedIsPrime) 50 | .map(Euler35Test::rotations) 51 | .filter(list -> list.forAll(memoizedIsPrime)) 52 | .length(); 53 | } 54 | 55 | private static boolean isPrime(int n) { 56 | return n == 2 || n % 2 != 0 && 57 | Stream.rangeClosedBy(3, (int) Math.sqrt(n), 2) 58 | .find(x -> n % x == 0) 59 | .isEmpty(); 60 | } 61 | 62 | private static List rotations(int n) { 63 | final CharSeq seq = CharSeq.of(String.valueOf(n)); 64 | return Stream.range(0, seq.length()) 65 | .map(i -> seq.drop(i).appendAll(seq.take(i))) 66 | .map(s -> Integer.valueOf(s.toString())) 67 | .toList(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler36Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | /** 28 | * Problem 36: Double-base palindromes 29 | *

The decimal number, 585 = 10010010012 (binary), is palindromic in both bases.

30 | *

Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2.

31 | *

(Please note that the palindromic number, in either base, may not include leading zeros.)

32 | * See also projecteuler.net problem 36. 33 | */ 34 | public class Euler36Test { 35 | 36 | @Test 37 | public void shouldSolveProblem36() { 38 | assertThat(solve(1000000)).isEqualTo(872187); 39 | } 40 | 41 | private static int solve(int n) { 42 | return Stream.range(1, n) 43 | .filter(Euler36Test::isDoubleBasePalindrome) 44 | .sum().intValue(); 45 | } 46 | 47 | private static boolean isPalindrome(CharSeq seq) { 48 | return seq.dropWhile(c -> c == '0').equals(seq.reverse().dropWhile(c -> c == '0')); 49 | } 50 | 51 | private static boolean isDoubleBasePalindrome(int x) { 52 | final CharSeq seq = CharSeq.of(Integer.toString(x)); 53 | final CharSeq rev = CharSeq.of(Integer.toBinaryString(x)); 54 | return isPalindrome(seq) && isPalindrome(rev); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler37Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.List; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.API.*; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler37Test { 29 | 30 | /** 31 | * Problem 37 Truncatable primes 32 | *

33 | * The number 3797 has an interesting property. Being prime itself, it is 34 | * possible to continuously remove digits from left to right, and remain 35 | * prime at each stage: 3797, 797, 97, and 7. Similarly we can work from 36 | * right to left: 3797, 379, 37, and 3. 37 | *

38 | * Find the sum of the only eleven primes that are both truncatable from 39 | * left to right and right to left. 40 | *

41 | * NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. 42 | *

43 | * See also projecteuler.net 44 | * problem 37. 45 | */ 46 | @Test 47 | public void shouldSolveProblem37() { 48 | assertThat(isTruncatablePrime(3797)).isTrue(); 49 | List.of(2, 3, 5, 7).forEach(i -> assertThat(isTruncatablePrime(7)).isFalse()); 50 | 51 | assertThat(sumOfTheElevenTruncatablePrimes()).isEqualTo(748_317); 52 | } 53 | 54 | private static int sumOfTheElevenTruncatablePrimes() { 55 | return PrimeNumbers.primes() 56 | .filter(Euler37Test::isTruncatablePrime) 57 | .take(11) 58 | .sum().intValue(); 59 | } 60 | 61 | private static boolean isTruncatablePrime(int prime) { 62 | return Match(prime).of( 63 | Case($(p -> p > 7), p -> { 64 | final CharSeq primeSeq = CharSeq.of(Integer.toString(p)); 65 | return List.rangeClosed(1, primeSeq.length() - 1) 66 | .flatMap(i -> List.of(primeSeq.drop(i), primeSeq.dropRight(i))) 67 | .map(CharSeq::mkString) 68 | .map(Long::valueOf) 69 | .forAll(Utils.MEMOIZED_IS_PRIME::apply); 70 | }), 71 | Case($(), false) 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler38Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.List; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.API.*; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler38Test { 29 | 30 | /** 31 | * Problem 38 Pandigital multiples 32 | *

33 | * Take the number 192 and multiply it by each of 1, 2, and 3: 34 | *

35 |      * 192 × 1 = 192
36 |      * 192 × 2 = 384
37 |      * 192 × 3 = 576
38 |      * 
39 | *

40 | * By concatenating each product we get the 1 to 9 pandigital, 192384576. We 41 | * will call 192384576 the concatenated product of 192 and (1,2,3) 42 | *

43 | * The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 44 | * 4, and 5, giving the pandigital, 918273645, which is the concatenated 45 | * product of 9 and (1,2,3,4,5). 46 | *

47 | * What is the largest 1 to 9 pandigital 9-digit number that can be formed 48 | * as the concatenated product of an integer with (1,2, ... , n) where n > 49 | * 1? 50 | *

51 | * See also projecteuler.net 52 | * problem 38. 53 | */ 54 | @Test 55 | public void shouldSolveProblem38() { 56 | assertThat(isPandigitalMultiple(CharSeq.of("192384576"))).isTrue(); 57 | assertThat(isPandigitalMultiple(CharSeq.of("918273645"))).isTrue(); 58 | 59 | assertThat(largest1To9PandigitalMultiple().mkString()).isEqualTo("932718654"); 60 | } 61 | 62 | private static CharSeq largest1To9PandigitalMultiple() { 63 | return CharSeq.of("87654321") 64 | .permutations() 65 | .map(CharSeq::mkString) 66 | .map(Integer::valueOf) 67 | .sorted() 68 | .reverse() 69 | .map(i -> "9" + i) // Since 918273645 is known we don't have to investigate numbers not starting with a 9. 70 | .map(CharSeq::of) 71 | .find(Euler38Test::isPandigitalMultiple) 72 | .get(); 73 | } 74 | 75 | private static boolean isPandigitalMultiple(CharSeq pandigital) { 76 | return List.rangeClosed(1, pandigital.length() - 1) 77 | .exists(i -> isPandigitalMultipleRest(pandigital.drop(i), Integer.valueOf(pandigital.take(i).mkString()), 2)); 78 | } 79 | 80 | private static boolean isPandigitalMultipleRest(CharSeq pandigitalRest, int multiplicand, int multiplicator) { 81 | return Match(pandigitalRest.length()).of( 82 | Case($(0), true), 83 | Case($(), length -> List.rangeClosed(1, length) 84 | .find(i -> Integer.valueOf(pandigitalRest.take(i).mkString()) == multiplicand * multiplicator) 85 | .map(i -> isPandigitalMultipleRest(pandigitalRest.drop(i), multiplicand, multiplicator + 1)) 86 | .getOrElse(false) 87 | ) 88 | ); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler39Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.Tuple2; 23 | import io.vavr.Tuple3; 24 | import io.vavr.collection.List; 25 | import io.vavr.collection.Map; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static io.vavr.control.Option.some; 29 | import static java.lang.Math.floor; 30 | import static java.lang.Math.hypot; 31 | import static org.assertj.core.api.Assertions.assertThat; 32 | 33 | public class Euler39Test { 34 | 35 | /** 36 | * Problem 39 Integer right triangles 37 | *

38 | * If p is the perimeter of a right angle triangle with integral 39 | * length sides, {a,b,c}, there are exactly three solutions for 40 | * p = 120. 41 | *

42 | * {20,48,52}, {24,45,51}, {30,40,50} 43 | *

44 | * For which value of p ≤ 1000, is the number of solutions maximised? 45 | *

46 | * See also projecteuler.net 47 | * problem 39. 48 | */ 49 | @Test 50 | public void shouldSolveProblem39() { 51 | assertThat(SOLUTIONS_FOR_PERIMETERS_UP_TO_1000.get(120)).isEqualTo(some(List.of(Tuple.of(20, 48, 52), Tuple.of(24, 45, 51), Tuple.of(30, 40, 50)))); 52 | 53 | assertThat(perimeterUpTo1000WithMaximisedNumberOfSolutions()).isEqualTo(840); 54 | } 55 | 56 | private static int perimeterUpTo1000WithMaximisedNumberOfSolutions() { 57 | return SOLUTIONS_FOR_PERIMETERS_UP_TO_1000 58 | .map((perimeter, listOfSolutions) -> Tuple.of(perimeter, listOfSolutions.length())) 59 | .maxBy(Tuple2::_2) 60 | .get()._1; 61 | } 62 | 63 | private static final Map>> SOLUTIONS_FOR_PERIMETERS_UP_TO_1000 64 | = List.rangeClosed(1, 500) 65 | .flatMap(a -> List.rangeClosed(a, 500) 66 | .map(b -> Tuple.of(a, b, hypot(a, b)))) 67 | .filter(t -> floor(t._3) == t._3) 68 | .map(t -> t.map3(Double::intValue)) 69 | .groupBy(t -> t.apply((a, b, c) -> a + b + c)) 70 | .filterKeys(d -> d <= 1_000); 71 | } 72 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler40Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.CharSeq; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | public class Euler40Test { 28 | 29 | /** 30 | * Problem 40 Champernowne's constant 31 | *

32 | * An irrational decimal fraction is created by concatenating the positive 33 | * integers: 34 | *

35 | * 0.123456789101112131415161718192021... 36 | *

37 | * It can be seen that the 12th digit of the fractional part is 38 | * 1. 39 | *

40 | * If dn represents the nth digit of the 41 | * fractional part, find the value of the following expression. 42 | *

43 |      * d1 × d10 × d100 × d1000 × d10000 × d100000 × d1000000
44 |      * 
45 | *

46 | * See also projecteuler.net 47 | * problem 40. 48 | */ 49 | @Test 50 | public void shouldSolveProblem40() { 51 | assertThat(decimalDigitAtPosition(12)).isEqualTo('1'); 52 | 53 | assertThat(solution()).isEqualTo(210); 54 | } 55 | 56 | private static int solution() { 57 | return Stream.iterate(1, i -> i * 10) 58 | .takeWhile(i -> i <= 1_000_000) 59 | .map(Euler40Test::decimalDigitAtPosition) 60 | .map(c -> Character.digit(c, 10)) 61 | .fold(1, (i1, i2) -> i1 * i2); 62 | } 63 | 64 | private static char decimalDigitAtPosition(int num) { 65 | return FIRST_1_000_000_DECIMALS.get(num - 1); 66 | } 67 | 68 | private static final Stream FIRST_1_000_000_DECIMALS = Stream.from(1) 69 | .map(i -> i.toString()) 70 | .flatMap(CharSeq::of) 71 | .take(1_000_000); 72 | } 73 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler41Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.collection.Stream; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import static io.vavr.collection.euler.Utils.isPrime; 26 | import static java.util.Comparator.reverseOrder; 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | public class Euler41Test { 30 | 31 | /** 32 | * Problem 41 Pandigital prime 33 | *

34 | * We shall say that an n-digit number is pandigital if it makes use 35 | * of all the digits 1 to n exactly once. For example, 2143 is a 36 | * 4-digit pandigital and is also prime. 37 | * 38 | * What is the largest n-digit pandigital prime that exists? 39 | *

40 | * See also projecteuler.net 41 | * problem 41. 42 | */ 43 | @Test 44 | public void shouldSolveProblem41() { 45 | assertThat(nDigitPandigitalNumbers(4)).contains(2143); 46 | assertThat(isPrime(2143)).isTrue(); 47 | 48 | assertThat(largestNPandigitalPrime()).isEqualTo(7652413); 49 | } 50 | 51 | private static int largestNPandigitalPrime() { 52 | return Stream.rangeClosedBy(9, 1, -1) 53 | .flatMap(n -> nDigitPandigitalNumbers(n) 54 | .filter(Utils::isPrime) 55 | .sorted(reverseOrder())) 56 | .head(); 57 | } 58 | 59 | private static List nDigitPandigitalNumbers(int n) { 60 | return List.rangeClosed(1, n) 61 | .permutations() 62 | .map(List::mkString) 63 | .map(Integer::valueOf); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler45Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.collection.Stream; 23 | import org.assertj.core.api.Assertions; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler45Test { 29 | 30 | /** 31 | * Problem 45 Triangular, pentagonal, and hexagonal 32 | * 33 | *

Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:

34 | *

Triangle Tn=n(n+1)/2 1, 3, 6, 10, 15, ...

35 | *

Pentagonal Pn=n(3n−1)/2 1, 5, 12, 22, 35, ...

36 | *

Hexagonal Hn=n(2n−1) 1, 6, 15, 28, 45, ...

37 | * 38 | *

39 | * It can be verified that T285 = P165 = H143 = 40755. 40 | * Find the next triangle number that is also pentagonal and hexagonal. 41 | *

42 | * 43 | * See also projecteuler.net 44 | * problem 45. 45 | */ 46 | 47 | @Test 48 | public void shouldSolveProblem45() { 49 | assertThat(List.of(5, 12, 22, 35)).allMatch(Euler45Test::isPentagonal); 50 | assertThat(List.of(3, 11, 21, 36)).allMatch(i -> !isPentagonal(i)); 51 | Assertions.assertThat(HEXAGONAL.take(5)).containsExactly(6L, 15L, 28L, 45L, 66L); 52 | 53 | assertThat(HEXAGONAL 54 | .filter(Euler45Test::isPentagonal) 55 | .head()) 56 | .isEqualTo(40755); 57 | 58 | assertThat(HEXAGONAL 59 | .filter(Euler45Test::isPentagonal) 60 | .tail() 61 | .head()) 62 | .isEqualTo(1533776805L); 63 | } 64 | 65 | private static final Stream HEXAGONAL = Stream.from(2L).map(i -> i*(2*i -1)); 66 | 67 | private static boolean isPentagonal(long i) { 68 | // If a number k is pentagonal then n(3n−1)/2 = k; for some integer n 69 | // by the quadratic formula (1+sqrt(1+4*3*2k))/6 = n 70 | long discriminant = 1+24*i; 71 | return isPerfectSquare(discriminant) && (1 + flooredRoot(discriminant)) % 6 == 0; 72 | } 73 | 74 | private static boolean isPerfectSquare(long i) { 75 | long sqrtFloor = flooredRoot(i); 76 | return sqrtFloor*sqrtFloor == i; 77 | } 78 | 79 | private static long flooredRoot(long i) { 80 | return (long)Math.sqrt(i+0.5); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler48Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.Stream; 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | public class Euler48Test { 27 | 28 | private static final long MOD = 10_000_000_000L; 29 | 30 | /** 31 | * Problem 48: Self powers 32 | *

33 | * The series, 11 + 22 + 33 + ... + 1010 = 10405071317. 34 | *

35 | * Find the last ten digits of the series, 11 + 22 + 33 + ... + 10001000. 36 | *

37 | * See also projecteuler.net problem 48. 38 | */ 39 | @Test 40 | public void shouldSolveProblem48() { 41 | assertThat(sumPowers(10)).isEqualTo(405_071_317L); 42 | assertThat(sumPowers(1000)).isEqualTo(9_110_846_700L); 43 | } 44 | 45 | private static long sumPowers(int max) { 46 | return Stream.range(1, max) 47 | .map(Euler48Test::selfPower) 48 | .reduce(Euler48Test::sumMod); 49 | } 50 | 51 | private static long selfPower(long v) { 52 | final Stream powers = Stream.iterate(v, el -> multMod(el, el)); 53 | return bits(v) 54 | .map(powers::get) 55 | .prepend(1L) 56 | .reduce(Euler48Test::multMod); 57 | } 58 | 59 | private static long multMod(long v1, long v2) { 60 | final Stream shifts = Stream.iterate(v1, el -> sumMod(el, el)); 61 | return bits(v2) 62 | .map(shifts::get) 63 | .prepend(0L) 64 | .reduce(Euler48Test::sumMod); 65 | } 66 | 67 | private static long sumMod(long v1, long v2) { 68 | return (v1 + v2) % MOD; 69 | } 70 | 71 | private static Stream bits(long v) { 72 | return Stream.from(0) 73 | .takeWhile(b -> (v >> b) > 0) 74 | .filter(b -> ((v >> b) & 1) != 0); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler55Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.collection.List; 22 | import io.vavr.collection.Stream; 23 | import java.math.BigInteger; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler55Test { 29 | 30 | /** 31 | * Problem 55: Lychrel numbers 32 | *

33 | * If we take 47, reverse and add, 47 + 74 = 121, which is palindromic. 34 | *

35 | * Not all numbers produce palindromes so quickly. For example, 36 | *

    37 | *
  • 349 + 943 = 1292 38 | *
  • 1292 + 2921 = 4213 39 | *
  • 4213 + 3124 = 7337 40 | *
41 | * That is, 349 took three iterations to arrive at a palindrome. 42 | *

43 | * Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. 44 | * A number that never forms a palindrome through the reverse and add process is called a Lychrel number. 45 | * Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume 46 | * that a number is Lychrel until proven otherwise. In addition you are given that for every number 47 | * below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, 48 | * (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. 49 | * In fact, 10677 is the first number to be shown to require over fifty iterations 50 | * before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits). 51 | *

52 | * Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; 53 | * the first example is 4994. 54 | *

55 | * How many Lychrel numbers are there below ten-thousand? 56 | *

57 | * See also projecteuler.net problem 55. 58 | */ 59 | @Test 60 | public void shouldSolveProblem55() { 61 | assertThat(solve()).isEqualTo(249); 62 | } 63 | 64 | private static int solve() { 65 | return Stream.range(1, 10_000) 66 | .filter(Euler55Test::isLychrel) 67 | .length(); 68 | } 69 | 70 | private static boolean isLychrel(int n) { 71 | return Stream.iterate(String.valueOf(n), Euler55Test::next) 72 | .tail() // Surprisingly, there are palindromic numbers that are themselves Lychrel numbers 73 | .take(50) 74 | .find(Utils::isPalindrome) 75 | .isEmpty(); 76 | } 77 | 78 | private static String next(String s) { 79 | return List.of(s, Utils.reverse(s)) 80 | .map(BigInteger::new) 81 | .reduce(BigInteger::add) 82 | .toString(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler57Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.Tuple2; 23 | import io.vavr.collection.Stream; 24 | import java.math.BigDecimal; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | public class Euler57Test { 30 | 31 | /** 32 | * Problem 57: Square root convergents 33 | *

34 | * It is possible to show that the square root of two can be expressed as an infinite continued fraction. 35 | *

36 | * √ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213... 37 | *

38 | * By expanding this for the first four iterations, we get: 39 | *

    40 | *
  • 1 + 1/2 = 3/2 = 1.5
  • 41 | *
  • 1 + 1/(2 + 1/2) = 7/5 = 1.4
  • 42 | *
  • 1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
  • 43 | *
  • 1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...
  • 44 | *
45 | * The next three expansions are 99/70, 239/169, and 577/408, but the eighth expansion, 1393/985, 46 | * is the first example where the number of digits in the numerator exceeds the number of digits in the denominator. 47 | *

48 | * In the first one-thousand expansions, how many fractions contain a numerator with more digits than denominator? 49 | *

50 | * See also projecteuler.net problem 57. 51 | */ 52 | @Test 53 | public void shouldSolveProblem57() { 54 | assertThat(cnt()).isEqualTo(153); 55 | } 56 | 57 | private static int cnt() { 58 | return fractions() 59 | .take(1000) 60 | .filter(f -> f._1.toPlainString().length() > f._2.toPlainString().length()) 61 | .length(); 62 | } 63 | 64 | private static Stream> fractions() { 65 | return Stream.iterate(Tuple.of(BigDecimal.ONE, BigDecimal.ONE), Euler57Test::it); 66 | } 67 | 68 | /** 69 | * a/b -> 1 + 1/(1 + a/b) = (a + 2b)/(a + b) 70 | */ 71 | private static Tuple2 it(Tuple2 val) { 72 | return Tuple.of(val._1.add(val._2.add(val._2)), val._1.add(val._2)); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler67Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function3; 22 | import io.vavr.collection.Vector; 23 | import java.util.Arrays; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler67Test { 29 | 30 | /** 31 | * Problem 67: Maximum path sum II 32 | *

33 | * By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. 34 | *

35 |      *        3
36 |      *       7 4
37 |      *      2 4 6
38 |      *     8 5 9 3
39 |      * 
40 | * That is, 3 + 7 + 4 + 9 = 23. 41 | *

42 | * Find the maximum total from top to bottom in p067_triangle.txt, a 15K text file containing a triangle with one-hundred rows. 43 | *

44 | * NOTE: This is a much more difficult version of Problem 18. 45 | *

46 | * See also projecteuler.net problem 67. 47 | */ 48 | @Test 49 | public void shouldSolveProblem67() { 50 | assertThat(solve("small_triangle.txt")).isEqualTo(23); 51 | assertThat(solve("p067_triangle.txt")).isEqualTo(7273); 52 | } 53 | 54 | private static int solve(String fileName) { 55 | return smart.apply(loadTriangle(fileName), 0, 0); 56 | } 57 | 58 | private final static Function3>, Integer, Integer, Integer> smart = Function3.of( 59 | (Vector> tr, Integer row, Integer col) -> { 60 | int value = tr.get(row).get(col); 61 | if (row == tr.length() - 1) { 62 | return tr.get(row).get(col); 63 | } else { 64 | return value + Math.max(Euler67Test.smart.apply(tr, row + 1, col), Euler67Test.smart.apply(tr, row + 1, col + 1)); 65 | } 66 | } 67 | ).memoized(); 68 | 69 | static Vector> loadTriangle(String fileName) { 70 | return Vector.ofAll( 71 | Utils.readLines(Utils.file(fileName)).map(line -> 72 | Arrays.stream(line.split("\\s")).map(Integer::parseInt) 73 | ).map(s -> Vector.ofAll(s::iterator)) 74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler71Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.Tuple4; 23 | import io.vavr.collection.Stream; 24 | import org.junit.jupiter.api.Test; 25 | 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler71Test { 29 | 30 | /** 31 | * Problem 71: Ordered fractions 32 | *

33 | * Consider the fraction, n/d, where n and d are positive integers. If n 35 | * If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get: 36 | *

37 | * 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8 38 | *

39 | * It can be seen that 2/5 is the fraction immediately to the left of 3/7. 40 | *

41 | * By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7. 42 | *

43 | * See also projecteuler.net problem 71. 44 | */ 45 | @Test 46 | public void shouldSolveProblem71() { 47 | assertThat(left37(8)).isEqualTo(2); 48 | assertThat(left37(1_000_000)).isEqualTo(428_570); 49 | } 50 | 51 | private static int left37(int maxDenominator) { 52 | return Stream.iterate(Tuple.of(0, 1, 1, 1), (Tuple4 t) -> { 53 | final int m1 = t._1 + t._3; 54 | final int m2 = t._2 + t._4; 55 | if (m1 * 7 >= m2 * 3) { 56 | return Tuple.of(t._1, t._2, m1, m2); 57 | } else { 58 | return Tuple.of(m1, m2, t._3, t._4); 59 | } 60 | }).takeWhile(t -> t._2 <= maxDenominator && t._4 <= maxDenominator).last()._1; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Euler99Test.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import static io.vavr.collection.euler.Utils.file; 24 | import static io.vavr.collection.euler.Utils.readLines; 25 | import static java.util.Arrays.asList; 26 | import static org.assertj.core.api.Assertions.assertThat; 27 | 28 | public class Euler99Test { 29 | 30 | /** 31 | * Problem 99: Largest exponential 32 | *

33 | * Comparing two numbers written in index form like 211 and 37 is not difficult, 34 | * as any calculator would confirm that 211 = 2048 < 37 = 2187. 35 | *

36 | * However, confirming that 632382518061 > 519432525806 would be much more difficult, 37 | * as both numbers contain over three million digits. 38 | *

39 | * Using p099_base_exp.txt, a 22K text file containing one thousand lines with a base/exponent pair on each line, 40 | * determine which line number has the greatest numerical value. 41 | *

42 | * See also projecteuler.net problem 99. 43 | */ 44 | @Test 45 | public void shouldSolveProblem99() { 46 | assertThat(solve()).isEqualTo(709); 47 | } 48 | 49 | private static long solve() { 50 | return readLines(file("p099_base_exp.txt")) 51 | .flatMap(s -> asList(s.split(","))) 52 | .map(Integer::parseInt) 53 | .grouped(2) 54 | .map(t -> t.get(1) * Math.log(t.get(0))) 55 | .zipWithIndex() 56 | .reduce((t1, t2) -> t1._1 > t2._1 ? t1 : t2) 57 | ._2 + 1; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/PrimeNumbers.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Tuple; 22 | import io.vavr.collection.HashMap; 23 | import io.vavr.collection.Set; 24 | import io.vavr.collection.Stream; 25 | import io.vavr.collection.TreeSet; 26 | 27 | final class PrimeNumbers { 28 | 29 | private static final Set PRIMES_2_000_000 = Sieve.fillSieve(2_000_000, TreeSet.empty()); 30 | 31 | private PrimeNumbers() { 32 | } 33 | 34 | static Stream primes() { 35 | return Stream.ofAll(PRIMES_2_000_000); 36 | } 37 | 38 | static HashMap factorization(long num) { 39 | if (num == 1) { 40 | return HashMap.empty(); 41 | } else { 42 | return primeFactors(num) 43 | .map(p -> HashMap.of(Tuple.of(p, 1L)) 44 | .merge(factorization(num / p), (a, b) -> a + b)) 45 | .getOrElse(HashMap::empty); 46 | } 47 | } 48 | 49 | static Stream primeFactors(long num) { 50 | return Stream.rangeClosed(2L, (int) Math.sqrt(num)) 51 | .find(d -> num % d == 0) 52 | .map(d -> Stream.cons(d, () -> primeFactors(num / d))) 53 | .getOrElse(() -> Stream.of(num)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/collection/euler/Sieve.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.collection.euler; 20 | 21 | import io.vavr.Function2; 22 | import io.vavr.Function3; 23 | import io.vavr.collection.List; 24 | import io.vavr.collection.Set; 25 | import io.vavr.collection.Stream; 26 | import io.vavr.control.Option; 27 | 28 | final class Sieve { 29 | 30 | private Sieve() { 31 | } 32 | 33 | private final static List>> RULES = List.of( 34 | (x, y) -> Option.of((4 * x * x) + (y * y)).filter(n -> n % 12 == 1 || n % 12 == 5), 35 | (x, y) -> Option.of((3 * x * x) + (y * y)).filter(n -> n % 12 == 7), 36 | (x, y) -> Option.of((3 * x * x) - (y * y)).filter(n -> x > y && n % 12 == 11) 37 | ); 38 | 39 | private final static List, Integer, Integer, Set>> STEPS = List.of( 40 | (sieve, limit, root) -> Stream.rangeClosed(1, root).crossProduct() 41 | .foldLeft(sieve, (xs, xy) -> 42 | RULES.foldLeft(xs, (ss, r) -> r.apply(xy._1, xy._2) 43 | .filter(p -> p < limit) 44 | .map(p -> ss.contains(p) ? ss.remove(p) : ss.add(p)) 45 | .getOrElse(ss) 46 | ) 47 | ), 48 | (sieve, limit, root) -> Stream.rangeClosed(5, root) 49 | .foldLeft(sieve, (xs, r) -> xs.contains(r) 50 | ? Stream.rangeBy(r * r, limit, r * r).foldLeft(xs, Set::remove) 51 | : xs 52 | ) 53 | ); 54 | 55 | static Set fillSieve(int limit, Set empty) { 56 | return STEPS.foldLeft(empty.add(2).add(3), (s, step) -> 57 | step.apply(s, limit, (int) Math.ceil(Math.sqrt(limit))) 58 | ); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/concurrent/Concurrent.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package io.vavr.concurrent; 20 | 21 | import io.vavr.CheckedFunction0; 22 | import io.vavr.control.Try; 23 | import java.util.Random; 24 | import java.util.concurrent.ForkJoinPool; 25 | import java.util.concurrent.TimeUnit; 26 | import java.util.concurrent.TimeoutException; 27 | import java.util.function.Supplier; 28 | 29 | import static org.assertj.core.api.Assertions.fail; 30 | 31 | final class Concurrent { 32 | 33 | private static final Random RND = new Random(); 34 | 35 | // Max sleep time to delay computation 36 | private static final int SLEEP_MAX_MILLIS = 150; 37 | 38 | private Concurrent() { 39 | } 40 | 41 | static void waitUntil(Supplier condition) { 42 | long millis = 1; 43 | boolean interrupted = false; 44 | while (!interrupted && !condition.get()) { 45 | if (millis > 4096) { 46 | fail("Condition not met."); 47 | } else { 48 | try { 49 | Thread.sleep(millis); 50 | millis = millis << 1; 51 | } catch(InterruptedException x) { 52 | interrupted = true; 53 | } 54 | } 55 | } 56 | } 57 | 58 | /** 59 | * Block current thread a random time between 0 and {@link #SLEEP_MAX_MILLIS} ms. 60 | */ 61 | static void zZz() { 62 | Try.run(() -> Thread.sleep(RND.nextInt(SLEEP_MAX_MILLIS))); 63 | } 64 | 65 | static CheckedFunction0 zZz(T value) { 66 | return () -> { 67 | zZz(); 68 | return value; 69 | }; 70 | } 71 | 72 | static CheckedFunction0 zZz(X exception) { 73 | return () -> { 74 | zZz(); 75 | throw exception; 76 | }; 77 | } 78 | 79 | static void gracefullyFinishThreads() throws TimeoutException { 80 | final boolean isQuiescent = ForkJoinPool.commonPool().awaitQuiescence(1L, TimeUnit.MINUTES); 81 | if (isQuiescent) { 82 | System.out.println("ForkJoinPool.commonPool() is quiecent"); 83 | } else { 84 | throw new TimeoutException("Timeout while waiting for running threads in ForkJoinPool.commonPool() to finish."); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vavr/src/test/java/io/vavr/issues/Issue2559Test.java: -------------------------------------------------------------------------------- 1 | package io.vavr.issues; 2 | 3 | import io.vavr.Tuple2; 4 | import io.vavr.collection.HashSet; 5 | import io.vavr.collection.Set; 6 | import java.util.Objects; 7 | import org.junit.jupiter.api.BeforeEach; 8 | import org.junit.jupiter.api.Test; 9 | 10 | import static org.assertj.core.api.Assertions.assertThat; 11 | 12 | /** 13 | * partition method seems to not work correctly, comparing to scala 14 | * https://github.com/vavr-io/vavr/issues/2559 15 | */ 16 | public class Issue2559Test { 17 | 18 | private java.util.Map fruitsBeingEaten = new java.util.HashMap<>(); 19 | 20 | @BeforeEach 21 | public void setUp() { 22 | fruitsBeingEaten = new java.util.HashMap<>(); 23 | } 24 | 25 | @Test 26 | public void partitionShouldBeUnique() { 27 | final Set fruitsToEat = HashSet.of("apple", "banana"); 28 | final Tuple2, ? extends Set> partition = fruitsToEat.partition(this::biteAndCheck); 29 | assertThat(partition._1).isEmpty(); 30 | assertThat(partition._2).isEqualTo(HashSet.of("apple", "banana")); 31 | assertThat(fruitsBeingEaten) 32 | .hasSize(2) 33 | .containsEntry("apple", new Eat(1, "apple")) 34 | .containsEntry("banana", new Eat(1, "banana")); 35 | } 36 | 37 | private boolean biteAndCheck(String name) { 38 | final Eat eat = fruitsBeingEaten.getOrDefault(name, Eat.prepare(name)).bite(); 39 | fruitsBeingEaten.put(name, eat); 40 | return eat.isEaten(); 41 | } 42 | 43 | private static class Eat { 44 | final int bites; 45 | final String name; 46 | 47 | public static Eat prepare(String name) { 48 | return new Eat(0, name); 49 | } 50 | 51 | private Eat(int bites, String name) { 52 | this.bites = bites; 53 | this.name = name; 54 | } 55 | 56 | public Eat bite() { 57 | return new Eat(bites + 1, name); 58 | } 59 | 60 | public boolean isEaten() { 61 | return bites >= 2; 62 | } 63 | 64 | @Override 65 | public boolean equals(Object o) { 66 | if (this == o) return true; 67 | if (!(o instanceof Eat)) return false; 68 | Eat eat = (Eat) o; 69 | return bites == eat.bites && Objects.equals(name, eat.name); 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | return Objects.hash(bites, name); 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "Eat{" + 80 | "bites=" + bites + 81 | ", name='" + name + '\'' + 82 | '}'; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /vavr/src/test/java/outside_of_vavr/IllegalAccessErrorTest.java: -------------------------------------------------------------------------------- 1 | /* ____ ______________ ________________________ __________ 2 | * \ \/ / \ \/ / __/ / \ \/ / \ 3 | * \______/___/\___\______/___/_____/___/\___\______/___/\___\ 4 | * 5 | * Copyright 2014-2025 Vavr, https://vavr.io 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | package outside_of_vavr; 20 | 21 | import io.vavr.collection.Array; 22 | import io.vavr.collection.BitSet; 23 | import io.vavr.collection.HashMap; 24 | import io.vavr.collection.List; 25 | import java.util.function.BiFunction; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | public class IllegalAccessErrorTest { 31 | 32 | @Test 33 | public void shouldNotThrowIllegalAccessErrorWhenUsingHashMapMergeMethodReference() { 34 | final BiFunction, HashMap, HashMap> merge = HashMap::merge; 35 | final HashMap reduced = Array.of("a", "b", "c") 36 | .map(t -> HashMap.of(t, t)) 37 | .reduce(merge); 38 | assertThat(reduced).isEqualTo(HashMap.of("a", "a", "b", "b", "c", "c")); 39 | } 40 | 41 | @Test 42 | public void shouldNotThrowIllegalAccessErrorWhenUsingBitSetAddAllMethodReference() { 43 | final BiFunction, BitSet, BitSet> union = BitSet::union; 44 | final BitSet reduced = List.of(BitSet.of(1, 2, 3), BitSet.of(2, 3, 4)).reduce(union); 45 | assertThat(reduced).isEqualTo(BitSet.of(1, 2, 3, 4)); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /vavr/src/test/resources/io/vavr/collection/euler/p018_triangle.txt: -------------------------------------------------------------------------------- 1 | 75 2 | 95 64 3 | 17 47 82 4 | 18 35 87 10 5 | 20 04 82 47 65 6 | 19 01 23 75 03 34 7 | 88 02 77 73 07 63 67 8 | 99 65 04 28 06 16 70 92 9 | 41 41 26 56 83 40 80 70 33 10 | 41 48 72 33 47 32 37 16 94 29 11 | 53 71 44 65 25 43 91 52 97 51 14 12 | 70 11 33 28 77 73 17 78 39 68 17 57 13 | 91 71 52 38 17 14 91 43 58 50 27 29 48 14 | 63 66 04 68 89 53 67 30 73 16 69 87 40 31 15 | 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 16 | -------------------------------------------------------------------------------- /vavr/src/test/resources/io/vavr/collection/euler/small_triangle.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 7 4 3 | 2 4 6 4 | 8 5 9 3 5 | -------------------------------------------------------------------------------- /vavr/src/test/resources/junit-platform.properties: -------------------------------------------------------------------------------- 1 | junit.jupiter.execution.parallel.enabled = true 2 | junit.jupiter.execution.parallel.mode.default = concurrent 3 | --------------------------------------------------------------------------------