Skip to content
Snippets Groups Projects
Commit 7ce00f0b authored by penguinn's avatar penguinn
Browse files

start nine prisoners

parent 40aa6024
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Nine Prisoners
An artice in [Quanta magazine](https://www.quantamagazine.org/150-year-old-math-design-problem-solved-20150609) mentions the following puzzle by Dudeney and popularized by Martin Gardner:
*"So in the spirit of Kirkman, we will leave the gentle reader with another brainteaser, a slight variation on the schoolgirl puzzle devised in 1917 by the British puzzle aficionado Henry Ernest Dudeney and later popularized by Martin Gardner: Nine prisoners are taken outdoors for exercise in rows of three, with each adjacent pair of prisoners linked by handcuffs, on each of the six weekdays (back in Dudeney’s less enlightened times, Saturday was still a weekday). Can the prisoners be arranged over the course of the six days so that each pair of prisoners shares handcuffs exactly once?"*
An encoding of this puzzle in B is relatively straightforward, thanks to the use of sets, sequences and permutations and universal quantification. To improve the performance, symmetry reductions were added by hand in the model below. The constant `arrange` contains the solution to our puzzle: the arrangement of the prisoners for every working day from `1` to `Days`.
In this notebook we will create two visualizations. The first one will be a quite simple table and is defined in the `ANIMATION_FUNCTION` in the machine below.
To investigate the machine, we have to set up its constants and initialize it, with the two commands below the machine.
%% Cell type:code id: tags:
``` prob
::load
MACHINE NinePrisoners
DEFINITIONS
Prisoners == 1..9;
Days == 6;
Cuffs == {1,2, 4,5, 7,8 };
share(day,cuff) == {arrange(day)(cuff),arrange(day)(cuff+1)};
/*The animation function for a simple visualisation*/
ANIMATION_FUNCTION ==
{r,c,i| r:1..Days & c:1..3 & i = arrange(r)(c) } \/
{r,c,i| r:1..Days & c:5..7 & i = arrange(r)(c-1) } \/
{r,c,i| r:1..Days & c:9..11 & i = arrange(r)(c-2) };
ANIMATION_FUNCTION_DEFAULT == {r,c,i| r:1..Days & c:1..11 & i = " " }
CONSTANTS arrange
PROPERTIES
/* typing + permutation requirement */
arrange : (1..Days) --> perm(Prisoners) &
/* symmetry breaking */
arrange(1) = %i.(i:Prisoners|i) &
!d.(d:1..Days =>
!c.(c:Prisoners & c mod 3 = 1 => arrange(d)(c) < arrange(d)(c+2))) &
!d.(d:1..Days =>
!c.(c:{1,3} => arrange(d)(c) < arrange(d)(c+3)))
&
/* the constraint proper */
!(c,d).(c:Cuffs & d:2..Days =>
!(c1,d1).(d1<d & d1>0 & c1:Cuffs =>
share(d,c) /= share(d1,c1))
)
OPERATIONS
r <-- Neighbours(i) = PRE i:Prisoners THEN
/* compute for every day the neighbours of i */
r := %d.(d:1..Days |
UNION(x,c).( x:Prisoners & c:Cuffs & i: share(d,c)| share(d,c) \ {i})
) END
END
```
%% Output
Loaded machine: NinePrisoners
%% Cell type:code id: tags:
``` prob
:constants
```
%% Cell type:code id: tags:
``` prob
:init
```
%% Output
Machine initialised using operation 0: $initialise_machine()
%% Cell type:code id: tags:
``` prob
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment