Thursday, April 20, 2017

My Solution For The 'Counting Stars' Problem

In today's post, I share my solution for the 'Counting Stars' problem found at https://10xrecruit.kattis.com/problems/countingstars

The Problem


The field of astronomy has been significantly advanced through the use of computer technology. Algorithms can automatically survey digital images of the night sky, looking for new patterns.
For this problem, you should write such an analysis program which counts the number of stars visible in a bitmap image. An image consists of pixels, and each pixel is either black or white (represented by the characters # and -, respectively). All black pixels are considered to be part of the sky, and each white pixel is considered to be part of a star. White pixels that are adjacent vertically or horizontally are part of the same star.

Input

Each test case begins with a line containing a pair of integers . This is followed by  lines, each of which contains exactly  pixels. Input contains at least one and at most  test cases, and input ends at the end of the file.

Output

For each case, display the case number followed by the number of stars that are visible in the corresponding image. Follow the format of the sample output.
Sample Input 1Sample Output 1
10 20
#################---
##-###############--
#---################
##-#################
########---#########
#######-----########
########---#########
##################--
#################---
##################-#
3 10
#-########
----------
#-########
3 5
#-#-#
#-#-#
#---#
Case 1: 4
Case 2: 1
Case 3: 1

My Solution

Solution.java
package counting_stars;

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * 
 * @author Omar L.
 *
 */

public class Solution {

 static final String BITMAPS_FILE_NAME = "sample.in";
 static final String SPLIT_TOKEN = " ";
 static final char STAR = '-';
 static final char PART_OF_THE_SAME_STAR = 'X';
 static final int START_OF_THE_ARRAY = 0;
 static final int NUMBER_OF_ROWS_INDEX = 0;
 static final int NUMBER_OF_COLUMNS_INDEX = 1;
 static final int LEFT_BORDER_OF_THE_BITMAP = 0;
 static final int TOP_BORDER_OF_THE_BITMAP = 0;
 static final int RESET = 0;

 // Each test case begins with a line containing a pair of integers
 // 1 <= m, n <= 100.
 static final int MIN_LENGTH = 1;
 static final int MAX_LENGTH = 100;
 // Input contains at least one and at most 50 test cases.
 static final int MAX_TEST_CASES = 50;

 static BufferedReader bitmapBufferdReader;
 static char[][] bitmap;
 static int numberOfStars;
 static int numberOfRows;
 static int numberOfColumns;
 static int caseNumber;

 static void process() {
  readBitmapsFile();
  String numberOfRowsAndColumnsString;
  try {
   while((numberOfRowsAndColumnsString = bitmapBufferdReader.readLine()) != null
     && ++caseNumber < MAX_TEST_CASES) {
    String[] numberOfRowsAndColumns = numberOfRowsAndColumnsString.trim().split(SPLIT_TOKEN);
    numberOfRows = Integer.parseInt(numberOfRowsAndColumns[NUMBER_OF_ROWS_INDEX]);
    numberOfColumns = Integer.parseInt(numberOfRowsAndColumns[NUMBER_OF_COLUMNS_INDEX]);
    if (numberOfRows >= MIN_LENGTH && numberOfRows <= MAX_LENGTH && numberOfColumns >= MIN_LENGTH
      && numberOfColumns <= MAX_LENGTH) {
     readBitmap();
     countStars();
     System.out.println("Case " + caseNumber + ": " + numberOfStars);
    } else
     return;
   }
  } catch (NumberFormatException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 // Count the number of stars visible in a bitmap image.
 static void countStars() {
  numberOfStars = RESET;
  for (int row = START_OF_THE_ARRAY; row < numberOfRows; row++) {
   for (int col = START_OF_THE_ARRAY; col < numberOfColumns; col++) {
    if (bitmap[row][col] == STAR) {
     numberOfStars++;
     bitmap[row][col] = PART_OF_THE_SAME_STAR;
     checkRight(row, col);
     checkDown(row, col);
    }
   }
  }
 }

 static void readBitmap() {
  bitmap = new char[numberOfRows][];
  for (int row = START_OF_THE_ARRAY; row < numberOfRows; row++) {
   try {
    bitmap[row] = bitmapBufferdReader.readLine().toCharArray();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 static void readBitmapsFile() {
  try {
   bitmapBufferdReader = Files.newBufferedReader(Paths.get(BITMAPS_FILE_NAME));
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 // Check for white pixels that are adjacent horizontally and are part of the
 // same star.
 static void checkRight(int row, int col) {
  while (++col < numberOfColumns && bitmap[row][col] == STAR) {
   bitmap[row][col] = PART_OF_THE_SAME_STAR;
   checkDown(row, col);
   checkUp(row, col);
  }
 }

 // Check for white pixels that are adjacent vertically and are part of the
 // same star.
 static void checkDown(int row, int col) {
  while (++row < numberOfRows && bitmap[row][col] == STAR) {
   bitmap[row][col] = PART_OF_THE_SAME_STAR;
   checkLeft(row, col);
   checkRight(row, col);
  }
 }

 static void checkLeft(int row, int col) {
  while (--col >= LEFT_BORDER_OF_THE_BITMAP && bitmap[row][col] == STAR) {
   bitmap[row][col] = PART_OF_THE_SAME_STAR;
   checkDown(row, col);
   checkUp(row, col);
  }
 }

 static void checkUp(int row, int col) {
  while (--row >= TOP_BORDER_OF_THE_BITMAP && bitmap[row][col] == STAR) {
   bitmap[row][col] = PART_OF_THE_SAME_STAR;
   checkLeft(row, col);
   checkRight(row, col);
  }
 }

 public static void main(String[] args) {
  process();
 }
}

1 comment: