Do the needful?

8

Goal

Replace all comments in C, C++, or Java Code with the comment // Do the needful.

Specifics

This coding challenge is a simple one. Take as input the name of a file. The input file shall contain C, C++, or Java code. The code shall contain one or more comments. The comments can be single line /* */ or // delimited, as well as multi-line /* */ delimited. The output of the program should be identical to the input except all of the comments should be converted to // Do the needful.

For example if the input file is:

#include <iostream.h>

int   result;    // the result of the calculations 
char  oper_char; // the user-specified operator 
int   value;     // value specified after the operator

/* standard main function */     
int main()
{
    result = 0; // initialize the result 

    // Loop forever (or till we hit the break statement) 
    while (1) {
        cout << "Result: " << result << '\n';

        /* This code outputs display and requests
           input from the user */
        cout << "Enter operator and number: ";
        cin >> oper_char;
        cin >> value;

        if (oper_char = '+') {
            result += value;
        } else {
            cout << "Unknown operator " << oper_char << '\n';
        }
    }
    return (0);
}

The output of the program should read

#include <iostream.h>

int   result;    // Do the needful
char  oper_char; // Do the needful
int   value;     // Do the needful

// Do the needful
int main()
{
    result = 0; // Do the needful

    // Do the needful
    while (1) {
        cout << "Result: " << result << '\n';

        // Do the needful
        cout << "Enter operator and number: ";
        cin >> oper_char;
        cin >> value;

        if (oper_char = '+') {
            result += value;
        } else {
            cout << "Unknown operator " << oper_char << '\n';
        }
    }
    return (0);
}

Scoring

This is a popularity contest. You get two extra votes added to your score if none of the following words appears in your program in any case variation: {"do", "the", "needful"}. Score is number of votes plus bonus if applicable.

Allowances

If comments appear in string literals it is acceptable to convert them to // Do the needful as well. After all... you can never have enough needful.

ojblass

Posted 2014-05-26T23:33:47.093

Reputation: 2 575

Question was closed 2017-12-13T17:33:39.867

5You know that the bonus is easily acquired by using "d" + "o", "t" + "he" and "need" + "ful"? Also, does the submission have to be able to deal with any valid C, C++ or Java code? That's pretty harsh and amounts to writing a lexer for all three languages (I'm thinking about comment literals in strings and vice-versa.) If so, what about 3rd-party lexer libraries? – Martin Ender – 2014-05-26T23:55:12.683

This site always makes me laugh at the creative ways people think about problems. I was not aware that you could cheat the bonus but I am going to leave it as it is. If the comments appear in literals and strings and it changes them I will allow the solution to stand if it accidentally replaces them. – ojblass – 2014-05-26T23:57:58.507

2What should the program do when a /* ... */ precedes a non-comment on a line? – Greg Hewgill – 2014-05-27T00:27:53.497

I would put the comment on its own line. – ojblass – 2014-05-27T00:31:43.873

1Do we need to consider cases like char str[]="/**///"; or a comment-start sequence /* appears in a /* comment, or a backslash-newline appears in a // comment, or a // comment within a /**/ comment? – user12205 – 2014-05-27T00:37:11.783

nested comments can result in multiple needfuls the more needful the better. String literals can be replaced too. – ojblass – 2014-05-27T01:25:44.277

3Why make this a popularity contest and not code golf? It works just fine as golf. – Aaronaught – 2014-05-27T02:41:55.260

1To reward creativity over brevity. – ojblass – 2014-05-27T02:50:34.893

2eventually lots of solutions are based on the same regex replacement. What about some bonus points for non regex solutions? – CousinCocaine – 2014-05-27T14:34:04.973

I'm curious where this idea came from – Nick T – 2014-05-27T23:55:26.820

Just random siliness... I hear that phrase a lot and it strikes a nerve. – ojblass – 2014-05-28T00:26:40.220

Answers

4

CoffeeScript (66 bytes)

(c)->c.replace /\/\/.*\n?|\/\*[^]*?\*\//g,"// D\o t\he needfu\l\n"

This code will parse strings, but there is a good reason. You see, there is a possibility that there is a comment in a template generating C /**/ comments.

This gets the bonus, as it avoids exact case insensitive matches for Do, the, and needful. It also uses ES5 candle ([^]) operator to do stuff. I would put a comment Do the needful in this program, but that would remove the bonus.

Konrad Borowski

Posted 2014-05-26T23:33:47.093

