Prime triangle: Difference between revisions

Added FreeBASIC
(Dialects of BASIC moved to the BASIC section.)
(Added FreeBASIC)
 
(9 intermediate revisions by 6 users not shown)
Line 129:
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
{{trans|Visual Basic .NET}}
<syntaxhighlight lang="vbnet">Dim Shared As Uinteger maxNumber = 20 ' Largest number we will consider.
Dim Shared As Uinteger prime(2 * maxNumber) ' prime sieve.
 
Function countArrangements(Byval n As Uinteger) As Uinteger
Dim As Uinteger i
If n < 2 Then ' No solutions for n < 2.
Return 0
Elseif n < 4 Then
' For 2 and 3. there is only 1 solution: 1, 2 and 1, 2, 3.
For i = 1 To n
Print Using "###"; i;
Next i
Print
Return 1
Else
' 4 or more - must find the solutions.
Dim As Boolean printSolution = True
Dim As Boolean used(n)
Dim As Uinteger number(n)
' The triangle row must have 1 in the leftmost and n in the rightmost elements.
' The numbers must alternate between even and odd in order for the sums to be prime.
For i = 0 To n - 1
number(i) = i Mod 2
Next i
used(1) = True
number(n) = n
used(n) = True
' Find the intervening numbers and count the solutions.
Dim As Uinteger count = 0
Dim As Uinteger p = 2
Do While p > 0
Dim As Uinteger p1 = number(p - 1)
Dim As Uinteger current = number(p)
Dim As Uinteger sgte = current + 2
Do While sgte < n Andalso (Not prime(p1 + sgte) Or used(sgte))
sgte += 2
Loop
If sgte >= n Then
sgte = 0
End If
If p = n - 1 Then
' We are at the final number before n.
' It must be the final even/odd number preceded by the final odd/even number.
If sgte <> 0 Then
' Possible solution.
If prime(sgte + n) Then
' Found a solution.
count += 1
If printSolution Then
For i = 1 To n - 2
Print Using "###"; number(i);
Next i
Print Using "###"; sgte; n
printSolution = False
End If
End If
sgte = 0
End If
' Backtrack for more solutions.
p -= 1
' There will be a further backtrack as next is 0 ( there could only be one possible number at p - 1 ).
End If
If sgte <> 0 Then
' have a/another number that can appear at p.
used(current) = False
used(sgte) = True
number(p) = sgte
' Haven't found all the intervening digits yet.
p += 1
Elseif p <= 2 Then
' No more solutions.
p = 0
Else
' Can't find a number for this position, backtrack.
used(number(p)) = False
number(p) = p Mod 2
p -= 1
End If
Loop
Return count
End If
End Function
 
Dim As Integer i, s, n
prime(2) = True
For i = 3 To Ubound(prime) Step 2
prime(i) = True
Next i
For i = 3 To Cint(Sqr(Ubound(prime))) Step 2
If prime(i) Then
For s = i * i To Ubound(prime) Step i + i
prime(s) = False
Next s
End If
Next i
 
Dim As Integer arrangements(maxNumber)
For n = 2 To Ubound(arrangements)
arrangements(n) = countArrangements(n)
Next n
For n = 2 To Ubound(arrangements)
Print arrangements(n);
Next n
Print
 
Sleep</syntaxhighlight>
{{out}}
<pre>Same as Visual Basic .NET entry.</pre>
 
==={{header|Visual Basic .NET}}===
{{Trans|ALGOL 68}}
Line 927 ⟶ 1,038:
end
else .count += 1
| .icount =as .$count - 1
| untilreduce range(.i$count >- 1; $n - 21; 2) #as $n-2i (.;
.arrang[.$i] as $ai
| if .canFollow[$ad-1][$ai-1]
then .countarrang as= swap(.arrang; $counti; $count-1)
| ptrs(.ires; as$n; $icount)
| .arrang = swap(.arrang; $i; $count-1)
| ptrs(.res; $n; $count) # updates .res but also .count and .i
| .count = $count # restore .count
| .i = $i # restore .i
| .arrang = swap(.arrang; $i; $count-1) # restore .arrang
else .
end )
| .i += 2
)
end;
 
Line 996 ⟶ 1,101:
[1,1,1,1,1,2,4,7,24,80,216,648,1304,3392,13808,59448,155464,480728,1588162]
</pre>
 
 
=={{header|Julia}}==
Line 1,170 ⟶ 1,274:
{1, 1, 1, 1, 1, 2, 4, 7, 24, 80, 216, 648, 1304, 3392, 13808, 59448, 155464, 480728, 1588162}</pre>
 
=={{header|Nim}}==
{{trans|C}}
<syntaxhighlight lang="Nim">import std/[monotimes, strutils, times]
 
const IsPrime = [false, false, true, true, false, true, false, true,
false, false, false, true, false, true, false, false,
false, true, false, true, false, false, false, true,
false, false, false, false, false, true, false, true,
false, false, false, false, false, true, false, false,
false, true, false, true, false, false, false, true,
false, false, false, false, false, true, false, false,
false, false, false, true, false, true, false, false]
 
