37 lines
1.3 KiB
Common Lisp
37 lines
1.3 KiB
Common Lisp
;;;; Approach: The exponents are reasonably similar, so when
|
|
;;;; necessary, see if the smaller base with larger exponent's extra
|
|
;;;; terms would exceed the ratio terms. Avoid large calculations by
|
|
;;;; normalizing to a single extra term.
|
|
|
|
(defun smallerp (sb se bb be)
|
|
"Given (< SB BB) and (> SE BE) ('S' meaning smaller base, 'B' meaning bigger), returns non-NIL if (< (EXPT SB SE) (EXPT BB BE))"
|
|
(let ((ratio (/ sb bb)))
|
|
(< sb
|
|
(expt ratio (/ be (- be se))))))
|
|
|
|
(defun exp< (n1 n2)
|
|
"Returns non-NIL if (< (APPLY #'EXPT N1) (APPLY #'EXPT N2)), assuming exponents are very large and erasonably similar"
|
|
(destructuring-bind (b1 e1) n1
|
|
(destructuring-bind (b2 e2) n2
|
|
(cond
|
|
;; Trivial cases
|
|
((and (< b1 b2) (< e1 e2)) t)
|
|
((and (>= b1 b2) (>= e1 e2)) nil)
|
|
;; Cases requiring actual calculation
|
|
((< b1 b2) (smallerp b1 e1 b2 e2))
|
|
(t (not (smallerp b2 e2 b1 e1)))))))
|
|
|
|
(defun largest-exponential (&optional lines)
|
|
(loop with biggest = nil
|
|
with biggest-line = nil
|
|
for line in (uiop:read-file-lines "0099_base_exp.txt")
|
|
for exponential = (mapcar #'parse-integer (uiop:split-string line :separator '(#\,)))
|
|
for i upfrom 0
|
|
while (or (not lines)
|
|
(< i lines))
|
|
do (when (or (not biggest)
|
|
(exp< biggest exponential))
|
|
(setf biggest-line (1+ i))
|
|
(setf biggest exponential))
|
|
finally (return biggest-line)))
|