From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id XAA31707; Wed, 24 Apr 2002 23:23:32 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id XAA31561 for ; Wed, 24 Apr 2002 23:23:31 +0200 (MET DST) Received: from mail.cs.net.pl (cyber.cs.net.pl [62.233.142.98]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id g3OLNS103260 for ; Wed, 24 Apr 2002 23:23:29 +0200 (MET DST) Received: by mail.cs.net.pl (Postfix, from userid 510) id 0A43FE16; Wed, 24 Apr 2002 23:23:17 +0200 (CEST) Date: Wed, 24 Apr 2002 23:23:16 +0200 From: Tomasz Zielonka To: Jacek Chrzaszcz Cc: caml-list@inria.fr Subject: Re: [Caml-list] How to read three integers from a text-file... ? Message-ID: <20020424212316.GA26318@cs.net.pl> References: <15557.14957.358556.545541@absurd.mimuw.edu.pl> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <15557.14957.358556.545541@absurd.mimuw.edu.pl> User-Agent: Mutt/1.3.28i Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Tue, Apr 23, 2002 at 12:41:49PM +0200, Jacek Chrzaszcz wrote: > Hello list, [Hello] ;) > Is there a clean way (a one-liner) to read a constant number of > integers separated by whitespace from a text-file (or stdin) ? For 'constant numbers' greater than 1 there are at least five solutions: 1) Write function which will read 'n' ints from input and return a list of them. But that would be unsafe, inefficient and would cause 'this pattern-matching is not exhaustive' warnings in destructuring 'let' bindings. 2) Write several functions: read_1_int, read_2_ints, ..., read_5_ints, which will return tuples with appropriate number of ints. Safer but still inefficient (tuple allocation, copying) and a bit clumsy. 3) Create CamlP4 macro/(syntax extension) which will expand to 'let's binding subsequent ints to given names. Something like: READINTS(a, b, c, d) (sorry, I know it looks like a CPP macro) expanded to: let a = get_int () in let b = get_int () in let c = get_int () in let d = get_int () in 4) Create mechanism dual to printf, but as far as I understand OCaml's printf, this would require extending typechecker. 5) Just 'n' times use a function which reads 1 integer from input. Personally I prefer option 5. I write let read_int = () at top of my program, to avoid using this standard OCaml function. Then I define get_int function, which just reads characters one by one. get_int: unit -> int When using such imperative function, one should be careful. OCaml's evaluation order is not left to right, so following constructs may have effects other than desired: let pair = (get_int (), get_int ()) f (get_int ()) (get_int ()) > I know I can use String.index, Str.split or read char by char (this > sucks), but you have to admit the Pascal or even C versions are more > appealing. Reading char by char sucks? Why? Scanf probably does it, and it isn't exactly _reading_ char by char when you have buffered I/O. I participated in online contest recently and I made some "research" in integer reading :) I've even made benchmarks - the task was to read first integer from input as 'n', sum following 'n' unsigned integers and print the result. Here are the times for n=200000 on PIII 850 (gcc ocamlopt 3.04). program time description ----------------------------------------------------------------------- c_scanf 0.201s - C scanf ("%d", ... c_scanf4 0.173s - C scanf ("%d%d%d%d", ... c_macro 0.095s - my C macro (using getchar()) c_macro2 0.037s - my C macro with input pre-loaded into array ml_genlex 5.032s - Genlex, Genlex.npeek, List.map & List.fold_left ml_genlex2 3.583s - Genlex with other sum function ml_ocamllex 0.517s - ocamllex + int_of_string ml_simple 0.100s - char by char tail-recursive reading function ml_string2 0.061s - similar function, but with input pre-loading Note that C programs were compiled without optimisation. With -O3 c_macro2 peforms even faster - 0m0.028s. I think that ml_simple solution is satisfactory for such contests. It's fast, simple and quite safe to use. I can send the source if someone's interested. > I am asking this question, because our students want to use Ocaml for > competing in various programming contests, where the comfort and speed > (of programming) are essential. My simple solution is comfortable enough for me. Speed of execution is also important in contests - you rather don't want to spend 5 seconds to just read the data. > Jacek Chrzaszcz tomek -- Tomek Zielonka ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners