(() => {
    'use strict';

    // a005179 :: () -> [Int]
    const a005179 = () =>
        fmapGen(
            n => find(
                compose(
                    eq(n),
                    succ,
                    length,
                    properDivisors
                )
            )(enumFrom(1)).Just
        )(enumFrom(1));

    // ------------------------TEST------------------------
    // main :: IO ()
    const main = () =>
        console.log(
            take(15)(
                a005179()
            )
        );

    // [1,2,4,6,16,12,64,24,36,48,1024,60,4096,192,144]

    // -----------------GENERIC FUNCTIONS------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = a =>
        b => ({
            type: 'Tuple',
            '0': a,
            '1': b,
            length: 2
        });

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

    // enumFrom :: Enum a => a -> [a]
    function* enumFrom(x) {
        // A non-finite succession of enumerable
        // values, starting with the value x.
        let v = x;
        while (true) {
            yield v;
            v = succ(v);
        }
    };

    // eq (==) :: Eq a => a -> a -> Bool
    const eq = a =>
        // True when a and b are equivalent in the terms
        // defined below for their shared data type.
        b => a === b;

    // find :: (a -> Bool) -> Gen [a] -> Maybe a
    const find = p => xs => {
        const mb = until(tpl => {
            const nxt = tpl[0];
            return nxt.done || p(nxt.value);
        })(
            tpl => Tuple(tpl[1].next())(
                tpl[1]
            )
        )(Tuple(xs.next())(xs))[0];
        return mb.done ? (
            Nothing()
        ) : Just(mb.value);
    }

    // fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
    const fmapGen = f =>
        function*(gen) {
            let v = take(1)(gen);
            while (0 < v.length) {
                yield(f(v[0]))
                v = take(1)(gen)
            }
        };

    // group :: [a] -> [[a]]
    const group = xs => {
        // A list of lists, each containing only equal elements,
        // such that the concatenation of these lists is xs.
        const go = xs =>
            0 < xs.length ? (() => {
                const
                    h = xs[0],
                    i = xs.findIndex(x => h !== x);
                return i !== -1 ? (
                    [xs.slice(0, i)].concat(go(xs.slice(i)))
                ) : [xs];
            })() : [];
        return go(xs);
    };

    // length :: [a] -> Int
    const length = xs =>
        // Returns Infinity over objects without finite
        // length. This enables zip and zipWith to choose
        // the shorter argument when one is non-finite,
        // like cycle, repeat etc
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // liftA2List :: (a -> b -> c) -> [a] -> [b] -> [c]
    const liftA2List = f => xs => ys =>
        // The binary operator f lifted to a function over two
        // lists. f applied to each pair of arguments in the
        // cartesian product of xs and ys.
        xs.flatMap(
            x => ys.map(f(x))
        );

    // mul (*) :: Num a => a -> a -> a
    const mul = a => b => a * b;

    // properDivisors :: Int -> [Int]
    const properDivisors = n =>
        // The ordered divisors of n,
        // excluding n itself.
        1 < n ? (
            sort(group(primeFactors(n)).reduce(
                (a, g) => liftA2List(mul)(a)(
                    scanl(mul)([1])(g)
                ),
                [1]
            )).slice(0, -1)
        ) : [];

    // primeFactors :: Int -> [Int]
    const primeFactors = n => {
        // A list of the prime factors of n.
        const
            go = x => {
                const
                    root = Math.floor(Math.sqrt(x)),
                    m = until(
                        ([q, _]) => (root < q) || (0 === (x % q))
                    )(
                        ([_, r]) => [step(r), 1 + r]
                    )(
                        [0 === x % 2 ? 2 : 3, 1]
                    )[0];
                return m > root ? (
                    [x]
                ) : ([m].concat(go(Math.floor(x / m))));
            },
            step = x => 1 + (x << 2) - ((x >> 1) << 1);
        return go(n);
    };

    // scanl :: (b -> a -> b) -> b -> [a] -> [b]
    const scanl = f => startValue => xs =>
        xs.reduce((a, x) => {
            const v = f(a[0])(x);
            return Tuple(v)(a[1].concat(v));
        }, Tuple(startValue)([startValue]))[1];

    // sort :: Ord a => [a] -> [a]
    const sort = xs => xs.slice()
        .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

    // succ :: Enum a => a -> a
    const succ = x =>
        1 + x;

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = n =>
        // The first n elements of a list,
        // string of characters, or stream.
        xs => 'GeneratorFunction' !== xs
        .constructor.constructor.name ? (
            xs.slice(0, n)
        ) : [].concat.apply([], Array.from({
            length: n
        }, () => {
            const x = xs.next();
            return x.done ? [] : [x.value];
        }));

    // until :: (a -> Bool) -> (a -> a) -> a -> a
    const until = p => f => x => {
        let v = x;
        while (!p(v)) v = f(v);
        return v;
    };

    // MAIN ---
    return main();
})();


def deck: [ { by 1..3 -> (colour: $),
  by 1..3 -> (symbol: $),
    by 1..3 -> (number: $),
      by 1..3 -> (shading: $)}
];

templates deal
  @: $deck;
  [ 1..$ -> \([email protected]::length -> SYS::randomInt -> ^@deal($ + 1) !\)] !
end deal

templates isSet
  def set : $;
  [ $(1).colour::raw + $(2).colour::raw + $(3).colour::raw, $(1).symbol::raw + $(2).symbol::raw + $(3).symbol::raw,
    $(1).number::raw + $(2).number::raw + $(3).number::raw, $(1).shading::raw + $(2).shading::raw + $(3).shading::raw ] -> #
  // if it is an array where all elements of 3, 6 or 9, it is a set
  when <[<=3|=6|=9>+ VOID]> do $set !
end isSet

templates findSets
  def hand: $;
  [ 1..$hand::length - 2 -> \(def a: $;
          $a+1..$hand::length - 1 -> \(def b: $;
              $b+1..$hand::length -> $hand([$a, $b, $]) !
          \) !
      \) -> isSet ] !
end findSets

templates setPuzzle
  def nCards: $(1);
  def nSets: $(2);
  {} -> #
  when <{sets: <[]($nSets..)>}> do $ !
  otherwise
    def hand: $nCards -> deal;
    {hand: $hand, sets: $hand -> findSets} -> #
end setPuzzle

templates formatCard
  def colours: ['red', 'green', 'purple'];
  def symbols: ['oval', 'squiggle', 'diamond'];
  def numbers: ['one', 'two', 'three'];
  def shadings: ['solid', 'open', 'striped'];
  $ -> '$colours($.colour);-$symbols($.symbol);-$numbers($.number);-$shadings($.shading);' !
end formatCard

templates formatSets
  $ -> 'hand:
$.hand... -> '$ -> formatCard;
';
sets:
$.sets... -> '[$... -> ' $ -> formatCard; ';]
';' !
end formatSets

[9,4] -> setPuzzle -> formatSets -> !OUT::write


# Generate random integer uniformly on range [0..$n-1]
proc random n {expr {int(rand() * $n)}}

# Generate a shuffled deck of all cards; the card encoding was stolen from the
# Perl6 solution. This is done once and then used as a constant. Note that the
# rest of the code assumes that all cards in the deck are unique.
set ::AllCards [apply {{} {
    set cards {}
    foreach color {1 2 4} {
	foreach symbol {1 2 4} {
	    foreach number {1 2 4} {
		foreach shading {1 2 4} {
		    lappend cards [list $color $symbol $number $shading]
		}
	    }
	}
    }
    # Knuth-Morris-Pratt shuffle (not that it matters)
    for {set i [llength $cards]} {$i > 0} {} {
	set j [random $i]
	set tmp [lindex $cards [incr i -1]]
	lset cards $i [lindex $cards $j]
	lset cards $j $tmp
    }
    return $cards
}}]

# Randomly pick a hand of cards from the deck (itself in a global for
# convenience).
proc drawCards n {
    set cards $::AllCards;    # Copies...
    for {set i 0} {$i < $n} {incr i} {
	set idx [random [llength $cards]]
	lappend hand [lindex $cards $idx]
	set cards [lreplace $cards $idx $idx]
    }
    return $hand
}

# Test if a particular group of three cards is a valid set
proc isValidSet {a b c} {
    expr {
	  ([lindex $a 0]|[lindex $b 0]|[lindex $c 0]) in {1 2 4 7} &&
	  ([lindex $a 1]|[lindex $b 1]|[lindex $c 1]) in {1 2 4 7} &&
	  ([lindex $a 2]|[lindex $b 2]|[lindex $c 2]) in {1 2 4 7} &&
	  ([lindex $a 3]|[lindex $b 3]|[lindex $c 3]) in {1 2 4 7}
    }
}

# Get all unique valid sets of three cards in a hand.
proc allValidSets {hand} {
    set sets {}
    for {set i 0} {$i < [llength $hand]} {incr i} {
	set a [lindex $hand $i]
	set hand [set cards2 [lreplace $hand $i $i]]
	for {set j 0} {$j < [llength $cards2]} {incr j} {
	    set b [lindex $cards2 $j]
	    set cards2 [set cards3 [lreplace $cards2 $j $j]]
	    foreach c $cards3 {
		if {[isValidSet $a $b $c]} {
		    lappend sets [list $a $b $c]
		}
	    }
	}
    }
    return $sets
}

# Solve a particular version of the set puzzle, by picking random hands until
# one is found that satisfies the constraints. This is usually much faster
# than a systematic search. On success, returns the hand found and the card
# sets within that hand.
proc SetPuzzle {numCards numSets} {
    while 1 {
	set hand [drawCards $numCards]
	set sets [allValidSets $hand]
	if {[llength $sets] == $numSets} {
	    break
	}
    }
    return [list $hand $sets]
}


# The number of prime factors (as in prime factorization)
def numfactors:
  . as $num
  | reduce range(1; 1 + sqrt|floor) as $i (null;
       if ($num % $i) == 0
       then ($num / $i) as $r
       | if $i == $r then .+1 else .+2 end
       else .
       end );

# Output: a stream
def A06954:
  foreach range(1; infinite) as $i ({k: 0};
     .j = .k + 1
     | until( $i == (.j | numfactors); .j += 1)
     | .k = .j ;
     .j ) ;

"First 15 terms of OEIS sequence A069654: ",
[limit(15; A06954)]


using Primes

function numfactors(n)
    f = [one(n)]
    for (p,e) in factor(n)
        f = reduce(vcat, [f*p^j for j in 1:e], init=f)
    end
    length(f)
end

function A06954(N)
    println("First $N terms of OEIS sequence A069654: ")
    k = 0
    for i in 1:N
        j = k
        while (j += 1) > 0
            if i == numfactors(j)
                print("$j ")
                k = j
                break
            end
        end
    end
end

A06954(15)


// Version 1.3.21

const val MAX = 15

fun countDivisors(n: Int): Int {
    var count = 0
    var i = 1
    while (i * i <= n) {
        if (n % i == 0) {
            count += if (i == n / i) 1 else 2
        }
        i++
    }
    return count
}

fun main() {
    println("The first $MAX terms of the sequence are:")
    var i = 1
    var next = 1
    while (next <= MAX) {
        if (next == countDivisors(i)) {
            print("$i ")
            next++
        }
        i++
    }
    println()
}


