Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, December 4, 2013

Mnemonics as a Key->Value associations in programming

Suppose that you need to memorize a list of values. There is a mnemonic technique to do that. Basically, you need to take a known list of keys, create associations and map the to the target values. You know the keys, you can iterate them. The funny stories are used to associate the keys to values. In result, you get a structure in memory that can can retrieve the values like the most fundamental programming pattern

for (Key k: keys)
  value = map.get(key)

Saturday, August 17, 2013

Exploiting exponential curve

http://www.scilogs.com/the_science_talent_project/my-simple-spaced-repetition-system/ says that we should repeat material with exponentially decreasing rate. I have estimated that this allows you to add a new item to learn every time unit to fill the gaps of free slots that appear over time. I've guessed that, provided the exponent of 2, this allows to introduce a new item every second clock. However, the simulation shows otherwise
 
public class ExponentialLearning {

    public static void main(String[] args) {
        int densityCounter = 0;
        int runtime = 200;//10000;
        final int shift = 2; // introduce a new item every n cycles
        int shiftNext = 0;
      
        class Item {
            final int what;
            int when; // when next ouput
            Item(int what, int time) {
                this.what = what;
                this.when = 1;
                //System.out.print("(" + this + " created) ");
            }
          
            public String toString() {
                return what + "@" + when;
            }
        }
      
        Collection counters = new ArrayList<>();
        LinkedList output = new LinkedList<>();
      
        for (int time = 0, exponent = 1, exponentNext; time != runtime ; time++) {

            System.out.print(time + ": ");

            // add new item every shift cycles
            if (time == shiftNext) {
                counters.add(new Item(counters.size(), time));
                shiftNext += shift;
            }

            exponentNext = exponent * 2;
            for (Item item : counters) {
                if (item.when + item.what*shift == time) {
                    //System.out.print(", output: " + item.what + " ");
                    output.addFirst(item.what);
                    item.when *= 2;
                }
            }
          
            exponent = exponentNext;
          
            if (!output.isEmpty()) {
                for (Integer integer : output) {
                    System.out.print(integer + ", ");
                    densityCounter++;
                }
                output.removeFirst();

            }

            System.out.println();
        }

        System.out.println("average density = " + ((float)densityCounter / (float)runtime));
    }
}


The curve below shows the output: you see exponentially accumulating amount of material to reherse (horizontally) at every next time step (vertically).



1: 1, 
2: 1, 
3: 2, 
4: 2, 1, 
5: 3, 1, 
6: 3, 2, 1, 
7: 4, 2, 1, 
8: 4, 3, 1, 2, 1, 
9: 5, 3, 1, 2, 1, 
10: 5, 4, 2, 3, 1, 2, 1, 
11: 6, 4, 2, 3, 1, 2, 1, 
12: 6, 5, 3, 4, 2, 3, 1, 2, 1, 
13: 7, 5, 3, 4, 2, 3, 1, 2, 1, 
14: 7, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
15: 8, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
16: 8, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
17: 9, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
18: 9, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
19: 10, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
20: 10, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
21: 11, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
22: 11, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
23: 12, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
24: 12, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
25: 13, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
26: 13, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
27: 14, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
28: 14, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
29: 15, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
30: 15, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
31: 16, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
32: 16, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
33: 17, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
34: 17, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
35: 18, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
36: 18, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
37: 19, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
38: 19, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
39: 20, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
40: 20, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
41: 21, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
42: 21, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
43: 22, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
44: 22, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
45: 23, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
46: 23, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
47: 24, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
48: 24, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
49: 25, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
50: 25, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
51: 26, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
52: 26, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
53: 27, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
54: 27, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
55: 28, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
56: 28, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
57: 29, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
58: 29, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
59: 30, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
60: 30, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
61: 31, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
62: 31, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
63: 32, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
64: 32, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
65: 33, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
66: 33, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
67: 34, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
68: 34, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
69: 35, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
70: 35, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
71: 36, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
72: 36, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
73: 37, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
74: 37, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
75: 38, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
76: 38, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
77: 39, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
78: 39, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
79: 40, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
80: 40, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
81: 41, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
82: 41, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
83: 42, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
84: 42, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
85: 43, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
86: 43, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
87: 44, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
88: 44, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
89: 45, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
90: 45, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
91: 46, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
92: 46, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
93: 47, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
94: 47, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
95: 48, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
96: 48, 47, 45, 41, 33, 17, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
97: 49, 47, 45, 41, 33, 17, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
98: 49, 48, 46, 42, 34, 18, 47, 45, 41, 33, 17, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 
99: 50, 48, 46, 42, 34, 18, 47, 45, 41, 33, 17, 46, 44, 40, 32, 16, 45, 43, 39, 31, 15, 44, 42, 38, 30, 14, 43, 41, 37, 29, 13, 42, 40, 36, 28, 12, 41, 39, 35, 27, 11, 40, 38, 34, 26, 10, 39, 37, 33, 25, 9, 38, 36, 32, 24, 8, 37, 35, 31, 23, 7, 36, 34, 30, 22, 6, 35, 33, 29, 21, 5, 34, 32, 28, 20, 4, 33, 31, 27, 19, 3, 32, 30, 26, 18, 2, 31, 29, 25, 17, 1, 30, 28, 24, 16, 29, 27, 23, 15, 28, 26, 22, 14, 27, 25, 21, 13, 26, 24, 20, 12, 25, 23, 19, 11, 24, 22, 18, 10, 23, 21, 17, 9, 22, 20, 16, 8, 21, 19, 15, 7, 20, 18, 14, 6, 19, 17, 13, 5, 18, 16, 12, 4, 17, 15, 11, 3, 16, 14, 10, 2, 15, 13, 9, 1, 14, 12, 8, 13, 11, 7, 12, 10, 6, 11, 9, 5, 10, 8, 4, 9, 7, 3, 8, 6, 2, 7, 5, 1, 6, 4, 5, 3, 4, 2, 3, 1, 2, 1, 


