# HG changeset patch # User Robert McIntyre # Date 1344288159 14400 # Node ID 7698e9bdff2b33d15181fd6cc9c5e2c1ab8cb06d # Parent da4c47650d3877f2c01a4184e2216c6838a8b92d upgraded pokemon-types to clojure version 1.3 diff -r da4c47650d38 -r 7698e9bdff2b org/lpsolve.org --- a/org/lpsolve.org Sun Feb 05 11:24:40 2012 -0700 +++ b/org/lpsolve.org Mon Aug 06 17:22:39 2012 -0400 @@ -137,6 +137,7 @@ : wheat 21.875 : barley 53.125 + This shows that the farmer can maximize his profit by planting 21.875 of the available acres with wheat and the remaining 53.125 acres with barley; by doing so, he will make $6315.62(5) in profit. @@ -152,13 +153,13 @@ We are going to solve the same problem involving wheat and barley, that we did above, but this time using clojure and the =lp_solve= API. -#+srcname: intro +#+name: intro #+begin_src clojure :results silent (ns pokemon.lpsolve - (:use [clojure.contrib def set [seq :only [indexed]] pprint]) + ;;(:use [clojure.contrib def set [seq :only [indexed]] pprint]) (:import lpsolve.LpSolve) (:require pokemon.types) - (:require incanter.core trans) + (:require incanter.core) (:require rlm.map-utils)) #+end_src @@ -172,7 +173,7 @@ =LD_LIBRARY_PATH=$HOME/roBin/lpsolve:$LD_LIBRARY_PATH=. If everything is set-up correctly, -#+srcname: body +#+name: body #+begin_src clojure :results verbatim :exports both (import 'lpsolve.LpSolve) #+end_src @@ -205,7 +206,7 @@ To deal with these issues I'll create four functions for interfacing with =LpSolve= -#+srcname: declares +#+name: declares #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) @@ -226,7 +227,7 @@ call to =deleteLP=. I use a non-hygienic macro similar to =with-open= to ensure that =deleteLP= is always called. -#+srcname: memory-management +#+name: memory-management #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) (defmacro linear-program @@ -251,7 +252,7 @@ done working, so it's important to collect the important results and add return them in an immutable structure at the end. -#+srcname: get-results +#+name: get-results #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) @@ -306,7 +307,7 @@ *** Solution Status of an LpSolve Object -#+srcname: solve +#+name: solve #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) @@ -319,7 +320,7 @@ (defn integer-constants [class] (filter static-integer? (.getFields class))) -(defn-memo constant-map +(defn constant-map "Takes a class and creates a map of the static constant integer fields with their names. This helps with C wrappers where they have just defined a bunch of integer constants instead of enums." @@ -328,6 +329,8 @@ (into (sorted-map) (zipmap (map #(.get % nil) integer-fields) (map #(.getName %) integer-fields))))) + +(alter-var-root #'constant-map memoize) (defn solve "Solve an instance of LpSolve and return a string representing the @@ -351,7 +354,7 @@ [[http://lpsolve.sourceforge.net/][=lp\_solve= website]]. The following is a more or less line-by-line translation of the Java code from that example. -#+srcname: farmer-example +#+name: farmer-example #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) (defn farmer-example [] @@ -413,7 +416,7 @@ -#+srcname: lp-solve +#+name: lp-solve #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) (defn initialize-lpsolve-row-oriented @@ -462,7 +465,7 @@ Now, we can use a much more functional approach to solving the farmer's problem: -#+srcname: better-farmer +#+name: better-farmer #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) (defn better-farmer-example [] @@ -551,7 +554,7 @@ and setting the constraint vector $c$ to all ones, which means that we want to find the immortal type which uses the least amount of types. -#+srcname: pokemon-lp +#+name: pokemon-lp #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) @@ -609,10 +612,11 @@ "sets the variable names of the problem given a vector of names" [#^LpSolve lps names] (dorun - (map (fn [[index name]] - (.setColName lps (inc index) (str name))) - ;; ONE based indexing!!! - (indexed names)))) + (keep-indexed + (fn [index name] + (.setColName lps (inc index) (str name))) + ;; ONE based indexing!!! + names))) (defn poke-solve ([poke-matrix target objective-function constraint min-num-types] @@ -645,7 +649,7 @@ With this, we are finally able to get some results. ** Results -#+srcname: results +#+name: results #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) @@ -974,7 +978,7 @@ on defense type combinations. However, it is possible to make every tool attack-oriented via a simple macro. -#+srcname: attack-oriented +#+name: attack-oriented #+begin_src clojure :results silent (in-ns 'pokemon.lpsolve) diff -r da4c47650d38 -r 7698e9bdff2b org/types.org --- a/org/types.org Sun Feb 05 11:24:40 2012 -0700 +++ b/org/types.org Mon Aug 06 17:22:39 2012 -0400 @@ -132,18 +132,19 @@ table with its corresponding Pok\eacute{}mon type. -#+srcname: header +#+name: header #+begin_src clojure :results silent (ns pokemon.types (:use clojure.set) - (:use clojure.contrib.combinatorics) - (:use clojure.contrib.math) - (:use clojure.contrib.def) +;; (:use clojure.contrib.combinatorics) + (:use clojure.math.combinatorics) + (:use clojure.math.numeric-tower) +;; (:use clojure.contrib.def) (:use rlm.rlm-commands) (:require rlm.map-utils)) #+end_src -#+srcname: data +#+name: data #+begin_src clojure :results silent (in-ns 'pokemon.types) ;; record type strengths as a vector of vectors @@ -246,7 +247,7 @@ is immune to Ground (susceptibility of 0). [[http://bulbapedia.bulbagarden.net/wiki/Zapdos][Zapdos']] type, Electric/Flying, is immune to Ground because $2 \times 0 = 0$. -#+srcname: types +#+name: types #+begin_src clojure :results silent (in-ns 'pokemon.types) @@ -316,7 +317,7 @@ way of finding the best node, and to always expand the best node at every step. -#+srcname: search +#+name: search #+begin_src clojure :results silent (in-ns 'pokemon.types) @@ -336,7 +337,7 @@ ;; LOWER values of the function are preferred (compare (- val-a val-b) 0))))) -(defn-memo best-first-step [successors [visited unvisited]] +(defn best-first-step [successors [visited unvisited]] (cond (empty? unvisited) nil true (let [best-node (first unvisited) @@ -347,6 +348,7 @@ visited*)] (println best-node) [visited* unvisited*]))) +(alter-var-root #'best-first-step memoize) ;; memoize partial from core so that for example ;; (= (partial + 1) (partial + 1)) @@ -378,11 +380,12 @@ Now that we have a basic best-first-search, it's convenient to write a few pok\eacute{}mon-type specific convenience functions. -#+srcname: pokemon-search +#+name: pokemon-search #+begin_src clojure :results silent (in-ns 'pokemon.types) -(defvar type-compare (comparatize susceptance) - "compare two type combinations W.R.T. their susceptibilities") +(def type-compare + "compare two type combinations W.R.T. their susceptibilities" + (comparatize susceptance)) (defn type-successors "Return the set of types that can be made by appending a single type @@ -419,9 +422,9 @@ (partial type-successors* n) (multitypes 1))))))) -(defvar immortals - (comp (partial filter immortal?) pokemon-type-search) - "find all the immortal pokemon types ") +(def immortals + "find all the immortal pokemon types." + (comp (partial filter immortal?) pokemon-type-search)) #+end_src @@ -460,7 +463,7 @@ doing anything too crazy with lazy-sequences and late-binding, this simple macro will do the job. -#+srcname: old-school +#+name: old-school #+begin_src clojure :results silent (in-ns 'pokemon.types) @@ -553,7 +556,7 @@ Many people start out a battle with either a Normal pok\eacute{}mon or an Electric pok\eacute{}mon. Here's some justification for that choice. -#+srcname: weaknesses +#+name: weaknesses #+begin_src clojure :results silent (in-ns 'pokemon.types) (defn critical-weaknesses [type] @@ -606,7 +609,7 @@ ** The Worst Pok\eacute{}mon Types -#+srcname: weak-types +#+name: weak-types #+begin_src clojure :results silent (in-ns 'pokemon.types)