{"id":32745822,"url":"https://github.com/aalexuser/functional-programming-3","last_synced_at":"2026-02-21T05:05:00.122Z","repository":{"id":260129039,"uuid":"880407370","full_name":"AaLexUser/Functional-programming-3","owner":"AaLexUser","description":"Лабораторная работа 3 по функциональному программированию (ИТМО, ПИиКТ-СППО, 4 курс)","archived":false,"fork":false,"pushed_at":"2024-10-29T18:42:42.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-29T18:49:28.379Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AaLexUser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-29T17:06:08.000Z","updated_at":"2024-10-29T18:42:46.000Z","dependencies_parsed_at":"2024-10-29T19:20:47.528Z","dependency_job_id":null,"html_url":"https://github.com/AaLexUser/Functional-programming-3","commit_stats":null,"previous_names":["aalexuser/functional-programming-3"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AaLexUser/Functional-programming-3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaLexUser%2FFunctional-programming-3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaLexUser%2FFunctional-programming-3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaLexUser%2FFunctional-programming-3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaLexUser%2FFunctional-programming-3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AaLexUser","download_url":"https://codeload.github.com/AaLexUser/Functional-programming-3/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AaLexUser%2FFunctional-programming-3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":282494953,"owners_count":26678646,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-03T02:00:05.676Z","response_time":108,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-11-03T17:06:37.498Z","updated_at":"2025-11-03T17:06:39.541Z","avatar_url":"https://github.com/AaLexUser.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Лабораторная работа №3\n\n## Дисциплина\n\nФункциональное программирование\n\n## Выполнил\n\nЛапин Алексей Александрович, P34102\n\n## Цель работы\n\nПолучить навыки работы с вводом/выводом, потоковой обработкой данных, командной строкой.\n\n## Требования\n\n- обязательно должна быть реализована линейная интерполяция (отрезками, [link](https://en.wikipedia.org/wiki/Linear_interpolation));\n- настройки алгоритма интерполяции и выводимых данных должны задаваться через аргументы командной строки:\n    - какие алгоритмы использовать (в том числе два сразу);\n    - частота дискретизации результирующих данных;\n    - и т.п.;\n- входные данные должны задаваться в текстовом формате на подобии \".csv\" (к примеру `x;y\\n` или `x\\ty\\n`) и подаваться на стандартный ввод, входные данные должны быть отсортированы по возрастанию x;\n- выходные данные должны подаваться на стандартный вывод;\n- программа должна работать в потоковом режиме (пример -- `cat | grep 11`), это значит, что при запуске программы она должна ожидать получения данных на стандартный ввод, и, по мере получения достаточного количества данных, должна выводить рассчитанные точки в стандартный вывод;\n\nПриложение должно быть организовано следующим образом:\n\n```text\n    +---------------------------+\n    | обработка входного потока |\n    +---------------------------+\n            |\n            | поток / список / последовательность точек\n            v\n    +-----------------------+      +------------------------------+\n    | алгоритм интерполяции |\u003c-----| генератор точек, для которых |\n    +-----------------------+      | необходимо вычислить         |\n            |                      | промежуточные значения       |\n            |                      +------------------------------+\n            |\n            | поток / список / последовательность рассчитанных точек\n            v\n    +------------------------+\n    | печать выходных данных |\n    +------------------------+\n```\n\nПотоковый режим для алгоритмов, работающих с группой точек должен работать следующим образом:\n\n```text\no o o o o o . . x x x\n  x x x . . o . . x x x\n    x x x . . o . . x x x\n      x x x . . o . . x x x\n        x x x . . o . . x x x\n          x x x . . o . . x x x\n            x x x . . o o o o o o EOF\n```\n\nгде:\n\n- каждая строка -- окно данных, на основании которых производится расчёт алгоритма;\n- строки сменяются по мере поступления в систему новых данных (старые данные удаляются из окна, новые -- добавляются);\n- `o` -- рассчитанные данные, можно видеть:\n    - большинство окон используется для расчёта всего одной точки, так как именно в \"центре\" результат наиболее точен;\n    - первое и последнее окно используются для расчёта большого количества точек, так лучших данных для расчёта у нас не будет.\n- `.` -- точки, задействованные в рассчете значения `o`.\n- `x` -- точки, расчёт которых для \"окон\" не требуется.\n\nПример вычислений для шага 1.0 и функции sin(x):\n\n```text\nВвод первых двух точек (в данном примере X Y через пробел):\n0 0.00\n1.571 1\n\nВывод:\nЛинейная (идем от первой точки из введенных (0.00) с шагом 1, покрывая все введенные X (1.571 \u003c 2)):\n0.00    1.00    2.00\n0.00    0.64    1.27\n\nВвод третьей точки:\n3.142 0\n\nСледующий вывод:\nЛинейная (идем от второй точки из введенных (1.571) с шагом 1, покрывая все введенные X (3.142 \u003c 3.57)):\n1.57    2.57    3.57\n1.00    0.36    -0.27\n\nВвод четвертой точки:\n4.712 -1\n\nСледующий вывод:\nЛинейная (идем от третьей точки из введенных (3.142) с шагом 1, покрывая все введенные X (4.712 \u003c 5.14)):\n3.14    4.14    5.14\n0.00    -0.64   -1.27\n\nЛагранж (теперь количество введенных точек повзоляет его рассчитать, идем от первой точки (0.00) из введенных с шагом 1, покрывая все введенные X (4.712 \u003c 5)):\n0.00    1.00    2.00    3.00    4.00    5.00\n0.00    0.97    0.84    0.12    -0.67   -1.03\n\nВвод пятой точки:\n12.568  0\n\nСледующий вывод:\nЛинейная (идем от четвертой точки из введенных (4.712) с шагом 1, покрывая все введенные X (12.568 \u003c 12.71))):\n4.71    5.71    6.71    7.71    8.71    9.71    10.71   11.71   12.71\n-1.00   -0.87   -0.75   -0.62   -0.49   -0.36   -0.24   -0.11   0.02\n\nЛагранж (идем от второй точки из введенных (1.571) с шагом 1, покрывая все введенные X (12.568 \u003c 12.57))):\n1.57    2.57    3.57    4.57    5.57    6.57    7.57    8.57    9.57    10.57   11.57   12.57\n1.00    0.37    -0.28   -0.91   -1.49   -1.95   -2.26   -2.38   -2.25   -1.84   -1.11   0.00\n\nИ т.д.\n```\n\nКак видно из примера выше, окна для каждого метода двигаются по-разному. Для линейной окно начало сдвигаться уже при вводе третьей точки (т.к. для вычисления нужно всего две), в то время как для Лагранжа окно начало двигаться только когда была введена пятая точка (т.к. здесь для вычислений нужно больше точек).\n\nОбщие требования:\n\n- программа должна быть реализована в функциональном стиле;\n- ввод/вывод должен быть отделён от алгоритмов интерполяции;\n- требуется использовать идиоматичный для технологии стиль программирования.\n\n## Ход работы\n\n### Структура проекта\n\n```shell\n├── README.md\n├── src/\n│   ├── core.clj\n│   ├── input.clj\n│   └── interpolation.clj\n├── test/\n│   └── interpolation_test.clj\n│\n├── .github/workflows/\n│   └── clojure.yml\n│\n├── .gitingore \n├── tests.edn\n└── deps.edn\n```\n\n#### Парсер аргументов командной строки.\n\nПарсер аргументов командной строки реализован с помощью библиотеки [clojure.tools.cli](https://github.com/clojure/tools.cli).\n\n```clojure\n(def cli-options\n  [[\"-a\" \"--algorithms ALGORITHMS\" \"Comma-separated list of interpolation algorithms (linear,lagrange)\"\n    :default []\n    :parse-fn #(mapv str/lower-case (map str/trim (str/split % #\",\")))\n    :validate [#(every? algorithms %) \"Unknown algorithm specified\"]]\n   [\"-s\" \"--step STEP\" \"Data sampling frequency\"\n    :parse-fn #(Double/parseDouble %)\n    :validate [#(pos? %) \"Step must be positive\"]\n    :default 1.0]\n   [\"-h\" \"--help\"]])\n```\n\nВ данном случае программа принимает на вход два аргумента:\n\n- `-a` или `--algorithms` -- список алгоритмов, которые необходимо применить к входным данным;\n- `-s` или `--step` -- шаг, с которым будут выводиться результаты.\n\n#### Функция main\n\n```clojure\n(defn -main [\u0026 args]\n  (let [{:keys [algorithms step]} (parse-args args)]\n    (try\n      (let [points-seq (read-input-seq) \n            accumulated-points (reductions conj [] points-seq)]\n        (doseq [points accumulated-points]\n          (run-interpolation algorithms step points)))\n      (catch Exception e\n        (exit 1 (str \"Error during interpolation: \" (.getMessage e)))))))\n```\n\n#### Обработка входного потока.\n\n```clojure\n(defn parse-point [input]\n  (let [tokens (str/split input #\"[,\\t ;]+\")]\n    (if (str/blank? input) (do (println \"Blank input received. Exiting.\") (System/exit 0))\n        (if (= (count tokens) 2)\n          (let [[x y] tokens]\n            (try\n              (-\u003ePoint (Double/parseDouble x) (Double/parseDouble y))\n              (catch NumberFormatException e\n                (throw (ex-info \"Both coordinates must be valid numbers.\" {:input input} e)))))\n          (throw (ex-info \"Input must contain exactly two numerical values separated by comma, tab, space, or semicolon.\" {:input input}))))))\n\n\n(defn read-input-seq\n  \"Lazily reads input lines from standard input and parses them into Point records.\"\n  []\n  (-\u003e\u003e (line-seq (java.io.BufferedReader. *in*))\n       (map str/trim)\n       (map parse-point)\n       (filter some?)))\n```\n\n#### Функция генерации точек, для которых будут вычисляться значения.\n\n```clojure\n(defn generate-steps\n  \"Generates a sequence of steps from x-min to x-max with the specified step size.\"\n  [x-min x-max step]\n  (let [steps (take-while #(\u003c= % x-max)\n                           (iterate #(+ % step) x-min))\n        last-step (+ (last steps) step)]\n    (if (= (last steps) x-max)\n      (vec steps)\n      (conj (vec steps) last-step))))\n```\n\nФункция `generate-steps` генерирует последовательность значений x, с заданным шагом.\n\n#### Алгоритмы интерполяции:\n\n- Линейная интерполяция\n\n```clojure\n(defn linear-interpolation\n  \"Performs linear interpolation between the last two points for a given x.\"\n  [points x]\n  (let [[p0 p1] (take-last 2 points)\n        x0 (:x p0)\n        x1 (:x p1)\n        y0 (:y p0)\n        y1 (:y p1)]\n    (+ (* (- y1 y0) (/ (- x x0) (- x1 x0))) y0)))\n```\n\n- Интерполяция Лагранжа\n\n```clojure\n(defn lagrange-basis\n  \"Calculates the Lagrange basis polynomial for a given point x.\"\n  [points i x]\n  (reduce\n   (fn [acc j]\n     (if (= i j)\n       acc\n       (/ (* acc (- x (:x (nth points j))))\n          (- (:x (nth points i)) (:x (nth points j))))))\n   1\n   (range (count points))))\n\n(defn lagrange-interpolation\n  \"Performs Lagrange interpolation between the last four points for a given x.\"\n  [points x]\n  (reduce\n   (fn [acc i]\n     (+ acc (* (lagrange-basis points i x) (:y (nth points i)))))\n   0\n   (range (count points))))\n```\n\n## Вывод программы\n\n```shell\n\u003e clojure -M -m core -a linear,lagrange\n0 0\n1.571 1\nLinear interpolation result:\n0.00    1.00    2.00\n0.00    0.64    1.27\n3.142 0\nLinear interpolation result:\n1.57    2.57    3.57\n1.00    0.36    -0.27\n4.712 -1\nLinear interpolation result:\n3.14    4.14    5.14\n0.00    -0.64   -1.27\nLagrange interpolation result:\n0.00    1.00    2.00    3.00    4.00    5.00\n0.00    0.97    0.84    0.12    -0.67   -1.03\n12.568  0\nLinear interpolation result:\n4.71    5.71    6.71    7.71    8.71    9.71    10.71   11.71   12.71\n-1.00   -0.87   -0.75   -0.62   -0.49   -0.36   -0.24   -0.11   0.02\nLagrange interpolation result:\n1.57    2.57    3.57    4.57    5.57    6.57    7.57    8.57    9.57    10.57   11.57  12.57\n1.00    0.37    -0.28   -0.91   -1.49   -1.95   -2.26   -2.38   -2.25   -1.84   -1.11  0.00\n\nBlank input received. Exiting.\n```\n\n```shell\n\u003e clojure -M -m core -a linear,lagrange -s 0.5\n0 0\n1 1\nLinear interpolation result:\n0.00    0.50    1.00\n0.00    0.50    1.00\n2 2\nLinear interpolation result:\n1.00    1.50    2.00\n1.00    1.50    2.00\n3 3\nLinear interpolation result:\n2.00    2.50    3.00\n2.00    2.50    3.00\nLagrange interpolation result:\n0.00    0.50    1.00    1.50    2.00    2.50    3.00\n0.00    0.50    1.00    1.50    2.00    2.50    3.00\n4 4\nLinear interpolation result:\n3.00    3.50    4.00\n3.00    3.50    4.00\nLagrange interpolation result:\n1.00    1.50    2.00    2.50    3.00    3.50    4.00\n1.00    1.50    2.00    2.50    3.00    3.50    4.00\n\nBlank input received. Exiting.\n```\n\n## Заключение\n\nВ ходе выполнения лабораторной работы были достигнуты следующие результаты:\n\n1. Реализована программа для интерполяции данных с поддержкой:\n   - Линейной интерполяции\n   - Интерполяции методом Лагранжа\n   - Потоковой обработки входных данных\n   - Настраиваемой частоты дискретизации\n\n2. Получены практические навыки:\n   - Работы с потоковым вводом/выводом в Clojure\n   - Обработки аргументов командной строки\n   - Реализации алгоритмов интерполяции в функциональном стиле\n\n3. Программа полностью соответствует заданным требованиям и демонстрирует эффективное применение функционального подхода к решению поставленной задачи.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalexuser%2Ffunctional-programming-3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faalexuser%2Ffunctional-programming-3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faalexuser%2Ffunctional-programming-3/lists"}