Reputation: 11 185

6

Perl, 68 characters

perl -0pe's@((//).*?(\n)|(/\*).*?(\*/))@\2\4 Do the needful \3\5@sg'

This takes some liberties with the specification, and retains the original comment style. This avoids the problem with /* ... */ comments appearing before the end of the line.

No attempt is made to avoid comments within string literals, and no claim is made for the bonus points.

Greg Hewgill

Posted 2014-05-26T23:33:47.093

Reputation: 2 641

I am having a ball using this on source code! – ojblass – 2014-05-27T01:08:39.420

2I would say it improves upon some commenting styles. – Greg Hewgill – 2014-05-27T01:09:19.020

You can get the bonus point like this – ojblass – 2014-05-27T01:23:14.500

perl -0pe 's/((//).?(\n)|(/*).?(*/))/\2\4 D\coo th\coe needfu\cul \3\5/sg' – ojblass – 2014-05-27T01:23:42.697

Sure, but that's just trivial obfuscation, not really interesting. And we're golfing here, right? – Greg Hewgill – 2014-05-27T01:24:09.130

no golf just popularity plus bonus – ojblass – 2014-05-27T01:24:36.480

Maybe I missed something. But wasn't /* standard main function */ supposed to turn into // Do the needful instead of /* Do the needful */? – FDinoff – 2014-05-27T04:32:53.317

1@FDinoff: Yes, that was a liberty I took to simplify the problem, otherwise you have to figure out what to do with code lines where a /* ... */ comment precedes actual code (you can't naively turn it into a // comment). – Greg Hewgill – 2014-05-27T07:11:51.807

5

Perl

First world anarchy! :)

"you can never have enough needful"

