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 =
rubocop:disable Style/AsciiComments
[ 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|divided\s*by|dividing\s*by)\s*#{VALUE_PATTERN} ) /xi.freeze
Class Method Summary collapse
- .normalize_content(s) ⇒ Object
- .normalize_value(s) ⇒ Object
- .parse(str) ⇒ Object
-
.process(pbm) ⇒ Object
rubocop:enable Style/AsciiComments.
Class Method Details
.normalize_content(s) ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/at_coder_friends/parser/modulo.rb', line 58 def normalize_content(s) s .tr('0-9A-Za-z', '0-9A-Za-z') .gsub(/[[:space:]]/, ' ') .gsub(%r{[^一-龠_ぁ-ん_ァ-ヶーa-zA-Z0-9 -/:-@\[-`\{-~]}, '') .gsub(/{\\rm\s*mod\s*}\\?/i, 'mod') # {\rm mod} -> mod .gsub(/\\rm\s*{\s*mod\s*}\\?/i, 'mod') # \rm{mod}\ -> mod .gsub(/\\mbox\s*{\s*mod\s*}/i, 'mod') # \mbox{mod} -> mod .gsub(%r{<var>\s*mod\s*</var>}i, 'mod') # <var>mod</var> -> mod end |
.normalize_value(s) ⇒ Object
69 70 71 72 73 |
# File 'lib/at_coder_friends/parser/modulo.rb', line 69 def normalize_value(s) s .gsub(/\A([^(=]+)[(=].*\z/, '\1') # 1000000007 (10^9+7), ... =10^9+7 .gsub(/[{}()=\\ ]/, '') end |
.parse(str) ⇒ Object
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/at_coder_friends/parser/modulo.rb', line 47 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
rubocop:enable Style/AsciiComments
37 38 39 40 41 42 43 44 45 |
# File 'lib/at_coder_friends/parser/modulo.rb', line 37 def process(pbm) mods = [] SECTIONS.any? do |section| next unless (html = pbm.sections[section]&.html) !(mods = parse(html)).empty? end pbm.constants += mods end |