Помогите пожалуйста перевести код с 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 шт):

Автор решения: GrAnd

В куске кода ниже оператор 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!') # иначе сообщаем об ошибке
→ Ссылка