Haskell: callender
От: Аноним  
Дата: 24.11.09 17:33
Оценка:
Уважаемые, не затруднит ли кого написать консольный календарик (пользователь вводит день недели соответствующий первому числу и количество дней в месяце, программа печатает в семь столбиков числа месяца). С подобным вопросом обратилась студентка на одном форуме, но спрашивала о С++, я от нечего делать написал ей на С++, а поскольку сижу изучаю хаскель, стало интересно посмотреть, как на нём это делается.

Сам подобное написать не могу, я пока ещё в самом начале изучения и элементарное для данной задачи — как вообще хранить данные введённые пользователем, не могу найти, как сделать. -/

p.s. не студент, задание сдавать мне никуда не надо.
Re: Haskell: callender
От: MigMit Россия http://migmit.vox.com
Дата: 24.11.09 19:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Уважаемые, не затруднит ли кого написать консольный календарик (пользователь вводит день недели соответствующий первому числу и количество дней в месяце, программа печатает в семь столбиков числа месяца).


Такое — только на бейсике. Для компьютера МК85.
Re[2]: Haskell: callender
От: Аноним  
Дата: 24.11.09 20:25
Оценка:
Здравствуйте, MigMit, Вы писали:

MM>Такое — только на бейсике. Для компьютера МК85.


Не сможешь. У этого калькулятора экран содержал только одну строку судя по педевикии.
Re[3]: Haskell: callender
От: MigMit Россия http://migmit.vox.com
Дата: 24.11.09 20:28
Оценка:
Здравствуйте, Аноним, Вы писали:

MM>>Такое — только на бейсике. Для компьютера МК85.


А>Не сможешь. У этого калькулятора экран содержал только одну строку судя по педевикии.


Зато он был графическим. Так что можно сделать плавный скроллинг.
Re: Haskell: callender
От: Буравчик Россия  
Дата: 24.11.09 22:25
Оценка: 4 (1)
Здравствуйте, Аноним, Вы писали:

А>Уважаемые, не затруднит ли кого написать консольный календарик (пользователь вводит день недели соответствующий первому числу и количество дней в месяце, программа печатает в семь столбиков числа месяца).


import Text.Printf

-- Будем представлять календарь как таблицу (список списков)
-- Каждая клетка таблицы может включать дату, заголовок или быть пустой
data Cell = Day Int | Header String | Empty deriving Show

-- Формируем таблицу с календарем (отделили чистую функцию от IO)
-- Строим список, который соответствует таблице, если читать ее слева направо, сверху вниз. 
-- Склеиваем: заголовки, начальные пустые клетки, даты, конечные пустые клетки
-- Разбиваем полученный список на блоки по 7 элементов. Получаем "таблицу" (список списков)
-- Например, для (calendar 15 5) функция возвращает: 
--   [Header "mon",Header "tue",Header "wed",Header "thu",Header "fri",Header "sat",Header "sun"]
--   [Empty,Empty,Empty,Empty,Day 1,Day 2,Day 3]
--   [Day 4,Day 5,Day 6,Day 7,Day 8,Day 9,Day 10]
--   [Day 11,Day 12,Day 13,Day 14,Day 15,Empty,Empty]
calendar :: Int -> Int -> [[Cell]]
calendar days first = splitBy 7 $ headerLine ++ datesLines
  where countStart = first-1                   -- количество пустых клеток на первой неделе
        countEnd   = (8-days-first) `mod` 7    -- количество пустых клеток на последнкй неделе
        datesLines = replicate countStart Empty ++ map Day [1..days] ++ replicate countEnd Empty
        headerLine = map Header ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] 

-- Разбивает список xs на блоки по n элементов
splitBy :: Int -> [t] -> [[t]]
splitBy _ [] = []
splitBy n xs = start : splitBy n end
  where (start, end) = splitAt n xs

-- Печатает календарь (вынесли форматирование календаря в отдельную функцию)
-- Для каждой строки вызываем showLine: преобразовываем значение клетки в строку (showElement), 
--   форматируем (printf) и вставляем между ними пробелы (unwords). Получаем строку для вывода на экран.
-- Полученные строки выводим на экран (unlines превращает список строк в одну строку с символами '\n')
printCalendar :: [[Cell]] -> IO ()
printCalendar cells = putStr $ unlines $ map showLine $ cells
  where showLine xs = unwords $ map (printf "%3s" . showElement) xs
        showElement (Day d)    = show d
        showElement (Header h) = h
        showElement Empty      = ""

main = do
  first <- do putStr "Enter start day of week (1..7): " ; readLn
  days <- do putStr "Enter count days in month: " ; readLn
  putStrLn ""
  printCalendar $ calendar days first


Использовать на свой страх и риск!

Вот, например календарь на ноябрь 2009:

Enter start day of week (1..7): 7
Enter count days in month: 30

mon tue wed thu fri sat sun
                          1
  2   3   4   5   6   7   8
  9  10  11  12  13  14  15
 16  17  18  19  20  21  22
 23  24  25  26  27  28  29
 30


А>p.s. не студент, задание сдавать мне никуда не надо.


Best regards, Буравчик
Re[2]: Haskell: callender
От: Аноним  
Дата: 24.11.09 22:55
Оценка:
Сеньк э лот. Отдельное спасибо за коментарии. Утолили жажду, так сказать, у меня вечно терпения не хватает линейно осваивать что-то новое, всё время тянет заглянуть вперёд. В данном случае (моего знакомства с ФЯ) постоянно охота сравнений с чем-то приземлённм и обыденным, как например с решением календаря на С++. А то в доступных примерах квик сорт, конечно, впечатляет, но...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.