Last active
May 6, 2017 23:15
-
-
Save LuxXx/1c2c9f50ed8c7806fd9505a8e8cda957 to your computer and use it in GitHub Desktop.
What if there were no primitive data types in java?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author David | |
* | |
* When I took an introductory course in mathematics, the lecturer introduced the natural numbers | |
* using a set of axioms called the peano axioms. | |
* I wondered if it would be possible to create a Java class that represents the integers without | |
* using any primitive type such as int, double, byte, boolean, etc. | |
* The class should be able to perform the operations + and *. | |
* I also created the relation ==, <, >, <=, >= to define an order. | |
* | |
* How are the numbers represented? | |
* Zero is the empty set | |
* A successor of a number is the set that contains this number | |
* 0 := {} | |
* 1 := {0} = {{}} | |
* 2 := {1} = {{0}} = {{{}}} | |
* ... | |
* | |
*/ | |
public class PeanoInteger { | |
public static void main(String[] args) { | |
for (PeanoInteger i = PeanoInteger.ZERO; i.compareTo(PeanoInteger.TEN) == PeanoInteger.Compare.LESS; i = i.successor()) { | |
System.out.println(i); | |
} | |
} | |
public static final PeanoInteger ZERO = new PeanoInteger(null); | |
public static final PeanoInteger ONE = ZERO.successor(); | |
public static final PeanoInteger TWO = ONE.successor(); | |
public static final PeanoInteger THREE = TWO.successor(); | |
public static final PeanoInteger TEN = THREE.multiply(THREE).add(ONE); | |
private PeanoInteger number; | |
private PeanoInteger(PeanoInteger number) { | |
this.number = number; | |
} | |
public PeanoInteger successor() { | |
return new PeanoInteger(this); | |
} | |
public PeanoInteger add(PeanoInteger val) { | |
PeanoInteger that = this; | |
for (PeanoInteger i = ZERO; i.compareTo(val) == Compare.LESS; i = i.successor()) { | |
that = that.successor(); | |
} | |
return that; | |
} | |
public PeanoInteger multiply(PeanoInteger val) { | |
PeanoInteger result = ZERO; | |
for (PeanoInteger i = ZERO; i.compareTo(val) == Compare.LESS; i = i.successor()) { | |
result = result.add(this); | |
} | |
return result; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
return obj instanceof PeanoInteger ? equals((PeanoInteger) obj) : false; | |
} | |
private boolean equals(PeanoInteger number) { | |
if (number == null) return false; | |
if (number.number == null && this.number == null) return true; | |
if (this.number == null) return false; | |
return this.number.equals(number.number); | |
} | |
public static enum Compare { | |
LESS, EQUALS, GREATER; | |
} | |
public Compare compareTo(PeanoInteger val) { | |
PeanoInteger that = this; | |
while(!(that.number == null && val.number == null)) { | |
if (that.number == null) return Compare.LESS; | |
if (val.number == null) return Compare.GREATER; | |
that = that.number; | |
val = val.number; | |
} | |
return Compare.EQUALS; | |
} | |
public PeanoInteger copy() { | |
PeanoInteger clone = new PeanoInteger(null); | |
PeanoInteger that = number; | |
while(that != null) { | |
clone = new PeanoInteger(clone); | |
that = that.number; | |
} | |
return clone; | |
} | |
/* | |
* The following code is used to create a string representation of this number | |
* Any base and any digits are possible | |
*/ | |
public String asSet() { | |
return "{" + (number == null ? "" : number.asSet()) + "}"; | |
} | |
/** | |
* This enum defines the representation of the digits | |
* You may use any base and any digit can have any character as representation | |
* | |
*/ | |
private enum Symbol { | |
ZERO("0"), | |
ONE("1"), | |
TWO("2"), | |
THREE("3"), | |
FOUR("4"), | |
FIVE("5"), | |
SIX("6"), | |
SEVEN("7"), | |
EIGHT("8"), | |
NINE("9"), | |
// TEN("A"), | |
// ELEVEN("B"), | |
// TWELVE("C"), | |
// THIRTEEN("D"), | |
// FOURTEEN("E"), | |
// FIFTEEN("F"), | |
; | |
private String symbol; | |
private Symbol(String symbol) { | |
this.symbol = symbol; | |
} | |
public Symbol next() { | |
Symbol[] values = values(); | |
for (int i = 0; i < values.length - 1; i++) { | |
if (values[i].equals(this)) return values[i+1]; | |
} | |
return values[0]; | |
} | |
public static Symbol getBySymbol(String symbol) { | |
for (Symbol s : values()) { | |
if (s.symbol.equals(symbol)) | |
return s; | |
} | |
throw new Error("No number with this symbol exists"); | |
} | |
public boolean isLast() { | |
return equals(values()[values().length - 1]); | |
} | |
public static Symbol first() { | |
return values()[0]; | |
} | |
@Override | |
public String toString() { | |
return symbol; | |
} | |
} | |
/** | |
* This method returns the string represenation of the successor of any number as String in any base | |
* @param s the string representation of the number we want to increase | |
* @return the string representation of the successor of s | |
*/ | |
private static String plus(String s) { | |
if (s.length() == 0) return Symbol.first().next().toString(); | |
String lastCharacter = s.substring(s.length() - 1, s.length()); | |
Symbol lastSymbol = Symbol.getBySymbol(lastCharacter); | |
if (lastSymbol.isLast()) | |
return plus(s.substring(0, s.length() - 1)) + lastSymbol.next(); | |
return s.substring(0, s.length() - 1) + lastSymbol.next(); | |
} | |
@Override | |
public String toString() { | |
String representation = Symbol.first().toString(); | |
PeanoInteger that = number; | |
while (that != null) { | |
that = that.number; | |
representation = plus(representation); | |
} | |
return representation; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment