Download
/*
  
  Magic Hexagon in Gecode.

  Prob023: Magic Hexagon
  http://www.comp.rgu.ac.uk/staff/ha/ZCSP/prob023/prob023.pdf
  http://www.cse.unsw.edu.au/~tw/csplib/prob/prob023/

  Compare with the following models:
  * MiniZinc: http://www.hakank.org/minizinc/magic_hexagon.mzn
  * SICStus Prolog: http://www.hakank.org/sicstus/magic_hexagon.ecl
  * ECLiPSe: http://www.hakank.org/eclipse/magic_hexagon.ecl

  This Gecode model was created by Hakan Kjellerstrand (hakank@gmail.com)
  Also, see my Gecode page: http://www.hakank.org/gecode/ .

*/

#include <gecode/driver.hh>
#include <gecode/int.hh>
#include <gecode/minimodel.hh>

using namespace Gecode;

using std::cout;
using std::endl;
using std::setw;
using std::string;


class MagicHexagon : public Script {
protected:

  static const int len = 19;

  IntVarArray x;

public:

  MagicHexagon(const Options& opt) 
    : 
    x(*this, len, 1, len)
  {

    IntVar
      a(x[0]),
      b(x[1]),
      c(x[2]),
      d(x[3]),
      e(x[4]),
      f(x[5]),
      g(x[6]),
      h(x[7]),
      i(x[8]),
      j(x[9]),
      k(x[10]),
      l(x[11]),
      m(x[12]),
      n(x[13]),
      o(x[14]),
      p(x[15]),
      q(x[16]),
      r(x[17]),
      s(x[18]);
    
    distinct(*this, x, opt.icl());

    // Not very beautiful, but experimental...
    rel(*this,
        a + b + c ==  38 &&
        d + e + f + g ==  38 &&
        h + i + j + k + l ==  38 && 
        m + n + o + p ==  38 && 
        q + r + s ==  38 && 
        a + d + h ==  38 && 
        b + e + i + m ==  38 && 
        c + f + j + n + q ==  38 && 
        g + k + o + r ==  38 && 
        l + p + s ==  38 && 
        c + g + l ==  38 && 
        b + f + k + p ==  38 && 
        a + e + j + o + s ==  38 && 
        d + i + n + r ==  38 && 
        h + m + q ==  38 && 
        
        a < c &&
        a < h &&
        a < l &&
        a < q &&
        a < s &&
        c < h
        );

    // branching
    branch(*this, x, INT_VAR_SIZE_MIN(), INT_VAL_MIN());

  }

  // Print solution
  virtual void
  print(std::ostream& os) const {
    os << "x: " << x << endl;
    os << endl;

  }


  // Constructor for cloning s
  MagicHexagon(bool share, MagicHexagon& s) : Script(share,s) {
    x.update(*this, share, s.x);
  }

  // Copy during cloning
  virtual Space*
  copy(bool share) {
    return new MagicHexagon(share,*this);
  }
};


int
main(int argc, char* argv[]) {

  Options opt("MagicHexagon");

  opt.solutions(0);
  opt.icl(ICL_DOM);

  opt.parse(argc,argv);

  Script::run<MagicHexagon,DFS,Options>(opt);
    
  return 0;
}