dtonhofer

dtonhofer

Functional Programming in Java, Second Edition: Functional Programming in Java, Second Edition: JUnit code improvements for Chapter 11, pages 195 ff “Refactoring Nested Loops"

Nothing surprising here, just adapting the form to the other examples.

Ah yes, compute() now returns an immutable list in all cases.

package chapter11;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NestedLoopTest {

    record Triple(int a, int b, int c) {
        public String toString() {
            return String.format("%d %d %d", a, b, c);
        }
    }

    private static Triple triple(int a, int b, int c) {
        return new Triple(a, b, c);
    }

    interface PythagoreanTriples {
        List<Triple> compute(int numberOfValues);
    }

    // (m² - n², 2 * m * n, m² + n²) is a valid triple because, resolving
    // (m⁴ + n⁴ - 2 * m² * n²) + (4 * m² * n²) = m⁴ + n⁴ + 2 * m² * n²
    // assuming m > n

    private static Triple getTripleEuclidsWay(final int m, final int n) {
        if (m <= n) {
            throw new IllegalArgumentException("m <= n");
        }
        final int a = m * m - n * n;
        final int b = 2 * m * n;
        final int c = m * m + n * n;
        return triple(a, b, c);
    }

    static class PythagoreanTriplesBefore implements PythagoreanTriples {

        public List<Triple> compute(int tripleCount) {
            if (tripleCount == 0) {
                return List.of(); // unmodifiable
            }
            List<Triple> triples = new ArrayList<>();
            for (int m = 2; ; m++) {
                for (int n = 1; n < m; n++) {
                    triples.add(getTripleEuclidsWay(m, n));
                    if (triples.size() == tripleCount)
                        break;
                }
                if (triples.size() == tripleCount)
                    break;
            }
            return Collections.unmodifiableList(triples);
        }
    }

    static class PythagoreanTriplesAfter implements PythagoreanTriples {

        public List<Triple> compute(int tripleCount) {
            return Stream.iterate(2, e -> e + 1)
                    .flatMap(m -> IntStream.range(1, m).mapToObj(n -> getTripleEuclidsWay(m, n)))
                    .limit(tripleCount)
                    .toList();
        }

    }

    private static void commonPythagoreanTriplesTests(final PythagoreanTriples pytris) {
        assertAll(
                () -> assertEquals(List.of(), pytris.compute(0)),
                () -> assertEquals(List.of(triple(3, 4, 5)),
                        pytris.compute(1)),
                () -> assertEquals(
                        List.of(triple(3, 4, 5), triple(8, 6, 10), triple(5, 12, 13)),
                        pytris.compute(3)),
                () -> assertEquals(
                        List.of(triple(3, 4, 5), triple(8, 6, 10),
                                triple(5, 12, 13), triple(15, 8, 17),
                                triple(12, 16, 20)),
                        pytris.compute(5))
        );
    }

    @Test
    void pythagoreanTriplesBefore() {
        commonPythagoreanTriplesTests(new PythagoreanTriplesBefore());
    }

    @Test
    void pythagoreanTriplesAfter() {
        commonPythagoreanTriplesTests(new PythagoreanTriplesAfter());
    }
}

Where Next?

Popular Pragmatic Bookshelf topics Top

jimschubert
In Chapter 3, the source for index introduces Config on page 31, followed by more code including tests; Config isn’t introduced until pag...
New
iPaul
page 37 ANTLRInputStream input = new ANTLRInputStream(is); as of ANTLR 4 .8 should be: CharStream stream = CharStreams.fromStream(i...
New
GilWright
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
mikecargal
Title: Hands-On Rust (Chap 8 (Adding a Heads Up Display) It looks like ​.with_simple_console_no_bg​(SCREEN_WIDTH*2, SCREEN_HEIGHT*2...
New
leba0495
Hello! Thanks for the great book. I was attempting the Trie (chap 17) exercises and for number 4 the solution provided for the autocorre...
New
curtosis
Running mix deps.get in the sensor_hub directory fails with the following error: ** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
jskubick
I think I might have found a problem involving SwitchCompat, thumbTint, and trackTint. As entered, the SwitchCompat changes color to hol...
New
adamwoolhether
Is there any place where we can discuss the solutions to some of the exercises? I can figure most of them out, but am having trouble with...
New
akraut
The markup used to display the uploaded image results in a Phoenix.LiveView.HTMLTokenizer.ParseError error. lib/pento_web/live/product_l...
New
andreheijstek
After running /bin/setup, the first error was: The foreman' command exists in these Ruby versions: That was easy to fix: gem install fore...
New

Other popular topics Top

Devtalk
Hello Devtalk World! Please let us know a little about who you are and where you’re from :nerd_face:
New
Devtalk
Reading something? Working on something? Planning something? Changing jobs even!? If you’re up for sharing, please let us know what you’...
1062 22827 403
New
PragmaticBookshelf
Write Elixir tests that you can be proud of. Dive into Elixir’s test philosophy and gain mastery over the terminology and concepts that u...
New
Rainer
My first contact with Erlang was about 2 years ago when I used RabbitMQ, which is written in Erlang, for my job. This made me curious and...
New
Margaret
Hello everyone! This thread is to tell you about what authors from The Pragmatic Bookshelf are writing on Medium.
1147 29994 760
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
DevotionGeo
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New
First poster: bot
zig/http.zig at 7cf2cbb33ef34c1d211135f56d30fe23b6cacd42 · ziglang/zig. General-purpose programming language and toolchain for maintaini...
New
PragmaticBookshelf
Develop, deploy, and debug BEAM applications using BEAMOps: a new paradigm that focuses on scalability, fault tolerance, and owning each ...
New
PragmaticBookshelf
Use advanced functional programming principles, practical Domain-Driven Design techniques, and production-ready Elixir code to build scal...
New

Latest in Functional Programming in Java, Second Edition

Functional Programming in Java, Second Edition Portal

Sub Categories: