Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,70 @@
(require 'struct)
(require 'hash)
(require 'sql)
(define H null) ;; cache
(define T (make-table (struct goodies (name valeur poids volume ))))
(define-syntax-rule (name i) (table-xref T i 0))
(define-syntax-rule (valeur i) (table-xref T i 1))
(define-syntax-rule (poids i) (table-xref T i 2))
(define-syntax-rule (volume i) (table-xref T i 3))
(define goodies
'(("🍁-panacea" 3000 300 25)
("🌵-ichor" 1800 200 15)
("⭐️-gold" 2500 2000 2)))
(list->table goodies T)
;; i = item index, p= remaining weight, v = remaining volume
;; make an unique hash-key from (i p v)
(define (t-key i p v) (string-append i "|" p "|" v))
;; retrieve best core for item i
;; returns ( score . quantity)
(define (t-get i p v)
(if ( < i 0) (cons 0 0)
(hash-ref H (t-key i p v )))) ;; may be #f
;; compute best quantity.score (i), assuming best (i-1 p v) is known
(define (score-qty i p v (q) (score)(smax)(qmax))
(or
(t-get i p v) ;; already known
(begin
(set! q (min (quotient p (poids i)) (quotient v (volume i)))) ;; max possible q
(set! smax -Infinity)
( for ((k (1+ q))) ;; try all legal quantities
(set! score (+
(first (score-qty (1- i) (- p (* k (poids i))) (- v (* k (volume i)))))
(* k (valeur i))))
#:continue (< score smax)
(set! smax score)
(set! qmax k))
(hash-set H (t-key i p v) (cons smax qmax)))))
;; compute best scores, starting from last item
(define (task P V)
(define N (1- (table-count T)))
(define qty 0)
(set! H (make-hash))
(writeln 'total-value (first (score-qty N P V)))
(for/list ((i (in-range N -1 -1)))
(set! qty (rest (t-get i P V)))
#:continue (= qty 0)
(begin0
(cons (name i) (t-get i P V))
(set! P (- P (* (poids i) qty)))
(set! V (- V (* (volume i) qty))))))
;; output
(task 25000 250)
total-value 54500
→ (("⭐️-gold" 54500 . 11) ("🌵-ichor" 27000 . 15))
(length (hash-keys H)) ;; # entries in cache
→ 218

View file

@ -0,0 +1,65 @@
struct KnapsackItem {
Number volume,
Number weight,
Number value,
String name,
}
var items = [
KnapsackItem(25, 3, 3000, "panacea")
KnapsackItem(15, 2, 1800, "ichor" )
KnapsackItem( 2, 20, 2500, "gold" )
]
var (
max_weight = 250,
max_vol = 250,
vsc = 1000,
wsc = 10
)
func solve(i, w, v) is cached {
return [0, []] if i.is_neg;
var x = solve(i.dec, w, v);
var (w1, v1);
Inf.times { |t|
var item = items[i];
break if ((w1 = (w - t*item.weight)).is_neg)
break if ((v1 = (v - t*item.volume)).is_neg)
var y = solve(i.dec, w1, v1);
if ((var tmp = (y[0] + t*item.value)) > x[0]) {
x = [tmp, [y[1]..., [i, t]]];
}
}
return x
}
var x = solve(items.end, max_weight, max_vol)
print <<"EOT"
Max value #{x[0]}, with:
Item Qty Weight Vol Value
#{"-" * 50}
EOT
var (wtot=0, vtot=0);
x[1].each { |s|
var item = items[s[0]];
" #{item.name}:\t% 3d % 8d% 8g% 8d\n".printf(
s[1],
item.weight * s[1] / wsc,
item.volume * s[1] / vsc,
item.value * s[1]
);
wtot += (item.weight * s[1]);
vtot += (item.volume * s[1]);
}
print <<"EOT"
#{"-" * 50}
Total:\t #{"%8d%8g%8d" % (wtot/wsc, vtot/vsc, x[0])}
EOT