@Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (this.hashCode() != obj.hashCode()) return false;

    if (obj instanceof PrizeNode) {
      PrizeNode other = (PrizeNode) obj;
      if (this.getTardiness() != other.getTardiness()) return false;
      else if (this.getRecords().equals(other.getRecords())) return true;
    }

    return false;
  }
  public Collection<PrizeNode> getSuccessors() {
    Collection<PrizeNode> result = new ArrayList<>();
    if (this.getTardiness() == 0) {
      PrizeNode c = new PrizeNode();
      @SuppressWarnings("unchecked")
      LinkedList<Attendance> a = (LinkedList<Attendance>) this.records_.clone();
      if (a.size() >= 2) {
        a.poll();
      }
      a.offer(Attendance.Late);
      c.setRecords(a);
      c.setTardiness(1);
      result.add(c);
    }

    {
      PrizeNode c = new PrizeNode();
      @SuppressWarnings("unchecked")
      LinkedList<Attendance> a = (LinkedList<Attendance>) this.records_.clone();
      if (a.size() >= 2) {
        a.poll();
      }
      a.offer(Attendance.OnTime);
      c.setRecords(a);
      c.setTardiness(this.tardiness_);
      result.add(c);
    }

    boolean isAbsentOk = (this.records_.size() < 2);
    isAbsentOk = isAbsentOk || (this.records_.peekFirst() != Attendance.Absent);
    isAbsentOk = isAbsentOk || (this.records_.peekLast() != Attendance.Absent);
    if (isAbsentOk) {
      PrizeNode c = new PrizeNode();
      @SuppressWarnings("unchecked")
      LinkedList<Attendance> a = (LinkedList<Attendance>) this.records_.clone();
      if (a.size() >= 2) {
        a.poll();
      }
      a.offer(Attendance.Absent);
      c.setRecords(a);
      c.setTardiness(this.tardiness_);
      result.add(c);
    }

    return result;
  }