#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
MODE GEN = VOID; # hint/flag generator contructs #
MODE YIELDINT = PROC(INT)GEN;
MODE GENINT = PROC(YIELDINT)GEN;
PROC is perfect square = (INT n)BOOL:
    ENTIER (sqrt(n)+0.5) ** 2 = n; # Round to nearest integer #
PROC gen int = (YIELDINT yield)GEN: 
    FOR i DO yield(i) OD;
PROC gen square = (GENINT gen, YIELDINT yield)GEN:
    gen((INT value)VOID: yield(value*value));
PROC gen sum = (GENINT gen, YIELDINT yield)GEN:
BEGIN
    INT sum := 0;
    gen((INT value)VOID: yield(sum +:= value))
END;
PROC gen perfect square = (GENINT gen, YIELDINT yield)GEN:
BEGIN
    gen((INT value)VOID: 
        IF is perfect square(value) AND value NE 1 THEN
            yield(value) # Yield the perfect square sum #
        FI
    )
END;
PROC head = (GENINT gen)INT:
BEGIN
   INT return;
   gen((INT i)VOID: ( return := i; GOTO done ));
   done: return
END;
MODE PIPEINT = PROC(GENINT, YIELDINT)GEN;
MODE SINKINT = PROC(GENINT)INT;
OP AND = (GENINT source, PIPEINT pipe)GENINT: pipe(source,##);
OP AND = (GENINT source, SINKINT sink)INT: sink(source);
BEGIN
  # INT result := head(gen perfect square(gen sum(gen square(gen int,##),##),##)); #
    INT result := gen int AND gen square AND gen sum AND gen perfect square AND head;
    printf(($"This sum is a perfect square: "gl$, result))
END
 
No comments:
Post a Comment