Runtime Error на удаленной среде при абсурдных обстоятельствах
На Timus.org решал задачи, код отсылал на компиляцию Python3.8 x64 и в 1 тривиальной задаче постоянно ловил Runtime Error на 10 тесте. Заключил основное тело программы в try: <...> except ZeroDivisionError: print(0)(чтобы заменить runtime error на wrong answer и заключая разные куски кода, найти проблемный) и стал ловить Runtime error на 8 тесте. Как заключение кода в try: <...> except ZeroDivisionError: print(0) , где <...> заведомо рабочий код(проходит тесты 8 и 9) может вызывать Runtime error, там где раньше он исправно работал
#Получаем простое число по его порядковому номеру где порядок числа 2 == 0
smpllst=[2,3,5,7,11]
def simpleNum(a):
global smpllst
if a>len(smpllst):
for i in range(len(smpllst),a):
nmbr=smpllst[len(smpllst)-1]+1
smpl=False
while not smpl:
nmbr+=1
smpl=True
for u in smpllst:
if (nmbr%u)==0:
smpl=False
break
smpllst+=[nmbr]
return smpllst[a]
#Убираем еденички из списка
def rmv1(lst):
i=0
while i<len(lst):
if lst[i]==1:
lst.pop(i)
else:
i+=1
#считываем длину последовательности перестановок(1строка),считываем в rdr саму последовательность
longitude=int(input())
rdr2=tuple(map(int,input().split()))
rdr=[]
for i in range(longitude): rdr+=[rdr2[i]]
#в combine записываем длину всех изолированных перестановок
cmbn=[]
for i in range(len(rdr)):
if rdr[i]!=0:
lp=1
pntr=rdr[i]
while i!=pntr-1:
lp+=1
tmp=rdr[pntr-1]
rdr[pntr-1]=0
pntr=tmp
cmbn+=[lp]
#Ищем наименьший общий делитель для всех малый перестановок;пишем его в rslt
rmv1(cmbn)
rslt=1
q=0
while len(cmbn)>0:
dvsr=simpleNum(q)
have1=False
#Техномагия: c try except runtime error на 8 тесте,без них на 10
#Пытаюсь превратить runtime error в wrong answer
try:
for i in cmbn:
if (i % dvsr)==0:
have1=True
break
if have1:
rslt=rslt*dvsr
for i in range(len(cmbn)):
if (cmbn[i]%dvsr)==0 : cmbn[i]=cmbn[i]//dvsr
rmv1(cmbn)
except ZeroDivisionError:
print(-1)
else:
q+=1
#выводим степень перестановки(сколько раз её нужно применять на саму себя, чтобы получить исходную последовательность)
print(rslt)
Timus.org задача 1024(школьная)
Ответы (1 шт):
Я проверил вашу программу на таком входе:
41 2 1 5 3 4 10 6 7 8 9 17 11 12 13 14 15 16 28 18 19 20 21 22 23 24 25 26 27 41 29 30 31 32 33 34 35 36 37 38 39 40
Результат:
Traceback (most recent call last): File "original.py", line 49, in <module> dvsr=simpleNum(q) File "original.py", line 17, in simpleNum return smpllst[a] IndexError: list index out of range
Ситуацию можно улучшить такой правкой:
< if a>len(smpllst):
< for i in range(len(smpllst),a):
--------
> if a>=len(smpllst):
> for i in range(len(smpllst),a+1):
P.S. Вычисление НОК не требует разложения числа на простые множители. Через НОД проще:
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
def lcm(seq):
lcm = 1
for v in seq:
lcm = lcm * v // gcd(lcm, v)
return lcm
В Питоне 3.9 есть встроенная функция math.lcm, но у вас предыдущий Питон.
Длины циклов будет проще считать если перестановку из диапазона [1, N] перевести в [0, N-1].
Всё вместе:
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
def lcm(seq):
lcm = 1
for v in seq:
lcm = lcm * v // gcd(lcm, v)
return lcm
def loops(p):
f = [False] * len(p)
for i in range(len(p)):
if not f[i]:
c = 0
while not f[i]:
c += 1
f[i] = True
i = p[i]
yield c
input()
p = [int(w) - 1 for w in input().split()]
print(lcm(loops(p)))