Module: AtCoderFriends::Parser::Modulo

Defined in:
lib/at_coder_friends/parser/modulo.rb

Overview

parses problem page and extract modulo values

Constant Summary collapse

SECTIONS =
[
  Problem::SECTION_OUT_FMT,
  Problem::SECTION_STATEMENT,
  Problem::SECTION_TASK,
  Problem::SECTION_INTRO
].freeze
VALUE_PATTERN =

(998244353) 十億九

%r{
  (?:
    <var>([^<>]+)</var>
    |\(([^()]+)\)
    |\\\(([^()]+)\\\)
    |\$([^$]+)\$
    |\{([^{}]+)\}
    |([\d,^+]+)
    |([一二三四五六七八九十百千万億]+)
  )
}x.freeze
MOD_PATTERN =

<var>1,000,000,007</var> (素数)で割った余り

/
  (?:
    #{VALUE_PATTERN}\s*(?:\([^()]+\)\s*)?で割った(?:剰余|余り|あまり)
    |(?:modulo|mod|divid(?:ed|ing)\s*by)\s*#{VALUE_PATTERN}
  )
/xi.freeze

Class Method Summary collapse

Class Method Details

.normalize_content(s) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'lib/at_coder_friends/parser/modulo.rb', line 57

def normalize_content(s)
  s
    .tr('0-9A-Za-z', '0-9A-Za-z')
    .gsub(/[[:space:]]/, ' ')
    .gsub(%r{[^一-龠_ぁ-んァ-ヶーa-zA-Z0-9 -/:-@\[-`\{-~]}, '')
    .gsub(/{\\[a-z]+\s*mod\s*}\\?/i, 'mod') # {\rm mod}, {\bmod} -> mod
    .gsub(/\\[a-z]+\s*{\s*mod\s*}\\?/i, 'mod') # \text{mod} -> mod
    .gsub(%r{<var>\s*mod\s*</var>}i, 'mod') # <var>mod</var> -> mod
end

.normalize_value(s) ⇒ Object



67
68
69
70
71
# File 'lib/at_coder_friends/parser/modulo.rb', line 67

def normalize_value(s)
  s
    .gsub(/\A([^(=]+)[(=].*\z/, '\1') # 1000000007 (10^9+7), ... =10^9+7
    .gsub(/[{}()=\\ ]/, '')
end

.parse(str) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/at_coder_friends/parser/modulo.rb', line 46

def parse(str)
  str = normalize_content(str)
  str
    .scan(MOD_PATTERN)
    .map(&:compact)
    .map { |(v)| normalize_value(v) }
    .reject(&:empty?)
    .uniq
    .map { |v| Problem::Constant.new('mod', :mod, v) }
end

.process(pbm) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/at_coder_friends/parser/modulo.rb', line 36

def process(pbm)
  mods = []
  SECTIONS.any? do |section|
    next unless (html = pbm.sections[section]&.html)

    !(mods = parse(html)).empty?
  end
  pbm.constants += mods
end