Solve the no connection puzzle: Difference between revisions

Add C# implementation
(Scala contribution added.)
(Add C# implementation)
 
(38 intermediate revisions by 16 users not shown)
Line 7:
/ │ X │ \
/ │/ \│ \
'''C'''───'''D'''───'''E'''───'''F'''
\ │\ /│ /
\ │ X │ /
Line 27:
/ │ X │ \
/ │/ \│ \
'''8'''───'''1'''───'''6'''───'''2'''
\ │\ /│ /
\ │ X │ /
Line 56:
[https://www.youtube.com/watch?v=AECElyEyZBQ No Connection Puzzle] (youtube).
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V connections = [(0, 2), (0, 3), (0, 4),
(1, 3), (1, 4), (1, 5),
(6, 2), (6, 3), (6, 4),
(7, 3), (7, 4), (7, 5),
(2, 3), (3, 4), (4, 5)]
 
F ok(conn, perm)
R abs(perm[conn[0]] - perm[conn[1]]) != 1
 
F solve()
[[Int]] r
V perm = Array(1..8)
L
I all(:connections.map(conn -> ok(conn, @perm)))
r [+]= copy(perm)
I !perm.next_permutation()
L.break
R r
 
V solutions = solve()
print(‘A, B, C, D, E, F, G, H = ’solutions[0].join(‘, ’))</syntaxhighlight>
 
{{out}}
<pre>
A, B, C, D, E, F, G, H = 3, 4, 7, 1, 8, 2, 5, 6
</pre>
 
=={{header|Ada}}==
This solution is a bit longer than it actually needs to be; however, it uses tasks to find the solution and the used types and solution-generating functions are well-separated, making it more amenable to other solutions or altering it to display all solutions.
<syntaxhighlight lang="ada">
<lang Ada>
With
Ada.Text_IO,
Line 68 ⟶ 99:
begin
Ada.Text_IO.Put_Line( Connection_Types.Image(Result) );
end;</langsyntaxhighlight>
<langsyntaxhighlight Adalang="ada">Pragma Ada_2012;
 
Package Connection_Types with Pure is
Line 115 ⟶ 146:
Function Image ( Input : Partial_Board ) Return String;
 
End Connection_Types;</langsyntaxhighlight>
<syntaxhighlight lang="ada">
<lang Ada>
Pragma Ada_2012;
 
Line 123 ⟶ 154:
 
Function Connection_Combinations return Partial_Board;
</syntaxhighlight>
</lang>
<langsyntaxhighlight Adalang="ada">Pragma Ada_2012;
 
Package Body Connection_Types is
Line 196 ⟶ 227:
end Image;
 
End Connection_Types;</langsyntaxhighlight>
<langsyntaxhighlight Adalang="ada">Function Connection_Combinations return Partial_Board is
 
begin
Line 270 ⟶ 301:
End return;
End Connection_Combinations;
</syntaxhighlight>
</lang>
{{out}}
<pre> 4 5
Line 287 ⟶ 318:
{{works with|Dyalog APL 17.0 Unicode}}
 
<syntaxhighlight lang="apl">
<lang APL>
 
 
Line 305 ⟶ 336:
tries[''⍴solns;]
}
</langsyntaxhighlight>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
 
/* ARM assembly Raspberry PI */
Line 847 ⟶ 879:
iMagicNumber: .int 0xCCCCCCCD
 
</syntaxhighlight>
</lang>
<pre>
a=3 b=4 c=7 d=1
Line 863 ⟶ 895:
 
</pre>
 
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">oGrid := [[ "", "X", "X"] ; setup oGrid
,[ "X", "X", "X", "X"]
,[ "", "X", "X"]]
Line 938 ⟶ 969:
list .= oGrid[row, col+1] ? row ":" col+1 "," : oGrid[row, col-1] ? row ":" col-1 "," : ""
return Trim(list, ",")
}</langsyntaxhighlight>
Outputs:<pre>
3 5
Line 949 ⟶ 980:
\|/ \|/
4 6</pre>
 
=={{header|C}}==
{{trans|Go}}
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stdio.h>
#include <math.h>
 
int connections[15][2] = {
{0, 2}, {0, 3}, {0, 4}, // A to C,D,E
{1, 3}, {1, 4}, {1, 5}, // B to D,E,F
{6, 2}, {6, 3}, {6, 4}, // G to C,D,E
{7, 3}, {7, 4}, {7, 5}, // H to D,E,F
{2, 3}, {3, 4}, {4, 5}, // C-D, D-E, E-F
};
 
int pegs[8];
int num = 0;
 
bool valid() {
int i;
for (i = 0; i < 15; i++) {
if (abs(pegs[connections[i][0]] - pegs[connections[i][1]]) == 1) {
return false;
}
}
return true;
}
 
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
 
void printSolution() {
printf("----- %d -----\n", num++);
printf(" %d %d\n", /* */ pegs[0], pegs[1]);
printf("%d %d %d %d\n", pegs[2], pegs[3], pegs[4], pegs[5]);
printf(" %d %d\n", /* */ pegs[6], pegs[7]);
printf("\n");
}
 
void solution(int le, int ri) {
if (le == ri) {
if (valid()) {
printSolution();
}
} else {
int i;
for (i = le; i <= ri; i++) {
swap(pegs + le, pegs + i);
solution(le + 1, ri);
swap(pegs + le, pegs + i);
}
}
}
 
int main() {
int i;
for (i = 0; i < 8; i++) {
pegs[i] = i + 1;
}
 
solution(0, 8 - 1);
return 0;
}</syntaxhighlight>
{{out}}
<pre>----- 0 -----
3 4
7 1 8 2
5 6
 
----- 1 -----
3 5
7 1 8 2
4 6
 
----- 2 -----
3 6
7 1 8 2
4 5
 
----- 3 -----
3 6
7 1 8 2
5 4
 
----- 4 -----
4 3
2 8 1 7
6 5
 
----- 5 -----
4 5
2 8 1 7
6 3
 
----- 6 -----
4 5
7 1 8 2
3 6
 
----- 7 -----
4 6
7 1 8 2
3 5
 
----- 8 -----
5 3
2 8 1 7
6 4
 
----- 9 -----
5 4
2 8 1 7
6 3
 
----- 10 -----
5 4
7 1 8 2
3 6
 
----- 11 -----
5 6
7 1 8 2
3 4
 
----- 12 -----
6 3
2 8 1 7
5 4
 
----- 13 -----
6 3
2 8 1 7
4 5
 
----- 14 -----
6 4
2 8 1 7
5 3
 
----- 15 -----
6 5
2 8 1 7
4 3</pre>
 
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
using System.Collections.Generic;
using System.Linq;
 
public class NoConnection
{
// adopted from Go
static int[][] links = new int[][] {
new int[] {2, 3, 4}, // A to C,D,E
new int[] {3, 4, 5}, // B to D,E,F
new int[] {2, 4}, // D to C, E
new int[] {5}, // E to F
new int[] {2, 3, 4}, // G to C,D,E
new int[] {3, 4, 5}, // H to D,E,F
};
 
static int[] pegs = new int[8];
 
public static void Main(string[] args)
{
List<int> vals = Enumerable.Range(1, 8).ToList();
Random rng = new Random();
 
do
{
vals = vals.OrderBy(a => rng.Next()).ToList();
for (int i = 0; i < pegs.Length; i++)
pegs[i] = vals[i];
 
} while (!Solved());
 
PrintResult();
}
 
static bool Solved()
{
for (int i = 0; i < links.Length; i++)
foreach (int peg in links[i])
if (Math.Abs(pegs[i] - peg) == 1)
return false;
return true;
}
 
static void PrintResult()
{
Console.WriteLine($" {pegs[0]} {pegs[1]}");
Console.WriteLine($"{pegs[2]} {pegs[3]} {pegs[4]} {pegs[5]}");
Console.WriteLine($" {pegs[6]} {pegs[7]}");
}
}
</syntaxhighlight>
{{out}}
<pre>
6 1
4 3 8 7
2 5
 
</pre>
 
=={{header|C++}}==
{{trans|C}}
<syntaxhighlight lang="cpp">#include <array>
#include <iostream>
#include <vector>
 
std::vector<std::pair<int, int>> connections = {
{0, 2}, {0, 3}, {0, 4}, // A to C,D,E
{1, 3}, {1, 4}, {1, 5}, // B to D,E,F
{6, 2}, {6, 3}, {6, 4}, // G to C,D,E
{7, 3}, {7, 4}, {7, 5}, // H to D,E,F
{2, 3}, {3, 4}, {4, 5}, // C-D, D-E, E-F
};
std::array<int, 8> pegs;
int num = 0;
 
void printSolution() {
std::cout << "----- " << num++ << " -----\n";
std::cout << " " /* */ << pegs[0] << ' ' << pegs[1] << '\n';
std::cout << pegs[2] << ' ' << pegs[3] << ' ' << pegs[4] << ' ' << pegs[5] << '\n';
std::cout << " " /* */ << pegs[6] << ' ' << pegs[7] << '\n';
std::cout << '\n';
}
 
bool valid() {
for (size_t i = 0; i < connections.size(); i++) {
if (abs(pegs[connections[i].first] - pegs[connections[i].second]) == 1) {
return false;
}
}
return true;
}
 
void solution(int le, int ri) {
if (le == ri) {
if (valid()) {
printSolution();
}
} else {
for (size_t i = le; i <= ri; i++) {
std::swap(pegs[le], pegs[i]);
solution(le + 1, ri);
std::swap(pegs[le], pegs[i]);
}
}
}
 