type TriangleRow = openArray[Natural]
 
template isPrime(n: Natural): bool = IsPrime[n]
 
func primeTriangleRow(a: var TriangleRow): bool =
if a.len == 2:
return isPrime(a[0] + a[1])
for i in countup(1, a.len - 2, 2):
if isPrime(a[0] + a[i]):
swap a[i], a[1]
if primeTriangleRow(a.toOpenArray(1, a.high)):
return true
swap a[i], a[1]
 
func primeTriangleCount(a: var TriangleRow): Natural =
if a.len == 2:
if isPrime(a[0] + a[1]):
inc result
else:
for i in countup(1, a.len - 2, 2):
if isPrime(a[0] + a[i]):
swap a[i], a[1]
inc result, primeTriangleCount(a.toOpenArray(1, a.high))
swap a[i], a[1]
 
proc print(a: TriangleRow) =
if a.len == 0: return
for i, n in a:
if n > 0: stdout.write ' '
stdout.write align($n, 2)
stdout.write '\n'
 
let start = getMonoTime()
for n in 2..20:
var a = newSeq[Natural](n)
for i in 0..<n:
a[i] = i + 1
if a.primeTriangleRow:
print a
echo()
for n in 2..20:
var a = newSeq[Natural](n)
for i in 0..<n:
a[i] = i + 1
if n > 2: stdout.write " "
stdout.write a.primeTriangleCount
echo '\n'
 
echo "Elapsed time: ", (getMonoTime() - start).inMilliseconds, " ms"
</syntaxhighlight>
 
{{out}}
<pre> 1 2
1 2 3
1 2 3 4
1 4 3 2 5
1 4 3 2 5 6
1 4 3 2 5 6 7
1 2 3 4 7 6 5 8
1 2 3 4 7 6 5 8 9
1 2 3 4 7 6 5 8 9 10
1 2 3 4 7 10 9 8 5 6 11
1 2 3 4 7 10 9 8 5 6 11 12
1 2 3 4 7 6 5 12 11 8 9 10 13
1 2 3 4 7 6 13 10 9 8 11 12 5 14
1 2 3 4 7 6 13 10 9 8 11 12 5 14 15
1 2 3 4 7 6 5 12 11 8 15 14 9 10 13 16
1 2 3 4 7 6 5 12 11 8 9 10 13 16 15 14 17
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18 19
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 19 18 11 20
 
1 1 1 1 1 2 4 7 24 80 216 648 1304 3392 13808 59448 155464 480728 1588162
 
Elapsed time: 535 ms
</pre>
 
