Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,67 @@
PROGRAM HERON
DIM LISTA%[600,4]
PROCEDURE GCD(J%,K%->MCD%)
WHILE J%<>K% DO
IF J%>K% THEN
J%=J%-K%
ELSE
K%=K%-J%
END IF
END WHILE
MCD%=J%
END PROCEDURE
BEGIN
PRINT(CHR$(12);) !CLS
FOR C%=1 TO 200 DO
FOR B%=1 TO C% DO
FOR A%=1 TO B% DO
S#=(A%+B%+C%)/2#
AREA#=S#*(S#-A%)*(S#-B%)*(S#-C%)
IF AREA#>0 THEN
AREA#=SQR(AREA#)
IF AREA#=INT(AREA#) THEN
GCD(B%,C%->RES%)
GCD(A%,RES%->RES%)
IF RES%=1 THEN
COUNT%=COUNT%+1
LISTA%[COUNT%,0]=A% LISTA%[COUNT%,1]=B% LISTA%[COUNT%,2]=C%
LISTA%[COUNT%,3]=2*S# LISTA%[COUNT%,4]=AREA#
END IF
END IF
END IF
END FOR
END FOR
END FOR
PRINT("Number of triangles:";COUNT%)
! sorting array
FLIPS%=TRUE
WHILE FLIPS% DO
FLIPS%=FALSE
FOR I%=1 TO COUNT%-1 DO
IF LISTA%[I%,4]>LISTA%[I%+1,4] THEN
FOR K%=0 TO 4 DO
SWAP(LISTA%[I%,K%],LISTA%[I%+1,K%])
END FOR
FLIPS%=TRUE
END IF
END FOR
END WHILE
! first ten
FOR I%=1 TO 10 DO
PRINT(#1,LISTA%[I%,0],LISTA%[I%,1],LISTA%[I%,2],LISTA%[I%,3],LISTA%[I%,4])
END FOR
PRINT
! triangle with area=210
FOR I%=1 TO COUNT% DO
IF LISTA%[I%,4]=210 THEN
PRINT(LISTA%[I%,0],LISTA%[I%,1],LISTA%[I%,2],LISTA%[I%,3],LISTA%[I%,4])
END IF
END FOR
END PROGRAM

View file

@ -0,0 +1,25 @@
;; returns quintuple (A s a b c)
;; or #f if not hero
(define (hero a b c (s 0) (A 0))
(when
(= 1 (gcd a b c))
(set! s (// (+ a b c) 2))
(set! A (* s (- s a)(- s b)(- s c)))
(when (square? A)
(list (sqrt A) (* s 2) c b a))))
;; all heroes a,b,c < sidemax
;; sorted by A|s|c & a <=b <= c
(define (heroes (sidemax 201))
(list-sort/fields 3
(for*/list ((a (in-range 1 sidemax)) (b (in-range a sidemax)) (c (in-range b sidemax)))
#:continue (<= (+ a b) c) ;; triangle inequality must hold !! cut search
#:continue (not (hero a b c))
(hero a b c))))
(define (print-hero h)
(printf "A: %6d s: %6d sides: %dx%dx%d"
(list-ref h 0) (list-ref h 1)
(list-ref h 2)(list-ref h 3) (list-ref h 4)))
(define (print-laurels H)
(writeln '🌿🌿 (length H) 'heroes '🌿🌿))

View file

@ -0,0 +1,147 @@
' version 02-05-2016
' compile with: fbc -s console
#Macro header
Print
Print " a b c s area"
Print "-----------------------------------"
#EndMacro
Type triangle
Dim As UInteger a
Dim As UInteger b
Dim As UInteger c
Dim As UInteger s
Dim As UInteger area
End Type
Function gcd(x As UInteger, y As UInteger) As UInteger
Dim As UInteger t
While y
t = y
y = x Mod y
x = t
Wend
Return x
End Function
Function Heronian_triangles(a_max As UInteger, b_max As UInteger, _
c_max As UInteger, result() As triangle) As UInteger
Dim As UInteger a, b, c
Dim As UInteger s, sqroot, total, temp
For a = 1 To a_max
For b = a To b_max
' make sure that a + b + c is even
For c = b + (a And 1) To c_max Step 2
' to form a triangle a + b must be greater then c
If (a + b) <= c Then Exit For
' check if a, b and c have a common divisor
If (gcd(c, b) <> 1 And gcd(c, a) <> 1) Then
Continue For
End If
s = (a + b + c) \ 2
temp = s * (s - a) * (s - b) * (s - c)
sqroot = Sqr(temp)
If (sqroot * sqroot) = temp Then
total += 1
With result(total)
.a = a
.b = b
.c = c
.s = s
.area = sqroot
End With
End If
Next
Next
Next
Return total
End Function
Sub sort_tri(result() As triangle, total As UInteger)
' shell sort
' sort order: area, s, c
Dim As UInteger x, y, inc, done
inc = total
Do
inc = IIf(inc > 1, inc \ 2, 1)
Do
done = 0
For x = 1 To total - inc
y = x + inc
If result(x).area > result(y).area Then
Swap result(x), result(y)
done = 1
Else
If result(x).area = result(y).area Then
If result(x).s > result(y).s Then
Swap result(x), result(y)
done = 1
Else
If result(x).s = result(y).s Then
If result(x).c > result(y).c Then
Swap result(x), result(y)
done = 1
End If
End If
End If
End If
End If
Next
Loop Until done = 0
Loop Until inc = 1
End Sub
' ------=< MAIN >=------
ReDim result(1 To 1000) As triangle
Dim As UInteger x, y, total
total = Heronian_triangles(200, 200, 200, result() )
' trim the array by removing empty entries
ReDim Preserve result(1 To total ) As triangle
sort_tri(result(), total)
Print "There are ";total;" Heronian triangles with sides <= 200"
Print
Print "First ten sorted entries"
header ' print header
For x = 1 To IIf(total > 9, 10, total)
With result(x)
Print Using " #####"; .a; .b; .c; .s; .area
End With
Next
Print
Print
Print "Entries with a area = 210"
header ' print header
For x = 1 To UBound(result)
With result(x)
If .area = 210 Then
Print Using " #####"; .a; .b; .c; .s; .area
End If
End With
Next
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End

View file

@ -0,0 +1,86 @@
include "ConsoleWindow"
// Set width of tabs
def tab 10
local fn gcd( a as long, b as long )
dim as long result
if ( b != 0 )
result = fn gcd( b, a mod b)
else
result = abs(a)
end if
end fn = result
begin globals
dim as long triangleInfo( 600, 4 )
end globals
local fn CalculateHeronianTriangles( numberToCheck as long ) as long
dim as long c, b, a, result, count : count = 0
dim as double s, area
for c = 1 to numberToCheck
for b = 1 to c
for a = 1 to b
s = ( a + b + c ) / 2
area = s * ( s - a ) * ( s - b ) * ( s - c )
if area > 0
area = sqr( area )
if area = int( area )
result = fn gcd( b, c )
result = fn gcd( a, result )
if result == 1
count++
triangleInfo( count, 0 ) = a
triangleInfo( count, 1 ) = b
triangleInfo( count, 2 ) = c
triangleInfo( count, 3 ) = 2 * s
triangleInfo( count, 4 ) = area
end if
end if
end if
next
next
next
end fn = count
dim as long i, k, count
count = fn CalculateHeronianTriangles( 200 )
print
print "Number of triangles:"; count
print
print "---------------------------------------------"
print "Side A", "Side B", "Side C", "Perimeter", "Area"
print "---------------------------------------------"
// Sort array
dim as Boolean flips : flips = _true
while ( flips = _true )
flips = _false
for i = 1 to count - 1
if triangleInfo( i, 4 ) > triangleInfo( i + 1, 4 )
for k = 0 to 4
swap triangleInfo( i, k ), triangleInfo( i + 1, k )
next
flips = _true
end if
next
wend
// Find first 10 heronian triangles
for i = 1 to 10
print triangleInfo( i, 0 ), triangleInfo( i, 1 ), triangleInfo( i, 2 ), triangleInfo( i, 3 ), triangleInfo( i, 4 )
next
print
print "Triangles with an area of 210:"
print
// Search for triangle with area of 210
for i = 1 to count
if triangleInfo( i, 4 ) == 210
print triangleInfo( i, 0 ), triangleInfo( i, 1 ), triangleInfo( i, 2 ), triangleInfo( i, 3 ), triangleInfo( i, 4 )
end if
next

View file

@ -0,0 +1,60 @@
import math, algorithm, strfmt, sequtils
type
HeronianTriangle = tuple
a: int
b: int
c: int
s: float
A: int
proc `$` (t: HeronianTriangle): string =
fmt("{:3d}, {:3d}, {:3d}\t{:7.3f}\t{:3d}", t.a, t.b, t.c, t.s, t.A)
proc hero(a:int, b:int, c:int): tuple[s, A: float] =
let s: float = (a + b + c) / 2
result = (s, sqrt( s * (s - float(a)) * (s - float(b)) * (s - float(c)) ))
proc isHeronianTriangle(x: float): bool = ceil(x) == x and x.toInt > 0
proc gcd(x: int, y: int): int =
var
(dividend, divisor) = if x > y: (x, y) else: (y, x)
remainder = dividend mod divisor
while remainder != 0:
dividend = divisor
divisor = remainder
remainder = dividend mod divisor
result = divisor
var list = newSeq[HeronianTriangle]()
const max = 200
for c in 1..max:
for b in 1..c:
for a in 1..b:
let (s, A) = hero(a, b, c)
if isHeronianTriangle(A) and gcd(a, gcd(b, c)) == 1:
let t:HeronianTriangle = (a, b, c, s, A.toInt)
list.add(t)
echo "Numbers of Heronian Triangle : ", list.len
list.sort do (x, y: HeronianTriangle) -> int:
result = cmp(x.A, y.A)
if result == 0:
result = cmp(x.s, y.s)
if result == 0:
result = cmp(max(x.a, x.b, x.c), max(y.a, y.b, y.c))
echo "Ten first Heronian triangle ordered : "
echo "Sides Perimeter Area"
for t in list[0 .. <10]:
echo t
echo "Heronian triangle ordered with Area 210 : "
echo "Sides Perimeter Area"
for t in list.filter(proc (x: HeronianTriangle): bool = x.A == 210):
echo t

View file

@ -0,0 +1,38 @@
function heroArea(integer a, b, c)
atom s = (a+b+c)/2
return sqrt(s*(s-a)*(s-b)*(s-c))
end function
function hero(atom h)
return remainder(h,1)=0 and h>0
end function
sequence list = {}
integer tries = 0
for a=1 to 200 do
for b=1 to a do
for c=1 to b do
tries += 1
if gcd({a,b,c})=1 then
atom hArea = heroArea(a,b,c)
if hero(hArea) then
list = append(list,{hArea,a+b+c,a,b,c})
end if
end if
end for
end for
end for
list = sort(list)
printf(1,"Primitive Heronian triangles with sides up to 200: %d (of %,d tested)\n\n",{length(list),tries})
printf(1,"First 10 ordered by area/perimeter/sides:\n")
printf(1,"area perimeter sides")
for i=1 to 10 do
printf(1,"\n%4d %3d %dx%dx%d",list[i])
end for
printf(1,"\n\narea = 210:\n")
printf(1,"area perimeter sides")
for i=1 to length(list) do
if list[i][1]=210 then
printf(1,"\n%4d %3d %dx%dx%d",list[i])
end if
end for

View file

@ -0,0 +1,29 @@
size = 20
number = 0
see " a b c area perimeter" + nl
for i = 1 to size
for j = i + 1 to size
for k = j + 1 to size
perim = (i + j + k) / 2
heronian = sqrt(perim*(perim - i)*(perim - j)*(perim-k))
if heronian = floor(heronian)
if gcd(gcd(i, j),k) = 1
if i + j > k and i + k > j and j + k > i
number += 1
if number <= 20
if len(string(i)) = 1 stri = " " + string(i) else stri = string(i) ok
if len(string(j)) = 1 strj = " " + string(j) else strj = string(j) ok
if len(string(k)) = 1 strk = " " + string(k) else strk = string(k) ok
if len(string(heronian)) = 1 her = " " + string(heronian) else her = string(heronian) ok
see stri + " "+ strj + " "+ strk + " " + her + " " + perim*2 + nl ok ok ok ok
next
next
next
func gcd gcd, b
while b
c = gcd
gcd = b
b = c % b
end
return gcd

View file

@ -0,0 +1,48 @@
class Triangle(a, b, c) {
has (sides, perimeter, area)
method init {
sides = [a, b, c].sort
perimeter = [a, b, c].sum
var s = (perimeter / 2)
area = sqrt(s * (s - a) * (s - b) * (s - c))
}
method is_valid(a,b,c) {
var (short, middle, long) = [a, b, c].sort...;
(short + middle) > long
}
method is_heronian {
area == area.to_i
}
method <=>(other) {
[area, perimeter, sides] <=> [other.area, other.perimeter, other.sides]
}
method to_s {
"%-11s%6d%8.1f" % (sides.join('x'), perimeter, area)
}
}
var (max, area) = (200, 210)
var prim_triangles = []
for a in (1..max) {
for b in (a..max) {
for c in (b..max) {
next if (Math.gcd(a, b, c) > 1)
prim_triangles << Triangle(a, b, c) if Triangle.is_valid(a, b, c)
}
}
}
var sorted = prim_triangles.grep{.is_heronian}.sort
say "Primitive heronian triangles with sides upto #{max}: #{sorted.size}"
say "\nsides perim. area"
say sorted.first(10).join("\n")
say "\nTriangles with an area of: #{area}"
sorted.each{|tr| say tr if (tr.area == area)}

View file

@ -0,0 +1,54 @@
import Foundation
typealias PrimitiveHeronianTriangle = (s1:Int, s2:Int, s3:Int, p:Int, a:Int)
func heronianArea(side1 s1:Int, side2 s2:Int, side3 s3:Int) -> Int? {
let d1 = Double(s1)
let d2 = Double(s2)
let d3 = Double(s3)
let s = (d1 + d2 + d3) / 2.0
let a = sqrt(s * (s - d1) * (s - d2) * (s - d3))
if a % 1 != 0 || a <= 0 {
return nil
} else {
return Int(a)
}
}
func gcd(a:Int, b:Int) -> Int {
if b != 0 {
return gcd(b, a % b)
} else {
return abs(a)
}
}
var triangles = [PrimitiveHeronianTriangle]()
for s1 in 1...200 {
for s2 in 1...s1 {
for s3 in 1...s2 {
if gcd(s1, gcd(s2, s3)) == 1, let a = heronianArea(side1: s1, side2: s2, side3: s3) {
triangles.append((s3, s2, s1, s1 + s2 + s3, a))
}
}
}
}
sort(&triangles) {t1, t2 in
if t1.a < t2.a || t1.a == t2.a && t1.p < t2.p {
return true
} else {
return false
}
}
println("Number of primitive Heronian triangles with sides up to 200: \(triangles.count)\n")
println("First ten sorted by area, then perimeter, then maximum side:\n")
println("Sides\t\t\tPerimeter\tArea")
for t in triangles[0...9] {
println("\(t.s1)\t\(t.s2)\t\(t.s3)\t\t\(t.p)\t\t\(t.a)")
}

View file

@ -0,0 +1,40 @@
# input should be an array of the lengths of the sides
def hero:
(add/2) as $s
| ($s*($s - .[0])*($s - .[1])*($s - .[2])) as $a2
| if $a2 > 0 then ($a2 | sqrt) else 0 end;
def is_heronian:
hero as $h
| $h > 0 and ($h|floor) == $h;
def gcd3(x; y; z):
# subfunction expects [a,b] as input
def rgcd:
if .[1] == 0 then .[0]
else [.[1], .[0] % .[1]] | rgcd
end;
[ ([x,y] | rgcd), z ] | rgcd;
def task(maxside):
def rjust(width): tostring | " " * (width - length) + .;
[ range(1; maxside+1) as $c
| range(1; $c+1) as $b
| range(1; $b+1) as $a
| if ($a + $b) > $c and gcd3($a; $b; $c) == 1
then [$a,$b,$c] | if is_heronian then . else empty end
else empty
end ]
# sort by increasing area, perimeter, then sides
| sort_by( [ hero, add, .[2] ] )
| "The number of primitive Heronian triangles with sides up to \(maxside): \(length)",
"The first ten when ordered by increasing area, then perimeter, then maximum sides:",
" perimeter area",
(.[0:10][] | "\(rjust(11)) \(add | rjust(3)) \(hero | rjust(4))" ),
"All those with area 210, ordered as previously:",
" perimeter area",
( .[] | select( hero == 210 ) | "\(rjust(11)) \(add|rjust(3)) \(hero|rjust(4))" ) ;
task(200)

View file

@ -0,0 +1,22 @@
$ time jq -n -r -f heronian.jq
The number of primitive Heronian triangles with sides up to 200: 517
The first ten when ordered by increasing area, then perimeter, then maximum sides:
perimeter area
[3,4,5] 12 6
[5,5,6] 16 12
[5,5,8] 18 12
[4,13,15] 32 24
[5,12,13] 30 30
[9,10,17] 36 36
[3,25,26] 54 36
[7,15,20] 42 42
[10,13,13] 36 60
[8,15,17] 40 60
All those with area 210, ordered as previously:
perimeter area
[17,25,28] 70 210
[20,21,29] 70 210
[12,35,37] 84 210
[17,28,39] 84 210
[7,65,68] 140 210
[3,148,149] 300 210