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) { ...@@ -148,6 +148,20 @@ Box* dictGet2(BoxedDict* self, Box* k) {
return dictGet3(self, k, None); 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; BoxedClass* dict_iterator_cls = NULL;
extern "C" void dictIteratorGCHandler(GCVisitor* v, void* p) { extern "C" void dictIteratorGCHandler(GCVisitor* v, void* p) {
...@@ -189,6 +203,10 @@ void setupDict() { ...@@ -189,6 +203,10 @@ void setupDict() {
addRTFunction(get, (void*)dictGet3, UNKNOWN, 3, false); addRTFunction(get, (void*)dictGet3, UNKNOWN, 3, false);
dict_cls->giveAttr("get", new BoxedFunction(get)); 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("__getitem__", new BoxedFunction(boxRTFunction((void*)dictGetitem, NULL, 2, false)));
dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NULL, 3, false))); dict_cls->giveAttr("__setitem__", new BoxedFunction(boxRTFunction((void*)dictSetitem, NULL, 3, false)));
......
...@@ -169,6 +169,13 @@ Box* setLen(BoxedSet* self) { ...@@ -169,6 +169,13 @@ Box* setLen(BoxedSet* self) {
return boxInt(self->s.size()); return boxInt(self->s.size());
} }
Box* setAdd(BoxedSet* self, Box* v) {
assert(self->cls == set_cls);
self->s.insert(v);
return None;
}
} // namespace set } // namespace set
using namespace pyston::set; using namespace pyston::set;
...@@ -218,6 +225,8 @@ void setupSet() { ...@@ -218,6 +225,8 @@ void setupSet() {
set_cls->giveAttr("__len__", new BoxedFunction(boxRTFunction((void*)setLen, BOXED_INT, 1, false))); 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(); set_cls->freeze();
} }
......
...@@ -42,6 +42,8 @@ extern "C" BoxedString* strAdd(BoxedString* lhs, Box* _rhs) { ...@@ -42,6 +42,8 @@ extern "C" BoxedString* strAdd(BoxedString* lhs, Box* _rhs) {
} }
extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
const BoxedTuple::GCVector* elts; const BoxedTuple::GCVector* elts;
BoxedTuple::GCVector _elts; BoxedTuple::GCVector _elts;
if (rhs->cls == tuple_cls) { if (rhs->cls == tuple_cls) {
...@@ -189,6 +191,8 @@ extern "C" BoxedString* strMul(BoxedString* lhs, BoxedInt* rhs) { ...@@ -189,6 +191,8 @@ extern "C" BoxedString* strMul(BoxedString* lhs, BoxedInt* rhs) {
} }
extern "C" Box* strEq(BoxedString* lhs, Box* rhs) { extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
assert(lhs->cls == str_cls);
if (rhs->cls != str_cls) if (rhs->cls != str_cls)
return boxBool(false); return boxBool(false);
...@@ -197,10 +201,14 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) { ...@@ -197,10 +201,14 @@ extern "C" Box* strEq(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strLen(BoxedString* self) { extern "C" Box* strLen(BoxedString* self) {
assert(self->cls == str_cls);
return boxInt(self->s.size()); return boxInt(self->s.size());
} }
extern "C" Box* strStr(BoxedString* self) { extern "C" Box* strStr(BoxedString* self) {
assert(self->cls == str_cls);
return self; return self;
} }
...@@ -223,6 +231,8 @@ static bool _needs_escaping[256] ...@@ -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 }; 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 static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain
extern "C" Box* strRepr(BoxedString* self) { extern "C" Box* strRepr(BoxedString* self) {
assert(self->cls == str_cls);
std::ostringstream os(""); std::ostringstream os("");
const std::string& s = self->s; const std::string& s = self->s;
...@@ -270,11 +280,15 @@ extern "C" Box* strRepr(BoxedString* self) { ...@@ -270,11 +280,15 @@ extern "C" Box* strRepr(BoxedString* self) {
} }
extern "C" Box* strHash(BoxedString* self) { extern "C" Box* strHash(BoxedString* self) {
assert(self->cls == str_cls);
std::hash<std::string> H; std::hash<std::string> H;
return boxInt(H(self->s)); return boxInt(H(self->s));
} }
extern "C" Box* strNonzero(BoxedString* self) { extern "C" Box* strNonzero(BoxedString* self) {
assert(self->cls == str_cls);
return boxBool(self->s.size() != 0); return boxBool(self->s.size() != 0);
} }
...@@ -290,6 +304,8 @@ extern "C" Box* strNew2(BoxedClass* cls, Box* obj) { ...@@ -290,6 +304,8 @@ extern "C" Box* strNew2(BoxedClass* cls, Box* obj) {
} }
Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) { Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
assert(self->cls == str_cls);
const std::string& s = self->s; const std::string& s = self->s;
assert(step != 0); assert(step != 0);
...@@ -313,6 +329,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) { ...@@ -313,6 +329,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step) {
Box* strLower(BoxedString* self) { Box* strLower(BoxedString* self) {
assert(self->cls == str_cls); assert(self->cls == str_cls);
std::string lowered(self->s); std::string lowered(self->s);
std::transform(lowered.begin(), lowered.end(), lowered.begin(), tolower); std::transform(lowered.begin(), lowered.end(), lowered.begin(), tolower);
return boxString(std::move(lowered)); return boxString(std::move(lowered));
...@@ -446,6 +463,8 @@ Box* strContains(BoxedString* self, Box* elt) { ...@@ -446,6 +463,8 @@ Box* strContains(BoxedString* self, Box* elt) {
extern "C" Box* strGetitem(BoxedString* self, Box* slice) { extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls);
if (slice->cls == int_cls) { if (slice->cls == int_cls) {
BoxedInt* islice = static_cast<BoxedInt*>(slice); BoxedInt* islice = static_cast<BoxedInt*>(slice);
int64_t n = islice->n; int64_t n = islice->n;
......
...@@ -264,6 +264,10 @@ extern "C" BoxedString* noneRepr(Box* v) { ...@@ -264,6 +264,10 @@ extern "C" BoxedString* noneRepr(Box* v) {
return new BoxedString("None"); return new BoxedString("None");
} }
extern "C" Box* noneHash(Box* v) {
return boxInt(819239); // chosen randomly
}
extern "C" BoxedString* functionRepr(BoxedFunction* v) { extern "C" BoxedString* functionRepr(BoxedFunction* v) {
// TODO there has to be a better way // TODO there has to be a better way
if (v == repr_obj) if (v == repr_obj)
...@@ -472,6 +476,7 @@ void setupRuntime() { ...@@ -472,6 +476,7 @@ void setupRuntime() {
none_cls->giveAttr("__name__", boxStrConstant("NoneType")); none_cls->giveAttr("__name__", boxStrConstant("NoneType"));
none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false))); none_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)noneRepr, NULL, 1, false)));
none_cls->giveAttr("__str__", none_cls->getattr("__repr__")); none_cls->giveAttr("__str__", none_cls->getattr("__repr__"));
none_cls->giveAttr("__hash__", new BoxedFunction(boxRTFunction((void*)noneHash, NULL, 1, false)));
none_cls->freeze(); none_cls->freeze();
module_cls->giveAttr("__name__", boxStrConstant("module")); module_cls->giveAttr("__name__", boxStrConstant("module"));
......
...@@ -35,3 +35,9 @@ print sorted(d.items()) ...@@ -35,3 +35,9 @@ print sorted(d.items())
print d.get(4) print d.get(4)
print d.get(4, 5) print d.get(4, 5)
print d.get(3, 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): ...@@ -25,6 +25,7 @@ def fact(n):
return t return t
if __name__ == "__main__": if __name__ == "__main__":
# test data is from the Google CodeJam site:
s = """ s = """
3 3
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) ...@@ -17,3 +17,12 @@ print sorted(s1 & s2)
print sorted(s1 | s2) print sorted(s1 | s2)
print len(set(range(5))) 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