package util;
import java.util.List;
public class ListenElement<T> {
private T data;
private ListenElement next;
public ListenElement() {
}
public ListenElement(T data) {
this.data = data;
}
public ListenElement(T data, ListenElement next) {
this.data = data;
this.next = next;
}
public static boolean is_a_list(Object object) {
if(object instanceof ListenElement){
ListenElement element = (ListenElement) object;
ListenElement next = element.next;
return next == null || ListenElement.is_a_list(next);
}
return false;
}
public ListenElement getNext() {
return this.next;
}
public T getData() {
return data;
}
public ListenElement reverse() {
if (next == null)
return this;
ListenElement secondElem = next;
next = null;
ListenElement reverseRest = secondElem.reverse();
secondElem.next = this;
return reverseRest;
}
public boolean include(Object element) {
ListenElement listElement = this;
if (this.data == element) {
return true;
}
while (listElement.next != null) {
listElement = listElement.next;
if (listElement.data == element) {
return true;
}
}
return false;
}
public ListenElement difflist(ListenElement liste) {
ListenElement listElement = this;
ListenElement prev = null;
ListenElement differenzListe = new ListenElement();
while (listElement != null) {
if (!liste.include(listElement.data)) {
differenzListe = new ListenElement<>(listElement.data, prev);
prev = differenzListe;
}
listElement = listElement.next;
}
return differenzListe.reverse();
}
public boolean praefix(ListenElement praefix) {
ListenElement listElement_1 = this;
ListenElement listElement_2 = praefix;
while (listElement_2.next != null && listElement_1.next != null) {
if (listElement_2.data == listElement_1.data) {
listElement_1 = listElement_1.next;
listElement_2 = listElement_2.next;
} else {
return false;
}
}
return listElement_1.next != null;
}
public boolean suffix(ListenElement suffix) {
ListenElement listElement_1 = this;
while (listElement_1.next != null) {
listElement_1 = listElement_1.next;
if (listElement_1.data == suffix.data) {
ListenElement liste1 = listElement_1;
ListenElement liste2 = suffix;
while ((liste1.next != null && liste2.next != null) && (liste1.data == liste2.data)) {
liste1 = liste1.next;
liste2 = liste2.next;
}
if (liste1.next == null && liste2.next == null) {
return true;
}
}
}
return false;
}
public boolean infix(ListenElement infix) {
ListenElement listElement_1 = this;
if (listElement_1.suffix(infix) || listElement_1.praefix(infix)) {
return false;
} else {
while (listElement_1.next != null) {
listElement_1 = listElement_1.next;
if (listElement_1.praefix(infix)) {
return true;
}
}
return false;
}
}
public int[] eo_count() {
int even = 0;
int odd = 0;
if (isListEven()) {
even += 1;
}
if (isListOdd()) {
odd += 1;
}
int[] listCount = count();
even += listCount[0];
odd += listCount[1];
return new int[]{even, odd};
}
public int[] count() {
int even = 0;
int odd = 0;
if (ListenElement.is_a_list(this.getData())) {
int[] evenOdd = ((ListenElement) this.getData()).eo_count();
even += evenOdd[0];
odd += evenOdd[1];
}
if (this.getNext() == null) return new int[]{even, odd};
int[] nextEvenOdd = this.getNext().count();
even += nextEvenOdd[0];
odd += nextEvenOdd[1];
return new int[]{even, odd};
}
private boolean isListEven() {
return length() % 2 == 0;
}
private boolean isListOdd() {
return length() % 2 == 1;
}
public int length() {
if (this.getNext() == null) return 1;
return 1 + this.getNext().length();
}
public ListenElement del_element(char position, ListenElement element) {
switch (position) {
case 'a':
return delAll(this, element);
case 'e':
return delFirst(this, element);
case 'l':
return delLast(this, element);
default:
return null;
}
}
private ListenElement delAll(ListenElement list, ListenElement element) {
ListenElement prev = null;
ListenElement result = new ListenElement();
while (list != null) {
if (list.data != element.data) {
result = new ListenElement<>(list.data, prev);
prev = result;
}
list = list.next;
}
return result.reverse();
}
private ListenElement delFirst(ListenElement list, ListenElement element) {
ListenElement prev = null;
ListenElement result = new ListenElement();
boolean finish_flag = false;
while (list != null) {
if (list.data != element.data || finish_flag) {
result = new ListenElement<>(list.data, prev);
prev = result;
}
else if (!finish_flag) {
finish_flag = true;
}
list = list.next;
}
return result.reverse();
}
private ListenElement delLast(ListenElement list, ListenElement element) {
ListenElement result;
result = delFirst(list.reverse(), element);
return result.reverse();
}
public ListenElement substitute(char position, ListenElement element, ListenElement element2) {
switch (position) {
case 'a':
return substituteAll(this, element, element2);
case 'e':
return substituteFirst(this, element, element2);
case 'l':
return substituteLast(this, element, element2);
default:
return null;
}
}
private ListenElement substituteAll(ListenElement list, ListenElement element, ListenElement element2) {
ListenElement prev = null;
ListenElement result = new ListenElement();
while (list != null) {
if (list.data != element.data) {
result = new ListenElement<>(list.data, prev);
}
else {
result = new ListenElement<>(element2.data, prev);
}
prev = result;
list = list.next;
}
return result.reverse();
}
private ListenElement substituteFirst(ListenElement list, ListenElement element, ListenElement element2) {
ListenElement prev = null;
ListenElement result = new ListenElement();
boolean finish_flag = false;
while (list != null) {
if (list.data != element.data || finish_flag) {
result = new ListenElement<>(list.data, prev);
}
else if (!finish_flag) {
result = new ListenElement<>(element2.data, prev);
finish_flag = true;
}
prev = result;
list = list.next;
}
return result.reverse();
}
private ListenElement substituteLast(ListenElement list, ListenElement element, ListenElement element2) {
ListenElement result;
result = substituteFirst(list.reverse(), element, element2);
return result.reverse();
}
public boolean deepEquals(ListenElement other) {
if (this.getNext() == null && other.getNext() == null) return this.equals(other);
if (other.getNext() == null || this.getNext() == null) return false;
return this.equals(other) && this.getNext().deepEquals(other.getNext());
}
public String toDeepString() {
if (this.getNext() == null) return toString() + ", " + "null";
return toString() + ", " + this.getNext().toDeepString();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ListenElement other = (ListenElement) obj;
return data.equals(other.data);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + data.hashCode();
return result;
}
@Override
public String toString() {
return "[data=" + data + "]";
}
}