/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.lang.reflect.Array;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
// (4 == 2 + 2) && true
No
<Double
> mais
= new Galho
<Double,Double
>(new Soma
(),
new FolhaNumerica
(2),
new FolhaNumerica
(2)); No
<Boolean
> igual
= new Galho
<Double,Boolean
>(new Igualdade
(),
new FolhaNumerica
(4), mais
); No
<Boolean
> raiz
= new Galho
<Boolean,Boolean
>(new Conjuncao
(), igual,
new FolhaBooleana
(true));
boolean resultado = raiz.avaliar(); // true
System.
out.
println(resultado
); }
}
interface No<T> {
T avaliar();
}
class FolhaNumerica implements No<Double> {
double valor;
public Double avaliar
() { return valor
; } FolhaNumerica(double valor) { this.valor = valor; }
}
class FolhaBooleana implements No<Boolean> {
boolean valor;
public Boolean avaliar
() { return valor
; } FolhaBooleana(boolean valor) { this.valor = valor; }
}
interface Operador<E,S> {
S aplicar(E[] operandos);
Class<E> obterClasseOperandos();
}
class Soma
implements Operador
<Double,Double
> { public String toString
() { return "+"; } double ret = 0;
ret += d;
return ret;
}
public Class
<Double
> obterClasseOperandos
() { return Double.
class; } }
class Conjuncao
implements Operador
<Boolean,Boolean
> { public String toString
() { return "&&"; } if ( !b )
return false;
return true;
}
public Class
<Boolean
> obterClasseOperandos
() { return Boolean.
class; } }
class Igualdade
implements Operador
<Double,Boolean
> { public String toString
() { return "=="; } double primeiro = operandos[0];
if ( d != primeiro )
return false;
return true;
}
public Class
<Double
> obterClasseOperandos
() { return Double.
class; } }
class Galho<E,S> implements No<S> {
Operador<E,S> op;
No<E>[] operandos;
public S avaliar() {
@SuppressWarnings("unchecked")
E
[] array
= (E
[])Array.
newInstance(op.
obterClasseOperandos(), operandos.
length); for ( int i = 0 ; i < array.length ; i++ )
array[i] = operandos[i].avaliar(); // Avalia cada sub-nó recursivamente
return op.aplicar(array); // Passa os resultados para o operador
}
Galho(Operador<E,S> op, No<E>... operandos) {
this.op = op;
this.operandos = operandos;
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmxhbmcucmVmbGVjdC5BcnJheTsKaW1wb3J0IGphdmEuaW8uKjsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CiAgICAgICAgLy8gKDQgPT0gMiArIDIpICYmIHRydWUKICAgICAgICBObzxEb3VibGU+IG1haXMgPSBuZXcgR2FsaG88RG91YmxlLERvdWJsZT4obmV3IFNvbWEoKSwgbmV3IEZvbGhhTnVtZXJpY2EoMiksIG5ldyBGb2xoYU51bWVyaWNhKDIpKTsKICAgICAgICBObzxCb29sZWFuPiBpZ3VhbCA9IG5ldyBHYWxobzxEb3VibGUsQm9vbGVhbj4obmV3IElndWFsZGFkZSgpLCBuZXcgRm9saGFOdW1lcmljYSg0KSwgbWFpcyk7CiAgICAgICAgTm88Qm9vbGVhbj4gcmFpeiA9IG5ldyBHYWxobzxCb29sZWFuLEJvb2xlYW4+KG5ldyBDb25qdW5jYW8oKSwgaWd1YWwsIG5ldyBGb2xoYUJvb2xlYW5hKHRydWUpKTsKCiAgICAgICAgYm9vbGVhbiByZXN1bHRhZG8gPSByYWl6LmF2YWxpYXIoKTsgLy8gdHJ1ZQogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbihyZXN1bHRhZG8pOwoJfQp9CgppbnRlcmZhY2UgTm88VD4gewogICAgVCBhdmFsaWFyKCk7Cn0KCmNsYXNzIEZvbGhhTnVtZXJpY2EgaW1wbGVtZW50cyBObzxEb3VibGU+IHsKICAgIGRvdWJsZSB2YWxvcjsKICAgIHB1YmxpYyBEb3VibGUgYXZhbGlhcigpIHsgcmV0dXJuIHZhbG9yOyB9CiAgICBGb2xoYU51bWVyaWNhKGRvdWJsZSB2YWxvcikgeyB0aGlzLnZhbG9yID0gdmFsb3I7IH0KfQoKY2xhc3MgRm9saGFCb29sZWFuYSBpbXBsZW1lbnRzIE5vPEJvb2xlYW4+IHsKICAgIGJvb2xlYW4gdmFsb3I7CiAgICBwdWJsaWMgQm9vbGVhbiBhdmFsaWFyKCkgeyByZXR1cm4gdmFsb3I7IH0KICAgIEZvbGhhQm9vbGVhbmEoYm9vbGVhbiB2YWxvcikgeyB0aGlzLnZhbG9yID0gdmFsb3I7IH0KfQoKaW50ZXJmYWNlIE9wZXJhZG9yPEUsUz4gewogICAgUyBhcGxpY2FyKEVbXSBvcGVyYW5kb3MpOwogICAgQ2xhc3M8RT4gb2J0ZXJDbGFzc2VPcGVyYW5kb3MoKTsKfQoKY2xhc3MgU29tYSBpbXBsZW1lbnRzIE9wZXJhZG9yPERvdWJsZSxEb3VibGU+IHsKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiAiKyI7IH0KICAgIHB1YmxpYyBEb3VibGUgYXBsaWNhcihEb3VibGVbXSBvcGVyYW5kb3MpIHsKICAgICAgICBkb3VibGUgcmV0ID0gMDsKICAgICAgICBmb3IgKCBEb3VibGUgZCA6IG9wZXJhbmRvcyApCiAgICAgICAgICAgIHJldCArPSBkOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CiAgICBwdWJsaWMgQ2xhc3M8RG91YmxlPiBvYnRlckNsYXNzZU9wZXJhbmRvcygpIHsgcmV0dXJuIERvdWJsZS5jbGFzczsgfQp9CgpjbGFzcyBDb25qdW5jYW8gaW1wbGVtZW50cyBPcGVyYWRvcjxCb29sZWFuLEJvb2xlYW4+IHsKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiAiJiYiOyB9CiAgICBwdWJsaWMgQm9vbGVhbiBhcGxpY2FyKEJvb2xlYW5bXSBvcGVyYW5kb3MpIHsKICAgICAgICBmb3IgKCBCb29sZWFuIGIgOiBvcGVyYW5kb3MgKQogICAgICAgICAgICBpZiAoICFiICkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHB1YmxpYyBDbGFzczxCb29sZWFuPiBvYnRlckNsYXNzZU9wZXJhbmRvcygpIHsgcmV0dXJuIEJvb2xlYW4uY2xhc3M7IH0KfQoKY2xhc3MgSWd1YWxkYWRlIGltcGxlbWVudHMgT3BlcmFkb3I8RG91YmxlLEJvb2xlYW4+IHsKICAgIHB1YmxpYyBTdHJpbmcgdG9TdHJpbmcoKSB7IHJldHVybiAiPT0iOyB9CiAgICBwdWJsaWMgQm9vbGVhbiBhcGxpY2FyKERvdWJsZVtdIG9wZXJhbmRvcykgewogICAgICAgIGRvdWJsZSBwcmltZWlybyA9IG9wZXJhbmRvc1swXTsKICAgICAgICBmb3IgKCBEb3VibGUgZCA6IG9wZXJhbmRvcyApCiAgICAgICAgICAgIGlmICggZCAhPSBwcmltZWlybyApCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICBwdWJsaWMgQ2xhc3M8RG91YmxlPiBvYnRlckNsYXNzZU9wZXJhbmRvcygpIHsgcmV0dXJuIERvdWJsZS5jbGFzczsgfQp9CgpjbGFzcyBHYWxobzxFLFM+IGltcGxlbWVudHMgTm88Uz4gewogICAgT3BlcmFkb3I8RSxTPiBvcDsKICAgIE5vPEU+W10gb3BlcmFuZG9zOwoKICAgIHB1YmxpYyBTIGF2YWxpYXIoKSB7CiAgICAgICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAgICAgRVtdIGFycmF5ID0gKEVbXSlBcnJheS5uZXdJbnN0YW5jZShvcC5vYnRlckNsYXNzZU9wZXJhbmRvcygpLCBvcGVyYW5kb3MubGVuZ3RoKTsKICAgICAgICBmb3IgKCBpbnQgaSA9IDAgOyBpIDwgYXJyYXkubGVuZ3RoIDsgaSsrICkKICAgICAgICAgICAgYXJyYXlbaV0gPSBvcGVyYW5kb3NbaV0uYXZhbGlhcigpOyAvLyBBdmFsaWEgY2FkYSBzdWItbsOzIHJlY3Vyc2l2YW1lbnRlCgogICAgICAgIHJldHVybiBvcC5hcGxpY2FyKGFycmF5KTsgLy8gUGFzc2Egb3MgcmVzdWx0YWRvcyBwYXJhIG8gb3BlcmFkb3IKICAgIH0KCiAgICBHYWxobyhPcGVyYWRvcjxFLFM+IG9wLCBObzxFPi4uLiBvcGVyYW5kb3MpIHsKICAgICAgICB0aGlzLm9wID0gb3A7CiAgICAgICAgdGhpcy5vcGVyYW5kb3MgPSBvcGVyYW5kb3M7CiAgICB9Cn0=