Skip to content

Instantly share code, notes, and snippets.

@saska-gist
Created November 24, 2018 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saska-gist/336ba51ecb3cca2f4cc20aa3bab2181a to your computer and use it in GitHub Desktop.
Save saska-gist/336ba51ecb3cca2f4cc20aa3bab2181a to your computer and use it in GitHub Desktop.
# A scip model for solving the puzzle at
# https://www.puzzleprime.com/brain-teasers/deduction/the-dark-bridge/
param ncrossings := 25;
set friends := { 1..4 };
set ntimes := { 1,2,7,10 }; # time needed to cross the bridge
set xings := { 1..ncrossings }; # bridge crossings
var x[xings * friends] binary; # which friends cross the bridge every time
var A[xings * friends] binary; # which friends are on side A every time
var B[xings * friends] binary; # which friends are on side B every time
# a person is either on side A or B
subto ab: forall <c,f> in xings*friends do A[c,f]==(1-B[c,f]);
# in the beginning everyone is on side A
subto a1: A[1,1]==1; subto a2: A[1,2]==1;
subto a3: A[1,3]==1; subto a4: A[1,4]==1;
# at the end everyone must be on side B
subto b1: B[ncrossings,1]==1; subto b2: B[ncrossings,2]==1;
subto b3: B[ncrossings,3]==1; subto b4: B[ncrossings,4]==1;
# only 1 or 2 people can cross the bridge at the same time
subto x1: forall <c> in xings do sum <f> in friends: x[c, f] <= 2;
# if not everyone is on side B, someone must cross the bridge
subto x2: forall <c> in xings do vif A[c,1]+A[c,2]+A[c,3]+A[c,4]>=1
then sum <f> in friends: x[c, f] >= 1 end;
# as soon as everyone is on side B, no more bridge crossings
subto x3: forall <c> in xings do vif A[c,1]+A[c,2]+A[c,3]+A[c,4]==0
then sum <f> in friends: x[c, f] == 0 end;
#
# continuity
#
# from A to B
subto c1: forall <c,f> in xings*friends with c<ncrossings and (c mod 2)==1
do x[c,f] <= A[c,f];
subto c2: forall <c,f> in xings*friends with c<ncrossings and (c mod 2)==1
do B[c+1,f] == B[c,f] + x[c,f] ;
# from B to A
subto c3: forall <c,f> in xings*friends with c<ncrossings and (c mod 2)==0
do x[c,f] <= B[c,f];
subto c4: forall <c,f> in xings*friends with c<ncrossings and (c mod 2)==0
do A[c+1,f] == A[c,f] + x[c,f];
# how much time each crossing takes
var time[xings] integer >=0 <=max(ntimes);
# crossing the bridge takes the time needed
# for the slowest of the group to cross it
subto t1: forall <c> in xings do
vif x[c,4]==1 then time[c]==10 end;
subto t2: forall <c> in xings do
vif x[c,3]==1 and x[c,4]==0 then time[c]==7 end;
subto t3: forall <c> in xings do
vif x[c,2]==1 and x[c,3]+x[c,4]==0 then time[c]==2 end;
subto t4: forall <c> in xings do
vif x[c,1]==1 and x[c,2]+x[c,3]+x[c,4]==0 then time[c]==1 end;
subto t5: forall <c> in xings do
vif x[c,1]+x[c,2]+x[c,3]+x[c,4]==0 then time[c]==0 end;
var total_time integer;
minimize cost: total_time;
subto tt: sum <t> in xings: time[t] == total_time;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment