language: Common Lisp (clisp) (clisp 2.47)
date: 121 days 7 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
(defun generate-products (n product m k a b c d &optional (accum nil))
  (if (= n 0)
      accum
      (generate-products
       (- n 1)
       (list (+ (mod (+ (* a (first product)) B) M) 1)
             (+ (mod (+ (* c (second product)) D) K) 1))
       m k a b c d
       (cons product accum))))
 
(defun all-x-such-that (lst func)
  (remove-if-not func lst))
(defun there-exists (lst func)
  (> (length (remove-if-not func lst)) 0))
(defun there-does-not-exist (lst func)
  (not (there-exists lst func)))
 
(defun preferred-over (A B)
  "A is cheaper or equal in price to B, A weighs less or the same as B, and A =/= B"
  (and (<= (first A) (first B))
       (<= (second A) (second B))
       (not (equalp A B))))
 
(defun count-bargains+deals (line-stream)
  ;;Generate all of the products.
  (let ((products (apply #'generate-products 
                         (append 
                          (list (read line-stream));;N
                          (list (list (read line-stream) (read line-stream)));;Product
                          (loop for i from 1 to 6 do T collect (read line-stream))))));;Other
    ;;Good deal:
    ;;All X from products such that there does not exist a Y such that Y is preferred over X.
    ;;Terrible deal:
    ;;All X from products such that there does not exist a Y such that X is preferred over Y.
    (list (length (all-x-such-that
                   products
                   (lambda (x)
                     (there-does-not-exist
                      products
                      (lambda (product)
                        (preferred-over x product))))))
          (length (all-x-such-that 
                   products 
                   (lambda (x) 
                     (there-does-not-exist 
                      products
                      (lambda (product)
                        (preferred-over product x)))))))))
 
(defun foreach-line/stream (file-stream func &optional (n 0))
  "Foreach line, (func string-stream-for-line line-number).
   Line numbers are zero-indexed"
  (let ((line (read-line file-stream nil)))
    (if line 
        (progn
          (with-input-from-string (sstr line)
            (funcall func sstr n))
          (foreach-line/stream file-stream func (+ n 1)))
        nil)))
 
(defun main ()
  (with-open-file (stream "hackercup-3-input.txt" :direction :input :if-does-not-exist nil)
    (if (null stream)
        (error "could not open file")
        (progn
          (read-line stream);;Discard the first line
          (foreach-line/stream
           stream
           (lambda (line-stream n)
             (let ((result (count-bargains+deals line-stream)))
               (format T "Case #~A: ~A ~A~%" n (first result) (second result)))))))))