Cockroach Salad
Description
Cockroach Salad is a card game designed by Jacques Zeimet in 2007. The rules are as follows:
- When you play a card, if there is no restriction, you must say the name of the vegetable printed on your card.
- However, you can not say the same name twice in a row. If you can not say the correct vegetable, you must say say an arbitrary different vegetable.
- One vegetable name is banned and you can not say it. If you would need to say it, say an arbitrary different vegetable.
In this challenge, we’ll have 4 vegetables: a (lettuce), b (tomato), c (cucumber), and d (grape). Given the order you draw cards from the deck, output what vegetables you would say out out. If there are capital letters A, B, C, D in the input, those mean that vegetable is now banned. Do not include these in the output. One vegetable is banned at a time, a new banned vegetable replaces the last one.
Worked Out Example
Lets take the input: aabAaacd
- First, we see an
a. This is valid so we outputa. - Then we get an
aagain. We can not sayatwice in a row, so we outputb. We could have also outputtedcordand it would also be valid. - Next, we see
b. However, we can’t outputbtwice in a row so we outputd. We could have also outputtedaorc. - Now we see an
A. This is a capital so it meansais now banned. We output nothing. - Then we get an
a, butais banned.dwas last outputted so we can’t print that either. So we outputc. - Then another
a. We outputd, sinceais banned. - Next,
c.cis valid so we must outputc. - Next,
d, which is also valid.
So the final output could be abadcdcd, but there are other valid options.
Each line in the input will be one string.
Judge
(async function*(context: Context): Challenge { function validateOutput(input: string, output: string): boolean { output = output.trimEnd(); let i=0; let previous = ''; let banned = ''; for (const character of input) { if (character == character.toLocaleUpperCase()) { banned = character.toLocaleLowerCase(); continue; } if (character != previous && character != banned) { if (output[i] != character) { return false; } } else if (output[i] == previous || output[i] == banned) { console.error(`${output[i]} ${previous} ${banned}`); return false } previous = output[i]; i++; } return i==output.length; } function solve(input: string): string { let previous = ''; let banned = ''; let output = ''; for (const character of input) { if (character.toLocaleUpperCase() == character) { banned = character.toLocaleLowerCase(); continue; } if (character != banned && character != previous) { output += character; previous = character; continue; } else { let char = ['a','b','c','d'].filter(i=>i!=previous && i!=banned)[0]; previous = char; output += char; continue; } } return output; } function randomString(chars: string, length: number): string { let string = ''; for (let i=0; i<length; i++) { string += chars[Math.floor(Math.random() * chars.length)] } return string; } class FakeSolve { input: string; output: string; constructor(input: string, output: string) { this.input = input; this.output = output; } toString() { return this.output; } } let randomTestCases = []; for (let i=0; i<100; i++) { randomTestCases.push(randomString('aaaabbbbccccddddABCD', Math.floor(Math.random() * 100) + 25)) } // Automatically shuffle and deal test cases over multiple runs yield* context.runTestCases( randomTestCases.map( i=>[i, new FakeSolve(i, solve(i))] as [string,FakeSolve] ), { compareFunction(a, b) { return validateOutput(b.input, a) } } ); // Finally, the challenge is passed if no test cases failed return context.noFailures(); })
Example Code
function solve(input) { let previous = ''; let banned = ''; let output = ''; for (const character of input) { if (character.toLocaleUpperCase() == character) { banned = character.toLocaleLowerCase(); continue; } if (character != banned && character != previous) { output += character; previous = character; continue; } else { let char = ['a','b','c','d'].filter(i=>i!=previous && i!=banned)[0]; previous = char; output += char; continue; } } return output; } process.stdin.on('data',i=>(''+i).split('\n').forEach(k=>console.log(solve(k))))