Policy on answering challenges with cumbersome I/O

We've probably all seen new users ask questions with cumbersome I/O rules, like mandatory taking the input by reading separated lines of STDIN and outputting to STDOUT to give an example.

In those cases, we usually point them to the default I/O rules in the hope they'll change their challenge description, and also point to the Sandbox so they can get feedback on challenges before posting it on main next time.

However, what is the policy regarding answering those kind of challenges? If the challenge itself is completely clear, despite the cumbersome I/O rules, we should just downvote it. We don't have any reason to close-vote it as unclear if it really isn't, so that's not an option. But is there any reason to also keep it completely unanswered until they've changed their I/O rules?

The main reason I ask is because of this challenge that was posted yesterday. As you can see, it uses a similar input-format as programming contest websites usually use, which I will quote here:

Input Format

• First Line: $$\N\$$(number of strings in the list)
• Next $$\N\$$ lines: String $$\S_i\$$
• Next line $$\Q\$$(number of questions)
• Next $$\Q\$$ lines : Three space-separated integers $$\L\$$, $$\R\$$ and $$\K\$$ Sample Input 5 aaaaa bbbbb ccccc ddddd eeeee 3 3 3 3 1 5 16 3 5 15

Very cumbersome, and even with mandatory 1-based indexing. Still, the challenge itself is clear.

I posted an answer for this challenge, which just got downvoted. Hence the reason for this meta question. I understand downvoting the challenge has a good reason, but what reason is there for downvoting the answers? If this score remains, I will just delete my answer no problem, but I'm mainly trying to understand the reason behind the downvote on my answer and how to prevent it in the future. And what people's opinion are regarding answering questions with cumbersome I/O rules.

Sorry, it was an accident. I had a little fiasco with my computer this morning and I must've pressed the down arrow inadvertently. Stupid touchscreen...

If you make an edit I'll give you an upvote.

• Ah ok, that makes sense. Np, it happens sometimes. Grimmy just suggested a golf, so I've edited my answer. Hmm, I guess this entire meta question is then irrelevant, but I'll just leave it in case someone has an interesting thing/opinion to mention. Mar 2, 2020 at 14:48

This I/O format is fair for many languages – it should be corrected because it isn't fair for all languages, but is normally being used in good faith and we can easily modify answers in languages where it works

I think it's worth thinking about why people use this I/O format in the first place (on other sites). It isn't necessarily a "natural" I/O format for most languages. However, it has the advantage of being very easy to parse; and most competitive programming sites take submissions only as full programs and run them automatically, so they need to have some concrete I/O format to use.

The most notable thing about the "newline-separated length-prefixed array" format is that it isn't cumbersome, at least by the standard of practical languages. Let's imagine we have a challenge whose input format is "the input is an array, specified via a length as a decimal integer on the first line, followed by the elements, each as a decimal integer, on the subsequent lines". Here's a sample input in this format:

5
1
3
6
10
15


representing the array $$\[1,3,6,10,15]\$$. Let's look at what it takes to parse this in various languages.

Practical languages

If I were to write a Perl snippet that reads data in this format, I'd write it like this:

Perl 5, 11 bytes

map<>,1..<>


Try it online!

This is trivially easy to write, short compared to the average Perl program, and simple to memorise. It isn't detracting much from competing in Perl. (I'm not 100% sure that this is optimal, but if we used this sort of I/O format, we'd find the optimal way to write it very quickly.)

What about lower-level languages, like C?

C89 (gcc), 72 bytes

int l;scanf("%d",&l);int*a=malloc(l*4),*b=a;for(;b<a+l;scanf("%d",b++));


Try it online!

