-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
16 changed files
with
913 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
from typing import Dict, Any, Optional | ||
|
||
from atcodertools.codegen.code_style_config import CodeStyleConfig | ||
from atcodertools.codegen.models.code_gen_args import CodeGenArgs | ||
from atcodertools.codegen.template_engine import render | ||
from atcodertools.fmtprediction.models.format import Pattern, SingularPattern, ParallelPattern, TwoDimensionalPattern, \ | ||
Format | ||
from atcodertools.fmtprediction.models.type import Type | ||
from atcodertools.fmtprediction.models.variable import Variable | ||
|
||
|
||
def _loop_header(var: Variable, for_second_index: bool): | ||
if for_second_index: | ||
index = var.second_index | ||
loop_var = "j" | ||
else: | ||
index = var.first_index | ||
loop_var = "i" | ||
|
||
return "for(int {loop_var} = 0;{loop_var} < {len};{loop_var}++)".format( | ||
loop_var=loop_var, | ||
len=index.get_length() | ||
) + "{" | ||
|
||
|
||
class CSharpCodeGenerator: | ||
|
||
def __init__(self, | ||
format_: Optional[Format[Variable]], | ||
config: CodeStyleConfig): | ||
self._format = format_ | ||
self._config = config | ||
|
||
def generate_parameters(self) -> Dict[str, Any]: | ||
if self._format is None: | ||
return dict(prediction_success=False) | ||
|
||
return dict(formal_arguments=self._formal_arguments(), | ||
actual_arguments=self._actual_arguments(), | ||
input_part=self._input_part(), | ||
prediction_success=True) | ||
|
||
def _input_part(self): | ||
lines = [] | ||
for pattern in self._format.sequence: | ||
lines += self._render_pattern(pattern) | ||
return "\n{indent}".format(indent=self._indent(2)).join(lines) | ||
|
||
def _convert_type(self, type_: Type) -> str: | ||
if type_ == Type.float: | ||
return "double" | ||
elif type_ == Type.int: | ||
return "long" | ||
elif type_ == Type.str: | ||
return "string" | ||
else: | ||
raise NotImplementedError | ||
|
||
def _get_declaration_type(self, var: Variable): | ||
ctype = self._convert_type(var.type) | ||
if var.dim_num() == 0: | ||
return ctype | ||
else: | ||
return "{}[{}]".format(ctype, "," * (var.dim_num() - 1)) | ||
|
||
def _actual_arguments(self) -> str: | ||
""" | ||
:return the string form of actual arguments e.g. "N, K, a" | ||
""" | ||
return ", ".join([ | ||
v.name if v.dim_num() == 0 else '{}'.format(v.name) | ||
for v in self._format.all_vars()]) | ||
|
||
def _formal_arguments(self): | ||
""" | ||
:return the string form of formal arguments e.g. "int N, int K, std::vector<int> a" | ||
""" | ||
return ", ".join([ | ||
"{decl_type} {name}".format( | ||
decl_type=self._get_declaration_type(v), | ||
name=v.name) | ||
for v in self._format.all_vars() | ||
]) | ||
|
||
def _generate_declaration(self, var: Variable): | ||
""" | ||
:return: Create declaration part E.g. array[1..n] -> std::vector<int> array = std::vector<int>(n-1+1); | ||
""" | ||
if var.dim_num() == 0: | ||
dims = [] | ||
elif var.dim_num() == 1: | ||
dims = [var.first_index.get_length()] | ||
elif var.dim_num() == 2: | ||
dims = [var.first_index.get_length(), | ||
var.second_index.get_length()] | ||
else: | ||
raise NotImplementedError | ||
ret = "{decl_type} {name}".format( | ||
decl_type=self._get_declaration_type(var), name=var.name) | ||
if len(dims) > 0: | ||
t = self._convert_type(var.type) | ||
d = [] | ||
for dim in dims: | ||
d.append(str(dim)) | ||
ret += " = new {type}[{dims}]".format(type=t, dims=",".join(d)) | ||
ret += ";" | ||
return ret | ||
|
||
def _input_code_for_var(self, var: Variable) -> str: | ||
name = self._get_var_name(var) | ||
if var.type == Type.float: | ||
return '{name} = cin.ReadDouble;'.format(name=name) | ||
elif var.type == Type.int: | ||
return '{name} = cin.ReadLong;'.format(name=name) | ||
elif var.type == Type.str: | ||
return '{name} = cin.Read;'.format(name=name) | ||
else: | ||
raise NotImplementedError | ||
|
||
@staticmethod | ||
def _get_var_name(var: Variable): | ||
name = var.name | ||
if var.dim_num() >= 1: | ||
name += "[i" | ||
if var.dim_num() >= 2: | ||
name += ",j" | ||
name += "]" | ||
return name | ||
|
||
def _render_pattern(self, pattern: Pattern): | ||
lines = [] | ||
for var in pattern.all_vars(): | ||
lines.append(self._generate_declaration(var)) | ||
|
||
representative_var = pattern.all_vars()[0] | ||
if isinstance(pattern, SingularPattern): | ||
lines.append(self._input_code_for_var(representative_var)) | ||
elif isinstance(pattern, ParallelPattern): | ||
lines.append(_loop_header(representative_var, False)) | ||
for var in pattern.all_vars(): | ||
lines.append("{indent}{line}".format(indent=self._indent(1), | ||
line=self._input_code_for_var(var))) | ||
lines.append("}") | ||
elif isinstance(pattern, TwoDimensionalPattern): | ||
lines.append(_loop_header(representative_var, False)) | ||
lines.append( | ||
"{indent}{line}".format(indent=self._indent(1), line=_loop_header(representative_var, True))) | ||
for var in pattern.all_vars(): | ||
lines.append("{indent}{line}".format(indent=self._indent(2), | ||
line=self._input_code_for_var(var))) | ||
lines.append("{indent}}}".format(indent=self._indent(1))) | ||
lines.append("}") | ||
else: | ||
raise NotImplementedError | ||
|
||
return lines | ||
|
||
def _indent(self, depth): | ||
return self._config.indent(depth) | ||
|
||
|
||
class NoPredictionResultGiven(Exception): | ||
pass | ||
|
||
|
||
def main(args: CodeGenArgs) -> str: | ||
code_parameters = CSharpCodeGenerator( | ||
args.format, args.config).generate_parameters() | ||
return render( | ||
args.template, | ||
mod=args.constants.mod, | ||
yes_str=args.constants.yes_str, | ||
no_str=args.constants.no_str, | ||
**code_parameters | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using System; | ||
using System.Text; | ||
using System.Linq; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using static System.Console; | ||
using static System.Math; | ||
using System.Diagnostics; | ||
|
||
public class Program{ | ||
{% if mod %} | ||
const long MOD = {{ mod }}; | ||
{% endif %} | ||
{% if yes_str %} | ||
const string YES = "{{ yes_str }}"; | ||
{% endif %} | ||
{% if no_str %} | ||
const string NO = "{{ no_str }}"; | ||
{% endif %} | ||
|
||
public static void Main(string[] args){ | ||
ConsoleInput cin = new ConsoleInput(Console.In, ' '); | ||
{% if prediction_success %} | ||
{{ input_part }} | ||
new Program().Solve({{ actual_arguments }}); | ||
{% else %} | ||
// Failed to predict input format | ||
{% endif %} | ||
} | ||
|
||
{% if prediction_success %} | ||
public void Solve({{ formal_arguments }}){ | ||
|
||
} | ||
{% endif %} | ||
} | ||
|
||
public class ConsoleInput{ | ||
private readonly System.IO.TextReader _stream; | ||
private char _separator = ' '; | ||
private Queue<string> inputStream; | ||
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){ | ||
this._separator = separator; | ||
this._stream = stream; | ||
inputStream = new Queue<string>(); | ||
} | ||
public string Read{ | ||
get{ | ||
if (inputStream.Count != 0) return inputStream.Dequeue(); | ||
string[] tmp = _stream.ReadLine().Split(_separator); | ||
for (int i = 0; i < tmp.Length; ++i) | ||
inputStream.Enqueue(tmp[i]); | ||
return inputStream.Dequeue(); | ||
} | ||
} | ||
public string ReadLine { get { return _stream.ReadLine(); } } | ||
public int ReadInt { get { return int.Parse(Read); } } | ||
public long ReadLong { get { return long.Parse(Read); } } | ||
public double ReadDouble { get { return double.Parse(Read); } } | ||
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;} | ||
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;} | ||
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using System; | ||
using System.Text; | ||
using System.Linq; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using static System.Console; | ||
using static System.Math; | ||
|
||
public class Program{ | ||
public static void Main(string[] args){ | ||
ConsoleInput cin = new ConsoleInput(Console.In, ' '); | ||
${input_part} | ||
new Program().Solve(${actual_arguments}); | ||
} | ||
|
||
public void Solve(${formal_arguments}){ | ||
|
||
} | ||
} | ||
|
||
public class ConsoleInput{ | ||
private readonly System.IO.TextReader _stream; | ||
private char _separator = ' '; | ||
private Queue<string> inputStream; | ||
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){ | ||
this._separator = separator; | ||
this._stream = stream; | ||
inputStream = new Queue<string>(); | ||
} | ||
public string Read{ | ||
get{ | ||
if (inputStream.Count != 0) return inputStream.Dequeue(); | ||
string[] tmp = _stream.ReadLine().Split(_separator); | ||
for (int i = 0; i < tmp.Length; ++i) | ||
inputStream.Enqueue(tmp[i]); | ||
return inputStream.Dequeue(); | ||
} | ||
} | ||
public string ReadLine { get { return _stream.ReadLine(); } } | ||
public int ReadInt { get { return int.Parse(Read); } } | ||
public long ReadLong { get { return long.Parse(Read); } } | ||
public double ReadDouble { get { return double.Parse(Read); } } | ||
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;} | ||
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;} | ||
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System; | ||
using System.Text; | ||
using System.Linq; | ||
using System.Collections; | ||
using System.Collections.Generic; | ||
using static System.Console; | ||
using static System.Math; | ||
|
||
public class Program{ | ||
{% if mod %} | ||
const long MOD = {{ mod }}; | ||
{% endif %} | ||
{% if yes_str %} | ||
const string YES = "{{ yes_str }}"; | ||
{% endif %} | ||
{% if no_str %} | ||
const string NO = "{{ no_str }}"; | ||
{% endif %} | ||
|
||
public static void Main(string[] args){ | ||
ConsoleInput cin = new ConsoleInput(Console.In, ' '); | ||
{{ input_part }} | ||
new Program().Solve({{ actual_arguments }}); | ||
} | ||
|
||
public void Solve({{ formal_arguments }}){ | ||
|
||
} | ||
} | ||
|
||
public class ConsoleInput{ | ||
private readonly System.IO.TextReader _stream; | ||
private char _separator = ' '; | ||
private Queue<string> inputStream; | ||
public ConsoleInput(System.IO.TextReader stream, char separator = ' '){ | ||
this._separator = separator; | ||
this._stream = stream; | ||
inputStream = new Queue<string>(); | ||
} | ||
public string Read{ | ||
get{ | ||
if (inputStream.Count != 0) return inputStream.Dequeue(); | ||
string[] tmp = _stream.ReadLine().Split(_separator); | ||
for (int i = 0; i < tmp.Length; ++i) | ||
inputStream.Enqueue(tmp[i]); | ||
return inputStream.Dequeue(); | ||
} | ||
} | ||
public string ReadLine { get { return _stream.ReadLine(); } } | ||
public int ReadInt { get { return int.Parse(Read); } } | ||
public long ReadLong { get { return long.Parse(Read); } } | ||
public double ReadDouble { get { return double.Parse(Read); } } | ||
public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret;} | ||
public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret;} | ||
public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret;} | ||
} |
Oops, something went wrong.