commit 3cf69722be344e12df639be467a53ccc6d09ca07
parent e46f8f24becd61686a7f6d339e93c986aacb6b1e
Author: dwrz <dwrz@dwrz.net>
Date: Wed, 26 Jun 2019 21:18:56 +0000
Refactor elisp/grains
Diffstat:
1 file changed, 28 insertions(+), 82 deletions(-)
diff --git a/elisp/grains/grains.el b/elisp/grains/grains.el
@@ -5,7 +5,7 @@
;;; simpler: simply shift an unsigned long long to get the number of
;;; grains at square n.
;;;
-;;; In Emacs, that approach doesn't seem to work. Only 30 bits are used
+;;; In Emacs, that approach doesn't seem to work. Only 61 bits are used
;;; for integers, resulting in overflows above square 60.
;;;
;;; The solution, if one wants to calculate it, seems to be to rely on
@@ -15,15 +15,14 @@
;;; However, it also occurred to me that the values here are known,
;;; limited, and not likely to change anytime soon. By using contants,
;;; we can get constant time determination of the number of grains for
-;;; a square. The functions used by the tests, square and total, simply
-;;; return constant values, with the number of grains for a square
-;;; relying on a vector that matches the n-th index to the corresponding
-;;; grains.
+;;; a square. The functions used by the tests, square and total, return
+;;; these constant values.
;;;
;;; Emacs itself was useful in effectuating this solution. I used a
;;; macro to evaluate calculate-square for n, and then insert the
;;; results in this buffer. There's probably a more elegant way to do
-;;; this in Emacs, but this approach was adequate for the task.
+;;; this, but the approach was adequate for this task.
+;;;
;;; Sometimes, making the programmer's life easier can lead to more
;;; efficient code.
@@ -31,82 +30,18 @@
(require 'calc)
-(defun calculate-square(n)
- "Return the number of grains at square N. Use left shifts when n is equal to or below 60, and calc for numbers up to 65."
- (cond ((< n 0) 0)
- ((> n 65) 0)
- ((<= n 60) (lsh 1 (- n 1)))
- (t (string-to-number (calc-eval (format "2^%d" (1- n)))))))
-
-(defun calculate-total()
- "Return the total number of grains on a chessboard with 64 squares."
- (1- (square 65)))
-
-(defvar grains [0
- 1
- 2
- 4
- 8
- 16
- 32
- 64
- 128
- 256
- 512
- 1024
- 2048
- 4096
- 8192
- 16384
- 32768
- 65536
- 131072
- 262144
- 524288
- 1048576
- 2097152
- 4194304
- 8388608
- 16777216
- 33554432
- 67108864
- 134217728
- 268435456
- 536870912
- 1073741824
- 2147483648
- 4294967296
- 8589934592
- 17179869184
- 34359738368
- 68719476736
- 137438953472
- 274877906944
- 549755813888
- 1099511627776
- 2199023255552
- 4398046511104
- 8796093022208
- 17592186044416
- 35184372088832
- 70368744177664
- 140737488355328
- 281474976710656
- 562949953421312
- 1125899906842624
- 2251799813685248
- 4503599627370496
- 9007199254740992
- 18014398509481984
- 36028797018963968
- 72057594037927936
- 144115188075855872
- 288230376151711744
- 576460752303423488
- 1152921504606846976
- 2305843009213693952
- 4611686018427387904
- 9223372036854775808]
+(defvar grains
+ [0 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536 131072
+ 262144 524288 1048576 2097152 4194304 8388608 16777216 33554432 67108864
+ 134217728 268435456 536870912 1073741824 2147483648 4294967296 8589934592
+ 17179869184 34359738368 68719476736 137438953472 274877906944 549755813888
+ 1099511627776 2199023255552 4398046511104 8796093022208 17592186044416
+ 35184372088832 70368744177664 140737488355328 281474976710656
+ 562949953421312 1125899906842624 2251799813685248 4503599627370496
+ 9007199254740992 18014398509481984 36028797018963968 72057594037927936
+ 144115188075855872 288230376151711744 576460752303423488
+ 1152921504606846976 2305843009213693952 4611686018427387904
+ 9223372036854775808]
"Vector containing the number of grains for a square with the corresponding index.")
(defun square(n)
@@ -119,5 +54,16 @@
"Return the total number of grains on a chessboard with 64 squares."
18446744073709551616)
+(defun calculate-square(n) ;; Not used, for reference only.
+ "Return the number of grains at square N. Use left shifts when n is equal to or below 60, and calc for numbers up to 65."
+ (cond ((< n 0) 0)
+ ((> n 65) 0)
+ ((<= n 60) (lsh 1 (- n 1)))
+ (t (string-to-number (calc-eval (format "2^%d" (1- n)))))))
+
+(defun calculate-total() ;; Not used, for reference only.
+ "Return the total number of grains on a chessboard with 64 squares."
+ (1- (square 65)))
+
(provide 'grains)
;;; grains.el ends here