Encode text to a puzzle with key

by Ben Gillbanks

HTML

<input type="text" id="msg" placeholder="Type your message here" value="Go upstairs and look under mummy and daddy's duvet cover to find your prize">
	<button id="go">Generate Puzzle</button>

	<h3>Key (letter → number)</h3>
	<pre id="key"></pre>

	<h3>Encoded Puzzle</h3>
	<pre id="puzzle"></pre>

CSS

body { font-family: sans-serif; padding: 1rem; line-height: 2; }
		input, button { font-size: 1rem; padding: 0.5rem; }
		pre { background: #f4f4f4; padding: 1rem; white-space: initial; line-height: 2; }

JavaScript

const btn = document.getElementById('go');
		const msg = document.getElementById('msg');
		const keyOut = document.getElementById('key');
		const puzzleOut = document.getElementById('puzzle');

		btn.addEventListener('click', () => {
			const text = msg.value;
			// extract unique letters (A‑Z), uppercase
			const letters = Array.from(new Set(
				text.toUpperCase().match(/[A-Z]/g) || []
			));
			// shuffle letters
			for (let i = letters.length - 1; i > 0; i--) {
				const j = Math.floor(Math.random() * (i + 1));
				[letters[i], letters[j]] = [letters[j], letters[i]];
			}
			// assign numbers
			const map = {};
			letters.forEach((l, i) => map[l] = i + 1);

			// build key output
			keyOut.textContent = letters
				.map(l => `${map[l]} = ${l}`)
				.join(', ');

			// build encoded puzzle
			const encoded = Array.from(text).map(ch => {
				const up = ch.toUpperCase();
				return map[up] || ch;
			});
			let output = encoded.join(', ');
			output.replace( ' ,', ' ' );
			puzzleOut.textContent = output;
		});