I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 605 posts at DZone. You can read more from them at their website. View Full User Profile

Thursday Code Puzzler: Count The Lines Of Code

07.11.2012
| 3682 views |
  • submit to reddit

It's Thursday already, so time for another code puzzler. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.

Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer.  It's all about the participation!

Count The Lines Of Code

Write a program that counts the lines of actual code in a Java program. Whitespace and comments don't count. 

Catch up on all our previous puzzlers here

Comments

Vijay Nathani replied on Thu, 2012/07/12 - 1:10am

Here is a Groovy solution

new File('Program.java').text.replaceAll('//.*\n','\n').replaceAll('(?s)/\\*.*\\*/','\n').readLines().count() { !it.isAllWhitespace() }

 

Prasad Adam replied on Thu, 2012/07/12 - 1:51am

Guess replacing whitespaces and single-line comments with NULL should ignore these from the final LOC. But managaing block comments would be tricky and can't be done in a simple manner. Will think about the same later and revert if find some trick to take care of this scenario.

Chirag Visavadia replied on Thu, 2012/07/12 - 7:03am

public class LinesOfCode { public static void main(String[] args) { try { BufferedReader reader = new BufferedReader(new FileReader("D:\\LineCount.java")); int totalLine = 0; String line = ""; while ((line = reader.readLine()) != null) { line = line.trim(); // catch comments if (line.startsWith("//") || line.startsWith("/*") || line.startsWith("*/") || line.startsWith("*") || line.isEmpty()) continue; totalLine++; } System.out.println("Total Lines: " + totalLine); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }

Vijay Nathani replied on Thu, 2012/07/12 - 9:53am in response to: Chirag Visavadia

His code formated is

public class LinesOfCode { 
	public static void main(String[] args) { 
		try { 
			BufferedReader reader = new BufferedReader(
				new FileReader("Program.java")); 
			int totalLine = 0; 
			String line = ""; 
			while ((line = reader.readLine()) != null) { 
				line = line.trim(); 
				// catch comments 
				if (line.startsWith("//") || line.startsWith("/*") ||
					line.startsWith("*/") || line.startsWith("*") || 
					line.isEmpty())
					continue; 
				totalLine++; 
			} 
			System.out.println("Total Lines: " + totalLine); 
		} catch (FileNotFoundException e) { 
			e.printStackTrace(); 
		} catch (IOException e) { 
			e.printStackTrace(); 
		} 
	} 
} 

 I don't think this solution is perfect because it assumes that the code has been formatted in a particular manner. It assumes that

- all single line comments are on a separte line.

- all block comments  have * at the start of each line

- all block comments end on a separate line

- every line of a block comment starts with a *

Anyway, a good try.

Alex Kizub replied on Thu, 2012/07/12 - 10:14am in response to: Vijay Nathani

This solution also is incorrect for lines like "int i=2\n*2;"

Mike P(Okidoky) replied on Thu, 2012/07/12 - 1:09pm

I solemnly swear that this is 100% genuine. 
import java.io.File;
import java.util.Scanner;
import java.util.regex.Pattern;

public class CodeLines
{
	public static void main(String[] args) throws Exception
	{
		// load file
		//
		String code = new Scanner(new File(args[0])).useDelimiter("\\A").next();
		
		// strip comments
		//
		code = Pattern.compile("/\\*.*?\\*/|//.*?$", Pattern.MULTILINE | Pattern.DOTALL).matcher(code).replaceAll("");
		
		// split into array using non empty lines as delimiters
		//
		String[] s = Pattern.compile("\\S.*?$", Pattern.MULTILINE).split(code.trim());
		
		// count
		//
		System.out.println(s.length);
	}
}
One-liner version:
System.out.println(Pattern.compile("\\S.*?$", Pattern.MULTILINE).split(Pattern.compile("/\\*.*?\\*/|//.*?$", Pattern.MULTILINE | Pattern.DOTALL).matcher(new Scanner(new File(args[0])).useDelimiter("\\A").next()).replaceAll("").trim()).length);

Tomas M. replied on Fri, 2012/07/13 - 2:53am

   public int getLineCount(String text) {
      int count = 1;
      for (int i = 0; i < text.length(); i++) {
         char c = text.charAt(i);
         if (c == '/' && '*' == text.charAt(i+1)) {
            for (; i < text.length() && i+1 < text.length() && !"*/".equals(text.substring(i, i+1)); i++) {
            }
         } else if (c == '\n')
            count++;
      }
      return count;
   }

Prasad Adam replied on Fri, 2012/07/13 - 7:50am in response to: Mike P(Okidoky)

@Mike This one works with all my test cases (line of code, not a comment, starting with *, inside block comment having/not having * etc). I did have a code sample in mind but since it's not going to be as efficient and as graceful as yours, not posting it. Kudos to you!

Prasad Adam replied on Fri, 2012/07/13 - 7:53am in response to: Chirag Visavadia

@Chirag: It fails to tackle scenarios like line within a block comment not starting with *. Legit code-line starting with * etc. Good try though!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.