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 639 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
| 5433 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!

Qiang Di Pa replied on Sat, 2013/11/16 - 3:36am

 http://bags49.com enjoying the person for reasons that have nothing to do with money. You must generate a relationship with a person before you can ever hope to get money out of them. Apply this in your head, right now across all the situations where people exchange money. Moreover, the awareness related to to its best. 8 million diluted weighted fair shares outstanding & unusual.

Shahbaz Ahmad replied on Tue, 2014/01/28 - 6:43am in response to: Mike P(Okidoky)

can you kindly explain the line no 11??

Comment viewing options

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