Commit 344f58b7 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Add some more GCJ solutions as test cases

These seem to work fairly well as tests since
- they don't use any external libraries, and
- they have a very straightforward input-to-output model

Added some more runtime functions
gcj_2014_2d is currently crashing pyston
parent fa787025
import sys
_rand = 12345
def randint():
global _rand
_rand = (_rand * 1103515245 + 12345) % (1<<31)
return _rand
if __name__ == "__main__":
f = sys.stdin
if len(sys.argv) >= 2:
fn = sys.argv[1]
if fn != '-':
f = open(fn)
T = 100
for _T in xrange(T):
N = 1000
nums = [randint() for i in xrange(N)]
r = 0
while nums:
m = min(nums)
i = nums.index(m)
r += min(i, len(nums)-1-i)
del nums[i]
print "Case #%d: %d" % (_T+1, r)
......@@ -148,6 +148,20 @@ Box* dictGet2(BoxedDict* self, Box* k) {
return dictGet3(self, k, None);
}
Box* dictSetdefault3(BoxedDict* self, Box* k, Box* v) {
assert(self->cls == dict_cls);
auto it = self->d.find(k);
if (it != self->d.end())
return it->second;
self->d.insert(it, std::make_pair(k, v));
return v;
}
Box* dictSetdefault2(BoxedDict* self, Box* k) {
return dictSetdefault3(self, k, None);
}
BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, void* p) {
......@@ -189,6 +203,10 @@ void setupDict() {
addRTFunction(get, (void*)dictGet3, UNKNOWN, 3, false);
dict_cls->giveAttr("get", new BoxedFunction(get));
CLFunction* setdefault = boxRTFunction((void*)dictSetdefault2, UNKNOWN, 2, false);
addRTFunction(setdefault, (void*)dictSetdefault3, UNKNOWN, 3, false);
dict_cls->giveAttr("setdefault", new BoxedFunction(setdefault));
dict_cls->giveAttr("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NULL, 3, false)));
......
......@@ -169,6 +169,13 @@ Box* setLen(BoxedSet* self) {
return boxInt(self->s.size());
}
Box* setAdd(BoxedSet* self, Box* v) {
assert(self->cls == set_cls);
self->s.insert(v);
return None;
}
} // namespace set
using namespace pyston::set;
......@@ -218,6 +225,8 @@ void setupSet() {
set_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)setLen, BOXED_INT, 1, false)));
set_cls->giveAttr("add", new BoxedFunction(boxRTFunction((void*)setAdd, NONE, 2, false)));
set_cls->freeze();
}
......
......@@ -42,6 +42,8 @@ extern "C" BoxedString* strAdd(BoxedString* lhs, Box* _rhs) {
}
extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
const BoxedTuple::GCVector* elts;
BoxedTuple::GCVector _elts;
if (rhs->cls == tuple_cls) {
......@@ -189,6 +191,8 @@ extern "C" BoxedString* strMul(BoxedString* lhs, BoxedInt* rhs) {
}
extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
if (rhs->cls != str_cls)
return boxBool(false);
......@@ -197,10 +201,14 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
}
extern "C" Box* strLen(BoxedString* self) {
assert(self->cls == str_cls);
return boxInt(self->s.size());
}
extern "C" Box* strStr(BoxedString* self) {
assert(self->cls == str_cls);
return self;
}
......@@ -223,6 +231,8 @@ static bool _needs_escaping[256]
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true };
static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain
extern "C" Box* strRepr(BoxedString* self) {
assert(self->cls == str_cls);
std::ostringstream os("");
const std::string& s = self->s;
......@@ -270,11 +280,15 @@ extern "C" Box* strRepr(BoxedString* self) {
}
extern "C" Box* strHash(BoxedString* self) {
assert(self->cls == str_cls);
std::hash<std::string> H;
return boxInt(H(self->s));
}
extern "C" Box* strNonzero(BoxedString* self) {
assert(self->cls == str_cls);
return boxBool(self->s.size() != 0);
}
......@@ -290,6 +304,8 @@ extern "C" Box* strNew2(BoxedClass* cls, Box* obj) {
}
Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
assert(self->cls == str_cls);
const std::string& s = self->s;
assert(step != 0);
......@@ -313,6 +329,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
Box* strLower(BoxedString* self) {
assert(self->cls == str_cls);
std::string lowered(self->s);
std::transform(lowered.begin(), lowered.end(), lowered.begin(), tolower);
return boxString(std::move(lowered));
......@@ -446,6 +463,8 @@ Box* strContains(BoxedString* self, Box* elt) {
extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls);
if (slice->cls == int_cls) {
BoxedInt* islice = static_cast<BoxedInt*>(slice);
int64_t n = islice->n;
......
......@@ -264,6 +264,10 @@ extern "C" BoxedString* noneRepr(Box* v) {
return new BoxedString("None");
}
extern "C" Box* noneHash(Box* v) {
return boxInt(819239); // chosen randomly
}
extern "C" BoxedString* functionRepr(BoxedFunction* v) {
// TODO there has to be a better way
if (v == repr_obj)
......@@ -472,6 +476,7 @@ void setupRuntime() {
none_cls->giveAttr("__name__", boxStrConstant("NoneType"));
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false)));
none_cls->giveAttr("__str__", none_cls->getattr("__repr__"));
none_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)noneHash, NULL, 1, false)));
none_cls->freeze();
module_cls->giveAttr("__name__", boxStrConstant("module"));
......
......@@ -35,3 +35,9 @@ print sorted(d.items())
print d.get(4)
print d.get(4, 5)
print d.get(3, 5)
print sorted(d.items())
print d.setdefault(11, 9)
print sorted(d.items())
print d.setdefault(11, 10)
print sorted(d.items())
......@@ -25,6 +25,7 @@ def fact(n):
return t
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
3
3
......
import sys
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
5
66 150 4
0 67 54 133
55 20 60 67
61 63 64 67
65 63 65 85
64 21 8
32 1 55 13
42 14 61 19
16 6 26 20
11 1 13 3
14 2 30 4
28 9 30 16
5 14 14 17
11 4 13 6
99 321 10
0 52 16 52
22 52 38 52
83 52 98 52
16 105 82 105
0 158 16 158
31 158 47 158
83 158 98 158
15 211 81 211
0 264 16 264
20 264 36 264
6 313 1
0 157 5 286
76 119 8
13 17 72 80
25 98 38 117
50 116 63 118
49 2 66 12
61 92 66 105
1 52 7 105
9 80 9 91
45 113 59 114
22 437 1
0 187 21 315
""".strip()
l = s.split('\n')
T = int(l.pop(0))
for _T in xrange(T):
W, H, B = map(int, l.pop(0).split())
buildings = []
for i in xrange(B):
buildings.append(map(int, l.pop(0).split()))
grid = [[1] * H for i in xrange(W)]
for x0, y0, x1, y1 in buildings:
for x in xrange(x0, x1+1):
for y in xrange(y0, y1+1):
grid[x][y] = 0
r = 0
for sx in xrange(W):
if grid[sx][0] == 0:
continue
cx, cy = sx, 0
dx, dy = 0, 1
visited = []
while True:
# print "at", cx, cy
visited.append((cx, cy))
if cy == H-1:
for x, y in visited:
grid[x][y] = 0
r += 1
# print "made it!"
break
dx, dy = -dy, dx
failed = False
while True:
nx, ny = cx + dx, cy + dy
if nx >= 0 and nx < W and ny >= 0 and ny < H and grid[nx][ny]:
cx, cy = nx, ny
break
else:
if (cx, cy) == (sx, 0) and (dx, dy) == (0, -1):
failed = True
break
dx, dy = dy, -dx
if failed:
for x, y in visited:
grid[x][y] = 0
# print "failed"
break
# print "moved", dx, dy
print "Case #%d: %d" % (_T+1, r)
# expected: fail
# - crashes somewhere
import sys
P = 1000000007
def powmod(b, e):
r = 1
m = b
b = 1
while e:
if e & b:
r = (r * m) % P
e &= ~b
m = (m * m) % P
b <<= 1
return r
def inv(n):
return powmod(n, P - 2)
def choose(n, c):
t = 1
for i in xrange(c + 1, n + 1):
t = (t * i) % P
for i in xrange(1, n - c + 1):
t = (t * inv(i)) % P
return t
for i in xrange(1, 1000):
assert (inv(i) * i) % P == 1
if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """
5
20 16
IHAHAG
NPOEMADQGIHEB
IEDKEQCIOKKAKI
NHGMBMAINMQNGF
CDJPIQIGAJJOIQNAQGJI
JAMAPACLCHIPNBKAPG
DBBLEB
AIGIIPOQFK
FQHEBPIEADL
AADGDIGQQNKMPGK
ONJD
NH
ABMGHGHJACBJNIEJCAF
DQMELMNHNLHPNBFFQK
PCKPOQONKELNNDFBCE
JPLLNEECCMHPFDBJHEOJHJ
IMBPEMNPQLFOPB
PCNGQOENGKHJPDNAFIQLFCMO
AKCAOKP
OCGFQAAOOBFCOGNGKDM
17 10
GDICD
ABAEGLKABNCLKGGJJCAL
IDAIKCJHF
BNCFDDEBJ
CCJDBIHLMHGBAHMN
CMDFICIKHFKFJKBEIKI
IJJDCJFJ
LLMGGGHI
C
BEMECLEGBNBCNMEKJIB
HJCEFCG
DBNEKNIHIDLBNELBHADNGJ
DDCBJ
EDKGLCLGFKGKGFCMNFJ
DLHEEGGEKNEADN
EEENAMDBMLMLEJGCNNHGFBAM
AMHGBBCGFKLMEKCMGK
6 4
QMNCVNWWJCXHDHDKNARYXLP
DWHXQHJVPQDVO
QKKS
TRRIFUGURDFVDOALTMBUFCSST
LEIGFEXXOESUBMAGIDWKQRXR
KU
7 4
CDECGBCCFEDCA
BFFEB
EECGDCDECEAADFABCAFCDEG
CFGCCCDFADAF
BECCEAFGDADDBBBE
BGGCDDAADGEFCBCEDCGBEDA
EGFDGAGCDEFE
12 9
JNHNTURARPLCPJUEHPJLR
ML
SOQPUECHV
BEKHQCTBNFVLC
MGQARMIIDAPPJBUPG
ABWODFJJSEEHCKLIBU
IKFNEKCERIGUSS
LTMBPKRQJDVAQEBJVSPHUSBM
UKJOOQUSFGUOQRUNWVCMHQO
QQKRPHMRLALSAGLIDKLHFP
LAGNBBSVFEMUODPTKGEUSCKRA
INUVNMJPLMFSCSJNTUWHWOKO
""".strip()
l = s.split('\n')
T = int(l.pop(0))
for _T in xrange(T):
M, N = map(int, l.pop(0).split())
strings = []
suffix_map = {}
prefix_counts = {}
for i in xrange(M):
s = l.pop(0).strip()
strings.append(s)
for i in xrange(len(s) + 1):
substr = s[:i]
prefix_counts[substr] = prefix_counts.get(substr, 0) + 1
for i in xrange(len(s)):
substr1 = s[:i]
substr2 = s[:i+1]
suffix_map.setdefault(substr1, set([])).add(substr2)
suffix_map.setdefault(s, set([])).add(None)
worst = 0
for n in prefix_counts.values():
worst += min(n, N)
total = powmod(N, M)
mem = {}
def ftotal(into, exist):
# print N, into, exist
if into < max(exist):
return 0
key = (into, tuple(sorted(exist)))
if key in mem:
return mem[key]
bottom = 1
for e in exist:
bottom = (bottom * choose(into, e)) % P
bad = 0
# print bottom, "recursing:"
for i in xrange(1, into):
pbad = ftotal(i, exist)
# print i, choose(into, i), pbad
bad += choose(into, i) * pbad
# print bottom, bad
rtn = bottom - bad
mem[key] = rtn
return rtn
def frac(into, exist):
into = min(into, N)
exist = [min(e, N) for e in exist]
if into < max(exist):
return 0
if into == max(exist):
return 1
top = ftotal(into, exist) * choose(N, into)
bottom = 1
for e in exist:
bottom = (bottom * choose(N, e)) % P
# print top, bottom
return (top * inv(bottom)) % P
for prefix in prefix_counts:
suffix_counts = []
for suffix in suffix_map[prefix]:
if suffix is None:
suffix_counts.append(1)
else:
suffix_counts.append(prefix_counts[suffix])
fr = frac(prefix_counts[prefix], suffix_counts)
# print prefix, prefix_counts[prefix], suffix_counts, (fr * 81) % P, 81
total = (total * fr) % P
# print prefix_counts
print "Case #%d: %d %d" % (_T+1, worst, total % P)
......@@ -17,3 +17,12 @@ print sorted(s1 & s2)
print sorted(s1 | s2)
print len(set(range(5)))
s = set(range(5))
print sorted(s)
s.add(3)
print sorted(s)
s.add("")
print len(s)
s.add(None)
print len(s)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment