string = '\\n' assert string.size() == 2
string = "\n" string = '\n'
string = "Jon 'Maddog' Orwant" string = 'Jon \'Maddog\' Orwant'
string = 'Jon "Maddog" Orwant' string = "Jon \"Maddog\" Orwant"
string = '''
This is a multiline string declaration
using single quotes (you can use double quotes)
'''
string = 'hippopotamus'
start = 5; end = 7; endplus1 = 8
assert string.substring(start, endplus1) == 'pot'
assert string[start..end] == 'pot'
assert string.substring(start) == 'potamus'
assert string[start..-1] == 'potamus'
assert string - 'hippo' - 'mus' + 'to' == 'potato'
assert string.replace('ppopotam','bisc') == 'hibiscus'
assert string.substring(0, 2) + 'bisc' + string[-2..-1] == 'hibiscus'
sb = new StringBuffer(string)
sb[2..-3] = 'bisc'
assert sb.toString() == 'hibiscus'
data = 'hippopotamus means river horse'
def fields = unpack('A5 x8 A5 x1 A5 x1 A*', data)
assert fields == ['hippo', 'means', 'river', 'horse']
s = new Scanner(data)
s.findInLine(/(.{5}).{8}(.{5}) (.{5}) (.*)/)
m = s.match()
fields = []
(1..m.groupCount()).each{ fields << m.group(it) }
assert fields == ['hippo', 'means', 'river', 'horse']
input = '1 fish 2 fish red fish blue fish'
s = new Scanner(input).useDelimiter(/\s*fish\s*/)
fields = []
2.times{ fields << s.nextInt() }
2.times{ fields << s.next() }
assert fields == [1, 2, 'red', 'blue']
String[] fivers = unpack('A5 ' * (data.length() / 5), data)
assert fivers == ["hippo", "potam", "us me", "ans r", "iver ", "horse"]
assert 'abcd' as String[] == ['a', 'b', 'c', 'd']
string = "This is what you have"
assert string[0] == 'T'
assert string[5..6] == 'is'
assert string[13..-1] == 'you have'
assert string[-1] == 'e'
assert string[-4..-1] == 'have'
assert string[-8, -7, -6] == 'you'
data = new StringBuffer(string)
data[5..6] = "wasn't" ; assert data.toString() == "This wasn't what you have"
data[-12..-1] = "ondrous" ; assert data.toString() == "This wasn't wondrous"
data[0..0] = "" ; assert data.toString() == "his wasn't wondrous"
data[-10..-1] = "" ; assert data.toString() == "his wasn'"
string = "This wasn't wondrous"
assert string[-10..-1] =~ /^t\sw.*s$/
string = 'This is a test'
assert string[0..4].replaceAll('is', 'at') + string[5..-1] == 'That is a test'
string = 'make a hat'
string = string[-1] + string[1..-2] + string[0]
assert string == 'take a ham'
string = 'To be or not to be'
assert unpack("x6 A6", string) == ['or not']
assert unpack("x6 A2 X5 A2", string) == ['or', 'be']
assert cut2fmt([8, 14, 20, 26, 30]) == 'A7 A6 A6 A6 A4 A*'
def unpack(String format, String data) {
def result = []
int formatOffset = 0, dataOffset = 0
int minDataOffset = 0, maxDataOffset = data.size()
new StringTokenizer(format).each{ token ->
int tokenLen = token.length()
int count = 0
if (tokenLen == 1) count = 1
else if (token.charAt(1) == '*') count = -1
else count = token[1..-1].toInteger()
char action = token.charAt(0)
switch (action) {
case 'A':
if (count == -1) {
start = [dataOffset, maxDataOffset].min()
result.add(data[start..-1])
dataOffset = maxDataOffset
} else {
start = [dataOffset, maxDataOffset].min()
end = [dataOffset + count, maxDataOffset].min()
result.add(data[start..<end])
dataOffset += count
}
break
case 'x':
if (count == -1) dataOffset = maxDataOffset
else dataOffset += count
break
case 'X':
if (count == -1) dataOffset = minDataOffset
else dataOffset -= count
break
default:
throw new RuntimeException('Unknown action token', formatOffset)
}
formatOffset += tokenLen + 1
}
return result as String[]
}
def cut2fmt(positions) {
template = ''
lastpos = 1
for (pos in positions) {
template += 'A' + (pos - lastpos) + ' '
lastpos = pos
}
return template + 'A*'
}
b = false; c = 'cat'
assert (b ? b : c) == 'cat'
b = true
assert (b ? b : c)
b = []
assert (b ? b : c) == 'cat'
x = false; y = 'dog'
if (!x) x = y
assert x == 'dog'
x = 'cat'
if (!x) x = y
assert x == 'cat'
assert System.getProperty('user.name')
def setDefaultIfNullOrEmpty(startingPoint) {
(!startingPoint || startingPoint.length() == 0) ? 'Greenwich' : startingPoint
}
assert setDefaultIfNullOrEmpty(null) == 'Greenwich'
assert setDefaultIfNullOrEmpty('') == 'Greenwich'
assert setDefaultIfNullOrEmpty('Something else') == 'Something else'
v1 = 'alpha'; v2 = 'omega'
swap = { temp = v1; v1 = v2; v2 = temp }
swap()
assert v1 == 'omega' && v2 == 'alpha'
char ch = 'e'
int num = ch ch = (char) num
s1 = "Number " + num + " is character " + (char) num
assert s1 == 'Number 101 is character e'
s2 = "Character " + ch + " is number " + (int) ch
assert s2 == 'Character e is number 101'
char[] ascii = "sample".toCharArray() assert new String(ascii) == "sample"
assert new String([115, 97, 109, 112, 108, 101] as char[]) == "sample"
assert "HAL".toCharArray().collect{new String(it+1 as char[])}.join() == 'IBM'
assert ("HAL" as String[]).collect{it.next()}.join() == 'IBM'
assert "HAL".replaceAll('.', {it.next()}) == 'IBM'
string = "an apple a day"
assert string[3..7].split('')[1..5] == ['a', 'p', 'p', 'l', 'e']
assert string.split('').toList().unique().sort().join() == ' adelnpy'
checksum = 0
new File(args[0]).eachByte{ checksum += it }
checksum %= (int) Math.pow(2, 16) - 1
println checksum
delay = args[1].toInteger()
new File(args[0]).eachByte{ print ((char) it); Thread.sleep(delay) }
assert 'string'.reverse() == 'gnirts'
string = 'Yoda said, "can you see this?"'
revwords = string.split(' ').toList().reverse().join(' ')
assert revwords == 'this?" see you "can said, Yoda'
words = ['bob', 'alpha', 'rotator', 'omega', 'reviver']
long_palindromes = words.findAll{ w -> w == w.reverse() && w.size() > 5 }
assert long_palindromes == ['rotator', 'reviver']
s1 = 'abc\t def\tghi \n\tx'
s2 = 'abc def ghi \n x'
def expand(s) {
s.split('\n').toList().collect{
line = it
while (line.contains('\t')) {
line = line.replaceAll(/([^\t]*)(\t)(.*)/){
all,pre,tab,suf -> pre + ' ' * (8 - pre.size() % 8) + suf
}
}
return line
}.join('\n')
}
def unexpand(s) {
s.split('\n').toList().collect{
line = it
for (i in line.size()-1..1) {
if (i % 8 == 0) {
prefix = line[0..<i]
if (prefix.trim().size() != prefix.size()) {
line = prefix.trim() + '\t' + line[i..-1]
}
}
}
return line
}.join('\n')
}
assert expand(s1) == s2
assert unexpand(s2) == s1
debt = 150
assert "You owe $debt to me" == 'You owe 150 to me'
rows = 24; cols = 80
assert "I am $rows high and $cols wide" == 'I am 24 high and 80 wide'
assert 'I am 17 years old'.replaceAll(/\d+/, {2*it.toInteger()}) == 'I am 34 years old'
assert "bo peep".toUpperCase() == 'BO PEEP'
assert 'JOHN'.toLowerCase() == 'john'
def capitalize(s) {s[0].toUpperCase() + (s.size()<2 ? '' : s[1..-1]?.toLowerCase())}
assert capitalize('joHn') == 'John'
s = "thIS is a loNG liNE".replaceAll(/\w+/){capitalize(it)}
assert s == 'This Is A Long Line'
s1 = 'JOhn'; s2 = 'joHN'
assert s1.equalsIgnoreCase(s2)
private Random rand
def randomCase(char ch) {
(rand.nextInt(100) < 20) ? Character.toLowerCase(ch) : ch
}
n = 10
assert "I have ${n+1} guanacos." == 'I have 11 guanacos.'
assert "I have " + (n+1) + " guanacos." == 'I have 11 guanacos.'
naughty = 'Mr Bad Credit'
def get_manager_list(s) { 'The Big Boss' }
msg = """
To: $naughty
From: Your Bank
Cc: ${ get_manager_list(naughty) }
Date: ${ new Date() }
Dear $naughty,
Today, you bounced check number ${ 500 + new Random().nextInt(100) } to us.
Your account is now closed.
Sincerely,
the management
"""
expected = '''
To: Mr Bad Credit
From: Your Bank
Cc: The Big Boss
Date: XXX
Dear Mr Bad Credit,
Today, you bounced check number XXX to us.
Your account is now closed.
Sincerely,
the management
'''
sanitized = msg.replaceAll('(?m)^Date: (.*)$','Date: XXX')
sanitized = sanitized.replaceAll(/(?m)check number (\d+) to/,'check number XXX to')
assert sanitized == expected
ant = new AntBuilder()
ant.mail(from:'manager@grumpybank.com', tolist:'innocent@poorhouse.com',
encoding:'plain', mailhost:'mail.someserver.com',
subject:'Friendly Letter', message:'this is a test message')
def raw = '''
your text
goes here
'''
def expected = '''
your text
goes here
'''
assert raw.split('\n').toList().collect{
it.replaceAll(/^\s+/,'')
}.join('\n') + '\n' == expected
input = '''Folding and splicing is the work of an editor,
not a mere collection of silicon
and
mobile electrons!'''
expected = '''Folding and splicing
is the work of an
editor, not a mere
collection of
silicon and mobile
electrons!'''
def wrap(text, maxSize) {
all = []
line = ''
text.eachMatch(/\S+/) {
word = it[0]
if (line.size() + 1 + word.size() > maxSize) {
all += line
line = word
} else {
line += (line == '' ? word : ' ' + word)
}
}
all += line
return all.join('\n')
}
assert wrap(input, 20) == expected
string = /Mom said, "Don't do that."/
assert string.replaceAll(/['"]/){/\\/+it[0]} == /Mom said, \"Don\'t do that.\"/ //'
assert string.replaceAll(/['"]/){it[0]+it[0]} == /Mom said, ""Don''t do that.""/ //'
assert "DIR /?".replaceAll(/[^A-Z]/){/\\/+it[0]} == /DIR\ \/\?/
assert ' x '.trim() == 'x'
new BufferedReader(new InputStreamReader(System.in)).eachLine{
println(">" + it.trim() + "<");
}
pattern = /"([^\"\\]*(?:\\.[^\"\\]*)*)",?|([^,]+),?|,/
line = /XYZZY,"","O'Reilly, Inc","Wall, Larry","a \"glug\" bit,",5,"Error, Core Dumped"/
m = line =~ pattern
expected = [/XYZZY/, '', /O'Reilly, Inc/, /Wall, Larry/, //'
/a \"glug\" bit,/, /5/, /Error, Core Dumped/]
for (i in 0..<m.size().toInteger())
assert expected[i] == (m[i][2] ? m[i][2] : m[i][1])
soundex = new org.apache.commons.codec.language.Soundex()
assert soundex.soundex('Smith') == soundex.soundex('Smyth')
input = '''I have analysed the new part. As long as you
aren't worried about the colour, it is a dropin replacement.''' //'
expected = '''I have analyzed the new part. As long as you
aren't worried about the color, it is a drop-in replacement.''' //'
translations = [colour:'color', analysed:'analyzed', dropin:'drop-in']
def fixstyle(s) {
s.split('\n').toList().collect{
line = it
translations.each{ key, value ->
line = line.replaceAll(/(?<=\W)/ + key + /(?=\W)/, value)
}
return line
}.join('\n')
}
assert fixstyle(input) == expected
input = '''
PID PPID PGID WINPID TTY UID STIME COMMAND
4636 1 4636 4636 con 1005 08:24:50 /usr/bin/bash
676 4636 676 788 con 1005 13:53:32 /usr/bin/ps
'''
select1 = '''
PID PPID PGID WINPID TTY UID STIME COMMAND
676 4636 676 788 con 1005 13:53:32 /usr/bin/ps
'''
select2 = '''
PID PPID PGID WINPID TTY UID STIME COMMAND
4636 1 4636 4636 con 1005 08:24:50 /usr/bin/bash
'''
format = cut2fmt([10, 18, 26, 37, 42, 47, 56])
def psgrep(s) {
out = []
lines = input.split('\n').findAll{ it.size() }
vars = unpack(format, lines[0]).toList().collect{ it.toLowerCase().trim() }
out += lines[0]
lines[1..-1].each{
values = unpack(format, it).toList().collect{
try {
return it.toInteger()
} catch(NumberFormatException e) {
return it.trim()
}
}
vars.eachWithIndex{ var, i ->
binding.setVariable(var, values[i])
}
if (new GroovyShell(binding).evaluate(s)) out += it
}
return '\n' + out.join('\n') + '\n'
}
assert psgrep('winpid < 800') == select1
assert psgrep('uid % 5 == 0 && command =~ /sh$/') == select2
input = 'ps'.execute().text
input = 'path_to_cygwin/bin/ps.exe'.execute().text
input = 'pslist.exe'.execute().text
import java.text.*
int nb = 0
try {
nb = NumberFormat.getInstance().parse('33.5') nb = NumberFormat.getInstance().parse('abc')
} catch (ParseException ex) {
assert ex.getMessage().contains('abc')
}
assert nb == 33
try {
nb = Integer.parseInt('34')
assert nb == 34
nb = new Integer('35')
nb = Integer.parseInt('abc')
} catch (NumberFormatException ex) {
assert ex.getMessage().contains('abc')
}
assert nb == 35
integerPattern = /^[+-]?\d+$/
assert '-36' =~ integerPattern
assert !('abc' =~ integerPattern)
decimalPattern = /^-?(?:\d+(?:\.\d*)?|\.\d+)$/
assert '37.5' =~ decimalPattern
wage = 5.36
week = 40 * wage
assert "One week's wage is: \$$week" == /One week's wage is: $214.40/
// if you want to use explicit doubles and floats you can still use
// printf in version 5, 6 or 7 JVMs
// printf('%5.2f', week as double)
// => 214.40
//----------------------------------------------------------------------------------
// @@PLEAC@@_2.3
//----------------------------------------------------------------------------------
a = 0.255
b = a.setScale(2, BigDecimal.ROUND_HALF_UP);
assert a.toString() == '0.255'
assert b.toString() == '0.26'
a = [3.3 , 3.5 , 3.7, -3.3] as double[]
// warning rint() rounds to nearest integer - slightly different to Perl's int()
rintExpected = [3.0, 4.0, 4.0, -3.0] as double[]
floorExpected = [3.0, 3.0, 3.0, -4.0] as double[]
ceilExpected = [4.0, 4.0, 4.0, -3.0] as double[]
a.eachWithIndex{ val, i ->
assert Math.rint(val) == rintExpected[i]
assert Math.floor(val) == floorExpected[i]
assert Math.ceil(val) == ceilExpected[i]
}
assert Integer.parseInt('0110110', 2) == 54
assert Integer.toString(54, 2) == '110110'
assert Integer.toString(60, 16) == '3c'
x = 3; y = 20
for (i in x..y) {
}
(x..<y).each {
}
assert (x..y).step(7) == [3, 10, 17]
years = []
(5..<13).each{ age -> years += age }
assert years == [5, 6, 7, 8, 9, 10, 11, 12]
class IntegerCategory {
static def romanMap = [1000:'M', 900:'CM', 500:'D', 400:'CD', 100:'C', 90:'XC',
50:'L', 40:'XL', 10:'X', 9:'IX', 5:'V', 4:'IV', 1:'I']
static getRoman(Integer self) {
def remains = self
def text = ''
romanMap.keySet().sort().reverse().each{ key ->
while (remains >= key) {
remains -= key
text += romanMap[key]
}
}
return text
}
static int parseRoman(Object self, String input) {
def ustr = input.toUpperCase()
int sum = 0
romanMap.keySet().sort().reverse().each{ key ->
while (ustr.startsWith(romanMap[key])) {
sum += key
ustr -= romanMap[key]
}
}
return sum
}
}
use(IntegerCategory) {
int fifteen = 15
assert fifteen.roman == 'XV'
assert parseRoman('XXVI') == 26
for (i in 1..3900) {
assert i == parseRoman(i.roman)
}
}
random = new Random()
100.times{
next = random.nextInt(50) + 25
assert next > 24
assert next < 76
}
chars = []
['A'..'Z','a'..'z','0'..'9',('!@$%^&*' as String[]).toList()].each{chars += it}
password = (1..8).collect{ chars[random.nextInt(chars.size())] }.join()
assert password.size() == 8
long seed = System.currentTimeMillis()
random1 = new Random(seed)
random2 = new Random(seed)
assert random1.nextInt() == random2.nextInt()
seed = System.currentTimeMillis() + Runtime.runtime.freeMemory()
random = new Random()
mean = 25
sdev = 2
salary = random.nextGaussian() * sdev + mean
printf 'You have been hired at \$%.2f', salary
assert Math.toRadians(90) == Math.PI / 2
assert Math.toDegrees(Math.PI) == 180
t = Math.tan(1.5)
assert t > 14.1 && t < 14.11
ac = Math.acos(0.1)
assert ac > 1.47 && ac < 1.48
assert Math.log(Math.E) == 1
assert Math.log10(10000) == 4
def logn(base, val) { Math.log(val)/Math.log(base) }
assert logn(2, 1024) == 10
import Jama.Matrix
matrix1 = new Matrix([
[3, 2, 3],
[5, 9, 8]
] as double[][])
matrix2 = new Matrix([
[4, 7],
[9, 3],
[8, 1]
] as double[][])
expectedArray = [[54.0, 30.0], [165.0, 70.0]] as double[][]
productArray = matrix1.times(matrix2).array
for (i in 0..<productArray.size()) {
assert productArray[i] == expectedArray[i]
}
import org.apache.commons.math.complex.Complex
a = new Complex(3, 5) b = new Complex(2, -2) expected = new Complex (16, 4) assert expected == a * b
assert Integer.parseInt('101', 16) == 257
assert Integer.parseInt('077', 8) == 63
print 'Gimme a number in decimal, octal, or hex: '
reader = new BufferedReader(new InputStreamReader(System.in))
input = reader.readLine().trim()
switch(input) {
case ~'^0x\\d+':
number = Integer.parseInt(input.substring(2), 16); break
case ~'^0\\d+':
number = Integer.parseInt(input.substring(1), 8); break
default:
number = Integer.parseInt(input)
}
println 'Decimal value: ' + number
print 'Enter file permission in octal: '
input = new BufferedReader(new InputStreamReader(System.in))
num = input.readLine().trim()
permission = Integer.parseInt(num, 8)
println 'Decimal value: ' + permission
nf = NumberFormat.getInstance()
assert nf.format(-1740525205) == '-1,740,525,205'
def timeMessage(hour) { 'It took ' + hour + ' hour' + (hour == 1 ? '' : 's') }
assert 'It took 1 hour' == timeMessage(1)
assert 'It took 2 hours' == timeMessage(2)
limits = [1, ChoiceFormat.nextDouble(1)] as double[]
names = ['century', 'centuries'] as String[]
choice = new ChoiceFormat(limits, names)
numCenturies = 1
expected = 'It took 1 century'
assert expected == "It took $numCenturies " + choice.format(numCenturies)
choice = new ChoiceFormat('0#are no files|1#is one file|2#are multiple files')
assert choice.format(3) == 'are multiple files'
def factorize(BigInteger orig) {
factors = [:]
def addFactor = { x -> if (factors[x]) factors[x] += 1 else factors[x] = 1 }
n = orig
i = 2
sqi = 4 while (sqi <= n) {
while (n.remainder(i) == 0) {
n /= i
addFactor i
}
sqi += 2 * i + 1
i += 1
}
if ((n != 1) && (n != orig)) addFactor n
return factors
}
def pretty(factors) {
if (!factors) return "PRIME"
sb = new StringBuffer()
factors.keySet().sort().each { key ->
sb << key
if (factors[key] > 1) sb << "**" + factors[key]
sb << " "
}
return sb.toString().trim()
}
assert pretty(factorize(2178)) == '2 3**2 11**2'
assert pretty(factorize(39887)) == 'PRIME'
assert pretty(factorize(239322000000000000000000)) == '2**19 3 5**18 39887'
println new Date()
cal = Calendar.instance
println 'Today is day ' + cal.get(Calendar.DAY_OF_YEAR) + ' of the current year.'
cal = Calendar.instance
Y = cal.get(Calendar.YEAR)
M = cal.get(Calendar.MONTH) + 1
D = cal.get(Calendar.DATE)
println "The current date is $Y $M $D"
cal = Calendar.instance
cal.timeZone = TimeZone.getTimeZone("America/Los_Angeles")
cal.timeZone = TimeZone.getTimeZone("UTC")
cal.set(Calendar.MONTH, Calendar.DECEMBER)
long time = cal.time.time / 1000
println time
cal = Calendar.instance
cal.time = new Date(time * 1000)
println('Dateline: '
+ cal.get(Calendar.HOUR_OF_DAY) + ':'
+ cal.get(Calendar.MINUTE) + ':'
+ cal.get(Calendar.SECOND) + '-'
+ cal.get(Calendar.YEAR) + '/'
+ (cal.get(Calendar.MONTH) + 1) + '/'
+ cal.get(Calendar.DATE))
import java.text.SimpleDateFormat
long difference = 100
long after = time + difference
long before = time - difference
cal = Calendar.instance
df = new SimpleDateFormat()
printCal = {cal -> df.format(cal.time)}
cal.set(2000, 0, 1, 00, 01, 0)
assert printCal(cal) == '1/01/00 00:01'
cal.roll(Calendar.MINUTE, -2)
assert printCal(cal) == '1/01/00 00:59'
cal.add(Calendar.HOUR, -1)
assert printCal(cal) == '31/12/99 23:59'
cal.timeZone = TimeZone.getTimeZone("UTC")
cal.set(1973, 0, 18, 3, 45, 50)
cal.add(Calendar.DATE, 55)
cal.add(Calendar.HOUR_OF_DAY, 2)
cal.add(Calendar.MINUTE, 17)
cal.add(Calendar.SECOND, 5)
assert printCal(cal) == '14/03/73 16:02'
long birthTime = 96176750359 long interval = 5 + 17 * 60 + 2 * 60 * 60 + 55 * 60 * 60 * 24 then = new Date(birthTime + interval * 1000)
assert df.format(then) == '14/03/73 16:02'
bree = 361535725 nat = 96201950 difference = bree - nat
println "There were $difference seconds between Nat and Bree"
seconds = difference % 60
difference = (difference - seconds) / 60
minutes = difference % 60
difference = (difference - minutes) / 60
hours = difference % 24
difference = (difference - hours) / 24
days = difference % 7
weeks = (difference - days) / 7
println "($weeks weeks, $days days, $hours:$minutes:$seconds)"
cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
cal.set(1981, 5, 16) date1 = cal.time
cal.set(1973, 0, 18) date2 = cal.time
difference = Math.abs(date2.time - date1.time)
days = difference / (1000 * 60 * 60 * 24)
assert days == 3071
cal = Calendar.instance
cal.set(1981, 5, 16)
yearDay = cal.get(Calendar.DAY_OF_YEAR);
year = cal.get(Calendar.YEAR);
yearWeek = cal.get(Calendar.WEEK_OF_YEAR);
df1 = new SimpleDateFormat("dd/MMM/yy")
df2 = new SimpleDateFormat("EEEE")
print(df1.format(cal.time) + ' was a ' + df2.format(cal.time))
println " and was day number $yearDay and week number $yearWeek of $year"
input = "1998-06-03"
df1 = new SimpleDateFormat("yyyy-MM-dd")
date = df1.parse(input)
df2 = new SimpleDateFormat("MMM/dd/yyyy")
println 'Date was ' + df2.format(date)
import java.text.DateFormat
df = new SimpleDateFormat('E M d hh:mm:ss z yyyy')
cal.set(2007, 0, 1)
println 'Customized format gives: ' + df.format(cal.time)
df = DateFormat.getDateInstance(DateFormat.FULL, Locale.FRANCE)
println 'Customized format gives: ' + df.format(cal.time)
println 'Press return when ready'
before = System.currentTimeMillis()
input = new BufferedReader(new InputStreamReader(System.in)).readLine()
after = System.currentTimeMillis()
elapsed = (after - before) / 1000
println "You took $elapsed seconds."
size = 500; number = 100; total = 0
for (i in 0..<number) {
array = []
size.times{ array << Math.random() }
doubles = array as double[]
long t0 = System.currentTimeMillis()
Arrays.sort(doubles)
long t1 = System.currentTimeMillis()
total += (t1 - t0)
}
println "On average, sorting $size random numbers takes ${total / number} milliseconds"
delayMillis = 50
Thread.sleep(delayMillis)
sampleMessage = '''Delivered-To: alias-someone@somewhere.com.au
Received: (qmail 27284 invoked from network); 30 Dec 2006 15:16:26 -0000
Received: from unknown (HELO lists-outbound.sourceforge.net) (66.35.250.225)
by bne012m.server-web.com with SMTP; 30 Dec 2006 15:16:25 -0000
Received: from sc8-sf-list2-new.sourceforge.net (sc8-sf-list2-new-b.sourceforge.net [10.3.1.94])
by sc8-sf-spam2.sourceforge.net (Postfix) with ESMTP
id D8CCBFDE3; Sat, 30 Dec 2006 07:16:24 -0800 (PST)
Received: from sc8-sf-mx1-b.sourceforge.net ([10.3.1.91]
helo=mail.sourceforge.net)
by sc8-sf-list2-new.sourceforge.net with esmtp (Exim 4.43)
id 1H0fwX-0003c0-GA
for pleac-discuss@lists.sourceforge.net; Sat, 30 Dec 2006 07:16:20 -0800
Received: from omta05ps.mx.bigpond.com ([144.140.83.195])
by mail.sourceforge.net with esmtp (Exim 4.44) id 1H0fwY-0005D4-DD
for pleac-discuss@lists.sourceforge.net; Sat, 30 Dec 2006 07:16:19 -0800
Received: from win2K001 ([138.130.127.127]) by omta05ps.mx.bigpond.com
with SMTP
id <20061230151611.XVWL19269.omta05ps.mx.bigpond.com@win2K001>;
Sat, 30 Dec 2006 15:16:11 +0000
From: someone@somewhere.com
To: <pleac-discuss@lists.sourceforge.net>
Date: Sun, 31 Dec 2006 02:14:57 +1100
Subject: Re: [Pleac-discuss] C/Posix/GNU - @@pleac@@_10x
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: pleac-discuss-bounces@lists.sourceforge.net
Errors-To: pleac-discuss-bounces@lists.sourceforge.net
----- Original Message -----
From: someone@somewhere.com
To: otherperson@somewhereelse.com
Cc: <pleac-discuss@lists.sourceforge.net>
Sent: Wednesday, December 27, 2006 9:18 AM
Subject: Re: [Pleac-discuss] C/Posix/GNU - @@pleac@@_10x
I really like that description of PLEAC.
'''
expected = '''
Sender Recipient Time Delta
<origin> somewhere.com 01:14:57 06/12/31
win2K001 omta05ps.mx.bigpond.com 01:14:57 06/12/31 1m 14s
omta05ps.mx.bigpond.com mail.sourceforge.net 01:16:11 06/12/31 8s
sc8-sf-mx1-b.sourceforge. sc8-sf-list2-new.sourcefo 01:16:19 06/12/31 1s
sc8-sf-list2-new.sourcefo sc8-sf-spam2.sourceforge. 01:16:20 06/12/31 4s
unknown bne012m.server-web.com 01:16:24 06/12/31 1s
'''
class MailHopDelta {
def headers, firstSender, firstDate, out
MailHopDelta(mail) {
extractHeaders(mail)
out = new StringBuffer()
def m = (mail =~ /(?m)^Date:\s+(.*)/)
firstDate = parseDate(m[0][1])
firstSender = (mail =~ /(?m)^From.*\@([^\s>]*)/)[0][1]
out('Sender Recipient Time Delta'.split(' '))
}
def parseDate(date) {
try {
return new SimpleDateFormat('EEE, dd MMM yyyy hh:mm:ss Z').parse(date)
} catch(java.text.ParseException ex) {}
try {
return new SimpleDateFormat('dd MMM yyyy hh:mm:ss Z').parse(date)
} catch(java.text.ParseException ex) {}
try {
return DateFormat.getDateInstance(DateFormat.FULL).parse(date)
} catch(java.text.ParseException ex) {}
DateFormat.getDateInstance(DateFormat.LONG).parse(date)
}
def extractHeaders(mail) {
headers = []
def isHeader = true
def currentHeader = ''
mail.split('\n').each{ line ->
if (!isHeader) return
switch(line) {
case ~/^\s*$/:
isHeader = false
if (currentHeader) headers << currentHeader
break
case ~/^\s+.*/:
currentHeader += line; break
default:
if (currentHeader) headers << currentHeader
currentHeader = line
}
}
}
def out(line) {
out << line[0][0..<[25,line[0].size()].min()].padRight(26)
out << line[1][0..<[25,line[1].size()].min()].padRight(26)
out << line[2].padRight(17) + ' '
out << line[3] + '\n'
}
def prettyDate(date) {
new SimpleDateFormat('hh:mm:ss yy/MM/dd').format(date)
}
def process() {
out(['<origin>', firstSender, prettyDate(firstDate), ''])
def prevDate = firstDate
headers.grep(~/^Received:\sfrom.*/).reverseEach{ hop ->
def from = (hop =~ /from\s+(\S+)|\((.*?)\)/)[0][1]
def by = (hop =~ /by\s+(\S+\.\S+)/)[0][1]
def hopDate = parseDate(hop[hop.lastIndexOf(';')+2..-1])
out([from, by, prettyDate(prevDate), prettyDelta(hopDate.time - prevDate.time)])
prevDate = hopDate
}
return out.toString()
}
def prettyField(secs, sign, ch, multiplier, sb) {
def whole = (int)(secs / multiplier)
if (!whole) return 0
sb << '' + (sign * whole) + ch + ' '
return whole * multiplier
}
def prettyDelta(millis) {
def sign = millis < 0 ? -1 : 1
def secs = (int)Math.abs(millis/1000)
def sb = new StringBuffer()
secs -= prettyField(secs, sign, 'd', 60 * 60 * 24, sb)
secs -= prettyField(secs, sign, 'h', 60 * 60, sb)
secs -= prettyField(secs, sign, 'm', 60, sb)
prettyField(secs, sign, 's', 1, sb)
return sb.toString().trim()