;;; -*- lexical-binding: t -*- ;; ;; this file: ;; https://dataswamp.org/~incal/emacs-init/math.el (require 'cl-lib) (require 'dwim) ; https://dataswamp.org/~incal/emacs-init/dwim.el (require 'perm) ; https://dataswamp.org/~incal/emacs-init/perm.el ;; ---------------------------------------------------------- (require 'calc-ext) (defalias 'mean #'calcFunc-vmean) ;; (mean 1 2 3 4 5) (defun infx (str) (let* ((exp (math-read-expr str)) (fun (car exp)) (new (cons (intern (caar (cl-member fun math-expr-opers :key #'cadr :test #'equal))) (cdr exp)))) (apply (car new) (cdr new)))) ;; (infx "0 < 10") (defun nand (&rest conditions) (when (member nil conditions) t)) ;; (nand) ; nil ;; (nand 1 2 3) ; nil ;; (nand nil) ; t ;; (nand 1 2 nil 3) ; t ;; (not (and)) ; nil ;; (not (and 1 2 3)) ; nil ;; (not (and nil)) ; t ;; (not (and 1 2 nil 3)) ; t ;; ---------------------------------------------------------- (defalias '** #'expt) (defalias 'ceil #'ceiling) (defun percent-change (from to) (if (= from to) 0 (/ (- to from) (abs from) 0.01))) ;; (percent-change 1 2) ; 100 ;; (percent-change 1 1) ; 0 ;; (percent-change 1 0) ; -100 ;; (percent-change 1 -1) ; -200 ;; ;; (percent-change 0 1) ; 1.0e+INF ;; (percent-change 0 0) ; 0 ;; (percent-change 0 -1) ; -1.0e+INF ;; ;; (percent-change -1 1) ; 200 ;; (percent-change -1 0) ; 100 ;; (percent-change -1 -1) ; 0 ;; (percent-change -1 -2) ; -100 (defun distance-point (min max) (+ min (/ (- max min) 2.0)) ) ;; (distance-point 1 5) ; 3 ;; (distance-point 1 10) ; 5.5 ;; (distance-point 60 100) ; 80 (defun // (nom denom) (/ nom denom 1.0) ) ;; (/ 8 256) ; 0 ;; (// 8 256) ; 0.03125 (defun arith-sum (n) (cl-loop with sum = 0 for i from 1 to (1- n) do (cl-incf sum i) finally return sum) ) (defun digs (n) (* n (1- n)) ) (defun mean-value (vs) (let*((sum (apply #'+ vs)) (mean (/ sum (length vs) 1.0)) ) mean) ) (defun mean-str (strs) (mean-value (cl-map 'list #'length strs)) ) (defun faster (old new) (format "%.1f%%" (* 100 (1- (/ new old 1.0)))) ) ;; (faster 0.2 0.5) ; 150.0% ;; (faster 1.35 0.84) ; -37.8% ;; (faster 200 400) ; 100.0% ;; (faster 1000 1000) ; 0.0% ;; (faster 1000 100) ; -90.0% (defun percent (nom &optional denom str) (or denom (setq denom 1)) (let ((perc (/ nom denom 0.01))) (if str (format "%d%%" (floor perc)) perc) )) ;; (percent 0.25) ; 25.0 ;; (percent 50 75) ; 66.66 ... ;; (percent (// 1 2) nil t) ; 50.0% ;; (percent 1019 22 t) ; 4631.8% (let ((min-def 0) (max-def 9) (inc-def 1) ) (defun interval (&optional min max inc) (interactive `(,(read-number "min: " min-def) ,(read-number "max: " max-def) ,(read-number "inc: " inc-def)) ) (or min (setq min min-def)) (or max (setq max max-def)) (or inc (setq inc inc-def)) (unless (<= min max) (error "Bogus interval") ) (unless (> inc 0) (error "Bogus increment") ) (cl-loop for i from min to max by inc collect i) ) (declare-function interval nil) ) ;; (interval 10 5) ; Bogus interval ;; (interval 1 3 -1) ; Bogus increment ;; (interval 5 10) ; (5 6 7 8 9 10) ;; (interval 1.8 2.0 0.1) ; (1.8 1.9 2.0) ;; (interval) ; (0 1 2 3 4 5 6 7 8 9) ;; (interval 19 99) ; (19 20 21 ... 97 98 99) (defun digits-sum (&optional beg end) (interactive (use-region)) (or beg (setq beg (point-min))) (or end (setq end (point-max))) (let ((sum 0)) (goto-char beg) (while (re-search-forward " [[:digit:].]+ " end t) (cl-incf sum (string-to-number (match-string-no-properties 0))) ) (prog1 sum (message "sum: %.1f" sum) ))) (defalias 'di #'digits-sum) (defun film-mean () (interactive) (let ((scores) (beg (point-min)) (end (point-max)) ) (save-excursion (goto-char beg) (while (re-search-forward "[[:digit:]]" end t) (when (= (current-column) 73) (push (string-to-number (match-string-no-properties 0)) scores) ))) (when scores (message (format "%.3f" (mean-value scores))) ))) (defun positive-integer-p (n) (and (integerp n) (< 0 n) )) ;; (positive-integer-p 1.5) ; nil ;; (positive-integer-p 1) ; t ;; (positive-integer-p 0) ; nil ;; (positive-integer-p -1) ; nil (defun string-to-number-number (str) (let ((s (string-trim str))) (when (string-match-p "\\`[+-]?\\([[:digit:]]+\\|[[:digit:]]*\\.[[:digit:]]+\\)\\'" s) (string-to-number s) ))) (defun string-to-number-number-test () (cl-map 'list (lambda (e) (pcase-let ((`(,a ,b) e)) (if (and a b) (= a b) (eq a b) ))) (list (list (string-to-number-number " 10") 10) (list (string-to-number-number " 1.5") 1.5) (list (string-to-number-number " +0") 0) (list (string-to-number-number " 0") 0) (list (string-to-number-number " -0.0") -0.0) (list (string-to-number-number " -1.5") -1.5) (list (string-to-number-number "-10") -10) (list (string-to-number-number "123this used to work") nil) (list (string-to-number-number "NAN") nil) ))) ;; (string-to-number-number-test) (defun read-integer () (let ((str) (str-number) (n) ) (cl-loop until (progn (setq str (read-string "integer: ")) (if (string= str "0") (setq n 0) (setq str-number (string-to-number str)) (unless (= str-number 0) (setq n str-number) )) (integerp n)) ) n) ) ;; (read-integer) (defun compare (old new) (format "%.2f%%" (* 100 (/ (- old new) (* old 1.0) )))) ;; (compare 185 80) ; 56.76% (defun hypotenuse (c1 c2) (sqrt (+ (* c1 c1) (* c2 c2))) ) (defun speed (hour minute second km) (let*((s (+ second (* 60 minute) (* 60 60 hour))) (m (* 1000 km)) (mps (/ m s)) ) (* 3.6 mps) )) ;; (speed 04 44 10 42.195) ; 8.909208211143694 ;; (speed 02 01 39 42.195) ; 20.811344019728732 ;; (speed 19 04 00 168 ) ; 7.2 (defun binom (n k) (/ (cl-factorial n) (* (cl-factorial k) (cl-factorial (- n k)) ))) (defun product (l) (cl-loop with prod = 1 for i in l do (setq prod (* prod i)) finally return prod) ) ;; (product '(1 2 3 4)) ; 24 (defun tau-ceti (speed) (let*((dist (* 11.8 9.46 (expt 10 12))) (time (/ dist speed) ) (days (/ time 24)) (whole-days (round days)) ) (format-seconds "%y years" (- (float-time (encode-time 0 0 0 whole-days 0 0)) (float-time (encode-time 0 0 0 0 0 0)) )))) ;; (tau-ceti 5000) ; 2 548 584 years (provide 'math)