Module: AtCoderFriends::Parser::InputFormat
- Includes:
- InputFormatConstants
- Defined in:
- lib/at_coder_friends/parser/input_format.rb
Overview
parses input data format and generates input definitons
Defined Under Namespace
Classes: Iterator
Constant Summary
Constants included from InputFormatConstants
AtCoderFriends::Parser::InputFormatConstants::PARSERS, AtCoderFriends::Parser::InputFormatConstants::SECTIONS
Class Method Summary collapse
- .match_smp!(inpdefs, smp) ⇒ Object
-
.max_smp(smps) ⇒ Object
rubocop:enable Metrics/MethodLength, Metrics/AbcSize.
- .normalize(fmt) ⇒ Object
- .parse(str, smps) ⇒ Object
-
.parse_fmt(lines) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/AbcSize.
- .process(pbm) ⇒ Object
Class Method Details
.match_smp!(inpdefs, smp) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 153 def match_smp!(inpdefs, smp) lines = smp.split("\n") inpdefs.each_with_index do |inpdef, i| break if i >= lines.size next if inpdef.item != :number inpdef.item = :string if lines[i].split[0] =~ /[^\-0-9]/ break if i[varray matrix].include?(inpdef.container) end inpdefs end |
.max_smp(smps) ⇒ Object
rubocop:enable Metrics/MethodLength, Metrics/AbcSize
146 147 148 149 150 151 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 146 def max_smp(smps) smps .select { |smp| smp.ext == :in } .max_by { |smp| smp.txt.size } &.txt end |
.normalize(fmt) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 106 def normalize(fmt) fmt .gsub(/[+*-]\d+/, '') # N-1, N+1 -> N .gsub(%r{[-/ ]}, ' ') # a-b, a/b -> a b .gsub(/\{.*?\}/) { |w| w.delete(' ') } # {1, 1}->{1,1} shortest match .gsub(/[_,'\\(){}|$]/, '') .gsub(/[・::…‥]+/, '..') .gsub(/[clv]?dots/, '..') .gsub(/^\s*\.[.\s]*$/, '..') .split("\n") .map(&:strip) end |
.parse(str, smps) ⇒ Object
98 99 100 101 102 103 104 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 98 def parse(str, smps) lines = normalize(str) inpdefs = parse_fmt(lines) smpx = max_smp(smps) smpx && match_smp!(inpdefs, smpx) inpdefs end |
.parse_fmt(lines) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/AbcSize
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 120 def parse_fmt(lines) it = Iterator.new(lines + ['']) # sentinel prv = nil cur = it.next Enumerator.new do |y| loop do unless (parser = PARSERS.find { |ps| ps[:pat] =~ cur }) puts "unknown format: #{cur}" unless cur.empty? (cur = it.next) ? next : break end container, item = parser.values_at(:container, :item) m = parser[:pat].match(cur) names = parser[:names].call(m) pat2 = parser[:pat2].call(names) loop do prv = cur cur = it.next break unless pat2 && pat2 =~ cur end size = parser[:size].call(prv) y << Problem::InputFormat.new(container, item, names, size) end end.to_a end |
.process(pbm) ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/at_coder_friends/parser/input_format.rb', line 89 def process(pbm) str = SECTIONS .map { |key| pbm.sections[key]&.code_block } .find(&:itself) || '' inpdefs = parse(str, pbm.samples) pbm.formats = inpdefs end |