# Problem 3: Row-by-Row Iterator (10 points)
Given a two-dimensional structure (example below), a row-by-row iterator (aka. natural Pusheen walker) yields elements from the first row from left to right, then proceed to the second row, so on so forth. As an example, the 2d structure on the left results in the sequence on the right. Observe that the empty rows—which can appear anywhere, including at the start and/or the end—are skipped.

You will implement a public class:
```java
public class PusheenWalker<T> implements Iterable<T> { ... }
```
with the following specifications:
- The only constructor takes as input a List<List<T>> representing the said 2D structure. As an example,
this lets us write new PusheenWalker<>(twoD) and the result has type PusheenWalker<Integer>.
- The iterator given by this class—as described earlier—yields elements from left to right, then onto the following row, skipping each empty row, until all the elements have been returned. There may be many consecutive empty rows.
**Ground Rules:** Your code cannot store a collection of any kind, aside from a reference to the input structure. This means, for example, that you cannot make an output list ahead of time and simply return from that list. Moreover, do not use Java streams.
Grading:
Assignment summed up:
- we need to figure out the underlying datastructure that we want to iterate over.
- figure out how we get `hasNext()` and `next()`.
```java
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class PusheenWalker<T> implements Iterable<T> {
private final List<List<T>> twoD;
public PusheenWalker(List<List<T>> twoD) {
this.twoD = twoD;
}
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
private int rowIndex = 0; // To keep track of the current row
private int colIndex = 0; // To keep track of the current column within the row
@Override
public boolean hasNext() {
// Move forward to find a non-empty row if necessary
while (rowIndex < twoD.size() && (twoD.get(rowIndex) == null || twoD.get(rowIndex).isEmpty() || colIndex >= twoD.get(rowIndex).size())) {
rowIndex++;
colIndex = 0; // Reset column index at the start of a new row
}
return rowIndex < twoD.size(); // Check if there are more rows to iterate
}
@Override
public T next() {
if (!hasNext()) { // Uses hasNext to ensure there's a next element
throw new NoSuchElementException("No more elements to iterate");
}
T nextItem = twoD.get(rowIndex).get(colIndex++);
// Check if we need to move to the next row for subsequent calls
if (colIndex >= twoD.get(rowIndex).size()) {
rowIndex++;
colIndex = 0;
}
return nextItem;
}
};
}
}
```
in out `main` we can then use this for-each loop:
```java
List<List<Integer>> twoD = List.of(
List.of(3, 7),
List.of(),
List.of(1),
List.of(5, 0, 2)
);
PusheenWalker<Integer> walker = new PusheenWalker<>(twoD);
// our code allows this iteration to happen
for (Integer item : walker) {
System.out.println(item);
}
```
# Problem 3: Bounded Skipper Iterator (10 points)
For integer $k > 1$, the bounded skipper sequence of length n is the sequence of the first n numbers such that each number is neither divisible by k nor has k inside its decimal representation (e.g., $145223$ has $k = 52$ inside). For example, using $k = 3$, the bounded skipper sequence of length `n = 11` is
$1, 2, 4, 5, 7, 8, 10, 11, 14, 16, 17$
(Notice that $3, 6, 9, 12, 15$ are skipped because they are divisible by 3, and 13 is skipped because it contains 3.) You will write a public class
`public class BoundedSkipper implements Iterable<Integer>`
with the constructor
`public BoundedSkipper(int k, int n) {...}`
so that the following code will work
```java
for (int v: new BoundedSkipper(3, 11)) {
System.out.println(i);
// prints out the above sequence on separate lines
}
```
Since the class implements Iterable, it must have a public Iterator<Integer> iterator() method.
#### Ground Rules:
1. The only file you can modify here (aside from creating/writing tests) is BoundedSkipper.java.
2. You must not use IntStream, LongStream, or DoubleStream.
3. You must not construct the entire sequence anywhere. It is expected that your iterator generates the next number in the sequence on the fly. This means that you cannot, for example, make an ArrayList of length n and return it. In fact, you cannot store more a constant amount of data anywhere in your class.
```java
import java.util.Iterator;
import java.util.NoSuchElementException;
public class BoundedSkipper implements Iterable<Integer>{
// Instance Variable
private final int k;
private final int n;
// Constructor
public BoundedSkipper(int k, int n) {
this.k = k;
this.n = n;
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int cur = 0;
private int next = 1;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return cur < n;
}
@Override
public Integer next() {
// TODO Auto-generated method stub
if (!hasNext()) {
throw new NoSuchElementException();
}
while (!isValid(next)) {
next++;
}
cur++;
return next++;
}
private boolean isValid(int val) {
if (val % k ==0) { return false; }
return !String.valueOf(val).contains(String.valueOf(k));
}
};
}
public static void main(String[] args) {
for (int v: new BoundedSkipper(3, 11)) {
System.out.println(v); // prints out the above sequence on separate lines
}
}
}
```