开发者

How to implement this problem in Common Lisp?

I'm a beginning programmer, who is very interested in Common Lisp, but doesn't know it at all. I would be very thankful to anyone, who can implement 开发者_Python百科the following problem in Common Lisp, so I can see how Common Lisp handles basic things, like string processing, file I/O, etc.

Here is the problem:

Example of input, read from "problem.in" file:

3 5 
XHXSS 
XSHSX 
XXHSS

You are given h by w table of characters. The first number is the number of rows, second number is the number of columns.

For each column of characters you should do the following:

Begin looking through characters from top to bottom.

If 'X' is found, output the cost of the column (cost is zero by default) followed by space character and then go to the next column (skipping all other characters in the current column).

If 'S' is found, increase cost by 1.

If 'H' is found, increase cost by 3.

If there was no 'X' in the column, output 'N' followed by space character.

Example of output, written to "problem.out" file:

0 4 0 N 1 

Here is my implementation in C++:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(void)
{

    ifstream input;
    input.open("problem.in");

    ofstream output("problem.out");

    int h, w;
    input >> h >> w;

    string * str = new string[h];

    for(int i = 0; i < h; i++) input >> str[i];

    for(int i = 0; i < w; i++)
    {

        int cost = 0;
        bool found = false;

        for(int j = 0; j < h; j++)
        {
            char ch = str[j][i];
            if(ch == 'X') { found = true; break; }  
            else if(ch == 'S') cost += 1;
            else if(ch == 'H') cost += 3;
        }

        if(found) output << cost;
        else output << 'N';

        output << ' ';
    }

    input.close();
    output.close();

    return 0;
}

I would prefer to see this problem implemented as one function, something along these lines:

(defun main()

...

(with-open-file (input "problem.in" :direction :input)
(...))

...

(with-open-file (output "problem.out" :direction :output :if-exists :supersede)
(...))

...
)


(defun solve-problem (in-file out-file)
  (labels ((solve (in out)
             (let ((h (read in))
                   (w (read in)))
               (compute-output out h w
                              (read-array in h w (make-array (list h w))))))
           (read-array (stream h w array)
             (loop for i below h do (read-line stream)
                   (loop for j below w
                         do (setf (aref array i j)
                                  (read-char stream))))
             array)
           (compute-output (stream h w array)
             (loop with x-p and cost for j below w do
               (setf x-p nil cost 0)
               (loop for i below h do
                 (case (aref array i j)
                   (#\X (setf x-p t) (return))
                   (#\S (incf cost))
                   (#\H (incf cost 3))))
               (format stream "~a " (if x-p cost #\N)))))
    (with-open-file (in in-file)
      (with-open-file (out out-file :direction :output :if-exists :supersede)
        (solve in out)))))

CL-USER 17 > (solve-problem "/tmp/test.data" "/tmp/result.text")
NIL

CL-USER 18 > (with-open-file (stream "/tmp/result.text") (read-line stream))
"0 4 0 N 1 "


You would not do this in a single function nowadays. The 70's are over.

You would define a function read-problem-set, which returns a list of rows, each of which is a list of characters. Then, you would define a function transpose, which transposes that to a list of columns. The "meat" of the calculation would be done by a function cost, which reads in a column and returns its cost. Finally, you can write a function output-column-costs, which writes a list to the specified file in the required format. Connect all the pieces in a function solve-problem:

(defun solve-problem (in-file out-file)
  (output-column-costs out-file
                       (mapcar #'cost
                               (transpose (read-problem-set in-file)))))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