2014-01-15 6 views
0

Итак, наш учитель дал нам задание найти три целых числа a, b c. Они находятся между 0 и 450 с использованием Python.Ошибка в цикле. (Поиск трех целых чисел)

а = с + 11, если б даже
а = 2с-129, если б нечетно

б = ас мод 2377

с = (Σ (б-7k) с к = 0 . тоже-1) +142 (Под ред я написал это неправильно был -149)

Я устал мой код, который выглядит следующим образом:.. (все еще новичок, я думаю, много мой код неправильно)

for a, b, c in range(0, 450): 
    if b % 2 == 0: 
     a = c + 11 
    else: 
     a = 2 * c - 129 
    b = (a * c) % 2377 
    c = sum(b - 7 * k for k in range(0, a - 1)) 

но я получаю ошибка:

for a, b, c in range(0, 450): 
TypeError: 'int' object is not iterable 

Что я делаю неправильно и как я могу его проверить каждый номер от 0 до 450?

+0

Что вы ожидаете, что делать в этом случае? Диапазон – Caramiriel

+2

(0,450) дает вам одно число, а не 3 одновременно. Я думаю, вам нужно повторить 1 значение (возможно, а) и проверить значение для 2 других. – njzk2

+1

Что @ njzk2 сказал. Есть более 91 миллиона комбинаций чисел в диапазоне 0..450. Это очень сложно проверить, поскольку вычисление 'c' связано с другим циклом. Лучше всего повторить одно число в диапазоне и вычислить два других из него, затем проверить, что все находятся в требуемом диапазоне и что вычисленное значение для третьего соответствует числу, с которого вы начали. Это 451 цикл вместо 91 миллиона. – Duncan

ответ

2

Вы должны гнездиться петли для грубой силы его, как вы пытаетесь:

for a in range(451): # range(450) excludes 450 
    for b in range(451): 
     for c in range(451): 
      ... 

Это очень очевидно, O (п), но если вы хотите быстро и грязный ответ, я думаю, он будет работать — всего 91 миллион петель, в худшем случае.

+0

Более 91 миллиона: помните, что вычисление правильного значения для 'c' составляет в среднем 225 итераций. Так что это 21 000 миллионов раз вокруг этого конкретного цикла, если некоторые из петель не пропущены. – Duncan

+0

А, так что нет грубой силы. Форматирование уравнений было немного грязным, поэтому я просто застеклял это до «почему я не могу распаковать 3 номера из 1 числа». –

+0

n4 фактически из-за вычисления c – njzk2

3
import itertools 

for b, c in itertools.product(*[range(450)]*2): 
    if b % 2 == 0: 
     a = c + 11 
    else: 
     a = 2 * c - 129 
    derived_b = (a * c) % 2377 
    derived_c = sum(b - 7 * k for k in range(0, a - 1)) 

    if derived_b == b and derived_c == c: 
     print a, b, c 
3

Ответов Ники T и Эрик, надеюсь, помогли вам решить проблему с Перебор значениями a, b и c. Хотелось бы также отметить, что то, как вы приближаетесь к этой проблеме, не сработает. Какой смысл повторять различные значения a, если вы собираетесь назначить a чему-то в любом случае на каждой итерации цикла? А также для b и c. Более подходящий подход включает , проверяющий, что любая заданная тройка (a, b, c)удовлетворяет условиям, указанным в задании. Например:

from itertools import product, tee 

def test(a, b, c): 
    flags = {'a': False, 
      'b': False, 
      'c': False} 
    if (b % 2 == 0 and a == c+11) or (b % 2 == 1 and a == 2*c-129): 
     flags['a'] = True 
    if b == (a * c) % 2377: 
     flags['b'] = True 
    if c == sum(b - 7*k for k in range(a-1)) - 149: 
     flags['c'] = True 
    return all(flags.values()) # True if zero flags are False 

def run_tests(): 
    # iterate over all combinations of a=0..450, b=0..450, c=0..450 
    for a, b, c in product(*tee(range(451), 3)): 
     if test(a, b, c): 
      return (a, b, c) 

print(run_tests()) 

Примечание: Это медленное решение. Очевидно, что тот, который делает меньше циклов, например, в ответ glglgl, или комментарий Дункана, является благоприятным. Это действительно больше для иллюстративных целей, чем что-либо.

+0

Что такое «продукт» и «тройник»? – Zahand

+0

@ Zahand См. [Соответствующую документацию] (http://docs.python.org/2/library/itertools.html). – glglgl

1

Материал с [0, 450] - это как подсказка.

Фактически, ваши переменные соединены вместе. Вы можете немедленно устранить по крайней мере одну петлю напрямую:

for b in range(0, 451): 
    for c in range(0, 451): 
     if b % 2: # odd 
      a = 2 * c - 129 
     else: 
      a = c + 11 
     if b != (a * c) % 2377: continue # test failed 
     if c != sum(b - 7 * k for k in range(a)): continue # test failed as well 
     print a, b, c 

должен выполнить эту работу.

0

Я не буду публиковать полный код (в конце концов, это домашнее задание), но вы можете устранить две из внешних петель. Это проще всего, если вы перебираете c.

Вы код должен выглядеть примерно так:

for c in range(451): 
    # calculate a assuming b is even 
    # calculate b 
    # if b is even and a and b are in range: 
     # calculate what c should be and compare against what it is 
    # calculate a assuming b is odd 
    # calculate b 
    # if b is odd and a and b are in range: 
     # calculate what c should be and compare against what it is 

дополнительного кредит для устранения дублирования кода для вычисления c

0
a = c + 11 if b is even 
a = 2c-129 if b is odd 
b = ac mod 2377 

c = (∑(b-7k) from k = 0 to a-1) +142 

Это дает сильную связь между всем 3 номером

Учитывая значение a, существует 2 значения c (a-11 или (a+129)/2), которые, в свою очередь, дают 2 значения для b (ac mod 2377 для обоих значений c, обусловленных нечетностью результата для b), которое, в свою очередь, применяется в формуле для проверки c.

Общая сложность для этого - o (n^2) из-за формулы для вычисления c.

Вот пример реализации:

for a in xrange(451): 
    c_even = a - 11 
    b = (a*c_even) % 2377 
    if b % 2 == 0: 
     c = sum(b - 7 * k for k in range(a)) + 142 
     if c == c_even: 
      print (a, b, c) 
      break 
    c_odd = (a+129)/2 
    b = (a*c_odd) % 2377 
    if b % 2 == 1: 
     c = sum(b - 7 * k for k in range(a)) + 142 
     if c == c_odd: 
      print (a, b, c) 
      break 
Смежные вопросы