Day3.java

1
package com.roxoft.aoc.y2015.Day3;
2
3
import com.roxoft.aoc.UnexpectedSolutionException;
4
import com.roxoft.lib.IntegerCoord2D;
5
import com.roxoft.lib.Movable2DEntity;
6
7
import java.util.ArrayList;
8
import java.util.List;
9
10
public final class Day3 {
11
    /** List of instructions to follow. */
12
    private final String instructions;
13
    /** The {@link List} of {@link Movable2DEntity}s that will be visiting houses. */
14
    private final List<Movable2DEntity> santas;
15
    /** Which {@link Movable2DEntity} is receiving the next instruction. **/
16
    private int santaFocus = 0;
17
18
    /**
19
     * @param santaNumber the number of the desired {@link Movable2DEntity}.
20
     * @return The {@link Movable2DEntity} identified by the provided santaNumber
21
     */
22
    public Movable2DEntity getSanta(final int santaNumber) {
23 1 1. getSanta : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::getSanta → KILLED
        return santas.get(santaNumber);
24
    }
25
26
    private Day3(final String instructionSequence) {
27
        instructions = instructionSequence;
28
        santas = new ArrayList<>();
29
    }
30
31
    private Day3(final String instructionSequence, final List<Movable2DEntity> predefinedSantas) {
32
        instructions = instructionSequence;
33
        santas = predefinedSantas;
34
    }
35
36
    /**
37
     * @param instructionSequence A {@link String} representing a series of instructions
38
     *
39
     * @return A {@link Day3} object ready for solving the problem.
40
     */
41
    public static Day3 of(final String instructionSequence) {
42 1 1. of : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::of → KILLED
        return new Day3(instructionSequence);
43
    }
44
45
    /**
46
     * @return A new {@link Day3} object that is a clone of this one with an additional {@link Movable2DEntity} at {@link IntegerCoord2D} (0,0)
47
     */
48
    public Day3 withNewSanta() {
49 1 1. withNewSanta : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::withNewSanta → KILLED
        return withASantaAt(IntegerCoord2D.of(0, 0));
50
    }
51
52
    /**
53
     * @param location the {@link IntegerCoord2D} location of the new {@link Movable2DEntity}
54
     *
55
     * @return A new {@link Day3} object that is a clone of this one with an additional {@link Movable2DEntity} at the provided {@link IntegerCoord2D} location
56
     */
57
    public Day3 withASantaAt(final IntegerCoord2D location) {
58
        final List<Movable2DEntity> newSantaList = santas;
59
        newSantaList.add(Movable2DEntity.at(location));
60 1 1. withASantaAt : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::withASantaAt → KILLED
        return new Day3(
61
                instructions,
62
                newSantaList
63
        );
64
    }
65
66
    /**
67
     * @return The number of unique houses visited by all {@link Movable2DEntity}s currently
68
     */
69
    public long getNumberOfVisitedHouses() {
70 1 1. getNumberOfVisitedHouses : replaced long return with 0 for com/roxoft/aoc/y2015/Day3/Day3::getNumberOfVisitedHouses → KILLED
        return santas
71
                .stream()
72
                .map(Movable2DEntity::locationHistory)
73
                .flatMap(List::stream)
74
                .distinct()
75
                .count();
76
    }
77
78
    /**
79
     * @return An updated {@link Day3} object where all instructions have been followed
80
     */
81
    public Day3 followInstructions() {
82 2 1. followInstructions : changed conditional boundary → KILLED
2. followInstructions : negated conditional → KILLED
        for (int i = 0; i < instructions.length(); i++) {
83
            followInstruction(i);
84
        }
85 1 1. followInstructions : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followInstructions → KILLED
        return this;
86
    }
87
88
    /**
89
     * @param i the instruction index to follow
90
     * @return An updated {@link Day3} object where the indicated instruction has been followed
91
     */
92
    public Day3 followInstruction(final int i) {
93
        final Movable2DEntity nextSanta = santas.get(santaFocus);
94
95
        switch (instructions.charAt(i)) {
96 1 1. followInstruction : removed call to com/roxoft/lib/Movable2DEntity::moveUp → KILLED
            case '^': nextSanta.moveUp(); break;
97 1 1. followInstruction : removed call to com/roxoft/lib/Movable2DEntity::moveDown → KILLED
            case 'v': nextSanta.moveDown(); break;
98 1 1. followInstruction : removed call to com/roxoft/lib/Movable2DEntity::moveRight → KILLED
            case '>': nextSanta.moveRight(); break;
99 1 1. followInstruction : removed call to com/roxoft/lib/Movable2DEntity::moveLeft → KILLED
            case '<': nextSanta.moveLeft(); break;
100
            default: throw new UnexpectedSolutionException("Unexpected instruction '" + instructions.charAt(0) + "'");
101
        }
102
103
        //Cycle through Santas
104 4 1. followInstruction : changed conditional boundary → KILLED
2. followInstruction : Replaced integer addition with subtraction → KILLED
3. followInstruction : negated conditional → KILLED
4. followInstruction : Replaced integer addition with subtraction → KILLED
        santaFocus = (santaFocus + 1) < santas.size() ? (santaFocus + 1) : 0;
105 1 1. followInstruction : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followInstruction → KILLED
        return this; //XXX: Immutable classes would probably be better.
106
    }
107
108
    /**
109
     * @return An updated {@link Day3} object where the next instruction has been followed
110
     */
111
    public Day3 followNextInstruction() {
112 1 1. followNextInstruction : replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followNextInstruction → KILLED
        return followInstruction(0);
113
    }
114
}

Mutations

23

1.1
Location : getSanta
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_east()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::getSanta → KILLED

42

1.1
Location : of
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:assumption_invalidDirection()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::of → KILLED

49

1.1
Location : withNewSanta
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:assumption_invalidDirection()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::withNewSanta → KILLED

60

1.1
Location : withASantaAt
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:assumption_invalidDirection()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::withASantaAt → KILLED

70

1.1
Location : getNumberOfVisitedHouses
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B1()]
replaced long return with 0 for com/roxoft/aoc/y2015/Day3/Day3::getNumberOfVisitedHouses → KILLED

82

1.1
Location : followInstructions
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B1()]
changed conditional boundary → KILLED

2.2
Location : followInstructions
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B1()]
negated conditional → KILLED

85

1.1
Location : followInstructions
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B1()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followInstructions → KILLED

96

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_north()]
removed call to com/roxoft/lib/Movable2DEntity::moveUp → KILLED

97

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_south()]
removed call to com/roxoft/lib/Movable2DEntity::moveDown → KILLED

98

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_east()]
removed call to com/roxoft/lib/Movable2DEntity::moveRight → KILLED

99

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_west()]
removed call to com/roxoft/lib/Movable2DEntity::moveLeft → KILLED

104

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B3()]
changed conditional boundary → KILLED

2.2
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B3()]
Replaced integer addition with subtraction → KILLED

3.3
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B3()]
negated conditional → KILLED

4.4
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:example_B3()]
Replaced integer addition with subtraction → KILLED

105

1.1
Location : followInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_east()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followInstruction → KILLED

112

1.1
Location : followNextInstruction
Killed by : com.roxoft.aoc.y2015.Day3.Day3Test.[engine:junit-jupiter]/[class:com.roxoft.aoc.y2015.Day3.Day3Test]/[method:requirement_east()]
replaced return value with null for com/roxoft/aoc/y2015/Day3/Day3::followNextInstruction → KILLED

Active mutators

Tests examined


Report generated by PIT 1.14.4