Problem:


Problem C: Leaky Cryptography

The ACM ICPC judges are very careful about not leaking their problems, and all communications are encrypted. However, one does sometimes make mistakes, like using too weak an
encryption scheme. Here is an example of that.

The encryption chosen was very simple: encrypt each chunk of the input by flipping some bits
according to a shared key. To provide reasonable security, the size of both chunk and key is 32
bits.

That is, suppose the input was a sequence of m 32-bit integers.

                   N1      N2    N3 ... Nm

After encoding with the key K it becomes the following sequence of m 32-bit integers.

(N1 &and; K) (N2 &and; K) (N3 &and; K) ... (Nm &and; K)

where (a &and; b) is the bitwise exclusive or of a and b.

Exclusive or is the logical operator which is 1 when only one of its operands is 1, and 0 otherwise.
Here is its definition for 1-bit integers.

     0 &oplus; 0 = 0      0 &oplus; 1 = 1
     1 &oplus; 0 = 1      1 &oplus; 1 =0

As you can see, it is identical to addition modulo 2. For two 32-bit integers a and b, their bitwise
exclusive or a &and; b is defined as follows, using their binary representations, composed of 0's and 1's.

 a &and; b = a31 ... a1a0 &and; b31 ... b1b0 = c31 ... c1c0

where

   ci = ai &oplus; bi (i = 0, 1, ... , 31).

For instance, using binary notation, 11010110 &and; 01010101 = 10100011, or using hexadecimal, 

d6 &and; 55 = a3.

Since this kind of encryption is notoriously weak to statistical attacks, the message has to be
compressed in advance, so that it has no statistical regularity. We suppose that N1 N2 ... Nm
is already in compressed form.

However, the trouble is that the compression algorithm itself introduces some form of regularity:
after every 8 integers of compressed data, it inserts a checksum, the sum of these integers. That
is, in the above input, N9 = &sum;8i=1 Ni = N1 + ... + N8, where additions are modulo 232.

Luckily, you could intercept a communication between the judges. Maybe it contains a problem for the finals!

As you are very clever, you have certainly seen that you can easily find the lowest bit of the key,
denoted by K0. On the one hand, if K0 = 1, then after encoding, the lowest bit of &sum;8i=1 Ni &and; K is unchanged, as K0 is added an even number of times, but the lowest bit of N9 &and; K is changed,
so they shall differ. On the other hand, if K0 = 0, then after encoding, the lowest bit of &sum;8i=1 Ni &and; K shall still be identical to the lowest bit of N9 &and; K, as they do not change. For instance, if the lowest bits after encoding are 1 1 1 1 1 1 1 1 1 then K0 must be 1, but if
they are 1 1 1 1 1 1 1 0 1 then K0 must be 0.

So far, so good. Can you do better?

You should find the key used for encoding.

Input

The input starts with a line containing only a positive integer S, indicating the number of
datasets in the input. S is no more than 1000.

It is followed by S datasets. Each dataset is composed of nine 32-bit integers corresponding
to the first nine chunks of a communication. They are written in hexadecimal notation, using
digits ‘0’ to ‘9’ and lowercase letters ‘a’ to ‘f’, and with no leading zeros. They are separated
by a space or a newline. Each dataset is ended by a newline.

Output

For each dataset you should output the key used for encoding. Each key shall appear alone on
its line, and be written in hexadecimal notation, using digits ‘0’ to ‘9’ and lowercase letters ‘a’
to ‘f’, and with no leading zeros.

Sample Input

8
1 1 1 1 1 1 1 1 8
3 2 3 2 3 2 3 2 6
3 4 4 7 7 b a 2 2e
e1 13 ce 28 ca 6 ab 46 a6d
b08 49e2 6128 f27 8cf2 bc50 7380 7fe1 723b
4eba eb4 a352 fd14 6ac1 eed1 dd06 bb83 392bc
ef593c08 847e522f 74c02b9c 26f3a4e1 e2720a01 6fe66007
7a4e96ad 6ee5cef6 3853cd88
60202fb8 757d6d66 9c3a9525 fbcd7983 82b9571c ddc54bab 853e52da
22047c88 e5524401

