aboutsummaryrefslogtreecommitdiff
path: root/src/ch/epfl/xblast/Lists.java
blob: 4ea45c2be9297b3783189bb19ec9bc758e6c15e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package ch.epfl.xblast;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Lists utility class providing common operations on lists.
 *
 * @author Pacien TRAN-GIRARD (261948)
 * @author Timothée FLOURE (257420)
 */
public final class Lists {

    /**
     * Returns a reversed copy of the given list, leaving the original one unmodified.
     *
     * @param l   the list to reverse
     * @param <T> the type of the list's elements
     * @return a reversed copy of the list.
     */
    public static <T> List<T> reversed(List<T> l) {
        List<T> r = new ArrayList<>(l);
        Collections.reverse(r);
        return r;
    }

    /**
     * Returns a symmetric version of the list, without repeating the last element of the input list.
     * For instance, mirrored([kay]) will return [kayak].
     *
     * @param l   the input list
     * @param <T> the type of the list's elements
     * @return the mirrored list
     * @throws IllegalArgumentException if the given list is empty
     */
    public static <T> List<T> mirrored(List<T> l) {
        if (l == null || l.size() == 0) throw new IllegalArgumentException();

        return Stream
                .concat(l.stream(), Lists.reversed(l).stream().skip(1))
                .collect(Collectors.toList());
    }

    /**
     * Returns a copy of the given list with element e inserted at index i.
     *
     * @param l   the list
     * @param i   the insertion index
     * @param e   the element to insert
     * @param <T> the type of the list's elements
     * @return a copy of the list with the element inserted
     */
    public static <T> List<T> inserted(List<T> l, int i, T e) {
        List<T> r = new LinkedList<>(l);
        r.add(i, e);
        return r;
    }

    /**
     * Returns all the permutations of the elements of the given list
     *
     * @param l   given list
     * @param <T> the type of the list's elements
     * @return a list of all the permutations of the list
     * @throws IllegalArgumentException if the given list is null
     */
    public static <T> List<List<T>> permutations(List<T> l) {
        if (l == null) throw new IllegalArgumentException();
        if (l.size() <= 1) return Collections.singletonList(l);
        if (l.size() == 2) return Arrays.asList(l, Lists.reversed(l));

        List<List<T>> p = new LinkedList<>();
        for (List<T> sp : Lists.permutations(l.subList(1, l.size())))
            for (int i = 0; i <= sp.size(); ++i)
                p.add(Lists.inserted(sp, i, l.get(0)));

        return p;
    }

}