res = {#, DivisorSigma[0, #]} & /@ Range[100000];
highest = 0;
filter = {};
Do[
 If[r[[2]] == highest + 1,
  AppendTo[filter, r[[1]]];
  highest = r[[2]]
  ]
 ,
 {r, res}
 ]
Take[filter, 15]


reduce[x_] :=
 Block[{pairs, unique},
  pairs =
   DeleteCases[
    Subsets[[email protected]
      [email protected], {2}], _?(Intersection @@ x[[#]] == {} &)];
  unique = Complement[[email protected]@x, [email protected]];
  Join[Union[Flatten[x[[#]]]] & /@ pairs, x[[unique]]]]
consolidate[x__] := FixedPoint[reduce, {x}]


proc consolidate(sets: varargs[set[char]]): seq[set[char]] =
  if len(sets) < 2:
    return @sets
  var (r, b) = (@[sets[0]], consolidate(sets[1..^1]))
  for x in b:
    if len(r[0] * x) != 0:
      r[0] = r[0] + x
    else:
      r.add(x)
  r

echo consolidate({'A', 'B'}, {'C', 'D'})
echo consolidate({'A', 'B'}, {'B', 'D'})
echo consolidate({'A', 'B'}, {'C', 'D'}, {'D', 'B'})
echo consolidate({'H', 'I', 'K'}, {'A', 'B'}, {'C', 'D'}, {'D', 'B'}, {'F', 'G', 'H'})


let join a b =
  List.fold_left (fun acc v ->
    if List.mem v acc then acc else v::acc
  ) b a

let share a b = List.exists (fun x -> List.mem x b) a

let extract p lst =
  let rec aux acc = function
  | x::xs -> if p x then Some (x, List.rev_append acc xs) else aux (x::acc) xs
  | [] -> None
  in
  aux [] lst

let consolidate sets =
  let rec aux acc = function
  | [] -> List.rev acc
  | x::xs ->
      match extract (share x) xs with
      | Some (y, ys) -> aux acc ((join x y) :: ys)
      | None -> aux (x::acc) xs
  in
  aux [] sets

let print_sets sets =
  print_string "{ ";
  List.iter (fun set ->
    print_string "{";
    print_string (String.concat " " set);
    print_string "} "
  ) sets;
  print_endline "}"

let () =
  print_sets (consolidate [["A";"B"]; ["C";"D"]]);
  print_sets (consolidate [["A";"B"]; ["B";"C"]]);
  print_sets (consolidate [["A";"B"]; ["C";"D"]; ["D";"B"]]);
  print_sets (consolidate [["H";"I";"K"]; ["A";"B"]; ["C";"D"]; ["D";"B"];
                           ["F";"G";"H"]]);
;;


sieve=: 3 :0
 range=. <. + [email protected]:|@:-
 tally=. y#0
 for_i.#\tally do.
  j=. }:^:(y<:{:)i * 1 range >: <. y % i
  tally=. j >:@:{`[`]} tally
 end.
 /:~({./.~ {."1) tally,.i.#tally
)


import java.util.Arrays;

public class OEIS_A005179 {

    static int count_divisors(int n) {
        int count = 0;
        for (int i = 1; i * i <= n; ++i) {
            if (n % i == 0) {
                if (i == n / i)
                    count++;
                else
                    count += 2;
            }
        }
        return count;
    }

    public static void main(String[] args) {
        final int max = 15;
        int[] seq = new int[max];
        System.out.printf("The first %d terms of the sequence are:\n", max);
        for (int i = 1, n = 0; n < max; ++i) {
            int k = count_divisors(i);
            if (k <= max && seq[k - 1] == 0) {
                seq[k- 1] = i;
                n++;
            }
        }
        System.out.println(Arrays.toString(seq));
    }
}


import "/dynamic" for Enum
import "/trait" for Comparable
import "/fmt" for Fmt
import "/str" for Str
import "/math" for Nums
import "/sort" for Sort
import "random" for Random

var Color   = Enum.create("Color",   ["RED", "GREEN", "PURPLE"])
var Symbol  = Enum.create("Symbol",  ["OVAL", "SQUIGGLE", "DIAMOND"])
var Number  = Enum.create("Number",  ["ONE", "TWO", "THREE"])
var Shading = Enum.create("Shading", ["SOLID", "OPEN", "STRIPED"])
var Degree  = Enum.create("Degree",  ["BASIC", "ADVANCED"])

class Card is Comparable {
    static zero { Card.new(Color.RED, Symbol.OVAL, Number.ONE, Shading.SOLID) }

    construct new(color, symbol, number, shading) {
        _color   = color
        _symbol  = symbol
        _number  = number
        _shading = shading
        _value   = color * 27 + symbol * 9 + number * 3 + shading
    }

    color   { _color }
    symbol  { _symbol }
    number  { _number }
    shading { _shading }
    value   { _value }

    compare(other) { (_value - other.value).sign }

    toString {
        return Str.lower(Fmt.swrite("$-8s$-10s$-7s$-7s",
            Color.members  [_color],
            Symbol.members [_symbol],
            Number.members [_number],
            Shading.members[_shading]
        ))
    }
}

var createDeck = Fn.new {
    var deck = List.filled(81, null)
    for (i in 0...81) {
        var col = (i/27).floor
        var sym = (i/ 9).floor % 3
        var num = (i/ 3).floor % 3
        var shd = i % 3
        deck[i] = Card.new(col, sym, num, shd)
    }
    return deck
}

var rand = Random.new()

var isSet = Fn.new { |trio|
    var r1 = Nums.sum(trio.map { |c| c.color   }) % 3
    var r2 = Nums.sum(trio.map { |c| c.symbol  }) % 3
    var r3 = Nums.sum(trio.map { |c| c.number  }) % 3
    var r4 = Nums.sum(trio.map { |c| c.shading }) % 3
    return r1 + r2 + r3 + r4 == 0
}

var playGame = Fn.new { |degree|
    var deck = createDeck.call()
    var nCards = (degree == Degree.BASIC) ? 9 : 12
    var nSets = (nCards/2).floor
    var sets = List.filled(nSets, null)
    for (i in 0...nSets) sets[i] = [Card.zero, Card.zero, Card.zero]
    var hand = []
    while (true) {
        rand.shuffle(deck)
        hand = deck.take(nCards).toList
        var count = 0
        var hSize = hand.count
        var outer = false
        for (i in 0...hSize-2) {
            for (j in i+1...hSize-1) {
                for (k in j+1...hSize) {
                    var trio = [hand[i], hand[j], hand[k]]
                    if (isSet.call(trio)) {
                        sets[count] = trio
                        count = count + 1
                        if (count == nSets) {
                            outer = true
                            break
                        }
                    }
                }
                if (outer) break
            }
            if (outer) break
        }
        if (outer) break
    }
    Sort.quick(hand)
    System.print("DEALT %(nCards) CARDS:\n")
    System.print(hand.join("\n"))
    System.print("\nCONTAINING %(nSets) SETS:\n")
    for (s in sets) {
        Sort.quick(s)
        System.print(s.join("\n"))
        System.print()
    }
}

playGame.call(Degree.BASIC)
System.print()
playGame.call(Degree.ADVANCED)


import strformat

const MAX = 15

func countDivisors(n: int): int =
  var i = 1
  var count = 0
  while i * i <= n:
    if n mod i == 0:
      if i == n div i:
        inc count
      else:
        inc count, 2
    inc i
  count

var i, next = 1
echo fmt"The first {MAX} terms of the sequence are:"
while next <= MAX:
  if next == countDivisors(i):
    write(stdout, fmt"{i} ")
    inc next
  inc i
write(stdout, "\n")


program AntiPrimesPlus;
{$IFDEF FPC}
  {$MODE Delphi}
{$ELSE}
  {$APPTYPE CONSOLE} // delphi
{$ENDIF}
uses
  sysutils,math;
const
  MAX =32;

function getDividersCnt(n:Uint32):Uint32;
// getDividersCnt by dividing n into its prime factors
// aka n = 2250 = 2^1*3^2*5^3 has (1+1)*(2+1)*(3+1)= 24 dividers
var
  divi,quot,deltaRes,rest : Uint32;
begin
  result := 1;

  //divi  := 2; //separat without division
  while Not(Odd(n)) do
  Begin
    n := n SHR 1;
    inc(result);
  end;

  //from now on only odd numbers
  divi  := 3;
  while (sqr(divi)<=n) do
  Begin
    DivMod(n,divi,quot,rest);
    if rest = 0 then
    Begin
      deltaRes := 0;
      repeat
        inc(deltaRes,result);
        n := quot;
        DivMod(n,divi,quot,rest);
      until rest <> 0;
      inc(result,deltaRes);
    end;
    inc(divi,2);
  end;
  //if last factor of n is prime
  IF n <> 1 then
    result := result*2;
end;

var
  T0 : Int64;
  i,next,DivCnt: Uint32;
begin
  writeln('The first ',MAX,' anti-primes plus are:');
  T0:= GetTickCount64;
  i := 1;
  next := 1;
  repeat
    DivCnt := getDividersCnt(i);
    IF DivCnt= next then
    Begin
      write(i,' ');
      inc(next);
      //if next is prime then only prime( => mostly 2 )^(next-1) is solution
      IF (next > 4) AND (getDividersCnt(next) = 2) then
        i := 1 shl (next-1) -1;// i is incremented afterwards
    end;
    inc(i);
  until Next > MAX;
  writeln;
  writeln(GetTickCount64-T0,' ms');
end.


/* REXX ***************************************************************
* 04.08.2013 Walter Pachl using ooRexx features
*                   (maybe not in the best way -improvements welcome!)
*                   but trying to demonstrate the algorithm
**********************************************************************/
s.1=.array~of(.set~of('A','B'),.set~of('C','D'))
s.2=.array~of(.set~of('A','B'),.set~of('B','D'))
s.3=.array~of(.set~of('A','B'),.set~of('C','D'),.set~of('D','B'))
s.4=.array~of(.set~of('H','I','K'),.set~of('A','B'),.set~of('C','D'),,
              .set~of('B','D'),.set~of('F','G','H'))
s.5=.array~of(.set~of('snow','ice','slush','frost','fog'),,
              .set~of('iceburgs','icecubes'),,
              .set~of('rain','fog','sleet'))
s.6=.array~of('one')
s.7=.array~new
s.8=.array~of('')
Do si=1 To 8                           /* loop through the test data */
  na=s.si                              /* an array of sets           */
  head='Output(s):'
  Say left('Input' si,10) list_as(na)  /* show the input             */
  Do While na~items()>0                /* while the array ain't empty*/
    na=cons(na)                        /* consolidate and get back   */
                                       /*  array of remaining sets   */
    head='          '
    End
  Say '===='                           /* separator line             */
  End
Exit

cons: Procedure Expose head
/**********************************************************************
* consolidate the sets in the given array
**********************************************************************/
  Use Arg a
  w=a                                  /* work on a copy             */
  n=w~items()                          /* number of sets in the array*/
  Select
    When n=0 Then                      /* no set in array            */
      Return .array~new                /* retuns an empty array      */
    When n=1 Then Do                   /* one set in array           */
      Say head list(w[1])              /* show its contents          */
      Return .array~new                /* retuns an empty array      */
      End
    Otherwise Do                       /* at least two sets are there*/
      b=.array~new                     /* use for remaining sets     */
      r=w[n]                           /* start with last set        */
      try=1
      Do until changed=0               /* loop until result is stable*/
        changed=0
        new=0
        n=w~items()                    /* number of sets             */
        Do i=1 To n-try                /* loop first through n-1 sets*/
          try=0                        /* then through all of them   */
          is=r~intersection(w[i])
          If is~items>0 Then Do        /* any elements in common     */
            r=r~union(w[i])            /* result is the union        */
            Changed=1                  /* and result is now larger   */
            End
          Else Do                      /* no elemen in common        */
            new=new+1                  /* add the set to the array   */
            b[new]=w[i]                /* of remaining sets          */
            End
          End
        If b~items()=0 Then Do         /* no remaining sets          */
          w=.array~new
          Leave                        /* we are done                */
          End
        w=b                            /* repeat with remaining sets */
        b=.array~new                   /* prepare for next iteration */
        End
      End
    Say head list(r)                   /* show one consolidated set  */
    End
  Return w                             /* return array of remaining  */

list: Procedure
/**********************************************************************
* list elements of given set
**********************************************************************/
  Call trace ?O
  Use Arg set
  arr=set~makeArray
  arr~sort()
  ol='('
  Do i=1 To arr~items()
    If i=1 Then
      ol=ol||arr[i]
    Else
      ol=ol||','arr[i]
    End
  Return ol')'

list_as: Procedure
/**********************************************************************
* List an array of sets
**********************************************************************/
  Call trace ?O
  Use Arg a
  n=a~items()
  If n=0 Then
    ol='no element in array'
  Else Do
    ol=''
    Do i=1 To n
      ol=ol '('
      arr=a[i]~makeArray
      Do j=1 To arr~items()
        If j=1 Then
          ol=ol||arr[j]
        Else
          ol=ol','arr[j]
        End
      ol=ol') '
      End
    End
  Return strip(ol)


# divisors as an unsorted stream (without calling sqrt)
def divisors:
  if . == 1 then 1
  else . as $n
  | label $out
  | range(1; $n) as $i
  | ($i * $i) as $i2
  | if $i2 > $n then break $out
    else if $i2 == $n
         then $i
         elif ($n % $i) == 0
         then $i, ($n/$i)
         else empty
	 end
    end
  end;

def count(s): reduce s as $x (0; .+1);

# smallest number with exactly n divisors
def A005179:
  . as $n
  | first( range(1; infinite) | select( count(divisors) == $n ));

# The task:
"The first 15 terms of the sequence are:",
[range(1; 16) | A005179]


using Primes

numfactors(n) = reduce(*, e+1 for (_,e) in factor(n); init=1)

A005179(n) = findfirst(k -> numfactors(k) == n, 1:typemax(Int))

println("The first 15 terms of the sequence are:")
println(map(A005179, 1:15))


// Version 1.3.21

const val MAX = 15

fun countDivisors(n: Int): Int {
    var count = 0
    var i = 1
    while (i * i <= n) {
        if (n % i == 0) {
            count += if (i == n / i) 1 else 2
        }
        i++
    }
    return count
}

fun main() {
    var seq = IntArray(MAX)
    println("The first $MAX terms of the sequence are:")
    var i = 1
    var n = 0
    while (n < MAX) {
        var k = countDivisors(i)
        if (k <= MAX && seq[k - 1] == 0) {
            seq[k - 1] = i
            n++
        }
        i++
    }
    println(seq.asList())
}


const nDraw=9, nGoal=(nDraw/2);  // Basic
var [const] UH=Utils.Helpers; // baked in stash of goodies
deck:=Walker.cproduct("red green purple".split(), // Cartesian product of 4 lists of lists
		"one two three".split(),    // T(1,2,3) (ie numbers) also works
		"oval squiggle diamond".split(),
		"solid open striped".split()).walk();
reg draw,sets,N=0;
do{ N+=1;
   draw=deck.shuffle()[0,nDraw]; // one draw per shuffle
   sets=UH.pickNFrom(3,draw)  // 84 sets of 3 cards (each with 4 features)
        .filter(fcn(set){    // list of 12 items (== 3 cards)
                    set[0,4].zip(set[4,4],set[8,4]) // -->4 tuples of 3 features
		    .pump(List,UH.listUnique,"len", // 1,3 (good) or 2 (bad)
		               '==(2))		    // (F,F,F,F)==good
		    .sum(0) == 0 		    // all 4 feature sets good
		 });
}while(sets.len()!=nGoal);

println("Dealt %d cards %d times:".fmt(draw.len(),N));
draw.pump(Void,fcn(card){ println(("%8s "*4).fmt(card.xplode())) });
println("\nContaining:");
sets.pump(Void,fcn(card){ println((("%8s "*4 + "\n")*3).fmt(card.xplode())) });


use strict;
use warnings;
use ntheory 'divisors';

print "First 15 terms of OEIS: A069654\n";
my $m = 0;
for my $n (1..15) {
    my $l = $m;
    while (++$l) {
        print("$l "), $m = $l, last if $n == divisors($l);
    }
}


with javascript_semantics
constant limit = 15
sequence res = repeat(0,limit)
integer next = 1
atom n = 1
while next<=limit do
    integer k = length(factors(n,1))
    if k=next then
        res[k] = n
        next += 1
        if next>4 and is_prime(next) then
            n := power(2,next-1)-1 -- (-1 for +=1 next)
        end if
    end if
    n += 1
end while
printf(1,"The first %d terms are: %v\n",{limit,res})


100H: /* FIND THE SMALLEST NUMBER > THE PREVIOUS ONE WITH EXACTLY N DIVISORS */

   /* CP/M BDOS SYSTEM CALL */
   BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
   /* CONSOLE OUTPUT ROUTINES */
   PR$CHAR:   PROCEDURE( C ); DECLARE C BYTE;    CALL BDOS( 2, C );  END;
   PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S );  END;
   PR$NL:     PROCEDURE; CALL PR$STRING( .( 0DH, 0AH, '$' ) );       END;
   PR$NUMBER: PROCEDURE( N );
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR( 6 ) BYTE INITIAL( '.....$' ), W BYTE;
      N$STR( W := LAST( N$STR ) - 1 ) = '0' + ( ( V := N ) MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END;
      CALL PR$STRING( .N$STR( W ) );
   END PR$NUMBER;

   /* TASK */

   /* RETURNS THE DIVISOR COUNT OF N */
   COUNT$DIVISORS: PROCEDURE( N )ADDRESS;
      DECLARE N ADDRESS;
      DECLARE ( I, I2, COUNT ) ADDRESS;
      COUNT = 0;
      I     = 1;
      DO WHILE( ( I2 := I * I ) < N );
         IF N MOD I = 0 THEN COUNT = COUNT + 2;
         I = I + 1;
      END;
      IF I2 = N THEN RETURN ( COUNT + 1 ); ELSE RETURN ( COUNT );
   END COUNT$DIVISORS ;

   DECLARE MAX LITERALLY '15';
   DECLARE ( I, NEXT ) ADDRESS;

   CALL PR$STRING( .'THE FIRST $' );
   CALL PR$NUMBER( MAX );
   CALL PR$STRING( .' TERMS OF THE SEQUENCE ARE:$' );
   NEXT = 1;
   I    = 1;
   DO WHILE( NEXT <= MAX );
      IF NEXT = COUNT$DIVISORS( I ) THEN DO;
         CALL PR$CHAR( ' ' );
         CALL PR$NUMBER( I );
         NEXT = NEXT + 1;
      END;
      I = I + 1;
   END;

EOF


cons(V)={
  my(v,u,s);
  for(i=1,#V,
    v=V[i];
    for(j=i+1,#V,
      u=V[j];
      if(#setintersect(u,v),V[i]=v=vecsort(setunion(u,v));V[j]=[];s++)
    )
  );
  V=select(v->#v,V);
  if(s,cons(V),V)
};


use strict;
use English;
use Smart::Comments;

my @ex1 = consolidate( (['A', 'B'], ['C', 'D']) );
### Example 1: @ex1
my @ex2 = consolidate( (['A', 'B'], ['B', 'D']) );
### Example 2: @ex2
my @ex3 = consolidate( (['A', 'B'], ['C', 'D'], ['D', 'B']) );
### Example 3: @ex3
my @ex4 = consolidate( (['H', 'I', 'K'], ['A', 'B'], ['C', 'D'], ['D', 'B'], ['F', 'G', 'H']) );
### Example 4: @ex4
exit 0;

sub consolidate {
    scalar(@ARG) >= 2 or return @ARG;
    my @result = ( shift(@ARG) );
    my @recursion = consolidate(@ARG);
    foreach my $r (@recursion) {
        if (set_intersection($result[0], $r)) {
            $result[0] = [ set_union($result[0], $r) ];
        }
        else {
            push @result, $r;
        }
    }
    return @result;
}

sub set_union {
    my ($a, $b) = @ARG;
    my %union;
    foreach my $a_elt (@{$a}) { $union{$a_elt}++; }
    foreach my $b_elt (@{$b}) { $union{$b_elt}++; }
    return keys(%union);
}

sub set_intersection {
    my ($a, $b) = @ARG;
    my %a_hash;
    foreach my $a_elt (@{$a}) { $a_hash{$a_elt}++; }
    my @result;
    foreach my $b_elt (@{$b}) {
        push(@result, $b_elt) if exists($a_hash{$b_elt});
    }
    return @result;
}


with(NumberTheory):

countDivisors := proc(x::integer)
 return numelems(Divisors(x));
end proc:

sequenceValue := proc(x::integer)
 local count:
 for count from 1 to infinity while not countDivisors(count) = x do end:
 return count;
end proc:

seq(sequenceValue(number), number = 1..15);


Take[SplitBy[SortBy[{DivisorSigma[0, #], #} & /@ Range[100000], First], First][[All, 1]], 15] // Grid


MODULE A005179;
FROM InOut IMPORT WriteCard, WriteLn;

CONST Amount = 15;
VAR found, i, ndivs: CARDINAL;
    A: ARRAY [1..Amount] OF CARDINAL;

PROCEDURE divisors(n: CARDINAL): CARDINAL;
    VAR count, i: CARDINAL;
BEGIN
    count := 0;
    i := 1;
    WHILE i*i <= n DO
        IF n MOD i = 0 THEN
            INC(count);
            IF n DIV i # i THEN
                INC(count);
            END;
        END;
        INC(i);
    END;
    RETURN count;
END divisors;

BEGIN
    FOR i := 1 TO Amount DO A[i] := 0; END;

    found := 0;
    i := 1;
    WHILE found < Amount DO
        ndivs := divisors(i);
        IF (ndivs <= Amount) AND (A[ndivs] = 0) THEN
            INC(found);
            A[ndivs] := i;
        END;
        INC(i);
    END;

    FOR i := 1 TO Amount DO
        WriteCard(A[i], 4);
        WriteLn;
    END;
END A005179.


with javascript_semantics
function has_intersection(sequence set1, set2)
    for i=1 to length(set1) do
        if find(set1[i],set2) then
            return true
        end if
    end for
    return false
end function

function get_union(sequence set1, set2)
    for i=1 to length(set2) do
        if not find(set2[i],set1) then
            set1 = append(set1,set2[i])
        end if
    end for
    return set1
end function

function consolidate(sequence sets)
    for i=length(sets) to 1 by -1 do
        for j=length(sets) to i+1 by -1 do
            if has_intersection(sets[i],sets[j]) then
                sets[i] = get_union(sets[i],sets[j])
                sets[j..j] = {}
            end if
        end for
    end for
    return sets
end function

?consolidate({"AB","CD"})
?consolidate({"AB","BD"})
?consolidate({"AB","CD","DB"})
?consolidate({"HIK","AB","CD","DB","FGH"})


def count_divisors(n)
        count = 0
        for (i = 1) ((i * i) <= n) (i += 1)
                if (n % i) = 0
                        if i = (n / i)
                                count += 1
                        else
                                count += 2
                        end
                end
        end
        return count
end

max = 15
seq = {0} * max
print format("The first %d terms of the sequence are:\n", max)
i = 1
for (n = 0) (n < max) (i += 1)
        k = count_divisors(i)
        if (k <= max)
                if seq[k - 1] = 0
                        seq[k - 1] = i
                        n += 1
                end
        end
end
println seq


import strformat

const MAX = 15

func countDivisors(n: int): int =
  var count = 0
  var i = 1
  while i * i <= n:
    if n mod i == 0:
      if i == n div i:
        inc count, 1
      else:
        inc count, 2
    inc i
  count

var sequence: array[MAX, int]
echo fmt"The first {MAX} terms of the sequence are:"
var i = 1
var n = 0
while n < MAX:
  var k = countDivisors(i)
  if k <= MAX and sequence[k - 1] == 0:
    sequence[k - 1] = i
    inc n
  inc i
echo sequence


use strict;
use warnings;
use ntheory 'divisors';

print "First 15 terms of OEIS: A005179\n";
for my $n (1..15) {
    my $l = 0;
    while (++$l) {
        print "$l " and last if $n == divisors($l);
    }
}


with javascript_semantics
constant limit = 15
sequence res = repeat(0,limit)
integer found = 0, n = 1
while found<limit do
    integer k = length(factors(n,1))
    if k<=limit and res[k]=0 then
        res[k] = n
        found += 1
    end if
    n += 1
end while
printf(1,"The first %d terms are: %V\n",{limit,res})


 /* FIND THE SMALLEST NUMBER > THE PREVIOUS ONE WITH EXACTLY N DIVISORS */

sequence_100H: procedure options                                                (main);

/* PROGRAM-SPECIFIC %REPLACE STATEMENTS MUST APPEAR BEFORE THE %INCLUDE AS */
/* E.G. THE CP/M PL/I COMPILER DOESN'T LIKE THEM TO FOLLOW PROCEDURES      */
   /* PL/I                                                                      */
      %replace maxnumber by         15;
   /* PL/M */                                                                   /*
      DECLARE  MAXNUMBER LITERALLY '15';
   /* */

/* PL/I DEFINITIONS                                                             */
%include 'pg.inc';
/* PL/M DEFINITIONS: CP/M BDOS SYSTEM CALL AND CONSOLE I/O ROUTINES, ETC. */    /*
   DECLARE BINARY LITERALLY 'ADDRESS', CHARACTER LITERALLY 'BYTE';
   DECLARE FIXED  LITERALLY ' ',       BIT       LITERALLY 'BYTE';
   DECLARE STATIC LITERALLY ' ',       RETURNS   LITERALLY ' ';
   DECLARE FALSE  LITERALLY '0',       TRUE      LITERALLY '1';
   DECLARE HBOUND LITERALLY 'LAST',    SADDR     LITERALLY '.';
   BDOSF: PROCEDURE( FN, ARG )BYTE;
                               DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END;
   BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;   END;
   PRCHAR:   PROCEDURE( C );   DECLARE C BYTE;      CALL BDOS( 2, C ); END;
   PRSTRING: PROCEDURE( S );   DECLARE S ADDRESS;   CALL BDOS( 9, S ); END;
   PRNL:     PROCEDURE;        CALL PRCHAR( 0DH ); CALL PRCHAR( 0AH ); END;
   PRNUMBER: PROCEDURE( N );
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
      N$STR( W := LAST( N$STR ) ) = '$';
      N$STR( W := W - 1 ) = '0' + ( ( V := N ) MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END;
      CALL BDOS( 9, .N$STR( W ) );
   END PRNUMBER;
   MODF: PROCEDURE( A, B )ADDRESS;
      DECLARE ( A, B )ADDRESS;
      RETURN( A MOD B );
   END MODF;
   MIN: PROCEDURE( A, B ) ADDRESS;
      DECLARE  ( A, B ) ADDRESS;
      IF A < B THEN RETURN( A ); ELSE RETURN( B );
   END MIN;
/* END LANGUAGE DEFINITIONS */

   /* TASK */

   COUNTDIVISORS: PROCEDURE( N )RETURNS /* THE DIVISOR COUNT OF N */            (
                                FIXED BINARY                                    )
                                ;
      DECLARE N                 FIXED BINARY;
      DECLARE ( I, I2, COUNT )  FIXED BINARY;
      COUNT = 0;
      I     = 1;
      I2    = 1;
      DO WHILE( I2 < N );
         IF MODF( N, I ) = 0 THEN COUNT = COUNT + 2;
         I  = I + 1;
         I2 = I * I;
      END;
      IF I2 = N THEN RETURN ( COUNT + 1 ); ELSE RETURN ( COUNT );
   END COUNTDIVISORS ;

   DECLARE ( I, NEXT ) FIXED BINARY;

   CALL PRSTRING( SADDR( 'THE FIRST $' ) );
   CALL PRNUMBER( MAXNUMBER );
   CALL PRSTRING( SADDR( ' TERMS OF THE SEQUENCE ARE:$' ) );
   NEXT = 1;
   I    = 1;
   DO WHILE( NEXT <= MAXNUMBER );
      IF NEXT = COUNTDIVISORS( I ) THEN DO;
         CALL PRCHAR( ' ' );
         CALL PRNUMBER( I );
         NEXT = NEXT + 1;
      END;
      I = I + 1;
   END;

EOF: end sequence_100H;


def divisors(n):
    divs = [1]
    for ii in range(2, int(n ** 0.5) + 3):
        if n % ii == 0:
            divs.append(ii)
            divs.append(int(n / ii))
    divs.append(n)
    return list(set(divs))

def sequence(max_n=None):
    previous = 0
    n = 0
    while True:
        n += 1
        ii = previous
        if max_n is not None:
            if n > max_n:
                break
        while True:
            ii += 1
            if len(divisors(ii)) == n:
                yield ii
                previous = ii
                break

if __name__ == '__main__':
    for item in sequence(15):
        print(item)


(de consolidate (S)
   (when S
      (let R (cons (car S))
         (for X (consolidate (cdr S))
            (if (mmeq X (car R))
               (set R (uniq (conc X (car R))))
               (conc R (cons X)) ) )
         R ) ) )


Set: procedure options (main);     /* 13 November 2013 */
   declare set(20) character (200) varying;
   declare e character (1);
   declare (i, n) fixed binary;

   set = '';
   n = 1;
   do until (e = ']');
      get edit (e) (a(1)); put edit (e) (a(1));
      if e = '}' then n = n + 1; /* end of set. */
      if e ^= '{' & e ^= ',' & e ^= '}' & e ^= ' ' then
         set(n) = set(n) || e;   /* Build set */
   end;
   /* We have read in all sets. */
   n = n - 1; /* we have n sets */
   /* Display the sets: */
   put skip list ('The original sets:');
   do i = 1 to n;
      call print(i);
   end;
   /* Look for sets to combine: */
   do i = 2 to n;
      if length(set(i)) > 0 then
         if search(set(1), set(i)) > 0 then
            /* there's at least one common element */
            do; call combine (1, i); set(i) = '';  end;
   end;

   put skip (2) list ('Results:');
   do i = 1 to n;
      if length(set(i)) > 0 then call print (i);
   end;

combine: procedure (p, q);
   declare (p, q) fixed binary;
   declare e character (1);
   declare i fixed binary;

   do i = 1 to length(set(q));
      e = substr(set(q), i, 1);
      if index(set(p), e) = 0 then set(p) = set(p) || e;
   end;

end combine;

print: procedure(k);
   declare k fixed binary;
   declare i fixed binary;

   put edit ('{') (a);
   do i = 1 to length(set(k));
      put edit (substr(set(k), i, 1)) (a);
      if i < length(set(k)) then put edit (',') (a);
   end;
   put edit ('} ') (a);
end print;

end Set;


def consolidate(sets):
    setlist = [s for s in sets if s]
    for i, s1 in enumerate(setlist):
        if s1:
            for s2 in setlist[i+1:]:
                intersection = s1.intersection(s2)
                if intersection:
                    s2.update(s1)
                    s1.clear()
                    s1 = s2
    return [s for s in setlist if s]


#lang racket
(define (consolidate ss)
  (define (comb s cs)
    (cond [(set-empty? s) cs]
          [(empty? cs) (list s)]
          [(set-empty? (set-intersect s (first cs)))
           (cons (first cs) (comb s (rest cs)))]
          [(consolidate (cons (set-union s (first cs)) (rest cs)))]))
  (foldl comb '() ss))

(consolidate (list (set 'a 'b) (set 'c 'd)))
(consolidate (list (set 'a 'b) (set 'b 'c)))
(consolidate (list (set 'a 'b) (set 'c 'd) (set 'd 'b)))
(consolidate (list (set 'h 'i 'k) (set 'a 'b) (set 'c 'd) (set 'd 'b) (set 'f 'g 'h)))


def divisors(n):
    divs = [1]
    for ii in range(2, int(n ** 0.5) + 3):
        if n % ii == 0:
            divs.append(ii)
            divs.append(int(n / ii))
    divs.append(n)
    return list(set(divs))

def sequence(max_n=None):
    n = 0
    while True:
        n += 1
        ii = 0
        if max_n is not None:
            if n > max_n:
                break
        while True:
            ii += 1
            if len(divisors(ii)) == n:
                yield ii
                break

if __name__ == '__main__':
    for item in sequence(15):
        print(item)


 [ 0
   [ 1+ 2dup
     factors size =
     until ]
   nip ]            is nfactors ( n --> n )

 15 times [ i^ 1+ nfactors echo sp ]


#Need to add 1 to account for skipping n. Not the most efficient way to count divisors, but quite clear.
divisorCount <- function(n) length(Filter(function(x) n %% x == 0, seq_len(n %/% 2))) + 1
smallestWithNDivisors <- function(n)
{
  i <- 1
  while(divisorCount(i) != n) i <- i + 1
  i
}
print(sapply(1:15, smallestWithNDivisors))


  [ stack ]                is terms (   --> s )

  [ temp put
    [] terms put
    0 1
    [ dip 1+
      over factors size
      over = if
        [ over
          terms take
          swap join
          terms put
          1+ ]
      terms share size
      temp share = until ]
    terms take
    temp release
    dip 2drop ]            is task  ( n --> [ )

  15 task echo


#Need to add 1 to account for skipping n. Not the most efficient way to count divisors, but quite clear.
divisorCount <- function(n) length(Filter(function(x) n %% x == 0, seq_len(n %/% 2))) + 1
A06954 <- function(terms)
{
  out <- 1
  while((resultCount <- length(out)) != terms)
  {
    n <- resultCount + 1
    out[n] <- out[resultCount]
    while(divisorCount(out[n]) != n) out[n] <- out[n] + 1
  }
  out
}
print(A06954(15))


sub div-count (\x) {
    return 2 if x.is-prime;
    +flat (1 .. x.sqrt.floor).map: -> \d {
        unless x % d { my \y = x div d; y == d ?? y !! (y, d) }
    }
}

my $limit = 15;

my $m = 1;
put "First $limit terms of OEIS:A069654";
put (1..$limit).map: -> $n { my $ = $m = first { $n == .&div-count }, $m..Inf };


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

enum Elems <A B C D E F G H I J K>;
say $_, "\n    ==> ", consolidate |$_
    for [set(A,B), set(C,D)],
        [set(A,B), set(B,D)],
        [set(A,B), set(C,D), set(D,B)],
        [set(H,I,K), set(A,B), set(C,D), set(D,B), set(F,G,H)];


/*REXX program demonstrates a method of    set consolidating    using some sample sets. */
@.=;               @.1 = '{A,B}     {C,D}'
                   @.2 = "{A,B}     {B,D}"
                   @.3 = '{A,B}     {C,D}     {D,B}'
                   @.4 = '{H,I,K}   {A,B}     {C,D}     {D,B}     {F,G,H}'
                   @.5 = '{snow,ice,slush,frost,fog} {icebergs,icecubes} {rain,fog,sleet}'

           do j=1  while @.j\==''                /*traipse through each of sample sets. */
           call SETconsolidate @.j               /*have the function do the heavy work. */
           end   /*j*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
isIn:  return wordpos(arg(1), arg(2))\==0        /*is (word) argument 1 in the set arg2?*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
SETconsolidate: procedure;  parse arg old;       #= words(old);       new=
       say ' the old set='  space(old)

         do k=1  for #                           /* [↓]  change all commas to a blank.  */
         !.k= translate( word(old, k), , '},{')  /*create a list of words  (aka, a set).*/
         end   /*k*/                             /* [↑]  ··· and also remove the braces.*/

         do  until \changed;     changed= 0      /*consolidate some sets  (well, maybe).*/
              do set=1  for #-1
                  do item=1  for words(!.set);       x= word(!.set, item)
                      do other=set+1  to #
                      if isIn(x, !.other)  then do;  changed= 1           /*it's changed*/
                                                     !.set= !.set !.other;       !.other=
                                                     iterate set
                                                end
                      end   /*other*/
                  end       /*item */
              end           /*set  */
         end                /*until ¬changed*/

            do set=1  for #;                  $=                            /*elide dups*/
              do items=1  for words(!.set);   x= word(!.set, items)
              if x==','  then iterate;        if x==''  then leave
              $= $ x                                                        /*build new.*/
                     do  until  \isIn(x, !.set);      _= wordpos(x, !.set)
                     _= wordpos(x, !.set)
                     !.set= subword(!.set, 1, _-1) ',' subword(!.set, _+1)  /*purify set*/
                     end   /*until ¬isIn ··· */
              end          /*items*/
            !.set= translate( strip($), ',', " ")
            end            /*set*/

         do i=1  for #; if !.i==''  then iterate /*ignore any  set  that is a null set. */
         new= space(new   '{'!.i"}")             /*prepend and append a set identifier. */
         end   /*i*/

       say ' the new set='  new;         say
       return


sub div-count (\x) {
    return 2 if x.is-prime;
    +flat (1 .. x.sqrt.floor).map: -> \d {
        unless x % d { my \y = x div d; y == d ?? y !! (y, d) }
    }
}

my $limit = 15;

put "First $limit terms of OEIS:A005179";
put (1..$limit).map: -> $n { first { $n == .&div-count }, 1..Inf };


/*REXX program finds and displays  the   smallest number   with  exactly   N   divisors.*/
parse arg N .                                    /*obtain optional argument from the CL.*/
if N=='' | N==","  then N= 15                    /*Not specified?  Then use the default.*/
say '──divisors──  ──smallest number with N divisors──' /*display title for the numbers.*/
@.=                                              /*the  @  array is used for memoization*/
    do i=1  for N;     z= 1  +  (i\==1)          /*step through a number of divisors.   */
       do j=z  by z                              /*now, search for a number that ≡ #divs*/
       if @.j==.  then iterate                   /*has this number already been found?  */
       d= #divs(j);    if d\==i  then iterate    /*get # divisors;  Is not equal?  Skip.*/
       say center(i, 12)  right(j, 19)           /*display the #divs and the smallest #.*/
       @.j= .                                    /*mark as having found #divs for this J*/
       leave                                     /*found a number, so now get the next I*/
       end   /*j*/
    end      /*i*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
#divs: procedure; parse arg x 1 y                /*X and Y:  both set from 1st argument.*/
       if x<7  then do; if x<3   then return x   /*handle special cases for one and two.*/
                        if x<5   then return x-1 /*   "      "      "    "  three & four*/
                        if x==5  then return 2   /*   "      "      "    "  five.       */
                        if x==6  then return 4   /*   "      "      "    "  six.        */
                    end
       odd= x // 2                               /*check if   X   is  odd  or not.      */
       if odd  then      #= 1                    /*Odd?   Assume  Pdivisors  count of 1.*/
               else do;  #= 3;   y= x%2;  end    /*Even?     "        "        "    " 3.*/
                                                 /* [↑]   start with known num of Pdivs.*/
                  do k=3  for x%2-3  by 1+odd  while k<y  /*for odd numbers, skip evens.*/
                  if x//k==0  then do            /*if no remainder, then found a divisor*/
                                   #=#+2;  y=x%k /*bump  #  Pdivs,  calculate limit  Y. */
                                   if k>=y  then do;  #= #-1;  leave;  end      /*limit?*/
                                   end                                          /*  ___ */
                              else if k*k>x  then leave        /*only divide up to √ x  */
                  end   /*k*/                    /* [↑]  this form of DO loop is faster.*/
       return #+1                                /*bump "proper divisors" to "divisors".*/


/*REXX program finds and displays   N   numbers of the   "anti─primes plus"   sequence. */
parse arg N .                                    /*obtain optional argument from the CL.*/
if N=='' | N==","  then N= 15                    /*Not specified?  Then use the default.*/
idx= 1                                           /*the maximum number of divisors so far*/
say '──index──  ──anti─prime plus──'             /*display a title for the numbers shown*/
#= 0                                             /*the count of anti─primes found  "  " */
        do i=1  until #==N                       /*step through possible numbers by twos*/
        d= #divs(i);  if d\==idx  then iterate   /*get # divisors;  Is too small?  Skip.*/
        #= # + 1;     idx= idx + 1               /*found an anti─prime #;  set new minD.*/
        say center(#, 8)  right(i, 15)           /*display the index and the anti─prime.*/
        end   /*i*/
exit 0                                            /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
#divs: procedure; parse arg x 1 y                /*X and Y:  both set from 1st argument.*/
       if x<7  then do                           /*handle special cases for numbers < 7.*/
                    if x<3   then return x       /*   "      "      "    "  one and two.*/
                    if x<5   then return x - 1   /*   "      "      "    "  three & four*/
                    if x==5  then return 2       /*   "      "      "    "  five.       */
                    if x==6  then return 4       /*   "      "      "    "  six.        */
                    end
       odd= x // 2                               /*check if   X   is  odd  or not.      */
       if odd  then      #= 1;                   /*Odd?   Assume  Pdivisors  count of 1.*/
               else do;  #= 3;    y= x % 2       /*Even?     "        "        "    " 3.*/
                    end                          /* [↑]  Even,  so add 2 known divisors.*/
                                                 /* [↓] start with known number of Pdivs*/
          do k=3  for x%2-3  by 1+odd  while k<y /*for odd numbers, skip over the evens.*/
          if x//k==0  then do                    /*if no remainder, then found a divisor*/
                           #= # + 2;   y= x % k  /*bump the # Pdivs;  calculate limit Y.*/
                           if k>=y  then do;   #= # - 1;   leave
                                         end     /* [↑]  has the limit been reached?    */
                           end                   /*                         ___         */
                      else if k*k>x  then leave  /*only divide up to the   √ x          */
          end   /*k*/                            /* [↑]  this form of DO loop is faster.*/
       return # + 1                              /*bump "proper divisors" to "divisors".*/


# Project : ANti-primes

see "working..." + nl
see "wait for done..." + nl + nl
see "the first 15 Anti-primes Plus are:" + nl + nl
num = 1
n = 0
result = list(15)
while num < 16
      n = n + 1
      div = factors(n)
      if div = num
         result[num] = n
         num = num + 1
      ok
end
see "["
for n = 1 to len(result)
    if n < len(result)
       see string(result[n]) + ","
    else
       see string(result[n]) + "]" + nl + nl
    ok
next
see "done..." + nl

func factors(an)
     ansum = 2
     if an < 2
        return(1)
     ok
     for nr = 2 to an/2
         if an%nr = 0
            ansum = ansum+1
         ok
     next
     return ansum


require 'prime'

def num_divisors(n)
  n.prime_division.inject(1){|prod, (_p,n)| prod *= (n + 1) }
end

seq = Enumerator.new do |y|
  cur = 0
  (1..).each do |i|
    if num_divisors(i) == cur + 1 then
      y << i
      cur += 1
    end
  end
end

p seq.take(15)


# Project : Set consolidation

load "stdlib.ring"
test = ["AB","AB,CD","AB,CD,DB","HIK,AB,CD,DB,FGH"]
for t in test
     see consolidate(t) + nl
next
func consolidate(s)
	sets = split(s,",")
	n = len(sets)
	for i = 1 to n
	     p = i
             ts = ""
	     for j = i to 1 step -1
		 if ts = ""
		    p = j
		 ok
		 ts = ""
		 for k = 1 to len(sets[p])
                      if j > 1
		         if substring(sets[j-1],substr(sets[p],k,1),1) = 0
			     ts = ts + substr(sets[p],k,1)
		         ok
                      ok
		 next
		 if len(ts) < len(sets[p])
                    if j > 1
		       sets[j-1] = sets[j-1] + ts
		       sets[p] = "-"
		       ts = ""
                    ok
		 else
		    p = i
		 ok
	     next
	next
	consolidate = s + " = " + substr(list2str(sets),nl,",")
        return consolidate


require 'set'

tests = [[[:A,:B], [:C,:D]],
         [[:A,:B], [:B,:D]],
         [[:A,:B], [:C,:D], [:D,:B]],
         [[:H,:I,:K], [:A,:B], [:C,:D], [:D,:B], [:F,:G,:H]]]
tests.map!{|sets| sets.map(&:to_set)}

tests.each do |sets|
  until sets.combination(2).none?{|a,b| a.merge(b) && sets.delete(b) if a.intersect?(b)}
  end
  p sets
end


object SetConsolidation extends App {
    def consolidate[Type](sets: Set[Set[Type]]): Set[Set[Type]] = {
        var result = sets // each iteration combines two sets and reiterates, else returns
        for (i <- sets; j <- sets - i; k = i.intersect(j);
            if result == sets && k.nonEmpty) result = result - i - j + i.union(j)
        if (result == sets) sets else consolidate(result)
    }

    // Tests:
    def parse(s: String) =
        s.split(",").map(_.split("").toSet).toSet
    def pretty[Type](sets: Set[Set[Type]]) =
        sets.map(_.mkString("{",",","}")).mkString(" ")
    val tests = List(
        parse("AB,CD") -> Set(Set("A", "B"), Set("C", "D")),
        parse("AB,BD") -> Set(Set("A", "B", "D")),
        parse("AB,CD,DB") -> Set(Set("A", "B", "C", "D")),
        parse("HIK,AB,CD,DB,FGH") -> Set(Set("A", "B", "C", "D"), Set("F", "G", "H", "I", "K"))
    )
    require(Set("A", "B", "C", "D") == Set("B", "C", "A", "D"))
    assert(tests.forall{case (test, expect) =>
        val result = consolidate(test)
        println(s"${pretty(test)} -> ${pretty(result)}")
        expect == result
    })

}


load "stdlib.ring"

see "working..." + nl
see "the first 15 terms of the sequence are:" + nl

for n = 1 to 15
    for m = 1 to 4100
        pnum = 0
        for p = 1 to 4100
            if (m % p = 0)
               pnum = pnum + 1
            ok
        next
        if pnum = n
           see "" + m + " "
           exit
        ok
     next
next

see nl + "done..." + nl


require 'prime'

def num_divisors(n)
  n.prime_division.inject(1){|prod, (_p,n)| prod *= (n + 1) }
end

def first_with_num_divs(n)
  (1..).detect{|i| num_divisors(i) == n }
end

p (1..15).map{|n| first_with_num_divs(n) }


use itertools::Itertools;

const PRIMES: [u64; 15] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47];
const MAX_DIVISOR: usize = 64;

struct DivisorSeq {
    max_number_of_divisors: u64,
    index: u64,
}

impl DivisorSeq {
    fn new(max_number_of_divisors: u64) -> DivisorSeq {
        DivisorSeq {
            max_number_of_divisors,
            index: 1,
        }
    }
}

impl Iterator for DivisorSeq {
    type Item = u64;

    fn next(&mut self) -> Option<u64> {
        if self.max_number_of_divisors < self.index {
            return None;
        }
        #[allow(unused_mut)]
        let mut result: u64;
        let divisors_of_divisor = get_divisors(self.index);
        match divisors_of_divisor.len() {
            1 | 2 => {
                // when # divisors is a prime
                result = 2_u64.pow(self.index as u32 - 1);
                self.index += 1;
            }
            3 => {
                // when # divisors is a prime square
                result = 6_u64.pow(divisors_of_divisor[1] as u32 - 1);
                self.index += 1;
            }
            4 => {
                // when # divisors is a prime * non-prime
                result = 2_u64.pow(divisors_of_divisor[2] as u32 - 1)
                    * 3_u64.pow(divisors_of_divisor[1] as u32 - 1);
                self.index += 1;
            }
            8 if divisors_of_divisor
                .iter()
                .filter(|x| PRIMES.contains(x))
                .count()
                == 3 =>
            {
                // sphenic numbers, aka p*m*q, where, p, m and q are prime
                let first_primes = divisors_of_divisor
                    .iter()
                    .filter(|x| PRIMES.contains(x))
                    .collect::<Vec<_>>();
                result = 2_u64.pow(*first_primes[2] as u32 - 1)
                    * 3_u64.pow(*first_primes[1] as u32 - 1)
                    * 5_u64.pow(*first_primes[0] as u32 - 1);
                self.index += 1;
            }
            _ => {
                // brute force and slow: iterates over the numbers to find
                // one with the appropriate number of divisors
                let mut x: u64 = 1;
                loop {
                    if get_divisors(x).len() as u64 == self.index {
                        break;
                    }
                    x += 1;
                }

                result = x;
                self.index += 1;
            }
        }
        Some(result)
    }
}
/// Gets all divisors of a number
fn get_divisors(n: u64) -> Vec<u64> {
    let mut results = Vec::new();

    for i in 1..(n / 2 + 1) {
        if n % i == 0 {
            results.push(i);
        }
    }
    results.push(n);
    results
}

fn main() {
    // simple version using factorizing numbers
    // with rules applied from A005179 so speed up
    // but as such it is slow in some cases, e.g for 52
    let seq_iter = DivisorSeq::new(64);
    println!("Simple method with rules");
    println!("# divisors     Smallest number");
    for (i, x) in seq_iter.enumerate() {
        println!("{:>10}{:20}", i + 1, x);
    }

    // more advanced version using calculations based on number of
    // prime factors and their exponent

    // load initial result table with an initial value of 2**n for each item
    let mut min_numbers = vec![0_u64; MAX_DIVISOR];
    (0_usize..MAX_DIVISOR).for_each(|n| min_numbers[n] = 2_u64.pow(n as u32));

    let prime_list = (1..15).map(|i| PRIMES[0..=i].to_vec()).collect::<Vec<_>>();

    for pl in prime_list.iter() {
        // calculate the max exponent a prime can get in a given prime-list
        // to be able to produce the desired number of divisors
        let max_exponent = 1 + MAX_DIVISOR as u32 / 2_u32.pow(pl.len() as u32 - 1);

        // create a combination of exponents using cartesian product
        let exponents = (1_usize..=pl.len())
            .map(|_| 1_u32..=max_exponent)
            .multi_cartesian_product()
            .filter(|elt| {
                let mut prev = None::<&u32>;
                elt.iter().all(|x| match prev {
                    Some(n) if x > n => false,
                    _ => {
                        prev = Some(x);
                        true
                    }
                })
            });

        // iterate throught he exponent combinations
        for exp in exponents {
            // calculate the number of divisors using the formula
            // given primes of p, q, r
            // and exponents of a1, a2, a3
            // the # divisors is (a1+1)* (a2+1) *(a3+1)
            let num_of_divisors = exp.iter().map(|x| x + 1).product::<u32>() as usize;

            // and calculate the number with those primes and the given exponent set
            let num = pl.iter().zip(exp.iter()).fold(1_u64, |mut acc, (p, e)| {
                // check for overflow if numbers won't fit into u64
                acc = match acc.checked_mul(p.pow(*e)) {
                    Some(z) => z,
                    _ => 0,
                };
                acc
            });

            // finally, if the number is less than what we have so far in the result table
            // replace the result table with the smaller number
            if num > 0
                && min_numbers.len() >= num_of_divisors
                && min_numbers[num_of_divisors - 1] > num
            {
                min_numbers[num_of_divisors - 1] = num;
            }
        }
    }

    println!("Advanced method");
    println!("# divisors     Smallest number");
    for (i, x) in min_numbers.iter().enumerate() {
        println!("{:>10}{:20}", i + 1, x);
    }
}


func n_divisors(n) {
    1..Inf -> first_by { .sigma0 == n }
}

say 15.of { n_divisors(_+1) }


func n_divisors(n, from=1) {
    from..Inf -> first_by { .sigma0 == n }
}

with (1) { |from|
    say 15.of { from = n_divisors(_+1, from) }
}


// See https://en.wikipedia.org/wiki/Divisor_function
func divisorCount(number: Int) -> Int {
    var n = number
    var total = 1
    // Deal with powers of 2 first
    while n % 2 == 0 {
        total += 1
        n /= 2
    }
    // Odd prime factors up to the square root
    var p = 3
    while p * p <= n {
        var count = 1
        while n % p == 0 {
            count += 1
            n /= p
        }
        total *= count
        p += 2
    }
    // If n > 1 then it's prime
    if n > 1 {
        total *= 2
    }
    return total
}

let limit = 32
var n = 1
var next = 1
while next <= limit {
    if next == divisorCount(number: n) {
        print(n, terminator: " ")
        next += 1
        if next > 4 && divisorCount(number: next) == 2 {
            n = 1 << (next - 1) - 1;
        }
    }
    n += 1
}
print()


import "/math" for Int

var limit = 24
var res = List.filled(limit, 0)
var next = 1
var n = 1
while (next <= limit) {
    var k = Int.divisors(n).count
    if (k == next) {
        res[k-1] = n
        next = next + 1
        if (next > 4 && Int.isPrime(next)) n = 2.pow(next-1) - 1
    }
    n = n + 1
}
System.print("The first %(limit) terms are:")
System.print(res)


func Divs(N);   \Count divisors of N
int  N, D, C;
[C:= 0;
if N > 1 then
    [D:= 1;
    repeat  if rem(N/D) = 0 then C:= C+1;
            D:= D+1;
    until   D >= N;
    ];
return C;
];

int An, N;
[An:= 1;  N:= 0;
loop [if Divs(An) = N then
        [IntOut(0, An);  ChOut(0, ^ );
        N:= N+1;
        if N >= 15 then quit;
        ];
     An:= An+1;
     ];
]


fcn countDivisors(n)
   { [1..(n).toFloat().sqrt()] .reduce('wrap(s,i){ s + (if(0==n%i) 1 + (i!=n/i)) },0) }


func consolidate() { [] }
func consolidate(this, *those) {
    gather {
        consolidate(those...).each { |that|
            if (this & that) { this |= that }
            else             { take that }
        }
        take this;
    }
}

enum |A="A", B, C, D, _E, F, G, H, I, _J, K|;

func format(ss) {
    ss.map{ '(' + .join(' ') + ')' }.join(' ')
}

[
    [[A,B], [C,D]],
    [[A,B], [B,D]],
    [[A,B], [C,D], [D,B]],
    [[H,I,K], [A,B], [C,D], [D,B], [F,G,H]]
].each { |ss|
    say (format(ss), "\n\t==> ", format(consolidate(ss...)));
}


package require struct::set

proc consolidate {sets} {
    if {[llength $sets] < 2} {
	return $sets
    }

    set r [list {}]
    set r0 [lindex $sets 0]
    foreach x [consolidate [lrange $sets 1 end]] {
	if {[struct::set size [struct::set intersect $x $r0]]} {
	    struct::set add r0 $x
	} else {
	    lappend r $x
	}
    }
    return [lset r 0 $r0]
}


// See https://en.wikipedia.org/wiki/Divisor_function
func divisorCount(number: Int) -> Int {
    var n = number
    var total = 1
    // Deal with powers of 2 first
    while n % 2 == 0 {
        total += 1
        n /= 2
    }
    // Odd prime factors up to the square root
    var p = 3
    while p * p <= n {
        var count = 1
        while n % p == 0 {
            count += 1
            n /= p
        }
        total *= count
        p += 2
    }
    // If n > 1 then it's prime
    if n > 1 {
        total *= 2
    }
    return total
}

let limit = 15
var sequence = Array(repeating: 0, count: limit)
var count = 0
var n = 1
while count < limit {
    let divisors = divisorCount(number: n)
    if divisors <= limit && sequence[divisors - 1] == 0 {
        sequence[divisors - 1] = n
        count += 1
    }
    n += 1
}
for n in sequence {
    print(n, terminator: " ")
}
print()


proc divCount {n} {
    set cnt 0
    for {set d 1} {($d * $d) <= $n} {incr d} {
        if {0 == ($n % $d)} {
            incr cnt
            if {$d < ($n / $d)} {
                incr cnt
            }
        }
    }
    return $cnt
}

proc A005179 {n} {
    if {$n >= 1} {
        for {set k 1} {1} {incr k} {
            if {$n == [divCount $k]} {
                return $k
            }
        }
    }
    return 0
}

proc show {func lo hi} {
    puts "${func}($lo..$hi) ="
    for {set n $lo} {$n <= $hi} {incr n} {
        puts -nonewline " [$func $n]"
    }
    puts ""
}

show A005179 1 15


import "/math" for Int

var limit = 22
var numbers = List.filled(limit, 0)
var i = 1
while (true) {
    var nd = Int.divisors(i).count
    if (nd <= limit && numbers[nd-1] == 0) {
        numbers[nd-1] = i
        if (numbers.all { |n| n > 0 }) break
    }
    i = i + 1
}
System.print("The first %(limit) terms are:")
System.print(numbers)


(defun mkset (p x) (set [p x] (or [p x] x)))

(defun fnd (p x) (if (eq [p x] x) x (fnd p [p x])))

(defun uni (p x y)
  (let ((xr (fnd p x)) (yr (fnd p y)))
    (set [p xr] yr)))

(defun consoli (sets)
  (let ((p (hash)))
    (each ((s sets))
      (each ((e s))
        (mkset p e)
        (uni p e (car s))))
    (hash-values
      [group-by (op fnd p) (hash-keys
                             [group-by identity (flatten sets)])])))

;; tests

(each ((test '(((a b) (c d))
               ((a b) (b d))
               ((a b) (c d) (d b))
               ((h i k) (a b) (c d) (d b) (f g h)))))
  (format t "~s -> ~s\n" test (consoli test)))


Private Function has_intersection(set1 As Collection, set2 As Collection) As Boolean
    For Each element In set1
        On Error Resume Next
        tmp = set2(element)
        If tmp = element Then
            has_intersection = True
            Exit Function
        End If
    Next element
End Function
Private Sub union(set1 As Collection, set2 As Collection)
    For Each element In set2
        On Error Resume Next
        tmp = set1(element)
        If tmp <> element Then
            set1.Add element, element
        End If
    Next element
End Sub
Private Function consolidate(sets As Collection) As Collection
    For i = sets.Count To 1 Step -1
        For j = sets.Count To i + 1 Step -1
            If has_intersection(sets(i), sets(j)) Then
                union sets(i), sets(j)
                sets.Remove j
            End If
        Next j
    Next i
    Set consolidate = sets
End Function
Private Function mc(s As Variant) As Collection
    Dim res As New Collection
    For i = 1 To Len(s)
        res.Add Mid(s, i, 1), Mid(s, i, 1)
    Next i
    Set mc = res
End Function
Private Function ms(t As Variant) As Collection
    Dim res As New Collection
    Dim element As Collection
    For i = LBound(t) To UBound(t)
        Set element = t(i)
        res.Add t(i)
    Next i
    Set ms = res
End Function
Private Sub show(x As Collection)
    Dim t() As String
    Dim u() As String
    ReDim t(1 To x.Count)
    For i = 1 To x.Count
        ReDim u(1 To x(i).Count)
        For j = 1 To x(i).Count
            u(j) = x(i)(j)
        Next j
        t(i) = "{" & Join(u, ", ") & "}"
    Next i
    Debug.Print "{" & Join(t, ", ") & "}"
End Sub
Public Sub main()
    show consolidate(ms(Array(mc("AB"), mc("CD"))))
    show consolidate(ms(Array(mc("AB"), mc("BD"))))
    show consolidate(ms(Array(mc("AB"), mc("CD"), mc("DB"))))
    show consolidate(ms(Array(mc("HIK"), mc("AB"), mc("CD"), mc("DB"), mc("FGH"))))
End Sub


Function consolidate(s)
	sets = Split(s,",")
	n = UBound(sets)
	For i = 1 To n
		p = i
		ts = ""
		For j = i To 1 Step -1
			If ts = "" Then
				p = j
			End If
			ts = ""
			For k = 1 To Len(sets(p))
				If InStr(1,sets(j-1),Mid(sets(p),k,1)) = 0 Then
					ts = ts & Mid(sets(p),k,1)
				End If
			Next
			If Len(ts) < Len(sets(p)) Then
				sets(j-1) = sets(j-1) & ts
				sets(p) = "-"
				ts = ""
			Else
				p = i
			End If
		Next
	Next
	consolidate = s & " = " & Join(sets," , ")
End Function

'testing
test = Array("AB","AB,CD","AB,CD,DB","HIK,AB,CD,DB,FGH")
For Each t In test
	WScript.StdOut.WriteLine consolidate(t)
Next


func Divisors(N); \Return number of divisors of N
int  N, Count, D;
[Count:= 0;
for D:= 1 to N do
    if rem(N/D) = 0 then Count:= Count+1;
return Count;
];

int N, AN;
[for N:= 1 to 15 do
    [AN:= 0;
    repeat AN:= AN+1 until Divisors(AN) = N;
    IntOut(0, AN);  ChOut(0, ^ );
    ];
]


fcn countDivisors(n)
   { [1.. n.toFloat().sqrt()].reduce('wrap(s,i){ s + (if(0==n%i) 1 + (i!=n/i)) },0) }
A005179w:=(1).walker(*).tweak(fcn(n){
   var N=0,cache=Dictionary();
   if(cache.find(n)) return(cache.pop(n));	// prune
   while(1){
      if(n == (d:=countDivisors(N+=1))) return(N);
      if(n<d and not cache.find(d)) cache[d]=N;
   }
});


import "/set" for Set

var consolidateSets = Fn.new { |sets|
    var size = sets.count
    var consolidated = List.filled(size, false)
    var i = 0
    while (i < size - 1) {
        if (!consolidated[i]) {
            while (true) {
                var intersects = 0
                for (j in i+1...size) {
                    if (!consolidated[j]) {
                        if (!sets[i].intersect(sets[j]).isEmpty) {
                            sets[i].addAll(sets[j])
                            consolidated[j] = true
                            intersects = intersects + 1
                        }
                    }
                }
                if (intersects == 0) break
            }
        }
        i = i + 1
    }
    return (0...size).where { |i| !consolidated[i] }.map { |i| sets[i] }.toList
}

var unconsolidatedSets = [
    [Set.new(["A", "B"]), Set.new(["C", "D"])],
    [Set.new(["A", "B"]), Set.new(["B", "D"])],
    [Set.new(["A", "B"]), Set.new(["C", "D"]), Set.new(["D", "B"])],
    [Set.new(["H", "I", "K"]), Set.new(["A", "B"]), Set.new(["C", "D"]),
     Set.new(["D", "B"]), Set.new(["F", "G", "H"])]
]
for (sets in unconsolidatedSets) {
    System.print("Unconsolidated: %(sets)")
    System.print("Cosolidated   : %(consolidateSets.call(sets))\n")
}


fcn consolidate(sets){  // set are munged if they are read/write
   if(sets.len()<2) return(sets);
   r,r0 := List(List()),sets[0];
   foreach x in (consolidate(sets[1,*])){
      i,ni:=x.filter22(r0.holds); //-->(intersection, !intersection)
      if(i) r0=r0.extend(ni);
      else  r.append(x);
   }
   r[0]=r0;
   r
}


obj := {mA: Func("mA"), mB: Func("mB"), mC: Func("mC")}
InputBox, methodToCall, , Which method should I call?
obj[methodToCall].()

mA(){
 MsgBox Method A
}
mB(){
 MsgBox Method B
}
mC(){
 MsgBox Method C
}


(task=
  ( oracle
  =   (predicate="is made of green cheese")
      (generateTruth=.str$(!arg " " !(its.predicate) "."))
      (generateLie=.str$(!arg " " !(its.predicate) "!"))
  )
& new$oracle:?SourceOfKnowledge
&   put
  $ "You may ask the Source of Eternal Wisdom ONE thing.
Enter \"Truth\" or \"Lie\" on the next line and press the <Enter> key.
"
&   whl
  ' ( get':?trueorlie:~Truth:~Lie
    & put$"Try again\n"
    )
& put$(str$("You want a " !trueorlie ". About what?" \n))
& get'(,STR):?something
& (SourceOfKnowledge..str$(generate !trueorlie))$!something
);


using System;

class Example
{
    public int foo(int x)
    {
        return 42 + x;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var example = new Example();
        var method = "foo";

        var result = (int)example.GetType().GetMethod(method).Invoke(example, new object[]{ 5 });
        Console.WriteLine("{0}(5) = {1}", method, result);
    }
}


Class Unknown.Example Extends %RegisteredObject
{

Method Foo()
{
	Write "This is foo", !
}

Method Bar()
{
	Write "This is bar", !
}

}


(import '[java.util Date])
(import '[clojure.lang Reflector])

(def date1 (Date.))
(def date2 (Date.))
(def method "equals")

;; Two ways of invoking method "equals" on object date1
;; using date2 as argument

;; Way 1 - Using Reflector class
;; NOTE: The argument date2 is passed inside an array
(Reflector/invokeMethod date1 method (object-array [date2]))

;; Way 2 - Using eval
;; Eval runs any piece of valid Clojure code
;; So first we construct a piece of code to do what we want (where method name is inserted dynamically),
;; then we run the code using eval
(eval `(. date1 ~(symbol method) date2))


(funcall (intern "SOME-METHOD") my-object a few arguments)


local :object { :add @+ }
local :method :add

!. object! method 1 2


for name in ["foo", "bar"] {
    E.call(example, name, [])
}


import extensions;

class Example
{
    foo(x)
        = x + 42;
}

public program()
{
    var example := new Example();
    var methodSignature := "foo";

    var invoker := new MessageName(methodSignature);
    var result := invoker(example,5);

    console.printLine(methodSignature,"(",5,") = ",result)
}


USING: accessors kernel math prettyprint sequences words ;
IN: rosetta-code.unknown-method-call

TUPLE: foo num ;
C: <foo> foo
GENERIC: add5 ( x -- y )
M: foo add5 num>> 5 + ;

42 <foo>              ! construct a foo
"add" "5" append      ! construct a word name
                      ! must specify vocab to look up a word
"rosetta-code.unknown-method-call"
lookup-word execute . ! 47


include FMS-SI.f
include FMS-SILib.f

var x  \ instantiate a class var object named x

\ Use a standard Forth string and evaluate it.
\ This is equivalent to sending the !: message to object x
42 x  s" !:"  evaluate

x p: 42     \ send the print message ( p: ) to x to verify the contents


package main

import (
    "fmt"
    "reflect"
)

type example struct{}

// the method must be exported to be accessed through reflection.
func (example) Foo() int {
    return 42
}

func main() {
    // create an object with a method
    var e example
    // get the method by name
    m := reflect.ValueOf(e).MethodByName("Foo")
    // call the method with no argments
    r := m.Call(nil)
    // interpret first return value as int
    fmt.Println(r[0].Int()) // => 42
}


class Example {
    def foo(value) {
        "Invoked with '$value'"
    }
}

def example = new Example()
def method = "foo"
def arg = "test value"

assert "Invoked with 'test value'" == example."$method"(arg)


procedure main()
   x := foo()    # create object
   x.m1()        # static call of m1 method
   #  two examples where the method string can be dynamically constructed ...
   "foo_m1"(x)   # ... need to know class name and method name to construct name
   x.__m["m1"]   # ... general method (better)
end

class foo(a,b,c) # define object
method m1(x)
end
end


Example := Object clone
Example foo := method(x, 42+x)

name := "foo"
Example clone perform(name,5) println  // prints "47"


   sum =: +/
   prod =: */
   count =: #

   nameToDispatch =: 'sum'    NB. pick a name already defined

   ". nameToDispatch,' 1 2 3'
6
   nameToDispatch~ 1 2 3
6
   nameToDispatch (128!:2) 1 2 3
6

   nameToDispatch =: 'count'  NB. pick another name

   ". nameToDispatch,' 1 2 3'
3
   nameToDispatch~ 1 2 3
3
   nameToDispatch (128!:2) 1 2 3
3


import java.lang.reflect.Method;

class Example {
  public int foo(int x) {
    return 42 + x;
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    Object example = new Example();
    String name = "foo";
    Class<?> clazz = example.getClass();
    Method meth = clazz.getMethod(name, int.class);
    Object result = meth.invoke(example, 5); // result is int wrapped in an object (Integer)
    System.out.println(result);        // prints "47"
  }
}


example = new Object;
example.foo = function(x) {
    return 42 + x;
};

name = "foo";
example[name](5)      # => 47


const functions = Dict{String,Function}(
    "foo" => x -> 42 + x,
    "bar" => x -> 42 * x)

@show functions["foo"](3)
@show functions["bar"](3)


// Kotlin JS version 1.1.4-3

class C {
    fun foo() {
        println("foo called")
    }
}

fun main(args: Array<String>) {
    val c = C()
    val f = "c.foo"
    js(f)()  // invokes c.foo dynamically
}


define mytype => type {
	public foo() => {
		return 'foo was called'
	}
	public bar() => {
		return 'this time is was bar'
	}
}
local(obj = mytype, methodname = tag('foo'), methodname2 = tag('bar'))
#obj->\#methodname->invoke
#obj->\#methodname2->invoke


obj = script("MyClass").new()
-- ...
method = #foo
arg1 = 23
res = call(method, obj, arg1)


:- object(foo).

	:- public(bar/1).
	bar(42).

:- end_object.


local example = { }
function example:foo (x) return 42 + x end

local name = "foo"
example[name](example, 5) --> 47


ToExpression[Input["function? E.g. Sin",]][Input["value? E.g. 0.4123"]]


  funName = 'foo';   % generate function name
  feval (funNAME, ...)  % evaluation function with optional parameters

  funName = 'a=atan(pi)';   % generate function name
  eval (funName, 'printf(''Error\n'')')


#import <Foundation/Foundation.h>

@interface Example : NSObject
- (NSNumber *)foo;
@end

@implementation Example
- (NSNumber *)foo {
  return @42;
}
@end

int main (int argc, const char *argv[]) {
  @autoreleasepool {

    id example = [[Example alloc] init];
    SEL selector = @selector(foo); // or = NSSelectorFromString(@"foo");
    NSLog(@"%@", [example performSelector:selector]);

  }
  return 0;
}


package Example;
sub new {
    bless {}
}
sub foo {
    my ($self, $x) = @_;
    return 42 + $x;
}

package main;
my $name = "foo";
print Example->new->$name(5), "\n"; # prints "47"


with javascript_semantics
procedure Hello()
    ?"Hello"
end procedure

string erm = "Hemmm"
for i=3 to 5 do
    erm[i]+=-1+(i=5)*3
end for

call_proc(routine_id(erm),{})


<?php
class Example {
  function foo($x) {
    return 42 + $x;
  }
}

$example = new Example();

$name = 'foo';
echo $example->$name(5), "\n";        // prints "47"

// alternately:
echo call_user_func(array($example, $name), 5), "\n";
?>


go =>
  println("Function: Use apply/n"),
  Fun = "fib",
  A = 10,
  % Convert F to an atom
  println(apply(to_atom(Fun),A)),
  nl,

  println("Predicate: use call/n"),
  Pred = "pyth",
  call(Pred.to_atom,3,4,Z),
  println(z=Z),

  % Pred2 is an atom so it can be used directly with call/n.
  Pred2 = pyth,
  call(Pred.to_atom,13,14,Z2),
  println(z2=Z2),

  nl.

% A function
fib(1) = 1.
fib(2) = 1.
fib(N) = fib(N-1) + fib(N-2).

% A predicate
pyth(X,Y,Z) =>
  Z = X**2 + Y**2.


string unknown = "format_nice";
object now = Calendar.now();
now[unknown]();


$method = ([Math] | Get-Member -MemberType Method -Static | Where-Object {$_.Definition.Split(',').Count -eq 1} | Get-Random).Name
$number = (1..9 | Get-Random) / 10
$result = [Math]::$method($number)
$output = [PSCustomObject]@{
    Method = $method
    Number = $number
    Result = $result
}

$output | Format-List


class Example(object):
     def foo(self, x):
             return 42 + x

name = "foo"
getattr(Example(), name)(5)      # => 47


(define foo -> 5)

(define execute-function
  Name -> (eval [(INTERN Name)]))

(execute-function "foo")


#lang racket
(define greeter
  (new (class object% (super-new)
         (define/public (hello name)
           (displayln (~a "Hello " name "."))))))

; normal method call
(send greeter hello "World")

; sending an unknown method
(define unknown 'hello)
(dynamic-send greeter unknown "World")


my $object = 42 but role { method add-me($x) { self + $x } }
my $name = 'add-me';
say $object."$name"(5);  # 47


class Example
  def foo
    42
  end
  def bar(arg1, arg2, &block)
    block.call arg1, arg2
  end
end

symbol = :foo
Example.new.send symbol                         # => 42
Example.new.send( :bar, 1, 2 ) { |x,y| x+y }    # => 3
args = [1, 2]
Example.new.send( "bar", *args ) { |x,y| x+y }  # => 3


class Example {
  def foo(x: Int): Int = 42 + x
}

object Main extends App {
  val example = new Example

  val meth = example.getClass.getMethod("foo", classOf[Int])

  assert(meth.invoke(example, 5.asInstanceOf[AnyRef]) == 47.asInstanceOf[AnyRef], "Not confirm expectation.")
  println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
}


class Example {
    method foo(x) {
        42 + x
    }
}

var name = 'foo'
var obj = Example()

say obj.(name)(5)          # prints: 47
say obj.method(name)(5)    # =//=


Object subclass: #Example.

Example extend [
  foo: x [
    ^ 42 + x ] ].

symbol := 'foo:' asSymbol. " same as symbol := #foo: "

Example new perform: symbol with: 5. " returns 47 "


import Foundation

class MyUglyClass: NSObject {
  @objc
  func myUglyFunction() {
    print("called myUglyFunction")
  }
}

let someObject: NSObject = MyUglyClass()

someObject.perform(NSSelectorFromString("myUglyFunction"))


package require Tcl 8.6
oo::class create Example {
    method foo {} {return 42}
    method 1 {s} {puts "fee$s"}
    method 2 {s} {puts "fie$s"}
    method 3 {s} {puts "foe$s"}
    method 4 {s} {puts "fum$s"}
}
set eg [Example new]
set mthd [format "%c%c%c" 102 111 111];    # A "foo" by any other means would smell as sweet
puts [$eg $mthd]
for {set i 1} {$i <= 4} {incr i} {
    $eg $i ...
}


import "meta" for Meta

class Test {
    construct new() {}

    foo() { System.print("Foo called.") }

    bar() { System.print("Bar called.") }
}

var test = Test.new()
for (method in ["foo", "bar"]) {
    Meta.eval("test.%(method)()")
}


name:="len"; "this is a test".resolve(name)() //-->14


V s1 = Set([1, 2, 3, 4])
V s2 = Set([3, 4, 5, 6])
print(s1.union(s2))
print(s1.intersection(s2))
print(s1.difference(s2))
print(s1 < s1)
print(Set([3, 1]) < s1)
print(s1 <= s1)
print(Set([3, 1]) <= s1)
print(Set([3, 2, 4, 1]) == s1)
print(s1 == s2)
print(2 C s1)
print(10 !C s1)
print(Set([1, 2, 3, 4, 5]) > s1)
print(Set([1, 2, 3, 4]) > s1)
print(Set([1, 2, 3, 4]) >= s1)
print(s1.symmetric_difference(s2))
print(s1.len)
s1.add(99)
print(s1)
s1.discard(99)
print(s1)


with ada.containers.ordered_sets, ada.text_io;
use ada.text_io;

procedure set_demo is
	package cs is new ada.containers.ordered_sets (character); use cs;

	function "+" (s : string) return set is
	(if s = "" then empty_set else Union(+ s(s'first..s'last - 1), To_Set (s(s'last))));

	function "-" (s : Set) return string is
	(if s = empty_set then "" else - (s - To_Set (s.last_element)) & s.last_element);
	s1, s2 : set;
begin
	loop
		put ("s1= ");
		s1 := + get_line;
		exit when s1 = +"Quit!";
		put ("s2= ");
		s2 := + get_line;
		Put_Line("Sets [" & (-s1) & "], [" & (-s2) & "] of size"
                & S1.Length'img & " and" & s2.Length'img & ".");
  		Put_Line("Intersection:   [" & (-(Intersection(S1, S2))) & "],");
  		Put_Line("Union:          [" & (-(Union(s1, s2)))        & "],");
  		Put_Line("Difference:     [" & (-(Difference(s1, s2)))   & "],");
  		Put_Line("Symmetric Diff: [" & (-(s1 xor s2)) & "],");
  		Put_Line("Subset: "  & Boolean'Image(s1.Is_Subset(s2))
              & ", Equal: " & Boolean'Image(s1 = s2) & ".");
	end loop;
end set_demo;


record
union(record a, record b)
{
    record c;
    r_copy(c, a);
    r_wcall(b, r_add, 1, 2, c);
    return c;
}

record
intersection(record a, record b)
{
    record c;
    text s;
    for (s in a) {
        if (r_key(b, s)) {
            c[s] = 0;
        }
    }
    return c;
}

record
difference(record a, record b)
{
    record c;
    r_copy(c, a);
    r_vcall(b, r_resign, 1, c);
    return c;
}

integer
subset(record a, record b)
{
    integer e;
    text s;
    e = 1;
    for (s in a) {
        if (!r_key(b, s)) {
            e = 0;
            break;
        }
    }
    return e;
}

integer
equal(record a, record b)
{
    return subset(a, b) && subset(b, a);
}

integer
main(void)
{
    record a, b;
    text s;

    r_fit(a, "apple", 0, "cherry", 0, "grape", 0);
    r_fit(b, "banana", 0, "cherry", 0, "date", 0);

    s = "banana";

    o_(" ", s, " is ", r_key(a, s) ? "" : "not ", "an element of A\n");
    o_(" ", s, " is ", r_key(b, s) ? "" : "not ", "an element of B\n");

    r_vcall(union(a, b), o_, 1, " ");
    o_newline();

    r_vcall(intersection(a, b), o_, 1, " ");
    o_newline();

    r_vcall(difference(a, b), o_, 1, " ");
    o_newline();

    o_(" ", subset(a, b) ? "yes" : "no", "\n");

    o_(" ", equal(a, b) ? "yes" : "no", "\n");

    return 0;
}


# sets using associative arrays                                              #
# include the associative array code for string keys and values              #
PR read "aArray.a68" PR

# adds the elements of s to the set a,                                       #
#      the elements will have empty strings for values                       #
OP // = ( REF AARRAY a, []STRING s )REF AARRAY:
BEGIN
    FOR s pos FROM LWB s TO UPB s DO
        a // s[ s pos ] := ""
    OD;
    a
END # // # ;
# returns a set containing the elements of a that aren't in b                #
OP - = ( REF AARRAY a, REF AARRAY b )REF AARRAY:
BEGIN
    REF AARRAY result := INIT HEAP AARRAY;
    REF AAELEMENT e := FIRST a;
    WHILE e ISNT nil element DO
        IF NOT ( b CONTAINSKEY key OF e ) THEN
            result // key OF e := value OF e
        FI;
        e := NEXT a
    OD;
    result
END # - # ;
# returns a set containing the elements of a and those of b, i.e. a UNION b  #
PRIO U = 6;
OP   U = ( REF AARRAY a, REF AARRAY b )REF AARRAY:
BEGIN
    REF AARRAY result := INIT HEAP AARRAY;
    REF AAELEMENT e := FIRST a;
    WHILE e ISNT nil element DO
        result // key OF e := value OF e;
        e := NEXT a
    OD;
    e := FIRST b;
    WHILE e ISNT nil element DO
        result // key OF e := value OF e;
        e := NEXT b
    OD;
    result
END # U # ;
# returns a set containing the elements of a INTERSECTION b                  #
PRIO N = 6;
OP   N = ( REF AARRAY a, REF AARRAY b )REF AARRAY:
BEGIN
    REF AARRAY result := INIT HEAP AARRAY;
    REF AAELEMENT e := FIRST a;
    WHILE e ISNT nil element DO
        IF b CONTAINSKEY key OF e THEN
            result // key OF e := value OF e
        FI;
        e := NEXT a
    OD;
    result
END # N # ;
# returns TRUE if all the elements of a are in b, FALSE otherwise            #
OP <= = ( REF AARRAY a, REF AARRAY b )BOOL:
BEGIN
    BOOL result := TRUE;
    REF AAELEMENT e := FIRST a;
    WHILE result AND ( e ISNT nil element ) DO
        result := b CONTAINSKEY key OF e;
        e := NEXT a
    OD;
    result
END # <= # ;
# returns TRUE if all the elements of a are in b                             #
#             and all the elements of b are in a, FALSE otherwise            #
OP = = ( REF AARRAY a, REF AARRAY b )BOOL: a <= b AND b <= a;
# returns NOT ( a = b )                                                      #
OP /= = ( REF AARRAY a, REF AARRAY b )BOOL: NOT ( a = b );
# returns TRUE if all the elements of a are in b                             #
#         but not all the elements of b are in a, FALSE otherwise            #
OP < = ( REF AARRAY a, REF AARRAY b )BOOL: a <= b AND b /= a;

# prints the elements of a in no-particlar order                             #
PROC print set = ( REF AARRAY a )VOID:
BEGIN
    print( ( "[" ) );
    REF AAELEMENT e := FIRST a;
    WHILE e ISNT nil element DO
        print( ( " ", key OF e ) );
        e := NEXT a
    OD;
    print( ( " ]", newline ) )
END # print set # ;

# construct associative arrays for the task                                  #
REF AARRAY gas giants       := INIT LOC AARRAY;
REF AARRAY ice giants       := INIT LOC AARRAY;
REF AARRAY rocky planets    := INIT LOC AARRAY;
REF AARRAY inner planets    := INIT LOC AARRAY;
REF AARRAY moonless planets := INIT LOC AARRAY;
gas giants       // []STRING( "Jupiter", "Saturn"  );
ice giants       // []STRING( "Uranus",  "Neptune" );
rocky planets    // []STRING( "Mercury", "Venus", "Earth", "Mars" );
inner planets    // []STRING( "Mercury", "Venus", "Earth", "Mars" );
moonless planets // []STRING( "Mercury", "Venus"   );

print( ( "rocky planets   : " ) );print set( rocky planets    );
print( ( "inner planets   : " ) );print set( inner planets    );
print( ( "gas giants      : " ) );print set( gas giants       );
print( ( "ice giants      : " ) );print set( ice giants       );
print( ( "moonless planets: " ) );print set( moonless planets );
print( ( newline ) );

print( ( """Saturn"" is "
       , IF gas giants CONTAINSKEY "Saturn" THEN "" ELSE " not" FI
       , "in gas giants", newline
       )
     );
print( ( """Venus"" is "
       , IF gas giants CONTAINSKEY "Venus" THEN "" ELSE "not " FI
       , "in gas giants", newline
       )
     );
print( ( "gas giants UNION ice giants                : " ) );
print set( gas giants U ice giants );
print( ( "moonless planets INTERSECTION rocky planets: " ) );
print set( moonless planets N rocky planets );
print( ( "rocky planets \ moonless planets           : " ) );
print set( rocky planets - moonless planets );
print( ( "moonless planets <= rocky planets          : "
       , IF moonless planets <= rocky planets THEN "yes" ELSE "no" FI
       , newline
       )
     );
print( ( "moonless planets = rocky planets           : "
       , IF moonless planets = rocky planets THEN "yes" ELSE "no" FI
       , newline
       )
     );
print( ( "inner planets = rocky planets              : "
       , IF inner planets = rocky planets THEN "yes" ELSE "no" FI
       , newline
       )
     );
print( ( "moonless planets < rocky planets           : "
       , IF moonless planets < rocky planets THEN "yes" ELSE "no" FI
       , newline
       )
     );

# REF AARRAYs are mutable                                                    #

REF AARRAY all planets := inner planets U gas giants U ice giants;
print( ( "all planets                   : " ) );
print set( all planets );
print( ( "... after restoration of Pluto: " ) );
all planets // "Pluto";
print set( all planets )


public class MySetController{
    public Set<String> strSet {get; private set; }
    public Set<Id> idSet {get; private set; }

    public MySetController(){
        //Initialize to an already known collection.  Results in a set of abc,def.
        this.strSet = new Set<String>{'abc','abc','def'};

        //Initialize to empty set and add in entries.
        this.strSet = new Set<String>();
        this.strSet.add('abc');
        this.strSet.add('def');
        this.strSet.add('abc');
        //Results in {'abc','def'}

        //You can also get a set from a map in Apex. In this case, the account ids are fetched from a SOQL query.
        Map<Id,Account> accountMap = new Map<Id,Account>([Select Id,Name From Account Limit 10]);
        Set<Id> accountIds = accountMap.keySet();

        //If you have a set, you can also use it with the bind variable syntax in SOQL:
        List<Account> accounts = [Select Name From Account Where Id in :accountIds];

        //Like other collections in Apex, you can use a for loop to iterate over sets:
        for(Id accountId : accountIds){
            Account a = accountMap.get(accountId);
            //Do account stuffs here.
        }
    }
}


use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
--use scripting additions

on doSetTask()
    -- 'set' at the beginnings of lines is an AppleScript command; nothing to do with sets.

    set output to {}
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to ", "

    set S to current application's class "NSSet"'s setWithArray:({1, 2, 3, 6, 7, 8, 9, 0})
    set end of output to "Set S:  " & (S's allObjects() as list)
    set end of output to "\"aardvark\" is a member of S:  " & ((S's containsObject:("aardvark")) as boolean)
    set end of output to "3 is a member of S:  " & ((S's containsObject:(3)) as boolean)

    set A to S's |copy|() -- or: set A to current application's class "NSSet"'s setWithArray:({1, 2, 3, 6, 7, 8, 9, 0})
    set end of output to linefeed & "Set A:  " & (A's allObjects() as list)
    set B to current application's class "NSSet"'s setWithArray:({2, 2, 2, 3, 4, 5, 6, 7, 7, 7, 8})
    set end of output to "Set B:  " & (B's allObjects() as list)

    set union to A's setByAddingObjectsFromSet:(B)
    -- Or:
    -- set union to A's mutableCopy()
    -- tell union to unionSet:(B)
    set end of output to "Union of A and B:  " & (union's allObjects() as list)

    set intersection to A's mutableCopy()
    tell intersection to intersectSet:(B)
    set end of output to "Intersection of A and B:  " & (intersection's allObjects() as list)

    set difference to A's mutableCopy()
    tell difference to minusSet:(B)
    set end of output to "Difference of A and B:  " & (difference's allObjects() as list)

    set end of output to "A is a subset of B:  " & ((A's isSubsetOfSet:(B)) as boolean)
    set end of output to "A is a subset of S:  " & ((A's isSubsetOfSet:(S)) as boolean)

    set end of output to "A is equal to B:  " & ((A's isEqualToSet:(B)) as boolean)
    set end of output to "A is equal to S:  " & ((A's isEqualToSet:(S)) as boolean)

    set AppleScript's text item delimiters to linefeed
    set output to output as text
    set AppleScript's text item delimiters to astid

    return output
end doSetTask

doSetTask()


a: [1 2 3 4]
b: [3 4 5 6]

print in? 3 a
print contains? b 3

print union a b
print intersection a b
print difference a b
print difference.symmetric a b

print a = b

print subset? [1 3] a
print subset?.proper [1 3] a
print subset? [1 3] [1 3]
print subset?.proper [1 3] [1 3]

print superset? a [1 3]
print superset?.proper a [1 3]
print superset? [1 3] [1 3]
print superset?.proper [1 3] [1 3]