Friday, July 29, 2011

Compile-time constants in Java annotation element values

In hindsight, this should've been obvious:
public class CompileTimeConstantsTest {
 
    @interface Awesome { String value(); }
 
    private static final String X = "X";
    private final int a = 1;
    public final int b = 1;

    @Awesome(a < b ? X : X + X) // compiles just fine
    int whatever;
 
}

Friday, June 24, 2011

Add menu accelerator for FindBugs plugin

One way to run FindBugs is to:
  1. Right click on the Java source file you’re editing
  2. Move cursor and hover over "Find Bugs"
  3. Wait until child menu appears
  4. Move cursor to select and then click on "Find Bugs"
You can greatly accelerate this process by modifying eclipse/plugins/edu.umd.cs.findbugs.plugin.eclipse_1.3.9.20090821/plugin.xml:
REPLACE:
   label="Find Bugs"

WITH:
   label="Find Bu&amp;gs"
Then restart Eclipse with -clean command line argument. Now, to run FindBugs, you can just:
  1. Press Menu key
  2. Press G (this didn’t use to have an accelerator, but now does)
  3. Press F (this already has an accelerator)
Similarly, you can clear all FindBugs markers by pressing the key sequence Menu G C.

Monday, February 14, 2011

Pascal's triangle using regex

The pattern can probably be simplified, but this works.
String s;
System.out.println(s = "-;");
for (int n = 10; n --> 0 ;) {
   System.out.println(s = s.replaceAll("^(?=(-;))|;(?=(-*;))", "$1$2"));
}

Wednesday, February 9, 2011

Per-site user stylesheet rules for Firefox

I'll summarize this later:

userContent.css and @-moz-document
https://developer.mozilla.org/en/CSS/@-moz-document

Where's my profile directory?
about:support

You'll probably want to use !important.
http://www.w3.org/TR/CSS2/cascade.html#important-rules

Thursday, February 3, 2011

Generating Collatz sequence using regex

See: Collatz conjecture on Wikipedia

final int N = 11;
String s = new String(new char[N]);

while (s.length() > 1) {
    System.out.print(s.length() + ", ");
    s = s.replaceAll("(.+)\\1$|((.)+)", "$1$2$2$2$3");
}
System.out.println(s.length());

// prints 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1

Solving the postage stamp problem using regex

See: Postage stamp problem on Wikipedia
int n = 0;

while (
   (new String(new char[++n]))
      .matches("(.{1}|.{4}|.{9}|.{31}|.{51}){0,5}")
);

System.out.println(n); // 127
(see also on ideone.com)

That is, when the only available stamp denominations are {1, 4, 9, 31, 51}, and when envelopes can only accommodate up to 5 stamps, the smallest unrepresentable total stamp value is 127.

It's easy to confirm correctness, because (not so) coincidentally, this set of stamp denominations is the unique solution to the (5, 5) global PSP. See Al Zimmermann's Programming Contest - Son of Darts.

Monday, January 31, 2011

Redshift on multiple monitors

There are probably better ways to get Redshift to "work" on multiple monitors, but this will do for now:
#!/usr/bin/zsh

for i in {0..3} 
do
   redshift -m vidmode:screen=$i -t 5500:4000 &
done
This is a wonderful piece of software.

Monday, January 17, 2011

Pascal's triangle: yet another mindblowing fact

I knew (and at some point understood) the link between Pascal's triangle mod 2 and Sierpinski's triangle, but this is a new discovery:
Project Euler Problem 148
def row(n):
    Cnk = 1
    for k in range(n+1):
        yield Cnk
        Cnk = Cnk * (n-k) / (k+1)

#for i in range(10):
#    print list(row(i))

def div7(x):
    return x % 7 == 0

for i in range(200):
    if i and div7(i): print 
    print sum(div7(x) for x in row(i)),
Output:
0 0 0 0 0 0 0
6 5 4 3 2 1 0
12 10 8 6 4 2 0
18 15 12 9 6 3 0
24 20 16 12 8 4 0
30 25 20 15 10 5 0
36 30 24 18 12 6 0
48 47 46 45 44 43 42
53 50 47 44 41 38 35
58 53 48 43 38 33 28
63 56 49 42 35 28 21
68 59 50 41 32 23 14
73 62 51 40 29 18 7
78 65 52 39 26 13 0
96 94 92 90 88 86 84
100 95 90 85 80 75 70
104 96 88 80 72 64 56
108 97 86 75 64 53 42
112 98 84 70 56 42 28
116 99 82 65 48 31 14
120 100 80 60 40 20 0
144 141 138 135 132 129 126
147 140 133 126 119 112 105
150 139 128 117 106 95 84
153 138 123 108 93 78 63
156 137 118 99 80 61 42
159 136 113 90 67 44 21
162 135 108 81 54 27 0
192 188 184 180 ...
This is... insane!!!

Wednesday, January 12, 2011

Generator expression

I hope I'm doing this right...
Project Euler Problem 99
import math, operator, csv

f = csv.reader(open('base_exp.txt'), delimiter=',')
lines = (map(int, line) for line in f)

print max(
    enumerate(
      (math.log(b) * e for b, e in lines),
      1
    ),
    key=operator.itemgetter(1)
)

Saturday, January 8, 2011

Reference point (Part 2)

Project Euler Problem 54
import csv
import re

def facerank(face):
    return '23456789TJQKA'.find(face)

def handrank(hand):
    faces = ''.join(
        sorted([face for (face, suit) in hand], key=facerank)
    )
    is_straight = facerank(faces) != -1
    is_flush = len(set(suit for (face, suit) in hand)) == 1
    
    sorted_groups = sorted(
        [ (len(m.group(0)), facerank(m.group(1)))
            for m in re.finditer(r'(.)\1*', faces) ],
        reverse=True
    )
    
    return (
        [5] if is_flush and is_straight else
        [3, 1.2] if is_flush else
        [3, 1.1] if is_straight else
        [size for (size, member) in sorted_groups]
    ), sorted_groups

print sum(
    handrank(line[:5]) > handrank(line[5:])
        for line in csv.reader(open('poker.txt'), delimiter=" ")
)

Wow, just learned that you can "unzip" in this manner:
faces, suits = zip(*hand)
You can also use findall instead:
[ (len(xs), facerank(x))
    for xs, x in re.findall(r'((.)\2*)', faces) ]