average density = 79 items/iteration

Wednesday, April 17, 2013

Java GC makes memory management a nightmare

I had a hand in ZamiaCAD. It is hyped for its scalability - there is a manager that breaks large objects and passiviates (aka persists) them in a custom database so that you can design arbitrary large circuits with moderate amount of RAM. However, the question appears immediately: why not to leave this task to OS? After all, main memory paging is one of the OS primary duties. Why did ZamiaCAD programmers needed to reinvent the wheel?

The standard answer is that app-tailored paging can be more optimal. But, I am not sure. What I am sure is that it is a big pain for programmer! Now, for every operation, he must decide all the time if the passiviation of the object is necessary and what objects are referred from the object at hand, which referenced may also need the persistence? Might be it is not that difficult for the little genious inventor of Zamia because he is a little genius but, for average person, it is a major inconcievable obstacle to contributing.

So, why the little genius decided to do this terrible thing, which kills his application? The problem is not that he wanted to optimize the paging. But, he had no other option since as soon as JVM heap exeeds the physical memory, thrashing slows down the program execution to a full stop ("the whole program falls into a thrashing hole", as they put here). So, initially relieved from the demand to release the memory, java programmers end up with an extremely complex custom passiviation mechanism, specific to every their application thereby. You cannot create universal POJO-graph partition.This makes java processing of large models a nightmare.

You cannot describe the large models directly in java. To passiviate objects, you need to replace the POJO java references with database identifiers. You can emulate such db-references, creating your own virtual machines, which is involved and makes programming more complex and error-prone because you have to give up the Java static code checker and sorta invent your own language. The emulation will additionally slow down your execution speed order of magnitude.

Thursday, January 17, 2013

Java (OOP) is sux from the very beginning

I knew for a while that composition must be used instead of inheritance. I just realized that there is no one example (stackoverflow was asked explicitly) when inheritance would be preferred. Never! The very inheritance, the cornerstone of OOP (Java is OOP), is considered a bad practice! Integer extends Number, FilterInputStream extends InputStream, which extends Closable. Java begins with Object whereby every other object inherits a dozen of fields (lock, hash, class) and 11 methods (wait, getHash, getClass) from it.

Notably however, design pattern experts who make us thinking that inheritance is evil and stone age structural composition must always be used instead, promote OOP and the idea that we must replace conditionals with polymorphism! (which is achievable only through inheritance in OOP languages). For no reason [1], [2], [3]!

Update The last bullet is that tight coupling between functions and data is bad.

Sunday, September 9, 2012

Super constructor must be a first statement in Java constructor


I know the answer: "we need rules to prevent shooting into your own foot". Ok, I make millions of programming mistakes every day. For real safety, we need only one simple rule: prohibit all statements and do not use Java at all. If we explain everything by "not shooting your foot", this is reasonable. But there is not much reason is such reason.
When I programmed in Delphi, I always wanted the compiler to check me if I read uninitialized variables. I have discovered myself that is is stupid to read uncertain variables because it leads to unpredictable result and is errorenous obviously. By just looking at the code I could see if there is an error. I wished if compiler could do this job. It is also a reliable signal of programming error if function does not return any value. But I never wanted the compiler to enforce me the super constructor first. Why?
You say that constructors just initialize fields. Super fields are derived; extra fields are introduced. From the goal point of view, it does not matter in which order you initialize the variables. I have studied parallel architectures and can say that all the fields can even be assigned in parallel... What? Do you want to use the unitialized fields? Stupid people always want to take away our freedoms and break the JLS rules the God gives to us! Please, policeman, take away that person!
Where do I say so? I'm just saying only about initializing/assigning, not using the fields. Java compiler already defends me from the mistake of accessing notinitialized. Some cases sneak but this example shows how this stupid rule does not save us from the read-accessing incompletely initialized in construction:
public class BadSuper {
    String field;
    public String toString() {
        return "field = " + field;
    }
    public BadSuper(String val) {
        field = val;

        // yea, superfirst does not protect from accessing
        // inconstructed subclass fields. Subclass constr
        // must be called before super()!
        System.err.println(this);
    }
}
public class BadPost extends BadSuper {

    Object o;
    public BadPost(Object o) {
        super("str");
        this. o = o;
    }

    public String toString() { 
        // superconstructor will boom here, because o is not initialized!
        return super.toString() + ", obj = " + o.toString();
    }

    public static void main(String[] args) {
        new BadSuper("test 1");
        new BadPost(new Object());
    }
}
It shows that actually, subfields have to be inilialized before the supreclass! Meantime, java requirement "defends" us from specializing the class by specializing what the super constructor argument is,
public class MyKryo extends Kryo {

    class MyClassResolver extends DefaultClassResolver {
        public Registration register(Registration registration) {
            System.out.println(MyKryo.this.getDepth());
            return super.register(registration);
        }

    }
    MyKryo() {
        // cannot instantiate MyClassResolver in super
        super(new MyClassResolver(), new MapReferenceResolver());
    }
}
Try to make it compilable. It is always pain. Especially, when you cannot assign the argument later.
Initialization order is not important for initialization in general. I could understand that you should not use super methods before initializing super. But, the requirement for super to be the first statement is different. It only saves you from the code that does useful things simply. I do not see how this adds safety. Actually, safety suffers because we need to use ugly workarounds. Doing post-initialization, outside the constructors also degrades safety (otherwise, why do we need constructors?) and defeats the java final safety reenforcer.
To conclude
  1. Reading not initialized is a bug.
  2. Initialization order is not important from the computer science point of view. Doing initalization or computations in different order is not a bug.
  3. Reenforcing read-access to not initialized is good but compilers fail to detect all such bugs
  4. Making super the first does not solve the problem as it
  5. "Prevents" shooting into right things but not into the foot
  6. It requires to invent workarounds,
    1. where, because of complexity of analysis, it is easier to shoot into the foot
    2. doing post-initialization outside the constructors degrades safety (otherwise, why do we need constructors?)
    3. and that degrade safety by defeating final access modifier
When there was java forum alive, java bigots attecked me for these thoughts. Particularly, they dislaked that fields can be initialized in parallel, saying that natural development ensures correctness. When I replied that you could use an advanced engineering to create a human right away, without "developing" any ape first, and it still be an ape, they stopped to listen me. Cos modern technology cannot afford it. Ok, Take something simpler. How do you produce a Renault? Should you construct an Automobile first? No, you start by producing a Renault right away and, once completed, you'll see that this is an automobile. So, the requirement to produce fields in "natural order" is unnatural. In case of alarmclock or armchair, which are still chair and clock, you may need first develop the base (clock and chair) and then add extra. So, I can have examples where superfields must be initialized first and, oppositely, when they need to be initialized later. The order does not exist in advance. So, the compiler cannot be aware of the proper order. Only programmer/constructor knows is. Compiler should not take more responsibility and enforce the wrong order onto programmer.
Saying that I should not initialize some fields because the others are not initialize is like "you cannot initialize the thing because it is not initialized". This is a kind of argument we have.
So, to conclude once more, the feature that "protects" me from doing things in simple and right way in order to enforce something that does not add noticeably to the bug elimination at that is a strongly negative thing and it pisses me off, altogether with the all the arguments to support it I've seen so far.
It is "a conceptual question about software development" Should there be the requirement to call super() first or not. I do not know. If you do or have an idea, you have place to answer. I think that I have provided enough arguments against this feature. Lets appreciate the ones who benefit form it. Let is just be something more than simple abstract "protection", that can defend every stupid thing. Why do we need it in the language that I am going to develop?

