Discussion:
The hardest euler problem.
(too old to reply)
a***@spenarnc.xs4all.nl
2024-06-10 17:24:31 UTC
Permalink
Remember the year 2008? There was a post with the same title.

At the time the hardest euler problem was 177, at level 80%.
I have solved several level 100% problems but this problem
evaded me, till now!

https://projecteuler.net/problem=177
Integer Angled Quadrilaterals.
Let be a convex quadrilateral, with diagonals. At each vertex the
diagonal makes an angle with each of the two sides, creating eight
corner angles that must be an integral measured in degrees.
Find the number of such quadrilaterals.
Not only must you find how to generate them, but I kept apparently
generating duplicates. At last I generated all of them, and removed
duplicates and succeeded.

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat purring. - the Wise from Antrim -
minforth
2024-06-13 05:54:29 UTC
Permalink
Euler #177 is a fairly straightforward exercise in CLP(FD)
programming. To emulate it in Forth is a challenge in itself,
not unlike the famous Magic Hexagon solver.

The CLP(FD) constraints are the angle sums. I quickly hacked
something together in BProlog to find the first solution.
There are many more... :

:- initialization(main).

main :-

Angles = [ % angles counter-clockwise
A1,A2, B1,B2, C1,C2, D1,D2 ],
Angles :: 1..179,

euler(Angles), % read puzzle

% avoid duplications and square
A1+A2 #< 90,
% angle sums
A2+B1+B2+C1 #= 180,
B2+C1+C2+D1 #= 180,
A1+A2+B1+D2 #= 180,
A1+C2+D1+D2 #= 180,
% central symmetry
A2+B1 #= C2+D1,
B2+C1 #= A1+D2,
% rectangle
A1+A2+B1+B2+C1+C2+D1+D2 #= 360,

labeling(Angles),
writeln(Angles).

euler([_,_, _,_, _,_, _,_]).
a***@spenarnc.xs4all.nl
2024-06-13 19:48:09 UTC
Permalink
Post by minforth
Euler #177 is a fairly straightforward exercise in CLP(FD)
programming. To emulate it in Forth is a challenge in itself,
not unlike the famous Magic Hexagon solver.
The CLP(FD) constraints are the angle sums. I quickly hacked
something together in BProlog to find the first solution.
:- initialization(main).
main :-
Angles = [ % angles counter-clockwise
A1,A2, B1,B2, C1,C2, D1,D2 ],
Angles :: 1..179,
euler(Angles), % read puzzle
% avoid duplications and square
A1+A2 #< 90,
% angle sums
A2+B1+B2+C1 #= 180,
B2+C1+C2+D1 #= 180,
A1+A2+B1+D2 #= 180,
A1+C2+D1+D2 #= 180,
% central symmetry
A2+B1 #= C2+D1,
B2+C1 #= A1+D2,
% rectangle
A1+A2+B1+B2+C1+C2+D1+D2 #= 360,
labeling(Angles),
writeln(Angles).
euler([_,_, _,_, _,_, _,_]).
You are quite confused.
You don't even understand that goniometrics is involved
in this problem.

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat purring. - the Wise from Antrim -
minforth
2024-06-14 07:45:50 UTC
Permalink
Post by a***@spenarnc.xs4all.nl
You are quite confused.
You don't even understand that goniometrics is involved
in this problem.
I take that as a friendly hint. But you are deducting
really too much from a few lines of Prolog. ;-)

Groetjes Andreas
Ahmed
2024-06-13 11:59:20 UTC
Permalink
Hi,
My attempt to solve this problem.

\ the code begins here

\ Euler_177
\ Example:
\ DAC = 20, BAC = 60, ABD = 50, CBD = 30,
\ BCA = 40, DCA = 30, CDB = 80, ADB = 50


\ ---------------------------
0 value vals_num
20 value vals_num_max


0 value nloops_prec
0 value nloops
0 value constraint_num
30 value max_num_constraints
create loop_loc max_num_constraints allot
loop_loc max_num_constraints erase

