Haskell mode, 2

Euler problem 3.3

.

The goal of this blog post is to install an advanced Haskell mode, called LSP mode, for Emacs.

.

1. Open the bash terminal, use the following commands to install the three packages:

sudo apt-get install elpa-haskell-mode

sudo apt-get install elpa-yasnippet

sudo apt-get install elpa-which-key

.

2. Read and follow the exact steps of my post titled “Haskell mode“.

.

.

— Me@2022.09.20 12:49:29 PM

.

.

2022.09.21 Wednesday (c) All rights reserved by ACHK

Way

There is always a WAY.

.

(defun sum-of-squares(x y &key (a 1) (b 1))
  (+ (* a x x) (* b y y)))

(deftype candidate()
  '(simple-array boolean (*)))

(defmacro get-sieve-function(a b mod-results)
  `(lambda(x y)
     (let* ((n (sum-of-squares x y :a ,a :b ,b))
        (r (mod n 12)))
       (when (and (<= n limit)
          (not (null
            (member r ,mod-results))))
     (setf (aref candidates n)
           (not (aref candidates n)))))))

(defun get-atkin-prime-candidates-map(limit)
  (let* ((lmt (isqrt limit))
         (candidates (make-array
              (1+ limit)
              :initial-element nil))
         (stage1 (get-sieve-function 4 1 '(1 5)))
         (stage2 (get-sieve-function 3 1 '(7)))
         (stage3 (get-sieve-function 3 -1 '(11))))
    (declare (type candidate candidates))
    (declare (optimize (speed 3)))
    (loop for x from 1 to lmt do
      (loop for y from 1 to lmt do
    (progn
      (funcall stage1 x y)
      (funcall stage2 x y)
      (when (> x y)
        (funcall stage3 x y)))))
    candidates))

(defun atkin-sieve-map(candidates)
  (let ((len (length candidates)))
    (loop for i from 1 to (1- len)
      when (aref candidates i)
        do (loop for j from 1
             for n = (* j i i)
             while (< n len)
             do (setf (aref candidates n) nil))))
  (setf (aref candidates 2) T)
  (setf (aref candidates 3) T)
  candidates)

(defun eratosthene-sieve-map(limit)
  (let ((candidates
      (make-array
       (1+ limit) :initial-element T)))
    (declare (type candidate candidates))
    (declare (optimize (speed 3)))
    (progn
      (setf (aref candidates 0) nil)
      (setf (aref candidates 1) nil))
    (loop for i from 2 to limit
      when (aref candidates i)
        do (loop for j from (+ i i) to limit by i
             when (aref candidates j)
               do (setf (aref candidates j) nil)))
    candidates))

;; This is free software released
;; into the public domain.
;;
;; ykm

(defun get-primes(limit
          &key
            (generator :eratosthene))
  (let ((candidates
      (case generator
        (:atkin (atkin-sieve-map
             (get-atkin-prime-candidates-map
              limit)))
        (:eratosthene (eratosthene-sieve-map
               limit))
        (otherwise
         (error "not valid type
(:atkin :eratosthene)")))))
    (declare (type candidate candidates))
    (loop for i from 0 to (1- (length candidates))
      when (aref candidates i)
        collect i)))

(format t "soe: ~d
" (time (length (get-primes 12345678))))

(format t "soa: ~d
" (time (length (get-primes 12345678
                :generator :atkin))))

(defmacro log10 (x)
  `(/ (log ,x) (log 10)))

.

— Me@2022.09.06 03:24:36 PM

.

.

2022.09.06 Tuesday (c) All rights reserved by ACHK

It doesn’t matter

Euler problem 3.1

.

The bad news is: You cannot make people like, love, understand, validate, accept, or be nice to you.

The good news is: It doesn’t matter.

(defmacro sq (x)
  `(* ,x ,x))

(defmacro list-head (lst)
  `(car ,lst))

(defmacro list-tail (lst)
  `(cdr ,lst))

(defmacro last-item (lst)
  `(car (last ,lst)))

(defun good-reverse (lst)
  (labels ((rev (lst acc)
         (if (null lst)
         acc
         (rev
          (cdr lst)
          (cons (car lst) acc)))))
    (rev lst nil)))

(defun prime-sieve-a-list (input-lst)
  (labels ((sieve-iter (go-lst acc-list)
         (if (not go-lst) 
         acc-list        
         (if (> (sq (list-head go-lst))
            (last-item go-lst))

             (append (good-reverse acc-list)
                 go-lst)
             
             (sieve-iter
              (remove-if #'(lambda (x)
                     (=
                      (mod x (list-head go-lst))
                      0))
                 (list-tail go-lst))
              (cons (list-head go-lst)
                acc-list))))))

    (sieve-iter input-lst '())))

(defun range (max &key (min 0) (step 1))
  (loop :for n :from min :below max :by step
    collect n))

(defmacro prime-sieve (n)
  `(prime-sieve-a-list (cons 2 (range (1+ ,n)
                      :min 3
                      :step 2))))

(time (length (prime-sieve 1234567)))

;; 0.764 seconds of real time
;; 95360

(time (length (prime-sieve 12345678)))

;; 20.128 seconds of real time
;; 809227

— Me@2022-08-27 07:59:30 PM

.

.

2022.08.28 Sunday (c) All rights reserved by ACHK

Haskell mode

The goal of this blog post is to install an advanced Haskell mode, called LSP mode, for Emacs.

0. In this tutorial, you will need to go to the official website of NixOS and that of MELPA (Milkypostman’s Emacs Lisp Package Archive). Make sure that both websites are the real official ones. Any instructions from an imposter website can get your machine infected with malware.

1. Assuming your computer OS is Ubuntu 20.04 or above, go to the NixOS official website. Follow the instructions to install the Nix package manager (not the NixOS) onto your OS. Choose the “single-user installation” method.

2. On the NixOS official website, click the magnifying glass at the top right corner to reach the package search engine.

3. Search “haskell language server” and then copy its installation command.

nix-env -iA nixpkgs.haskell-language-server

4. Run the command in the bash terminal to install the Haskell Language Server.

.

5. Search “stack” on the package search engine.

6. Run its installation command

nix-env -iA nixpkgs.stack

to install the Haskell Tool Stack.

7. Search “ghc” on the package search engine.

8. Run its installation command

nix-env -iA nixpkgs.ghc

to install the Glasgow Haskell Compiler.

.

9. Reboot your computer.

This step is needed for triggering the OS to recognize the Nix package manager setup.

.

10. Go to MELPA package manager’s official website. Follow the instructions to install “Melpa”, not “Melpa Stable”.

11. Open the Emacs editor. Click "Options" and then "Manage Emacs Packages".

Install the following packages. For each of them, make sure that you have chosen the source archive as “melpa“. Versions from other sources would not work.

company Modular text completion framework
flycheck On-the-fly syntax checking
lsp-haskell Haskell support for lsp-mode
lsp-mode LSP mode
lsp-ui UI modules for lsp-mode

12. Open Emacs’ initialization file, which has the filename

.emacs

Its location should be

~/.emacs

13. Add the following code to the file.

;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'company)

(require 'flycheck)

(require 'lsp-ui) 

;;;;;;;;;;;;;;;;;;;;;;;;;;

(require 'lsp)

(add-hook 'haskell-mode-hook #'lsp)

(add-hook 'haskell-literate-mode-hook #'lsp)

(save-place-mode 1)

;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun haskell-and-go-back ()

  (interactive)
  
  (haskell-process-load-file)
  
  (windmove-up))

(global-set-key 
            (kbd "C-n") 
            'haskell-and-go-back)

;;;;;;;;;;;;;;;;;;;;;;;;;;

14. Close the Emacs program.

.

15. Create a dummy Haskell source code file named “test.hs”.

16. Use Emacs to open it.

17. You should see this message:

18. Select one of the first 3 answers. Then you can start to do the Haskell source code editing.

19. To compile your code, hold the Ctrl key and press n.

Ctrl+n

— Me@2022-08-18 05:22:02 PM

.

.

2022.08.20 Saturday (c) All rights reserved by ACHK

開心 vs 關心

Euler problem 2

.

The older I get, the less I care about what people think about me. Therefore the older I get, the happier I am.

.

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

(defun fib (n)
  (cond ((= n 0) 0)
        ((= n 1) 1)
        ((> n 1) (+ (fib (- n 2)) (fib (- n 1))))))

(time (fib 40))

;; Evaluation took:
;;   2.648 seconds of real time
;;   2.640080 seconds of total run time
;;   99.70% CPU
;;   9,002,590,370 processor cycles
;;   0 bytes consed
;; 

;; tail resursion

(defun fib-t (n)
  (labels ((fib-iter (m a b)
            (if (= m 0)
            a
            (fib-iter (- m 1) b (+ a b)))))
        (fib-iter n 0 1)))

(time (fib-t 40))

;; Evaluation took:
;;   0.000 seconds of real time
;;   0.000002 seconds of total run time
;;   100.00% CPU
;;   2,184 processor cycles
;;   0 bytes consed
;;
  
;; infinite list

(defmacro append-last (lst obj)
  `(append ,lst (list ,obj)))

(defun fib-i (n)
  (labels ((fib-iter (m fib-list a b)
            (if (> m (- n 2))
            fib-list
            (fib-iter (1+ m)
                (append-last fib-list (+ a b))
                b
                (+ a b)))))
    (fib-iter 0 '(0 1) 0 1)))

(time (fib-i 40))

;; Evaluation took:
;;   0.000 seconds of real time
;;   0.000008 seconds of total run time 
;;   100.00% CPU
;;   21,960 processor cycles
;;   32,768 bytes consed


(defun filter (fn lst)
  (let ((acc nil))
    (dolist (x lst)
      (let ((val (funcall fn x)))
    (if val (push val acc))))
    (nreverse acc)))

(defmacro filter-list (fn lst)
  `(filter #'(lambda (x)
                (if (funcall ,fn x) x))
            ,lst))

(defmacro filter-2 (fn1 fn2 lst)
  `(filter-list #'(lambda (x)
                    (if (and
                    (funcall ,fn1 x)
                    (funcall ,fn2 x))
                    x))
                ,lst))

(reduce #'+ (filter-2 #'evenp
              #'(lambda (x) (< x 4000000))
              (fib-i 100)))

; 4613732

— Me@2022-08-07 12:34:19 PM

.

.

2022.08.09 Tuesday (c) All rights reserved by ACHK

Mega Man Zero 3

Euler problem 1

.

(proclaim '(optimize speed))

(reduce #'+ '(1 2 3 4))

; 10

(loop :for n :below 10 :collect n)

; (0 1 2 3 4 5 6 7 8 9)

(describe :below)

(defun range (max &key (min 0) (step 1))
   (loop :for n :from min :below max :by step
      collect n))
      
(- (+ (* 3 (reduce #'+ (range 334 :min 1 :step 1)))
      (* 5 (reduce #'+ (range 200 :min 1 :step 1))))
   (* 15 (reduce #'+ (range 67 :min 1 :step 1))))
   
; 233168

(defun sum-1-n (n)
  (/ (* n (+ n 1)) 2))
  
(- (+ (* 3 (sum-1-n 333))
      (* 5 (sum-1-n 199)))
   (* 15 (sum-1-n 66)))
   
; 233168

— Me@2022-08-01 03:29:01 PM

.

.

2022.08.01 Monday (c) All rights reserved by ACHK

Org-babel-clojure

SICMUtils, 2

.

The goal of this post to setup the Emacs editor for Clojure programming.

.

1. Read and follow the exact steps of the last post.

.

2. Open the .emacs file. Go to the end of the file. Add the following code:

(require 'org)
(require 'ob-clojure)

(setq org-babel-clojure-backend 'cider)
(require 'cider)

(set-register ?c '(file . "~/my-stuff/my-stuff.org"))

(setq org-confirm-babel-evaluate nil)

(setq org-src-tab-acts-natively t)

3. Close Emacs.

.

4. Go to the directory “~/my-stuff/” and then create a file named “my-stuff.org“.

5. Use Emacs to open the file.

6. Within the file, add the following code:

#+BEGIN_SRC emacs-lisp

  (+ 1 1)

#+END_SRC

7. Place the text cursor in the code block (between the line #+BEGIN_SRC and the line #+END_SRC).

8. Hit the Emacs command

C-c C-c

9. You will get the evaluation result:

#+RESULTS:
: 2

.

10. Hit the Emacs command:

M-x cider-jack-in

11. Within the file “my-stuff.org“, add the code:

#+BEGIN_SRC clojure :results value		  

  (require '[sicmutils.env :as env])

#+END_SRC

12. Place the text cursor in the code block.

13. Hit the Emacs command

C-c C-c

.

14. Add the code:

#+BEGIN_SRC clojure :results value		  

  (env/bootstrap-repl!) 

#+END_SRC

15. Place the text cursor in the code block and then hit the Emacs command

C-c C-c

.

16. Add the code:


#+BEGIN_SRC clojure :results replace drawer
 
(->TeX (simplify ((D cube) 'x)))
 
#+END_SRC

17. Place the text cursor and then hit

C-c C-c

It will give you the \LaTeX code

#+RESULTS:
:RESULTS:
"3\\,{x}^{2}"
:END:

— Me@2022-07-27 11:34:28 PM

.

.

2022.07.28 Thursday (c) All rights reserved by ACHK

Common Lisp Reloaded

; sudo apt-get install sbcl

; sudo apt-get install slime

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(setq inferior-lisp-program "sbcl")

(defun load-slime-with-correct-buffer-position ()

  (save-excursion (slime))
     
 
  (delete-other-windows) 
) 

(defun prelude-start-slime ()
  (unless (slime-connected-p)
    (load-slime-with-correct-buffer-position)))

(add-hook 'slime-mode-hook 'prelude-start-slime)

(set-register ?f '(file . "/path_to/lisp_file.lisp"))

— Me@2022-07-23 05:20:32 PM

.

.

2022.07.23 Saturday (c) All rights reserved by ACHK

C-h ?


C-h w command-name

C-h k key-sequence

C-h f function-name

— Me@2022-06-18 12:52:10 PM

.

.

2022.06.19 Sunday (c) All rights reserved by ACHK

3Blue1Brown

(defun 3b1b ()

    (interactive)

    (setq is-python-mode (string= major-mode "python-mode"))

    (if (not is-python-mode)
        (print "This is not a python file.")


        (print buffer-file-name)

        (setq the-command (format "%s %s %s" 
                                "manim -p"
                                buffer-file-name  
                                "JustAShape")) 

        (print the-command)                        

        (shell-command the-command) 
    )  
)

(global-set-key (kbd "C-p") '3b1b)

(global-set-key (kbd "C-/") 'comment-region)

(global-set-key (kbd "C-.") 'uncomment-region)

— Me@2022-06-05 04:00:37 PM

.

.

2022.06.05 Sunday (c) All rights reserved by ACHK