MATLAB, 3987 2827 2813
Not sure it is worth posting this given the enormity of it, but anyway:
b=java.io.ByteArrayOutputStream;org.apache.commons.io.IOUtils.copy(java.util.zip.InflaterInputStream(java.io.ByteArrayInputStream(typecast(org.apache.commons.codec.binary.Base64.decodeBase64(uint8('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')),'uint8'))),b);s=char(b.toByteArray)';
i=input('');h=@hex2dec;r=@reshape;t=cellfun(@(x){x(1:2),h(x(3:6)),h(r(x(7:end),2,[])')},strsplit(strtrim(regexprep(s,'([A-Z]{2,})',' $1'))),'Un',0);z='XX';for l=t
a=l{1};g=a{3};for g=r(a{3},2,[])
s=a{2}*10+g(1);e=s+g(2);if any(s:e==i);z=a{1};end
end
end;disp(z)
Yeah. Not really code golf material. Although much better now
After a bit of messing around, I managed to get MATLAB to directly access the Java Virtual Machine to be able to decompress a base64 encoded zip representation of the original data, which quite literally knocks 25% of the size of the code. I am being quite naughty here in that I don't block closing the InputStream and OutputStream during decompression, but who cares, it doesn't crash!.
After decompression, the zip codes are encoded in a format which is:
CCbbbboollooll...
Where CC
is the two letter zip code. bbbb
is a base (starting point) for this zip code which was divide by 10 and converted to hex so that only 4 characters are needed. For each base there is one or more ooll
entries which is two hex numbers where oo
is the offset from the base, and ll
is the number of codes in the range minus 1.
All of the hex numbers are lower case, and all of the zip codes are upper case. This allows each entry to be separated based on whenever a two upper case letters appear (because the are only present as the first two letters in an entry).
Once each entry is split up, the hex numbers are parsed and converted into decimal, and we basically work through every entry to find a match.
The ranges for a given ooll
pair are calculated as:
start = 10*dec(bbbb) + dec(oo)
end = start + dec(ll)
A new entry (CCbbbb
) occurs at each point that the a new zip code appears. Some of the codes appear at more than one base address as there are some which are not all grouped together. Allowing multiple entries costs some bytes of CCbbbb
headers, but it means that all of the lengths and ranges need only be 2 characters which saves quite a few.
Matlab is not good at encoding in different bases, so of the ideas I had for how to encode the data, this is the best I could think of. It turns out, that I can actually save quite a lot of bytes by resorting to directly accessing the Java Virtual Machine that Matlab is running to perform base64 decoding, followed by zip decompression. The input string was made by doing the reverse (compress then encode).