Помогите пожалуйста перевести код с pascal на python
Это код на pascal:
program ChckMonoton;
var
s: string;
function FuncIsCorrect(s: string): boolean; // функция, проверяющая правильность записи заданной в векторном виде БФ
var i, n: byte;
begin
i := 1;
n := length(s);
if s <> '' then begin // векторная запись должна быть непустой
if n and (n - 1) = 0 then begin // проверяем, является ли число цифр в записи степенью двойки
while (i <= n) and ((s[i] = '0') or (s[i] = '1')) do inc(i) // БФ в векторном виде не должна содержать символы кроме 0 и 1
end;
FuncIsCorrect := (i = n + 1) // если проверка пройдена до конца и условия не были нарушены, запись корректна
end
else begin
FuncIsCorrect := false
end
end;
function CheckOnTheConst(s: string): boolean; // функция, проверяющая, является ли БФ константой
var i, n: byte;
begin
n := length(s);
i := 1; // инициализация первого шага
while (i < n) and (s[i] = s[i + 1]) do inc(i); // проверяем, пока не нарушится определение константного вектора БФ
CheckOnTheConst := (i = n) // если проверка пройдена до конца и условие не нарушилось, то вектор БФ - константа
end;
function BinarySetNum(a: byte; i: word): string; // функция, генерирующая двоичный набор i-той строки таблицы
const b: array[0..1] of char = ('0', '1');
var s: string;
j: byte;
begin
dec(i); // i-тая строка таблицы истинности представляет собой двоичную запись числа (i - 1)
s := '';
for j := 1 to a do begin // генерируемый стринг должен состоять из a символов
s := b[i mod 2] + s; // записываем остаток от деления i на 2 в крайнюю слева позицию
i := i div 2 // продолжаем цепочку делений
end;
BinarySetNum := s
end;
function PrecedeBS(s1, s2: string): boolean; // функция, проверяющая, сравнимы ли два двоичных набора
var i, n: byte;
begin
n := length(s1); // длина сравниваемых наборов одинакова
i := 1; // инициализация первого шага
while (i <= n) and (s1[i] <= s2[i]) do inc(i); // проверяем, пока не нарушится определение предшествования
PrecedeBS := (i = n + 1) // если проверка пройдена до конца и условие не нарушилось, то 1-й набор предшествует 2-му
end;
function CheckForMonoton(s: string): boolean;
var a, i, j, n: byte;
flag: boolean;
CurrBS: string;
begin
if CheckOnTheConst(s) then begin // если функция - константа
CheckForMonoton := true // то она монотонна
end
else begin // если функция не константа
flag := true;
n := length(s);
a := round(ln(n) / ln(2)); // вычисляем арность функции
i := pos('1', s); // первую единицу в записи вектора БФ ищем отдельно
while flag and (i <> 0) do begin // пока не проверили все единицы в векторе БФ или не нарушилось условие
CurrBS := BinarySetNum(a, i); // генерируем i-тый набор
for j := i to n do begin // сравниваем i-тый набор со всеми последующими
if PrecedeBS(CurrBS, BinarySetNum(a, j)) and (s[i] > s[j]) then begin // проверка нарушения условия
flag := false
end
end;
s[i] := '0'; // убираем рассмотренную единицу для поиска следующей
i := pos('1', s) // ищем следующую единицу для продолжения цикла
end;
CheckForMonoton := flag
end
end;
begin
readln(s);
if FuncIsCorrect(s) then begin // если запись вектора БФ не содержит ошибок
writeln(CheckForMonoton(s)) // выводим ответ
end
else begin
writeln('Incorrect function!') // иначе сообщаем об ошибке
end
end.
Я пробовал сам переделать, вот то что вышло, но оно не работает:
import math
def isCorrect(s):
i = 1
n = len(s)
if s != '' :
if n == 0 and n-1 == 0:
while i <= n and s[i] == '0' or s[i] == '1':
i += 1
return i == n+1
else:
return False
def CheckOnTheConst(s):
n = len(s)
i = 1
while i < n and s[i] == s[i+1]:
i += 1
return i == n
def BinarySetNum(a, i):
b = ['0', '1']
i -= 1
s = ''
for k in range(1, a):
s += b[i % 2]
i = int(i / 2)
return s
def PrecedeBS(s1, s2):
n = len(s1)
i = 1
while i <= n and s1[i] <= s2[i]:
i += 1
return i == n + 1
def isMono(s):
if CheckOnTheConst(s):
return True
else:
flag = True
n = len(s)
a = int(math.log1p(n) / math.log1p(2))
i = s.index('1')
while flag and i != 0:
CurrBS = BinarySetNum(a, i)
for j in range(i, n):
if PrecedeBS(CurrBS, BinarySetNum(a, j)) and s[i] > s[i]:
flag = False
s[i] = '0'
i = s.index('1')
return 'Mono' if flag else 'not Mono'
f = str(input('vector of function = '))
if isCorrect(f):
print(isMono(f))
else:
print('Incorrect function!')
Заранее спасибо всем кто помог!
Ответы (1 шт):
В куске кода ниже оператор and используется не для булевой, а для битовой операции, для которой в Питоне есть отдельный оператор &.
if n and (n - 1) = 0 then begin // проверяем, является ли число цифр в записи степенью двойки
Итого первая функция:
def FuncIsCorrect(s: str) -> bool: # функция, проверяющая правильность записи заданной в векторном виде БФ
n = len(s)
return s and n & (n-1) == 0 and all(x in "01" for x in s)
Вторая функция что делает? Определяет состоит ли строка полностью из одинаковых символов. Ну и на питоне это можно проверить так:
def CheckOnTheConst(s: str) -> bool: # функция, проверяющая, является ли БФ константой
return len(set(s)) == 1
Следующая функция, по сути, выполняет перевод числа в строку в двоичном виде. Итого:
def BinarySetNum(a: int, i: int) -> str: # функция, генерирующая двоичный набор i-той строки таблицы
return f"{i:0{a}b}"[:a]
Далее... Поэлементное сравнение двух строк одинаковой длины в Питоне проще всего сделать через zip().
def PrecedeBS(s1: str, s2: str) -> bool: # функция, проверяющая, сравнимы ли два двоичных набора
return all(x <= y for x,y in zip(s1, s2))
Ну и остаток можно, в принципе, перевести "в лоб", ибо там особо ничего нет "питонистого".
def CheckForMonoton(s: str) -> bool:
if CheckOnTheConst(s): # если функция - константа
return True # то она монотонна
# если функция не константа
n = len(s)
a = round(math.log(n) / math.log(2)) # вычисляем арность функции
i = s.find('1') # первую единицу в записи вектора БФ ищем отдельно
while i != -1: # пока не проверили все единицы в векторе БФ или не нарушилось условие
CurrBS = BinarySetNum(a, i) # генерируем i-тый набор
for j in range(i+1, n): # сравниваем i-тый набор со всеми последующими
if PrecedeBS(CurrBS, BinarySetNum(a, j)) and (s[i] > s[j]): # проверка нарушения условия
return False
i = s.find('1', i+1) # ищем следующую единицу для продолжения цикла
return True
s = input()
if FuncIsCorrect(s): # если запись вектора БФ не содержит ошибок
print(CheckForMonoton(s)) # выводим ответ
else:
print('Incorrect function!') # иначе сообщаем об ошибке