int main() {
pegs = { 1, 2, 3, 4, 5, 6, 7, 8 };
solution(0, pegs.size() - 1);
return 0;
}</syntaxhighlight>
{{out}}
<pre>----- 0 -----
3 4
7 1 8 2
5 6
 
----- 1 -----
3 5
7 1 8 2
4 6
 
----- 2 -----
3 6
7 1 8 2
4 5
 
----- 3 -----
3 6
7 1 8 2
5 4
 
----- 4 -----
4 3
2 8 1 7
6 5
 
----- 5 -----
4 5
2 8 1 7
6 3
 
----- 6 -----
4 5
7 1 8 2
3 6
 
----- 7 -----
4 6
7 1 8 2
3 5
 
----- 8 -----
5 3
2 8 1 7
6 4
 
----- 9 -----
5 4
2 8 1 7
6 3
 
----- 10 -----
5 4
7 1 8 2
3 6
 
----- 11 -----
5 6
7 1 8 2
3 4
 
----- 12 -----
6 3
2 8 1 7
5 4
 
----- 13 -----
6 3
2 8 1 7
4 5
 
----- 14 -----
6 4
2 8 1 7
5 3
 
----- 15 -----
6 5
2 8 1 7
4 3</pre>
 
=={{header|Chapel}}==
<langsyntaxhighlight lang="chapel">type hole = int;
param A : hole = 1;
param B : hole = A+1;
Line 1,029 ⟶ 1,401:
}
</syntaxhighlight>
</lang>
<pre>
4 5
Line 1,043 ⟶ 1,415:
 