Output for the Sample Input

0
2
6
1c6
4924afc7
ffff95c5
546991d
901c4a16



Sample input:
8
1 1 1 1 1 1 1 1 8
3 2 3 2 3 2 3 2 6
3 4 4 7 7 b a 2 2e
e1 13 ce 28 ca 6 ab 46 a6d
b08 49e2 6128 f27 8cf2 bc50 7380 7fe1 723b
4eba eb4 a352 fd14 6ac1 eed1 dd06 bb83 392bc
ef593c08 847e522f 74c02b9c 26f3a4e1 e2720a01 6fe66007
7a4e96ad 6ee5cef6 3853cd88
60202fb8 757d6d66 9c3a9525 fbcd7983 82b9571c ddc54bab 853e52da
22047c88 e5524401


Sample output:
0
2
6
1c6
4924afc7
ffff95c5
546991d
901c4a16

Submission status: Wrong Answer

Solution code:
n = int(raw_input())
for loop in xrange(n):
    a = []
    while len(a) < 8:
        a += map(lambda i:int(i,16),raw_input().split())
    key = 0
    
    for i in xrange(32):
        s = sum(a[j]^key for j in xrange(8))
        if s&(1 << (i+1)-1) != (a[-1]^key)&(1 << (i+1)-1): key |= (1 << i)
    print "%x"%key

Submission status: Accepted

Solution code:
#!/usr/bin/env python

import sys
import math
import itertools as it
from collections import deque

sys.setrecursionlimit(10000000)

N = input()

for i in range(N):
    lst = []
    while len(lst) < 9:
        lst_ = raw_input().split()
        for S in lst_:
            lst.append(int(S, 16))
    res = lst[8]
    lst = lst[:8]
    diff = (sum(lst) - res) % (1 << 32)
    diff_lst = []
    for i in range(32):
        D = 0
        for j in lst:
            if j & (1 << i) == 0:
                D += (1 << i)
            else:
                D -= (1 << i)
        if res & (1 << i) == 0:
            D -= (1 << i)
        else:
            D += (1 << i)
        D %= (1 << 32)
        diff_lst.append([D, 1 << i])
    L1 = [[diff, 0]]
    for i in range(16):
        P = diff_lst[i]
        L = []
        for p in L1:
            L.append([(p[0] + P[0]) % (1 << 32), p[1] + P[1]])
        L1 += L
    L2 = [[0, 0]]
    for i in range(16, 32):
        P = diff_lst[i]
        L = []
        for p in L2:
            L.append([(p[0] + P[0]) % (1 << 32), p[1] + P[1]])
        L2 += L
    L1.sort()
    L2.sort()
    if L1[0][0] == 0:
        print hex(L1[0][1])[2:]
        continue
    pos = len(L2) - 1
    for p in L1:
        while p[0] + L2[pos][0] > (1 << 32):
            pos -= 1
        if p[0] + L2[pos][0] == (1 << 32):
            print hex(p[1] + L2[pos][1])[2:]
            break

Submission status: Accepted

Solution code:
#!/usr/bin/env python

import sys
import math
import itertools as it
from collections import deque

sys.setrecursionlimit(10000000)

N = input()

