Example #1
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	p := &model.Problem{
		Solutions: make(map[string]*model.Solution),
	}
	PanicIf(archive.LoadTests(p, "in/(.*).in$", "out/(.*).out$"))
	PanicIf(archive.LoadSolutions(p, "prog/(.*)"))
	return []*model.Problem{p}, nil
}
Example #2
0
File: import.go Project: lanior/upc
func importStatement(archive *formats.ProblemArchiveReader, problem *model.Problem, statement *Statement) {
	data, err := archive.ReadFile(statement.Path)
	PanicIf(err, "Cannot read statement %s: %s", statement.Path, err)

	getTeX := func(src []byte) model.FormattedText {
		return model.RawText(src)
	}

	if match := statementRe.FindSubmatch(data); match != nil {
		problem.Statement = getTeX(match[1])
		problem.InputFormat = getTeX(match[2])
		problem.OutputFormat = getTeX(match[3])
	}

	matches := exampleRe.FindAllSubmatch(data, -1)
	problem.Samples = make([]model.Sample, len(matches))
	for i, match := range matches {
		problem.Samples[i].Input = string(match[1])
		problem.Samples[i].Output = string(match[2])
	}
}
Example #3
0
File: import.go Project: lanior/upc
func addGenerator(archive *formats.ProblemArchiveReader, problem *model.Problem, generator *Generator) {
	gen := problem.Generators[generator.Name]
	if gen == nil {
		gen = new(model.Generator)
		problem.Generators[generator.Name] = gen
	}
	gen.Name = generator.Name
	if generator.OutputFile != "" {
		gen.OutputFile = generator.OutputFile
	}

	if generator.LanguageCode != 0 || generator.Source != "" {
		lang := getLanguage(generator.LanguageCode, generator.Source)
		PanicIf(lang == nil, "Unknown generator language")
		gen.Language = lang.Name
	}

	if generator.Source != "" {
		data, err := archive.ReadFile(generator.Source)
		PanicIf(err)
		gen.SourceCode = string(data)
	}
}
Example #4
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	data, err := archive.ReadFile("domjudge-problem.ini")
	PanicIf(err, "Cannot read problem settings: %s", err)

	settings := ParseSettings(data)

	p := &model.Problem{
		Title:       settings["name"],
		TimeLimit:   float32(settings.GetInt("timelimit")),
		MemoryLimit: 128,

		Solutions: make(map[string]*model.Solution),
	}

	PanicIf(archive.LoadTests(p, "(.*).in$", "(.*).out$"))
	PanicIf(archive.LoadSolutions(p, "sol_(.*)"))
	return []*model.Problem{p}, nil
}
Example #5
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	reader, err := archive.Open("problem.xml")
	PanicIf(err)
	defer reader.Close()

	problem := new(Problem)
	utils.NewXmlDecoder(reader).Decode(problem)

	testset := &problem.Script.Testset
	p := &model.Problem{
		InputFile:  testset.InputName,
		OutputFile: testset.OutputName,

		TimeLimit:   float32(parseTime(testset.TimeLimit)),
		MemoryLimit: float32(testset.MemoryLimit) / 1024 / 1024,

		Tests: make([]model.Test, testset.TestCount),
	}

	inputPattern := preparePattern(testset.InputPattern)
	outputPattern := preparePattern(testset.AnswerPattern)
	for i := 0; i < testset.TestCount; i++ {
		inputPattern = inputPattern
		outputPattern = outputPattern

		data, err := archive.ReadFile(fmt.Sprintf(inputPattern, i+1))
		PanicIf(err, "Cannot read test %d input: %s", i+1, err)
		p.Tests[i].Input = model.ConstTestData(data)

		data, err = archive.ReadFile(fmt.Sprintf(outputPattern, i+1))
		PanicIf(err, "Cannot read test %d input: %s", i+1, err)
		p.Tests[i].Output = model.ConstSolutionData(data)
	}
	return []*model.Problem{p}, nil
}
Example #6
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	data, err := archive.ReadFile("problem.xml")
	PanicIf(err)

	problem := new(Problem)
	xml.Unmarshal(data, problem)

	p := &model.Problem{
		Title:      problem.Names[0].Value,
		InputFile:  problem.Judging.InputFile,
		OutputFile: problem.Judging.OutputFile,

		TimeLimit:   float32(problem.Judging.TestSet.TimeLimit) / 1000,
		MemoryLimit: float32(problem.Judging.TestSet.MemoryLimit) / 1024 / 1024,

		Statement:    model.RawText(""),
		Constraints:  model.RawText(""),
		InputFormat:  model.RawText(""),
		OutputFormat: model.RawText(""),

		Generators: make(map[string]*model.Generator),
		Solutions:  make(map[string]*model.Solution),
		Images:     make(model.ImagesDict),
	}

	if p.InputFile == "" {
		p.InputFile = "*STDIN"
	}

	if p.OutputFile == "" {
		p.OutputFile = "*STDOUT"
	}

	getFile := func(file *File) (*programs.Compiler, []byte, string, error) {
		path := file.Path
		name := filepath.Base(path)
		ext := filepath.Ext(path)

		compiler := programs.GetCompilerByExt(ext)
		if compiler == nil {
			return nil, nil, "", fmt.Errorf("Unknown language extension %s", ext)
		}

		data, err := archive.ReadFile(path)
		if err != nil {
			return nil, nil, "", fmt.Errorf("Cannot read file %s: %s", path, err)
		}
		return compiler, data, name, nil
	}

	var mainSolution *model.Solution
	for _, solution := range problem.Assets.Solutions {
		compiler, data, name, err := getFile(&solution.Source)
		PanicIf(err, "Solution error: %s", err)

		p.Solutions[name] = &model.Solution{
			Name:       name,
			Language:   compiler.Name,
			SourceCode: string(data),
		}

		if solution.Tag == "main" {
			mainSolution = p.Solutions[name]
		}
	}

	getGenerator := func(name string) *model.Generator {
		if generator := p.Generators[name]; generator != nil {
			return generator
		}
		for _, executable := range problem.Files.Executables {
			path := executable.Source.Path
			filename := filepath.Base(path)
			ext := filepath.Ext(filename)
			genName := filename[:len(filename)-len(ext)]

			if genName == name {
				compiler, data, _, err := getFile(&executable.Source)
				PanicIf(err, "Generator error: %s", err)

				p.Generators[genName] = &model.Generator{
					Name:       genName,
					Language:   compiler.Name,
					SourceCode: string(data),
					OutputFile: "*STDOUT",
				}
				return p.Generators[genName]
			}
		}
		return nil
	}

	p.Tests = make([]model.Test, len(problem.Judging.TestSet.Tests))
	for i, test := range problem.Judging.TestSet.Tests {
		switch test.Method {
		case "manual":
			path := fmt.Sprintf(problem.Judging.TestSet.InputPathPattern, i+1)

			data, err := archive.ReadFile(path)
			PanicIf(err, "Cannot read test %d", i+1)

			p.Tests[i].Input = model.ConstTestData(data)
		case "generated":
			parts := strings.SplitN(test.Command, " ", 2)
			params := ""
			if len(parts) == 2 {
				params = parts[1]
			}

			generator := getGenerator(parts[0])
			PanicIf(generator == nil, "Unknown generator %s for test %d", parts[0], i+1)

			p.Tests[i].Input = &model.GeneratedInput{
				Generator:  generator.Name,
				Parameters: params,
			}
		default:
			Panic("Unknown test method %s", test.Method)
		}

		if mainSolution != nil {
			p.Tests[i].Output = &model.SolutionOutput{
				Solution: mainSolution.Name,
			}
		}
	}

	if checker := problem.Assets.Checker; checker != nil {
		compiler, data, _, err := getFile(&checker.Source)
		PanicIf(err, "Solution error: %s", err)

		p.Checker = &model.Checker{
			Style:      "testlib",
			Language:   compiler.Name,
			SourceCode: string(data),
		}
	}

	for _, statement := range problem.Statements {
		if statement.Format == "tex" && statement.Language == problem.Names[0].Language {
			importStatement(archive, p, &statement)
			break
		}
	}
	return []*model.Problem{p}, nil
}
Example #7
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	files := archive.Glob("*.xml")
	PanicIf(len(files) == 0, "Task file not found")
	PanicIf(len(files) > 1, "Several xml files found in the archive")

	reader, err := archive.Open(files[0])
	PanicIf(err)
	defer reader.Close()

	container := new(Container)
	utils.NewXmlDecoder(reader).Decode(container)

	problem := container.Problem
	PanicIf(problem == nil, "Problem node not found")

	p := &model.Problem{
		Title:  problem.Title,
		Author: problem.Author,

		TimeLimit:   float32(problem.TimeLimit),
		MemoryLimit: float32(problem.MemoryLimit),

		Statement:    parseSGML(problem.Statement),
		Constraints:  parseSGML(problem.Constraints),
		InputFormat:  parseSGML(problem.InputFormat),
		OutputFormat: parseSGML(problem.OutputFormat),

		Generators: make(map[string]*model.Generator),
		Solutions:  make(map[string]*model.Solution),
		Images:     make(model.ImagesDict),
	}

	getSample := func(res *SampleResource) string {
		if res.Source != "" {
			data, err := archive.ReadFile(res.Source)
			PanicIf(err)
			return string(data)
		}
		return res.Text
	}

	p.Samples = make([]model.Sample, len(problem.Samples))
	for i, sample := range problem.Samples {
		p.Samples[i].Input = getSample(&sample.SampleIn)
		p.Samples[i].Output = getSample(&sample.SampleOut)
	}

	for _, picture := range problem.Pictures {
		data, err := archive.ReadFile(picture.Source)
		PanicIf(err)
		p.Images[picture.Name] = data
	}

	for _, generator := range problem.Generators {
		addGenerator(archive, p, &generator)
	}

	for _, genRange := range problem.GeneratorRanges {
		for j := genRange.From; j <= genRange.To; j++ {
			generator := genRange.Generator
			generator.Name = applyTestRank(generator.Name, j)
			generator.Source = applyTestRank(generator.Source, j)
			addGenerator(archive, p, &generator)
		}
	}

	for _, solution := range problem.Solutions {
		lang := getLanguage(solution.LanguageCode, solution.Source)
		PanicIf(lang == nil, "Unknown solution language")

		data, err := archive.ReadFile(solution.Source)
		PanicIf(err)

		p.Solutions[solution.Name] = &model.Solution{
			Name:       solution.Name,
			Language:   lang.Name,
			SourceCode: string(data),
		}
	}

	convertTest := func(t *model.Test, test *Test) {
		t.Points = test.Points

		if in := test.InputFile; in != nil {
			if in.Source != "" {
				data, err := archive.ReadFile(in.Source)
				PanicIf(err)

				t.Input = model.ConstTestData(data)
			} else if in.Generator != "" || in.Parameters != "" {
				if t.Input == nil {
					t.Input = &model.GeneratedInput{}
				}

				if in.Generator != "" {
					t.Input.(*model.GeneratedInput).Generator = in.Generator
				}

				if in.Parameters != "" {
					t.Input.(*model.GeneratedInput).Parameters = in.Parameters
				}
			}
		}

		if out := test.OutputFile; out != nil {
			if out.Source != "" {
				data, err := archive.ReadFile(out.Source)
				PanicIf(err)

				t.Output = model.ConstSolutionData(data)
			} else if out.Solution != "" {
				t.Output = &model.SolutionOutput{Solution: out.Solution}
			}
		}
	}

	addTestGroup := func(test *Test) {
		for rank := range stringRange(test.Rank) {
			if rank < 1 {
				continue
			}

			for len(p.Tests) < rank {
				p.Tests = append(p.Tests, model.Test{})
			}

			processedTest := *test
			if in := processedTest.InputFile; in != nil {
				processedTest.InputFile = &InputFile{
					Generator:   applyTestRank(in.Generator, rank),
					Source:      applyTestRank(in.Source, rank),
					Parameters:  applyTestRank(in.Parameters, rank),
					GenerateAll: in.GenerateAll,
				}
			}

			if out := processedTest.OutputFile; out != nil {
				processedTest.OutputFile = &OutputFile{
					Solution: applyTestRank(out.Solution, rank),
					Source:   applyTestRank(out.Source, rank),
				}
			}

			convertTest(&p.Tests[rank-1], &processedTest)
		}
	}

	for _, testRange := range problem.TestRanges {
		test := Test{
			Rank:          fmt.Sprintf("%d-%d", testRange.From, testRange.To),
			TestDataMixin: testRange.TestDataMixin,
		}
		addTestGroup(&test)
	}

	for _, test := range problem.Tests {
		addTestGroup(&test)
	}

	for i, test := range p.Tests {
		if test.Input == nil || test.Output == nil {
			Panic("Test %d: incomplete input or output section", i+1)
		}
	}
	return []*model.Problem{p}, nil
}
Example #8
0
File: import.go Project: lanior/upc
func (self Format) ImportArchive(archive *formats.ProblemArchiveReader) (problems []*model.Problem, err error) {
	defer SuppressPanic(&err)

	file, err := archive.Open("conf/serve.cfg")
	PanicIf(err, "Cannot open contest config: %s", err)
	defer file.Close()

	config, err := ReadConfig(file)
	PanicIf(err, "Cannot read contest config: %s", err)

	problemsData := make(map[string]*Section)

	global := &Section{Values: make(ValuesMap)}

	getGlobal := func(key, defaultValue string) string {
		value, ok := global.Values[key]
		if !ok {
			return defaultValue
		}
		return value
	}

	for i, section := range config {
		if section.Name == "problem" {
			problemsData[section.Values["short_name"]] = &config[i]
		} else if section.Name == "" {
			global = &config[i]
		}
	}

	for _, problem := range problemsData {
		if problem.Values["abstract"] == "1" {
			continue
		}

		getValue := func(key, defaultValue string) string {
			value, ok := problem.Values[key]
			if !ok {
				super := problem.Values["super"]
				if parentProblem := problemsData[super]; parentProblem != nil {
					value, ok := parentProblem.Values[key]
					if !ok {
						return defaultValue
					}
					return value
				}
			}
			return value
		}

		p := &model.Problem{
			Title:       getValue("long_name", ""),
			TimeLimit:   float32(getInt(getValue("time_limit", "0"))),
			MemoryLimit: float32(getMemory(getValue("max_vm_size", "0")) / 1024 / 1024),
			Solutions:   make(map[string]*model.Solution),
		}

		if getValue("use_stdin", "false") != "false" {
			p.InputFile = "*STDIN"
		} else {
			p.InputFile = getValue("input_file", "input")
		}

		if getValue("use_stdout", "false") != "false" {
			p.OutputFile = "*STDOUT"
		} else {
			p.OutputFile = getValue("output_file", "output")
		}

		shortName := getValue("short_name", "")

		testSfx := getValue("test_sfx", global.Values["test_sfx"])
		corrSfx := getValue("corr_sfx", global.Values["corr_sfx"])

		var testDir, corrDir, solDir, statementPath string
		if getGlobal("advanced_layout", "0") == "1" {
			testDir = filepath.Join("problems", shortName, "tests")
			corrDir = testDir
			solDir = filepath.Join("problems", shortName, "solutions")
			statementPath = filepath.Join("problems", shortName, "statement.xml")
		} else {
			Panic("Unsupported problems layout")
		}

		testPattern := fmt.Sprintf("%s/(.*)%s$", testDir, testSfx)
		resultPattern := fmt.Sprintf("%s/(.*)%s$", corrDir, corrSfx)
		solutionPattern := fmt.Sprintf("%s/(.*)$", solDir)

		PanicIf(archive.LoadTests(p, testPattern, resultPattern))
		PanicIf(archive.LoadSolutions(p, solutionPattern))

		statementFile, err := archive.Open(statementPath)
		PanicIf(err, "Cannot open statement file")
		defer statementFile.Close()

		problem := new(Problem)
		utils.NewXmlDecoder(statementFile).Decode(problem)

		p.Samples = make([]model.Sample, len(problem.Examples.Items))
		for i, example := range problem.Examples.Items {
			p.Samples[i].Input = example.Input
			p.Samples[i].Output = example.Output
		}

		p.Title = problem.Statement.Title
		p.Statement = parseHTML(problem.Statement.Description.Text)
		p.InputFormat = parseHTML(problem.Statement.InputFormat.Text)
		p.OutputFormat = parseHTML(problem.Statement.OutputFormat.Text)

		problems = append(problems, p)
	}

	return problems, nil
}