(defun solve-quadratic (a b c)
  "Solve ax^2 + bx + c = 0, including linear and degenerate cases."
  (cond
    ((= a 0) 
     (cond
       ((= b 0)
        (if (= c 0)
            (format t "Infinite solutions~%")
            (format t "No solution~%")))
       (t
        (format t "Linear root: ~a~%" (/ (- c) b)))))
    (t  ;; quadratic case
     (let ((disc (- (* b b) (* 4 a c))))
       (cond
         ((< disc 0) (format t "No real roots.~%"))
         ((= disc 0) (format t "One real root: ~a~%" (/ (- b) (* 2 a))))
         (t (format t "Roots: ~a and ~a~%"
                    (/ (+ (- b) (sqrt disc)) (* 2 a))
                    (/ (- (- b) (sqrt disc)) (* 2 a)))))))))

(defun factorial (n)
  (let ((f 1))
    (dotimes (i n) (setf f (* f (+ i 1))))
    (format t "Result is: ~a~%" f)
    f))

(defun fibonacci-sequence (n)
  (let ((a 1) (b 2))
    (format t "Fibonacci Sequence: ")
    (dotimes (i n)
      (format t "~a " a)
      (rotatef a b)
      (setf b (+ a b)))
    (format t "~%")))

(defun collatz (n)
  (format t "Collatz sequence: ")
  (loop while (> n 1) do
       (format t "~a " n)
       (setf n (if (evenp n)
                   (/ n 2)
                   (+ (* 3 n) 1))))
  (format t "1~%"))

(defun ask-yes (prompt)
  (format t "~a~%" prompt)
  (let ((answer (read-line)))
    (member (string-downcase answer) '("yes") :test #'string=)))

(defun read-number (prompt)
  (format t "~a~%" prompt)
  (parse-integer (read-line)))

(defun main ()
  (if (ask-yes "Do you want to solve a quadratic function? (Yes/No)")
      (let ((a (read-number "Enter a:"))
            (b (read-number "Enter b:"))
            (c (read-number "Enter c:")))
        (solve-quadratic a b c))
    (if (ask-yes "Do you want to find a factorial number? (Yes/No)")
        (factorial (read-number "Write a number:"))
      (if (ask-yes "Do you want to generate the first N Fibonacci numbers? (Yes/No)")
          (fibonacci-sequence (read-number "Write a number:"))
        (if (ask-yes "Do you want to generate Collatz Conjecture? (Yes/No)")
            (collatz (read-number "Write a number:"))
          (format t "abort~%"))))))

;; Entry point
(main)
