// version 1.0.6

import java.security.MessageDigest

fun main(args: Array<String>) {
    val text  = "Rosetta Code"
    val bytes = text.toByteArray()
    val md = MessageDigest.getInstance("SHA-1")
    val digest = md.digest(bytes)
    for (byte in digest) print("%02x".format(byte))
    println()
}


'--------------------------------------------------------------------------------
'           FAST SHA1 CALCULATION BASED ON MS ADVAPI32.DLL BY CRYPTOMAN         '
'           BASED ON SHA256 EXAMPLE BY RICHARD T. RUSSEL AUTHOR OF LBB          '
'                           http://lbb.conforums.com/                           '
'           VERIFY CORRECTNESS BY http://www.fileformat.info/tool/hash.htm      '
'--------------------------------------------------------------------------------

print sha1$("Rosetta Code")
end

    X$="1234567890ABCDEF"

    dat$ = pack$(X$)

    print "SPEED TEST"
    for i=1 to 20
    t1=time$("ms")
    print sha1$(dat$)
    t2=time$("ms")
    print "calculated in ";t2-t1;" ms"
    next
    end

function sha1$(message$)

    HP.HASHVAL      = 2
    CRYPT.NEWKEYSET = 48
    PROV.RSA.AES    = 24
    buffer$         = space$(128)

    PROVRSAFULL     = 1
    ALGCLASSHASH    = 32768
    ALGTYPEANY      = 0
    ALGSIDMD2       = 1
    ALGSIDMD4       = 2
    ALGSIDMD5       = 3
    ALGSIDSHA1      = 4

    ALGOSHA1 = ALGCLASSHASH OR ALGTYPEANY OR ALGSIDSHA1

    struct temp, v as long
    open "ADVAPI32.DLL" for dll as #advapi32
    calldll #advapi32, "CryptAcquireContextA", temp as struct, _
                       0 as long, 0 as long, PROV.RSA.AES as long, _
                       0 as long, re as long
    hprov = temp.v.struct
    calldll #advapi32, "CryptCreateHash", hprov as long, _
                       ALGOSHA1 as long, 0 as long, 0 as long, _
                       temp as struct, re as long
    hhash = temp.v.struct
    l = len(message$)
    calldll #advapi32, "CryptHashData", hhash as long, message$ as ptr, _
                       l as long, 0 as long, re as long
    temp.v.struct = len(buffer$)
    calldll #advapi32, "CryptGetHashParam", hhash as long, _
                       HP.HASHVAL as long, buffer$ as ptr, _
                       temp as struct, 0 as long, re as long
    calldll #advapi32, "CryptDestroyHash", hhash as long, re as long
    calldll #advapi32, "CryptReleaseContext", hprov as long, re as long
    close #advapi32
    for i = 1 TO temp.v.struct
      sha1$ = sha1$ + right$("0" + dechex$(asc(mid$(buffer$,i))), 2)
    next
end function

function pack$(x$)
    for i = 1 TO len(x$) step 2
      pack$ = pack$ + chr$(hexdec(mid$(x$,i,2)))
    next
end function


{- Not so functional representation of R sets (with IEEE Double), in a strange way -}

import Data.List
import Data.Maybe

data BracketType = OpenSub | ClosedSub
    deriving (Show, Enum, Eq, Ord)

data RealInterval = RealInterval {left :: BracketType, right :: BracketType,
    lowerBound :: Double, upperBound :: Double}
    deriving (Eq)

type RealSet = [RealInterval]
posInf = 1.0/0.0 :: Double -- IEEE tricks
negInf = (-1.0/0.0) :: Double
set_R = RealInterval ClosedSub ClosedSub negInf posInf :: RealInterval

emptySet = [] :: [RealInterval]

instance Show RealInterval where
    show x@(RealInterval _ _ y y')
        | y == y' && (left x == right x) && (left x == ClosedSub) = "{" ++ (show y) ++ "}"
        | otherwise = [['(', '[']!!(fromEnum $ left x)] ++ (show $ lowerBound x) ++
         "," ++ (show $ upperBound x) ++ [[')', ']']!!(fromEnum $ right x)]
    showList [x] = shows x
    showList (h:t) = shows h . (" U " ++) . showList t
    showList [] =  (++ "(/)") -- empty set

construct_interval :: Char -> Double -> Double -> Char -> RealInterval
construct_interval '(' x y ')' = RealInterval OpenSub OpenSub x y
construct_interval '(' x y ']' = RealInterval OpenSub ClosedSub x y
construct_interval '[' x y ')' = RealInterval ClosedSub OpenSub x y
construct_interval _ x y _ = RealInterval ClosedSub ClosedSub x y

set_is_empty :: RealSet -> Bool
set_is_empty rs = (rs == emptySet)

set_in :: Double -> RealSet -> Bool
set_in x [] = False
set_in x rs =
    isJust (find (\s ->
        ((lowerBound s < x) && (x < upperBound s)) ||
        (x == lowerBound s && left s == ClosedSub) ||
        (x == upperBound s && right s == ClosedSub))
        rs)

-- max, min for pairs (double, bracket)
max_p :: (Double, BracketType) -> (Double, BracketType) -> (Double, BracketType)
min_p :: (Double, BracketType) -> (Double, BracketType) -> (Double, BracketType)
max_p p1@(x, y) p2@(x', y')
    | x == x' = (x, max y y') -- closed is stronger than open
    | x < x'  = p2
    | otherwise = p1

min_p [email protected](x, y) [email protected](x', y')
    | x == x' = (x, min y y')
    | x < x'  = p1
    | otherwise = p2

simple_intersection :: RealInterval -> RealInterval -> [RealInterval]
simple_intersection ri1@(RealInterval l_ri1 r_ri1 x1 y1) ri2@(RealInterval l_ri2 r_ri2 x2 y2)
    | (y1 < x2) || (y2 < x1) = emptySet
    | (y1 == x2) && ((fromEnum r_ri1) + (fromEnum l_ri2) /= 2) = emptySet
    | (y2 == x1) && ((fromEnum r_ri2) + (fromEnum l_ri1) /= 2) = emptySet
    | otherwise = let lb = if x1 == x2 then (x1, min l_ri1 l_ri2) else max_p (x1, l_ri1) (x2, l_ri2) in
        let rb = min_p (y1, right ri1) (y2, right ri2) in
            [RealInterval (snd lb) (snd rb) (fst lb) (fst rb)]

simple_union :: RealInterval -> RealInterval -> [RealInterval]
simple_union ri1@(RealInterval l_ri1 r_ri1 x1 y1) ri2@(RealInterval l_ri2 r_ri2 x2 y2)
    | (y1 < x2) || (y2 < x1) = [ri2, ri1]
    | (y1 == x2) && ((fromEnum r_ri1) + (fromEnum l_ri2) /= 2) = [ri1, ri2]
    | (y2 == x1) && ((fromEnum r_ri2) + (fromEnum l_ri1) /= 2) = [ri1, ri2]
    | otherwise = let lb = if x1 == x2 then (x1, max l_ri1 l_ri2) else min_p (x1, l_ri1) (x2, l_ri2) in
        let rb = max_p (y1, right ri1) (y2, right ri2) in
            [RealInterval (snd lb) (snd rb) (fst lb) (fst rb)]

simple_complement :: RealInterval -> [RealInterval]
simple_complement ri1@(RealInterval l_ri1 r_ri1 x1 y1) =
    [(RealInterval ClosedSub (inv l_ri1) negInf x1), (RealInterval (inv r_ri1) ClosedSub y1 posInf)]
    where
        inv OpenSub = ClosedSub
        inv ClosedSub = OpenSub

set_sort :: RealSet -> RealSet
set_sort rs =
    sortBy
        (\s1 s2 ->
            let (lp, rp) = ((lowerBound s1, left s1), (lowerBound s2, left s2)) in
                if max_p lp rp == lp then GT else LT)
        rs

set_simplify :: RealSet -> RealSet
set_simplify [] = emptySet
set_simplify rs =
    concat (map make_empty (set_sort (foldl
        (\acc ri1 -> (simple_union (head acc) ri1) ++ (tail acc))
        [head sorted_rs]
        sorted_rs)))
    where
        sorted_rs = set_sort rs
        make_empty ri@(RealInterval lb rb x y)
            | x >= y && (lb /= rb || rb /= ClosedSub) = emptySet
            | otherwise = [ri]

-- set operations
set_complement :: RealSet -> RealSet
set_union :: RealSet -> RealSet -> RealSet
set_intersection :: RealSet -> RealSet -> RealSet
set_difference :: RealSet -> RealSet -> RealSet
set_measure :: RealSet -> Double

set_complement rs =
    foldl set_intersection [set_R] (map simple_complement rs)
set_union rs1 rs2 =
    set_simplify (rs1 ++ rs2)
set_intersection rs1 rs2 =
    set_simplify $ concat [simple_intersection s1 s2 | s1 <- rs1, s2 <- rs2]
set_difference rs1 rs2 =
    set_intersection (set_complement rs2) rs1
set_measure rs =
    foldl (\acc x -> acc + (upperBound x) - (lowerBound x)) 0.0 rs

-- test
test = map (\x -> [x]) [construct_interval '(' 0 1 ']', construct_interval '[' 0 2 ')',
    construct_interval '[' 0 2 ')', construct_interval '(' 1 2 ']',
    construct_interval '[' 0 3 ')', construct_interval '(' 0 1 ')',
    construct_interval '[' 0 3 ')', construct_interval '[' 0 1 ']']
restest = [set_union (test!!0) (test!!1), set_intersection (test!!2) (test!!3),
    set_difference (test!!4) (test!!5), set_difference (test!!6) (test!!7)]
isintest s =
    mapM_
        (\x -> putStrLn ((show x) ++ " is in " ++ (show s) ++ " : " ++ (show (set_in x s))))
        [0, 1, 2]

testA = [construct_interval '(' (sqrt (n + (1.0/6))) (sqrt (n + (5.0/6))) ')' | n <- [0..99]]
testB = [construct_interval '(' (n + (1.0/6)) (n + (5.0/6)) ')' | n <- [0..9]]

main =
    putStrLn ("union " ++ (show (test!!0)) ++ " " ++ (show (test!!1)) ++ " = " ++ (show (restest!!0))) >>
    putStrLn ("inter " ++ (show (test!!2)) ++ " " ++ (show (test!!3)) ++ " = " ++ (show (restest!!1))) >>
    putStrLn ("diff " ++ (show (test!!4)) ++ " " ++ (show (test!!5)) ++ " = " ++ (show (restest!!2))) >>
    putStrLn ("diff " ++ (show (test!!6)) ++ " " ++ (show (test!!7)) ++ " = " ++ (show (restest!!3))) >>
    mapM_ isintest restest >>
    putStrLn ("measure: " ++ (show (set_measure (set_difference testA testB))))


crypto = xtra("Crypto").new()
put crypto.cx_sha1_string("Rosetta Code")


command shaRosettaCode
    local shex, sha1
    put sha1Digest("Rosetta Code") into sha1
    get binaryDecode("H*",sha1,shex)
    put shex
end shaRosettaCode


#!/usr/bin/lua

local sha1 = require "sha1"

for i, str in ipairs{"Rosetta code", "Rosetta Code"} do
  print(string.format("SHA-1(%q) = %s", str, sha1(str)))
end


procedure main(A)
    s1 := RealSet("(0,1]").union(RealSet("[0,2)"))
    s2 := RealSet("[0,2)").intersect(RealSet("(1,2)"))
    s3 := RealSet("[0,3)").difference(RealSet("(0,1)"))
    s4 := RealSet("[0,3)").difference(RealSet("[0,1]"))
    every s := s1|s2|s3|s4 do {
        every n := 0 to 2 do
            write(s.toString(),if s.contains(n) then " contains "
                                                else " doesn't contain ",n)
        write()
        }
end

class Range(a,b,lbnd,rbnd,ltest,rtest)

    method contains(x); return ((ltest(a,x),rtest(x,b)),self); end
    method toString(); return lbnd||a||","||b||rbnd; end
    method notEmpty(); return (ltest(a,b),rtest(a,b),self); end
    method makeLTest(); return proc(if lbnd == "(" then "<" else "<=",2); end
    method makeRTest(); return proc(if rbnd == "(" then "<" else "<=",2); end

    method intersect(r)
        if a < r.a then (na := r.a, nlb := r.lbnd)
        else if a > r.a then (na := a, nlb := lbnd)
        else (na := a, nlb := if "(" == (lbnd|r.lbnd) then "(" else "[")
        if b < r.b then ( nb := b, nrb := rbnd)
        else if b > r.b then (nb := r.b, nrb := r.rbnd)
        else (nb := b, nrb := if ")" == (rbnd|r.rbnd) then ")" else "]")
        range := Range(nlb||na||","||nb||nrb)
        return range
    end

    method difference(r)
        if /r then return RealSet(toString())
        r1 := lbnd||a||","||min(b,r.a)||map(r.lbnd,"([","])")
        r2 := map(r.rbnd,")]","[(")||max(a,r.b)||","||b||rbnd
        return RealSet(r1).union(RealSet(r2))
    end

initially(s)
    static lbnds, rbnds
    initial (lbnds := '([', rbnds := '])')
    if \s then {
        s ? {
            lbnd := (tab(upto(lbnds)),move(1))
            a := 1(tab(upto(',')),move(1))
            b := tab(upto(rbnds))
            rbnd := move(1)
            }
        ltest := proc(if lbnd == "(" then "<" else "<=",2)
        rtest := proc(if rbnd == ")" then "<" else "<=",2)
        }
end