--------------------
I asked this question in http://programmers.stackexchange.com/questions/164250/super-constructor-must-be-a-first-statement-in-java-constructor and figured out that it is not tolerated in programmer community at all, not only among java programmers.

Wednesday, August 15, 2012

My ideas are being implemented in Java

in year 2007, I was banned from the Java forum because I was asking why Java lacks some stuff. Java forum is controlled by Java bigots who defended their language as it is by all means (by false and dirty manipulations). For instance, they told that java File has one getExtension method because extensions are MS-DOS FAT32 feature and must not be on the multiplatrorm Java. My proof links, showing that Linux makes use of them also were ignored. I was just stupid to not undrestand that this is a MS filesystem feature. I was so dumb that could see that Java itself uses .class extension in class loader.

I argued for functions as first-class citizens. The bigots told me that this will never happen. It is proud to see that all these features get implemented in Scala and Java 8.

Finally, everybody accepts that Enterprise Java is sux now. Only me, a green developer asked what the fuck it is on the Java forum those days.

Odersky even introduced worksheets to make all necessary work in the religiously forbidden context - in the static initializers - and speaks about macros, which are evil in the java world. It was clearly explained to me when I explained what they enable, what you cannot do with simple functions.

I also argued that resolving the interface conflicts (when you implement a method defined in several superinterfaces) should use the Delphi-like confilct-resolution mechanism, when you specify the interface name, like InterfaceA.method() if you also have InterfaceB.method. Currently Java allows only one implementation. which sucks because confilcts are quite probable, e.g. getName method is quite popular and designer of one interface must not take care of all possible conflicts with infinity of other interfaces. User must be able to get a different result when asks the same object its name through different interfaces.

And certainly, super must not be the first statement of constructor!

Wednesday, February 15, 2012

Why java Set does not have get() method?


I have mentioned the same simple question in StackOverflow that I asked many years ago in sun.java.form that was one of the reasons to ban be there. I have my considerations.
http://stackoverflow.com/a/9299534/1083704

I had the same question in java forum years ago. They told me that the Set interface is defined. It cannot be changed because it will break the current implementations of Set interface. Then, they started to claim bullshit, like you see here: "Set does not need the get method" and started to drill me that Map must always be used to get elements from a set.
If you use the set only for mathematical operations, like intersection or union, then may be contains() is sufficient. However, Set is defined in collections to store data. I explained for need get() in Set using the relational data model.
In what follows, an SQL table is like a class. The columns define attributes (known as fields in Java) and records represent instances of the class. So that an object is a vector of fields. Some of the fields are primary keys. They define uniqueness of the object. This is what you do for contains() in Java:
class Element {

