packages feed

egison-3.5.0: sample/salesman.egi

;;;
;;; Travelling Salesman Problem
;;;

(define $station string)
(define $price   integer)
(define $graph   (multiset [station (multiset [station price])]))

(define $graph-data
  {
   ["Tokyo"     {              ["Shinjuku" 200] ["Shibuya" 200] ["Mitaka" 390] ["Kinshicho" 160] ["Kitasenju" 220]}]
   ["Shinjuku"  {["Tokyo" 200]                  ["Shibuya" 160] ["Mitaka" 220] ["Kinshicho" 220] ["Kitasenju" 310]}]
   ["Shibuya"   {["Tokyo" 200] ["Shinjuku" 160]                 ["Mitaka" 310] ["Kinshicho" 220] ["Kitasenju" 310]}]
   ["Mitaka"    {["Tokyo" 390] ["Shinjuku" 220] ["Shibuya" 310]                ["Kinshicho" 470] ["Kitasenju" 550]}]
   ["Kinshicho" {["Tokyo" 160] ["Shinjuku" 220] ["Shibuya" 220] ["Mitaka" 470]                   ["Kitasenju" 220]}]
   ["Kitasenju" {["Tokyo" 220] ["Shinjuku" 310] ["Shibuya" 310] ["Mitaka" 550] ["Kinshicho" 220]                  }]
   })

(define $trips ; List up all routes that visit each city exactly once and return to Tokyo
  (match-all graph-data graph
    [<cons [,"Tokyo" <cons [$s_1 $p_1] _>]
           (loop $i [2 5]
             <cons [,s_(- i 1) <cons [$s_i $p_i] _>]
                   ...>
             <cons [,s_5 <cons [(& ,"Tokyo" $s_6) $p_6] _>]
                   _>)>
     [(sum (map (lambda [$i] p_i) (between 1 6)))
      s]]))

(define $main
  (lambda [$args]
    (do {[(print "Route list:")]
         [(each (compose show print) trips)]
         [(write "Lowest price:")]
         [(print (show (min (map (lambda [$x $y] x) trips))))]})))