class RealSet(ranges)

    method contains(x); return ((!ranges).contains(x), self); end
    method notEmpty(); return ((!ranges).notEmpty(), self); end

    method toString()
        sep := s := ""
        every r := (!ranges).toString() do s ||:= .sep || 1(r, sep := " + ")
        return s
    end

    method clone()
        newR := RealSet()
        newR.ranges := (copy(\ranges) | [])
        return newR
    end

    method union(B)
        newR := clone()
        every put(newR.ranges, (!B.ranges).notEmpty())
        return newR
    end

    method intersect(B)
        newR := clone()
        newR.ranges := []
        every (r1 := !ranges, r2 := !B.ranges) do {
            range := r1.intersect(r2)
            put(newR.ranges, range.notEmpty())
            }
        return newR
    end

    method difference(B)
        newR := clone()
        newR.ranges := []
        every (r1 := !ranges, r2 := !B.ranges) do {
            rs := r1.difference(r2)
            if rs.notEmpty() then every put(newR.ranges, !rs.ranges)
            }
        return newR
    end

initially(s)
    put(ranges := [],Range(\s).notEmpty())
end


with(StringTools):
Hash("Ars longa, vita brevis",method="SHA1");

# "e640d285242886eb96ab80cbf858389b3df52f43"


/**
 SHA-1 in Neko
 Tectonics:
   nekoc SHA-1.neko
   neko SHA-1
*/

var SHA1 = $loader.loadprim("[email protected]_sha1", 3);
var base_encode = $loader.loadprim("[email protected]_encode", 2);

var msg = "Rosetta Code";
var result = SHA1(msg, 0, $ssize(msg));

/* Output in lowercase hex */
$print(base_encode(result, "0123456789abcdef"));


has=: 1 :'(interval m)`:6'
ing=: `''

interval=: 3 :0
  if.0<L.y do.y return.end.
  assert. 5=#words=. ;:y
  assert. (0 { words) e. ;:'[('
  assert. (2 { words) e. ;:','
  assert. (4 { words) e. ;:'])'
  'lo hi'=.(1 3{0".L:0 words)
  'cL cH'=.0 4{words e.;:'[]'
  (lo&(<`<:@.cL) *. hi&(>`>:@.cH))ing
)

union=: 4 :'(x has +. y has)ing'
intersect=: 4 :'(x has *. y has)ing'
without=: 4 :'(x has *. [: -. y has)ing'


/* NetRexx */
options replace format comments java crossref savelog symbols binary

import java.security.MessageDigest

SHA1('Rosetta Code', '48c98f7e5a6e736d790ab740dfc3f51a61abe2b5')

return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method SHA1(messageText, verifyCheck) public static

  algorithm   = 'SHA-1'
  digestSum = getDigest(messageText, algorithm)

  say '<Message>'messageText'</Message>'
  say Rexx('<'algorithm'>').right(12) || digestSum'</'algorithm'>'
  say Rexx('<Verify>').right(12) || verifyCheck'</Verify>'
  if digestSum == verifyCheck then say algorithm 'Confirmed'
                              else say algorithm 'Failed'

  return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method getDigest(messageText = Rexx, algorithm = Rexx 'MD5', encoding = Rexx 'UTF-8', lowercase = boolean 1) public static returns Rexx

  algorithm = algorithm.upper
  encoding  = encoding.upper

  message      = String(messageText)
  messageBytes = byte[]
  digestBytes  = byte[]
  digestSum    = Rexx ''

  do
    messageBytes = message.getBytes(encoding)
    md = MessageDigest.getInstance(algorithm)
    md.update(messageBytes)
    digestBytes = md.digest

    loop b_ = 0 to digestBytes.length - 1
      bb = Rexx(digestBytes[b_]).d2x(2)
      if lowercase then digestSum = digestSum || bb.lower
                   else digestSum = digestSum || bb.upper
      end b_
  catch ex = Exception
    ex.printStackTrace
  end

  return digestSum


import java.util.Objects;
import java.util.function.Predicate;

public class RealNumberSet {
    public enum RangeType {
        CLOSED,
        BOTH_OPEN,
        LEFT_OPEN,
        RIGHT_OPEN,
    }

    public static class RealSet {
        private Double low;
        private Double high;
        private Predicate<Double> predicate;
        private double interval = 0.00001;

        public RealSet(Double low, Double high, Predicate<Double> predicate) {
            this.low = low;
            this.high = high;
            this.predicate = predicate;
        }

        public RealSet(Double start, Double end, RangeType rangeType) {
            this(start, end, d -> {
                switch (rangeType) {
                    case CLOSED:
                        return start <= d && d <= end;
                    case BOTH_OPEN:
                        return start < d && d < end;
                    case LEFT_OPEN:
                        return start < d && d <= end;
                    case RIGHT_OPEN:
                        return start <= d && d < end;
                    default:
                        throw new IllegalStateException("Unhandled range type encountered.");
                }
            });
        }

        public boolean contains(Double d) {
            return predicate.test(d);
        }

        public RealSet union(RealSet other) {
            double low2 = Math.min(low, other.low);
            double high2 = Math.max(high, other.high);
            return new RealSet(low2, high2, d -> predicate.or(other.predicate).test(d));
        }

        public RealSet intersect(RealSet other) {
            double low2 = Math.min(low, other.low);
            double high2 = Math.max(high, other.high);
            return new RealSet(low2, high2, d -> predicate.and(other.predicate).test(d));
        }

        public RealSet subtract(RealSet other) {
            return new RealSet(low, high, d -> predicate.and(other.predicate.negate()).test(d));
        }

        public double length() {
            if (low.isInfinite() || high.isInfinite()) return -1.0; // error value
            if (high <= low) return 0.0;
            Double p = low;
            int count = 0;
            do {
                if (predicate.test(p)) count++;
                p += interval;
            } while (p < high);
            return count * interval;
        }

        public boolean isEmpty() {
            if (Objects.equals(high, low)) {
                return predicate.negate().test(low);
            }
            return length() == 0.0;
        }
    }

    public static void main(String[] args) {
        RealSet a = new RealSet(0.0, 1.0, RangeType.LEFT_OPEN);
        RealSet b = new RealSet(0.0, 2.0, RangeType.RIGHT_OPEN);
        RealSet c = new RealSet(1.0, 2.0, RangeType.LEFT_OPEN);
        RealSet d = new RealSet(0.0, 3.0, RangeType.RIGHT_OPEN);
        RealSet e = new RealSet(0.0, 1.0, RangeType.BOTH_OPEN);
        RealSet f = new RealSet(0.0, 1.0, RangeType.CLOSED);
        RealSet g = new RealSet(0.0, 0.0, RangeType.CLOSED);

        for (int i = 0; i <= 2; i++) {
            Double dd = (double) i;
            System.out.printf("(0, 1] ∪ [0, 2) contains %d is %s\n", i, a.union(b).contains(dd));
            System.out.printf("[0, 2) ∩ (1, 2] contains %d is %s\n", i, b.intersect(c).contains(dd));
            System.out.printf("[0, 3) − (0, 1) contains %d is %s\n", i, d.subtract(e).contains(dd));
            System.out.printf("[0, 3) − [0, 1] contains %d is %s\n", i, d.subtract(f).contains(dd));
            System.out.println();
        }

        System.out.printf("[0, 0] is empty is %s\n", g.isEmpty());
        System.out.println();

        RealSet aa = new RealSet(
            0.0, 10.0,
            x -> (0.0 < x && x < 10.0) && Math.abs(Math.sin(Math.PI * x * x)) > 0.5
        );
        RealSet bb = new RealSet(
            0.0, 10.0,
            x -> (0.0 < x && x < 10.0) && Math.abs(Math.sin(Math.PI * x)) > 0.5
        );
        RealSet cc = aa.subtract(bb);
        System.out.printf("Approx length of A - B is %f\n", cc.length());
    }
}


;; using the crypto module from http://www.newlisp.org/code/modules/crypto.lsp.html
;; (import native functions from the crypto library, provided by OpenSSL)
(module "crypto.lsp")
(crypto:sha1 "Rosetta Code")


import std/sha1

echo secureHash("Rosetta Code")


MODULE SHA1;
IMPORT
  Crypto:SHA1,
  Crypto:Utils,
  Strings,
  Out;
VAR
  h: SHA1.Hash;
  str: ARRAY 128 OF CHAR;
BEGIN
  h := SHA1.NewHash();
  h.Initialize;
  str := "Rosetta Code";
  h.Update(str,0,Strings.Length(str));
  h.GetHash(str,0);
  Out.String("SHA1: ");Utils.PrintHex(str,0,h.size);Out.Ln
END SHA1.


function realSet(set1, set2, op, values) {
    const makeSet=(set0)=>{
        let res = []
        if(set0.rangeType===0){
            for(let i=set0.low;i<=set0.high;i++)
                res.push(i);
        } else if (set0.rangeType===1) {
            for(let i=set0.low+1;i<set0.high;i++)
                res.push(i);
        } else if(set0.rangeType===2){
            for(let i=set0.low+1;i<=set0.high;i++)
                res.push(i);
        } else {
            for(let i=set0.low;i<set0.high;i++)
                res.push(i);
        }
        return res;
    }
    let res = [],finalSet=[];
    set1 = makeSet(set1);
    set2 = makeSet(set2);
    if(op==="union")
        finalSet = [...new Set([...set1,...set2])];
    else if(op==="intersect") {
        for(let i=0;i<set1.length;i++)
            if(set1.indexOf(set2[i])!==-1)
                finalSet.push(set2[i]);
    } else {
        for(let i=0;i<set2.length;i++)
            if(set1.indexOf(set2[i])===-1)
                finalSet.push(set2[i]);

        for(let i=0;i<set1.length;i++)
            if(set2.indexOf(set1[i])===-1)
                finalSet.push(set1[i]);
    }
    for(let i=0;i<values.length;i++){
        if(finalSet.indexOf(values[i])!==-1)
            res.push(true);
        else
            res.push(false);
    }
    return res;
}


$ ocaml -I +sha sha1.cma
        Objective Caml version 3.12.1

# Sha1.to_hex (Sha1.string "Rosetta Code") ;;
- : string = "48c98f7e5a6e736d790ab740dfc3f51a61abe2b5"


sha1(s)=extern("echo \"Str(`echo -n '"Str(s)"'|sha1sum|cut -d' ' -f1`)\"")


"""
    struct ConvexRealSet
Convex real set (similar to a line segment).
Parameters: lower bound, upper bound: floating point numbers
            includelower, includeupper: boolean true or false to indicate whether
            the set has a closed boundary (set to true) or open (set to false).
"""
mutable struct ConvexRealSet
    lower::Float64
    includelower::Bool
    upper::Float64
    includeupper::Bool
    function ConvexRealSet(lo, up, incllo, inclup)
       this = new()
       this.upper = Float64(up)
       this.lower = Float64(lo)
       this.includelower = incllo
       this.includeupper = inclup
       this
    end
end

function ∈(s, xelem)
    x = Float64(xelem)
    if(x == s.lower)
        if(s.includelower)
            return true
        else
            return false
        end
    elseif(x == s.upper)
        if(s.includeupper)
            return true
        else
            return false
        end
    end
    s.lower < x && x < s.upper
end

⋃(aset, bset, x) = (∈(aset, x) || ∈(bset, x))

⋂(aset, bset, x) = (∈(aset, x) && ∈(bset, x))

-(aset, bset, x) = (∈(aset, x) && !∈(bset, x))

isempty(s::ConvexRealSet) = (s.lower > s.upper) ||
                           ((s.lower == s.upper) && !s.includeupper && !s.includelower)

const s1 = ConvexRealSet(0.0, 1.0, false, true)
const s2 = ConvexRealSet(0.0, 2.0, true, false)
const s3 = ConvexRealSet(1.0, 2.0, false, true)
const s4 = ConvexRealSet(0.0, 3.0, true, false)
const s5 = ConvexRealSet(0.0, 1.0, false, false)
const s6 = ConvexRealSet(0.0, 1.0, true, true)
const sempty = ConvexRealSet(0.0, -1.0, true, true)
const testlist = [0, 1, 2]

function testconvexrealset()
    for i in testlist
        println("Testing with x = $i.\nResults:")
        println("    (0, 1] ∪ [0, 2): $(⋃(s1, s2, i))")
        println("    [0, 2) ∩ (1, 2]: $(⋂(s2, s3, i))")
        println("    [0, 3) − (0, 1): $(-(s4, s5, i))")
        println("    [0, 3) − [0, 1]: $(-(s4, s6, i))\n")
    end
    print("The set sempty is ")
    println(isempty(sempty) ? "empty." : "not empty.")
end

testconvexrealset()


// version 1.1.4-3

typealias RealPredicate = (Double) -> Boolean

enum class RangeType { CLOSED, BOTH_OPEN, LEFT_OPEN, RIGHT_OPEN }

class RealSet(val low: Double, val high: Double, val predicate: RealPredicate) {

    constructor (start: Double, end: Double, rangeType: RangeType): this(start, end,
        when (rangeType) {
            RangeType.CLOSED     -> fun(d: Double) = d in start..end
            RangeType.BOTH_OPEN  -> fun(d: Double) = start < d && d < end
            RangeType.LEFT_OPEN  -> fun(d: Double) = start < d && d <= end
            RangeType.RIGHT_OPEN -> fun(d: Double) = start <= d && d < end
        }
    )

    fun contains(d: Double) = predicate(d)

    infix fun union(other: RealSet): RealSet {
        val low2 = minOf(low, other.low)
        val high2 = maxOf(high, other.high)
        return RealSet(low2, high2) { predicate(it) || other.predicate(it) }
    }

    infix fun intersect(other: RealSet): RealSet {
        val low2 = maxOf(low, other.low)
        val high2 = minOf(high, other.high)
        return RealSet(low2, high2) { predicate(it) && other.predicate(it) }
    }

    infix fun subtract(other: RealSet) = RealSet(low, high) { predicate(it) && !other.predicate(it) }

    var interval = 0.00001

    val length: Double get() {
        if (!low.isFinite() || !high.isFinite()) return -1.0  // error value
        if (high <= low) return 0.0
        var p = low
        var count = 0
        do {
            if (predicate(p)) count++
            p += interval
        }
        while (p < high)
        return count * interval
    }

    fun isEmpty() = if (high == low) !predicate(low) else length == 0.0
}

fun main(args: Array<String>) {
    val a = RealSet(0.0, 1.0, RangeType.LEFT_OPEN)
    val b = RealSet(0.0, 2.0, RangeType.RIGHT_OPEN)
    val c = RealSet(1.0, 2.0, RangeType.LEFT_OPEN)
    val d = RealSet(0.0, 3.0, RangeType.RIGHT_OPEN)
    val e = RealSet(0.0, 1.0, RangeType.BOTH_OPEN)
    val f = RealSet(0.0, 1.0, RangeType.CLOSED)
    val g = RealSet(0.0, 0.0, RangeType.CLOSED)

    for (i in 0..2) {
        val dd = i.toDouble()
        println("(0, 1] ∪ [0, 2) contains $i is ${(a union b).contains(dd)}")
        println("[0, 2) ∩ (1, 2] contains $i is ${(b intersect c).contains(dd)}")
        println("[0, 3) − (0, 1) contains $i is ${(d subtract e).contains(dd)}")
        println("[0, 3) − [0, 1] contains $i is ${(d subtract f).contains(dd)}\n")
    }

    println("[0, 0] is empty is ${g.isEmpty()}\n")

    val aa = RealSet(0.0, 10.0) { x -> (0.0 < x && x < 10.0) &&
                                        Math.abs(Math.sin(Math.PI * x * x)) > 0.5  }
    val bb = RealSet(0.0, 10.0) { x -> (0.0 < x && x < 10.0) &&
                                        Math.abs(Math.sin(Math.PI * x)) > 0.5  }
    val cc = aa subtract bb
    println("Approx length of A - B is ${cc.length}")
}


program RosettaSha1;
uses
    sha1;
var
   d: TSHA1Digest;
begin
     d:=SHA1String('Rosetta Code');
     WriteLn(SHA1Print(d));
end.


use Digest::SHA qw(sha1_hex);

print sha1_hex('Rosetta Code'), "\n";


--
-- demo\rosetta\sha1.exw
-- =====================
--
--  NB no longer considered secure. Non-optimised.
--
function uint32(atom v)
    return and_bitsu(v,#FFFFFFFF)
end function

function sq_uint32(sequence s)
    for i=1 to length(s) do
        s[i] = uint32(s[i])
    end for
    return s
end function

function dword(string msg, integer i)
-- get dword as big-endian
    return msg[i]*#1000000+msg[i+1]*#10000+msg[i+2]*#100+msg[i+3]
end function

function xor_all(sequence s)
atom result = 0
    for i=1 to length(s) do
        result = xor_bits(result, s[i])
    end for
    result = uint32(result)
    return result
end function

function rol(atom word, integer bits)
-- left rotate the bits of a 32-bit number by the specified number of bits
    return uint32(word*power(2,bits))+floor(word/power(2,32-bits))
end function

function sha1(string msg)
atom a,b,c,d,e,temp,k
sequence w = repeat(0,80)
atom h0 = 0x67452301,
     h1 = 0xefcdab89,
     h2 = 0x98badcfe,
     h3 = 0x10325476,
     h4 = 0xc3d2e1f0

    integer bits = length(msg)*8
    msg &= #80
    while mod(length(msg),64)!=56 do msg &= '\0' end while
    msg &= reverse(int_to_bytes(bits,8))

    for chunk=1 to length(msg) by 64 do
        for i=1 to 16 do
            w[i] = dword(msg,chunk+(i-1)*4)
        end for
        for i=17 to 80 do
            w[i] = rol(xor_all({w[i-3],w[i-8],w[i-14],w[i-16]}),1)
        end for
        {a,b,c,d,e} = {h0,h1,h2,h3,h4}
        for i=1 to 80 do
            if i<=20 then
                temp = or_bits(and_bits(b,c),and_bits(not_bits(b),d))
                k = #5A827999
            elsif i<=40 then
                temp = xor_bits(xor_bits(b,c),d)
                k = #6ED9EBA1
            elsif i<=60 then
                temp = or_bits(or_bits(and_bits(b,c),and_bits(b,d)),and_bits(c,d))
                k = #8F1BBCDC
            else -- i<=80
                temp = xor_bits(xor_bits(b,c),d)
                k = #CA62C1D6
            end if
            {a,b,c,d,e} = {uint32(rol(a,5)+temp+e+k+w[i]),a,rol(b,30),c,d}
        end for
        {h0,h1,h2,h3,h4} = sq_uint32(sq_add({h0,h1,h2,h3,h4},{a,b,c,d,e}))
    end for
    sequence res = {h0, h1, h2, h3, h4}
    for i=1 to length(res) do
        res[i] = sprintf("%08X",res[i])
    end for
    return join(res)
end function

?sha1("Rosetta Code")


function createSet(low,high,rt)
    local l,h = tonumber(low), tonumber(high)
    if l and h then
        local t = {low=l, high=h}

        if type(rt) == "string" then
            if rt == "open" then
                t.contains = function(d) return low< d and d< high end
            elseif rt == "closed" then
                t.contains = function(d) return low<=d and d<=high end
            elseif rt == "left" then
                t.contains = function(d) return low< d and d<=high end
            elseif rt == "right" then
                t.contains = function(d) return low<=d and d< high end
            else
                error("Unknown range type: "..rt)
            end
        elseif type(rt) == "function" then
            t.contains = rt
        else
            error("Unable to find a range type or predicate")
        end

        t.union = function(o)
            local l2 = math.min(l, o.low)
            local h2 = math.min(h, o.high)
            local p = function(d) return t.contains(d) or o.contains(d) end
            return createSet(l2, h2, p)
        end

        t.intersect = function(o)
            local l2 = math.min(l, o.low)
            local h2 = math.min(h, o.high)
            local p = function(d) return t.contains(d) and o.contains(d) end
            return createSet(l2, h2, p)
        end

        t.subtract = function(o)
            local l2 = math.min(l, o.low)
            local h2 = math.min(h, o.high)
            local p = function(d) return t.contains(d) and not o.contains(d) end
            return createSet(l2, h2, p)
        end

        t.length = function()
            if h <= l then return 0.0 end
            local p = l
            local count = 0
            local interval = 0.00001
            repeat
                if t.contains(p) then count = count + 1 end
                p = p + interval
            until p>=high
            return count * interval
        end

        t.empty = function()
            if l == h then
                return not t.contains(low)
            end
            return t.length() == 0.0
        end

        return t
    else
        error("Either '"..low.."' or '"..high.."' is not a number")
    end
end

local a = createSet(0.0, 1.0, "left")
local b = createSet(0.0, 2.0, "right")
local c = createSet(1.0, 2.0, "left")
local d = createSet(0.0, 3.0, "right")
local e = createSet(0.0, 1.0, "open")
local f = createSet(0.0, 1.0, "closed")
local g = createSet(0.0, 0.0, "closed")

for i=0,2 do
    print("(0, 1]   union   [0, 2) contains "..i.." is "..tostring(a.union(b).contains(i)))
    print("[0, 2) intersect (1, 2] contains "..i.." is "..tostring(b.intersect(c).contains(i)))
    print("[0, 3)     -     (0, 1) contains "..i.." is "..tostring(d.subtract(e).contains(i)))
    print("[0, 3)     -     [0, 1] contains "..i.." is "..tostring(d.subtract(f).contains(i)))
    print()
end

print("[0, 0] is empty is "..tostring(g.empty()))
print()

local aa = createSet(
    0.0, 10.0,
    function(x) return (0.0<x and x<10.0) and math.abs(math.sin(math.pi * x * x)) > 0.5 end
)
local bb = createSet(
    0.0, 10.0,
    function(x) return (0.0<x and x<10.0) and math.abs(math.sin(math.pi * x)) > 0.5 end
)
local cc = aa.subtract(bb)
print("Approx length of A - B is "..cc.length())


<?php
$string = 'Rosetta Code';
echo sha1( $string ), "\n";
?>


(de leftRotate (X C)
   (| (mod32 (>> (- C) X)) (>> (- 32 C) X)) )

(de mod32 (N)
   (& N `(hex "FFFFFFFF")) )

