Интересная регулярка

Discussion in 'PHP' started by desTiny, 6 May 2008.

  1. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    //Решил не писать в вопросы по чему бы то ни было,
    //так как там точно сразу не ответят,
    //и вопрос затеряется в глубинах топика

    Задачка была предложена когда-то на олимпиаде по информатике - я что-то тогда примерно придумал, но, вроде, неправильно.

    Итак, задачка:
    Есть строка из нулей и единиц - запись какого-то числа X в двоичной системе.
    Надо составить регулярку, определяющую, делится ли это число X на 3.

    Что-то вдруг захотелось придумать к ней решение :)

    //решено: ответ дан мной ниже в теме
     
    #1 desTiny, 6 May 2008
    Last edited: 15 May 2008
    1 person likes this.
  2. Евгений Минаев

    Евгений Минаев Elder - Старейшина

    Joined:
    12 Nov 2007
    Messages:
    55
    Likes Received:
    169
    Reputations:
    159
    Очень интересная задача, пока пришел только к такому выводу - сумма цифр, полученная от деления числа в двоичном виде при делении на тройку дает остаток 0. Но это пока все догадки. Цель задачи - найти признак делимости на тройку в двоиной системе счисления

    Между прочим выше я лоханулся, надо деление доводить до конца. Мне тут подсказали про перемену знаков. Рассмотрим на тех же числах
    Не уверен что PCRE такое может xD


     
    #2 Евгений Минаев, 6 May 2008
    Last edited: 6 May 2008
    3 people like this.
  3. KSURi

    KSURi tnega AOLPS

    Joined:
    6 Jun 2006
    Messages:
    458
    Likes Received:
    219
    Reputations:
    357
    Ну если регулярки ничем не ограничены то можно "прочитерить")
    Code:
    # 13 (не делится, остаток = 1)
    C:\>perl -e"$_='1101';s/[10]+/oct(qq{0b$_})%3/e;print"
    1
    
    # 12 (делится, остаток 0):
    C:\>perl -e"$_='1100';s/[10]+/oct(qq{0b$_})%3/e;print"
    0
    C:\>
    
    третий раз поправил) все
     
    #3 KSURi, 6 May 2008
    Last edited: 7 May 2008
    2 people like this.
  4. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    На самом деле, всё что я понял - даже с доказательством, нетрудным - это то, что в этом двоичном числе

    Остаток от деления суммы цифр на чётных позициях на 3 равен остатку от деления суммы цифр на нечётных позициях на 3

    Иначе говоря,

    Сумма цифр на чётных позициях сравнима с суммой цифр на нечётных позициях по модулю 3

    И это как-то точно можно реализовать - говорю - задачка с олимпиады.

    2Евгений Минаев:
    Что-то я плохо понял твою идею...

    2xcedz - не то... переводить нельзя. Всё, что можно - проверить строку с двоичной записью на регулярке.
    2KSURi - хитрить нельзя :) По оригинальному условию - всё, что у нас есть - это строка и регулярка :)
     
  5. KSURi

    KSURi tnega AOLPS

    Joined:
    6 Jun 2006
    Messages:
    458
    Likes Received:
    219
    Reputations:
    357
    Ну хорошо-хорошо, чит был в том, что кроме регулярки (левая часть оператора s///) был использован простой код для замены (правая часть оператора s///).
    Вот вариант с чистой регуляркой, только динамической)
    Code:
    C:\>perl -e"$_='1100';/(??{$_=oct(qq{0b$_})%3})/;print"
    0
    C:\>perl -e"$_='1101';/(??{$_=oct(qq{0b$_})%3})/;print"
    1
    C:\>
    
    Небольшое док-во, что используется именно регулярка, т.е. встроенные возможности библиотеки PCRE:
    Code:
    C:\>perl -e"$_=qr/(??{$_=oct(qq{0b$_})%3})/;print ref"
    Regexp
    C:\>
    
     
  6. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    KSURi, нет.
    В регулярке можно использовать только конкатенацию, выбор, повторения и скобки.
     
  7. KSURi

    KSURi tnega AOLPS

    Joined:
    6 Jun 2006
    Messages:
    458
    Likes Received:
    219
    Reputations:
    357
    значит это не регулярка, а "кастрат".
     
  8. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Задачка от этого менее интересной не становится :)
     
  9. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    короче, правильный ответ был найден (методом пинания одного из оргов олимпиады:)):

    (0|1(01*0)*1)*
     
    #9 desTiny, 15 May 2008
    Last edited: 16 May 2008
    1 person likes this.