0 value min_val
0 value max_val

: .-- nloops 1+ to nloops postpone do postpone i ; immediate
: .?, postpone min_val postpone max_val postpone 1+ postpone within
postpone if ; immediate
: --> postpone to constraint_num 1+ to constraint_num nloops nloops_prec
<> if 1 loop_loc constraint_num + c! nloops to nloops_prec then ;
immediate
: --- ; immediate
: _begin_ ; immediate
: .| postpone then loop_loc constraint_num + c@ if postpone loop then
constraint_num 1- to constraint_num ; immediate
: _end_ ; immediate
: =, postpone = postpone if ; immediate
: =| postpone then ; immediate
: values dup 1+ to vals_num 0 ?do 0 value loop ;
\ --------------------------


\ euler 177
8 values DAC BAC ABD CBD BCA DCA CDB ADB
1 to min_val
179 to max_val

0 value count_max

0e fvalue aa
0e fvalue bb
0e fvalue cc
0e fvalue dd
0e fvalue ee
0e fvalue ff
0e fvalue gg
0e fvalue hh

0e fvalue tab
0e fvalue tcd
0e fvalue tb
0e fvalue tc

0e fvalue cx
0e fvalue cy
0e fvalue dx
0e fvalue dy

0e fvalue dcx
0e fvalue dcy

0e fvalue |ac|
0e fvalue |dc|
0e fvalue |bd|


1500000 value result_size_max
8 value result_angles
result_size_max result_angles * value size

create result size allot
result size erase

: th_result result_angles * result + + ;
: th_result! rot th_result c! ;
: th_result@ swap th_result c@ ;

: result_DAC! DAC 0 th_result! ;
: result_BAC! BAC 1 th_result! ;
: result_ABD! ABD 2 th_result! ;
: result_CBD! CBD 3 th_result! ;
: result_BCA! BCA 4 th_result! ;
: result_DCA! DCA 5 th_result! ;
: result_CDB! CDB 6 th_result! ;
: result_ADB! ADB 7 th_result! ;


: update_result
count_max result_DAC! count_max result_BAC! count_max result_ABD!
count_max result_CBD!
count_max result_BCA! count_max result_DCA! count_max result_CDB!
count_max result_ADB!
;

: count_max++ count_max 1+ to count_max ;

\ The solution is 129325, found in
https://github.com/lucky-bai/projecteuler-solutions/blob/master/Solutions.md

1e-5 fvalue tolerance_integer
2.013e-6 fvalue tolerance_equal

: approx_integer f- fabs tolerance_integer f< ;
: approx_equal f- fabs tolerance_equal f< ;

: deg>rad s>f pi f* 180e f/ ;
: approx_good fdup fround fswap fover approx_integer ;
: rad>deg 180e f* pi f/ fround approx_good if f>s else fdrop -1 then ;

: DCA_calc
DAC deg>rad to aa
BAC deg>rad to bb
ABD deg>rad to cc
CBD deg>rad to dd

aa bb f+ ftan to tab
cc dd f+ ftan to tcd
bb ftan to tb
cc ftan to tc

tcd tcd tb f+ f/ to cx
tb cx f* to cy

tc tc tab f+ f/ to dx
tab dx f* to dy

cx dx f- to dcx
cy dy f- to dcy

cx fdup f* cy fdup f* f+ fsqrt to |ac|
dx 1e f- fdup f* dy fdup f* f+ fsqrt to |bd|

dcx fdup f* dcy fdup f* f+ fsqrt to |dc|

cx dcx f* cy dcy f* f+ |ac| |dc| f* f/ facos rad>deg
;


: solve
0 to count_max
_begin_
180 1 .-- --> DAC DAC .?,
180 1 .-- --> BAC BAC .?,
DAC BAC + 180 <= true =,
180 1 .-- --> ABD ABD .?,
180 DAC - BAC - ABD - --- --> ADB ADB .?,
180 1 .-- --> CBD CBD .?,
ABD CBD + 180 <= true =,
180 BAC - ABD - CBD - --- --> BCA BCA .?,