        public int hashCode() {return sumOfKeyFields()}
        public boolean equals(Object e) {keyField1.equals(e) && keyField2.equals(e) && ..}
I'm not aware of DB internals. But, you specify key fields only once, when define a table. You just annotate key fields with @primary. You do not specify the keys second time, when add a record to the table. You do not separate keys from data, as you do in mapping. SQL tables are sets. They are not maps. Yet, they provide get() in addition to maintaining uniqueness and contains() check.
You see how they say that Set with get would be redundant? It is because their favorite map, which they impose to use in place of set, introduces the redundancy. The call put(obj.getKey(), obj) stores two keys: one for map key and duplicate as part of the object. This is the redundancy. The duplication involves more bloat in the code and wastes memory consumed at Runtime. I do not know about DB internals, but database normalization says that such duplication is bad idea. Redundancy means that it may happen that key in the map does not match the key of the referred object. The contradictions are a prominent mark of redundancy. Edgar F. Codd proposed DB normalization just to get rid of redundancies and their inferred inconsistencies.
So, we have 3 points, why using a map for implementing get in set is bad:
  1. redundancy in Runtime storage
  2. code bloat
  3. data storage normalization
I was banned from Sun forum for pointing this out. This world is dominated by bigots. They do not want to see concepts and how things can be improved. They see only actual world and cannot imagine that design of Collections may be different or is missing something. It is dangerous to remind rationale things to such people. They teach you their blindness and punish if you do not obey.

Duplicate of http://valjok.blogspot.com/2008/05/java-design-map-vs-setgetkey.html

Finally, I have discovered where normalization is specific on the topic: Normalization will never generate two tables with a one-to-one relationship between them. There is no theoretical reason to separate a single entity like this with some fields in a single record of one table and others in a single record of another table

Wednesday, January 14, 2009

Couplig the final circular references

Another initializatin problem, which precludes using "final" modifier for the fields is a circular reference: one object refers another, which refers the first object. For example, the two ends of a pipe are constructed sequentially and, thus, the counterpart, which was constructed first, cannot be marked "final". Yet, the references are final - the coupled parts constitute an indivisable solid object.

This is akin to the previous post because the following code produces "variable hBar cannot be initialized":
final JScrollBar hBar;
final JViewport viewPort = new JViewport() {
 {
  this.addChangeListener(new ChangeListener() {
   public void stateChanged(ChangeEvent e) {
    hBar.setValues(hBar.getValue(), getExtentSize().width,
      0, getViewSize().width);
   }
  });
 }
};
hBar = new JScrollBar(Adjustable.HORIZONTAL) {
 {
  getModel().addChangeListener(new ChangeListener() {

   public void stateChanged(ChangeEvent e) {
    frame.setTitle(getModel().getValue() + "");
   }

  });
 }
};

Thursday, January 8, 2009

Calling the overriden method

It seems that there is no way to call a sibling method.

Yesterday, I had just another conflict wich java forum dons. As usually, they insist that features not existent in the Java are "evil". They were proud remarking that they claim this without ever looking into my code. Once I asked to excuse me for ignoring their bigotry in the reply, they reported my post as expressing bad personal attitude and later removed the topic.

It is weired that even reflection returns the extended method when requested the method declared in the base calss!
class Base {

void method() {
System.out.println("method: call me!");
}

void anotherMethod() {
System.out.println("anotherMethod: I want to call the method above!");

Base.this.method();

try {
Method overriddenMethod = Base.class.getDeclaredMethod("method",
new Class[] {});
overriddenMethod.invoke(this, new Object[] {});
} catch (Exception e) {
e.printStackTrace();
}

}

}

class Extension extends Base {

void method() {
System.out.println("He-he-he. It's me, extended");
}

public static void main(String[] args) {
new Extension().anotherMethod();
}

}



It seems that the code is there but we cannot call it if the method is overriden. I have resolved the problem by declaring an additional method in the base. It contains the default implementation, which called both from the base method and anotherMethod. One mindfult person, however, presented the same idea, which means that it is the best we can do.

The bigots clamed that it is bad to invoke overriden code but refused to respond why then java allows super.method() to call it from the extended class. I have noted, however, that this defficiency is actually a strenght of Java taking two considerations
1) the feature is very rarely needed; and
2) can be very easily worked around.
If you remember, the Java spirit is to keep language simple. This means that rare features, wich can be easily implemented by existing java facilities must not be introduced into the language overcomplicating it. It is better to remove the complexity into the user program in this case. Optimization, efficiency, is a very good argument, which satisfies me. Unfortunately, these stupid idiots cannot understand it. They have no desire to see what is good and what is missing in Java. All they can is to put a stright jacket on the thinking people turinging us into obidient cattle.

Now, I recall that about 2 years ago they deleted my topic discussing why local classes are not visible in the routine before the thread reaches its declaration? The "dons" responded that the class does not exist before runtime creates it. They have removed my topic after I have mentioned that the classes are compiled in advance even before application is started and are loaded at JVM start up. Do they ever feel shame or act thoughtlessly? I have discovered that "in advance"visibility of local classes would make all the final variables visible througout the routine, even those not yet initialized ones.

Anonymous class initializes parent's final field

Java allows to initialize the final fields in the constructor. The problem is that it fails to do so if the initialization is hidden inside construction of a subobject, likewise it is in the example below.

class C {
 final Object o; // never assigned
 {
  new Object() {
   {
   o = new Object(){}; // cannot assign
   }
  };
 }
 public static void main(String[] args) {
  System.out.println(new C());
 }
}

I think it is defect because anonymous class objects are ensured to run once and only once. Taking part in the parent construction they ensure one-time initialization of the parent's final field.

What makes it useful to unnecessarily block the useful code? I have noted that the most classes I instantiate throughout the GUI Swing hierarcy are unique: some special panel and special JList within another special panel. Instances of anonymous classes ideally fit the case. By contrast, it would be bad to bloat the code space with reusable (named) classes declarations with the only purpose to instantiate a single instance of it by the following extra line of code.

