Find Joseph's Gift
Step: 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Challenge
Source code
+page.svelte
<script lang="ts">
import { submitReplaceState } from '$lib/util';
import type { PageData } from './$types';
export let data: PageData;
$: ({ presents, step } = data);
$: finalStep = presents.length;
let form: HTMLFormElement;
</script>
<h1>Find Joseph's Gift</h1>
<form on:submit={submitReplaceState} bind:this={form}>
<label for="num">Pick a number from 2 to 30:</label>
<input
id="num"
type="range"
min="2"
max="30"
name="presents"
value={presents.length}
on:input={() => form.requestSubmit()}
/>
<input type="hidden" name="step" value={step} />
<div class="controls">
<button disabled={step === 1} name="nstep" value="1">Start</button>
<button disabled={step === 1} name="nstep" value={step - 1}>Prev</button>
<button disabled={step >= finalStep} name="nstep" value={step + 1}>Next</button>
<button disabled={step >= finalStep} name="nstep" value={finalStep}>End</button>
</div>
</form>
<p>Step: {step}</p>
<div class="presents">
{#each presents as eliminated, idx}
<div class="present" class:eliminated class:chosen={step >= finalStep && !eliminated}>
{#if step >= finalStep && !eliminated}
🎁
{:else}
{idx + 1}
{/if}
</div>
{/each}
</div>
<style>
.presents {
display: grid;
grid-template-columns: repeat(auto-fit, 50px);
gap: 1rem;
width: 100%;
justify-content: center;
}
.present {
border: 1px solid black;
display: grid;
place-items: center;
aspect-ratio: 1/1;
height: 100%;
}
.eliminated {
border-style: dashed;
border-width: 3px;
}
.chosen {
border-width: 7px;
border-color: red;
font-size: 1.5rem;
}
form {
display: contents;
}
.controls {
display: flex;
gap: 0.5rem;
}
</style>
+page.ts
import type { PageLoad } from './$types';
export const load: PageLoad = ({ url }) => {
const stepParam = url.searchParams.get('nstep') ?? url.searchParams.get('step') ?? '1';
const numPresentsParam = url.searchParams.get('presents') ?? '22';
const numPresents = +numPresentsParam;
const step = Math.min(+stepParam, numPresents);
let presents: boolean[] = Array(numPresents).fill(false);
// there's probably a more efficient way
// ¯\_(ツ)_/¯
let pIdx = 1;
for (let i = 0; i < step; i++) {
if (i === numPresents - 1) continue;
let eliminated = pIdx % presents.length;
while (presents[eliminated] && eliminated < presents.length) {
eliminated = (eliminated + 1) % presents.length;
}
presents[eliminated] = true;
pIdx += 2;
}
return {
presents,
step
};
};