#!/usr/bin/ruby

#
## Permutations
#

## Array.permutations{}

assert_eq(
    gather {
        [0,1,2].permutations { |*p|
            take(p)
        }
    },
    [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
)

assert_eq(
    gather {
        [].permutations { |*p|
            take(p)
        }
    },
    [[]]
)

assert_eq(
    gather {
        [0].permutations { |*p|
            take(p)
        }
    },
    [[0]]
)

## Array.permutations()

assert_eq(
    [0,1,2].permutations,
    [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
)

assert_eq(
    [].permutations,
    [[]]
)

assert_eq(
    [0].permutations,
    [[0]]
)

## Number.permutations{}

assert_eq(
    gather {
        3.permutations { |*p|
            take(p)
        }
    },
    [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]]
)

assert_eq(
    gather {
        0.permutations { |*p|
            take(p)
        }
    },
    [[]]
)
assert_eq(
    gather {
        (-1).permutations { |*p|
            take(p)
        }
    },
    [[]]
)

assert_eq(
    gather {
        1.permutations { |*p|
            take(p)
        }
    },
    [[0]]
)


## Array.combinations{}

assert_eq(
    gather {
        [1,2,3].combinations(0, { |*c|
            take(c)
        })
    },
    [[]]
)

assert_eq(
    gather {
        [].combinations(1, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        [1].combinations(1, { |*c|
            take(c)
        })
    },
    [[1]]
)

assert_eq(
    gather {
        [1].combinations(2, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        [0,1,2,3].combinations(3, { |*c|
            take(c)
        })
    },
    [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]
)

assert_eq(
    gather {
        [0,1,2,3].combinations(-2, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        [0,1,2,3].combinations(2, { |*c|
            take(c)
        })
    },
    [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
)

assert_eq(
    gather {
        [0,1,2,3].combinations(4, { |*c|
            take(c)
        })
    },
    [[0, 1, 2, 3]]
)

## Array.combinations()

assert_eq(
    [1,2,3].combinations(0),
    [[]]
)

assert_eq(
    [].combinations(1),
    []
)

assert_eq(
    [1].combinations(1),
    [[1]]
)

assert_eq(
    [1].combinations(2),
    []
)

assert_eq(
    [0,1,2,3].combinations(3),
    [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]
)

assert_eq(
    [0,1,2,3].combinations(-2),
    []
)

assert_eq(
    [0,1,2,3].combinations(2),
    [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
)

assert_eq(
    [0,1,2,3].combinations(4),
    [[0, 1, 2, 3]]
)

## Number.combinations{}

assert_eq(
    gather {
        3.combinations(0, { |*c|
            take(c)
        })
    },
    [[]]
)

assert_eq(
    gather {
        0.combinations(1, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        1.combinations(1, { |*c|
            take(c)
        })
    },
    [[0]]
)

assert_eq(
    gather {
        1.combinations(2, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        4.combinations(3, { |*c|
            take(c)
        })
    },
    [[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]]
)

assert_eq(
    gather {
        4.combinations(-2, { |*c|
            take(c)
        })
    },
    []
)

assert_eq(
    gather {
        4.combinations(2, { |*c|
            take(c)
        })
    },
    [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
)

assert_eq(
    gather {
        4.combinations(4, { |*c|
            take(c)
        })
    },
    [[0, 1, 2, 3]]
)

say "** Test passed!"