2011-01-30 3 views
2

Я начинаю программист, который очень заинтересован в Common Lisp, но не знает его вообще. Я был бы очень благодарен всем, кто может реализовать следующую проблему в Common Lisp, поэтому я вижу, как Common Lisp обрабатывает основные вещи, такие как обработка строк, ввод-вывод файлов и т. Д.Как реализовать эту проблему в Common Lisp?

В этом случае:

Пример входных данных, чтение из файла "problem.in":

3 5 
XHXSS 
XSHSX 
XXHSS 

Вам предоставляется час по ж таблицы символов. Первое число - это количество строк, второе число - количество столбцов.

Для каждого столбца символов, которые вы должны сделать следующее:

Begin просматривал символов сверху вниз.

Если найдено «X», выведите стоимость столбца (стоимость равна нулю по умолчанию), а затем пробел, а затем перейдите к следующему столбцу (пропуская все остальные символы в текущем столбце).

Если «S», найдено, увеличивают стоимость на 1.

Если «Н» найдено, увеличивают стоимость на 3.

Если не было «X» в столбце, выход N» ', за которым следует пробел.

Пример вывода, записывается в "problem.out" файла:

0 4 0 N 1 

Вот моя реализация в 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; 
} 

Я бы предпочел, чтобы увидеть эту проблему реализуется как один функции в этом отношении:

(defun main() 

... 

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

... 

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

... 
) 

ответ

7
(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 " 
+0

Спасибо, что нашли время, чтобы написать это. У меня есть некоторые проблемы с вашим кодом. Вы, кажется, получаете правильные результаты, но я получаю следующие результаты (в Windows 7): в Clozure Common Lisp 1.6 результат 0 3 0 4 N. В Lispworks Personal 6.01 результат: Ошибка. Конец файла при чтении потока # . – Max

+0

@Max: Я получаю правильный результат, используя Clozure CL на моем Mac. Где вы получаете ошибку LispWorks? В призыве решить? –

+0

Попробуйте эту версию. Одна из отличий между Mac и Windows - это конец строки ... –

2

Вы бы не сделали это в одной функции в настоящее время. 70-е годы закончились.

Вы должны определить функцию read-problem-set, которая возвращает список строк, каждый из которых представляет собой список символов. Затем вы определяете функцию transpose, которая переносит это на список столбцов. «Мясо» вычисления будет сделано функцией cost, которая читается в столбце и возвращает ее стоимость. Наконец, вы можете написать функцию output-column-costs, которая записывает список в указанный файл в требуемом формате. Соедините все части в функции solve-problem:

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

Я знаю, что он может быть реализован с большим количеством функций, но я сознательно выбрал одну функцию. Я просто хотел посмотреть, как это будет выглядеть. Но в любом случае любая полная работающая реализация была бы приятной. :-) – Max