=={{header|D}}==
<langsyntaxhighlight lang="d">void main() @safe {
import std.stdio, std.math, std.algorithm, std.traits, std.string;
 
Line 1,069 ⟶ 1,441:
return board.tr("ABCDEFGH", "%(%d%)".format(perm)).writeln;
while (perm[].nextPermutation);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,086 ⟶ 1,458:
Using a simple backtracking.
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.conv, std.string, std.typecons;
 
// Holes A=0, B=1, ..., H=7
Line 1,150 ⟶ 1,522:
board.tr("ABCDEFGH", "%(%d%)".format(sol.p)).writeln;
writeln("Tested ", sol.tests, " positions and did ", sol.swaps, " swaps.");
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,163 ⟶ 1,535:
5 6
Tested 12094 positions and did 20782 swaps.</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
 
{ This item would normally be in a separate library. It is presented here for clarity}
 
{Permutator object steps through all permutation of array items}
{Zero-Based = True = 0..Permutions-1 False = 1..Permutaions}
{Permutation set on "Create(Size)" or by "Permutations" property}
{Permutation are contained in the array "Indices"}
 
type TPermutator = class(TObject)
private
FZeroBased: boolean;
FBase: integer;
FPermutations: integer;
procedure SetZeroBased(const Value: boolean);
procedure SetPermutations(const Value: integer);
protected
FMax: integer;
public
Indices: TIntegerDynArray;
constructor Create(Size: integer);
procedure Reset;
function Next: boolean;
property ZeroBased: boolean read FZeroBased write SetZeroBased;
property Permutations: integer read FPermutations write SetPermutations;
end;
 
 
 
procedure TPermutator.Reset;
var I: integer;
begin
FMax:=High(Indices);
for I:= 0 to High(Indices) do Indices[I]:= I+FBase;
end;
 
 
 
procedure TPermutator.SetPermutations(const Value: integer);
begin
if FPermutations<>Value then
begin
FPermutations := Value;
SetLength(Indices,Value);
Reset;
end;
end;
 
 
 
constructor TPermutator.Create(Size: integer);
begin
ZeroBased:=True;
Permutations:=Size;
Reset;
end;
 
 
function TPermutator.Next: boolean;
{Returns true when sequence completed}
var I,T: integer;
begin
while true do
begin
T:= Indices[0];
for I:=0 to FMax-1 do Indices[I]:= Indices[I+1];
Indices[FMax]:= T;
if T<>(FMax+FBase) then
begin
FMax:=High(Indices);
break;
end
else FMax:= FMax-1;
if FMax<0 then break;
end;
Result:=FMax<1;
if Result then Reset;
end;
 
 
 
procedure TPermutator.SetZeroBased(const Value: boolean);
begin
if FZeroBased<>Value then
begin
FZeroBased := Value;
if Value then FBase:=0
else FBase:=1;
Reset;
end;
end;
 
{------------------------------------------------------------------------------}
 
{Network structures}
{Puzzle node}
 
type TPuzNode = record
Name: string;
Value: integer;
end;
type PPuzNode = ^TPuzNode;
 
{Edges connecting nodes}
 
type TPuzEdge = record
N1,N2: ^TPuzNode;
end;
 
{All edges in puzzle}
 
var Edges: array [0..14] of TPuzEdge;
 
{All nodes in puzzle}
 
var A: TPuzNode = (Name: 'A'; Value: 1);
var B: TPuzNode = (Name: 'B'; Value: 2);
var C: TPuzNode = (Name: 'C'; Value: 3);
var D: TPuzNode = (Name: 'D'; Value: 4);
var E: TPuzNode = (Name: 'E'; Value: 5);
var F: TPuzNode = (Name: 'F'; Value: 6);
var G: TPuzNode = (Name: 'G'; Value: 7);
var H: TPuzNode = (Name: 'H'; Value: 8);
 
{Array of pointers to puzzle nodes }
 
var PuzNodes: array [0..7] of Pointer;
 
procedure BuildNetwork;
{Build puzzle net work}
begin
{Put pointers to nodes in array}
PuzNodes[0]:=@A;
PuzNodes[1]:=@B;
PuzNodes[2]:=@C;
PuzNodes[3]:=@D;
PuzNodes[4]:=@E;
PuzNodes[5]:=@F;
PuzNodes[6]:=@G;
PuzNodes[7]:=@H;
{Set up all edges}
Edges[0].N1:=@A; Edges[0].N2:=@C;
Edges[1].N1:=@A; Edges[1].N2:=@D;
Edges[2].N1:=@A; Edges[2].N2:=@E;
Edges[3].N1:=@B; Edges[3].N2:=@D;
Edges[4].N1:=@B; Edges[4].N2:=@E;
Edges[5].N1:=@B; Edges[5].N2:=@F;
Edges[6].N1:=@G; Edges[6].N2:=@C;
Edges[7].N1:=@G; Edges[7].N2:=@D;
Edges[8].N1:=@G; Edges[8].N2:=@E;
Edges[9].N1:=@H; Edges[9].N2:=@D;
Edges[10].N1:=@H; Edges[10].N2:=@E;
Edges[11].N1:=@H; Edges[11].N2:=@F;
Edges[12].N1:=@C; Edges[12].N2:=@D;
Edges[13].N1:=@D; Edges[13].N2:=@E;
Edges[14].N1:=@E; Edges[14].N2:=@F;
end;
 
 
 
function ValidPattern: boolean;
{Test if pattern of node values is valid}
{i.e., edges values are greater than 1}
var I: integer;
begin
Result:=False;
for I:=0 to High(Edges) do
if abs(Edges[I].N2.Value-Edges[I].N1.Value)<2 then exit;
Result:=True;
end;
 
 
function Permutate: boolean;
{Use permutator object to iterate through all combinations}
var PM: TPermutator;
var I: integer;
begin
{Create with 8 items}
PM:=TPermutator.Create(8);
try
{Set to make it 1..8}
PM.ZeroBased:=False;
Result:=True;
{Iterate through all permutation}
while not PM.Next do
begin
{Copy permutation into network}
for I:=0 to High(PM.Indices) do
PPuzNode(PuzNodes[I])^.Value:=PM.Indices[I];
{If permutation is valid exit}
if ValidPattern then exit;
end;
{No valid permutation found}
Result:=False;
finally PM.Free; end;
end;
 
{String to display game board}
 
var GameBoard: string =
' A B'+CRLF+
' /|\ /|\'+CRLF+
' / | X | \'+CRLF+
' / |/ \| \'+CRLF+
' C - D - E - F'+CRLF+
' \ |\ /| /'+CRLF+
' \ | X | /'+CRLF+
' \|/ \|/'+CRLF+
' G H'+CRLF;
 
 
procedure ShowPuzzle(Memo: TMemo);
{Display game board with correct answer inserted}
var I,Inx: integer;
var S: string;
var PN: TPuzNode;
begin
S:=GameBoard;
{Search for Letters A..H}
for I:=1 to Length(S) do
if S[I] in ['A'..'H'] then
begin
{Convert A..H to index}
Inx:=byte(S[I]) - $41;
{Get node A..H}
PN:=PPuzNode(PuzNodes[Inx])^;
{Store value in corresponding node}
S[I]:=char(PN.Value+$30);
end;
{Display board}
Memo.Lines.Add(S);
end;
 
 
procedure ConnectionPuzzle(Memo: TMemo);
{Solve connection puzzle}
var S: string;
var I: integer;
var PN: TPuzNode;
begin
BuildNetwork;
Permutate;
{Display result}
S:='';
for I:=0 to High(PuzNodes) do
begin
PN:=PPuzNode(PuzNodes[I])^;
S:=S+PN.Name+'='+IntToStr(PN.Value)+' ';
end;
Memo.Lines.Add(S);
{Show puzzle with values inserted}
ShowPuzzle(Memo);
end;
 
 
 
</syntaxhighlight>
{{out}}
<pre>
A=5 B=6 C=7 D=1 E=8 F=2 G=3 H=4
5 6
/|\ /|\
/ | X | \
/ |/ \| \
7 - 1 - 8 - 2
\ |\ /| /
\ | X | /
\|/ \|/
3 4
 
Elapsed Time: 2.092 ms.
 
</pre>
 
 
=={{header|Elixir}}==
{{trans|Ruby}}
This solution uses HLPsolver from [[Solve_a_Hidato_puzzle#Elixir | here]]
<langsyntaxhighlight lang="elixir"># It solved if connected A and B, connected G and H (according to the video).
 
# require HLPsolver
Line 1,192 ⟶ 1,844:
|> Enum.zip(~w[A B C D E F G H])
|> Enum.reduce(layout, fn {n,c},acc -> String.replace(acc, c, to_string(n)) end)
|> IO.puts</langsyntaxhighlight>
 
{{out}}
Line 1,208 ⟶ 1,860:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: assocs interpolate io kernel math math.combinatorics
math.ranges math.parser multiline pair-rocket sequences
sequences.generalizations ;
Line 1,253 ⟶ 1,905:
: main ( -- ) find-solution display-solution ;
 
MAIN: main</langsyntaxhighlight>
{{out}}
<pre>
Line 1,264 ⟶ 1,916:
\ | X | /
\|/ \|/
5 6
</pre>
 
=={{header|Fortran}}==
{{works with|gfortran|11.2.1}}
<syntaxhighlight lang="fortran">! This is free and unencumbered software released into the public domain,
! via the Unlicense.
! For more information, please refer to <http://unlicense.org/>
 
program no_connection_puzzle
 
implicit none
 
! The names of the holes.
integer, parameter :: a = 1
integer, parameter :: b = 2
integer, parameter :: c = 3
integer, parameter :: d = 4
integer, parameter :: e = 5
integer, parameter :: f = 6
integer, parameter :: g = 7
integer, parameter :: h = 8
 
integer :: holes(a:h)
 
call find_solutions (holes, a)
 
contains
 
recursive subroutine find_solutions (holes, current_hole_index)
integer, intent(inout) :: holes(a:h)
integer, intent(in) :: current_hole_index
 
integer :: peg_number
 
! Recursively construct and print possible solutions, quitting
! any partial solution that does not satisfy constraints.
do peg_number = 1, 8
holes(current_hole_index) = peg_number
if (satisfies_the_constraints (holes, current_hole_index)) then
if (current_hole_index == h) then
call print_solution (holes)
write (*, '()')
else
call find_solutions (holes, current_hole_index + 1)
end if
end if
end do
end subroutine find_solutions
 
function satisfies_the_constraints (holes, i) result (satisfies)
integer, intent(inout) :: holes(a:h)
integer, intent(in) :: i ! Where the new peg goes.
logical :: satisfies
 
integer :: j
 
! The most recently inserted peg must not be a duplicate of one
! already inserted.
satisfies = all (holes(a : i - 1) /= holes(i))
 
if (satisfies) then
! ‘Fill’ the unfilled holes with fake pegs that cause
! differences with them always to be larger than 1.
do j = i + 1, h
holes(j) = 100 * j
end do
 
! Check that the differences are satisfactory.
satisfies = 1 < abs (holes(a) - holes(c)) .and. &
& 1 < abs (holes(a) - holes(d)) .and. &
& 1 < abs (holes(a) - holes(e)) .and. &
& 1 < abs (holes(c) - holes(g)) .and. &
& 1 < abs (holes(d) - holes(g)) .and. &
& 1 < abs (holes(e) - holes(g)) .and. &
& 1 < abs (holes(b) - holes(d)) .and. &
& 1 < abs (holes(b) - holes(e)) .and. &
& 1 < abs (holes(b) - holes(f)) .and. &
& 1 < abs (holes(d) - holes(h)) .and. &
& 1 < abs (holes(e) - holes(h)) .and. &
& 1 < abs (holes(f) - holes(h)) .and. &
& 1 < abs (holes(c) - holes(d)) .and. &
& 1 < abs (holes(d) - holes(e)) .and. &
& 1 < abs (holes(e) - holes(f))
end if
end function satisfies_the_constraints
 
subroutine print_solution (holes)
integer, intent(in) :: holes(a:h)
 
write (*, '(I5, I4)') holes(a), holes(b)
write (*, '(" /│\ /│\")')
write (*, '(" / │ X │ \")')
write (*, '(" / │/ \│ \")')
write (*, '(3(I1, "───"), I1)') holes(c), holes(d), holes(e), holes(f)
write (*, '(" \ │\ /│ /")')
write (*, '(" \ │ X │ /")')
write (*, '(" \│/ \│/")')
write (*, '(I5, I4)') holes(g), holes(h)
end subroutine print_solution
 
end program no_connection_puzzle</syntaxhighlight>
The first solution printed:
{{out}}
<pre>
3 4
/│\ /│\
/ │ X │ \
/ │/ \│ \
7───1───8───2
\ │\ /│ /
\ │ X │ /
\│/ \│/
5 6
</pre>
Line 1,269 ⟶ 2,034:
=={{header|Go}}==
A simple recursive brute force solution.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,358 ⟶ 2,123:
}
return b - a
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,373 ⟶ 2,138:
Tested 12094 positions and did 20782 swaps.
</pre>
 
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">import java.util.stream.Collectors
import java.util.stream.IntStream
 
class NoConnection {
// adopted from Go
static int[][] links = [
[2, 3, 4], // A to C,D,E
[3, 4, 5], // B to D,E,F
[2, 4], // D to C, E
[5], // E to F
[2, 3, 4], // G to C,D,E
[3, 4, 5], // H to D,E,F
]
 
static int[] pegs = new int[8]
 
static void main(String[] args) {
List<Integer> vals = IntStream.range(1, 9)
.mapToObj({ it })
.collect(Collectors.toList())
 
while (true) {
Collections.shuffle(vals)
for (int i = 0; i < pegs.length; i++) {
pegs[i] = vals.get(i)
}
if (solved()) {
break
}
}
 
printResult()
}
 
static boolean solved() {
for (int i = 0; i < links.length; i++) {
for (int peg : links[i]) {
if (Math.abs(pegs[i] - peg) == 1) {
return false
}
}
}
return true
}
 
static void printResult() {
println(" ${pegs[0]} ${pegs[1]}")
println("${pegs[2]} ${pegs[3]} ${pegs[4]} ${pegs[5]}")
println(" ${pegs[6]} ${pegs[7]}")
}
}</syntaxhighlight>
{{out}}
<pre> 6 7
2 3 8 1
4 5</pre>
 
=={{header|Haskell}}==
<syntaxhighlight lang ="haskell">import Data.List (intercalate, permutations)
 
solution :: [Int]
solution@(a : b : c : d : e : f : g : h : _) = head $ filter isSolution (permutations [1 .. 8])
head $
filter isSolution (permutations [1 .. 8])
where
isSolution :: [Int] -> Bool
isSolution (a : b : c : d : e : f : g : h : _) =
all ((> 1) . abs) $
zipWith
(-)
[a, c, g, e, a, c, g, e, b, d, h, f, b, d, h, f]
[d, d, d, d, c, g, e, a, e, e, e, e, d, h, f, b]
 
main :: IO ()
main =
(putStrLn . unlines) $
unlines
let rightShift s
( | length s > 3 = szipWith
| otherwise =(\x y -> x : (" = " ++<> show sy))
['A' .. 'H']
in intercalate
"\n" solution
) :
(zipWith (\x y -> x : (" = " ++ show y)) ['A' .. 'H'] solution) :
( ((rightShift . unwords . fmap show) <$> [[], [a, b], [c, d, e, f], [g, h]])</lang>
<$> [[], [a, b], [c, d, e, f], [g, h]]
)
where
rightShift s
| length s > 3 = s
| otherwise = " " <> s</syntaxhighlight>
{{Out}}
<pre style="font-size:80%">A = 3
Line 1,416 ⟶ 2,247:
Supporting code:
 
<langsyntaxhighlight Jlang="j">holes=:;:'A B C D E F G H'
 
connections=:".;._2]0 :0
Line 1,449 ⟶ 2,280:
disp=:verb define
rplc&(,holes;&":&>y) box
)</langsyntaxhighlight>
 
Intermezzo:
 
<langsyntaxhighlight Jlang="j"> (#~ 1<attempt"1) pegs
3 4 7 1 8 2 5 6
3 5 7 1 8 2 4 6
Line 1,469 ⟶ 2,300:
6 3 2 8 1 7 5 4
6 4 2 8 1 7 5 3
6 5 2 8 1 7 4 3</langsyntaxhighlight>
 
Since there's more than one arrangement where the pegs satisfy the task constraints, and since the task calls for one solution, we will need to pick one of them. We can use the "first" function to satisfy this important constraint.
 
<langsyntaxhighlight Jlang="j"> disp {. (#~ 1<attempt"1) pegs
3 4
/|\ /|\
Line 1,484 ⟶ 2,315:
5 6
 
</syntaxhighlight>
</lang>
 
'''Video'''
Line 1,490 ⟶ 2,321:
If we follow the video and also connect A and B as well as G and H, we get only four solutions (which we can see are reflections / rotations of each other):
 
<langsyntaxhighlight Jlang="j"> (#~ 1<attempt"1) pegs
3 5 7 1 8 2 4 6
4 6 7 1 8 2 3 5
5 3 2 8 1 7 6 4
6 4 2 8 1 7 5 3</langsyntaxhighlight>
 
The first of these looks like this:
 
<langsyntaxhighlight Jlang="j"> disp {. (#~ 1<attempt"1) pegs
3 - 5
/|\ /|\
Line 1,508 ⟶ 2,339:
\|/ \|/
4 - 6
</syntaxhighlight>
</lang>
 
For this puzzle, we can also see that the solution can be described as: put the starting and ending numbers in the middle - everything else follows from there. It's perhaps interesting that we get this solution even if we do not explicitly put that logic into our code - it's built into the puzzle itself and is still the only solution no matter how we arrive there.
Line 1,515 ⟶ 2,346:
The backtracking is getting tiresome, we'll try a stochastic solution for a change.<br>
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import static java.lang.Math.abs;
import java.util.*;
import static java.util.stream.Collectors.toList;
Line 1,560 ⟶ 2,391:
System.out.printf(" %s %s%n", pegs[6], pegs[7]);
}
}</langsyntaxhighlight>
(takes about 500 shuffles on average)
<pre> 4 5
Line 1,569 ⟶ 2,400:
===ES6===
{{Trans|Haskell}}
<langsyntaxhighlight JavaScriptlang="javascript">(() => {
'use strict';
 
// GENERIC FUNCTIONS --------------------------------------- NO CONNECTION PUZZLE ---------------
 
// solvedPuzzle :: () -> [Int]
const solvedPuzzle = () => {
 
// universe :: [[Int]]
const universe = permutations(enumFromTo(1)(8));
 
// isSolution :: [Int] -> Bool
const isSolution = ([a, b, c, d, e, f, g, h]) =>
all(x => abs(x) > 1)([
a - d, c - d, g - d, e - d, a - c, c - g,
g - e, e - a, b - e, d - e, h - e, f - e,
b - d, d - h, h - f, f - b
]);
 
return universe[
until(i => isSolution(universe[i]))(
succ
)(0)
];
}
 
// ---------------------- TEST -----------------------
const main = () => {
const
firstSolution = solvedPuzzle(),
[a, b, c, d, e, f, g, h] = firstSolution;
 
return unlines(
zipWith(
a => n => a + ' = ' + n.toString()
)(enumFromTo('A')('H'))(firstSolution)
.concat([
[],
[a, b],
[c, d, e, f],
[g, h]
].map(
xs => unwords(xs.map(show))
.padStart(5, ' ')
))
);
}
 
// ---------------- GENERIC FUNCTIONS ----------------
 
// abs :: Num -> Num
const abs =
// Absolute value of a given number - without the sign.
Math.abs;
 
// abs :: Num a => a -> a
const abs = Math.abs;
 
// all :: (a -> Bool) -> [a] -> Bool
const all = (f, xs)p => xs.every(f);
// True if p(x) holds for every x in xs.
xs => [...xs].every(p);
 
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
 
// delete_compose (<<<) :: Eq(b a-> =c) -> (a -> [a]b) -> [a] -> c
const delete_compose = (x, xs...fs) =>
deleteBy((a,// b)A =>function adefined ===by b,the x, xs);right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
x => x
);
 
// deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
const deleteBy = (f, x, xs) =>
xs.length > 0 ? (
f(x, xs[0]) ? (
xs.slice(1)
) : [xs[0]].concat(deleteBy(f, x, xs.slice(1)))
) : [];
 
// enumFromTo :: Enum a => a -> a -> [a]
const enumFromTo = (m, => n) => {
const [tmx, tny] = [typeof m, typeof n];.map(fromEnum),
return tm !== tn ?b undefined= :x + (isNaN(m) =>? {0 : m - x);
return constArray.from({
length: 1 blnS =+ (tmy ===- 'string'x),
[base}, end] = [m(_, n].map(blnS ? (si) => s.codePointAttoEnum(0)m)(b :+ idi));
return Array.from({
length: Math.floor(end - base) + 1
}, (_, i) => blnS ? String.fromCodePoint(base + i) : m + i);
})();
};
 
// id :: a -> a
const id = x => x;
 
// justifyRightfromEnum :: IntEnum ->a Char -=> Texta -> TextInt
const justifyRightfromEnum = (n, cFiller, strText)x =>
ntypeof >x strText.length!== 'string' ? (
(cFillerx.repeat(n)constructor +=== strText)Object ? (
x.slice(-n)value
) : strText;parseInt(Number(x))
) : x.codePointAt(0);
 
 
// length :: [a] -> Int
const length = xs =>
// Returns Infinity over objects without finite
// length. This enables zip and zipWith to choose
// the shorter argument when one is non-finite,
// like cycle, repeat etc
'GeneratorFunction' !== xs.constructor
.constructor.name ? (
xs.length
) : Infinity;
 
 
// list :: StringOrArrayLike b => b -> [a]
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
) : Array.from(xs || []);
 
 
// permutations :: [a] -> [[a]]
const permutations = xs => (
xs.length ? concatMap(xys => concatMapys.reduceRight(ys => [
(a, y) => [x]a.concatflatMap(ys)
], ys => Array.from({
permutations(delete_(x, xs))), xs) length: [1 + ys.length
[] }, (_, i) => i)
.map(n => ys.slice(0, n)
];
.concat(y)
.concat(ys.slice(n))
)
), [
[]
]
)
)(list(xs));
 
 
// show :: a -> String
const show = x => JSON.stringify(x);
JSON.stringify(x);
 
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
// untilsucc :: (a -> Bool) -> (a ->Enum a) -=> a -> a
const untilsucc = (p, f, x) => {
let1 v =+ x;
while (!p(v)) v = f(v);
return v;
};
 
// unwords :: [String] -> String
const unwords = xs => xs.join(' ');
 
// zipWithtake :: (a -> b -> c)Int -> [a] -> [b] -> [ca]
const// zipWithtake =:: (f,Int xs,-> ys)String =-> {String
const take = const nyn = ys.length;>
return// (xs.lengthThe <=first nyn ?elements xsof :a xs.slice(0list, ny))
// string of .map((xcharacters, i)or => f(x, ys[i]));stream.
xs => 'GeneratorFunction' !== xs
};
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
 
// toEnum :: a -> Int -> a
// CONNECTION PUZZLE ------------------------------------------------------
const toEnum = e =>
// The first argument is a sample of the type
// allowing the function to make the right mapping
x => ({
'number': Number,
'string': String.fromCodePoint,
'boolean': Boolean,
'object': v => e.min + v
} [typeof e])(x);
 
// universe :: [[Int]]
const universe = permutations(enumFromTo(1, 8));
 
// isSolutionunlines :: [IntString] -> BoolString
const isSolutionunlines = ([a, b, c, d, e, f, g, h])xs =>
// A single string formed by the intercalation
all(x => abs(x) > 1, [a - d, c - d, g - d, e - d, a - c, c - g, g - e,
// of a list of strings with the newline character.
e - a, b - e, d - e, h - e, f - e, b - d, d - h, h - f, f - b
]xs.join('\n');
 
// firstSolution :: [Int]
const firstSolution = universe[until(
i => isSolution(universe[i]),
i => i + 1,
0
)];
 
// until :: (a -> Bool) -> (a -> a) -> a -> a
// TEST -------------------------------------------------------------------
const until = p =>
f => x => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
 
// [Int]
const [a, b, c, d, e, f, g, h] = firstSolution;
 
// unwords :: [String] -> String
return unlines(
const unwords = xs zipWith(=>
// A space-separated string derived
(a, n) => a + ' = ' + n.toString(),
// from a list enumFromTo('A',of 'H'),words.
xs.join(' firstSolution');
 
)
 
.concat(
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f [],=>
// Use of `take` and `length` here allows [a, b],
// zipping with non-finite [c, d, e, f],lists
// i.e. generators like cycle, [grepeat, h]iterate.
].map(xs => justifyRight(5,ys '=> ', unwords(xs.map(show)))){
const n = Math.min(length(xs), length(ys));
)
return Infinity > n ? (
);
(([as, bs]) => Array.from({
})();</lang>
length: n
}, (_, i) => f(as[i])(
bs[i]
)))([xs, ys].map(
compose(take(n), list)
))
) : zipWithGen(f)(xs)(ys);
};
 
return main();
})();</syntaxhighlight>
{{Out}}
<pre>A = 3
Line 1,705 ⟶ 2,626:
 
=={{header|jq}}==
{{works with|jq|1.46}}
'''Also works with gojq, the Go implementation of jq'''
 
We present a generate-and-test solver for a slightly more general version of the problem, in which there are N pegs and holes, and in which the connectedness of holes is defined by an array such that holes i and j are connected if and only if [i,j] is a member of the
array.
Line 1,715 ⟶ 2,638:
 
'''Part 1: Generic functions'''
<syntaxhighlight lang="jq">
<lang jq># Short-circuit determination of whether (a|condition)
# permutations of 0 .. (n-1) inclusive
# is true for all a in array:
def forall(array; condition):
def check:
. as $ix
| if $ix == (array|length) then true
elif (array[$ix] | condition) then ($ix + 1) | check
else false
end;
0 | check;
 
# permutations of 0 .. (n-1)
def permutations(n):
# Given a single array, generate a stream by inserting n at different positions:
Line 1,738 ⟶ 2,651:
 
# Count the number of items in a stream
def count(f): reduce f as $_ (0; .+1);</lang>
</syntaxhighlight>
 
'''Part 2: The no-connections puzzle for N pegs and holes'''
<syntaxhighlight lang="jq">
<lang jq># Generate a stream of solutions.
# Generate a stream of solutions.
# Input should be the connections array, i.e. an array of [i,j] pairs;
# N is the number of pegs and holds.
Line 1,750 ⟶ 2,664:
def ok(connections):
. as $p
| forallall( connections[];
(($p[.[0]] - $p[.[1]])|abs) != 1 );
 
. as $connections | permutations(N) | select(ok($connections));</lang>
</syntaxhighlight>
'''Part 3: The 8-peg no-connection puzzle'''
<syntaxhighlight lang="jq">
<lang jq># The connectedness matrix:
# The connectedness matrix
# In this table, 0 represents "A", etc, and an entry [i,j]
# signifies that the holes with indices i and j are connected.
Line 1,787 ⟶ 2,703:
| $letters
| reduce range(0;length) as $i ($board; index($letters[$i]) as $ix | .[$ix] = $in[$i] + 48)
| implode;</langsyntaxhighlight>
'''Examples''':
<langsyntaxhighlight lang="jq"># To print all the solutions:
# solve | pp
 
# To count the number of solutions:
# count(solve)
# => 16
 
limit(1; solve) | pp
# jq 1.4 lacks facilities for harnessing generators,
</syntaxhighlight>
# but the following will suffice here:
{{output}}
def one(f): reduce f as $s
Invocation: jq -n -r -f no_connection.jq
(null; if . == null then $s else . end);
<pre>
 
one(solve) | pp
</lang>
{{out}}
<lang sh>$ jq -n -r -f no_connection.jq
 
5 6
/|\ /|\
Line 1,813 ⟶ 2,725:
\ | X | /
\|/ \|/
3 4</lang>
</pre>
 
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia">
using Combinatorics
 
Line 1,857 ⟶ 2,769:
 
printsolutions()
</langsyntaxhighlight> {{output}} <pre>
Found 16 solutions.
3 4
Line 1,872 ⟶ 2,784:
=={{header|Kotlin}}==
{{trans|Go}}
<langsyntaxhighlight lang="scala">// version 1.2.0
 
import kotlin.math.abs
Line 1,955 ⟶ 2,867:
println(pegsAsString(p))
println("Tested $tests positions and did $swaps swaps.")
}</langsyntaxhighlight>
 
