More puzzlers

This commit is contained in:
Andrey Breslav
2011-11-13 19:05:09 +04:00
parent d494463352
commit 703963621e
32 changed files with 535 additions and 53 deletions
+1
View File
@@ -3,6 +3,7 @@
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/exPuzzlers.iml" filepath="$PROJECT_DIR$/exPuzzlers.iml" />
<module fileurl="file://$PROJECT_DIR$/../../stdlib/stdlib.iml" filepath="$PROJECT_DIR$/../../stdlib/stdlib.iml" />
</modules>
</component>
</project>
+1
View File
@@ -8,6 +8,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="stdlib" />
</component>
</module>
+20 -45
View File
@@ -1,61 +1,36 @@
namespace std
fun <T> 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 <T> 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 : Any> T?.npe() : T {
inline fun <T : Any> 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 : Any> T.getJavaClass() : Class<T> {
return ((this as Object).getClass()) as Class<T>
}
}
@@ -10,7 +10,7 @@ fun main(args : Array<String>) {
)
}
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
@@ -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<String>) {
// Note: \u000A is Unicode representation of linefeed (LF)
val c : Char = 0x000A .chr;
println(c);
Me().main()
}
@@ -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");
}
}
@@ -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<String>) {
MeToo().main()
}
@@ -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);
}
}
@@ -0,0 +1,33 @@
namespace no.pain.no.gain
import std.io.*
val rnd = java.util.Random();
fun main(args : Array<String>) {
// 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)
}
@@ -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!");
}
}
}
@@ -0,0 +1,43 @@
namespace big.delight.in.every.byte
import std.io.*
fun main(args : Array<String>) {
// 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<T> {
fun valueOf(i : Int) : T
fun next(current : T) : T
fun compareToInt(t : T, int : Int) : Int
}
class NumberRange<T : Comparable<T>>(val from : Int, val to : Int) : Range<Int>, Iterable<T>
where class object T : IntCompatible<T> {
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<T> = object : Iterator<T> {
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<Byte>(this.int, to.int)
@@ -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);
}
}
@@ -0,0 +1,14 @@
namespace `in`.the.loop
import std.io.*
val END = Integer.MAX_VALUE
val START = END - 100
fun main(args : Array<String>) {
var count = 0
// For-loop over integrals always terminates
for (i in START..END)
count++
println(count)
}
@@ -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;
}
}
@@ -0,0 +1,10 @@
namespace ghost.of.looper
import std.io.*
fun main(args : Array<String>) {
var i : Short = -1.sht
while (i != 1.sht)
// Lots of magic made explicit:
i = (i.int ushr 1).sht
}
@@ -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) {
}
}
}
@@ -0,0 +1,19 @@
namespace curse.of.loooper // BUG!!!
import std.io.*
class Curse<T : Comparable<T>>() {
fun curse(i : T, j : T) {
while (i <= j && j <= i && i != j) {
}
}
}
fun main(args : Array<String>) {
// BUG:
// val i : Integer = (128 : Int?) as Integer
// val j : Integer = (128 : Int?) as Integer
// while (i <= j && j <= i && i != j) {
// }
Curse<Int>.curse(128, 128)
}
@@ -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);
}
}
@@ -0,0 +1,11 @@
namespace down.`for`.the.count
import std.io.*
fun main(args : Array<String>) {
// Problematic code does not compile
// val START : Int = 2000000000
// for (f : Float in START..(START + 50)) {
//
// }
}
@@ -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;
}
}
}
@@ -0,0 +1,16 @@
namespace indecision
import std.io.*
fun main(args : Array<String>) {
println(decision())
}
fun decision() : Boolean {
try {
// Problematic code is illegal, as Java Puzzlers recommend:
// return true;
} finally {
return false;
}
}
@@ -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 {
}
@@ -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<String>) {
println("User ID: " + USER_ID)
}
@@ -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");
}
}
}
@@ -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<String>) {
try {
val b = Reluctant()
println("Surprise!")
}
catch (ex : Exception) {
println("I told you so")
}
}
@@ -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;
}
}
@@ -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<String>) {
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
@@ -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");
}
}
@@ -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<String>) {
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")
}