sub r { my %h = ( I=>1, V=>5, X=>10, L=>50, C=>100, D=>500, M=>1000 ); return $h{$_}; } print "$_: ", 0+r(), "\n" for (qw(I V X L C D M)); #### I: 1 V: 5 X: 10 L: 50 C: 100 D: 500 M: 1000 #### sub r {%h=(I,1,V,5,X,10,L,50,C,100,D,500,M,1000);$h{$_}} sub r {M1000D500C100L50X10V5I1=~$_;$'} sub r {M999D499C99L49X9V4I=~$_+$'} #### sub r {5**y/VLD//.E.(3*/M/+2*/C|D/+/X|L/)} sub r {1 .E.~-ord()*41%52%5>>y/VLD//} sub r {5**y/VLD//.E.ord()x3%75%50%4} sub r {1 .E.(72^ord)*5/7%5>>y/VLD//} sub r {5**y/VLD//.E.(42^88*ord)%5} sub r {1 .E.(3^77%ord)%7>>y/VLD//} #### sub r {10**(7&69303333/ord)%9995} sub r {10**(7&5045e8/ord)%2857} # needs 64-bit Perl sub r {IXCMVLD=~$_;"1E@-"%9995} sub r {XCMVLD=~$_;"1E@+"%9995} # Grimy improvement #### 10**(205558%ord(r)%7)%9995 # Python hash(r+"magicstrng")%1001 # Python (finding magicstrng is the subject of this node!) VLD=~$_*5+IXCM=~$_."E@-" # Perl 10**(7&5045e8/ord)%2857 # Perl (64-bit) IXCMVLD=~$_;"1E@-"%9995 # Perl XCMVLD=~$_;"1E@+"%9995 # Perl (update: Grimy improvement) uppp&md5_hex$_.PQcUv # Perl (needs Digest::MD5 module) 10**(494254%r/9)%4999 # Ruby (no need for explicit ord in this game) md5($r.magicstrng) # PHP (finding magicstrng is an unsolved problem) md5($r.PQcUv)&uppp # PHP wins due to superb mf properties of md5 #### import time print time.time(), time.clock() for q0 in range(1, 128): for q1 in range(1, 128): for q2 in range(1, 128): for q3 in range(1, 128): for q4 in range(1, 128): for q5 in range(1, 128): for q6 in range(1, 128): for q7 in range(1, 128): for q8 in range(1, 128): for q9 in range(1, 128): magic = chr(q0)+chr(q1)+chr(q2)+chr(q3)+chr(q4)+chr(q5)+chr(q6)+chr(q7)+chr(q8)+chr(q9) m = hash("M" + magic) % 1001 if m != 1000: continue d = hash("D" + magic) % 1001 if d != 500: continue c = hash("C" + magic) % 1001 if c != 100: continue l = hash("L" + magic) % 1001 if l != 50: continue x = hash("X" + magic) % 1001 if x != 10: continue v = hash("V" + magic) % 1001 if v != 5: continue i = hash("I" + magic) % 1001 if i != 1: continue print "bingo!", q0, q1, q2, q3, q4, q5, q6, q7, q8, q9 print time.time(), time.clock() #### #include #include // Python hash() function. Assumes 32-bit int. // Derived from string_hash() in stringobject.c in Python 2.5.1 sources. static int py_hash(const char* a, int size) { int len = size; const unsigned char* p = (unsigned char*)a; int x = *p << 7; while (--len >= 0) x = (1000003 * x) ^ *p++; x ^= size; if (x == -1) x = -2; return x; } // Simulate python modulo operator. Assumes mod is positive. static int py_mod(int j, int mod) { int ret; if (j >= 0) { ret = j % mod; } else { ret = j - (j / mod) * mod; if (ret) ret += mod; } return ret; } int main() { int q0, q1, q2, q3, q4, q5, q6, q7, q8, q9; int m, d, c, l, x, v, i; char magic[16]; time_t tstart = time(NULL); clock_t cstart = clock(); time_t tend; clock_t cend; if (sizeof(int) != 4) { fprintf(stderr, "oops sizeof int != 4\n"); return 1; } for (q0 = 1; q0 < 128; ++q0) { magic[1] = q0; for (q1 = 1; q1 < 128; ++q1) { magic[2] = q1; for (q2 = 1; q2 < 128; ++q2) { magic[3] = q2; for (q3 = 1; q3 < 128; ++q3) { magic[4] = q3; for (q4 = 1; q4 < 128; ++q4) { magic[5] = q4; for (q5 = 1; q5 < 128; ++q5) { magic[6] = q5; for (q6 = 1; q6 < 128; ++q6) { magic[7] = q6; for (q7 = 1; q7 < 128; ++q7) { magic[8] = q7; for (q8 = 1; q8 < 128; ++q8) { magic[9] = q8; for (q9 = 1; q9 < 128; ++q9) { magic[10] = q9; magic[0] = 'M'; m = py_mod(py_hash(magic, 11), 1001); if (m != 1000) continue; magic[0] = 'D'; d = py_mod(py_hash(magic, 11), 1001); if (d != 500) continue; magic[0] = 'C'; c = py_mod(py_hash(magic, 11), 1001); if (c != 100) continue; magic[0] = 'L'; l = py_mod(py_hash(magic, 11), 1001); if (l != 50) continue; magic[0] = 'X'; x = py_mod(py_hash(magic, 11), 1001); if (x != 10) continue; magic[0] = 'V'; v = py_mod(py_hash(magic, 11), 1001); if (v != 5) continue; magic[0] = 'I'; i = py_mod(py_hash(magic, 11), 1001); if (i != 1) continue; printf("bingo! %d %d %d %d %d %d %d %d %d %d\n", q0, q1, q2, q3, q4, q5, q6, q7, q8, q9); } } } } } } } } } } tend = time(NULL); cend = clock(); printf("(wall clock time:%ld secs, cpu time:%.2f units)\n", (long) (difftime(tend, tstart)+0.5), (double) (cend-cstart) / (double)CLOCKS_PER_SEC); return 0; } #### #include #include #include #include #define H_PRIME 1000003 // Most unlikely to get this many hits in a single call of the inner loop function. #define MAX_HITS 64 // my_m128_t mimics Intel __m128i type (which will be used later) typedef struct my_m128_t my_m128_t; struct my_m128_t { short m128i_i16[8]; }; // the inner loop function (lives in a separate file) extern "C" int inner( int startval, int endval, int m2, int d2, int c2, int l2, int x2, int v2, int i2, my_m128_t* ps ); void do_one(int q0, int sv1, int ev1, int sv2, int ev2, int sv3, int ev3) { time_t tstart = time(NULL); clock_t cstart = clock(); time_t tend; clock_t cend; my_m128_t soln[MAX_HITS]; int m1, m2; int m_char = 'M'; int m0 = ( ( H_PRIME * (m_char << 7) ) ^ m_char ) * H_PRIME; int d1, d2; int d_char = 'D'; int d0 = ( ( H_PRIME * (d_char << 7) ) ^ d_char ) * H_PRIME; int c1, c2; int c_char = 'C'; int c0 = ( ( H_PRIME * (c_char << 7) ) ^ c_char ) * H_PRIME; int l1, l2; int l_char = 'L'; int l0 = ( ( H_PRIME * (l_char << 7) ) ^ l_char ) * H_PRIME; int x1, x2; int x_char = 'X'; int x0 = ( ( H_PRIME * (x_char << 7) ) ^ x_char ) * H_PRIME; int v1, v2; int v_char = 'V'; int v0 = ( ( H_PRIME * (v_char << 7) ) ^ v_char ) * H_PRIME; int i1, i2; int i_char = 'I'; int i0 = ( ( H_PRIME * (i_char << 7) ) ^ i_char ) * H_PRIME; int q1, q2; int mm0 = (m0 ^ q0) * H_PRIME; int dd0 = (d0 ^ q0) * H_PRIME; int cc0 = (c0 ^ q0) * H_PRIME; int ll0 = (l0 ^ q0) * H_PRIME; int xx0 = (x0 ^ q0) * H_PRIME; int vv0 = (v0 ^ q0) * H_PRIME; int ii0 = (i0 ^ q0) * H_PRIME; fprintf(stderr, "%d: sv1=%d ev1=%d sv2=%d ev2=%d sv3=%d ev3=%d:\n", q0, sv1, ev1, sv2, ev2, sv3, ev3); // We ignore 0, 10, 13 because these three require escaping in Python. for (q1 = sv1; q1 < ev1; ++q1) { if (q1 == 10 || q1 == 13) continue; m1 = (mm0 ^ q1) * H_PRIME; d1 = (dd0 ^ q1) * H_PRIME; c1 = (cc0 ^ q1) * H_PRIME; l1 = (ll0 ^ q1) * H_PRIME; x1 = (xx0 ^ q1) * H_PRIME; v1 = (vv0 ^ q1) * H_PRIME; i1 = (ii0 ^ q1) * H_PRIME; for (q2 = sv2; q2 < ev2; ++q2) { if (q2 == 10 || q2 == 13) continue; m2 = (m1 ^ q2) * H_PRIME; d2 = (d1 ^ q2) * H_PRIME; c2 = (c1 ^ q2) * H_PRIME; l2 = (l1 ^ q2) * H_PRIME; x2 = (x1 ^ q2) * H_PRIME; v2 = (v1 ^ q2) * H_PRIME; i2 = (i1 ^ q2) * H_PRIME; int isoln = inner(sv3, ev3, m2, d2, c2, l2, x2, v2, i2, soln); if (isoln > 0) { int k; for (k = 0; k < isoln; ++k) { fprintf(stderr, "%d %d %d %hd %hd %hd %hd %hd %hd %hd\n", q0, q1, q2, soln[k].m128i_i16[0], soln[k].m128i_i16[1], soln[k].m128i_i16[2], soln[k].m128i_i16[3], soln[k].m128i_i16[4], soln[k].m128i_i16[5], soln[k].m128i_i16[6]); } } } } tend = time(NULL); cend = clock(); fprintf(stderr, "(wall clock time:%ld secs, cpu time:%.2f units)\n", (long) (difftime(tend, tstart)+0.5), (double) (cend-cstart) / (double)CLOCKS_PER_SEC); } int main(int argc, char* argv[]) { int sv0, sv1, sv2, sv3, ev1, ev2, ev3; if (argc != 8) { fprintf(stderr, "usage: prog sv0 sv1 ev1 sv2 ev2 sv3 ev3\n"); return 1; } sv0 = atoi(argv[1]); sv1 = atoi(argv[2]); ev1 = atoi(argv[3]); sv2 = atoi(argv[4]); ev2 = atoi(argv[5]); sv3 = atoi(argv[6]); ev3 = atoi(argv[7]); do_one(sv0, sv1, ev1, sv2, ev2, sv3, ev3); return 0; } #### #define H_PRIME 1000003 #define HASH_LEN 11 // my_m128_t mimics Intel __m128i type typedef struct my_m128_t my_m128_t; struct my_m128_t { short m128i_i16[8]; }; // Simulate python modulo operator. Assumes mod is positive. static int py_mod(int j, int mod) { int ret; if (j >= 0) { ret = j % mod; } else { ret = j - (j / mod) * mod; if (ret) ret += mod; } return ret; } // Apart from: // -1 % 1001 == 1000 // -2 % 1002 == 1000 // both -1 and -2 can never match any of 1000, 500, ..., 1 // Thus don't worry about the Python hash conversion from -1 to -2, except for M int inner( int startval, int endval, int m2, int d2, int c2, int l2, int x2, int v2, int i2, my_m128_t* ps) { int m, d, c, l, x, v, i; int m3, m4, m5, m6, m7, m8, m9; int d3, d4, d5, d6, d7, d8, d9; int c3, c4, c5, c6, c7, c8, c9; int l3, l4, l5, l6, l7, l8, l9; int x3, x4, x5, x6, x7, x8, x9; int v3, v4, v5, v6, v7, v8, v9; int i3, i4, i5, i6, i7, i8, i9; int q3, q4, q5, q6, q7, q8, q9; int iret = 0; for (q3 = startval; q3 < endval; ++q3) { if (q3 == 10 || q3 == 13) continue; m3 = (m2 ^ q3) * H_PRIME; d3 = (d2 ^ q3) * H_PRIME; c3 = (c2 ^ q3) * H_PRIME; l3 = (l2 ^ q3) * H_PRIME; x3 = (x2 ^ q3) * H_PRIME; v3 = (v2 ^ q3) * H_PRIME; i3 = (i2 ^ q3) * H_PRIME; for (q4 = 1; q4 < 128; ++q4) { if (q4 == 10 || q4 == 13) continue; m4 = (m3 ^ q4) * H_PRIME; d4 = (d3 ^ q4) * H_PRIME; c4 = (c3 ^ q4) * H_PRIME; l4 = (l3 ^ q4) * H_PRIME; x4 = (x3 ^ q4) * H_PRIME; v4 = (v3 ^ q4) * H_PRIME; i4 = (i3 ^ q4) * H_PRIME; for (q5 = 1; q5 < 128; ++q5) { if (q5 == 10 || q5 == 13) continue; m5 = (m4 ^ q5) * H_PRIME; d5 = (d4 ^ q5) * H_PRIME; c5 = (c4 ^ q5) * H_PRIME; l5 = (l4 ^ q5) * H_PRIME; x5 = (x4 ^ q5) * H_PRIME; v5 = (v4 ^ q5) * H_PRIME; i5 = (i4 ^ q5) * H_PRIME; for (q6 = 1; q6 < 128; ++q6) { if (q6 == 10 || q6 == 13) continue; m6 = (m5 ^ q6) * H_PRIME; d6 = (d5 ^ q6) * H_PRIME; c6 = (c5 ^ q6) * H_PRIME; l6 = (l5 ^ q6) * H_PRIME; x6 = (x5 ^ q6) * H_PRIME; v6 = (v5 ^ q6) * H_PRIME; i6 = (i5 ^ q6) * H_PRIME; for (q7 = 1; q7 < 128; ++q7) { if (q7 == 10 || q7 == 13) continue; m7 = (m6 ^ q7) * H_PRIME; d7 = (d6 ^ q7) * H_PRIME; c7 = (c6 ^ q7) * H_PRIME; l7 = (l6 ^ q7) * H_PRIME; x7 = (x6 ^ q7) * H_PRIME; v7 = (v6 ^ q7) * H_PRIME; i7 = (i6 ^ q7) * H_PRIME; for (q8 = 1; q8 < 128; ++q8) { if (q8 == 10 || q8 == 13) continue; m8 = (m7 ^ q8) * H_PRIME; d8 = (d7 ^ q8) * H_PRIME; c8 = (c7 ^ q8) * H_PRIME; l8 = (l7 ^ q8) * H_PRIME; x8 = (x7 ^ q8) * H_PRIME; v8 = (v7 ^ q8) * H_PRIME; i8 = (i7 ^ q8) * H_PRIME; for (q9 = 1; q9 < 128; ++q9) { if (q9 == 10 || q9 == 13) continue; m9 = (m8 ^ q9) ^ HASH_LEN; if (m9 == -1) m9 = -2; m = py_mod(m9, 1001); if (m != 1000) continue; d9 = (d8 ^ q9) ^ HASH_LEN; d = py_mod(d9, 1001); if (d != 500) continue; c9 = (c8 ^ q9) ^ HASH_LEN; c = py_mod(c9, 1001); if (c != 100) continue; l9 = (l8 ^ q9) ^ HASH_LEN; l = py_mod(l9, 1001); if (l != 50) continue; x9 = (x8 ^ q9) ^ HASH_LEN; x = py_mod(x9, 1001); if (x != 10) continue; v9 = (v8 ^ q9) ^ HASH_LEN; v = py_mod(v9, 1001); if (v != 5) continue; i9 = (i8 ^ q9) ^ HASH_LEN; i = py_mod(i9, 1001); if (i != 1) continue; ps[iret].m128i_i16[0] = q3; ps[iret].m128i_i16[1] = q4; ps[iret].m128i_i16[2] = q5; ps[iret].m128i_i16[3] = q6; ps[iret].m128i_i16[4] = q7; ps[iret].m128i_i16[5] = q8; ps[iret].m128i_i16[6] = q9; ++iret; } } } } } } } return iret; } #### m3 = (m2 ^ q3) * H_PRIME; d3 = (d2 ^ q3) * H_PRIME; c3 = (c2 ^ q3) * H_PRIME; l3 = (l2 ^ q3) * H_PRIME; x3 = (x2 ^ q3) * H_PRIME; v3 = (v2 ^ q3) * H_PRIME; i3 = (i2 ^ q3) * H_PRIME;