Module: AtCoderFriends::Parser::Constraints
- Defined in:
- lib/at_coder_friends/parser/constraints.rb
Overview
parses constraints
Constant Summary collapse
- SECTIONS =
[ Problem::SECTION_CONSTRAINTS, Problem::SECTION_IN_FMT, Problem::SECTION_IO_FMT, Problem::SECTION_STATEMENT ].freeze
- NAME_PAT =
/[0-9a-z_{},]+/i.freeze
- NAMES_PAT =
/#{NAME_PAT}(?:\s*,\s*#{NAME_PAT})*/.freeze
- NUM_PAT =
/[-+*^0-9{}, ]+/.freeze
- MAX_PATTERN =
/ (?: (#{NAMES_PAT})\s*<\s*(#{NUM_PAT}) |(#{NAMES_PAT})\s*は\s*#{NUM_PAT}\s*以上\s*(#{NUM_PAT})\s*以下の整数 ) /xmi.freeze
Class Method Summary collapse
- .normalize_content(s) ⇒ Object
- .normalize_names(s) ⇒ Object
- .normalize_value(s) ⇒ Object
- .parse(str) ⇒ Object
- .process(pbm) ⇒ Object
Class Method Details
.normalize_content(s) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/at_coder_friends/parser/constraints.rb', line 47 def normalize_content(s) # 1) &npsp; , fill-width space -> half width space # 2) {i, j}->{i,j} {N-1}->{N} shortest match s .tr('0-9A-Za-z', '0-9A-Za-z') .gsub(/[[:space:]]/) { |c| c.gsub(/[^\t\n]/, ' ') } # 1) .gsub(%r{</?var>}i, "\t") .gsub(%r{<sup>([^<>]+)</sup>}i, '^\1') .gsub(%r{<sub>([^<>]+)</sub>}i, '_{\1}') .gsub(/<("[^"]*"|'[^']*'|[^'"<>])*>/, '') .gsub('&', '&') .gsub(/(<|≦|≤|<|&leq?;|\\lt|\\leq?q?)/i, '<') .gsub('\\ ', ' ') .gsub('\\,', ',') .gsub('\\|', '|') .gsub(',', ', ') .gsub('×', '*') .gsub('\\lvert', '|') .gsub('\\rvert', '|') .gsub('\\mathit', '') .gsub('\\mathrm', '') .gsub('\\times', '*') .gsub(/\\begin(\{[^{}]*\})*/, '') .gsub(/\\end(\{[^{}]*\})*/, '') .gsub(/\{\}/, ' ') .gsub('|', '') .gsub(/\{.*?\}/) { |w| w.delete(' ()').gsub(/{(.+)-1}\z/, '\1') } # 2) end |
.normalize_names(s) ⇒ Object
76 77 78 79 80 81 82 83 84 |
# File 'lib/at_coder_friends/parser/constraints.rb', line 76 def normalize_names(s) # 1) {i,j}->{ij} shortest match s .gsub(/\{.*?\}/) { |w| w.delete(',') } # 1) .delete('{}') .gsub(/\s+/, '') .split(',') .reject(&:empty?) end |
.normalize_value(s) ⇒ Object
86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/at_coder_friends/parser/constraints.rb', line 86 def normalize_value(s) s .split(', ') &.map do |v| v .delete(' {}') .gsub(/\A[+*^,]+/, '') # remove preceding symbols .gsub(/[+*^,]+\z/, '') # remove trailing symbols end &.reject(&:empty?) &.first end |
.parse(str) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/at_coder_friends/parser/constraints.rb', line 35 def parse(str) str = normalize_content(str) pats = str.scan(MAX_PATTERN).map(&:compact) pairs = pats.each_with_object([]) do |(k, v), result| value = normalize_value(v) next unless value && !value.empty? normalize_names(k).each { |name| result << [name, value] } end pairs.uniq.map { |k, v| Problem::Constant.new(k, :max, v) } end |
.process(pbm) ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/at_coder_friends/parser/constraints.rb', line 25 def process(pbm) maxs = [] SECTIONS.any? do |section| next unless (text = pbm.sections[section]&.html) !(maxs = parse(text)).empty? end pbm.constants += maxs end |