diff --git a/docs/exPuzzlers/.idea/modules.xml b/docs/exPuzzlers/.idea/modules.xml
index 1233f39cda9..f1b24b71fe3 100644
--- a/docs/exPuzzlers/.idea/modules.xml
+++ b/docs/exPuzzlers/.idea/modules.xml
@@ -3,6 +3,7 @@
+
diff --git a/docs/exPuzzlers/exPuzzlers.iml b/docs/exPuzzlers/exPuzzlers.iml
index e0dc2c45a79..2c1255b7f1e 100644
--- a/docs/exPuzzlers/exPuzzlers.iml
+++ b/docs/exPuzzlers/exPuzzlers.iml
@@ -8,6 +8,7 @@
+
diff --git a/docs/exPuzzlers/kotlin/std.kt b/docs/exPuzzlers/kotlin/std.kt
index 797a7540927..9ad7308aae7 100644
--- a/docs/exPuzzlers/kotlin/std.kt
+++ b/docs/exPuzzlers/kotlin/std.kt
@@ -1,61 +1,36 @@
namespace std
-fun array(vararg array : T) = array
-fun array(vararg array : Byte) = array
-fun array(vararg array : Char) = array
-fun array(vararg array : Short) = array
-fun array(vararg array : Int) = array
-fun array(vararg array : Long) = array
-fun array(vararg array : Double) = array
-fun array(vararg array : Float) = array
+inline fun array(vararg array : T) = array
+inline fun array(vararg array : Byte) = array
+inline fun array(vararg array : Char) = array
+inline fun array(vararg array : Short) = array
+inline fun array(vararg array : Int) = array
+inline fun array(vararg array : Long) = array
+inline fun array(vararg array : Double) = array
+inline fun array(vararg array : Float) = array
fun Any?.identityEquals(other : Any?) = this === other
-fun T?.npe() : T {
+inline fun T?.sure() : T {
if (this == null)
throw NullPointerException()
return this;
}
-namespace io {
- import java.io.*
-
- fun print(message : Any?) { System.out?.print(message) }
- fun print(message : Int) { System.out?.print(message) }
- fun print(message : Long) { System.out?.print(message) }
- fun print(message : Byte) { System.out?.print(message) }
- fun print(message : Short) { System.out?.print(message) }
- fun print(message : Char) { System.out?.print(message) }
- fun print(message : Boolean) { System.out?.print(message) }
- fun print(message : Float) { System.out?.print(message) }
- fun print(message : Double) { System.out?.print(message) }
- fun print(message : CharArray) { System.out?.print(message) }
-
- fun println(message : Any?) { System.out?.println(message) }
- fun println(message : Int) { System.out?.println(message) }
- fun println(message : Long) { System.out?.println(message) }
- fun println(message : Byte) { System.out?.println(message) }
- fun println(message : Short) { System.out?.println(message) }
- fun println(message : Char) { System.out?.println(message) }
- fun println(message : Boolean) { System.out?.println(message) }
- fun println(message : Float) { System.out?.println(message) }
- fun println(message : Double) { System.out?.println(message) }
- fun println(message : CharArray) { System.out?.println(message) }
-
- private var systemIn : InputStream? = null // Unfortunately, System.in may change
- private var stdin : BufferedReader? = null // This may introduce leaks of system.in objects...
-
- fun readLine() : String? {
- if (stdin == null || systemIn != System.`in`) {
- stdin = java.io.BufferedReader(java.io.InputStreamReader(System.`in`))
- systemIn = System.`in`
+namespace string {
+ fun String.replaceAllSubstrings(pattern : String, replacement : String) : String {
+ return (this as java.lang.String).replace(pattern as CharSequence, replacement as CharSequence).sure()
}
- return stdin?.readLine()
+
+ fun String.replaceAllWithRegex(pattern : String, replacement : String) : String {
+ return (this as java.lang.String).replaceAll(pattern, replacement).sure()
}
}
-namespace string {
- fun String.replaceAll(pattern : String, replacement : String) : String {
- return (this as java.lang.String).replace(pattern as CharSequence, replacement as CharSequence).npe()
+namespace jutils {
+
+ fun T.getJavaClass() : Class {
+ return ((this as Object).getClass()) as Class
}
+
}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_02_expressive/_02_Time_for_a_Change/BigDecimalSolution.kt b/docs/exPuzzlers/src/_02_expressive/_02_Time_for_a_Change/BigDecimalSolution.kt
index 008841a00cf..11c717e56c6 100644
--- a/docs/exPuzzlers/src/_02_expressive/_02_Time_for_a_Change/BigDecimalSolution.kt
+++ b/docs/exPuzzlers/src/_02_expressive/_02_Time_for_a_Change/BigDecimalSolution.kt
@@ -10,7 +10,7 @@ fun main(args : Array) {
)
}
-val String.bd = BigDecimal(this)
+val String.bd : BigDecimal get() = BigDecimal(this)
fun BigDecimal.minus(other : BigDecimal) = this.subtract(other)
fun BigDecimal.minus(other : String) = subtract(other.bd) // this can be omitted
diff --git a/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt b/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt
index e9012cc3994..9d9add2653e 100644
--- a/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt
+++ b/docs/exPuzzlers/src/_03_character/_20_Whats_My_Class/Me.kt
@@ -1,18 +1,18 @@
namespace whats.my.`class`
import std.io.*
-import std.*
import std.string.*
-import typeinfo.*
+import std.jutils.*
-class Me {
+class Me() {
fun main() {
- (this as Object).getClass()?.getCanonicalName()?.replaceAll(".", "/")
+ println(getJavaClass().getCanonicalName()?.replaceAllSubstrings(".", "/"))
+
+ // Regex is denoted explicitly
+ println(getJavaClass().getCanonicalName()?.replaceAllWithRegex(".", "/"))
}
}
fun main(args : Array) {
- // Note: \u000A is Unicode representation of linefeed (LF)
- val c : Char = 0x000A .chr;
- println(c);
+ Me().main()
}
diff --git a/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.java b/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.java
new file mode 100644
index 00000000000..6eb4ebe265b
--- /dev/null
+++ b/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.java
@@ -0,0 +1,13 @@
+package _03_character._21_Whats_My_Class_Take_2;
+
+/**
+ * Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 45). Pearson Education (USA). Kindle Edition.
+ */
+
+public class MeToo {
+ public static void main(String[] args) {
+ System.out.println(MeToo.class.getName().
+ replaceAll("\\.", /*File.separator*/"\\") + ".class");
+ }
+}
+
diff --git a/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.kt b/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.kt
new file mode 100644
index 00000000000..5b42573147e
--- /dev/null
+++ b/docs/exPuzzlers/src/_03_character/_21_Whats_My_Class_Take_2/MeToo.kt
@@ -0,0 +1,19 @@
+namespace whats.my.`class`.take2
+
+import std.io.*
+import std.string.*
+import std.jutils.*
+import java.io.File;
+
+class MeToo() {
+ fun main() {
+ println(getJavaClass().getCanonicalName()?.replaceAllSubstrings(".", /*File.separator.sure()*/"\\"))
+
+ // Regex is denoted explicitly
+ println(getJavaClass().getCanonicalName()?.replaceAllWithRegex(".", "\\"))
+ }
+}
+
+fun main(args : Array) {
+ MeToo().main()
+}
diff --git a/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.java b/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.java
new file mode 100644
index 00000000000..8cec49d3bdd
--- /dev/null
+++ b/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.java
@@ -0,0 +1,28 @@
+package _03_character._23_No_Pain_No_Gain;
+
+/**
+ * Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 49). Pearson Education (USA). Kindle Edition.
+ */
+
+import java.util.Random;
+
+public class Rhymes {
+ private static Random rnd = new Random();
+
+ public static void main(String[] args) {
+ StringBuffer word = null;
+ switch (rnd.nextInt(2)) {
+ case 1:
+ word = new StringBuffer('P');
+ case 2:
+ word = new StringBuffer('G');
+ default:
+ word = new StringBuffer('M');
+ }
+ word.append('a');
+ word.append('i');
+ word.append('n');
+ System.out.println(word);
+ }
+}
+
diff --git a/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.kt b/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.kt
new file mode 100644
index 00000000000..aaf19a1b16d
--- /dev/null
+++ b/docs/exPuzzlers/src/_03_character/_23_No_Pain_No_Gain/Rhymes.kt
@@ -0,0 +1,33 @@
+namespace no.pain.no.gain
+
+import std.io.*
+
+val rnd = java.util.Random();
+
+fun main(args : Array) {
+ // The erroneous code does not compile:
+// var word : StringBuffer? = null
+// when (rnd.nextInt(2)) {
+// 1 => word = StringBuffer('P')
+// 2 => word = StringBuffer('G')
+// else => word = StringBuffer('M')
+// }
+// word?.append('a')
+// word?.append('i')
+// word?.append('n')
+// println(word)
+
+// A natural implementation can't possibly have two problems out of three:
+// * fall-through cases
+// * StringBuffer(int) called with 'P'
+ val word =
+ when (rnd.nextInt(2)) {
+ 1 => StringBuffer().append('P')
+ 2 => StringBuffer().append('G')
+ else => StringBuffer().append('M')
+ }
+ word?.append('a')
+ word?.append('i')
+ word?.append('n')
+ println(word)
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.java b/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.java
new file mode 100644
index 00000000000..ee0d13a3695
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.java
@@ -0,0 +1,14 @@
+package _04_loopy._24_Big_Delight_in_Every_Byte;
+
+/**
+ * Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 53). Pearson Education (USA). Kindle Edition.
+ */
+public class BigDelight {
+ public static void main(String[] args) {
+ for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {
+ if (b == 0x90)
+ System.out.print("Joy!");
+ }
+ }
+}
+
diff --git a/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.kt b/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.kt
new file mode 100644
index 00000000000..2913e2677ea
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_24_Big_Delight_in_Every_Byte/BigDelight.kt
@@ -0,0 +1,43 @@
+namespace big.delight.in.every.byte
+
+import std.io.*
+
+fun main(args : Array) {
+// for (b : Byte in Byte.MIN_VALUE..Byte.MAX_VALUE) {
+// // Problematic code does not compile
+// if (b == 0x90 .byt)
+// println("joy")
+// }
+ for (b : Byte in Byte.MIN_VALUE to Byte.MAX_VALUE) {
+ // Problematic code does not compile
+ if (b == 0x90 .byt)
+ println("joy")
+ }
+}
+
+trait IntCompatible {
+ fun valueOf(i : Int) : T
+ fun next(current : T) : T
+ fun compareToInt(t : T, int : Int) : Int
+}
+
+class NumberRange>(val from : Int, val to : Int) : Range, Iterable
+ where class object T : IntCompatible {
+
+ override fun contains(item: Int) : Boolean = from <= item && item <= to
+ fun contains(item: T) : Boolean = T.compareToInt(item, from) >= 0 && T.compareToInt(item, to) <= 0
+
+ override fun iterator(): Iterator = object : Iterator {
+ private var current : T = T.valueOf(from)
+ override fun next() : T {
+ if (!hasNext) throw java.util.NoSuchElementException()
+ val result = current
+ current = T.next(current)
+ return result
+ }
+ override val hasNext : Boolean
+ get() = T.compareToInt(current, to) < 0
+ }
+}
+
+fun Byte.to(to : Byte) = NumberRange(this.int, to.int)
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.java b/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.java
new file mode 100644
index 00000000000..d73facdf338
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.java
@@ -0,0 +1,23 @@
+package _04_loopy._25_In_the_Loop;
+
+/**
+ * Bloch, Joshua; Gafter, Neal (2005-06-24). Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (p. 57). Pearson Education (USA). Kindle Edition.
+ */
+public class InTheLoop {
+ public static final int END = Integer.MAX_VALUE;
+ public static final int START = END - 100;
+
+ public static void main(String[] args) {
+// int count = 0;
+// for (int i = START; i <= END; i++)
+// count++;
+// System.out.println(count);
+ final int end = Integer.MAX_VALUE;
+ int start = end - 100;
+ int count = 0;
+ for (int i = start; i <= end; i++)
+ count++;
+ System.out.println("count = " + count);
+ }
+}
+
diff --git a/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.kt b/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.kt
new file mode 100644
index 00000000000..fffa305d4c9
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_25_In_the_Loop/InTheLoop.kt
@@ -0,0 +1,14 @@
+namespace `in`.the.loop
+
+import std.io.*
+
+val END = Integer.MAX_VALUE
+val START = END - 100
+
+fun main(args : Array) {
+ var count = 0
+ // For-loop over integrals always terminates
+ for (i in START..END)
+ count++
+ println(count)
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.java b/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.java
new file mode 100644
index 00000000000..18b40c315b3
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.java
@@ -0,0 +1,10 @@
+package _04_loopy._31_Ghost_of_Looper;
+
+public class GhostOfLooper {
+ public static void main(String[] args) {
+ short i = -1;
+
+ while (i != 0)
+ i >>>= 1;
+ }
+}
diff --git a/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.kt b/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.kt
new file mode 100644
index 00000000000..fa47e5888e0
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_31_Ghost_of_Looper/GhostOfLooper.kt
@@ -0,0 +1,10 @@
+namespace ghost.of.looper
+
+import std.io.*
+
+fun main(args : Array) {
+ var i : Short = -1.sht
+ while (i != 1.sht)
+ // Lots of magic made explicit:
+ i = (i.int ushr 1).sht
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.java b/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.java
new file mode 100644
index 00000000000..60761a9f775
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.java
@@ -0,0 +1,11 @@
+package _04_loopy._32_Curse_of_Looper;
+
+public class CurseOfLooper {
+ public static void main(String[] args) {
+ // Place your declarations for i and j here
+ Integer i = 128;
+ Integer j = 128;
+ while (i <= j && j <= i && i != j) {
+ }
+ }
+}
diff --git a/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.kt b/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.kt
new file mode 100644
index 00000000000..e768340987c
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/CurseOfLooper.kt
@@ -0,0 +1,19 @@
+namespace curse.of.loooper // BUG!!!
+
+import std.io.*
+
+class Curse>() {
+ fun curse(i : T, j : T) {
+ while (i <= j && j <= i && i != j) {
+ }
+ }
+}
+
+fun main(args : Array) {
+// BUG:
+// val i : Integer = (128 : Int?) as Integer
+// val j : Integer = (128 : Int?) as Integer
+// while (i <= j && j <= i && i != j) {
+// }
+ Curse.curse(128, 128)
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/bug b/docs/exPuzzlers/src/_04_loopy/_32_Curse_of_Looper/bug
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.java b/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.java
new file mode 100644
index 00000000000..fb3b30f8536
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.java
@@ -0,0 +1,11 @@
+package _04_loopy._34_Down_for_the_Count;
+
+public class Count {
+ public static void main(String[] args) {
+ final int START = 2000000000;
+ int count = 0;
+ for (float f = START; f < START + 50; f++)
+ count++;
+ System.out.println(count);
+ }
+}
diff --git a/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.kt b/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.kt
new file mode 100644
index 00000000000..425fbb15671
--- /dev/null
+++ b/docs/exPuzzlers/src/_04_loopy/_34_Down_for_the_Count/Count.kt
@@ -0,0 +1,11 @@
+namespace down.`for`.the.count
+
+import std.io.*
+
+fun main(args : Array) {
+// Problematic code does not compile
+// val START : Int = 2000000000
+// for (f : Float in START..(START + 50)) {
+//
+// }
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.java b/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.java
new file mode 100644
index 00000000000..6416be6146a
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.java
@@ -0,0 +1,15 @@
+package _05_exceptional._36_Indecision;
+
+public class Indecisive {
+ public static void main(String[] args) {
+ System.out.println(decision());
+ }
+
+ static boolean decision() {
+ try {
+ return true;
+ } finally {
+ return false;
+ }
+ }
+}
diff --git a/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.kt b/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.kt
new file mode 100644
index 00000000000..26bb03cf30c
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_36_Indecision/Indecisive.kt
@@ -0,0 +1,16 @@
+namespace indecision
+
+import std.io.*
+
+fun main(args : Array) {
+ println(decision())
+}
+
+fun decision() : Boolean {
+ try {
+// Problematic code is illegal, as Java Puzzlers recommend:
+// return true;
+ } finally {
+ return false;
+ }
+}
diff --git a/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/BUG b/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/BUG
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.java b/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.java
new file mode 100644
index 00000000000..acc01cd88fe
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.java
@@ -0,0 +1,27 @@
+package _05_exceptional._38_Unwelcome_Guest;
+
+public class UnwelcomeGuest {
+ public static final long GUEST_USER_ID = -1;
+
+// private static final long USER_ID;
+// static {
+// try {
+// USER_ID = getUserIdFromEnvironment();
+// } catch (IdUnavailableException e) {
+// USER_ID = GUEST_USER_ID;
+// System.out.println("Logging in as guest");
+// }
+// }
+
+ private static long getUserIdFromEnvironment()
+ throws IdUnavailableException {
+ throw new IdUnavailableException(); // Simulate an error
+ }
+
+ public static void main(String[] args) {
+// System.out.println("User ID: " + USER_ID);
+ }
+}
+
+class IdUnavailableException extends Exception {
+}
diff --git a/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.kt b/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.kt
new file mode 100644
index 00000000000..68dc0d91fe9
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_38_Unwelcome_Guest/UnwelcomeGuest.kt
@@ -0,0 +1,22 @@
+namespace unwelcome.guest
+
+import std.io.*
+
+val GUEST_USER_ID = -1
+val USER_ID =
+ try {
+ getUserIdFromEnvironment()
+ }
+ catch (e : UnsupportedOperationException) {
+// catch (e : IdUnavailableException) { BUG
+ GUEST_USER_ID
+ }
+
+fun getUserIdFromEnvironment() = throw UnsupportedOperationException()
+//fun getUserIdFromEnvironment() = throw IdUnavailableException()
+
+//class IdUnavailableException() : Ex() {}
+
+fun main(args : Array) {
+ println("User ID: " + USER_ID)
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.java b/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.java
new file mode 100644
index 00000000000..5433d35b5a3
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.java
@@ -0,0 +1,18 @@
+package _05_exceptional._39_The_Reluctant_Constructor;
+
+public class Reluctant {
+ private Reluctant internalInstance = new Reluctant();
+
+ public Reluctant() throws Exception {
+ throw new Exception("I'm not coming out");
+ }
+
+ public static void main(String[] args) {
+ try {
+ Reluctant b = new Reluctant();
+ System.out.println("Surprise!");
+ } catch (Exception ex) {
+ System.out.println("I told you so");
+ }
+ }
+}
diff --git a/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.kt b/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.kt
new file mode 100644
index 00000000000..b98e14d6db4
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_39_The_Reluctant_Constructor/Reluctant.kt
@@ -0,0 +1,20 @@
+namespace the.reluctant.constructor
+
+import std.io.*
+
+public class Reluctant() {
+ val internalInstance = Reluctant() // Recursion is obvious
+ {
+ throw Exception("I'm not coming out")
+ }
+}
+
+fun main(args : Array) {
+ try {
+ val b = Reluctant()
+ println("Surprise!")
+ }
+ catch (ex : Exception) {
+ println("I told you so")
+ }
+}
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/BUG b/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/BUG
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.java b/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.java
new file mode 100644
index 00000000000..dc43d661ba9
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.java
@@ -0,0 +1,24 @@
+package _05_exceptional._42_Thrown_for_a_Loop;
+
+public class Loop {
+ public static void main(String[] args) {
+ int[][] tests = { { 6, 5, 4, 3, 2, 1 }, { 1, 2 },
+ { 1, 2, 3 }, { 1, 2, 3, 4 }, { 1 } };
+ int n = 0;
+
+ try {
+ int i = 0;
+ while (true) {
+ if (thirdElementIsThree(tests[i++]))
+ n++;
+ }
+ } catch(ArrayIndexOutOfBoundsException e) {
+ // No more tests to process
+ }
+ System.out.println(n);
+ }
+
+ private static boolean thirdElementIsThree(int[] a) {
+ return a.length >= 3 & a[2] == 3;
+ }
+}
diff --git a/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.kt b/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.kt
new file mode 100644
index 00000000000..2ee23e99c73
--- /dev/null
+++ b/docs/exPuzzlers/src/_05_exceptional/_42_Thrown_for_a_Loop/Loop.kt
@@ -0,0 +1,32 @@
+namespace thrown.`for`.a.looop // BUG
+
+import std.io.*
+import std.*
+
+fun iarr(vararg a : Int) = a // due to a BUG
+
+fun main(args : Array) {
+ val tests = array(
+ iarr(6, 5, 4, 3, 2, 1), iarr(1, 2),
+ iarr(1, 2, 3), iarr(1, 2, 3, 4), iarr(1)
+ )
+
+ var n = 0
+
+ try {
+ var i = 0
+ while (true) {
+ if (thirdElementIsThree(tests[i++]))
+ n++
+ }
+ }
+ catch (e : ArrayIndexOutOfBoundsException) {
+ // No more tests to process
+ }
+ println(n)
+}
+
+fun thirdElementIsThree(a : IntArray) =
+// Problematic code does not compile
+// a.size >= 3 & a[2] == 3
+ a.size >= 3 && a[2] == 3
\ No newline at end of file
diff --git a/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.java b/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.java
new file mode 100644
index 00000000000..8245e55d4b7
--- /dev/null
+++ b/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.java
@@ -0,0 +1,34 @@
+package _06_classy._47_Well_Dog_My_Cats;
+
+class Counter {
+ private static int count = 0;
+ public static final synchronized void increment() {
+ count++;
+ }
+ public static final synchronized int getCount() {
+ return count;
+ }
+}
+
+class Dog extends Counter {
+ public Dog() { }
+ public void woof() { increment(); }
+}
+
+class Cat extends Counter {
+ public Cat() { }
+ public void meow() { increment(); }
+}
+
+public class Ruckus {
+ public static void main(String[] args) {
+ Dog dogs[] = { new Dog(), new Dog() };
+ for (int i = 0; i < dogs.length; i++)
+ dogs[i].woof();
+ Cat cats[] = { new Cat(), new Cat(), new Cat() };
+ for (int i = 0; i < cats.length; i++)
+ cats[i].meow();
+ System.out.print(Dog.getCount() + " woofs and ");
+ System.out.println(Cat.getCount() + " meows");
+ }
+}
diff --git a/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.kt b/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.kt
new file mode 100644
index 00000000000..08c2ed5cb34
--- /dev/null
+++ b/docs/exPuzzlers/src/_06_classy/_47_Well_Dog_My_Cats/Ruckus.kt
@@ -0,0 +1,38 @@
+namespace well.dog.my.cats
+
+import std.io.*
+import std.*
+
+open class Counter {
+ class object {
+ private var count = 0
+ fun increment() { count++ }
+ fun getCount() = count
+ }
+}
+
+class Dog() : Counter {
+// Class objects are not inherited:
+// fun woof() { increment() }
+ fun woof() { Counter.increment() }
+}
+
+class Cat() : Counter {
+// Class objects are not inherited:
+// fun meow() { increment() }
+ fun meow() { Counter.increment() }
+}
+
+fun main(args : Array) {
+ val dogs = array(Dog(), Dog())
+ for (dog in dogs)
+ dog.woof()
+ val cats = array(Cat(), Cat())
+ for (cat in cats)
+ cat.meow()
+// Problematic code does not compile:
+// println("${Dog.getCount()} woofs")
+ println("${Counter.getCount()} woofs")
+// println("${Cat.getCount()} meows")
+ println("${Counter.getCount()} meows")
+}
\ No newline at end of file