### Hackerland Radio Transmitters - Java solution..

I have seen solutions much, much shorter!

```package biz.tugay;

import java.util.*;

public static int minNumOfTransmitters(int[] houseLocations, int transmitterRange) {
// Sort and remove duplicates..
houseLocations = uniqueHouseLocationsSorted(houseLocations);

int towerCount = 0;
for (int nextHouseNotCovered = 0; nextHouseNotCovered < houseLocations.length; ) {
final int towerLocation = HackerlandRadioTransmitters.findNextTowerIndex(houseLocations, nextHouseNotCovered, transmitterRange);
towerCount++;
if (nextHouseNotCovered == -1) {
break;
}
}

}

public static int[] uniqueHouseLocationsSorted(final int[] houseLocations) {
Arrays.sort(houseLocations);
final HashSet<Integer> integers = new HashSet<>();
final int[] houseLocationsUnique = new int[houseLocations.length];

int innerCounter = 0;
for (int houseLocation : houseLocations) {
if (integers.contains(houseLocation)) {
continue;
}
houseLocationsUnique[innerCounter] = houseLocation;
innerCounter++;
}
return Arrays.copyOf(houseLocationsUnique, innerCounter);
}

// Given an array of house locations, INDEX of the starting house that is not covered by a transmitter, and the transmitter range,
// This method returns the index where the tower can be farthest placed, in order for house at location houseLocations[houseNotCoveredIndex]
// gets covered.

// For example an array of {1, 5, 9} indicates the following house locations:
// .H...H...H
// 0123456789

// If house not covered index is 1, this means we need to find the farthest index where we can place the tower on..
// to cover the house at location = 5 (since houseLocations[1] = 5..
//      ? -> How to cover this house?
// .H...H...H
// 0123456789

// If transmitter range is 4 for example, index 2 will be fine:
// .....----T----
// .H...H...H....
// 0123456789....

// If transmitter range is 1, index 1 will be returned:
// ....-T-.......
// .H...H...H....
// 0123456789....
public static int findNextTowerIndex(final int[] houseLocations, final int houseNotCoveredIndex, final int transmitterRange) {
final int houseLocationWeWantToCover = houseLocations[houseNotCoveredIndex];
final int farthestHouseLocationAllowed = houseLocationWeWantToCover + transmitterRange;

// We need to find the index of the house where house.location is the biggest but <= farthestHouseLocationAllowed!
int towerIndex = houseNotCoveredIndex;

while (true) {
if (towerIndex == houseLocations.length - 1) {
break;
}

if (farthestHouseLocationAllowed >= houseLocations[towerIndex + 1]) {
towerIndex++;
continue;
}

break;
}

}

// Given an array of house locations, INDEX of tower and the transmitterRange,
// This method returns the INDEX of the next house location which is not covered by the tower.
// Returns -1 if no uncovered houses are found.

// For example an array of {1, 5, 9} indicates the following house locations:
// .H...H...H
// 0123456789

// If tower index is 1, this means we have a tower on houseLocations[1] (which is 5..):
// .....T....
// .H...H...H
// 0123456789

// Assume transmitter range is 1, since house at location '9' is NOT covered by (houseLocations[towerIndex] + 1 = 6), this method returns 9
// Assume transmitter range is 5, since house at location '9' IS covered by (houseLocations[towerIndex] + 5 = 10), this method returns -1
public static int nextHouseNotCoveredIndex(final int[] houseLocations, final int towerIndex, final int transmitterRange) {
// This is the farthest tower can cover to..
final int towerCoversUntil = houseLocations[towerIndex] + transmitterRange;

// Tower covers the house it sits on already, so the closest candidate is the house at the location pointed by houseLocations[towerIndex + 1].
int notCoveredHouseIndex = towerIndex + 1;

// Starting from nextHouseNotCoveredIndex, walk through the array and figure out whether the index we are on
// is covered by the tower or not.
// If covered, keep walking, if not covered return the found index.
while (notCoveredHouseIndex < houseLocations.length) {
final int locationOfHouseBeingChecked = houseLocations[notCoveredHouseIndex];

if (locationOfHouseBeingChecked > towerCoversUntil) {
break; // Tower does not cover the house anymore, break the loop..
}

notCoveredHouseIndex++;
}

if (notCoveredHouseIndex == houseLocations.length) {
notCoveredHouseIndex = -1;
}

return notCoveredHouseIndex;
}
}```

