<div class="gmail_quote">On Sun, May 8, 2011 at 3:04 PM, Timon Gehr <span dir="ltr"><<a href="mailto:timon.gehr@gmx.ch">timon.gehr@gmx.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<div class="im">Andrew Wiley wrote:<br>
> I was one of the D users, although I wasn't really worried about competing.<br>
> I just wanted to see how D would compare after doing so many programming<br>
> contests in Java.<br>
> The main thing that frustrated me was that getting input in D wasn't<br>
> anywhere near as straightforward as it is in Java. For the first problem,<br>
> I'd do something like this in Java:<br>
> Scanner in = new Scanner(System.in);<br>
> int numTests = in.nextInt();<br>
> for(int test = 0; test < numTests; tests++) { //need the test index for<br>
> output<br>
> int numSteps = in.nextInt();<br>
> for(; numSteps < 0; numSteps--)<br>
> char robot = in.nextChar();<br>
> int button = in.nextInt();<br>
> //solve the problem!<br>
> }<br>
> //print the output!<br>
> }<br>
<br>
<br>
</div>Well, I don't like D's readf either (I use scanf, 2-3x faster and better<br>
whitespace handling). That said, you really made my day.<br>
The problem is not that reading input in D is less straightforward than in Java,<br>
the problem is, that you are used to Java's way of doing IO. (which I pretty much<br>
dislike, I guess it is a matter of taste)<br>
<br>
You do not actually have to bother with string handling at all when doing IO in<br>
C/C++/D.<br>
<br>
Reading array of integers:<br>
<br>
int[100000] array; //somewhere in static storage, faster<br>
...<br>
scanf("%d",&n);<br>
foreach(ref x;array) scanf("%d",&x);<br></blockquote><div><br></div><div>What bothers me about that code is that you had to write a string to represent something that should be implicit. It may just be that formattedRead is more strict than scanf, but I had problems getting whitespace to behave properly with format code strings.</div>

<div>Plus, when you just type %d, what if I want a long? What if I want an infinite precision integer? These things aren't solved by C function calls, and trying to come up with a string format code for every possible input would needlessly complicate things.</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Or, some heap activity involved, and actually more keystrokes, but some people<br>
like this way:<br>
readf("%s",&n);//read number of items<br>
<br>
int[] array=to!(int[])(split(strip(readln())));<br>
<br>
<br>
How I would have written your example in D.<br>
int numTests; scanf("%d", &numTests);<br>
foreach(test;0..numTests){<br>
    int numSteps; scanf("%d", &numSteps);<br>
    foreach(step;0..numSteps){ //you have a bug in this line of your Java code<br>
introducing a looooong loop<br>
        char robot; scanf("%c", &robot);<br>
        int button; scanf("%d", &button);<br>
<div class="im">        //solve the problem!<br>
    }<br>
    //print the output<br>
}<br></div></blockquote><div><br></div><div>As a note, I recently discovered while running through some D1 code that %c isn't a format code recognized by the D2 formatting functions. I realize this is C though.</div>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
<br>
><br>
><br>
> In D, that looked like this:<br>
> string line;<br>
> int num;<br>
> stdin.readln(line);<br>
> formattedRead(line, "%s", &num);<br>
> for(int casen = 0; casen < num; casen++) {<br>
><br>
> ...<br>
><br>
> In a few places, I could have used stdin.readf instead of<br>
> readln/formattedRead, but not many because the number of items within a test<br>
> is on the same line as the items.<br>
<br>
</div>That is not a problem at all, you can read the first few elements with readf and<br>
the rest of the line with readln</blockquote><div><br></div><div>The documentation seems to imply that readf reads an entire line. Was I just misunderstanding it? </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

 </blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br>
> I could have just been missing something, but something that was trivial in<br>
> Java became brittle in D because I had to exactly match the whitespace for<br>
<br>
</div>I actually think Java's way is brittle. You have to instantiate a class just to<br>
read IO.<br></blockquote><div><br></div><div>That doesn't make it brittle, that makes it heavy and/or overkill. What's brittle is when I have to exactly match whitespace, write strings for things that should be implicit, and keep track of more state than is strictly necessary. Java's Scanner is nice because you ask for an integer and get an integer, and as long as you ask for the right things in the right order, you don't have to track any state whatsoever. Keeping track of where you are in the input stream is something better left to the code doing the reading rather than the user.</div>

<div>Your way doesn't involve state, but it also doesn't generalize to other types of streams.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">


<div class="im"><br>
> things to work. I suppose I could have read a line and used splitter to<br>
> split on whitespace, but that would make me have to watch more state and<br>
> would wind up looking like this:<br>
> string line;<br>
> stdin.readln(line);<br>
> auto split = split(line);<br>
> int num = to!int(split[0]);<br>
> split = split[1..$];<br>
<br>
</div>I don't get this.<br></blockquote><div><br></div><div>It's simple. I have a line that looks like this:</div><div>4 3 2 67 5</div><div>The first number is the number of numbers that follow, and the code looks like this:</div>

<div>string line = "4 3 2 67 5";</div><div>auto split = split(line);</div><div>int num = to!int(line[0]);</div><div>line = line[1..$];</div><div>foreach(index; 0..num) {</div><div>    int cur - to!int(line[0]);</div>

<div>    line = line[1..$];</div><div>    // do things</div><div>}</div><div><br></div><div>I realize this is just a more complicated version of your heap code above, but suppose I needed to read an integer, a string, and a floating point number for each item. This scales up quite nicely to that sort of thing.</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br>
><br>
> ...<br>
><br>
> Actually... now that I'm looking at that, if I wrote a Scanner-like class<br>
> based on this, is there any chance it could go into Phobos? Seems like<br>
> between split and to, we could get something much less brittle working.<br>
<br>
</div>No chance, that is not the way D/Phobos works. You do not have a class for<br>
everything that would not need one. (just like Phobos does not have a writer class<br>
for output)<br></blockquote><div><br></div><div>Yes, if I had thought a bit more, I wouldn't have said class. This could just be implemented as a few simple methods for reading primitives from string ranges (or character ranges, actually, as that would be more general). I would expect something like this to appear with the stream API that we'll hopefully build at some point. A class would probably be overkill.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
However I agree that Phobos has to provide some better input handling, since using<br>
possibly unsafe C functions is the best way to do it by now. (I think readf is<br>
severely crippled) I may try to implement a meaningful "read" function.</blockquote><div><br></div><div>I think that input handling like this should be built on top of a stream API, and because that API isn't here yet, improving input may be premature. Or it may be too useful to wait.</div>

</div><br>