for i in range(N):
    lst = []
    while len(lst) < 9:
        lst_ = raw_input().split()
        for S in lst_:
            lst.append(int(S, 16))
    res = lst[8]
    lst = lst[:8]
    diff = (sum(lst) - res) % (1 << 32)
    diff_lst = []
    for i in range(32):
        D = 0
        for j in lst:
            if j & (1 << i) == 0:
                D += (1 << i)
            else:
                D -= (1 << i)
        if res & (1 << i) == 0:
            D -= (1 << i)
        else:
            D += (1 << i)
        D %= (1 << 32)
        diff_lst.append((D, 1 << i))
    L1 = [(diff, 0)]
    for i in range(16):
        P = diff_lst[i]
        L = []
        for p in L1:
            L.append(((p[0] + P[0]) % (1 << 32), p[1] + P[1]))
        L1 += L
    L2 = [[0, 0]]
    for i in range(16, 32):
        P = diff_lst[i]
        L = []
        for p in L2:
            L.append(((p[0] + P[0]) % (1 << 32), p[1] + P[1]))
        L2 += L
    L1.sort()
    L2.sort()
    if L1[0][0] == 0:
        print hex(L1[0][1])[2:]
        continue
    pos = len(L2) - 1
    for p in L1:
        while p[0] + L2[pos][0] > (1 << 32):
            pos -= 1
        if p[0] + L2[pos][0] == (1 << 32):
            print hex(p[1] + L2[pos][1])[2:]
            break

Submission status: Accepted

Solution code:
#!/usr/bin/env python

import sys
import math
import itertools as it
from collections import deque

sys.setrecursionlimit(10000000)

N = input()

for i in range(N):
    lst = []
    while len(lst) < 9:
        lst_ = raw_input().split()
        for S in lst_:
            lst.append(int(S, 16))
    res = lst[8]
    lst = lst[:8]
    diff = (sum(lst) - res) % (1 << 32)
    diff_lst = []
    for i in range(32):
        D = 0
        for j in lst + [((1 << 32) - 1) ^ res]:
            if j & (1 << i) == 0:
                D += (1 << i)
            else:
                D -= (1 << i)
        D %= (1 << 32)
        diff_lst.append((D, 1 << i))
    L1 = [(diff, 0)]
    for i in range(16):
        P = diff_lst[i]
        L = []
        for p in L1:
            L.append(((p[0] + P[0]) % (1 << 32), p[1] + P[1]))
        L1 += L
    L2 = [[0, 0]]
    for i in range(16, 32):
        P = diff_lst[i]
        L = []
        for p in L2:
            L.append(((p[0] + P[0]) % (1 << 32), p[1] + P[1]))
        L2 += L
    L1.sort()
    L2.sort()
    if L1[0][0] == 0:
        print hex(L1[0][1])[2:]
        continue
    pos = len(L2) - 1
    for p in L1:
        while p[0] + L2[pos][0] > (1 << 32):
            pos -= 1
        if p[0] + L2[pos][0] == (1 << 32):
            print hex(p[1] + L2[pos][1])[2:]
            break

Submission status: Accepted

Solution code:
n = int(raw_input())
for loop in xrange(n):
    a = []
    while len(a) < 9:
        a += map(lambda i:int(i,16),raw_input().split())
    key = 0
    for i in xrange(32):
        s = sum(a[j]^key for j in xrange(8))
        if s&(1 << (i+1)-1) != (a[-1]^key)&(1 << (i+1)-1): key |= (1 << i)
    print "%x"%key

Submission status: Accepted

Solution code:
n = int(raw_input())
for loop in xrange(n):
    a = []
    while len(a) < 9:
        a += map(lambda i:int(i,16),raw_input().split())
    key = 0
    for i in xrange(32):
        s = sum(a[j]^key for j in xrange(8))
        if (s^a[-1]^key) & (1 << (i+1)-1) != 0: key |= (1 << i)
    print "%x"%key

Submission status: Accepted

Solution code:
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 998244353
dd = [(0,-1),(1,0),(0,1),(-1,0)]
ddn = [(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,-1),(-1,0),(-1,1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    rr = []
    n = I()
    ni = 0

    while ni < n:
        ni += 1
        a = []
        while len(a) < 9:
            a += LS()
        t = int(a[-1],16)
        a = list(map(lambda x: int(x,16), a[:-1]))
        r = 0
        for i in range(32):
            ii = 2**i
            iii = 2**(i+1)
            b = t & ii
            c = 0
            for d in a:
                c += d^r
            if (c & ii) != b:
                r += ii

        rr.append('{:0x}'.format(r))

    return '\n'.join(map(str, rr))


print(main())