Esempio n. 1
0
File: reader.go Progetto: lanior/upc
func (self *ProblemArchiveReader) LoadTests(problem *model.Problem, inPattern, outPattern string) error {
	inRe, err := regexp.Compile(inPattern)
	if err != nil {
		return err
	}

	outRe, err := regexp.Compile(outPattern)
	if err != nil {
		return err
	}

	tests := make(map[string]int)
	getData := func(name, file string) (id int, data []byte, err error) {
		id, ok := tests[name]
		if !ok {
			problem.Tests = append(problem.Tests, model.Test{})
			id = len(problem.Tests) - 1
			tests[name] = id
		}

		data, err = self.ReadFile(file)
		return
	}

	for _, file := range self.FileList() {
		in := inRe.FindStringSubmatch(file)
		if in != nil {
			id, data, err := getData(in[1], file)
			if err != nil {
				return err
			}
			problem.Tests[id].Input = model.ConstTestData(data)
		}

		out := outRe.FindStringSubmatch(file)
		if out != nil {
			id, data, err := getData(out[1], file)
			if err != nil {
				return err
			}
			problem.Tests[id].Output = model.ConstSolutionData(data)
		}
	}
	return nil
}
Esempio n. 2
0
File: import.go Progetto: 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
}
Esempio n. 3
0
File: import.go Progetto: 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
}
Esempio n. 4
0
File: import.go Progetto: lanior/upc
func convertProblem(problem *Problem) (*model.Problem, error) {
	p := &model.Problem{
		Title:  problem.Title,
		Author: problem.Source,

		InputFile:  "*STDIN",
		OutputFile: "*STDOUT",

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

	p.Samples = make([]model.Sample, min(len(problem.SampleInput), len(problem.SampleOutput)))
	for i := range p.Samples {
		p.Samples[i].Input = problem.SampleInput[i]
		p.Samples[i].Output = problem.SampleOutput[i]
	}

	p.Tests = make([]model.Test, min(len(problem.TestInput), len(problem.TestOutput)))
	for i := range p.Tests {
		p.Tests[i].Input = model.ConstTestData(problem.TestInput[i])
		p.Tests[i].Output = model.ConstSolutionData(problem.TestOutput[i])
	}

	p.Images = make(model.ImagesDict)
	for _, image := range problem.Images {
		content, err := base64.StdEncoding.DecodeString(image.Data)
		if err != nil {
			return nil, err
		}
		p.Images[image.Source] = content
	}

	i := 0
	p.Solutions = make(map[string]*model.Solution)
	for _, solution := range problem.Solutions {
		if len(solution.Language) > 0 && len(solution.Text) > 0 {
			name := fmt.Sprintf("sol_%d", i+1)
			p.Solutions[name] = &model.Solution{
				Name:       name,
				Language:   strings.ToLower(solution.Language),
				SourceCode: solution.Text,
			}
		}
		i++
	}

	p.Statement = processHTML(problem.Description, p.Images)
	p.InputFormat = processHTML(problem.InputFormat, p.Images)
	p.OutputFormat = processHTML(problem.OutputFormat, p.Images)

	if problem.Checker != nil {
		if len(problem.Checker.Text) > 0 && len(problem.Checker.Language) > 0 {
			p.Checker = &model.Checker{
				Style:      "testlib",
				Language:   strings.ToLower(problem.Checker.Language),
				SourceCode: problem.Checker.Text,
			}
		}
	}
	return p, nil
}