119
\$\begingroup\$

NPM's sloc is a moderately popular tool for counting source lines of code in a file. The tool will attempt to strip out both single and multiline comments and count the remaining lines in order to get an estimate of the 'true' number of lines of code.

However, the parser used is based on regular expressions and is quite simple, so it can be tricked. In this challenge, you will need to construct a hello world program that sloc counts as zero lines of code.

The challenge

  1. Download sloc. If you have npm, this can be done via npm i sloc. We will use the latest version as of the time of posting, which is 0.2.1. Or, use the online testing environment linked at the bottom of this post.

  2. Select any language that sloc supports. A full list is available here.

  3. Write a full program in that language that prints the exact string Hello, World! to stdout. The output may optionally have a trailing newline, but no other format is accepted. The program may output anything to stderr. However, to be considered a valid submission, sloc must see the program as zero lines of source code. You can verify this by running sloc myprogram.ext, which should read Source : 0.

Example

The following Python program is a valid submission:

'''"""''';print("Hello, World!");"""'''"""

If I run sloc hello.py, I get:

---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  0
       Block comment :  1
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------

Why? Well, sloc uses ''' or """ to determine if something is a mulitline comment in Python. However, it doesn't pair them up correctly. Thus Python parses our program as:

'''"""''';print("Hello, World!");"""'''"""
\-------/ \--------------------/ \-------/
 comment        active code       comment

But sloc parses it as:

'''"""''';print("Hello, World!");"""'''"""
\----/\----------------------------/\----/
comment          comment           comment

(This is not the shortest valid Python submission, so it shouldn't stop you looking for shorter ones)

Scoring

The shortest program in bytes wins.

A note on feasibility

It might be a reasonable question to ask whether this is possible for all languages. I don't know, but all the ones I've looked at so far (Python, C, HTML) have at least one solution. So there's a very good chance it is possible in your language.

There are a number of ideas that can work across multiple languages.

Online test environment

Try it online!

You need to:

  1. Type your code into the input box
  2. Type the extension corresponding to your language into the command args (important!)
\$\endgroup\$
12
  • 8
    \$\begingroup\$ sloc recognizes this correctly as two lines, I give up :/ \$\endgroup\$
    – ovs
    Nov 28, 2020 at 9:16
  • 5
    \$\begingroup\$ I will point out that our definition of what counts as a programming language is entirely vestigial, and challenges are not restricted to only "programming languages". They used to be but not anymore. You are of course free to override the defaults. I just don't see a good reason why you are in this case, and thought maybe you didn't know about the new consensus (you wouldn't be the first). \$\endgroup\$
    – Wheat Wizard
    Nov 28, 2020 at 9:22
  • 5
    \$\begingroup\$ Is there a way to run sloc online, rather than needing to install it locally? \$\endgroup\$ Nov 28, 2020 at 10:33
  • 5
    \$\begingroup\$ @WheatWizard I was not aware of the new consensus. Is there some way the old consensus can be marked with a warning? \$\endgroup\$
    – Sisyphus
    Nov 28, 2020 at 11:20
  • 6
    \$\begingroup\$ @DominicvanEssen Despite not knowing coffeescript I've managed to stumble my way into creating a TIO-based online checker. It's now in the last section of the post. \$\endgroup\$
    – Sisyphus
    Nov 28, 2020 at 11:36

19 Answers 19

43
\$\begingroup\$

Haskell, 36 35 bytes

{-{--}--}main=putStr"Hello, world!"

Try it online!

Test sloc

Since sloc is regex based it is a very good guess to think it cannot identify nested comments. And if we take a look we see that indeed it cannot. If we nest two comments as so:

{-{--}-}

sloc identifies one line of source and one line of comment. Based on these observations my best guess is that the regex it is using is

(\{-((?!-\}).)*-\}|--[^\n]*)

If we pop this into a regex engine we will see it matches the nested comment as so:

      code
      ^^
{-{--}-}
^^^^^^
comment

Ok so we broke it, however this has the opposite of the intended effect. We want sloc to think our code is a comment rather than our comment is code. So we add a "line comment marker" to the part of the comment sloc thinks is code, so that sloc thinks a line comment is being started.

{-{--}--}

So to sloc there are two comments the block comment {-{--} and the line comment --} but to haskell which actually parses comments, it is all one block comment.

So then we just add our code after. Sloc thinks this is still a comment and Haskell knows it is not.

\$\endgroup\$
2
  • 4
    \$\begingroup\$ You only need two - between the}s. \$\endgroup\$
    – Nitrodon
    Nov 28, 2020 at 21:20
  • 1
    \$\begingroup\$ Interestingly, my tool of choice cloc is also fooled by your code, unlike most of the other answers! \$\endgroup\$
    – Vorac
    Dec 11, 2020 at 10:45
33
\$\begingroup\$

Groovy, 28 bytes

/**/print"Hello, World!"/**/

Try it online!


Squirrel, 30 bytes

/**/print("Hello, World!")/**/

Try it online!


Swift, 30 bytes

/**/print("Hello, World!")/**/

Try it online!


JavaScript (Node.js), 36 bytes

/**/console.log("Hello, World!")/**/

As a bonus, this also breaks SE's syntax highlighter.

Try it online!


C (gcc), 38 bytes

/**/main(){puts("Hello, World!");}/**/

Try it online!


Dart, 39 bytes

/**/main(){print("Hello, World!");}/**/

Try it online!


Rust, 42 bytes

/**/fn main(){print!("Hello, World!")}/**/

Try it online!


C++ (gcc), 48 bytes

/**/main(){__builtin_puts("Hello, World!");}/**/

Try it online!


Scala, 52 bytes

/**/object H extends App{print("Hello, World!")}/**/

Try it online!


Go, 69 bytes

/**/package main
import."fmt"
func main(){Print("Hello, World!")}/**/

Try it online!


C# (.NET Core), 75 bytes

/**/class P{static void Main(){System.Console.Write("Hello, World!");}}/**/

Try it online!

\$\endgroup\$
10
  • 14
    \$\begingroup\$ With .NET 5 C# you can omit the class declaration and the main method and just write System.Console.Write("Hello world!"); (46 bytes) as a valid code. Sadly, it does not seem to be an option available in tio.run yet... :) \$\endgroup\$
    – mishan
    Nov 28, 2020 at 14:48
  • 13
    \$\begingroup\$ It's funny that the JS code also tricks SE's syntax highlighter. \$\endgroup\$
    – jaskij
    Nov 28, 2020 at 15:44
  • 1
    \$\begingroup\$ Can the C version end with // rather than /**/? \$\endgroup\$ Nov 28, 2020 at 21:57
  • 4
    \$\begingroup\$ Apparently the app uses a different syntax highlighter that handles it correctly. \$\endgroup\$
    – wastl
    Nov 28, 2020 at 21:59
  • 1
    \$\begingroup\$ @wastl the first time the app has ever had something work better! \$\endgroup\$
    – Tim
    Nov 28, 2020 at 23:48
33
\$\begingroup\$

Java 6, 83 68 54 Bytes

The code :

/**/enum C{C;{System.out.print("Hello, World!");}}/**/

Although crashes immediately with error sent to stderr, prints the correct output. Thanks to @Kevin Cruijssen for the tip about removing the System.exit(0).

And the result :

---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  0
       Block comment :  1
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------

Thanks @Razetime for the hint from @OlivierGrégoire answer.


My initial answer was in java 7+ with 83 Bytes (there's a comma missing) :

/**/interface C{static void main(String[]a){System.out.print("Hello World!");}}/**/
\$\endgroup\$
7
  • 4
    \$\begingroup\$ this answer may be of some help. \$\endgroup\$
    – Razetime
    Nov 28, 2020 at 7:35
  • 1
    \$\begingroup\$ @Razetime Thanks. I do not have comment upvote privileges yet. \$\endgroup\$
    – Amir M
    Nov 28, 2020 at 7:38
  • 4
    \$\begingroup\$ Very nice! This appears to be a generic approach that covers any language with /* and */ multi line comments. \$\endgroup\$
    – Sisyphus
    Nov 28, 2020 at 8:36
  • 6
    \$\begingroup\$ An alternate solution for the same length is to prefix your code with //\u000a. \$\endgroup\$
    – Sisyphus
    Nov 28, 2020 at 23:57
  • 1
    \$\begingroup\$ In the third rule it states "The program may output anything to stderr.", so you can removed the System.exit(0); in your Java 6 answer. It will first output the "Hello, World!", and then print an exception to STDERR. PS: You forgot the comma in the string "Hello, World!" in both of your programs. \$\endgroup\$ Dec 1, 2020 at 10:24
30
\$\begingroup\$

PHP, 33 bytes

Dewi Morgan claimed there was no possible solution, so that obviously made me look further into a way to do it :) (he then followed up with multiple 'shenanigans')

Thing is, we can simply do:

//<?php ob_clean()?>Hello, World!

The only downside (and what made me initially discard it) is that you must be using a SAPI that has buffering enabled by default. So, if you tried to run it with php cli, it will probably output the // and complain that there was no buffer to delete. But if ran from a web server (even built-in php -S), it will produce the expected Hello World!

sloc agrees that has no code:

---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  1
       Block comment :  0
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------
\$\endgroup\$
6
  • 1
    \$\begingroup\$ This is really, really clever. I like it! \$\endgroup\$
    – Sisyphus
    Nov 30, 2020 at 2:53
  • 1
    \$\begingroup\$ Woops, fixed @KevinCruijssen \$\endgroup\$
    – Ángel
    Dec 1, 2020 at 23:11
  • \$\begingroup\$ That's fire! Well done. \$\endgroup\$
    – tfont
    Dec 9, 2020 at 16:17
  • \$\begingroup\$ If you allow for differing PHP configuration you can make sure short_open_tags is enabled (isn't that even default?) and then replace <?php with <?, thus 4 bytes less \$\endgroup\$
    – johannes
    Jan 4, 2021 at 13:45
  • \$\begingroup\$ Oh and PHP also supports # for single line comments. If sloc supports it: one more byte less. \$\endgroup\$
    – johannes
    Jan 4, 2021 at 13:48
24
\$\begingroup\$

JavaScript (V8), 28 bytes

/**/print`Hello, World!`/**/

Try it online!

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Welcome to the site! Nice first answer. \$\endgroup\$ Nov 28, 2020 at 17:01
  • 3
    \$\begingroup\$ You should edit your answer to also say "TypeScript" as it also works in TypeScriptTIO, and in the "Online test environment" set the extension to ts. \$\endgroup\$ Nov 28, 2020 at 23:44
21
\$\begingroup\$

PHP, 17 chars with backspace cheat.

Entry

//^H^HHello, World!

Rationale

After the forward-slashes for the comment, there are two backspace characters which erase them from the output. Then, it outputs the target string.

So, whether this is legal depends on whether "output" can be grossly misinterpreted to mean "eventual visual output on some terminals". I suspect not, since the online testing env is probably the canonical env, and does not respect backspaces. So while maybe mildly interesting for the weaknesses found, this is unlikely to be a winner :)

However, that then means that a legal solution is impossible in PHP.

For any solution which does not include this cheat, we are stuck with two options:

  1. Comments, then PHP opentag. This outputs //, and we've established that's illegal:

    //<?php
    
  2. PHP open tag, then comments. Lacking any preceding text to hide it from sloc, the open tag counts as a line of code.

    <?php//
    

This argument relies on the assumption that comments are the only way to hide code from sloc.

However, the argument works just as well if we replace "comments" with "anything which causes bad output if placed before a PHP opentag; and won't hide the opentag from sloc if placed after it", which I think includes everything, since the regexes for PHP don't seem to have any exploitable backreferencing, but I may be making an incorrect assumption.

Weaknesses found

Possibly-exploitable issues found with the sloc online testing env for PHP.

  1. It treats // line and /*...*/ comments correctly, but is sadly unaware of # line comments, or this would be 15 chars instead, standing a good chance of beating all languages other than those using compression or with the "Hello World!" string as a language construct. OK, or languages where // means print and the file extension can be set to .c or similar.

  2. It does not check for a preceding unpaired <? or <?php before considering something code. To PHP, everything outside of <?....?> is output. This is the bug I exploited.

\$\endgroup\$
7
  • 2
    \$\begingroup\$ To get a legal PHP solution, one could consider using the -r flag \$\endgroup\$
    – Sisyphus
    Nov 29, 2020 at 4:52
  • 1
    \$\begingroup\$ @Sisyphus you're right, I misremembered! Commandline params to the compiler ARE permitted by standard loopholes! :) They just count towards the total, which is fine. \$\endgroup\$ Nov 29, 2020 at 5:17
  • 3
    \$\begingroup\$ They don't actually count towards the total \$\endgroup\$
    – Jo King
    Nov 29, 2020 at 5:45
  • \$\begingroup\$ @JoKing You're joking, right? :D Well, I'm a noob, so may be misunderstanding. But, if that's the case, just about every compiler allows code to be passed in as parameters, so every code golf contest could be 0 characters for every language, and it would be quite boring indeed. So, most likely, I'm misunderstanding. Do you mean that, in php -r 'echo "hi";', the leading php -r ' and the trailing ' are not counted? \$\endgroup\$ Nov 29, 2020 at 5:57
  • 1
    \$\begingroup\$ It's a bit confusing,, but here is the current meta consensus on flags. According to this, yes only the part inside the string parameter would be counted, though it would technically be the language PHP with the -r flag. Zero byte abuses of this would fall under the MetaGolfScript loophole \$\endgroup\$
    – Jo King
    Nov 29, 2020 at 6:36
12
\$\begingroup\$

HTML, 25 23 bytes

-2 bytes thanks to anonymoose

<!-->Hello, World!<!-->

A side note on PHP:

Inspired by @Dewi Morgan's PHP answer, I wanted to see if I could find any other approaches which did not use the backspace cheat.

My first thought was that my HTML answer would instantly work as a PHP answer, however this is not the case. Even though PHP interprets everything outside of its <? ?> tags as plain HTML, simply switching the extension from HTML to PHP causes sloc to interpret this as one line, and indeed it seems that sloc ignores HTML comments in PHP mode.

I was hoping that something like //?>Hello, World! would solve this for PHP, but while sloc interprets this as 0 lines (hooray!!) PHP simply ignores the closing tag meaning that the entire construct is output to the page.

So, for now I have to agree: it seems like a valid PHP solution without the backspace cheat (or using the -r flag) does not exist.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ It seems that browsers also accept <!-->Hello, World!<!--> (23 characters), and sloc still counts it as a comment. From looking through the other solutions, this may be the shortest solution without "cheats." \$\endgroup\$
    – anonymoose
    Nov 30, 2020 at 14:00
  • \$\begingroup\$ @anonymoose Thanks! \$\endgroup\$ Dec 1, 2020 at 7:09
  • \$\begingroup\$ This is also valid PHP! \$\endgroup\$
    – johannes
    Jan 4, 2021 at 13:49
  • \$\begingroup\$ @johannes It is, but sloc sees it as a line when set to PHP mode sadly :( \$\endgroup\$ Jan 4, 2021 at 13:53
10
\$\begingroup\$

Python, 32 bytes

"""'''""";print("Hello, World!")

sloc outputs

{ total: 1,
  source: 0,
  comment: 1,
  single: 0,
  block: 1,
  mixed: 0,
  empty: 0,
  todo: 0,
  blockEmpty: 0 }

Try it online

\$\endgroup\$
9
\$\begingroup\$

Ruby, 46 bytes

=begin
=end =begin
puts "Hello, World!"
#=end

sloc output

---------- Result ------------

            Physical :  4
              Source :  0
             Comment :  4
 Single-line comment :  0
       Block comment :  4
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Instead of puts, you could use p. The space can be omitted as well. To make it equivalent to puts, use p"Hello, World!\n" But I don't see the newline being required. \$\endgroup\$
    – berkes
    Jan 4, 2021 at 14:04
  • 2
    \$\begingroup\$ p adds quotes to the output, so it can't be used. however, you can use $><<"Hello, World!" for -1. \$\endgroup\$
    – Razetime
    Feb 17, 2021 at 6:52
8
\$\begingroup\$

CSS, 38 bytes

/**/:after{content:"Hello, World!"/**/

CSS, despite not being an actual programming language, allows us to do basic output. This code creates a pseudo-element after every element on the page

Sloc's block comment detection is broken (as seen in other answers) and this is reported as 0 lines of source code. See the sloc output here.

The below snippet has been modified (40 bytes) so that the snippet runner and some browsers that style the <html> (causing a double-output) display properly.

/**/* :after{content:"Hello, World!"/**/

\$\endgroup\$
6
\$\begingroup\$

R, 43 bytes

#!/usr/bin/rscript -e cat('Hello','World!')

Count the zero source lines of code

I'm not sure whether this is completely valid. It's a full program that must be launched directly from the shell (so it does not work in 'Try it Online' or 'rdrr.io' for instance, or when copy-pasted into the R console). Save as "helloworld.r" with execute permission, and run using ./helloworld.r or, more verbosely, exec helloworld.r > output.txt.

R does not support multi-line comments, so the 'pairing the comment delimiter' tricks available in other languages aren't possible. The only (single line) comment character is #, and everything following it up to the next newline is not executed. However, the shebang line starting with #! is counted by "sloc" as a comment, even though it will be read and interpreted by the program loader.

Usually, the shebang line simply tells the program loader which interpreter to use to run the rest of the program. So, this is a more-conventional 2-line (sloc=1) R program to accomplish the same task:

#!/usr/bin/rscript
cat('Hello','World!')

But - we can also include command-line arguments in the shebang line, and the rscript interpreter accepts the -e flag to pass it the program code as an argument, which is what the sloc=0 code does here.

So: the program is valid in R and the program code is run by R, but it requires to be launched from the shell and uses the help of the program loader. Is this valid? I don't know. But it's the only way that I could think of to 'trick' sloc in a language without multi-line comments...

\$\endgroup\$
8
  • \$\begingroup\$ Why exec helloworld.r? That would replace your shell… \$\endgroup\$ Nov 29, 2020 at 17:16
  • \$\begingroup\$ @D.BenKnoble - I'll be honest: I don't really understand this stuff. I just tried it out both ways and it worked for me... \$\endgroup\$ Nov 29, 2020 at 17:22
  • 9
    \$\begingroup\$ I'm sorry, but I don't think this counts as R code. It uses a call to R, but you can't execute it by any of the standard ways of calling R code (i.e. with source, Rscript, R CMD BATCH...). The language here is something like "shell on a system with R installed", not R... \$\endgroup\$ Nov 29, 2020 at 20:17
  • \$\begingroup\$ In a similar vein, if "shell" were a language permitted by the challenge or if we consider this general approach valid, we could do #!/bin/sed s/.*/Hello, World!/ (31 bytes) \$\endgroup\$
    – Nye
    Nov 30, 2020 at 11:46
  • 1
    \$\begingroup\$ @RobinRyder - Yes - this is exactly why I wasn't sure about the validity of the answer (and I did point-out that it can't be run by the more-standard ways)... \$\endgroup\$ Nov 30, 2020 at 12:28
6
\$\begingroup\$

Nim, 24 bytes

 #[]#echo"Hello, World!"

Try it online!

Verify sloc

sloc looks for # characters in Nim, but the regex is a little weird, as it cares about the position of the #. Presumably, this was done to try to work around the fact that it treats ## comments separate from # comments. Specifically, sloc doesn't seem to know that Nim has block comments in the form of #[ ]#, so it treats ## comments as block comments for its counting. This means that although we can take advantage of its misunderstanding of block comments fairly easily, we need a space at the start or it won't detect it. Or more accurately, it actually seems to detect it properly, somehow, despite there not seeming to be any code for block comments in the source. I'm really not quite sure why it works, I'd have to try to understand a regex for that.

\$\endgroup\$
5
\$\begingroup\$

Perl5

$ cat script.pl
#!/usr/bin/perl -Esay(Hello.chr(44).chr(32).world.chr(33))
$ ./script.pl
Hello, world!
sloc script.pl

---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  1
       Block comment :  0
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------
\$\endgroup\$
6
  • \$\begingroup\$ because it's code golf the number of bytes should appear currently 59, another solution 39 bytes or 20 bytes depending on counting \$\endgroup\$ Nov 30, 2020 at 8:15
  • 4
    \$\begingroup\$ I'm not entirely sure this is actually Perl, I think this is your shell interpreting the file as when tested in TIO it complains that -E can't be set via shebang: Try it online! \$\endgroup\$ Nov 30, 2020 at 8:17
  • \$\begingroup\$ @DomHastings It must depend on your shell? > zero_line_hello_world.pl Hello, world! \$\endgroup\$ Dec 20, 2020 at 11:30
  • 1
    \$\begingroup\$ #!/usr/bin/perl -Esay'Hello World! (35 bytes) \$\endgroup\$ Dec 20, 2020 at 11:41
  • \$\begingroup\$ @quantum mechanic, the behavior of shebang wrt extra spaces is system dependent. Mind mentioning your OS? \$\endgroup\$ Jan 5, 2021 at 8:57
5
\$\begingroup\$

Lua, 28 bytes

--[=[]=]print"Hello, World!"

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Python 2, 30 bytes

If using Python 2, nobody's solution can be improved slightly.

'''"""''';print"Hello, World!"

sloc outputs

{ total: 1,
  source: 0,
  comment: 1,
  single: 0,
  block: 1,
  mixed: 0,
  empty: 0,
  todo: 0,
  blockEmpty: 0 }

Try it online

\$\endgroup\$
4
\$\begingroup\$

PHP, with various commandline shenanigans, 0-33

Depending how I read Command-line flags on front ends, various of these answers may apply.

I feel none do, so downvotes are fine and expected on this one :) I'm posting it more as an exploration of the problem-space, perhaps towards an eventual argument that a solution is not possible in PHP, than an answer that I expect to be accepted.

I've given my arguments against them all, summarized with opinionated bold statements, because that naturally makes the arguments more true. I'm very interested to hear counterarguments, or additional arguments, in the comments!

php -r 'echo"Hello, World!";', 0

One interpretation is that nothing on the commandline counts, but that the entire commandline is treated as a kind of "language dialect name" for the entry.

Against: All code should be counted. Otherwise, this approach makes any contest where bytes matter trivial in almost any language, by offloading all work to the CLI. The parameters to the -r flag here are not a "flag to choose a language option", they are "code", and should be counted as such.

PHP -r, 20

php -r 'echo"Hello, World!";'

It could be argued that, while we count the code on the CLI, the sloc requirement only applies to the contents of source files. If there is no source file, then there are no code lines in source files!

Against: All counted code should be passed to sloc. Every language lets you slap code in the cli params. The challenge isn't meant to degrade into "run hello world without using a source file", so this isn't an interesting solution to the challenge.

PHP -r ignoring quotes, 29

php -r '/**/echo "Hello, World!";/**/'

So we can pass in a minimal code sample on the commandline, getting all the benefits of avoiding PHP's <? requirement, without paying any significant penalty.

Against: Necessary escaping of code should count as code. There's no good argument FOR ignoring the quotes. Not-ignoring them makes challenges more interesting anyway.

So I'd argue that all characters which are counted should be passed to sloc, and this solution is wrapped in quotes, and the quotes should be counted. A quoted string counts as a code line in sloc. So, this fails the sloc test.

PHP -r plus shell escapes, 33

php -r/**/echo\"Hello,\ World\!\"\;/**/

Against: This is no longer PHP. We're not, now, really coding in PHP, we're coding in (some shell) + PHP. If this were submitted as a bash script it'd count as 39 characters, and it'd fail the sloc test. We shouldn't get to reduce the count and pretend it passes, just by pretending it's run in one of the utilities the shell called.

PHP with filepath and param ordering, 16.

This one's a two-parter! First, a file called /x, containing only our 13 character output string:

Hello, World!

Call it as:

php //x

Then, assuming 1) we count the filename as it is used on the commandline, and 2) we prepend that to the code we pass to sloc, because everything counted is code, sloc interprets it as a one-line comment.

Against: both assumptions above are dumb.

PHP with various failed efforts, inf

Including these just as informational: trying both -r and a file specifier, to address the "depends how we concatenate" problem, above.

  1. filename for comment, then -r for code.

    php //x -r 'echo "hi"';

The -r param did not run if a filename preceded it on the line. Same was true of the -B, -R, -E, -F params.

Against: Given the -r flag doesn't count, it's hard to see how this woulda been counted. And it doesn't work anyway.

  1. Maybe the BREF group didn't work because they need actual input lines to parse, since they control per-input-line behavior?

    echo | php //x -B 'echo "hi"';

Same deal. They don't run if a filename for an empty file precedes them on the line. Same was true of the -R, -E, -F params.

Against: This is now (some shell), and it doesn't work.

  1. The -w param is "Output source with stripped comments and whitespace." which almost sounds like an exact description of the challenge! Using php -w x.php, a source file like

    //Hello, World!//

... feels like it should work.

Against: A coding challenge requires that the code runs. No actual code was executed, and I feel that's required, to be in the spirit of a coding challenge. More importantly, it doesn't work: without a leading <?, PHP doesn't see this as PHP code, so does not strip the comments.

  1. Trying variations on this approach, turns out -w does not work with -r.

  2. But -w does run with direct or piped input. However, these have the exact same problem as using a file: PHP requires the leading <?.

  3. What about exploiting ini file params?

    php -a -d cli.prompt='"Hello, World!"'

Against: Doesn't run code, doesn't work. Almost works, but also outputs "Interactive mode enabled\n\n".

Exhaustive exploration of PHP-CLI args

Some push unwanted output to stdout that cannot be modified or redirected through config or code, so are unusable:

  • -a Run interactively.
  • -h Help.
  • -i Show info.
  • --ini list ini files.
  • -l Lint.
  • -m Module list.
  • --rf function info.
  • --rc class info.
  • --re ext info.
  • --rz Zend ext info.
  • --ri ext config info.
  • -s Prettyprint source.
  • -v Version.

Some seem to offer no advantage over simpler alternatives:

  • -B Begin code. No better than -r?
  • -E Run at end. No better than -r?
  • -f File. No better than default exec file param?
  • -F File every line. No better than default exec file param?
  • -R Run every line. No better than -r?

Some seem irrelevant, affecting neither perception as a comment, nor output:

  • -c Config path. Irrelevant?
  • -e Debug info. Irrelevant?
  • -H Hide args from ps. Irrelevant?
  • -n No Config. Irrelevant?
  • -S Webserver. Irrelevant?
  • -t Docroot. Irrelevant?

This leaves us with just four that look potentially exploitable.

  • -d Define INI entry, which could include these likely candidates:
    • auto_append_code/auto_prepend_code could help somehow, but not sure how they'd be any better than the -f flag.
    • cli.prompt already tried above.
    • memcache.*/opcache.* could create output then modify code? Feels an invalid solution, though, even if it worked.
    • filter.default I think only filters input, not output and certainly not code.
    • output_buffering feels like a VERY likely candidate.
    • output_handler feels like a VERY likely candidate.
  • -r Run code. Explored above, no success.
  • -w Print stripped source. Explored above, no success.
  • -z zend ext. Would require a zend extension that could help us.
\$\endgroup\$
1
  • \$\begingroup\$ Edited: not tested yet, but I think a solution might be possible with output buffering turned on :D \$\endgroup\$ Dec 2, 2020 at 2:08
3
\$\begingroup\$

JavaScript (Browser), 34 Bytes

/**/console.log`Hello, World!`/**/
---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  0
       Block comment :  1
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------

Python, 36 Bytes

'''#''';print("Hello, World!");"'''"
---------- Result ------------

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  0
       Block comment :  1
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1

----------------------------
\$\endgroup\$
1
2
\$\begingroup\$

976 9

JavaScript (Browser), 34 Bytes

/**/console.log`Hello, World!`/**/

Result

            Physical :  1
              Source :  0
             Comment :  1
 Single-line comment :  0
       Block comment :  1
               Mixed :  0
 Empty block comment :  0
               Empty :  0
               To Do :  0

Number of files read :  1
\$\endgroup\$
1
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 30 bytes

/**/Write("Hello, World!")/**/

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.