寻找未被占用的小阵列中的空间

时间:2015-05-06 23:26:09

标签: c arrays

  

您将获得一个包含8个单元格的数组。您还会获得该数组的两个随机索引,例如A和B.您如何找到一个不是数组中A或B索引的单元格?

2 个答案:

答案 0 :(得分:1)

如果你开始假设某个E的公式看起来像E(A, B)&7,那么你可以搜索最小化操作次数的E.

这种方法找到了一个解决方案:(A|1)^(B|2)(它有一个很好的属性,&7是不必要的!)

对于所有0< = A,B< = 7,我们可以检查这与A和B的不同。

for A in xrange(8):
    for B in xrange(8):
        r = (A|1)^(B|2)
        print A, B, r
        assert r != A and r != B

很容易看出表达式是如何工作的:最低位总是与B的最低位不同,而第二低位总是与A的第二低位不同。

这里是搜索E的代码。它是一个小型堆栈机器,可以尝试每个合法的操作组合。在它运行时偶尔打印反例,并定期显示所有工作表达式。

import random

def hash_ok(ops):
    h = make_hash(ops)
    for i in xrange(8):
        for j in xrange(8):
            try:
                r = h(i, j)
            except Exception as e:
                return False, '%d, %d: %s -> %s' % (i, j, ops, e)
            if r == i or r == j:
                return False, '%d, %d: %s -> %d' % (i, j, ops, r)
    return True, None

ops = [
  ('a', 0, 1), ('b', 0, 1), ('+', 2, 1), ('-', 2, 1), ('*', 2, 1), ('/', 2, 1), ('%', 2, 1),
  ('|', 2, 1), ('&', 2, 1), ('^', 2, 1), ('~', 1, 1), ('neg', 1, 1), ('<<', 2, 1), ('>>', 2, 1)] + [
    (str(n), 0, 1) for n in xrange(0, 3)]

op_by_arity = {0: [], 1: [], 2: []}
arity = dict()

for op, a, n in ops:
    op_by_arity[a].append((op, n))
    arity[op] = a

def print_ops(ops):
    s = []
    for o in ops:
        if arity[o] == 0:
            s.append(o)
        elif arity[o] == 1:
            s.append('%s(%s)' % (o, s.pop()))
        else:
            y, x = s.pop(), s.pop()
            s.append('(%s %s %s)' % (x, o, y))
    return s[0]

print op_by_arity

def make_hash(ops):
    def f(a, b):
        s = []
        for o in ops:
            if o == 'a':
                s.append(a)
            elif o=='b': 
                s.append(b)
            elif o=='>>':
                y, x = s.pop(), s.pop()
                s.append(x>>y)
            elif o=='<<':
                y, x = s.pop(), s.pop()
                s.append(x<<y)
            elif o=='+':
                s.append(s.pop()+s.pop())
            elif o=='-':
                s.append(-(s.pop()-s.pop()))
            elif o=='*':
                s.append(s.pop()*s.pop())
            elif o=='/':
                y, x = s.pop(), s.pop()
                s.append(x//y)
            elif o=='%':
                y, x = s.pop(), s.pop()
                s.append(x%y)
            elif o=='|':
                s.append(s.pop()|s.pop())
            elif o=='&':
                s.append(s.pop()&s.pop())
            elif o=='^':
                s.append(s.pop()^s.pop())
            elif o=='~':
                s.append(~s.pop())
            elif o=='neg':
                s.append(-s.pop())
            elif o >= '0' and o <= '9':
                s.append(int(o))
            elif o[0] == '-':
                s.append(int(o))
            else:
                raise Exception('bogus op %s' % o)
        assert len(s) == 1
        return (s[0] % 8)
    return f

def enumerate_ops(n, s):
    if n == 0:
        if s == 1:
            yield []
        return
    for a, aops in op_by_arity.iteritems():
        if a > s:
            continue
        for op, add in aops:
            for seq in enumerate_ops(n - 1, s - a + add):
                yield [op] + seq

winners = []

for i, ops in enumerate(enumerate_ops(7, 0)):
    ok, err = hash_ok(ops)
    if ok:
        print print_ops(ops)
        winners.append(ops)
    if random.randrange(100000) == 1:
        print err
    if i % 1000000 == 0:
        for w in winners:
            print print_ops(w)

print

for w in winners:
    print print_ops(w)

答案 1 :(得分:0)

你可以循环遍历数组并输入第一个不是A或B的索引中的值。

for (int i = 0; i < 8; ++i)
    if (i != A && i != B)
    {
        array[i] = value_to_input;
        break;
    }