May 8th was the online qualification round. Let's see how factor deals with the problems.
First of all, all google codejam problems so far have had the same structure:
give a file describing N instances of the problem, output the file giving the N solutions to these instances.
The input file starts with a line containing the value of N, and then the description of N problems.
The output file must contain exactly N lines, each line looking like this :
Case #X: SOLUTION
,where X goes from 1 to N and SOLUTION is the solution to this instance of the problem.
Let's create a vocabulary that automates all this.
First, we load the vocabularies that we need.
USING: formatting io io.encodings.utf8 io.files math.parser
math.ranges sequences splitting kernel ;
IN: gcj.common
Then, declare a generic word that has to read the description of a problem and print it's solution: GENERIC: solve-case ( problem-class -- )
We often have to read integers from files, so here are two useful words for reading 1 or many integers from a line:: read-int ( -- n )
readln 10 base> ;
: read-ints ( -- ints )
readln " " split [ string>number ] map ;
We then need to be able to read the first line containing the number of cases, and for each case print the Case #X: SOLUTION line.: solve-cases ( problem-class -- )
read-int [1,b]
[ "Case #%d: " printf solve-case nl ] with each ;
We also need a function to generate a new filename to which we write the solution : the solution to X.in will be stored in X.out :: out-file ( in-file -- out-file )
"." split but-last ".out" suffix concat ;
Now, all we have to do is open the input file for reading, the output file for writting, and solve each case !: solve-file ( problem-class file -- )
dup out-file utf8 [ utf8 [ solve-cases ] with-file-reader ] with-file-writer ;
Then if one wants to use this generic solver for the gcj, all one has to do is create a new problem-class, and implement the solve-case method.
In another file :
SINGLETON: gcj.anamefortheproblem
M: gcj.anamefortheproblem solve-case
! implement your case here
;
and call the generic part like this :gcj.anamefortheproblem "path/to/input/file" solve-file
Here's the complete source file:
! Copyright (C) 2010 Jon Harper.
! See http://factorcode.org/license.txt for BSD license.
USING: formatting io io.encodings.utf8 io.files math.parser
math.ranges sequences splitting kernel ;
IN: gcj.common
GENERIC: solve-case ( problem-class -- )
: read-int ( -- n )
readln 10 base> ;
: read-ints ( -- ints )
readln " " split [ string>number ] map ;
: solve-cases ( problem-class -- )
read-int [1,b]
[ "Case #%d: " printf solve-case nl ] with each ;
: out-file ( in-file -- out-file )
"." split but-last ".out" suffix concat ;
: solve-file ( problem-class file -- )
dup out-file utf8 [ utf8 [ solve-cases ] with-file-reader ] with-file-writer ;
Aucun commentaire:
Enregistrer un commentaire