DCA_calc --- --> DCA DCA .?,

DCA BCA + 180 <= true =,
180 CBD - BCA - DCA - --- --> CDB CDB .?,
ADB CDB + 180 <= true =,
DAC BAC + ABD CBD + BCA DCA + CDB ADB +
+ + + 360 =,

ADB CDB + deg>rad fsin |dc| f*
DAC deg>rad fsin |ac| f* approx_equal true =,

BCA DCA + deg>rad fsin |dc| f*
CBD deg>rad fsin |bd| f* approx_equal true =,

count_max++
update_result

=| =| =| =| .| =| .| .| =| .| .| .| =| .| .|
_end_
;

: .result 8 0 do dup i th_result@ 4 .r loop drop ;
: .result_range 2dup < if 1+ swap then do cr i 7 .r ." : " i .result
loop ;

\ for a quadrilateral, there are 8 similars
\ 2 by mirror, and 4 by rotation symetries so 4*2 = 8

: .solution count_max 8 / . ;

: Euler_177 solve .solution ;

\ the code ends here

The result depends on the tolerance used for approximating angles in
integers and verifying the approximate equality

To get the solution 129325 (found in
https://github.com/lucky-bai/projecteuler-solutions/blob/master/Solutions.md)
the tolerances are 1e-5 for angles, and 2.013e-6 for approximate
equality.

To see the solutions: 1000 1100 .result_range will display the solutions
n° 1000 to n°1100 for example.
The solutions are saved in the array: result.

The code is in gforth and is executed with: gforth -m 1G in command line
(to get sufficient memory in dictionary to save the solutions)

We can use just gforth (without -m 1G in command line), but we must
comment out the creation of the array result and the words correspondant
to it like: update_result, .result, .result_range. we must also comment
out the word update_result in the word solve.

The execution time is about 75 seconds on my laptop with gforth.

Ahmed
Ahmed
2024-06-13 12:05:20 UTC
Permalink
To get the solution type:

In command line: gforth -m 1G euler_177.fs, where euler_177.fs is the
name where the precedent code is saved.
Then, in gforth prompt, type: euler_177

Ahmed
Ahmed
2024-06-13 16:52:34 UTC
Permalink
A new version with some modification (without saving the results
(angles)) and no need for tolerance_angle.
No need for -m 1G in command line (with gforth).
Same timing and same result.


\ Here, the code begins

\ Euler_177
\ Example:
\ DAC = 20, BAC = 60, ABD = 50, CBD = 30,
\ BCA = 40, DCA = 30, CDB = 80, ADB = 50


\ ---------------------------
0 value vals_num
20 value vals_num_max


0 value nloops_prec
0 value nloops
0 value constraint_num
30 value max_num_constraints
create loop_loc max_num_constraints allot
loop_loc max_num_constraints erase

0 value min_val
0 value max_val

: .-- nloops 1+ to nloops postpone do postpone i ; immediate
: .?, postpone min_val postpone max_val postpone 1+ postpone within
postpone if ; immediate
: --> postpone to constraint_num 1+ to constraint_num nloops nloops_prec
<> if 1 loop_loc constraint_num + c! nloops to nloops_prec then ;
immediate
: --- ; immediate
: _begin_ ; immediate
: .| postpone then loop_loc constraint_num + c@ if postpone loop then
constraint_num 1- to constraint_num ; immediate
: _end_ ; immediate
: =, postpone = postpone if ; immediate
: =| postpone then ; immediate
: values dup 1+ to vals_num 0 ?do 0 value loop ;
\ --------------------------


\ euler 177
8 values DAC BAC ABD CBD BCA DCA CDB ADB
1 to min_val
179 to max_val

0 value count_max

0e fvalue aa
0e fvalue bb
0e fvalue cc
0e fvalue dd
0e fvalue ee
0e fvalue ff
0e fvalue gg
0e fvalue hh

0e fvalue tab
0e fvalue tcd
0e fvalue tb
0e fvalue tc

0e fvalue cx
0e fvalue cy
0e fvalue dx
0e fvalue dy

0e fvalue dcx
0e fvalue dcy

0e fvalue |ac|
0e fvalue |dc|
0e fvalue |bd|

: count_max++ count_max 1+ to count_max ;

\ The solution is 129325, found in
https://github.com/lucky-bai/projecteuler-solutions/blob/master/Solutions.md

2.013e-6 fvalue tolerance_equal
: approx_equal f- fabs tolerance_equal f< ;

: deg>rad s>f pi f* 180e f/ ;
: rad>deg 180e f* pi f/ fround f>s ;

: DCA_calc
DAC deg>rad to aa
BAC deg>rad to bb
ABD deg>rad to cc
CBD deg>rad to dd

aa bb f+ ftan to tab
cc dd f+ ftan to tcd
bb ftan to tb
cc ftan to tc

tcd tcd tb f+ f/ to cx
tb cx f* to cy

tc tc tab f+ f/ to dx
tab dx f* to dy

cx dx f- to dcx
cy dy f- to dcy

cx fdup f* cy fdup f* f+ fsqrt to |ac|
dx 1e f- fdup f* dy fdup f* f+ fsqrt to |bd|

dcx fdup f* dcy fdup f* f+ fsqrt to |dc|

cx dcx f* cy dcy f* f+ |ac| |dc| f* f/ facos rad>deg
;


: solve
0 to count_max
_begin_
180 1 .-- --> DAC DAC .?,
180 1 .-- --> BAC BAC .?,
DAC BAC + 180 <= true =,
180 1 .-- --> ABD ABD .?,
180 DAC - BAC - ABD - --- --> ADB ADB .?,
180 1 .-- --> CBD CBD .?,
ABD CBD + 180 <= true =,
180 BAC - ABD - CBD - --- --> BCA BCA .?,

DCA_calc --- --> DCA DCA .?,

DCA BCA + 180 <= true =,
180 CBD - BCA - DCA - --- --> CDB CDB .?,
ADB CDB + 180 <= true =,
DAC BAC + ABD CBD + BCA DCA + CDB ADB +
+ + + 360 =,

ADB CDB + deg>rad fsin |dc| f*
DAC deg>rad fsin |ac| f* approx_equal true =,

BCA DCA + deg>rad fsin |dc| f*
CBD deg>rad fsin |bd| f* approx_equal true =,

count_max++

=| =| =| =| .| =| .| .| =| .| .| .| =| .| .|
_end_
;

: .solution count_max 8 / . ;

: Euler_177 solve .solution ;

\ Here, the code ends

Ahmed
a***@spenarnc.xs4all.nl
2024-06-16 14:06:55 UTC
Permalink
Post by Ahmed
A new version with some modification (without saving the results
(angles)) and no need for tolerance_angle.
No need for -m 1G in command line (with gforth).
<SNIP>
Post by Ahmed
: solve
0 to count_max
_begin_
180 1 .-- --> DAC DAC .?,
180 1 .-- --> BAC BAC .?,
DAC BAC + 180 <= true =,
180 1 .-- --> ABD ABD .?,
180 DAC - BAC - ABD - --- --> ADB ADB .?,
180 1 .-- --> CBD CBD .?,
ABD CBD + 180 <= true =,
180 BAC - ABD - CBD - --- --> BCA BCA .?,
DCA_calc --- --> DCA DCA .?,
DCA BCA + 180 <= true =,
180 CBD - BCA - DCA - --- --> CDB CDB .?,
ADB CDB + 180 <= true =,
DAC BAC + ABD CBD + BCA DCA + CDB ADB +
+ + + 360 =,
ADB CDB + deg>rad fsin |dc| f*
DAC deg>rad fsin |ac| f* approx_equal true =,
BCA DCA + deg>rad fsin |dc| f*
CBD deg>rad fsin |bd| f* approx_equal true =,
count_max++
=| =| =| =| .| =| .| .| =| .| .| .| =| .| .|
_end_
;
<SNIP>
Post by Ahmed
Ahmed
Respect!
Of you introduce control words like that, it is hard to understand without
explanation.
Would you care to paraphrase the line I have lifted out of the program.

Groetjes Albert
--
Don't praise the day before the evening. One swallow doesn't make spring.
You must not say "hey" before you have crossed the bridge. Don't sell the
hide of the bear until you shot it. Better one bird in the hand than ten in
the air. First gain is a cat purring. - the Wise from Antrim -
Ahmed
2024-06-16 17:06:07 UTC
Permalink
Post by a***@spenarnc.xs4all.nl
Respect!
Of you introduce control words like that, it is hard to understand without
explanation.
Would you care to paraphrase the line I have lifted out of the program.
Groetjes Albert
Hi,
I tried to apply what I already done with CLP previously to this problem
Euler problem 177.
The solution I found is not really acceptable because it depends on the
tolerance to consider a float approximately as an integer.

But I still concerned with the CLP in forth.

Here is a new simplified version of applying CLP to this problem in
forth (gforth)



The code begins here
\ Euler_177

\ ----- for CLP
0 value vals_num
20 value vals_num_max

0 value min_val
0 value max_val

0 value nloops_prec
0 value nloops
0 value constraint_num
30 value max_num_constraints
0 value constraint_count

: values dup 1+ to vals_num 0 ?do 0 value loop ;
: fvalues 0 ?do 0e fvalue loop ;

create loop_loc max_num_constraints allot
loop_loc max_num_constraints erase

create constraints_stack max_num_constraints cells allot
constraints_stack max_num_constraints cells erase

constraints_stack value constraints_stack_pointer

: push_to_constraints_stack
constraints_stack_pointer cell+ to constraints_stack_pointer
constraints_stack_pointer !
;
: pop_from_constraints_stack
constraints_stack_pointer dup @
swap cell- to constraints_stack_pointer
;

: update_constraints
constraint_num 1+ dup to constraint_count to constraint_num
nloops nloops_prec <> if
1 loop_loc constraint_num + c!
nloops to nloops_prec
then
;
: resolve_constraints
loop_loc constraint_num + c@ if
postpone loop
then
constraint_num 1- to constraint_num
;
: .---> nloops 1+ to nloops postpone do postpone i postpone to ;
immediate
: ----> postpone to ; immediate
: a| postpone then resolve_constraints ; immediate
: t| postpone then resolve_constraints ; immediate
: a?,
postpone min_val postpone max_val postpone 1+ postpone within
postpone if
update_constraints ['] a| push_to_constraints_stack
; immediate
: t?,
postpone if
update_constraints ['] t| push_to_constraints_stack
; immediate
: _begin_ ; immediate
: _end_
constraint_count 0 do
pop_from_constraints_stack execute
loop
; immediate

\ ---------end for CLP

\ Euler Problem 177
8 values DAC BAC ABD CBD BCA DCA CDB ADB
1 to min_val
179 to max_val

0 value count_max
8 fvalues aa bb cc dd ee ff gg hh
4 fvalues tab tcd tb tc
5 fvalues bx cx cy dx dy
1e to bx
2 fvalues dcx dcy
3 fvalues |ac| |dc| |bd|

: count_max++ count_max 1+ to count_max ;

3.16025e-3 fvalue tolerance_integer
: approx_integer f- fabs tolerance_integer f< ;
: approx_good fdup fround ftuck approx_integer ;

: rad>deg 180e f* pi f/ approx_good if f>s else fdrop -1 then ;
: deg>rad s>f pi f* 180e f/ ;

: DCA_calc \ Calculates the angle DCA using the rule of sines in a
triangle
\ I took the points A(0,0), B(bx,0), C (cx,cy) and
D(dx,dy), with bx = 1 for example
\ When we have the angles DAC, BAC, ABD and CBD, the points
C and D are well defined
\ geometrically so that cx, cy, dx and dy can be obtained
(analytic geometry)
\ and we can calculate the lengths |ac|, |bd| and |dc|
\ and then calculate the angle DCA
\
DAC deg>rad to aa
BAC deg>rad to bb
ABD deg>rad to cc
CBD deg>rad to dd

aa bb f+ ftan to tab
cc dd f+ ftan to tcd
bb ftan to tb
cc ftan to tc

bx tcd f* tcd tb f+ f/ to cx
tb cx f* to cy

bx tc f* tc tab f+ f/ to dx
tab dx f* to dy

cx dx f- to dcx
cy dy f- to dcy

cx fdup f* cy fdup f* f+ fsqrt to |ac|
dx bx f- fdup f* dy fdup f* f+ fsqrt to |bd|
dcx fdup f* dcy fdup f* f+ fsqrt to |dc|

CBD deg>rad fsin |bd| f* |dc| f/ fasin rad>deg BCA -
;

: solve
0 to count_max \ initialize the count of
the acceptable solutions
_begin_ \ begin solving with CLP
formalisme
180 1 .---> DAC DAC a?, \ from 1 to 179 choose
the value of the angle DAC,
\ if it is acceptable, go
ahead else choose the next
\ value for DAC and test
if acceptable ...
180 1 .---> BAC BAC a?, \ the same as above but
for BAC
DAC BAC + 180 <= t?, \ verify that the angle
BAD <= 180 (convex quadrilateral)
\ if it is true go ahead
else step back (backtrack)
180 1 .---> ABD ABD a?,
180 DAC - BAC - ABD - ----> ADB ADB a?,
180 1 .---> CBD CBD a?,
ABD CBD + 180 <= t?,
180 BAC - ABD - CBD - ----> BCA BCA a?, \ in the triangle ABC, we
have BAC+ABC+BCA = 180
\ so we can get BCA =
180-BAC-ABC = 180 -BAC-(ABD+CBD)
\ and if it is accepted
go ahead else backtrack
DCA_calc ----> DCA DCA a?, \ Here, we use the rule
of sines for the triangle ACD,
\ that states:
\ sin(CBD)/|cd| =
sin(BCD)/|bd| =sin(BDC)/|bc|
\ where |cd|, |bd| and
|bc| are the lengths of CD, BD and
\ BC segments. and from
that, we can write:
\ sin(CBD)/|cd| =
sin(BCD)/|bd|, so we can get
\ sin(BCD) =
sin(CBD)*|bd|/|cd|, and
\ BCD =
arcsin(sin(CBD)*|bd|/|cd|), but
\ BCD = BCA + DCA and BCA
is known, so we obtain:
\ DCA =
arcsin(sin(CBD)*|bd|/|cd|)-BCA
\ and this formula is
programmed in the word DCA_calc
DCA BCA + 180 <= t?,
180 CBD - BCA - DCA - ----> CDB CDB a?,
ADB CDB + 180 <= t?,
DAC BAC + ABD CBD +
BCA DCA + CDB ADB +
+ + + 360 = t?, \ The sum of the interior
angles of quadrilatrals = 360
count_max++ \ count the acceptable 8
angles (solutions)
_end_ \ the end of the CLP
;

: .solution count_max 8 / . ; \ I suppose (to be
verified) there are 8 similarities
\ 4 by rotation and 2 by
mirror symmetry ==> 4*2 = 8

: Euler_177 solve .solution ;


The code ends here.

I'm still playing with different simple CLP implementations in forth and
I haven't yet stabilized for a convenient approach.

Ahmed

Ahmed
2024-06-13 16:46:24 UTC
Permalink
The version without saving the angles (results), with some modification
(no use of tolerance_angle),
with gforth, no need for -m 1G in the command line.

\ Here, the code begins

\ Euler_177
\ Example:
\ DAC = 20, BAC = 60, ABD = 50, CBD = 30,
\ BCA = 40, DCA = 30, CDB = 80, ADB = 50


\ ---------------------------
0 value vals_num
20 value vals_num_max


0 value nloops_prec
0 value nloops
0 value constraint_num
30 value max_num_constraints
create loop_loc max_num_constraints allot
loop_loc max_num_constraints erase

0 value min_val
0 value max_val

: .-- nloops 1+ to nloops postpone do postpone i ; immediate
: .?, postpone min_val postpone max_val postpone 1+ postpone within
postpone if ; immediate
: --> postpone to constraint_num 1+ to constraint_num nloops nloops_prec
<> if 1 loop_loc constraint_num + c! nloops to nloops_prec then ;
immediate
: --- ; immediate
: _begin_ ; immediate
: .| postpone then loop_loc constraint_num + c@ if postpone loop then
constraint_num 1- to constraint_num ; immediate
: _end_ ; immediate
: =, postpone = postpone if ; immediate
: =| postpone then ; immediate
: values dup 1+ to vals_num 0 ?do 0 value loop ;
\ --------------------------


\ euler 177
8 values DAC BAC ABD CBD BCA DCA CDB ADB
1 to min_val
179 to max_val

0 value count_max

0e fvalue aa
0e fvalue bb
0e fvalue cc
0e fvalue dd
0e fvalue ee
0e fvalue ff
0e fvalue gg
0e fvalue hh

0e fvalue tab
0e fvalue tcd
0e fvalue tb
0e fvalue tc

0e fvalue cx
0e fvalue cy
0e fvalue dx
0e fvalue dy

0e fvalue dcx
0e fvalue dcy

0e fvalue |ac|
0e fvalue |dc|
0e fvalue |bd|

: count_max++ count_max 1+ to count_max ;

\ The solution is 129325, found in
https://github.com/lucky-bai/projecteuler-solutions/blob/master/Solutions.md

2.013e-6 fvalue tolerance_equal

: approx_equal f- fabs tolerance_equal f< ;

: deg>rad s>f pi f* 180e f/ ;
: rad>deg 180e f* pi f/ fround f>s ;

: DCA_calc
DAC deg>rad to aa
BAC deg>rad to bb
ABD deg>rad to cc
CBD deg>rad to dd

aa bb f+ ftan to tab
cc dd f+ ftan to tcd
bb ftan to tb
cc ftan to tc

tcd tcd tb f+ f/ to cx
tb cx f* to cy

tc tc tab f+ f/ to dx
tab dx f* to dy

cx dx f- to dcx
cy dy f- to dcy

cx fdup f* cy fdup f* f+ fsqrt to |ac|
dx 1e f- fdup f* dy fdup f* f+ fsqrt to |bd|

dcx fdup f* dcy fdup f* f+ fsqrt to |dc|

cx dcx f* cy dcy f* f+ |ac| |dc| f* f/ facos rad>deg
;


: solve
0 to count_max
_begin_
180 1 .-- --> DAC DAC .?,
180 1 .-- --> BAC BAC .?,
DAC BAC + 180 <= true =,
180 1 .-- --> ABD ABD .?,
180 DAC - BAC - ABD - --- --> ADB ADB .?,
180 1 .-- --> CBD CBD .?,
ABD CBD + 180 <= true =,
180 BAC - ABD - CBD - --- --> BCA BCA .?,

DCA_calc --- --> DCA DCA .?,

DCA BCA + 180 <= true =,
180 CBD - BCA - DCA - --- --> CDB CDB .?,
ADB CDB + 180 <= true =,
DAC BAC + ABD CBD + BCA DCA + CDB ADB +
+ + + 360 =,

ADB CDB + deg>rad fsin |dc| f*
DAC deg>rad fsin |ac| f* approx_equal true =,

BCA DCA + deg>rad fsin |dc| f*
CBD deg>rad fsin |bd| f* approx_equal true =,

count_max++

=| =| =| =| .| =| .| .| =| .| .| .| =| .| .|
_end_
;

: .solution count_max 8 / . ;

: Euler_177 solve .solution ;

\ Here, the code ends

With same timing and result as the previous version.

Ahmed
Loading...