#!perl -p0
sub the { s,(?<=\w)(.*)(\n),$1 // do the needful$2,g }
sub needful { s,//.*\n,\n,g,s,/\*.*?\*/,,msg }

do not do the needful

chinese perl goth

Posted 2014-05-26T23:33:47.093

Reputation: 1 089

4

Python 3.x, regex

Since it's not code golf I didn't fuss about code length. Nothing impressive, but I had fun remembering / relearning regex basics.

import re
import urllib.request as r
def dTN(filename):
    dtn = re.search(r"(?<=question-hyperlink\">)([A-Za-z \n]*)(?=[?]<)", r.urlopen("http://codegolf.stackexchange.com/questions/28625/").read().decode("utf8")).group(0)
    with open(filename) as f:
        return re.sub(r"//{1}.*", "//{0}".format(dtn), re.sub(r"/\*[A-Za-z \n]*\*/", "// {0}".format(dtn), f.read()))

Obversity

Posted 2014-05-26T23:33:47.093

Reputation: 181

2

sed, 90 characters

Could be improved. I learned a lot about sed while making this.

Reads from standard input, outputs to standard output. Assumes valid input - if you have unterminated comments, it won't treat it as a comment.

Tested on GNU sed v4.2.2.

s_/\*.*\*/_//_
tg
s_/\*.*$_//_
tl
:g
s_//.*$_// Do the needful_
P
d
:l
s_.*\*/_//_
tg
N
bl

And the prize for readability goes to....?

One-liner version:

s_/\*.*\*/_//_;tg;s_/\*.*$_//_;tl;:g;s_//.*$_// Do the needful_;P;d;:l;s_.*\*/_//_;tg;N;bl

Explanation

The control flow jumps around a lot, by means of GOTO statements (yes, sed has them!). sed does not have any loops or convenient conditional statements AFAIK.

s_/\*.*\*/_//_              # Substitute /* ... */ with //
tg                          # GOTO g if the substitution occured
s_/\*.*$_//_                # Substitute /*...<ENDOFLINE> with //
tl                          # GOTO l if the substitution occured
:g                          # GOTO-LABEL g
s_//.*$_// Do the needful_  # Replace //...<ENDOFLINE> with // Do the needful
P                           # Print the pattern space (current line with substitutions)
d                           # empty the pattern space and move on to the next line
:l                          # GOTO-LABEL l
s_.*\*/_//_                 # Replace ... */ with //
tg                          # GOTO g if the substitution occured
N                           # take another line from input and add it to the pattern space
bl                          # GOTO l

user16402

Posted 2014-05-26T23:33:47.093

Reputation:

2

Rebol

It's not code golf, so I'll be wordy.

do-the-needful: function [filename [file!]] [
    parse (data: to-string read filename) [
        ; match the pattern in brackets ANY number of times (zero okay)
        any [
            ; seek the parse position up TO one of the following matches
            ; if a match is hit, following code in parentheses is executed normally
            to [
                "/*" (terminator: "*/")
            | 
                "//" (terminator: newline)
            ]

            ; save parse position in start, seek up THRU terminator and leave parse
            ; position at the end of the terminator match (not the beginning as w/TO)
            start:
            thru terminator
            finish:

            ; Do partial replacement within the input; starting at START
            ; but limited to FINISH.  Again, structure in parentheses is exec'd as code
            (
                change/part start combine ["// Do the needful" newline] finish
            )
        ]
    ]
    return data
 ]

(Note: For political reasons, I am pushing COMBINE here, but it's not standard yet. So if you actually want to run this, use REJOIN. But I hate REJOIN. A wart on an otherwise beautiful language! Tell your friendly neighborhood Red dev leads to listen to me. Thanks.)

PARSE is a dialect, or language-within-a-language, in Rebol and Red. It twists things up, so for instance the symbol types that are used for assignment (the terminator: in terminator: newline) takes on a new meaning when used in the code-as-data paradigm... it saves the current parse position into a variable with that name. You can read more about why it's cool here.


UPDATE: Oh all right, I'll golf it too. In Rebmu, 72 chars... using rebmu/args which injects A as the argument:

pa DtsRDa[anTO["/*"(T"*/")|"//"(Tlf)]SthT F(chpS"// Do the needful^/"f)]d

Exactly the same program.

HostileFork says dont trust SE

Posted 2014-05-26T23:33:47.093

Reputation: 2 292

2

BrainFuck

Yes, BrainFuck is a Turing-complete language.
Good luck for understanding this code.

,[.-----------------------------------------------[>+>+<<-]>
>[-<<+>>][-]+<[[-]>-<]>[>,----------------------------------
-------------[>+>+<<-]>>[-<<+>>]<>[-]+<[>-<+++++[>+>+<<-]>>[
-<<+>>]<>[-]+<[>-<++++++++++++++++++++++++++++++++++++++++++
.[-]]>[<+++++++++++++++++++++++++++++++++++++++++++++++.----
-----------.++++++++++++++++++++++++++++++++++++.+++++++++++
++++++++++++++++++++++++++++++++.---------------------------
----------------------------------------------------.+++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++.------------.---.-------------------------
--------------------------------------------.+++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++.---------..-.++.+++++++++++++++.---------.[+++++[,------
------------------------------------],----------------------
-------------------------]>-]<<[-]]>[<++++++++++++++++++++++
+++++++++++++++++++++++++.---------------.++++++++++++++++++
++++++++++++++++++.+++++++++++++++++++++++++++++++++++++++++
++.---------------------------------------------------------
----------------------.+++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++.------------
.---.-------------------------------------------------------
--------------.+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++.---------..-.++.++++++++++
+++++.---------.[,----------]++++++++++.[-]>-]<<[-]<<>-]<<,]

Basically, the pseudo-code is :

get input_char
while (input_char is not null)
{
  print input_char
  if (input_char is '/')
  {
    get input_char
    if (input_char is '/')
    {
      print '/ Do the needful'
      get input_char until input_char is '\n'
    }
    else
    {
      if (input_char is '*')
      {
        print '/ Do the needful'
        get input_char until input_char is '*' followed by '/'
      }
      else
      {
        print input_char
      }
    }
  }
  get input_char
}

Some online interpreter are broken.
Try it here with the example given by the OP (ended with null-char to break the loop properly) :

#include <iostream.h>\n\nint   result;    // the result of the calculations \nchar  oper_char; // the user-specified operator \nint   value;     // value specified after the operator\n\n/* standard main function */     \nint main()\n{\n    result = 0; // initialize the result \n\n    // Loop forever (or till we hit the break statement) \n    while (1) {\n        cout << "Result: " << result << '\\n';\n\n        /* This code outputs display and requests\n           input from the user */\n        cout << "Enter operator and number: ";\n        cin >> oper_char;\n        cin >> value;\n\n        if (oper_char = '+') {\n            result += value;\n        } else {\n            cout << "Unknown operator " << oper_char << '\\n';\n        }\n    }\n    return (0);\n}\0

Michael M.

Posted 2014-05-26T23:33:47.093

Reputation: 12 173