This is getting a bit more cumbersome, and a bit harder to write, now (especially because if we aren't taking advantage of the limited range of int, we need a dynamic allocation to be able to handle arbitrarily large lengths, although C's lack of an array type also causes complications); I made an attempt to golf it (under the restriction that I had to declare all the variables I used correctly, without relying on predeclared variables, implicit int, or using variables as the wrong type), but there are almost certainly improvements I missed. However, parsing more or less any other format would be worse. In Perl, we could simplify the snippet by changing the input format to Perl's array notation (1, 3, 6, 10, 15), so that we could parse it with eval<>, but C has neither an array notation nor an eval operator so we can't really go any simpler. (Note in particular that different languages are good at parsing different formats; JavaScript would want [1, 3, 6, 10, 15], for example. But the newline-separated format is "fair" in the sense that practical languages generally don't vary in respect to which builtins they have available for parsing it.)

It's also worth noting that the length prefix on this format makes it fast to parse – delimited formats like Perl's and JavaScript's mean that you don't know the length of the array until you've finished parsing, so might have to allocate more memory mid-parse, whereas knowing the length in advance avoids this issue (sufficiently so that in languages like Rust and Java, the built-in list classes allow you to specify in advance how many elements you expect the list to eventually grow to). Offsite programming competitions often have at least some emphasis on speed (and we do even over here), so you wouldn't want the I/O mechanism to artificially slow down the program.

Golfing languages

So if this format is intended to put practical programming languages on a level playing field when it comes to parsing input, what about golfing languages? Many of those, especially more recently, are designed to abuse CGCC's lenient I/O rules.

If this format were more common (say it were standard on CGCC and the history of golfing languages were influenced by that environment), we'd probably see golfing languages adding builtins for it (and I'm currently planning to add builtins for handling this sort of I/O format to the next golfing language I write – it'd make the language more useful in places other than CGCC). As it is, though, the most popular languages don't have knowledge of this format in particular. For those that have builtins for reading from standard input, it hardly matters, though:

Jelly, 3 bytes

ƓƓ€


Try it online!

05AB1E, 5 bytes

IEIˆ}


Try it online!

(Note: I don't really know 05AB1E; I suspect I've missed a builtin and that this is doable in 4. These snippets are written under the assumption that we aren't allowed to read beyond the end of the part of standard input that represents the array; the 05AB1E would be simpler otherwise.)

Notable here is that the Jelly program is actually identical to the Perl program I wrote above; the builtins have shorter names, but it's the same builtins connected together the same way.

So our golfing languages might not have been designed to abuse this format, but if they're capable of reading input interactively, it doesn't matter – it's fair for them just the same as it is for the practical languages.

We do run into a bit of a dead end with some golfing languages, though; there are languages like GolfScript and Brachylog that are incapable of taking input interactively (GolfScript reads the entirety of standard input before it starts to run the program, whereas Brachylog doesn't really have the concept of a "full program" – just functions – and the concept of a Brachylog full program is primarily defined by the behaviour of TIO's wrapper). So parsing input, for these languages, is something that's out of scope, and the fact that they're excluded is a good reason to not use formats like this.

Challenge esolangs

Now let's look at esolangs which are designed to be hard to program in (or else naturally become hard to program in due to being excessively low level), rather than easy to golf in. The main issues with these are that they a) might not have the concept of an array and b) frequently can't read numbers in decimal, which makes the I/O format very unfair when it comes to these languages – parsing the input might be harder than solving the rest of the problem, and will be very repetitive if it isn't.

7, 61 non-whitespace characters, 23 bytes

177166177236623716405 7 131 7 740561726405 7 023 7 40352174640555400


Try it online!

(Whitespace added for readability.) 7 is an example of a low-level esolang which, among this genre, is particularly good at handling this sort of I/O format – it has I/O in decimal as a built-in. What it doesn't have is arrays, or even integers, so in order to be able to parse this sort of format, those have to be defined from scratch. (In case you're wondering how it does numerical I/O without integers: input is done via repeating the body of a function a number of times equal to the input, and the function can then be executed to effectively create a loop where the number of iterations is given by the input.)

Indeed, the program wasn't amazingly hard to implement – I managed to write the whole thing in one session without giving up in frustration, and it ends up shorter than the equivalent C program (despite the need to do all the "plumbing" from scratch, and to define formats for integers and for arrays of integers). The interesting thing here is that this "cumbersome" I/O format is actually a better fit than CGCC's "flexible" formats – those are trying to provide input using the language's data types, but 7 doesn't have those, and thus it would prefer to use a text format that's particularly easy to parse (like this one is!). In general, it's very unclear to me how I'm meant to take input in languages that don't have the standard data types that people normally use when specifying inputs to challenges.

The problem comes when we have languages with the opposite properties – they have arrays and integers built in, but no builtins for parsing numbers in decimal. In this case, the decimal parsing routine may well be extremely long, and need to be copied from answer to answer once the most optimal way to do it is found.

Conclusions

