On Sun, May 8, 2011 at 3:04 PM, Timon Gehr <timon.g...@gmx.ch> wrote:

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

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.
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.

Or, some heap activity involved, and actually more keystrokes, but some
> people
> like this way:
> readf("%s",&n);//read number of items
>
> int[] array=to!(int[])(split(strip(readln())));
>
>
> How I would have written your example in D.
> int numTests; scanf("%d", &numTests);
> foreach(test;0..numTests){
>    int numSteps; scanf("%d", &numSteps);
>    foreach(step;0..numSteps){ //you have a bug in this line of your Java
> code
> introducing a looooong loop
>        char robot; scanf("%c", &robot);
>        int button; scanf("%d", &button);
>         //solve the problem!
>    }
>    //print the output
> }
>

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.

>
> >
> >
> > In D, that looked like this:
> > string line;
> > int num;
> > stdin.readln(line);
> > formattedRead(line, "%s", &num);
> > for(int casen = 0; casen < num; casen++) {
> >
> > ...
> >
> > In a few places, I could have used stdin.readf instead of
> > readln/formattedRead, but not many because the number of items within a
> test
> > is on the same line as the items.
>
> That is not a problem at all, you can read the first few elements with
> readf and
> the rest of the line with readln


The documentation seems to imply that readf reads an entire line. Was I just
misunderstanding it?

>


> > I could have just been missing something, but something that was trivial
> in
> > Java became brittle in D because I had to exactly match the whitespace
> for
>
> I actually think Java's way is brittle. You have to instantiate a class
> just to
> read IO.
>

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.
Your way doesn't involve state, but it also doesn't generalize to other
types of streams.


> > things to work. I suppose I could have read a line and used splitter to
> > split on whitespace, but that would make me have to watch more state and
> > would wind up looking like this:
> > string line;
> > stdin.readln(line);
> > auto split = split(line);
> > int num = to!int(split[0]);
> > split = split[1..$];
>
> I don't get this.
>

It's simple. I have a line that looks like this:
4 3 2 67 5
The first number is the number of numbers that follow, and the code looks
like this:
string line = "4 3 2 67 5";
auto split = split(line);
int num = to!int(line[0]);
line = line[1..$];
foreach(index; 0..num) {
    int cur - to!int(line[0]);
    line = line[1..$];
    // do things
}

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.


> >
> > ...
> >
> > Actually... now that I'm looking at that, if I wrote a Scanner-like class
> > based on this, is there any chance it could go into Phobos? Seems like
> > between split and to, we could get something much less brittle working.
>
> No chance, that is not the way D/Phobos works. You do not have a class for
> everything that would not need one. (just like Phobos does not have a
> writer class
> for output)
>

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.


> However I agree that Phobos has to provide some better input handling,
> since using
> possibly unsafe C functions is the best way to do it by now. (I think readf
> is
> severely crippled) I may try to implement a meaningful "read" function.


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.

Reply via email to