/* __ __ __ __ __ ___ * \ \ / / \ \ / / __/ * \ \/ / /\ \ \/ / / * \____/__/ \__\____/__/.ɪᴏ * ᶜᵒᵖʸʳᶦᵍʰᵗ ᵇʸ ᵛᵃᵛʳ ⁻ ˡᶦᶜᵉⁿˢᵉᵈ ᵘⁿᵈᵉʳ ᵗʰᵉ ᵃᵖᵃᶜʰᵉ ˡᶦᶜᵉⁿˢᵉ ᵛᵉʳˢᶦᵒⁿ ᵗʷᵒ ᵈᵒᵗ ᶻᵉʳᵒ */ package io.vavr.collection.euler; import io.vavr.collection.CharSeq; import io.vavr.collection.List; import org.junit.Test; import static io.vavr.API.*; import static org.assertj.core.api.Assertions.assertThat; public class Euler37Test { /** * <strong>Problem 37 Truncatable primes</strong> * <p> * The number 3797 has an interesting property. Being prime itself, it is * possible to continuously remove digits from left to right, and remain * prime at each stage: 3797, 797, 97, and 7. Similarly we can work from * right to left: 3797, 379, 37, and 3. * <p> * Find the sum of the only eleven primes that are both truncatable from * left to right and right to left. * <p> * NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. * <p> * See also <a href="https://projecteuler.net/problem=37">projecteuler.net * problem 37</a>. */ @Test public void shouldSolveProblem37() { assertThat(isTruncatablePrime(3797)).isTrue(); List.of(2, 3, 5, 7).forEach(i -> assertThat(isTruncatablePrime(7)).isFalse()); assertThat(sumOfTheElevenTruncatablePrimes()).isEqualTo(748_317); } private static int sumOfTheElevenTruncatablePrimes() { return PrimeNumbers.primes() .filter(Euler37Test::isTruncatablePrime) .take(11) .sum().intValue(); } private static boolean isTruncatablePrime(int prime) { return Match(prime).of( Case($(p -> p > 7), p -> { final CharSeq primeSeq = CharSeq.of(Integer.toString(p)); return List.rangeClosed(1, primeSeq.length() - 1) .flatMap(i -> List.of(primeSeq.drop(i), primeSeq.dropRight(i))) .map(CharSeq::mkString) .map(Long::valueOf) .forAll(Utils.MEMOIZED_IS_PRIME::apply); }), Case($(), false) ); } }