=={{header|Pascal}}==
==={{header|Free Pascal}}===
Simple backtracking.Precaltulated like [[Prime_triangle#Phix]] Can_Follow by checking for sum gets prime.
<syntaxhighlight lang="pascal">
program PrimePyramid;
{$IFDEF FPC}
{$MODE delphi}{$Optimization ON,ALL}{$CodeAlign proc=32}
{$IFEND}
const
MAX = 21;//max 8 different SumToPrime : array[0..MAX,0..7] of byte;
//MAX = 57;//max 16 different SumToPrime : array[0..MAX,0..15] of byte;
cMaxAlign32 = (((MAX-1)DIV 32)+1)*32-1;//MAX > 0
type
tPrimeRange = set of 0..127;
var
SetOfPrimes :tPrimeRange =[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,
53,59,61,67,71,73,79,83,89,97,101,103,107,
109,113,127];
 
SumToPrime : array[0..cMaxAlign32,0..7] of byte;
// SumToPrime : array[0..MAX,0..15] of byte;
SumToPrimeMaxIdx,
SumMaxIdx,
Solution,
FirstSolution : array[0..cMaxAlign32] of byte;
 
free : array[0..cMaxAlign32] of boolean;
 
maxused : integer;
digitcount,SolCount : integer;
 
procedure InitSumToPrime;
var
i,j,idx : integer;
begin
For i := 1 to MAX do
Begin
idx := 0;
For j := 1 to MAX do
If (i+j) in SetOfPrimes then
Begin
SumToPrime[i,idx] := j;
inc(idx);
end;
SumToPrimeMaxIdx[i] := idx;
end;
end;
 
procedure InitFree(maxused : integer);
var
i,j : Integer;
begin
For i := 0 to 1 do
Free[i] := false;
For i := 2 to maxused-1 do
Free[i] := true;
For i := maxused to MAX do
Free[i] := false;
// search maxidx of max neighour sum to prime
For i := 1 to maxused-1 do
begin
j := SumToPrimeMaxIdx[i]-1;
while SumToPrime[i,j] > maxused-1 do
j -= 1;
SumMaxIdx[i] := j+1;
end;
end;
 
procedure CountSolution(digit:integer);
begin
// check if maxused can follow
if (digit+maxused) in SetOfPrimes then
Begin
if solcount = 0 then
FirstSolution := Solution;
inc(solCount);
end;
end;
 
procedure checkDigits(digit:integer);
var
idx,nextDigit: integer;
begin
idx := 0;
repeat
nextDigit := SumToPrime[digit,idx];
if Free[nextdigit] then
Begin
Solution[digitcount] := nextDigit;
dec(digitcount);
IF digitcount = 0 then
CountSolution(nextDigit);
free[nextdigit]:= false;
checkDigits(nextdigit);
inc(digitcount);
free[nextdigit]:= true;
end;
inc(idx);
until idx >= SumMaxIdx[digit];
end;
 
var
i,j : integer;
Begin
InitSumToPrime;
writeln('number| count| first solution');
writeln(' 2| 1| 1 2');
For i := 3 to 20 do
Begin
maxused := i;
InitFree(i);
digitcount := i-2;
solCount := 0;
checkDigits(1);
write(i:4,'|',solcount:10,'| 1');
For j := i-2 downto 1 do
write( FirstSolution[j]:3);
writeln(i:3);
end;
end.
</syntaxhighlight>
{{out|@TIO.RUN}}
<pre>
number| count| first solution
2| 1| 1 2
3| 1| 1 2 3
4| 1| 1 2 3 4
5| 1| 1 4 3 2 5
6| 1| 1 4 3 2 5 6
7| 2| 1 4 3 2 5 6 7
8| 4| 1 2 3 4 7 6 5 8
9| 7| 1 2 3 4 7 6 5 8 9
10| 24| 1 2 3 4 7 6 5 8 9 10
11| 80| 1 2 3 4 7 10 9 8 5 6 11
12| 216| 1 2 3 4 7 10 9 8 5 6 11 12
13| 648| 1 2 3 4 7 6 5 12 11 8 9 10 13
14| 1304| 1 2 3 4 7 6 13 10 9 8 11 12 5 14
15| 3392| 1 2 3 4 7 6 13 10 9 8 11 12 5 14 15
16| 13808| 1 2 3 4 7 6 5 12 11 8 15 14 9 10 13 16
17| 59448| 1 2 3 4 7 6 5 12 11 8 9 10 13 16 15 14 17
18| 155464| 1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18
19| 480728| 1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18 19
20| 1588162| 1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 19 18 11 20
Real time: 1.827 s User time: 1.794 s Sys. time: 0.021 s CPU share: 99.36 %
@home: real 0m0,679s</pre>
=={{header|Perl}}==
{{trans|Raku}}
Line 1,308 ⟶ 1,647:
1 1 1 1 1 2 4 7 24 80 216 648 1304 3392 13808 59448 155464 480728 1588162
"9.7s"
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">
 
from numpy import array
# for Rosetta Code by MG - 20230312
def is_prime(n: int) -> bool:
assert n < 64
return ((1 << n) & 0x28208a20a08a28ac) != 0
 
def prime_triangle_row(a: array, start: int, length: int) -> bool:
if length == 2:
return is_prime(a[0] + a[1])
for i in range(1, length - 1, 1):
if is_prime(a[start] + a[start + i]):
a[start + i], a[start + 1] = a[start + 1], a[start + i]
if prime_triangle_row(a, start + 1, length - 1):
return True
a[start + i], a[start + 1] = a[start + 1], a[start + i]
return False
 
def prime_triangle_count(a: array, start: int, length: int) -> int:
count: int = 0
if length == 2:
if is_prime(a[start] + a[start + 1]):
count += 1
else:
for i in range(1, length - 1, 1):
if is_prime(a[start] + a[start + i]):
a[start + i], a[start + 1] = a[start + 1], a[start + i]
count += prime_triangle_count(a, start + 1, length - 1)
a[start + i], a[start + 1] = a[start + 1], a[start + i]
return count
 
def print_row(a: array):
if a == []:
return
print("%2d"% a[0], end=" ")
for x in a[1:]:
print("%2d"% x, end=" ")
print()
 
for n in range(2, 21):
tr: array = [_ for _ in range(1, n + 1)]
if prime_triangle_row(tr, 0, n):
print_row(tr)
print()
for n in range(2, 21):
tr: array = [_ for _ in range(1, n + 1)]
if n > 2:
print(" ", end="")
print(prime_triangle_count(tr, 0, n), end="")
print()
</syntaxhighlight>
 
{{out}}
<pre>
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 4 3 2 5 6
1 4 3 2 5 6 7
1 2 3 4 7 6 5 8
1 2 3 4 7 6 5 8 9
1 2 3 4 7 6 5 8 9 10
1 2 3 4 7 6 5 8 9 10 11
1 2 3 4 7 10 9 8 5 6 11 12
1 2 3 4 7 6 5 12 11 8 9 10 13
1 2 3 4 7 6 5 12 11 8 9 10 13 14
1 2 3 4 7 6 13 10 9 8 11 12 5 14 15
1 2 3 4 7 6 5 12 11 8 15 14 9 10 13 16
1 2 3 4 7 6 5 12 11 8 9 10 13 16 15 14 17
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18 19
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 12 11 18 19 20
 
1 1 1 1 1 2 4 7 24 80 216 648 1304 3392 13808 59448 155464 480728 1588162
</pre>
 
Line 1,569 ⟶ 1,987:
{{libheader|Wren-fmt}}
Takes around 18.7 seconds which is fine for Wren.
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var canFollow = []
2,130

edits