Sorted Groups

Description

Given a string, divide it into substrings so each substring is sorted (either in ascending or descending order), then output the smallest number of such groups.

Your score in this challenge will be the length of your code in bytes multiplied by the number of sorted groups divided by 3.

For example, if you get the string:

aacdefba

It can be divided into sorted substrings, first one ascending the second descending:

aacdef
ba

Thus you would output 2. If this was a submission, it would be awarded 8 * 2 / 3 = 5 points.

Judge

(async function*(context: Context): Challenge {
	const words = (await Deno.readTextFile("/scripts/words.txt")).split('\n');

	function getWordGroups(word: string) {
		return [...word].reduce(({prev,groups,direction},char)=>{
			let valid = true;
			if (char < prev && direction > 0) {
				valid = false;
			}
			if (char > prev && direction < 0) {
				valid = false;
			}
			
			return {
				prev: char,
				groups: valid ? groups:groups+1,
				direction: valid ? char > prev ? 1 : char < prev ? -1 : direction : 0
			}
		},{prev:word[0],groups:1,direction:0}).groups
	}

	// Automatically shuffle and deal test cases over multiple runs
	yield* context.runTestCases(
		words.map(
			(word:string) => {
				let combinedWord = word + words[Math.floor(Math.random()*words.length)] + words[Math.floor(Math.random()*words.length)]
				return [
				combinedWord,
				getWordGroups(combinedWord)
			]}
		)
	);

	let textEncoder = new TextEncoder('utf-8');
	
	// Finally, the challenge is passed if no test cases failed
	return context.noFailures(
		Math.floor(textEncoder.encode(context.code).length * getWordGroups(context.code) / 3)
	);
})

Example Code

function getWordGroups(word) {
	return [...word].reduce(({prev,groups,direction},char)=>{
		let valid = true;
		if (char < prev && direction > 0) {
			valid = false;
		}
		if (char > prev && direction < 0) {
			valid = false;
		}
		
		return {
			prev: char,
			groups: valid ? groups:groups+1,
			direction: valid ? char > prev ? 1 : char < prev ? -1 : direction : 0
		}
	},{prev:word[0],groups:1,direction:0}).groups
}

process.stdin.on('data',e=>(''+e).split('\n').forEach(
	i=>console.log(getWordGroups(i))
))

Comments

mousetail
mousetail
This suggestion will automatically be accepted if it gets enough 👍
accepted

Suggestion to edit judge

Output
Expected
36 identical lines skipped return context.noFailures( return context.noFailures( Math.floor(textEncoder.encode(context.code.length) * getWordGroups(context.code) / 3) Math.floor(textEncoder.encode(context.code).length * getWordGroups(context.code) / 3) ); );