and of course, we need our test classes..
```package biz.tugay.test;

public class FindNextHouseNotCoveredIndexTests {

// Run with -ea (enable assertions!)
public static void main(String[] args) {
test_01();
test_02();
test_03();
test_04();
}

static void test_01() {
final int[] houseLocations = {1, 5, 9};
final int towerIndex = 1;
final int transmitterRange = 2;
final int houseNotCoveredIndex = HackerlandRadioTransmitters.nextHouseNotCoveredIndex(houseLocations, towerIndex, transmitterRange);
assert houseNotCoveredIndex == 2;
}

static void test_02() {
final int[] houseLocations = {1, 5, 9};
final int towerIndex = 1;
final int transmitterRange = 5;
final int houseNotCoveredIndex = HackerlandRadioTransmitters.nextHouseNotCoveredIndex(houseLocations, towerIndex, transmitterRange);
assert houseNotCoveredIndex == -1;
}

static void test_03() {
final int[] houseLocations = {1, 5, 6, 7, 8, 9, 10, 11};
final int towerIndex = 1;
final int transmitterRange = 5;
final int houseNotCoveredIndex = HackerlandRadioTransmitters.nextHouseNotCoveredIndex(houseLocations, towerIndex, transmitterRange);
assert houseNotCoveredIndex == 7;
}

static void test_04() {
final int[] houseLocations = {5, 10, 100};
final int towerIndex = 1;
final int transmitterRange = 15;
final int houseNotCoveredIndex = HackerlandRadioTransmitters.nextHouseNotCoveredIndex(houseLocations, towerIndex, transmitterRange);
assert houseNotCoveredIndex == 2;
}
}

package biz.tugay.test;

public class FindTowerIndexTests {

// Run with -ea (enable assertions!)
public static void main(String[] args) {
test_01();
test_02();
test_03();
}

static void test_01() {
final int[] houseLocations = {1, 5, 9};
final int houseNotCoveredIndex = 0;
final int transmitterRange = 2;

final int nextTowerIndex = HackerlandRadioTransmitters.findNextTowerIndex(houseLocations, houseNotCoveredIndex, transmitterRange);

assert nextTowerIndex == 0;
}

static void test_02() {
final int[] houseLocations = {1, 5, 9};
final int houseNotCoveredIndex = 0;
final int transmitterRange = 4;

final int nextTowerIndex = HackerlandRadioTransmitters.findNextTowerIndex(houseLocations, houseNotCoveredIndex, transmitterRange);

assert nextTowerIndex == 1;
}

static void test_03() {
final int[] houseLocations = {1, 5, 9};
final int houseNotCoveredIndex = 2;
final int transmitterRange = 20;

final int nextTowerIndex = HackerlandRadioTransmitters.findNextTowerIndex(houseLocations, houseNotCoveredIndex, transmitterRange);

assert nextTowerIndex == 2;
}
}

package biz.tugay.test;

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class MinimumNumberOfTransmittersTest {

// Run with -ea (enable assertions!)
public static void main(String[] args) throws IOException {
test_01();
test_02();
test_03();
test_04();
test_05();
test_06();
test_07();
test_08();
test_09();
test_10();
test_11();
}

static void test_01() {
final int[] houseLocations = {5, 4, 3};
assert uniqueHouseLocationsSorted[0] == 3;
assert uniqueHouseLocationsSorted[1] == 4;
assert uniqueHouseLocationsSorted[2] == 5;
}

static void test_02() {
final int[] houseLocations = {5, 4, 4, 3, 1};
assert uniqueHouseLocationsSorted[0] == 1;
assert uniqueHouseLocationsSorted[1] == 3;
assert uniqueHouseLocationsSorted[2] == 4;
assert uniqueHouseLocationsSorted[3] == 5;
assert uniqueHouseLocationsSorted.length == 4;
}

static void test_03() {
final int[] houseLocations = {3, 2, 2, 2, 2, 1};
assert uniqueHouseLocationsSorted[0] == 1;
assert uniqueHouseLocationsSorted[1] == 2;
assert uniqueHouseLocationsSorted[2] == 3;
assert uniqueHouseLocationsSorted.length == 3;
}

static void test_04() {
final int[] houseLocations = {1, 5};
final int transmitterRange = 4;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 1;
}

static void test_05() {
final int[] houseLocations = {1, 5, 9};
final int transmitterRange = 4;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 1;
}

static void test_06() {
final int[] houseLocations = {0, 3, 6, 9};
final int transmitterRange = 1;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 4;
}

static void test_07() {
final int[] houseLocations = {0};
final int transmitterRange = 20;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 1;
}

static void test_08() {
final int[] houseLocations = {2, 4, 5, 6, 7, 9, 11, 12};
final int transmitterRange = 2;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 3;
}

private static void test_09() throws IOException {
final File file = new File("test_case_06.txt");
final Scanner scanner = new Scanner(file);
int[] houseLocations = new int[37455];
for (int counter = 0; counter < 37455; counter++) {
houseLocations[counter] = scanner.nextInt();
}
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(uniqueHouseLocationsSorted, 80);

assert minNumOfTransmitters == 620;
}

static void test_10() {
final int[] houseLocations = {2, 4, 5, 6, 7, 9, 11, 12};
final int transmitterRange = 0;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 8;
}

static void test_11() {
final int[] houseLocations = {};
final int transmitterRange = 20;
final int minNumOfTransmitters = HackerlandRadioTransmitters.minNumOfTransmitters(houseLocations, transmitterRange);

assert minNumOfTransmitters == 0;
}
}```