(de not32 (N)
   (x| N `(hex "FFFFFFFF")) )

(de add32 @
   (mod32 (pass +)) )

(de sha1 (Str)
   (let Len (length Str)
      (setq Str
         (conc
            (need
               (-
                  8
                  (* 64 (/ (+ Len 1 8 63) 64)) )
               (conc
                  (mapcar char (chop Str))
                  (cons `(hex "80")) )
               0 )
            (flip
               (make
                  (setq Len (* 8 Len))
                  (do 8
                     (link (& Len 255))
                     (setq Len (>> 8 Len )) ) ) ) ) ) )
   (let
      (H0 `(hex "67452301")
         H1 `(hex "EFCDAB89")
         H2 `(hex "98BADCFE")
         H3 `(hex "10325476")
         H4 `(hex "C3D2E1F0") )
      (while Str
         (let
            (A H0  B H1  C H2  D H3  E H4
               W (conc
                    (make
                       (do 16
                          (link
                             (apply
                                |
                                (mapcar >> (-24 -16 -8 0) (cut 4 'Str)) ) ) ) )
                  (need 64 0) ) )
               (for (I 17 (>= 80 I) (inc I))
                  (set (nth W I)
                     (leftRotate
                        (x|
                           (get W (- I 3))
                           (get W (- I 8))
                           (get W (- I 14))
                           (get W (- I 16)) )
                        1 ) ) )
               (use (Tmp F K)
                  (for I 80
                     (cond
                        ((>= 20 I)
                           (setq
                              F (| (& B C) (& (not32 B) D))
                              K `(hex "5A827999") ) )
                        ((>= 40 I)
                           (setq
                              F (x| B C D)
                              K `(hex "6ED9EBA1") ) )
                        ((>= 60 I)
                           (setq
                              F (| (& B C) (& B D) (& C D))
                              K `(hex "8F1BBCDC") ) )
                        (T
                           (setq
                              F (x| B C D)
                              K `(hex "CA62C1D6") ) ) )
                     (setq
                        Tmp (add32 (leftRotate A 5) F E K (get W I) )
                        E D
                        D C
                        C (leftRotate B 30)
                        B A
                        A Tmp ) ) )
               (setq
                  H0 (add32 H0 A)
                  H1 (add32 H1 B)
                  H2 (add32 H2 C)
                  H3 (add32 H3 D)
                  H4 (add32 H4 E) ) ) )
      (mapcan
         '((N)
            (flip
               (make
                  (do 4
                     (link (& 255 N))
                     (setq N (>> 8 N)) ) ) ) )
         (list H0 H1 H2 H3 H4) ) ) )

(let Str "Rosetta Code"
   (println
      (pack
         (mapcar
            '((B) (pad 2 (hex B)))
            (sha1 Str) ) ) )
   (println
      (pack
         (mapcar
            '((B) (pad 2 (hex B)))
            (native
               "libcrypto.so"
               "SHA1"
               '(B . 20)
               Str
               (length Str)
               '(NIL (20)) ) ) ) ) )

(bye)


string input = "Rosetta Code";
string out = Crypto.SHA1.hash(input);
write( String.string2hex(out) +"\n");


Function Calculate-SHA1( $String ){
    $Enc = [system.Text.Encoding]::UTF8
    $Data = $enc.GetBytes($String)

    # Create a New SHA1 Crypto Provider
    $Sha = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider

    # Now hash and display results
    $Result = $sha.ComputeHash($Data)
    [System.Convert]::ToBase64String($Result)
}


(* defining functions *)
setcc[a_, b_] := a <= x <= b
setoo[a_, b_] := a < x < b
setco[a_, b_] := a <= x < b
setoc[a_, b_] := a < x <= b
setSubtract[s1_, s2_] := s1  &&  Not[s2];  (* new function; subtraction not built in *)
inSetQ[y_, set_] := set /. x -> y
(* testing sets *)
set1 = setoc[0, 1]  || setco[0, 2]  (* union built in as || shortcut (OR) *);
Print[set1]
Print["First trial set, (0, 1] ∪ [0, 2) , testing for {0,1,2}:"]
Print[inSetQ[#, set1] & /@ {0, 1, 2}]
set2 = setco[0, 2] && setoc[1, 2];  (* intersection built in as && shortcut (AND) *)
Print[]
Print[set2]
Print["Second trial set, [0, 2) ∩ (1, 2], testing for {0,1,2}:"]
Print[inSetQ[#, set2] & /@ {0, 1, 2}]
Print[]
set3 = setSubtract[setco[0, 3], setoo[0, 1]];
Print[set3]
Print["Third trial set, [0, 3) \[Minus] (0, 1), testing for {0,1,2}"]
Print[inSetQ[#, set3] & /@ {0, 1, 2}]
Print[]
set4 = setSubtract[setco[0, 3], setcc[0, 1]];
Print[set4]
Print["Fourth trial set, [0,3)\[Minus][0,1], testing for {0,1,2}:"]
Print[inSetQ[#, set4] & /@ {0, 1, 2}]


import math, strformat, sugar

type

  RealPredicate = (float) -> bool

  RangeType {.pure} = enum Closed, BothOpen, LeftOpen, RightOpen

  RealSet = object
    low, high: float
    predicate: RealPredicate

proc initRealSet(slice: Slice[float]; rangeType: RangeType): RealSet =
  result = RealSet(low: slice.a, high: slice.b)
  result.predicate = case rangeType
                     of Closed: (x: float) => x in slice
                     of BothOpen: (x: float) => slice.a < x and x < slice.b
                     of LeftOpen: (x: float) => slice.a < x and x <= slice.b
                     of RightOpen: (x: float) => slice.a <= x and x < slice.b

proc contains(s: RealSet; val: float): bool =
  ## Defining "contains" makes operator "in" available.
  s.predicate(val)

proc `+`(s1, s2: RealSet): RealSet =
  RealSet(low: min(s1.low, s2.low), high: max(s1.high, s2.high),
          predicate: (x:float) => s1.predicate(x) or s2.predicate(x))

proc `*`(s1, s2: RealSet): RealSet =
  RealSet(low: max(s1.low, s2.low), high: min(s1.high, s2.high),
          predicate: (x:float) => s1.predicate(x) and s2.predicate(x))

proc `-`(s1, s2: RealSet): RealSet =
  RealSet(low: s1.low, high: s1.high,
          predicate: (x:float) => s1.predicate(x) and not s2.predicate(x))

const Interval = 0.00001

proc length(s: RealSet): float =
  if s.low.classify() in {fcInf, fcNegInf} or s.high.classify() in {fcInf, fcNegInf}: return Inf
  if s.high <= s.low: return 0
  var p = s.low
  var count = 0.0
  while p < s.high:
    if s.predicate(p): count += 1
    p += Interval
  result = count * Interval

proc isEmpty(s: RealSet): bool =
  if s.high == s.low: not s.predicate(s.low)
  else: s.length == 0

when isMainModule:
  let
    a = initRealSet(0.0..1.0, LeftOpen)
    b = initRealSet(0.0..2.0, RightOpen)
    c = initRealSet(1.0..2.0, LeftOpen)
    d = initRealSet(0.0..3.0, RightOpen)
    e = initRealSet(0.0..1.0, BothOpen)
    f = initRealSet(0.0..1.0, Closed)
    g = initRealSet(0.0..0.0, Closed)

  for n in 0..2:
    let x = n.toFloat
    echo &"{n} ∊ (0, 1] ∪ [0, 2) is {x in (a + b)}"
    echo &"{n} ∊ [0, 2) ∩ (1, 2] is {x in (b * c)}"
    echo &"{n} ∊ [0, 3) − (0, 1) is {x in (d - e)}"
    echo &"{n} ∊ [0, 3) − [0, 1] is {x in (d - f)}\n"

  echo &"[0, 0] is empty is {g.isEmpty()}.\n"

  let
    aa = RealSet(low: 0, high: 10,
                 predicate: (x: float) => 0 < x and x < 10 and abs(sin(PI * x * x)) > 0.5)
    bb = RealSet(low: 0, high: 10,
                 predicate: (x: float) => 0 < x and x < 10 and abs(sin(PI * x)) > 0.5)
    cc = aa - bb

  echo &"Approximative length of A - B is {cc.length}."


a$="Rosetta Code"

UseSHA1Fingerprint() : b$=StringFingerprint(a$, #PB_Cipher_SHA1)

OpenConsole()
Print("[SHA1] Text: "+a$+" ==> "+b$)
Input()


import hashlib
h = hashlib.sha1()
h.update(bytes("Ars longa, vita brevis", encoding="ASCII"))
h.hexdigest()
# "e640d285242886eb96ab80cbf858389b3df52f43"


library(digest)

input <- "Rosetta Code"
cat(digest(input, algo = "sha1", serialize = FALSE), "\n")


#lang racket
(require file/sha1)
(sha1 (open-input-string "Rosetta Code"))


use utf8;

# numbers used as boundaries to real sets.  Each has 3 components:
#	the real value x;
#	a +/-1 indicating if it's x + ϵ or x - ϵ
#	a 0/1 indicating if it's the left border or right border
# e.g. "[1.5, ..." is written "1.5, -1, 0", while "..., 2)" is "2, -1, 1"
package BNum;

use overload (
	'""'	=> \&_str,
	'<=>'	=> \&_cmp,
);

sub new {
	my $self = shift;
	bless [@_], ref $self || $self
}

sub flip {
	my @a = @{+shift};
	$a[2] = !$a[2];
	bless \@a
}

my $brackets = qw/ [ ( ) ] /;
sub _str {
	my $v = sprintf "%.2f", $_[0][0];
	$_[0][2]
		? $v . ($_[0][1] == 1 ? "]" : ")")
		: ($_[0][1] == 1 ? "(" : "[" ) . $v;
}

sub _cmp {
	my ($a, $b, $swap) = @_;

	# if one of the argument is a normal number
	if ($swap) { return -_ncmp($a, $b) }
	if (!ref $b || !$b->isa(__PACKAGE__)) { return _ncmp($a, $b) }

	$a->[0] <=> $b->[0] || $a->[1] <=> $b->[1]
}

sub _ncmp {
	# $a is a BNum, $b is something comparable to a real
	my ($a, $b) = @_;
	$a->[0] <=> $b || $a->[1] <=> 0
}

package RealSet;
use Carp;
use overload (
	'""'	=> \&_str,
	'|'	=> \&_or,
	'&'	=> \&_and,
	'~'	=> \&_neg,
	'-'	=> \&_diff,
	'bool'	=> \&not_empty, # set is true if not empty
);

my %pm = qw/ [ -1 ( 1 ) -1 ] 1 /;
sub range {
	my ($cls, $a, $b, $spec) = @_;
	$spec =~ /^( \[ | \( )( \) | \] )$/x	or croak "bad spec $spec";

	$a = BNum->new($a, $pm{$1}, 0);
	$b = BNum->new($b, $pm{$2}, 1);
	normalize($a < $b ? [$a, $b] : [])
}

sub normalize {
	my @a = @{+shift};
	# remove invalid or duplicate borders, such as "[2, 1]" or "3) [3"
	# note that "(a" == "a]" and "a)" == "[a", but "a)" < "(a" and
	# "[a" < "a]"
	for (my $i = $#a; $i > 0; $i --) {
		splice @a, $i - 1, 2
			if $a[$i] <= $a[$i - 1]
	}
	bless \@a
}

sub not_empty { scalar @{ normalize shift } }

sub _str {
	my (@a, @s) = @{+shift}		or return '()';
	join " ∪ ", map { shift(@a).", ".shift(@a) } 0 .. $#a/2
}

sub _or {
	# we may have nested ranges now; let only outmost ones survive
	my $d = 0;
	normalize [
		map {	$_->[2] ? --$d ? () : ($_)
				: $d++ ? () : ($_) }
		sort{ $a <=> $b } @{+shift}, @{+shift}
	];
}

sub _neg {
	normalize [
		BNum->new('-inf', 1, 0),
		map($_->flip, @{+shift}),
		BNum->new('inf', -1, 1),
	]
}

sub _and {
	my $d = 0;
	normalize [
		map {	$_->[2] ? --$d ? ($_) : ()
				: $d++ ? ($_) : () }
		sort{ $a <=> $b } @{+shift}, @{+shift}
	];
}

sub _diff { shift() & ~shift() }

sub has {
	my ($a, $b) = @_;
	for (my $i = 0; $i < $#$a; $i += 2) {
		return 1 if $a->[$i] <= $b && $b <= $a->[$i + 1]
	}
	return 0
}

sub len {
	my ($a, $l) = shift;
	for (my $i = 0; $i < $#$a; $i += 2) {
		$l += $a->[$i+1][0] - $a->[$i][0]
	}
	return $l
}

package main;
use List::Util 'reduce';

sub rng { RealSet->range(@_) }
my @sets = (
	rng(0, 1, '(]') | rng(0, 2, '[)'),
	rng(0, 2, '[)') & rng(0, 2, '(]'),
	rng(0, 3, '[)') - rng(0, 1, '()'),
	rng(0, 3, '[)') - rng(0, 1, '[]'),
);

for my $i (0 .. $#sets) {
	print "Set $i = ", $sets[$i], ": ";
	for (0 .. 2) {
		print "has $_; " if $sets[$i]->has($_);
	}
	print "\n";
}

# optional task
print "\n####\n";
sub brev { # show only head and tail if string too long
	my $x = shift;
	return $x if length $x < 60;
	substr($x, 0, 30)." ... ".substr($x, -30, 30)
}

# "|sin(x)| > 1/2" means (n + 1/6) pi < x < (n + 5/6) pi
my $x = reduce { $a | $b }
	map(rng(sqrt($_ + 1./6), sqrt($_ + 5./6), '()'), 0 .. 101);
$x &= rng(0, 10, '()');

print "A\t", '= {x | 0 < x < 10 and |sin(π x²)| > 1/2 }',
	"\n\t= ", brev($x), "\n";

my $y = reduce { $a | $b }
	map { rng($_ + 1./6, $_ + 5./6, '()') } 0 .. 11;
$y &= rng(0, 10, '()');

print "B\t", '= {x | 0 < x < 10 and |sin(π x)| > 1/2 }',
	"\n\t= ", brev($y), "\n";

my $z = $x - $y;
print "A - B\t= ", brev($z), "\n\tlength = ", $z->len, "\n";
print $z ? "not empty\n" : "empty\n";


sub postfix:<mod2³²> { $^x % 2**32 }
sub infix:<⊕>        { ($^x + $^y)mod2³² }
sub S                { ($^x +< $^n)mod2³² +| ($x +> (32-$n)) }

my \f = -> \B,\C,\D { (B +& C) +| ((+^B)mod2³² +& D)   },
        -> \B,\C,\D { B +^ C +^ D                      },
        -> \B,\C,\D { (B +& C) +| (B +& D) +| (C +& D) },
        -> \B,\C,\D { B +^ C +^ D                      };

my \K = 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6;

sub sha1-pad(Blob $msg)
{
    my \bits = 8 * $msg.elems;
    my @padded = flat $msg.list, 0x80, 0x00 xx (-($msg.elems + 1 + 8) % 64);
    flat @padded.map({ :256[$^a,$^b,$^c,$^d] }), (bits +> 32)mod2³², (bits)mod2³²;
}

sub sha1-block(@H, @M is copy)
{
    @M.push: S(1, [+^] @M[$_ «-« <3 8 14 16>] ) for 16 .. 79;

    my ($A,$B,$C,$D,$E) = @H;
    for 0..79 -> \t {
        ($A, $B, $C, $D, $E) =
        S(5,$A) ⊕ f[t div 20]($B,$C,$D) ⊕ $E ⊕ @M[t] ⊕ K[t div 20],
        $A, S(30,$B), $C, $D;
    }
    @H »⊕=« ($A,$B,$C,$D,$E);
}

sub sha1(Blob $msg) returns Blob
{
    my @M = sha1-pad($msg);
    my @H = 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0;
    sha1-block(@H,@M[$_..$_+15]) for 0, 16...^ +@M;
    Blob.new: flat map { reverse .polymod(256 xx 3) }, @H;
}

say sha1(.encode('ascii')), "  $_"
   for 'abc',
       'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
       'Rosetta Code',
       'Ars longa, vita brevis';


with javascript_semantics
enum ID,ARGS
function cf(sequence f, atom x) return call_func(f[ID],deep_copy(f[ARGS])&x) end function
function Union(sequence a, b, atom x) return cf(a,x)  or     cf(b,x) end function
function Inter(sequence a, b, atom x) return cf(a,x) and     cf(b,x) end function
function Diffr(sequence a, b, atom x) return cf(a,x) and not cf(b,x) end function
function OpOp(atom a, b, x)           return a <  x and x <  b       end function
function ClCl(atom a, b, x)           return a <= x and x <= b       end function
function OpCl(atom a, b, x)           return a <  x and x <= b       end function
function ClOp(atom a, b, x)           return a <= x and x <  b       end function

--                              expected
--              ---- desc ----,  0 1 2,  --------------- set method ---------------
constant s = {{"(0,1] u [0,2)", {1,1,0}, {Union,{{OpCl,{0,1}},{ClOp,{0,2}}}}},
              {"[0,2) n (1,2]", {0,0,0}, {Inter,{{ClOp,{0,2}},{OpCl,{1,2}}}}},
              {"[0,3) - (0,1)", {1,1,1}, {Diffr,{{ClOp,{0,3}},{OpOp,{0,1}}}}},
              {"[0,3) - [0,1]", {0,0,1}, {Diffr,{{ClOp,{0,3}},{ClCl,{0,1}}}}}}

for i=1 to length(s) do
    sequence {desc, expect, method} = s[i]
    for x=0 to 2 do
        bool r = cf(method,x)
        string error = iff(r!=expect[x+1]?"error":"")
        printf(1,"%d in %s : %t %s\n", {x, desc, r, error})
    end for
    printf(1,"\n")
end for


# Project : SHA-1

load "stdlib.ring"
str = "Rosetta Code"
see "String: " + str + nl
see "SHA-1: "
see sha1(str) + nl


require 'digest'
puts Digest::SHA1.hexdigest('Rosetta Code')


use sha1::Sha1;

fn main() {
    let mut hash_msg = Sha1::new();
    hash_msg.update(b"Rosetta Code");
    println!("{}", hash_msg.digest().to_string());
}


class Setr():
    def __init__(self, lo, hi, includelo=True, includehi=False):
        self.eqn = "(%i<%sX<%s%i)" % (lo,
                                      '=' if includelo else '',
                                      '=' if includehi else '',
                                      hi)

    def __contains__(self, X):
        return eval(self.eqn, locals())

    # union
    def __or__(self, b):
        ans = Setr(0,0)
        ans.eqn = "(%sor%s)" % (self.eqn, b.eqn)
        return ans

    # intersection
    def __and__(self, b):
        ans = Setr(0,0)
        ans.eqn = "(%sand%s)" % (self.eqn, b.eqn)
        return ans

    # difference
    def __sub__(self, b):
        ans = Setr(0,0)
        ans.eqn = "(%sand not%s)" % (self.eqn, b.eqn)
        return ans

    def __repr__(self):
        return "Setr%s" % self.eqn

sets = [
    Setr(0,1, 0,1) | Setr(0,2, 1,0),
    Setr(0,2, 1,0) & Setr(1,2, 0,1),
    Setr(0,3, 1,0) - Setr(0,1, 0,0),
    Setr(0,3, 1,0) - Setr(0,1, 1,1),
]
settexts = '(0, 1] ∪ [0, 2);[0, 2) ∩ (1, 2];[0, 3) − (0, 1);[0, 3) − [0, 1]'.split(';')

for s,t in zip(sets, settexts):
    print("Set %s %s. %s" % (t,
                             ', '.join("%scludes %i"
                                     % ('in' if v in s else 'ex', v)
                                     for v in range(3)),
                             s.eqn))


import java.nio._

case class Hash(message: List[Byte]) {
  val defaultHashes = List(0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0)

  val hash = {
    val padded = generatePadding(message)
    val chunks: List[List[Byte]] = messageToChunks(padded)
    toHashForm(hashesFromChunks(chunks))
  }

  def generatePadding(message: List[Byte]): List[Byte] = {
    val finalPadding = BigInt(message.length * 8).toByteArray match {
      case x => List.fill(8 - x.length)(0.toByte) ++ x
    }
    val padding = (message.length + 1) % 64 match {
      case l if l < 56 =>
        message ::: 0x80.toByte :: List.fill(56 - l)(0.toByte)
      case l =>
        message ::: 0x80.toByte :: List.fill((64 - l) + 56 + 1)(0.toByte)
    }
    padding ::: finalPadding
  }

  def toBigEndian(bytes: List[Byte]) =
    ByteBuffer.wrap(bytes.toArray).getInt

  def messageToChunks(message: List[Byte]) =
    message.grouped(64).toList

  def chunkToWords(chunk: List[Byte]) =
    chunk.grouped(4).map(toBigEndian).toList

  def extendWords(words: List[Int]): List[Int] = words.length match {
    case i if i < 80 => extendWords(words :+ Integer.rotateLeft(
      (words(i - 3) ^ words(i - 8) ^ words(i - 14) ^ words(i - 16)), 1))
    case _ => words
  }

  def generateFK(i: Int, b: Int, c: Int, d: Int) = i match {
    case i if i < 20 => (b & c | ~b & d, 0x5A827999)
    case i if i < 40 => (b ^ c ^ d, 0x6ED9EBA1)
    case i if i < 60 => (b & c | b & d | c & d, 0x8F1BBCDC)
    case i if i < 80 => (b ^ c ^ d, 0xCA62C1D6)
  }

  def generateHash(words: List[Int], prevHash: List[Int]): List[Int] = {
    def generateHash(i: Int, currentHashes: List[Int]): List[Int] = i match {
      case i if i < 80 => currentHashes match {
        case a :: b :: c :: d :: e :: Nil => {
          val (f, k) = generateFK(i, b, c, d)
          val x = Integer.rotateLeft(a, 5) + f + e + k + words(i)
          val t = Integer.rotateLeft(b, 30)
          generateHash(i + 1, x :: a :: t :: c :: d :: Nil)
        }
      }
      case _ => currentHashes
    }
    addHashes(prevHash, generateHash(0, prevHash))
  }

  def addHashes(xs: List[Int], ys: List[Int]) = (xs, ys).zipped.map(_ + _)

  def hashesFromChunks(chunks: List[List[Byte]],
                        remainingHash: List[Int] = defaultHashes): List[Int] =
    chunks match {
      case Nil => remainingHash
      case x :: xs => {
        val words = extendWords(chunkToWords(x))
        val newHash = generateHash(words, remainingHash)
        hashesFromChunks(xs, newHash)
      }
    }

  def toHashForm(hashes: List[Int]) =
    hashes.map(b => ByteBuffer.allocate(4)
      .order(ByteOrder.BIG_ENDIAN).putInt(b).array.toList)
      .map(bytesToHex).mkString

  def bytesToHex(bytes: List[Byte]) =
    (for (byte <- bytes) yield (Character.forDigit((byte >> 4) & 0xF, 16) ::
      Character.forDigit((byte & 0xF), 16) :: Nil).mkString).mkString
}

object Hash extends App {
  def hash(message: String) = new Hash(message.getBytes.toList).hash

  println(hash("Rosetta Code"))
}


package Set_Puzzle is

   type Three is range 1..3;
   type Card is array(1 .. 4) of Three;
   type Cards is array(Positive range <>) of Card;
   type Set is array(Three) of Positive;

   procedure Deal_Cards(Dealt: out Cards);
   -- ouputs an array with disjoint cards

   function To_String(C: Card) return String;

   generic
      with procedure Do_something(C: Cards; S: Set);
   procedure Find_Sets(Given: Cards);
   -- calls Do_Something once for each set it finds.

end Set_Puzzle;


#lang racket

;; Use a macro to allow infix operators
(require (only-in racket [#%app #%%app]))
(define-for-syntax infixes '())
(define-syntax (definfix stx)
  (syntax-case stx ()
    [(_ (x . xs) body ...) #'(definfix x (λ xs body ...))]
    [(_ x body) (begin (set! infixes (cons #'x infixes)) #'(define x body))]))
(define-syntax (#%app stx)
  (syntax-case stx ()
    [(_ X op Y)
     (and (identifier? #'op) (ormap (λ(o) (free-identifier=? #'op o)) infixes))
     #'(#%%app op X Y)]
    [(_ f x ...) #'(#%%app f x ...)]))

;; Ranges: (X +-+ Y) => [X,Y]; (X --- Y) => (X,Y); and same for `+--' and `--+'
;; Simple implementation as functions

;; Constructors
(definfix ((+-+ X Y) n) (<= X n Y))             ; [X,Y]
(definfix ((--- X Y) n) (< X n Y))              ; (X,Y)
(definfix ((+-- X Y) n) (and (<= X n) (< n Y))) ; [X,Y)
(definfix ((--+ X Y) n) (and (< X n) (<= n Y))) ; (X,Y]
(definfix ((== X) n) (= X n))                   ; [X,X]
;; Set operations
(definfix ((∪ . Rs) n)  (ormap  (λ(p) (p n)) Rs))
(definfix ((∩ . Rs) n)  (andmap (λ(p) (p n)) Rs))
(definfix ((∖ R1 R2) n) (and (R1 n) (not (R2 n)))) ; set-minus, not backslash
(define ((¬ R) n) (not (R n)))
;; Special sets
(define (∅ n) #f)
(define (ℜ n) #t)

(define-syntax-rule (try set)
  (apply printf "~a => ~a ~a ~a\n" (~s #:width 23 'set)
         (let ([pred set]) (for/list ([i 3]) (if (pred i) 'Y 'N)))))
(try ((0 --+ 1) ∪ (0 +-- 2)))
(try ((0 +-- 2) ∩ (1 --+ 2)))
(try ((0 +-- 3) ∖ (0 --- 1)))
(try ((0 +-- 3) ∖ (0 +-+ 1)))


class Iv {
    has $.range handles <min max excludes-min excludes-max minmax ACCEPTS>;
    method empty {
	$.min after $.max or $.min === $.max && ($.excludes-min || $.excludes-max)
    }
    multi method Bool() { not self.empty };
    method length() { $.max - $.min }
    method gist() {
	($.excludes-min ?? '(' !! '[') ~
	$.min ~ ',' ~ $.max ~
	($.excludes-max ?? ')' !! ']');
    }
}

class IvSet {
    has Iv @.intervals;

    sub canon (@i) {
	my @new = consolidate(|@i).grep(*.so);
	@new.sort(*.range.min);
    }

    method new(@ranges) {
	my @iv = canon @ranges.map: { Iv.new(:range($_)) }
	self.bless(:intervals(@iv));
    }

    method complement {
	my @new;
	my @old = @!intervals;
	if not @old {
	    return iv -Inf..Inf;
	}
	my $pre;
	push @old, Inf^..Inf unless @old[*-1].max === Inf;
	if @old[0].min === -Inf {
	    $pre = @old.shift;
	}
	else {
	    $pre = -Inf..^-Inf;
	}
	while @old {
	    my $old = @old.shift;
	    my $excludes-min = !$pre.excludes-max;
	    my $excludes-max = !$old.excludes-min;
	    push @new, Range.new($pre.max,$old.min,:$excludes-min,:$excludes-max);
	    $pre = $old;
	}
	IvSet.new(@new);
    }

    method ACCEPTS(IvSet:D $me: $candidate) {
	so $.intervals.any.ACCEPTS($candidate);
    }
    method empty { so $.intervals.all.empty }
    multi method Bool() { not self.empty };

    method length() { [+] $.intervals».length }
    method gist() { join ' ', $.intervals».gist }
}

sub iv(**@ranges) { IvSet.new(@ranges) }

multi infix:<∩> (Iv $a, Iv $b) {
    if $a.min ~~ $b or $a.max ~~ $b or $b.min ~~ $a or $b.max ~~ $a {
	my $min = $a.range.min max $b.range.min;
	my $max = $a.range.max min $b.range.max;
	my $excludes-min = not $min ~~ $a & $b;
	my $excludes-max = not $max ~~ $a & $b;
	Iv.new(:range(Range.new($min,$max,:$excludes-min, :$excludes-max)));
    }
}
multi infix:<∪> (Iv $a, Iv $b) {
    my $min = $a.range.min min $b.range.min;
    my $max = $a.range.max max $b.range.max;
    my $excludes-min = not $min ~~ $a | $b;
    my $excludes-max = not $max ~~ $a | $b;
    Iv.new(:range(Range.new($min,$max,:$excludes-min, :$excludes-max)));
}

multi infix:<∩> (IvSet $ars, IvSet $brs) {
    my @overlap;
    for $ars.intervals -> $a {
	for $brs.intervals -> $b {
	    if $a.min ~~ $b or $a.max ~~ $b or $b.min ~~ $a or $b.max ~~ $a {
		my $min = $a.range.min max $b.range.min;
		my $max = $a.range.max min $b.range.max;
		my $excludes-min = not $min ~~ $a & $b;
		my $excludes-max = not $max ~~ $a & $b;
		push @overlap, Range.new($min,$max,:$excludes-min, :$excludes-max);
	    }
	}
    }
    IvSet.new(@overlap)
}

multi infix:<∪> (IvSet $a, IvSet $b) {
    iv |$a.intervals».range, |$b.intervals».range;
}

multi consolidate() { () }
multi consolidate($this is copy, *@those) {
    gather {
        for consolidate |@those -> $that {
            if $this ∩ $that { $this ∪= $that }
            else             { take $that }
        }
        take $this;
    }
}

multi infix:<−> (IvSet $a, IvSet $b) { $a ∩ $b.complement }

multi prefix:<−> (IvSet $a) { $a.complement; }

constant ℝ = iv -Inf..Inf;

my $s1 = iv(0^..1) ∪ iv(0..^2);
my $s2 = iv(0..^2) ∩ iv(1^..2);
my $s3 = iv(0..^3) − iv(0^..^1);
my $s4 = iv(0..^3) − iv(0..1) ;

say "\t\t\t\t0\t1\t2";
say "(0, 1] ∪ [0, 2) -> $s1.gist()\t", 0 ~~ $s1,"\t", 1 ~~ $s1,"\t", 2 ~~ $s1;
say "[0, 2) ∩ (1, 2] -> $s2.gist()\t", 0 ~~ $s2,"\t", 1 ~~ $s2,"\t", 2 ~~ $s2;
say "[0, 3) − (0, 1) -> $s3.gist()\t", 0 ~~ $s3,"\t", 1 ~~ $s3,"\t", 2 ~~ $s3;
say "[0, 3) − [0, 1] -> $s4.gist()\t", 0 ~~ $s4,"\t", 1 ~~ $s4,"\t", 2 ~~ $s4;

say '';

say "ℝ is not empty: ", !ℝ.empty;
say "[0,3] − ℝ is empty: ", not iv(0..3) − ℝ;

my $A = iv(0..10) ∩
   iv |(0..10).map({ $_ - 1/6 .. $_ + 1/6 }).cache;

my $B = iv 0..sqrt(1/6),
      |(1..99).map({ sqrt($_-1/6) .. sqrt($_ + 1/6) }), sqrt(100-1/6)..10;

say 'A − A is empty: ', not $A − $A;

say '';

my $C = $A − $B;
say "A − B =";
say "  ",.gist for $C.intervals;
say "Length A − B = ", $C.length;


; band - binary AND operation
; bor - binary OR operation
; bxor - binary XOR operation
; >>, << - binary shift operations
; runes->string - convert byte list to string /(runes->string '(65 66 67 65)) => "ABCA"/

(define (sha1-padding-size n)
   (let ((x (mod (- 56 (rem n 64)) 64)))
      (if (= x 0) 64 x)))

(define (sha1-pad-message message)
   (let*((message-len (string-length message))
         (message-len-in-bits (* message-len 8))
         (buffer-len (+ message-len 8 (sha1-padding-size message-len)))
         (message (string-append message (runes->string '(#b10000000))))
         (zeroes-len (- buffer-len message-len 1 4)) ; for ending length encoded value
         (message (string-append message (make-string zeroes-len 0)))
         (message (string-append message (runes->string (list
            (band (>> message-len-in-bits 24) #xFF)
            (band (>> message-len-in-bits 16) #xFF)
            (band (>> message-len-in-bits  8) #xFF)
            (band (>> message-len-in-bits  0) #xFF))))))
;      (print "message-len: " message-len)
;      (print "message-len-in-bits: " message-len-in-bits)
;      (print "buffer-len: " buffer-len)
;      (print "zeroes-len: " zeroes-len)
;      (print "message: " message)
;      (print "length(message): " (string-length message))
      message))

(define XOR (lambda args (fold bxor 0 args))) ; bxor more than 2 arguments
(define OR (lambda args (fold bor 0 args))) ; bor more than 2 arguments
(define NOT (lambda (arg) (bxor arg #xFFFFFFFF))) ; binary not operation

; to 32-bit number
(define (->32 i)
   (band i #xFFFFFFFF))

; binary cycle rotate left
(define (rol bits x)
   (->32
      (bor
         (<< x bits)
         (>> x (- 32 bits)))))

(define (word->list x)
   (list
      (band (>> x 24) #xFF)
      (band (>> x 16) #xFF)
      (band (>> x  8) #xFF)
      (band (>> x  0) #xFF)))

(define (message->words message)
   (let cycle ((W
               (let loop ((t (iota 0 1 16)))
                  (if (null? t)
                     null
                  (let*((p (* (car t) 4)))
                     (cons (OR
                              (<< (string-ref message (+ p 0)) 24)
                              (<< (string-ref message (+ p 1)) 16)
                              (<< (string-ref message (+ p 2))  8)
                              (<< (string-ref message (+ p 3))  0))
                           (loop (cdr t)))))))
               (t 16))
      (if (eq? t 80)
         W
         (cycle (append W (list
            (XOR
               (rol 1 (list-ref W (- t 3)))
               (rol 1 (list-ref W (- t 8)))
               (rol 1 (list-ref W (- t 14)))
               (rol 1 (list-ref W (- t 16))))))
            (+ t 1)))))

(define (sha1:digest message)
   (let*((h0 #x67452301)
         (h1 #xEFCDAB89)
         (h2 #x98BADCFE)
         (h3 #x10325476)
         (h4 #xC3D2E1F0)
         (K '(#x5A827999 #x6ED9EBA1 #x8F1BBCDC #xCA62C1D6))
         (padded-message (sha1-pad-message message))
         (n (/ (string-length padded-message) 64)))

      (let main ((i 0)
                 (A h0) (B h1) (C h2) (D h3) (E h4))
         (if (= i n)
            (fold append null
               (list (word->list A) (word->list B) (word->list C) (word->list D) (word->list E)))
            (let*((message (substring padded-message (* i 64) (+ (* i 64) 64)))
                  (W (message->words message)))
               (let*((a b c d e ; round 1
                        (let loop ((a A) (b B) (c C) (d D) (e E) (t 0))
                           (if (< t 20)
                              (loop (->32
                                          (+ (rol 5 a)
                                             (OR (band b c) (band (NOT b) d))
                                             e
                                             (list-ref W t)
                                             (list-ref K 0)))
                                    a
                                    (rol 30 b)
                                    c
                                    d
                                    (+ t 1))
                              (values a b c d e))))
                     (a b c d e ; round 2
                        (let loop ((a a) (b b) (c c) (d d) (e e) (t 20))
                           (if (< t 40)
                              (loop (->32
                                          (+ (rol 5 a)
                                             (XOR b c d)
                                             e
                                             (list-ref W t)
                                             (list-ref K 1)))
                                    a
                                    (rol 30 b)
                                    c
                                    d
                                    (+ t 1))
                              (values a b c d e))))
                     (a b c d e ; round 3
                        (let loop ((a a) (b b) (c c) (d d) (e e) (t 40))
                           (if (< t 60)
                              (loop (->32
                                          (+ (rol 5 a)
                                             (OR (band b c) (band b d) (band c d))
                                             e
                                             (list-ref W t)
                                             (list-ref K 2)))
                                    a
                                    (rol 30 b)
                                    c
                                    d
                                    (+ t 1))
                              (values a b c d e))))
                     (a b c d e ; round 4
                        (let loop ((a a) (b b) (c c) (d d) (e e) (t 60))
                           (if (< t 80)
                              (loop (->32
                                          (+ (rol 5 a)
                                             (XOR b c d)
                                             e
                                             (list-ref W t)
                                             (list-ref K 3)))
                                    a
                                    (rol 30 b)
                                    c
                                    d
                                    (+ t 1))
                              (values a b c d e)))))

                  (main (+ i 1)
                     (->32 (+ A a))
                     (->32 (+ B b))
                     (->32 (+ C c))
                     (->32 (+ D d))
                     (->32 (+ E e)))))))))


; Generate deck; card encoding from Raku
Loop, 81
	deck .= ToBase(A_Index-1, 3)+1111 ","
deck := RegExReplace(deck, "3", "4")

; Shuffle
deck := shuffle(deck)

msgbox % clipboard := allValidSets(9, 4, deck)
msgbox % clipboard := allValidSets(12, 6, deck)

; Render a hand (or any list) of cards
PrettyHand(hand) {
	 Color1:="red",Color2:="green",Color4:="purple"
	,Symbl1:="oval",Symbl2:="squiggle",Symbl4:="diamond"
	,Numbr1:="one",Numbr2:="two",Numbr4:="three"
	,Shape1:="solid",Shape2:="open",Shape4:="striped"
	Loop, Parse, hand, `,
	{
		StringSplit, i, A_LoopField
		s .= "`t" Color%i1% "`t" Symbl%i2% "`t" Numbr%i3% "`t" Shape%i4% "`n"
	}
	Return s
}

; Get all unique valid sets of three cards in a hand.
allValidSets(n, m, deck) {
	While j != m
	{
		j := 0
		,hand := draw(n, deck)
		,s := "Dealt " n " cards:`n" . prettyhand(hand)
		StringSplit, set, hand, `,
		comb := comb(n,3)
		Loop, Parse, comb, `n
		{
			StringSplit, i, A_LoopField, %A_Space%
			If isValidSet(set%i1%, set%i2%, set%i3%)
				s .= "`nSet " ++j ":`n" . prettyhand(set%i1% "," set%i2% "," set%i3%)
		}
	}
	Return s
}

; Convert n to arbitrary base using recursion
toBase(n,b) {  ; n >= 0, 1 < b < StrLen(t), t = digits
	Static t := "0123456789ABCDEF"
	Return (n < b ? "" : ToBase(n//b,b)) . SubStr(t,mod(n,b)+1,1)
}

; Knuth shuffle from http://rosettacode.org/wiki/Knuth_Shuffle#AutoHotkey
shuffle(list) {									; shuffle comma separated list, converted to array
	StringSplit a, list, `,						; make array (length = a0)
	Loop % a0-1 {
		Random i, A_Index, a0					; swap item 1,2... with a random item to the right of it
		t := a%i%, a%i% := a%A_Index%, a%A_Index% := t
	}
	Loop % a0									; construct string from sorted array
		s .= "," . a%A_Index%
	Return SubStr(s,2)							; drop leading comma
}

; Randomly pick a hand of cards from the deck
draw(n, deck) {
	Loop, % n
	{
		Random, i, 1, 81
		cards := deck
		Loop, Parse, cards, `,
			(A_Index = i) ? (hand .= A_LoopField ",") : (cards .= A_LoopField ",")
		deck := cards
	}
	Return SubStr(hand, 1, -1)
}

; Test if a particular group of three cards is a valid set
isValidSet(a, b, c) {
	StringSplit, a, a
	StringSplit, b, b
	StringSplit, c, c
	Return !((a1|b1|c1 ~= "[3,5,6]") + (a2|b2|c2 ~= "[3,5,6]") + (a3|b3|c3 ~= "[3,5,6]") + (a4|b4|c4 ~= "[3,5,6]"))
}

; Get all combinations, from http://rosettacode.org/wiki/Combinations#AutoHotkey
comb(n,t) { ; Generate all n choose t combinations of 1..n, lexicographically
	IfLess n,%t%, Return
	Loop %t%
		c%A_Index% := A_Index
	i := t+1, c%i% := n+1

	Loop {
		Loop %t%
			i := t+1-A_Index, c .= c%i% " "
		c .= "`n"	  ; combinations in new lines
		j := 1, i := 2
		Loop
			If (c%j%+1 = c%i%)
				 c%j% := j, ++j, ++i
			Else Break
		If (j > t)
			Return c
		c%j% += 1
	}
}


/*REXX program  demonstrates  a way to  represent any set of real numbers  and  usage.  */
call quertySet 1, 3,  '[1,2)'
call quertySet ,   ,  '[0,2)   union   (1,3)'
call quertySet ,   ,  '[0,1)   union   (2,3]'
call quertySet ,   ,  '[0,2]   inter   (1,3)'
call quertySet ,   ,  '(1,2)     ∩     (2,3]'
call quertySet ,   ,  '[0,2)     \     (1,3)'
say;                                      say center(' start of required tasks ', 40, "═")
call quertySet ,   ,  '(0,1]   union   [0,2)'
call quertySet ,   ,  '[0,2)     ∩     (1,3)'
call quertySet ,   ,  '[0,3]     -     (0,1)'
call quertySet ,   ,  '[0,3]     -     [0,1]'
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
emptySet:  parse arg _;               nam= valSet(_, 00);              return @.3>@.4
/*──────────────────────────────────────────────────────────────────────────────────────*/
isInSet:   parse arg #,x;             call valSet x
           if \datatype(#, 'N')       then call set_bad "number isn't not numeric:" #
           if (@.1=='(' &  #<[email protected].2) |,
              (@.1=='[' &  #< @.2) |,
              (@.4==')' &  #>[email protected].3) |,
              (@.4==']' &  #> @.3)    then return 0
           return 1
/*──────────────────────────────────────────────────────────────────────────────────────*/
quertySet: parse arg lv,hv,s1 oop s2 .;  op=oop;   upper op;      cop=
           if lv==''  then lv=0;      if hv==""  then hv= 2;      if op==''  then cop=  0
           if wordpos(op, '| or UNION')                 \==0                 then cop= "|"
           if wordpos(op, '& ∩ AND INTER INTERSECTION') \==0                 then cop= "&"
           if wordpos(op, '\ - DIF DIFF DIFFERENCE')    \==0                 then cop= "\"
           say
                   do i=lv  to hv;  b = isInSet(i, s1)
                   if cop\==0  then do
                                    b2= isInSet(i, s2)
                                    if cop=='&'  then b= b & b2
                                    if cop=='|'  then b= b | b2
                                    if cop=='\'  then b= b & \b2
                                    end
                   express = s1 center(oop, max(5, length(oop) ) )    s2
                   say right(i, 5)    ' is in set'     express": "   word('no yes', b+1)
                   end   /*i*/
           return
/*──────────────────────────────────────────────────────────────────────────────────────*/
valSet:    parse arg q;   q=space(q, 0);    L=length(q);     @.0= ',';     @.4= right(q,1)
           parse var q    @.1  2  @.2  ','  @.3  (@.4)
           if @.2>@.3  then parse var L   . @.0  @.2  @.3
           return space(@.1 @.2 @.0 @.3 @.4, 0)


$ include "seed7_05.s7i";
  include "msgdigest.s7i";

const proc: main is func
  begin
    writeln(hex(sha1("Rosetta Code")));
  end func;


var sha = frequire('Digest::SHA');
say sha.sha1_hex('Rosetta Code');


PackageLoader fileInPackage: 'Digest'.
(SHA1 hexDigestOf: 'Rosetta Code') displayNl.


package require sha1
puts [sha1::sha1 "Rosetta Code"]


#include <stdio.h>
#include <stdlib.h>

char *names[4][3] = {
	{ "red", "green", "purple" },
	{ "oval", "squiggle", "diamond" },
	{ "one", "two", "three" },
	{ "solid", "open", "striped" }
};

int set[81][81];

void init_sets(void)
{
	int i, j, t, a, b;
	for (i = 0; i < 81; i++) {
		for (j = 0; j < 81; j++) {
			for (t = 27; t; t /= 3) {
				a = (i / t) % 3;
				b = (j / t) % 3;
				set[i][j] += t * (a == b ? a : 3 - a - b);
			}
		}
	}
}

void deal(int *out, int n)
{
	int i, j, t, c[81];
	for (i = 0; i < 81; i++) c[i] = i;
	for (i = 0; i < n; i++) {
		j = i + (rand() % (81 - i));
		t = c[i], c[i] = out[i] = c[j], c[j] = t;
	}
}

int get_sets(int *cards, int n, int sets[][3])
{
	int i, j, k, s = 0;
	for (i = 0; i < n; i++) {
		for (j = i + 1; j < n; j++) {
			for (k = j + 1; k < n; k++) {
				if (set[cards[i]][cards[j]] == cards[k])
					sets[s][0] = i,
					sets[s][1] = j,
					sets[s][2] = k,
					s++;
			}
		}
	}

	return s;
}

void show_card(int c)
{
	int i, t;
	for (i = 0, t = 27; t; i++, t /= 3)
		printf("%9s", names[i][(c/t)%3]);
	putchar('\n');
}

void deal_sets(int ncard, int nset)
{
	int c[81];
	int csets[81][3]; // might not be enough for large ncard
	int i, j, s;

	do deal(c, ncard); while ((s = get_sets(c, ncard, csets)) != nset);

	printf("dealt %d cards\n", ncard);
	for (i = 0; i < ncard; i++) {
		printf("%2d:", i);
		show_card(c[i]);
	}
	printf("\nsets:\n");

	for (i = 0; i < s; i++) {
		for (j = 0; j < 3; j++) {
			printf("%2d:", csets[i][j]);
			show_card(c[csets[i][j]]);
		}
		putchar('\n');
	}
}

int main(void)
{
	init_sets();
	deal_sets(9, 4);

	while (1) deal_sets(12, 6);

	return 0;
}


class Rset
  Set = Struct.new(:lo, :hi, :inc_lo, :inc_hi) do
    def include?(x)
      (inc_lo ? lo<=x : lo<x) and (inc_hi ? x<=hi : x<hi)
    end
    def length
      hi - lo
    end
    def to_s
      "#{inc_lo ? '[' : '('}#{lo},#{hi}#{inc_hi ? ']' : ')'}"
    end
  end

  def initialize(lo=nil, hi=nil, inc_lo=false, inc_hi=false)
    if lo.nil? and hi.nil?
      @sets = []            # empty set
    else
      raise TypeError      unless lo.is_a?(Numeric) and hi.is_a?(Numeric)
      raise ArgumentError  unless valid?(lo, hi, inc_lo, inc_hi)
      @sets = [Set[lo, hi, !!inc_lo, !!inc_hi]]         # !! -> Boolean values
    end
  end

  def self.[](lo, hi, inc_hi=true)
    self.new(lo, hi, true, inc_hi)
  end

  def self.parse(str)
    raise ArgumentError  unless str =~ /(\[|\()(.+),(.+)(\]|\))/
    b0, lo, hi, b1 = $~.captures        # $~ : Regexp.last_match
    lo = Rational(lo)
    lo = lo.numerator  if lo.denominator == 1
    hi = Rational(hi)
    hi = hi.numerator  if hi.denominator == 1
    self.new(lo, hi, b0=='[', b1==']')
  end

  def initialize_copy(obj)
    super
    @sets = @sets.map(&:dup)
  end

  def include?(x)
    @sets.any?{|set| set.include?(x)}
  end

  def empty?
    @sets.empty?
  end

  def union(other)
    sets = (@sets+other.sets).map(&:dup).sort_by{|set| [set.lo, set.hi]}
    work = []
    pre = sets.shift
    sets.each do |post|
      if valid?(pre.hi, post.lo, !pre.inc_hi, !post.inc_lo)
        work << pre
        pre = post
      else
        pre.inc_lo |= post.inc_lo  if pre.lo == post.lo
        if pre.hi < post.hi
          pre.hi = post.hi
          pre.inc_hi = post.inc_hi
        elsif pre.hi == post.hi
          pre.inc_hi |= post.inc_hi
        end
      end
    end
    work << pre  if pre
    new_Rset(work)
  end
  alias | union

  def intersection(other)
    sets = @sets.map(&:dup)
    work = []
    other.sets.each do |oset|
      sets.each do |set|
        if set.hi < oset.lo or oset.hi < set.lo
          # ignore
        elsif oset.lo < set.lo and set.hi < oset.hi
          work << set
        else
          lo = [set.lo, oset.lo].max
          if set.lo == oset.lo
            inc_lo = set.inc_lo && oset.inc_lo
          else
            inc_lo = (set.lo < oset.lo) ? oset.inc_lo : set.inc_lo
          end
          hi = [set.hi, oset.hi].min
          if set.hi == oset.hi
            inc_hi = set.inc_hi && oset.inc_hi
          else
            inc_hi = (set.hi < oset.hi) ? set.inc_hi : oset.inc_hi
          end
          work << Set[lo, hi, inc_lo, inc_hi]  if valid?(lo, hi, inc_lo, inc_hi)
        end
      end
    end
    new_Rset(work)
  end
  alias & intersection

  def difference(other)
    sets = @sets.map(&:dup)
    other.sets.each do |oset|
      work = []
      sets.each do |set|
        if set.hi < oset.lo or oset.hi < set.lo
          work << set
        elsif oset.lo < set.lo and set.hi < oset.hi
          # delete
        else
          if set.lo < oset.lo
            inc_hi = (set.hi==oset.lo and !set.inc_hi) ? false : !oset.inc_lo
            work << Set[set.lo, oset.lo, set.inc_lo, inc_hi]
          elsif valid?(set.lo, oset.lo, set.inc_lo, !oset.inc_lo)
            work << Set[set.lo, set.lo, true, true]
          end
          if oset.hi < set.hi
            inc_lo = (oset.hi==set.lo and !set.inc_lo) ? false : !oset.inc_hi
            work << Set[oset.hi, set.hi, inc_lo, set.inc_hi]
          elsif valid?(oset.hi, set.hi, !oset.inc_hi, set.inc_hi)
            work << Set[set.hi, set.hi, true, true]
          end
        end
      end
      sets = work
    end
    new_Rset(sets)
  end
  alias - difference

  # symmetric difference
  def ^(other)
    (self - other) | (other - self)
  end

  def ==(other)
    self.class == other.class and @sets == other.sets
  end

  def length
    @sets.inject(0){|len, set| len + set.length}
  end

  def to_s
    "#{self.class}#{@sets.join}"
  end
  alias inspect to_s

  protected

  attr_accessor :sets

  private

  def new_Rset(sets)
    rset = self.class.new          # empty set
    rset.sets = sets
    rset
  end

  def valid?(lo, hi, inc_lo, inc_hi)
    lo < hi or (lo==hi and inc_lo and inc_hi)
  end
end

def Rset(lo, hi, inc_hi=false)
  Rset.new(lo, hi, false, inc_hi)
end


$ echo -n 'ASCII string' | sha1
9e9aeefe5563845ec5c42c5630842048c0fc261b


import crypto.sha1

fn main() {
    println("${sha1.hexhash('Rosetta Code')}")//Rosetta code

    mut h := sha1.new()
    h.write('Rosetta Code'.bytes()) ?
    println('${h.checksum().map(it.hex()).join('')}')
}


import "/crypto" for Sha1
import "/fmt" for Fmt

var strings = [
    "",
    "a",
    "abc",
    "message digest",
    "abcdefghijklmnopqrstuvwxyz",
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
    "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
    "The quick brown fox jumps over the lazy dog",
    "The quick brown fox jumps over the lazy cog",
    "Rosetta Code"
]

for (s in strings) {
    var hash = Sha1.digest(s)
    Fmt.print("$s <== '$0s'", hash, s)
}


$ zkl // run the REPL
zkl: var MsgHash=Import("zklMsgHash")
MsgHash
zkl: MsgHash.SHA1("Rosetta Code")
48c98f7e5a6e736d790ab740dfc3f51a61abe2b5

zkl: var hash=MsgHash.SHA1("Rosetta Code",1,False)  // hash once, return hash as bytes
Data(20)
zkl:  hash.bytes()
L(72,201,143,126,90,110,115,109,121,10,183,64,223,195,245,26,97,171,226,181)
zkl: hash.bytes().apply("toString",16).concat()
48c98f7e5a6e736d79ab740dfc3f51a61abe2b5

zkl: MsgHash.SHA1("a"*1000,1000); // hash 1000 a's 1000 times
34aa973cd4c4daa4f61eeb2bdbad27316534016f


using System;
using System.Collections.Generic;
using static System.Linq.Enumerable;

public static class SetPuzzle
{
    static readonly Feature[] numbers  = { (1, "One"), (2, "Two"), (3, "Three") };
    static readonly Feature[] colors   = { (1, "Red"), (2, "Green"), (3, "Purple") };
    static readonly Feature[] shadings = { (1, "Open"), (2, "Striped"), (3, "Solid") };
    static readonly Feature[] symbols  = { (1, "Oval"), (2, "Squiggle"), (3, "Diamond") };

    private readonly struct Feature
    {
        public Feature(int value, string name) => (Value, Name) = (value, name);
        public int Value { get; }
        public string Name { get; }
        public static implicit operator int(Feature f) => f.Value;
        public static implicit operator Feature((int value, string name) t) => new Feature(t.value, t.name);
        public override string ToString() => Name;
    }

    private readonly struct Card : IEquatable<Card>
    {
        public Card(Feature number, Feature color, Feature shading, Feature symbol) =>
            (Number, Color, Shading, Symbol) = (number, color, shading, symbol);

        public Feature Number { get; }
        public Feature Color { get; }
        public Feature Shading { get; }
        public Feature Symbol { get; }

        public override string ToString() => $"{Number} {Color} {Shading} {Symbol}(s)";
        public bool Equals(Card other) => Number == other.Number && Color == other.Color && Shading == other.Shading && Symbol == other.Symbol;
    }

    public static void Main() {
        Card[] deck = (
            from number in numbers
            from color in colors
            from shading in shadings
            from symbol in symbols
            select new Card(number, color, shading, symbol)
        ).ToArray();
        var random = new Random();

        Deal(deck, 9, 4, random);
        Console.WriteLine();
        Console.WriteLine();
        Deal(deck, 12, 6, random);
    }

    static void Deal(Card[] deck, int size, int target, Random random) {
        List<(Card a, Card b, Card c)> sets;
        do {
            Shuffle(deck, random.Next);
            sets = (
                from i in 0.To(size - 2)
                from j in (i + 1).To(size - 1)
                from k in (j + 1).To(size)
                select (deck[i], deck[j], deck[k])
            ).Where(IsSet).ToList();
        } while (sets.Count != target);
        Console.WriteLine("The board:");
        foreach (Card card in deck.Take(size)) Console.WriteLine(card);
        Console.WriteLine();
        Console.WriteLine("Sets:");
        foreach (var s in sets) Console.WriteLine(s);
    }

    static void Shuffle<T>(T[] array, Func<int, int, int> rng) {
        for (int i = 0; i < array.Length; i++) {
            int r = rng(i, array.Length);
            (array[r], array[i]) = (array[i], array[r]);
        }
    }

    static bool IsSet((Card a, Card b, Card c) t) =>
        AreSameOrDifferent(t.a.Number, t.b.Number, t.c.Number) &&
        AreSameOrDifferent(t.a.Color, t.b.Color, t.c.Color) &&
        AreSameOrDifferent(t.a.Shading, t.b.Shading, t.c.Shading) &&
        AreSameOrDifferent(t.a.Symbol, t.b.Symbol, t.c.Symbol);

    static bool AreSameOrDifferent(int a, int b, int c) => (a + b + c) % 3 == 0;
    static IEnumerable<int> To(this int start, int end) => Range(start, end - start - 1);
}


#[derive(Debug)]
enum SetOperation {
    Union,
    Intersection,
    Difference,
}

#[derive(Debug, PartialEq)]
enum RangeType {
    Inclusive,
    Exclusive,
}

#[derive(Debug)]
struct CompositeSet<'a> {
    operation: SetOperation,
    a: &'a RealSet<'a>,
    b: &'a RealSet<'a>,
}

#[derive(Debug)]
struct RangeSet {
    range_types: (RangeType, RangeType),
    start: f64,
    end: f64,
}

#[derive(Debug)]
enum RealSet<'a> {
    RangeSet(RangeSet),
    CompositeSet(CompositeSet<'a>),
}

impl RangeSet {
    fn compare_start(&self, n: f64) -> bool {
        if self.range_types.0 == RangeType::Inclusive {
            self.start <= n
        } else {
            self.start < n
        }
    }

    fn compare_end(&self, n: f64) -> bool {
        if self.range_types.1 == RangeType::Inclusive {
            n <= self.end
        } else {
            n < self.end
        }
    }
}

impl<'a> RealSet<'a> {
    fn new(start_type: RangeType, start: f64, end: f64, end_type: RangeType) -> Self {
        RealSet::RangeSet(RangeSet {
            range_types: (start_type, end_type),
            start,
            end,
        })
    }

    fn operation(&'a self, other: &'a Self, operation: SetOperation) -> Self {
        RealSet::CompositeSet(CompositeSet {
            operation,
            a: self,
            b: other,
        })
    }

    fn union(&'a self, other: &'a Self) -> Self {
        self.operation(other, SetOperation::Union)
    }

    fn intersection(&'a self, other: &'a Self) -> Self {
        self.operation(other, SetOperation::Intersection)
    }

    fn difference(&'a self, other: &'a Self) -> Self {
        self.operation(other, SetOperation::Difference)
    }

    fn contains(&self, n: f64) -> bool {
        if let RealSet::RangeSet(range) = self {
            range.compare_start(n) && range.compare_end(n)
        } else if let RealSet::CompositeSet(range) = self {
            match range.operation {
                SetOperation::Union => range.a.contains(n) || range.b.contains(n),
                SetOperation::Intersection => range.a.contains(n) && range.b.contains(n),
                SetOperation::Difference => range.a.contains(n) && !range.b.contains(n),
            }
        } else {
            unimplemented!();
        }
    }
}

fn make_contains_phrase(does_contain: bool) -> &'static str {
    if does_contain {
        "contains"
    } else {
        "does not contain"
    }
}

use RangeType::*;

fn main() {
    for (set_name, set) in [
        (
            "(0, 1] ∪ [0, 2)",
            RealSet::new(Exclusive, 0.0, 1.0, Inclusive)
                .union(&RealSet::new(Inclusive, 0.0, 2.0, Exclusive)),
        ),
        (
            "[0, 2) ∩ (1, 2]",
            RealSet::new(Inclusive, 0.0, 2.0, Exclusive)
                .intersection(&RealSet::new(Exclusive, 1.0, 2.0, Inclusive)),
        ),
        (
            "[0, 3) − (0, 1)",
            RealSet::new(Inclusive, 0.0, 3.0, Exclusive)
                .difference(&RealSet::new(Exclusive, 0.0, 1.0, Exclusive)),
        ),
        (
            "[0, 3) − [0, 1]",
            RealSet::new(Inclusive, 0.0, 3.0, Exclusive)
                .difference(&RealSet::new(Inclusive, 0.0, 1.0, Inclusive)),
        ),
    ] {
        println!("Set {}", set_name);

        for i in [0.0, 1.0, 2.0] {
            println!("- {} {}", make_contains_phrase(set.contains(i)), i);
        }
    }
}


package require Tcl 8.5

proc inRange {x range} {
    lassign $range a aClosed b bClosed
    expr {($aClosed ? $a<=$x : $a<$x) && ($bClosed ? $x<=$b : $x<$b)}
}
proc normalize {A} {
    set A [lsort -index 0 -real [lsort -index 1 -integer -decreasing $A]]
    for {set i 0} {$i < [llength $A]} {incr i} {
	lassign [lindex $A $i] a aClosed b bClosed
	if {$b < $a || ($a == $b && !($aClosed && $bClosed))} {
	    set A [lreplace $A $i $i]
	    incr i -1
	}
    }
    for {set i 0} {$i < [llength $A]} {incr i} {
	for {set j [expr {$i+1}]} {$j < [llength $A]} {incr j} {
	    set R [lindex $A $i]
	    lassign [lindex $A $j] a aClosed b bClosed
	    if {[inRange $a $R]} {
		if {![inRange $b $R]} {
		    lset A $i 2 $b
		    lset A $i 3 $bClosed
		}
		set A [lreplace $A $j $j]
		incr j -1
	    }
	}
    }
    return $A
}

proc realset {args} {
    set RE {^\s*([\[(])\s*([-\d.e]+|-inf)\s*,\s*([-\d.e]+|inf)\s*([\])])\s*$}
    set result {}
    foreach s $args {
	if {
	    [regexp $RE $s --> left a b right] &&
	    [string is double $a] && [string is double $b]
	} then {
	    lappend result [list \
		$a [expr {$left eq "\["}] $b [expr {$right eq "\]"}]]
	} else {
	    error "bad range descriptor"
	}
    }
    return $result
}
proc elementOf {x A} {
    foreach range $A {
	if {[inRange $x $range]} {return 1}
    }
    return 0
}
proc union {A B} {
    return [normalize [concat $A $B]]
}
proc intersection {A B} {
    set B [normalize $B]
    set C {}
    foreach RA [normalize $A] {
	lassign $RA Aa AaClosed Ab AbClosed
	foreach RB $B {
	    lassign $RB Ba BaClosed Bb BbClosed
	    if {$Aa > $Bb || $Ba > $Ab} continue
	    set RC {}
	    lappend RC [expr {max($Aa,$Ba)}]
	    if {$Aa==$Ba} {
		lappend RC [expr {min($AaClosed,$BaClosed)}]
	    } else {
		lappend RC [expr {$Aa>$Ba ? $AaClosed : $BaClosed}]
	    }
	    lappend RC [expr {min($Ab,$Bb)}]
	    if {$Ab==$Bb} {
		lappend RC [expr {min($AbClosed,$BbClosed)}]
	    } else {
		lappend RC [expr {$Ab<$Bb ? $AbClosed : $BbClosed}]
	    }
	    lappend C $RC
	}
    }
    return [normalize $C]
}
proc difference {A B} {
    set C {}
    set B [normalize $B]
    foreach arange [normalize $A] {
	if {[isEmpty [intersection [list $arange] $B]]} {
	    lappend C $arange
	    continue
	}
	lassign $arange Aa AaClosed Ab AbClosed
	foreach brange $B {
	    lassign $brange Ba BaClosed Bb BbClosed
	    if {$Bb < $Aa || ($Bb==$Aa && !($AaClosed && $BbClosed))} {
		continue
	    }
	    if {$Ab < $Ba || ($Ab==$Ba && !($BaClosed && $AbClosed))} {
		lappend C [list $Aa $AaClosed $Ab $AbClosed]
		unset arange
		break
	    }
	    if {$Aa==$Bb} {
		set AaClosed 0
		continue
	    } elseif {$Ab==$Ba} {
		set AbClosed 0
		lappend C [list $Aa $AaClosed $Ab $AbClosed]
		unset arange
		continue
	    }
	    if {$Aa<$Ba} {
		lappend C [list $Aa $AaClosed $Ba [expr {!$BaClosed}]]
		if {$Ab>$Bb} {
		    set Aa $Bb
		    set AaClosed [expr {!$BbClosed}]
		} else {
		    unset arange
		    break
		}
	    } elseif {$Aa==$Ba} {
		lappend C [list $Aa $AaClosed $Ba [expr {!$BaClosed}]]
		set Aa $Bb
		set AaClosed [expr {!$BbClosed}]
	    } else {
		set Aa $Bb
		set AaClosed [expr {!$BbClosed}]
	    }
	}
	if {[info exist arange]} {
	    lappend C [list $Aa $AaClosed $Ab $AbClosed]
	}
    }
    return [normalize $C]
}
proc isEmpty A {
    expr {![llength [normalize $A]]}
}
proc length A {
    set len 0.0
    foreach range [normalize $A] {
	lassign $range a _ b _
	set len [expr {$len + ($b-$a)}]
    }
    return $len
}


#include <time.h>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>

enum color {
    red, green, purple
};
enum symbol {
    oval, squiggle, diamond
};
enum number {
    one, two, three
};
enum shading {
    solid, open, striped
};
class card {
public:
    card( color c, symbol s, number n, shading h ) {
        clr = c; smb = s; nbr = n; shd = h;
    }
    color getColor() {
        return clr;
    }
    symbol getSymbol() {
        return smb;
    }
    number getNumber() {
        return nbr;
    }
    shading getShading() {
        return shd;
    }
    std::string toString() {
        std::string str = "[";
        str += clr == red ? "red " : clr == green ? "green " : "purple ";
        str += nbr == one ? "one " : nbr == two ? "two " : "three ";
        str += smb == oval ? "oval " : smb == squiggle ? "squiggle " : "diamond ";
        str += shd == solid ? "solid" : shd == open ? "open" : "striped";
        return str + "]";
    }
private:
    color    clr;
    symbol   smb;
    number   nbr;
    shading  shd;
};
typedef struct {
    std::vector<size_t> index;
} set;
class setPuzzle {
public:
    setPuzzle() {
        for( size_t c = red; c <= purple; c++ ) {
            for( size_t s = oval; s <= diamond; s++ ) {
                for( size_t n = one; n <= three; n++ ) {
                    for( size_t h = solid; h <= striped; h++ ) {
                        card crd( static_cast<color>  ( c ),
                                  static_cast<symbol> ( s ),
                                  static_cast<number> ( n ),
                                  static_cast<shading>( h ) );
                        _cards.push_back( crd );
                    }
                }
            }
        }
    }
    void create( size_t countCards, size_t countSets, std::vector<card>& cards, std::vector<set>& sets ) {
        while( true ) {
            sets.clear();
            cards.clear();
            std::random_shuffle( _cards.begin(), _cards.end() );
            for( size_t f = 0; f < countCards; f++ ) {
                cards.push_back( _cards.at( f ) );
            }
            for( size_t c1 = 0; c1 < cards.size() - 2; c1++ ) {
                for( size_t c2 = c1 + 1; c2 < cards.size() - 1; c2++ ) {
                    for( size_t c3 = c2 + 1; c3 < cards.size(); c3++ ) {
                        if( testSet( &cards.at( c1 ), &cards.at( c2 ), &cards.at( c3 ) ) ) {
                            set s;
                            s.index.push_back( c1 ); s.index.push_back( c2 ); s.index.push_back( c3 );
                            sets.push_back( s );
                        }
                    }
                }
            }
            if( sets.size() == countSets ) return;
        }
    }
private:
    bool testSet( card* c1, card* c2, card* c3 ) {
        int
        c = ( c1->getColor()   + c2->getColor()   + c3->getColor()   ) % 3,
        s = ( c1->getSymbol()  + c2->getSymbol()  + c3->getSymbol()  ) % 3,
        n = ( c1->getNumber()  + c2->getNumber()  + c3->getNumber()  ) % 3,
        h = ( c1->getShading() + c2->getShading() + c3->getShading() ) % 3;
        return !( c + s + n + h );
    }
    std::vector<card> _cards;
};
void displayCardsSets( std::vector<card>& cards, std::vector<set>& sets ) {
    size_t cnt = 1;
    std::cout << " ** DEALT " << cards.size() << " CARDS: **\n";
    for( std::vector<card>::iterator i = cards.begin(); i != cards.end(); i++ ) {
        std::cout << std::setw( 2 ) << cnt++ << ": " << ( *i ).toString() << "\n";
    }
    std::cout << "\n ** CONTAINING " << sets.size() << " SETS: **\n";
    for( std::vector<set>::iterator i = sets.begin(); i != sets.end(); i++ ) {
        for( size_t j = 0; j < ( *i ).index.size(); j++ ) {
            std::cout << " " << std::setiosflags( std::ios::left ) << std::setw( 34 )
                      << cards.at( ( *i ).index.at( j ) ).toString() << " : "
                      << std::resetiosflags( std::ios::left ) << std::setw( 2 ) << ( *i ).index.at( j ) + 1 << "\n";
        }
        std::cout << "\n";
    }
    std::cout << "\n\n";
}
int main( int argc, char* argv[] ) {
    srand( static_cast<unsigned>( time( NULL ) ) );
    setPuzzle p;
    std::vector<card> v9, v12;
    std::vector<set>  s4, s6;
    p.create(  9, 4,  v9, s4 );
    p.create( 12, 6, v12, s6 );
    displayCardsSets(  v9, s4 );
    displayCardsSets( v12, s6 );
    return 0;
}


import "/dynamic" for Enum

var RangeType = Enum.create("RangeType", ["CLOSED", "BOTH_OPEN", "LEFT_OPEN", "RIGHT_OPEN"])

class RealSet {
    construct new(start, end, pred) {
        _low  = start
        _high = end
        _pred = (pred == RangeType.CLOSED)     ? Fn.new { |d| d >= _low && d <= _high } :
                (pred == RangeType.BOTH_OPEN)  ? Fn.new { |d| d >  _low && d <  _high } :
                (pred == RangeType.LEFT_OPEN)  ? Fn.new { |d| d >  _low && d <= _high } :
                (pred == RangeType.RIGHT_OPEN) ? Fn.new { |d| d >= _low && d <  _high } : pred
    }

    low  { _low  }
    high { _high }
    pred { _pred }

    contains(d) { _pred.call(d) }

    union(other) {
        if (!other.type == RealSet) Fiber.abort("Argument must be a RealSet")
        var low2 = _low.min(other.low)
        var high2 = _high.max(other.high)
        return RealSet.new(low2, high2) { |d| _pred.call(d) || other.pred.call(d) }
    }

    intersect(other) {
        if (!other.type == RealSet) Fiber.abort("Argument must be a RealSet")
        var low2 = _low.max(other.low)
        var high2 = _high.min(other.high)
        return RealSet.new(low2, high2) { |d| _pred.call(d) && other.pred.call(d) }
    }

    subtract(other) {
        if (!other.type == RealSet) Fiber.abort("Argument must be a RealSet")
        return RealSet.new(_low, _high) { |d| _pred.call(d) && !other.pred.call(d) }
    }

    length {
        if (_low.isInfinity || _high.isInfinity) return -1  // error value
        if (_high <= _low) return 0
        var p = _low
        var count = 0
        var interval = 0.00001
        while (true) {
            if (_pred.call(p)) count = count + 1
            p = p + interval
            if (p >= _high) break
        }
        return count * interval
    }

    isEmpty { (_high == _low) ? !_pred.call(_low) : length == 0 }
}

var a = RealSet.new(0, 1, RangeType.LEFT_OPEN)
var b = RealSet.new(0, 2, RangeType.RIGHT_OPEN)
var c = RealSet.new(1, 2, RangeType.LEFT_OPEN)
var d = RealSet.new(0, 3, RangeType.RIGHT_OPEN)
var e = RealSet.new(0, 1, RangeType.BOTH_OPEN)
var f = RealSet.new(0, 1, RangeType.CLOSED)
var g = RealSet.new(0, 0, RangeType.CLOSED)

for (i in 0..2) {
    System.print("(0, 1] ∪ [0, 2) contains %(i) is %(a.union(b).contains(i))")
    System.print("[0, 2) ∩ (1, 2] contains %(i) is %(b.intersect(c).contains(i))")
    System.print("[0, 3) − (0, 1) contains %(i) is %(d.subtract(e).contains(i))")
    System.print("[0, 3) − [0, 1] contains %(i) is %(d.subtract(f).contains(i))\n")
}

System.print("[0, 0] is empty is %(g.isEmpty)\n")

var aa = RealSet.new(0, 10) { |x| (0 < x && x < 10) && ((Num.pi * x * x).sin.abs > 0.5) }
var bb = RealSet.new(0, 10) { |x| (0 < x && x < 10) && ((Num.pi * x).sin.abs > 0.5) }
var cc = aa.subtract(bb)
System.print("Approx length of A - B is %(cc.length)")


import ceylon.random {
    Random,
    DefaultRandom
}

abstract class Feature() of Color | Symbol | NumberOfSymbols | Shading {}

abstract class Color()
        of red | green | purple
        extends Feature() {}
object red extends Color() {
    string => "red";
}
object green extends Color() {
    string => "green";
}
object purple extends Color() {
    string => "purple";
}

abstract class Symbol()
        of oval | squiggle | diamond
        extends Feature() {}
object oval extends Symbol() {
    string => "oval";
}
object squiggle extends Symbol() {
    string => "squiggle";
}
object diamond extends Symbol() {
    string => "diamond";
}

abstract class NumberOfSymbols()
        of one | two | three
        extends Feature() {}
object one extends NumberOfSymbols() {
    string => "one";
}
object two extends NumberOfSymbols() {
    string => "two";
}
object three extends NumberOfSymbols() {
    string => "three";
}

abstract class Shading()
        of solid | open | striped
        extends Feature() {}
object solid extends Shading() {
    string => "solid";
}
object open extends Shading() {
    string => "open";
}
object striped extends Shading() {
    string => "striped";
}

class Card(color, symbol, number, shading) {
    shared Color color;
    shared Symbol symbol;
    shared NumberOfSymbols number;
    shared Shading shading;

    value plural => number == one then "" else "s";
    string => "``number`` ``shading`` ``color`` ``symbol````plural``";
}

{Card*} deck = {
    for(color in `Color`.caseValues)
    for(symbol in `Symbol`.caseValues)
    for(number in `NumberOfSymbols`.caseValues)
    for(shading in `Shading`.caseValues)
    Card(color, symbol, number, shading)
};

alias CardSet => [Card+];

Boolean validSet(CardSet cards) {

    function allOrOne({Feature*} features) =>
            let(uniques = features.distinct.size)
            uniques == 3 || uniques == 1;

    return allOrOne(cards*.color) &&
            allOrOne(cards*.number) &&
            allOrOne(cards*.shading) &&
            allOrOne(cards*.symbol);
}

{CardSet*} findSets(Card* cards) =>
        cards
            .sequence()
            .combinations(3)
            .filter(validSet);

Random random = DefaultRandom();

class Mode of basic | advanced {

    shared Integer numberOfCards;
    shared Integer numberOfSets;

    shared new basic {
        numberOfCards = 9;
        numberOfSets = 4;
    }

    shared new advanced {
        numberOfCards = 12;
        numberOfSets = 6;
    }
}

[{Card*}, {CardSet*}] deal(Mode mode) {
    value randomStream = random.elements(deck);
    while(true) {
        value cards = randomStream.distinct.take(mode.numberOfCards).sequence();
        value sets = findSets(*cards);
        if(sets.size == mode.numberOfSets) {
            return [cards, sets];
        }
    }
}

shared void run() {
    value [cards, sets] = deal(Mode.basic);
    print("The cards dealt are:
           ");
    cards.each(print);
    print("
           Containing the sets:
           ");
    for(cardSet in sets) {
        cardSet.each(print);
        print("");
    }

}