Zeus
Zeus

Reputation: 2253

Checking geometric shape

I've an array of four (4) numbers representing the sides of a polygon in the order A, B, C, and D. I need to check the array and determine if the polygon is a square, is rectangle or is nay other polygon.

I'm tracking squares, rectangles and polygons in index 0, 1, 2 of the check array.

This is my current code:

static void checkType(int[] arr, int[] check) {
    Map<Integer, Integer> map = new HashMap<>();

    for (int i = 0; i < arr.length; i++) {
        if (map.containsKey(arr[i])) {
            map.put(arr[i], map.get(arr[i]) + 1);
        } else {
            map.put(arr[i], 1);
        }
    }

    if (map.size() == 1) check[0]++;
    else if (map.size() == 2) check[1]++;
    else check[2]++;
}

The code still doesn't work. Any help appreciated.

Upvotes: 1

Views: 349

Answers (2)

ninja.coder
ninja.coder

Reputation: 9648

Your code works perfectly for a square i.e. when all sides are equal and there is only one entry in the map. It will also work for more than two entries in the map and will say that it is other polygon.

But, the problem with your code is that you assume there will be two entries in map only in the case of rectangle but that's not true.

For Example, {2,2,4,2} here there will be only two entries in the map but this clearly is not a rectangle!

Your logic is correct. You just have to add one more condition for mapSize() == 2 to make sure it is rectangle.

Instead of doing this:

else if (map.size() == 2) check[1]++;

Do this instead:

else if (map.size() == 2) {
    int cnt = 0;
    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        cnt = (cnt == 0) ? entry.getValue() : (cnt == entry.getValue() ? cnt : -1);
    }
    if(cnt != -1)
        check[1]++;
    else
        check[2]++;
}

Upvotes: 1

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48620

I believe that you are trying to count the number of occurrences of a side, in order to determine if the geometric shape is a rectangle, square, or another.

Adding an enum may make your code more easier to understand.

The randEntryValue method will pull out a random entry in the map and check its value. We do not care which value is checked, but we have to make sure that the occurrence is 2.

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class PolygonChecker {
    private enum PolygonType {
        RECTANGLE,
        SQUARE,
        OTHER;
    }

    public static void main(String[] args) {
        Map<PolygonType, Integer> map = new HashMap<PolygonType, Integer>();

        checkType(new int[] {2, 4, 2, 4}, map);    // Rectangle
        checkType(new int[] {3, 3, 3, 3}, map);    // Square
        checkType(new int[] {4, 4, 4, 5}, map);    // Other
        checkType(new int[] {1, 2, 3, 4}, map);    // Other
        checkType(new int[] {1, 2, 3, 4, 5}, map); // Other

        Iterator<Entry<PolygonType, Integer>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

    static void checkType(int[] sideArr, Map<PolygonType, Integer> check) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();

        if (sideArr.length == 4) {
            for (int i = 0; i < sideArr.length; i++) {
                incr(map, sideArr[i], 1);
            }

            if (map.size() == 1) {
                incr(check, PolygonType.SQUARE, 1);
            } else if (map.size() == 2 && randEntryValue(map) == 2) {
                incr(check, PolygonType.RECTANGLE, 1);
            } else {
                incr(check, PolygonType.OTHER, 1);
            }
        } else {
            incr(check, PolygonType.OTHER, 1);
        }
    }

    @SuppressWarnings("unchecked")
    static <K> Entry<K, Integer> randEntry(Map<K, Integer> map) {
        Object[] entries = map.entrySet().toArray();
        return (Entry<K, Integer>) entries[(int) (Math.random() * entries.length)];
    }

    static <K> int randEntryValue(Map<K, Integer> map) {
        return randEntry(map).getValue().intValue();
    }

    // Generic increment function.
    static <K> void incr(Map<K, Integer> map, K key, int amount) {
        if (map.containsKey(key)) {
            map.put(key, map.get(key) + amount);
        } else {
            map.put(key, amount);
        }
    }
}

Output

RECTANGLE=1
SQUARE=1
OTHER=3

Upvotes: 1

Related Questions