{{out}}
Line 1,976 ⟶ 2,888:
 
Press space bar to see solutions so far.
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module no_connection_puzzle {
\\ Holes
Line 2,069 ⟶ 2,981:
no_connection_puzzle
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,083 ⟶ 2,995:
</pre >
 
=={{header|Mathematicam4}}==
{{trans|Fortran}}
 
Unlike the Fortran from which it was migrated, this m4 program stops at the first solution. The holes are represented by positions in a string; you can regard the string as a variable-size array. (m4 is, of course, a string-manipulation language.)
 
The program ought to work with any POSIX-compliant m4. The display has been changed to use only ASCII characters, because very old m4 cannot handle UTF-8.
 
<syntaxhighlight lang="m4">divert(-1)
 
define(`abs',`eval(((( $1 ) < 0) * (-( $1 ))) + ((0 <= ( $1 )) * ( $1 )))')
 
define(`display_solution',
` substr($1,0,1) substr($1,1,1)
/|\ /|\
/ | X | \
/ |/ \| \
substr($1,2,1)`---'substr($1,3,1)`---'substr($1,4,1)`---'substr($1,5,1)
\ |\ /| /
\ | X | /
\|/ \|/
substr($1,6,1) substr($1,7,1)')
 
define(`satisfies_constraints',
`eval(satisfies_no_duplicates_constraint($1) && satisfies_difference_constraints($1))')
 
define(`satisfies_no_duplicates_constraint',
`eval(index(all_but_last($1),last($1)) == -1)')
 
define(`satisfies_difference_constraints',
`pushdef(`A',ifelse(eval(1 <= len($1)),1,substr($1,0,1),100))`'dnl
pushdef(`B',ifelse(eval(2 <= len($1)),1,substr($1,1,1),200))`'dnl
pushdef(`C',ifelse(eval(3 <= len($1)),1,substr($1,2,1),300))`'dnl
pushdef(`D',ifelse(eval(4 <= len($1)),1,substr($1,3,1),400))`'dnl
pushdef(`E',ifelse(eval(5 <= len($1)),1,substr($1,4,1),500))`'dnl
pushdef(`F',ifelse(eval(6 <= len($1)),1,substr($1,5,1),600))`'dnl
pushdef(`G',ifelse(eval(7 <= len($1)),1,substr($1,6,1),700))`'dnl
pushdef(`H',ifelse(eval(8 <= len($1)),1,substr($1,7,1),800))`'dnl
eval(1 < abs((A) - (C)) &&
1 < abs((A) - (D)) &&
1 < abs((A) - (E)) &&
1 < abs((C) - (G)) &&
1 < abs((D) - (G)) &&
1 < abs((E) - (G)) &&
1 < abs((B) - (D)) &&
1 < abs((B) - (E)) &&
1 < abs((B) - (F)) &&
1 < abs((D) - (H)) &&
1 < abs((E) - (H)) &&
1 < abs((F) - (H)) &&
1 < abs((C) - (D)) &&
1 < abs((D) - (E)) &&
1 < abs((E) - (F)))'`dnl
popdef(`A',`B',`C',`D',`E',`F',`G',`H')')
 
define(`all_but_last',`substr($1,0,decr(len($1)))')
define(`last',`substr($1,decr(len($1)))')
 
define(`last_is_eight',`eval((last($1)) == 8)')
define(`strip_eights',`ifelse(last_is_eight($1),1,`$0(all_but_last($1))',`$1')')
 
define(`incr_last',`all_but_last($1)`'incr(last($1))')
 
define(`solve_puzzle',`_$0(1)')
define(`_solve_puzzle',
`ifelse(eval(len($1) == 8 && satisfies_constraints($1)),1,`display_solution($1)',
satisfies_constraints($1),1,`$0($1`'1)',
last_is_eight($1),1,`$0(incr_last(strip_eights($1)))',
`$0(incr_last($1))')')
 
divert`'dnl
dnl
solve_puzzle</syntaxhighlight>
 
{{out}}
<pre> 3 4
/|\ /|\
/ | X | \
/ |/ \| \
7---1---8---2
\ |\ /| /
\ | X | /
\|/ \|/
5 6</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
This one simply takes all permutations of the pegs and filters out invalid solutions.
<langsyntaxhighlight Mathematicalang="mathematica">sol = Fold[
Select[#,
Function[perm, Abs[perm[[#2[[1]]]] - perm[[#2[[2]]]]] > 1]] &,
Line 2,095 ⟶ 3,091:
" `` ``\n /|\\ /|\\\n / | X | \\\n / |/ \\| \\\n`` - `` \
- `` - ``\n \\ |\\ /| /\n \\ | X | /\n \\|/ \\|/\n `` ``",
Sequence @@ sol]];</langsyntaxhighlight>
{{out}}
<pre> 3 4
Line 2,107 ⟶ 3,103:
5 6</pre>
 
=={{header|Perl 6Nim}}==
{{trans|C++}}
This uses a Warnsdorff solver, which cuts down the number of tries by more than a factor of six over the brute force approach. This same solver is used in:
I choose to use one-based indexing for the array of pegs. It seems more logical here and Nim allows to choose any starting index for static arrays.
 
<syntaxhighlight lang="nim">import strformat
* [[Solve a Hidato puzzle#Perl_6|Solve a Hidato puzzle]]
* [[Solve a Hopido puzzle#Perl_6|Solve a Hopido puzzle]]
* [[Solve a Holy Knight's tour#Perl_6|Solve a Holy Knight's tour]]
* [[Solve a Numbrix puzzle#Perl_6|Solve a Numbrix puzzle]]
* [[Solve the no connection puzzle#Perl_6|Solve the no connection puzzle]]
 
const Connections = [(1, 3), (1, 4), (1, 5), # A to C, D, E
The idiosyncratic adjacency diagram is dealt with by the simple expedient of bending the two vertical lines <tt>||</tt> into two bows <tt>)(</tt>, such that adjacency can be calculated simply as a distance of 2 or less.
(2, 4), (2, 5), (2, 6), # B to D, E, F
<lang perl6>my @adjacent = gather -> $y, $x {
(7, 3), (7, 4), (7, 5), # G to C, D, E
take [$y,$x] if abs($x|$y) > 2;
(8, 4), (8, 5), (8, 6), # H to D, E, F
} for flat -5 .. 5 X -5 .. 5;
(3, 4), (4, 5), (5, 6)] # C-D, D-E, E-F
 
type
solveboard q:to/END/;
Peg = 1. _ . . _ .8
Pegs = array[1. .8, . . . .Peg]
_ . _ 1 . _
. . . . . .
. _ . . _ .
END
sub solveboard($board) {
my $max = +$board.comb(/\w+/);
my $width = $max.chars;
 
my @grid;
my @known;
my @neigh;
my @degree;
@grid = $board.lines.map: -> $line {
[ $line.words.map: { /^_/ ?? 0 !! /^\./ ?? Rat !! $_ } ]
}
sub neighbors($y,$x --> List) {
eager gather for @adjacent {
my $y1 = $y + .[0];
my $x1 = $x + .[1];
take [$y1,$x1] if defined @grid[$y1][$x1];
}
}
 
func valid(pegs: Pegs): bool =
for ^@grid -> $y {
for ^@grid[$y](src, ->dst) $xin {Connections:
if @gridabs(pegs[$ysrc] - pegs[$xdst]) -> $v== {1:
return false
@known[$v] = [$y,$x];
result = true
}
if @grid[$y][$x].defined {
@neigh[$y][$x] = neighbors($y,$x);
@degree[$y][$x] = +@neigh[$y][$x];
}
}
}
print "\e[0H\e[0J";
 
my $tries = 0;
 
proc print(pegs: Pegs; num: Positive) =
try_fill 1, @known[1];
echo &"----- {num} -----"
echo &" {pegs[1]} {pegs[2]}"
echo &"{pegs[3]} {pegs[4]} {pegs[5]} {pegs[6]}"
echo &" {pegs[7]} {pegs[8]}"
echo()
 
sub try_fill($v, $coord [$y,$x] --> Bool) {
return True if $v > $max;
$tries++;
 
proc findSolution(pegs: var Pegs; left, right: Natural; solCount = 0): Natural =
my $old = @grid[$y][$x];
var solCount = solCount
if left == right:
if pegs.valid():
inc solCount
pegs.print(solCount)
else:
for i in left..right:
swap pegs[left], pegs[i]
solCount = pegs.findSolution(left + 1, right, solCount)
swap pegs[left], pegs[i]
result = solCount
 
return False if +$old and $old != $v;
return False if @known[$v] and @known[$v] !eqv $coord;
 
when isMainModule:
@grid[$y][$x] = $v; # conjecture grid value
 
var pegs = [Peg 1, 2, 3, 4, 5, 6, 7, 8]
print "\e[0H"; # show conjectured board
discard pegs.findSolution(1, 8)</syntaxhighlight>
for @grid -> $r {
say do for @$r {
when Rat { ' ' x $width }
when 0 { '_' x $width }
default { .fmt("%{$width}d") }
}
}
 
{{out}}
<pre>----- 1 -----
3 4
7 1 8 2
5 6
 
----- 2 -----
my @neighbors = @neigh[$y][$x][];
3 5
7 1 8 2
4 6
 
----- 3 -----
my @degrees;
3 6
for @neighbors -> \n [$yy,$xx] {
7 1 8 2
my $d = --@degree[$yy][$xx]; # conjecture new degrees
4 5
push @degrees[$d], n; # and categorize by degree
}
 
----- 4 -----
for @degrees.grep(*.defined) -> @ties {
3 6
for @ties.reverse { # reverse works better for this hidato anyway
7 1 8 2
return True if try_fill $v + 1, $_;
5 }4
}
 
----- 5 -----
for @neighbors -> [$yy,$xx] {
4 3
++@degree[$yy][$xx]; # undo degree conjectures
2 8 1 }7
6 5
 
----- 6 -----
@grid[$y][$x] = $old; # undo grid value conjecture
4 5
return False;
2 8 1 7
6 3
 
----- 7 -----
4 5
7 1 8 2
3 6
 
----- 8 -----
4 6
7 1 8 2
3 5
 
----- 9 -----
5 3
2 8 1 7
6 4
 
----- 10 -----
5 4
2 8 1 7
6 3
 
----- 11 -----
5 4
7 1 8 2
3 6
 
----- 12 -----
5 6
7 1 8 2
3 4
 
----- 13 -----
6 3
2 8 1 7
5 4
 
----- 14 -----
6 3
2 8 1 7
4 5
 
----- 15 -----
6 4
2 8 1 7
5 3
 
----- 16 -----
6 5
2 8 1 7
4 3</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict;
use warnings;
 
my $gap = qr/.{3}/s;
 
find( <<terminator );
-AB-
CDEF
-GH-
terminator
 
sub find
{
my $p = shift;
$p =~ /(\d)$gap.{0,2}(\d)(??{abs $1 - $2 <= 1 ? '' : '(*F)'})/ ||
$p =~ /^.*\n.*(\d)(\d)(??{abs $1 - $2 <= 1 ? '' : '(*F)'})/ and return;
if( $p =~ /[A-H]/ )
{
find( $p =~ s/[A-H]/$_/r ) for grep $p !~ $_, 1 .. 8;
}
else
{
say "$tries tries";
print $p =~ tr/-/ /r;
}</lang>
exit;
 
}
}</syntaxhighlight>
{{out}}
<pre> 4 3
34
7182
2 8 1 7
56
</pre>
6 5
18 tries</pre>
 
=={{header|Phix}}==
Brute force solution. I ordered the links highest letter first, then grouped by start letter to eliminate things asap. Nothing
to eliminate when placing A and B, when placing C, check that CA>1, when placing D, check that DA,DB,DC are all >1, etc.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
constant txt = """
<span style="color: #008080;">constant</span> <span style="color: #000000;">txt</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
A B
/|\ /|\ A B
/ | X /|\ /|\
/ |/ \| X | \
C - D/ - E|/ -\| F \
\C - |\D /|- E /- F
\ |\ X /| /
\ |/ \X | /
G\|/ H"""\|/
G H
--constant links = "CA DA DB DC EA EB ED FB FE GC GD GE HD HE HF"
"""</span>
constant links = {"","","A","ABC","ABD","BE","CDE","DEF"}
<span style="color: #000080;font-style:italic;">--constant links = "CA DA DB DC EA EB ED FB FE GC GD GE HD HE HF"</span>
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">links</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"A"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ABC"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ABD"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"BE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"CDE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"DEF"</span><span style="color: #0000FF;">}</span>
function solve(sequence s, integer idx, sequence part)
object res
<span style="color: #008080;">function</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">part</span><span style="color: #0000FF;">)</span>
integer v, p
<span style="color: #004080;">object</span> <span style="color: #000000;">res</span>
for i=1 to length(s) do
<span style="color: #004080;">integer</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span>
v = s[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
for j=1 to length(links[idx]) do
<span style="color: #000000;">v</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
p = links[idx][j]-'@'
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
if abs(v-part[p])<2 then v=0 exit end if
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">links</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'@'</span>
end for
<span style="color: #008080;">if</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">-</span><span style="color: #000000;">part</span><span style="color: #0000FF;">[</span><span style="color: #000000;">p</span><span style="color: #0000FF;">])<</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if v then
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if length(s)=1 then return part&v end if
<span style="color: #008080;">if</span> <span style="color: #000000;">v</span> <span style="color: #008080;">then</span>
res = solve(s[1..i-1]&s[i+1..$],idx+1,part&v)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">part</span><span style="color: #0000FF;">&</span><span style="color: #000000;">v</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if sequence(res) then return res end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$],</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">part</span><span style="color: #0000FF;">&</span><span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">res</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return 0
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">0</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
printf(1,substitute_all(txt,"ABCDEFGH",solve("12345678",1,"")))</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">substitute_all</span><span style="color: #0000FF;">(</span><span style="color: #000000;">txt</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ABCDEFGH"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"12345678"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,271 ⟶ 3,324:
 
=={{header|Picat}}==
<langsyntaxhighlight Picatlang="picat">import cp.
 
no_connection_puzzle(X) =>
Line 2,278 ⟶ 3,331:
X :: 1..N,
Graph =
{{1,23}, {1,34}, {1,45},
{2,1}, {2,34}, {2,5}, {2,6},
{3,21}, {3,4}, {3,6}, {3,7},
{4,1}, {4,2}, {4,3}, {4,65}, {4,7}, {4,8},
{5,1}, {5,2}, {5,34}, {5,6}, {5,7}, {5,8},
{6,2}, {6,3}, {6,4}, {6,5}, {6,7}, {6,8},
{7,3}, {7,4}, {7,6}, {7,85},
{8,54}, {8,65}, {8,76}},
 
all_distinct(X),
Line 2,310 ⟶ 3,363:
" %d %d \n",
A,B,C,D,E,F,G,H),
println(Solution).</syntaxhighlight>
 
</lang>
{{out}}
Test:
<pre>
Picat> no_connection_puzzle(_X)
[23,54,87,61,38,12,45,76]
 
23 54
/|\ /|\
/ | X | \
/ |/ \| \
87 - 61 - 38 - 12
\ |\ /| /
\ | X | /
\|/ \|/
45 76
 
 
</pre>
 
Line 2,334 ⟶ 3,385:
 
We first compute a list of nodes, with sort this list, and we attribute a value at the nodes.
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(clpfd)).
 
edge(a, c).
Line 2,389 ⟶ 3,440:
set_constraint(H, T1, V, VT).
 
</syntaxhighlight>
</lang>
Output :
<pre> ?- no_connection_puzzle(Vs).
Line 2,402 ⟶ 3,453:
=={{header|Python}}==
A brute force search solution.
<langsyntaxhighlight lang="python">from __future__ import print_function
from itertools import permutations
from enum import Enum
Line 2,428 ⟶ 3,479:
if __name__ == '__main__':
solutions = solve()
print("A, B, C, D, E, F, G, H =", ', '.join(str(i) for i in solutions[0]))</langsyntaxhighlight>
 
{{out}}
Line 2,437 ⟶ 3,488:
 
Add the following code after that above:
<langsyntaxhighlight lang="python">def pp(solution):
"""Prettyprint a solution"""
boardformat = r"""
Line 2,457 ⟶ 3,508:
for i, s in enumerate(solutions, 1):
print("\nSolution", i, end='')
pp(s)</langsyntaxhighlight>
 
;Extra output:
Line 2,638 ⟶ 3,689:
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">#lang racket
;; Solve the no connection puzzle. Tim Brown Oct. 2014
 
Line 2,680 ⟶ 3,731:
"~a") pzl))
 
(render-puzzle (find-good-network '(1 2 3 4 5 6 7 8)))</langsyntaxhighlight>
 
{{out}}
Line 2,692 ⟶ 3,743:
\|/ \|/
5 6</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
This uses a Warnsdorff solver, which cuts down the number of tries by more than a factor of six over the brute force approach. This same solver is used in:
 
* [[Solve a Hidato puzzle#Raku|Solve a Hidato puzzle]]
* [[Solve a Hopido puzzle#Raku|Solve a Hopido puzzle]]
* [[Solve a Holy Knight's tour#Raku|Solve a Holy Knight's tour]]
* [[Solve a Numbrix puzzle#Raku|Solve a Numbrix puzzle]]
* [[Solve the no connection puzzle#Raku|Solve the no connection puzzle]]
 
The idiosyncratic adjacency diagram is dealt with by the simple expedient of bending the two vertical lines <tt>||</tt> into two bows <tt>)(</tt>, such that adjacency can be calculated simply as a distance of 2 or less.
<syntaxhighlight lang="raku" line>my @adjacent = gather -> $y, $x {
take [$y,$x] if abs($x|$y) > 2;
} for flat -5 .. 5 X -5 .. 5;
 
solveboard q:to/END/;
. _ . . _ .
. . . . . .
_ . _ 1 . _
. . . . . .
. _ . . _ .
END
sub solveboard($board) {
my $max = +$board.comb(/\w+/);
my $width = $max.chars;
 
my @grid;
my @known;
my @neigh;
my @degree;
@grid = $board.lines.map: -> $line {
[ $line.words.map: { /^_/ ?? 0 !! /^\./ ?? Rat !! $_ } ]
}
sub neighbors($y,$x --> List) {
eager gather for @adjacent {
my $y1 = $y + .[0];
my $x1 = $x + .[1];
take [$y1,$x1] if defined @grid[$y1][$x1];
}
}
 
for ^@grid -> $y {
for ^@grid[$y] -> $x {
if @grid[$y][$x] -> $v {
@known[$v] = [$y,$x];
}
if @grid[$y][$x].defined {
@neigh[$y][$x] = neighbors($y,$x);
@degree[$y][$x] = +@neigh[$y][$x];
}
}
}
print "\e[0H\e[0J";
 
my $tries = 0;
 
try_fill 1, @known[1];
 
sub try_fill($v, $coord [$y,$x] --> Bool) {
return True if $v > $max;
$tries++;
 
my $old = @grid[$y][$x];
 
return False if +$old and $old != $v;
return False if @known[$v] and @known[$v] !eqv $coord;
 
@grid[$y][$x] = $v; # conjecture grid value
 
print "\e[0H"; # show conjectured board
for @grid -> $r {
say do for @$r {
when Rat { ' ' x $width }
when 0 { '_' x $width }
default { .fmt("%{$width}d") }
}
}
 
 
my @neighbors = @neigh[$y][$x][];
 
my @degrees;
for @neighbors -> \n [$yy,$xx] {
my $d = --@degree[$yy][$xx]; # conjecture new degrees
push @degrees[$d], n; # and categorize by degree
}
 
for @degrees.grep(*.defined) -> @ties {
for @ties.reverse { # reverse works better for this hidato anyway
return True if try_fill $v + 1, $_;
}
}
 
for @neighbors -> [$yy,$xx] {
++@degree[$yy][$xx]; # undo degree conjectures
}
 
@grid[$y][$x] = $old; # undo grid value conjecture
return False;
}
say "$tries tries";
}</syntaxhighlight>
 
{{out}}
<pre> 4 3
2 8 1 7
6 5
18 tries</pre>
 
=={{header|Red}}==
===Basic version===
<syntaxhighlight lang="red">Red ["Solve the no connection puzzle"]
 
points: [a b c d e f g h]
; 'links' series will be scanned by pairs: [a c], [a d] etc.
links: [a c a d a e b d b e b f c d c g d e d g d h e f e g e h f h]
allpegs: [1 2 3 4 5 6 7 8]
 
; check if two points are connected (then game is lost) i.e.
; both are have a value (not zero) and absolute difference is 1
connected: func [x y] [all [
x * y <> 0
1 = absolute (x - y)
]]
; a list of points is valid if no connexion is found
isvalid: function [pegs [block!]] [
; assign pegs values to points, or 0 for remaining points
set points append/dup copy pegs 0 8
foreach [x y] links [if connected get x get y [return false]]
true
]
; recursively build a list of up to 8 valid points
check: function [pegs [block!]] [
if isvalid pegs [
rest: difference allpegs pegs
either empty? rest [
print rejoin ["Here is a solution: " pegs]
halt ; comment this line to get all solutions
][
foreach peg rest [check append copy pegs peg]
]
]
]
; start with and empty list
check []
</syntaxhighlight>
 
{{out}}
<pre>Here is a solution: 3 4 7 1 8 2 5 6
(halted)
</pre>
 
===With graphics===
<syntaxhighlight lang="red">Red [Needs: 'View]
 
points: [a b c d e f g h]
; 'links' series will be scanned by pairs: [a c], [a d] etc.
links: [a c a d a e b d b e b f c d c g d e d g d h e f e g e h f h]
allpegs: [1 2 3 4 5 6 7 8]
 
; check if two points are connected (then game is lost) i.e.
; both are have a value (not zero) and absolute difference is 1
connected: func [x y] [all [
x * y <> 0
1 = absolute (x - y)
]]
; a list of points is valid if no connexion is found
isvalid: function [pegs [block!]] [
; assign pegs values to points, or 0 for remaining points
set points append/dup copy pegs 0 8
foreach [x y] links [if connected get x get y [return false]]
true
]
; recursively build a list of up to 8 valid points
check: function [pegs [block!]] [
if isvalid pegs [
rest: difference allpegs pegs
either empty? rest [
vis points
][
foreach peg rest [check append copy pegs peg]
]
]
]
; view solution found
vis: function [points] [
pos: [100x0 200x0 0x100 100x100 200x100 300x100 100x200 200x200]
offs: 30x30
pos-of: function [x] [pick pos index? find points x]
val-at: function [p] [get pick points index? find pos p]
visu: layout [img: image 362x262 draw []]
foreach [x y] links [append img/draw reduce [
'line offs + pos-of x offs + pos-of y]]
append img/draw [fill-pen snow]
foreach p pos [append img/draw reduce [
'circle offs + p 15 'text 21x15 + p form val-at p]]
view/options visu [text: "Solution to the no-connection puzzle"]
]
; start with and empty list
check []
</syntaxhighlight>
 
{{out}}
[https://raw.githubusercontent.com/Palaing/redlib/master/games/images/noconnexion.png graphical output image]
 
=={{header|REXX}}==
===unannotated solutions===
<langsyntaxhighlight lang="rexx">/*REXX program solves the "no-connectionno─connection" puzzle (the puzzle has eight pegs). */
parse arg limit . /*number of solutions wanted.*/ /* ╔═══════════════════════════╗ */
if limit=='' | limit==".," then limit=1 1 /* ║ A B ║ */
/* ║ /│\ /│\ ║ */
@. = /* ║ / │ \/ │ \ ║ */
Line 2,708 ⟶ 3,971:
@.7 = 'G C D E' /* ║ \│/ \│/ ║ */
@.8 = 'H D E F' /* ║ G H ║ */
cnt=0 0 /* ╚═══════════════════════════╝ */
do pegs=1 while @.pegs\==''; _= word(@.pegs, 1)
subs= 0
do #=1 for words(@.pegs) -1 /*create list of node paths.*/
__= word(@.pegs, # + 1); if __>_ then iterate
subs= subs + 1; !._.subs= __
end /*#*/
!._.0=subs subs /*assign the number of the node paths. */
end /*pegs*/
pegs= pegs -1 1 /*the number of pegs to be seated. */
_=' ' _= ' ' /*_ is used for indenting the output.*/
do a=1 for pegs; if ?('A') then iterate
do b=1 for pegs; if ?('B') then iterate
do c=1 for pegs; if ?('C') then iterate
do d=1 for pegs; if ?('D') then iterate
do e=1 for pegs; if ?('E') then iterate
do f=1 for pegs; if ?('F') then iterate
do g=1 for pegs; if ?('G') then iterate
do h=1 for pegs; if ?('H') then iterate
say _ 'a='a _ '"b='"||b _ 'c='c _ '"d='"d _ 'e='e _ '"f='"f _ 'g='g _ '"h='"h
cnt= cnt + 1; if cnt==limit then leave a
end /*h*/
end /*g*/
end /*f*/
end /*e*/
end /*d*/
end /*c*/
end /*b*/
end /*a*/
say /*display a blank line to the terminal.*/
s= left('s', cnt\==1) /*handle the case of plurals (or not).*/
say 'found ' cnt " solution"s'.' /*display the number of solutions found*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
?: parse arg node; nn= value(node)
nH= nn+1
do cn=c2d('A') to c2d(node) - 1; if value( d2c(cn) )==nn then return 1
end /*cn*/ /* [↑] see if there any are duplicates.*/
nL= nn-1
do ch=1 for !.node.0 /* [↓] see if there any ¬= ±1 values.*/
$= !.node.ch; fn= value($) /*the node name and its current peg #.*/
if nL==fn | nH==fn then return 1 /*if ≡ ±1, then the node can't be used.*/
end /*ch*/ /* [↑] looking for suitable number. */
return 0 /*the subroutine arg value passed is OK.*/</langsyntaxhighlight>
'''{{out|output''' |text=&nbsp; when using the default input:}}
<pre>
a=3 b=4 c=7 d=1 e=8 f=2 g=5 h=6
Line 2,758 ⟶ 4,021:
found 1 solution.
</pre>
{{out|output|text=&nbsp; when using the default input of: &nbsp; &nbsp; <tt> 999 </tt>}}
 
'''output''' &nbsp; when using the input of: &nbsp; <tt> 999 </tt>
<pre>
a=3 b=4 c=7 d=1 e=8 f=2 g=5 h=6
Line 2,783 ⟶ 4,045:
===annotated solutions===
Usage note: &nbsp; if the &nbsp; '''limit''' &nbsp; (the 1<sup>st</sup> argument) &nbsp; is negative, a diagram (node graph) is shown.
<langsyntaxhighlight lang="rexx">/*REXX program solves the "no-connectionno─connection" puzzle (the puzzle has eight pegs). */
@abc= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
parse arg limit . /*number of solutions wanted.*/ /* ╔═══════════════════════════╗ */
if limit=='' | limit==".," then limit=1 1 /* ║ A B ║ */
oLimit= limit; limit= abs(limit) /* ║ /│\ /│\ ║ */
@. = /* ║ / │ \/ │ \ ║ */
@.1 = 'A C D E' /* ║ / │ /\ │ \ ║ */
Line 2,797 ⟶ 4,059:
@.7 = 'G C D E' /* ║ \│/ \│/ ║ */
@.8 = 'H D E F' /* ║ G H ║ */
cnt=0 0 /* ╚═══════════════════════════╝ */
do pegs=1 while @.pegs\==''; _= word(@.pegs, 1)
subs= 0
do #=1 for words(@.pegs) -1 /*create list of node paths.*/
__= word(@.pegs, #+1); if __>_ then iterate
subs= subs + 1; !._.subs= __
end /*#*/
!._.0=subs subs /*assign the number of the node paths. */
end /*pegs*/
pegs= pegs - 1 /*the number of pegs to be seated. */
_=' ' _= ' ' /*_ is used for indenting the output. */
do a=1 for pegs; if ?('A') then iterate
do b=1 for pegs; if ?('B') then iterate
do c=1 for pegs; if ?('C') then iterate
do d=1 for pegs; if ?('D') then iterate
do e=1 for pegs; if ?('E') then iterate
do f=1 for pegs; if ?('F') then iterate
do g=1 for pegs; if ?('G') then iterate
do h=1 for pegs; if ?('H') then iterate
call showNodes
cnt= cnt + 1; if cnt==limit then leave a
end /*h*/
end /*g*/
end /*f*/
end /*e*/
end /*d*/
end /*c*/
end /*b*/
end /*a*/
say /*display a blank line to the terminal.*/
s= left('s', cnt\==1) /*handle the case of plurals (or not).*/
say 'found ' cnt " solution"s'.' /*display the number of solutions found*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
?: parse arg node; nn= value(node)
nH= nn+1
do cn=c2d('A') to c2d(node)-1; if value( d2c(cn) )==nn then return 1
end /*cn*/ /* [↑] see if there're any duplicates.*/
nL= nn-1
do ch=1 for !.node.0 /* [↓] see if there any ¬= ±1 values.*/
$= !.node.ch; fn= value($) /*the node name and its current peg #.*/
if nL==fn | nH==fn then return 1 /*if ≡ ±1, then the node can't be used.*/
end /*ch*/ /* [↑] looking for suitable number. */
return 0 /*the subroutine arg value passed is OK*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
showNodes: _= left('', 5) /*_ is used for padding the output. */
show=0 0 /*indicates no graph has been found yet*/
do box=1 for sourceline() while oLimit<0 /*Negative? Then display the diagram. */
xw= sourceline(box) /*get a source line of this program. */
p2= lastpos('*', xw) /*the position of last asterisk.*/
p1= lastpos('*', xw, max(1, p2-1) ) /* " " " penultimate " */
if pos('╔', xw)\==0 then show=1 1 /*Have found the top-left box corner ? */
if \show then iterate /*Not found? Then skip this line. */
xb= substr(xw, p1+1, p2-p1-2) /*extract the "box" part of line. */
xt=xb xb /*get a working copy of the box. */
do jx=1 for pegs /*do a substitution for all the pegs. */
@= substr(@abc, jx, 1) /*get the name of the peg (A ──► Z). */
xt= translate(xt, value(@), @) /*substitute the peg name with a value.*/
end /*jx*/ /* [↑] graph is limited to 26 nodes.*/
say _ xb _ _ xt /*display one line of the graph. */
if pos('╝', xw)\==0 then return /*Is this last line of graph? Then stop*/
end /*box*/
say _ 'a='a _ '"b='"||b _ 'c='c _ '"d='"d _ ' e='e _ '"f='"f _ 'g='g _ '"h='"h
return</langsyntaxhighlight>
'''{{out|output'''|text=&nbsp; when using the inputdefault inputs of: &nbsp; &nbsp; <tt> -31 </tt>}}
<pre>
╔═══════════════════════════╗ ╔═══════════════════════════╗
Line 2,908 ⟶ 4,170:
=={{header|Ruby}}==
Be it Golden Frogs jumping on trancendental lilly pads, or a Knight on a board, or square pegs into round holes this is essentially a Hidato Like Problem, so I use [http://rosettacode.org/wiki/Solve_a_Hidato_puzzle#With_Warnsdorff HLPSolver]:
<langsyntaxhighlight lang="ruby">
# Solve No Connection Puzzle
#
Line 2,933 ⟶ 4,195:
g.board[H[0]][H[1]].adj = [A,B,C,G]
g.solve
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,948 ⟶ 4,210:
 
=={{header|Scala}}==
{{libheader|Scala sub-repositories}}
{{Out}}Best seen in running your browser either by [https://scalafiddle.io/sf/Ub2LEup/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/ZXGSJLFEQe21Frh4Vwp0WA Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">object NoConnection extends App {
 
private def links = Seq(
Line 2,972 ⟶ 4,235:
 
printResult(genRandom.dropWhile(!notSolved(links, _)).head)
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
{{tcllib|struct::list}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
package require struct::list
 
Line 3,019 ⟶ 4,283:
break
}
}</langsyntaxhighlight>
{{out}}
<pre> 3 4
Line 3,030 ⟶ 4,294:
\|/ \|/
5 6</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="wren">import "./dynamic" for Tuple
 
var Solution = Tuple.create("Solution", ["p", "tests", "swaps"])
 
// Holes A=0, B=1, …, H=7
// With connections:
var conn = "
A B
/|\\ /|\\
/ | X | \\
/ |/ \\| \\
C - D - E - F
\\ |\\ /| /
\\ | X | /
\\|/ \\|/
G H
"
 
var connections = [
[0, 2], [0, 3], [0, 4], // A to C, D, E
[1, 3], [1, 4], [1, 5], // B to D, E, F
[6, 2], [6, 3], [6, 4], // G to C, D, E
[7, 3], [7, 4], [7, 5], // H to D, E, F
[2, 3], [3, 4], [4, 5] // C-D, D-E, E-F
]
 
// 'isValid' checks if the pegs are a valid solution.
// If the absolute difference between any pair of connected pegs is
// greater than one it is a valid solution.
var isValid = Fn.new { |pegs|
for (c in connections) {
if ((pegs[c[0]] - pegs[c[1]]).abs <= 1) return false
}
return true
}
 
var swap = Fn.new { |pegs, i, j|
var tmp = pegs[i]
pegs[i] = pegs[j]
pegs[j] = tmp
}
 
// 'solve' is a simple recursive brute force solver,
// it stops at the first found solution.
// It returns the solution, the number of positions tested,
// and the number of pegs swapped.
var solve
solve = Fn.new {
var pegs = List.filled(8, 0)
for (i in 0..7) pegs[i] = i + 1
var tests = 0
var swaps = 0
 
var recurse // recursive closure
recurse = Fn.new { |i|
if (i >= pegs.count - 1) {
tests = tests + 1
return isValid.call(pegs)
}
// Try each remaining peg from pegs[i] onwards
for (j in i...pegs.count) {
swaps = swaps + 1
swap.call(pegs, i, j)
if (recurse.call(i + 1)) return true
swap.call(pegs, i, j)
}
return false
}
 
recurse.call(0)
return Solution.new(pegs, tests, swaps)
}
 
var pegsAsString = Fn.new { |pegs|
var ca = conn.toList
var i = 0
for (c in ca) {
if ("ABCDEFGH".contains(c)) ca[i] = String.fromByte(48 + pegs[c.bytes[0] - 65])
i = i + 1
}
return ca.join()
}
 
var s = solve.call()
System.print(pegsAsString.call(s.p))
System.print("Tested %(s.tests) positions and did %(s.swaps) swaps.")</syntaxhighlight>
 
{{out}}
<pre>
3 4
/|\ /|\
/ | X | \
/ |/ \| \
7 - 1 - 8 - 2
\ |\ /| /
\ | X | /
\|/ \|/
5 6
 
Tested 12094 positions and did 20782 swaps.
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes;
 
int Hole, Max, I;
Line 3,068 ⟶ 4,437:
until Hole = 8;
Text(0, Str);
]</langsyntaxhighlight>
 
{{out}}
Line 3,085 ⟶ 4,454:
=={{header|zkl}}==
{{trans|D}}
<langsyntaxhighlight lang="zkl">const PegA=0, PegB=1, PegC=2, PegD=3, PegE=4, PegF=5, PegG=6, PegH=7;
connections:=T(
T(PegA, PegC), T(PegA, PegD), T(PegA, PegE),
Line 3,111 ⟶ 4,480:
board.translate("ABCDEFGH",p.apply('+(1)).concat()).println();
break; // comment out to see all 16 solutions
}</langsyntaxhighlight>
The filter1 method stops on the first True, so it acts like a conditional or.
{{out}}
337

edits