This really isn't a bad I/O format – it leads to a fairer comparison between languages than most I/O formats do (less important on CGCC because it isn't a cross-language competition, but still a nice property), and most languages can implement it in a fairly easy way. If you're using a language like Perl or Jelly, the parser for it can trivially be worked into your program without needing to put any thought into it at all, and might potentially even give golfing opportunities in which you do the input parsing and computation at the same time. If you're using a language like 7, it's still fairly easy to handle relative to the rest of the language, despite our normal I/O rules not working at all in that context. I'm not surprised that it's standard on most competitive programming sites.

However, there are some languages which hugely struggle when an I/O format like this is introduced. Some languages can't read from standard input interactively, and can't handle this format. Some don't have built-ins to read integers in decimal, and those will be faced with a huge amount of boilerplate (which will probably be identical from answer to answer) when trying to deal with this format. As a consequence, we don't have this format as standard and prefer to correct challenges that use it.

What to do about answering the challenge before the question is corrected? Well, if you're using a language for which the I/O format works, it'll probably simply be a matter of deleting the parser once you're done (and the parser will be very simple to write). If you're using a language for which the format doesn't work, you probably won't be able to answer the challenge before it's corrected. Either way, that's no reason to avoid answering it (keeping up with edits to the challenge will likely be trivial) and also no reason to avoid correcting the question.

• Good points indeed. As mentioned in the top-voted answer, I primarily created this meta question because of a voting mistake. It also makes sense that this format is used for automatic verification programs on other websites. +1 for writing everything above. PS: You can remove both the I in the 05AB1E program. An alternative 4-byter could be EI}). Although I'd probably use this 2-byter: |¦ to just get all inputs and remove the first item in this particular case. Jan 15 at 17:42

Questions with unnecessarily cumbersome I/O can be answered as if they followed default* I/O rules

*Or at least, more reasonable I/O rules

As long as you specify how you are handling I/O and it is within reason for a normal challenge, just ignore cumbersome I/O constraints and link this meta (assuming this meta is upvoted into consensus).

• -1 I disagree with this. If a challenge specifies a specific I/O format, even if it's cumbersome and annoying, then answers should follow that format. Being able to just ignore parts of a challenge because you think they're "cumbersome" is not ok in my book. If a challenge requires something you think is bad (or annoying/cumbersome/etc.) downvote instead Dec 29, 2021 at 17:25
• i have participated in democracy :) Dec 30, 2021 at 13:36

Defaults can be overridden

...that's why they're called defaults.

If the challenge itself is completely clear, despite the cumbersome I/O rules, we should just downvote it.

No, I think we shouldn't downvote good challenges just because they override some of the defaults.

In the particular case of the linked challenge, I think the I/O restrictions actually make it more interesting. With flexible I/O, it would be mostly trivial, but the weird input format opens up some golfing opportunies (as demonstrated by your answer being 20 17).

Of course, there are good reasons for the defaults, and I hope most questions will still follow them, but having one question overriding them every once in a while is perfectly acceptable.

• Cumbersome does not mean "other than the defaults". No one is downvoting a challenge "just because they override some of the defaults", that is a false premise. We are downvoting a challenge because we think it is bad.
– Wheat Wizard Mod
Mar 2, 2020 at 20:31
• @PostRockGarfHunter The only comment on the linked challenge that looks like an explanation for the downvotes says We have many useful defaults which should not be overridden without good reason. It sure looks like overriding the defaults is the reason it’s being downvoted (either that, or it’s just being downvoted without any explanation). Mar 2, 2020 at 21:02
• May I point you to the "without good reason" part of the quote. Downvoting for overriding the defaults without any reason to do so is very different from downvoting "just because they override some of the defaults" as you present it in your answer.
– Wheat Wizard Mod
Mar 2, 2020 at 21:28
• The default rule of flexible I/O is there because we once agreed that golfing I/O was too repetitive and uninteresting. While that decision was made years ago (AFAIK), I believe majority of us still think so, thus the downvotes on the challenge. Mar 3, 2020 at 7:13
• The I/O restrictions make it nearly impossible, if not impossible in a language I was planning to solve it in. Mar 3, 2020 at 12:08
• I made the comment and did not down-vote - to be clear I was offering suggestions which I thought would make the challenge more likely to be well-received by the community. I quite liked the question premise. Mar 4, 2020 at 1:33