Occasionally, some of the deeply instantiated objects need to be referenced from the top. The described deficiency of Java unfortunately precludes us from using the final specifier for such references.

A note on double-brace initializers and named arguments proposal.
Parameter polymorphism: through method overriding or field initialization?

Friday, May 23, 2008

Java design: Map vs. Set.get(key)

Java Set is a kind of collection, where all the elements are different. The equivalence is determined in the standard way, by hash/equals methods. The set has options to iterate its elements and check for element presence in it but there is no way to retrieve an element from the set by supplying the equivalent key. If you need such a option, you are suggested to use the Map interface. They tell that if you need the get-by-key in a Set, your design is wrong. Yet, it is wrong to think so. The Map structure is abused. I'll try to explain why.

The keys, also known as identifiers, are used for referencing. Within one program, objects are accessed by pointers (Object b = a.field.getSomething()). The pointers are natural and fast but invalid outside the program address space. Thus, files and DBs are used for communication, where externally understandable references are used. Normally, the linking is done by unique object names. Even human can interact the programs tending to give mnemonic names.

Consider a circuit editor. An engineer commands the program: 'join pin "a" of unit "u1" with pin "b" of unit "u2" by net "x"'. Here, objects of class Pin, Unit and Net are referred by name. The circuits are transferred between apps by netlist files:
(block "Circuit 1" (pin "in") (pin "out") (instance "AND" "u1") (instance "AND" "u2") (net "x" joins (u1.a, in)).

In this file, a block contains two ports, two instances of AND sub-blocks, and one net connecting two ports. The objects in the presented hierarchy inherently have a unique name within their container. There is only one instance "u1" in the block. It is natural, therefore, to establish a set of unique elements for every container. Using a map, on the other hand, results in bad design because of redundancy.

Redundancy is good in two cases: boosting performance (caching) or error detection. However, it is attribute of bad design when it is entailed for no advantage. That is because it increases complexity for no reason, consumes (mainly, storage) resources and creates potential for inconsistencies in the program.

The very possibility of inconsistency (also know as incoherency) is a sign of redundancy. When you use a map to retrieve the named objects by name, you have object name twice: in the key and in the value of the map:

class Net {
String name; // net name, unique within parent block
Block parent;
...
}
class Block {
String name; // block name, unique within parent block
Map<String, Net> connections;
void addNet(Net net) {
  connections.add(net.name, net) // name is duplicated
  net.parent = this;
}
...

All the objects in this example model have name, which is unique within the parent container. The example illustrates how a string key translates to a net object, which has a copy of the key. The name presents twice in the data model, consuming the twice memory needed. The inconsistency is produced when the key refers an object, which has a different name: ("a" -> net("b")). We must avoid redundancy (memory waste and potential for inconsistencies). The java.util.Map is a wrong structure to implement the lookup-demanding relationship. A better option would be
class Pin {
String name; // pin name, unique within parent block
Set<Net> connections;
void join(Net net) {
  connections.add(net) // no redundancy is created
}
}


Here is no room for error. In addition, the code is simpler and no data memory is wasted. The only problem is to define the equivalence so that container would match the elements by name as desired.

There is a definite analogy between a set of elements in java program and table of records in DB. The equivalence in the datatable is determined by key fields. There is no doubt that the primary key is not reflected to the rest of the record. The record is solid: it is constituted of all the fields including the key ones. Meantime, the keys in the map are separate objects from the values they map on. The redundancy can be illustrated in this way. Given a table
  field1(primary key), field2, field3

we are deprived of the facility to select an object by key field. Instead, we are invited to create an extra mapping
  field1(primary key) => field1(primary key), field2, field3.

Please tell me why is this map "a proper" design? I see only one reason: there is a group of Java adepts-fundamentalists, who define good design as "the one provisioned by java collections". The java.util.Set is exposed as mathematical abstraction, and contains(equivalent) satisfies the intersection-like math operations.

Yet, I'm sure that the set notion is also very useful outside of the math field. In this post, I have explained the need for Set and get-by-key in general-purpose applications. The omission is a great loss for programming, for Java. The Java Collections design flow must be rectified.

In the next post, I'll propose the Set with get(key) method along with the element equivalence management. It can be implemented in number of approaches.

Duplicated in http://valjok.blogspot.com/2012/02/why-java-set-does-not-have-get-method.html