Iterator Pattern: Every k-th Element

Problem

Write your own iterable class EveryKth that walks over an array and gives only the 1st, (k+1)th, (2k+1)th ... elements (indexes 0, k, 2k, ...). The caller must use a normal for-each loop (Iterable and Iterator in Java, Symbol.iterator in JavaScript, __iter__ in Python) and print the elements it receives, separated by spaces.

Constraints

  • 1 <= k
  • 1 <= n <= 10^5

Examples

Input

7
1 2 3 4 5 6 7
3

Output

1 4 7

Solutions

Best approachTime O(n / k)Space O(n / k)

The Iterator pattern hides how a collection is walked. The caller only asks for the next element. Here the step logic lives in one class, so a different walk (reverse, filtered) can be added without changing the caller.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Every k-th element.
 * Input   : n, array, k.
 * Output  : Chosen elements.
 * Approach: Custom iterator.
 * Time    : O(n / k)
 * Space   : O(n / k)
 * Java    : 8 or newer.
 */
import java.util.Scanner;
import java.util.Arrays;
import java.util.stream.Collectors;

public class Main {
        // Step 1: Iterable has one method, iterator(). The for-each loop calls it for us.
        static class EveryKth implements Iterable<Integer> {
            private final int[] data;
            private final int step;

            EveryKth(int[] data, int step) {
                this.data = data;
                this.step = step;
            }

            @Override
            public java.util.Iterator<Integer> iterator() {
                // Step 2: The iterator remembers its own position. hasNext() and next() are all it needs.
                return new java.util.Iterator<Integer>() {
                    private int position = 0;

                    @Override
                    public boolean hasNext() {
                        return position < data.length;
                    }

                    @Override
                    public Integer next() {
                        int value = data[position];
                        position += step;
                        return value;
                    }
                };
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static int[] solve(int[] a, int k) {
        // Step 3: The caller uses a normal for-each loop and knows nothing about the step logic.
        java.util.List<Integer> picked = new java.util.ArrayList<>();
        for (int value : new EveryKth(a, k)) {
            picked.add(value);
        }
        int[] result = new int[picked.size()];
        for (int i = 0; i < result.length; i++) {
            result[i] = picked.get(i);
        }
        return result;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        int k = scanner.nextInt();
        System.out.println(Arrays.stream(solve(a, k)).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
    }
}
Hints (1)
  1. What does the for-each loop call behind the scenes?