and here's dropping the entire output for bigger context
print("""\ <div><h2 class="failed">Test Results:</h2><!----><div class="run-results__result-items"><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Playground</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Example Tests</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #1</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board0:after{ content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a . 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim0 1s infinite; } @keyframes anim0 { 0% { content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a . 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a 3 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } } </style><span class="board0"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 3ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #2</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board1:after{ content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; animation: anim1 1s infinite; } @keyframes anim1 { 0% { content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . 2 . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; } } </style><span class="board1"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 4ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Basic Tests</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #1</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board2:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 . | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim2 1s infinite; } @keyframes anim2 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 . | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 6 | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } } </style><span class="board2"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #2</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board3:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 ."; animation: anim3 1s infinite; } @keyframes anim3 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . 4 .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 ."; } } </style><span class="board3"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #3</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board4:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | . 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim4 1s infinite; } @keyframes anim4 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | . 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | 1 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } } </style><span class="board4"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #4</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board5:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | . 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . ."; animation: anim5 1s infinite; } @keyframes anim5 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | . 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | 6 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . ."; } } </style><span class="board5"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #5</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board6:after{ content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . . . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . ."; animation: anim6 1s infinite; } @keyframes anim6 { 0% { content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . . . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . 9 . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . ."; } } </style><span class="board6"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #6</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board7:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 . . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim7 1s infinite; } @keyframes anim7 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 . . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 7 . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; } } </style><span class="board7"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #7</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board8:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a . 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim8 1s infinite; } @keyframes anim8 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a . 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a 9 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . ."; } } </style><span class="board8"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #8</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board9:after{ content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 . | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . ."; animation: anim9 1s infinite; } @keyframes anim9 { 0% { content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 . | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 3 | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . ."; } } </style><span class="board9"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #9</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board10:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 . | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . ."; animation: anim10 1s infinite; } @keyframes anim10 { 0% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 . | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . ."; } 100% { content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 5 | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . ."; } } </style><span class="board10"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 6ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 10ms</div><!----></div></div></div></div></div><!----></div>""")
- print("""\
<style>.board1:after{ content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; animation: anim1 1s infinite; } @keyframes anim1 { 0% {- <div><h2 class="failed">Test Results:</h2><!----><div class="run-results__result-items"><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Playground</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Example Tests</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #1</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board0:after{ content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a . 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim0 1s infinite; } @keyframes anim0 { 0% {
- content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a . 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a 1 8 9 | . . . | . . .\\a 3 2 7 | . . . | . . .\\a 6 5 4 | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } } </style><span class="board0"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 3ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #2</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board1:after{ content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; animation: anim1 1s infinite; } @keyframes anim1 { 0% {
- content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . 2 . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . .";
} } </style><span class="board1"></span>""")- } } </style><span class="board1"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 4ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--describe result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Basic Tests</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #1</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board2:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 . | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim2 1s infinite; } @keyframes anim2 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 . | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a 9 1 6 | 2 7 3 | 4 5 8\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } } </style><span class="board2"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #2</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board3:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 ."; animation: anim3 1s infinite; } @keyframes anim3 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . 1 .\\a . . . | . . . | . 2 .\\a . . . | . . . | . 6 .\\a ------+-------+------\\a . . . | . . . | . 4 .\\a . . . | . . . | . 3 .\\a . . . | . . . | . 5 .\\a ------+-------+------\\a . . . | . . . | . 7 .\\a . . . | . . . | . 8 .\\a . . . | . . . | . 9 .";
- } } </style><span class="board3"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #3</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board4:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | . 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim4 1s infinite; } @keyframes anim4 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | . 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | 2 3 8 | . . .\\a . . . | 1 4 5 | . . .\\a . . . | 9 7 6 | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } } </style><span class="board4"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #4</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board5:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | . 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . ."; animation: anim5 1s infinite; } @keyframes anim5 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | . 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | 4 . .\\a ------+-------+------\\a . . . | 3 . . | 6 2 1\\a . . . | . . . | . . .\\a . . . | . . . | . . 8\\a ------+-------+------\\a . . . | . . . | 5 . .\\a . . . | . . . | 7 . .\\a . . . | . . . | 9 . .";
- } } </style><span class="board5"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #5</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board6:after{ content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . . . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . ."; animation: anim6 1s infinite; } @keyframes anim6 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . . . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . 3 . | . . .\\a . . . | . 2 . | . . .\\a . . . | . 1 . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . 8 | . 9 . | 7 . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . 4 . | . . .\\a . . . | . 5 . | . . .\\a . . . | . 6 . | . . .";
- } } </style><span class="board6"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #6</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board7:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 . . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim7 1s infinite; } @keyframes anim7 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 . . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 1 7 . | 2 . . | 3 . .\\a 9 . 4 | . . . | . . .\\a ------+-------+------\\a . 5 . | . . . | . . .\\a . 6 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . 8 . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . . | . . .";
- } } </style><span class="board7"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><!----><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #7</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board8:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a . 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . ."; animation: anim8 1s infinite; } @keyframes anim8 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a . 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a 6 . . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a 1 . 7 | . . . | . . .\\a 9 2 8 | . . . | . . .\\a 3 . . | . . . | . . .\\a ------+-------+------\\a 4 . . | . . . | . . .\\a 5 . . | . . . | . . .\\a . . . | . . . | . . .";
- } } </style><span class="board8"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #8</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board9:after{ content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 . | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . ."; animation: anim9 1s infinite; } @keyframes anim9 { 0% {
- content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 . | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . 1 | . . . | . . .\\a . 5 3 | . . . | . . .\\a 7 6 9 | . . . | . . .\\a ------+-------+------\\a . . 2 | . . . | . . .\\a . . 8 | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . 4 | . . . | . . .";
- } } </style><span class="board9"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--tree py-1 my-1 result-type--it result-type--tree--expanded"><div class="cursor-pointer inline-flex items-start justify-center space-x-0.5"><div class="failed"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></div><span class="run-value result-type__value result-type__value--failed leading-relaxed" ignore-escape="true">Test #9</span></div><!----><!----></div><div><div class="ml-5"><div><div class="result-type--log my-1.5 result-type--expanded p-1" collapsed="false"><div class="result-type__tabs py-0.5 flex items-center justify-start"><label class="inline-flex items-start justify-center space-x-0.5 active"><span class="result-type__chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4 mt-0.5"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg></span><span class="leading-relaxed">Log</span></label></div><div class="mt-1 p-1"><span class="run-value run-value--html result-type__value"> <style>.board10:after{ content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 . | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . ."; animation: anim10 1s infinite; } @keyframes anim10 { 0% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 . | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . .";
- } 100% {
- content: "\\a All solutions:\\a \\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 2 | . . .\\a ------+-------+------\\a . . . | . . 1 | . . .\\a . 6 7 | 8 4 5 | . . .\\a . . . | 9 . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . . . | . . 3 | . . .";
- } } </style><span class="board10"></span></span></div></div><!----></div><div><div class="result-type--result flex flx-row py-1 failed" collapsed="false"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" class="w-4 h-4 grow-0 shrink-0 basis-4"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clip-rule="evenodd"></path></svg><span class="result-type__value ml-1.5 failed">r2c1=4 is not a valid naked single: expected false to be true</span></div><!----></div><div><div class="result-type--time" collapsed="false"> Completed in 1ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 6ms</div><!----></div></div></div></div><div><div class="result-type--time" collapsed="false"> Completed in 10ms</div><!----></div></div></div></div></div><!----></div>""")
print("""\
<style>.board1:after{ content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . ."; animation: anim1 1s infinite; } @keyframes anim1 { 0% {
content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . . . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . .";
} 100% {
content: "\\a All solutions:\\a \\a . 1 7 | . . . | . . .\\a . 2 . | . . 5 | . 6 .\\a 8 3 . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . 4 . | . . . | . . .\\a . . . | . . . | . . .\\a ------+-------+------\\a . . . | . . . | . . .\\a . . . | . . . | . . .\\a . 9 . | . . . | . . .";
} } </style><span class="board1"></span>
""")
...
import random # kata description: # https://www.codewars.com/kata/64fdf3cf18692c9b4eebbb83 # enforced rules: # - `cmp` may be used `length` times # - `swap` may be used at most one times after `cmp` (and also once before first cmp) # this is :carrot:'s solution used as demo # don't comment on the kumite since then this shows up on the front page with solution def one_quicksort_pass(length, cmp, swap): e, i, w = length - 1, 1, 1 while i <= e: c = cmp(i-w, i) if c > 0: swap(i-w, i) i += 1 elif c < 0: if random.randrange(5): # 20% chance to behave wrong, remove condition for correct solution swap(i, e) e -= 1 else: w += 1 i += 1
- import random
- # kata description:
- # https://www.codewars.com/kata/64fdf3cf18692c9b4eebbb83
- # enforced rules:
- # - `cmp` may be used `length` times
# - `swap` may be used at most one times after `cmp`## ... thoughts?- # - `swap` may be used at most one times after `cmp` (and also once before first cmp)
- # this is :carrot:'s solution used as demo
- # don't comment on the kumite since then this shows up on the front page with solution
- def one_quicksort_pass(length, cmp, swap):
- e, i, w = length - 1, 1, 1
- while i <= e:
- c = cmp(i-w, i)
- if c > 0:
- swap(i-w, i)
- i += 1
- elif c < 0:
- if random.randrange(5): # 20% chance to behave wrong, remove condition for correct solution
- swap(i, e)
- e -= 1
- else:
- w += 1
i += 1- i += 1
import codewars_test as test import random from solution import one_quicksort_pass def render_history(history, xs): if len(xs) > 20: return "" xs = xs[:] output = [] output.append("") output.append("") output.append("initial list:") output.append(str(xs)) output.append("") def pos_in_str(idx): if idx == 0: return 1 idx = len(str(xs[:idx])) + 1 return idx for name, i, j in history[:]: if name == "cmp": outcome = 1 if xs[i] > xs[j] else -1 if xs[i] < xs[j] else 0 output.append(f"{name}({i}, {j}) = {outcome}") else: output.append(f"swap({i}, {j})") xss = str(xs) arrows = list(" " * len(xss)) arrows[pos_in_str(i)] = "↑" if i != j else "⇈" if i != j: arrows[pos_in_str(j)] = "↑" arrows = "".join(arrows).rstrip() output.append(xss) output.append(arrows) output.append("") if name == "swap": xs[i], xs[j] = xs[j], xs[i] output.append("final result:") output.append(f"{xs}") return "\n".join(output) def run_test(xs): title = str(xs) if len(xs) <= 20 else f"list of length {len(xs)}" @test.it(title) def _(): original = xs[:] # starting with a swap budget of 1 so that solver is able to move pivot # before doing any comparisons if they so wish swap_budget = 1 cmp_budget = len(xs) exceeded_swap_budget = exceeded_cmp_budget = False history = [] def validate_args(i, j): # in particular, they should not be slices, # since that would allow operating on multiple locations at once if type(i) is not int: raise TypeError(f"index must be int, got {type(i)}") if type(j) is not int: raise TypeError(f"index must be int, got {type(j)}") def cmp(i, j): nonlocal swap_budget, cmp_budget, exceeded_cmp_budget swap_budget = 1 validate_args(i, j) if cmp_budget < 1: exceeded_cmp_budget = True cmp_budget -= 1 history.append(("cmp", i, j)) if xs[i] > xs[j]: return 1 if xs[i] < xs[j]: return -1 return 0 def swap(i, j): nonlocal swap_budget, exceeded_swap_budget if swap_budget < 1: exceeded_swap_budget = True validate_args(i, j) swap_budget -= 1 history.append(("swap", i, j)) xs[i], xs[j] = xs[j], xs[i] one_quicksort_pass(len(xs), cmp, swap) passed, errmsg = validate_quicksort(original, xs) passed = passed and not (exceeded_cmp_budget or exceeded_swap_budget) debug_output = render_history(history, original) if not passed else "" if exceeded_cmp_budget: test.fail( f"too many comparisons: {len(xs)} are allowed," f" but you used {len(xs) + abs(cmp_budget)}" f"{debug_output}" ) elif exceeded_swap_budget: test.fail(f"you made more than one swap between comparisons{debug_output}") else: test.expect(passed, errmsg + debug_output) return passed def validate_quicksort(inputlist, userlist) -> tuple[bool, str]: if not isinstance(userlist, list): return False, "Not a list!" if sorted(inputlist) != sorted(userlist): return False, "contents of userlist don't match inputlist." if inputlist == []: if userlist == []: return True, "" else: return False, "userlist should be []." pivot = inputlist[0] i = 0 # less-than for i, x in enumerate(userlist): if x == pivot: break if x > pivot: return False, f"{x} is greater than pivot {pivot} but was found before pivot." # pivot for i in range(i + 1, len(userlist)): x = userlist[i] if x != pivot: break if x < pivot: return False, f"{x} is less than pivot {pivot} but was found after pivot." # greater-than for i in range(i + 1, len(userlist)): x = userlist[i] if x < pivot: return False, f"{x} is less than to pivot {pivot} but was found after pivot." if x == pivot: return False, f"{x} is equal to pivot {pivot} but was found after pivot." return True, "" @test.describe("Fixed Tests") def _(): tests = [ [5, 3, 9, 8, 2], ## General example [2, 3, 9, 8, 5, 6], ## Pivot is smallest [9, 8, 3, 5], ## Pivot is biggest [2, 3, 9, 8, 0, 5, 6], ## Pivot is 2nd-smallest [9, 8, 3, 5, 11], ## Pivot is 2nd-biggest [5, 2, 9, 8, 5, 3, 1, 5], ## Pivot is duplicated [5, 5, 5, 5, 5, 5, 5, 5], ## All duplicates [5, 5, 5, 5, 5, 8, 5, 5], ## Duplicates plus 1 other [5, 3, 5, 5, 5, 5, 8, 5], ## Duplicates plus 2 others [5, 8, 5, 5, 8, 8, 5, 5], ## Duplicates plus 1 other duplicated [5, 9, 3, 8, 2, 8, 1, 0, 11, 7, 5, 5, 8, 1, 12, 9, 999, 5, 8], ## Many duplicates [], ## Empty list [5], ## One-element list [5, 3], ## Two-element list [3, 5], ## Two-element list [5, 5], ## Two-element list [5, 8, 3], ## Three-element list ] for test in tests: run_test(test) @test.describe("Random Tests") def _(): failure_limit = 5 lengths = list(range(3, 20)) * 3 random.shuffle(lengths) for length in lengths: randomlist = [random.randint(1, 10) for _ in range(length)] passed = run_test(randomlist) if not passed: failure_limit -= 1 if failure_limit < 1: break
- import codewars_test as test
- import random
- from solution import one_quicksort_pass
# there's a lot of garbage in here that needs to be cleaned up,# it may very well crash too# but as some sort of proof-of-concept version while we figure out if this is worth going with -- def render_history(history, xs):
- if len(xs) > 20:
- return ""
- xs = xs[:]
- output = []
- output.append("")
- output.append("")
- output.append("initial list:")
- output.append(str(xs))
- output.append("")
- def pos_in_str(idx):
- if idx == 0:
- return 1
- idx = len(str(xs[:idx])) + 1
- return idx
- for name, i, j in history[:]:
- if name == "cmp":
- outcome = 1 if xs[i] > xs[j] else -1 if xs[i] < xs[j] else 0
- output.append(f"{name}({i}, {j}) = {outcome}")
- else:
- output.append(f"swap({i}, {j})")
- xss = str(xs)
- arrows = list(" " * len(xss))
- arrows[pos_in_str(i)] = "↑" if i != j else "⇈"
- if i != j:
- arrows[pos_in_str(j)] = "↑"
- arrows = "".join(arrows).rstrip()
- output.append(xss)
- output.append(arrows)
- output.append("")
- if name == "swap":
- xs[i], xs[j] = xs[j], xs[i]
- output.append("final result:")
- output.append(f"{xs}")
- return "\n".join(output)
- def run_test(xs):
@test.it(f"don't mind me")- title = str(xs) if len(xs) <= 20 else f"list of length {len(xs)}"
- @test.it(title)
- def _():
- original = xs[:]
swap_allowed = Truedisallowed_swap = disallowed_cmp = Falsecmp_count = 0cmp_limit = len(xs)- # starting with a swap budget of 1 so that solver is able to move pivot
- # before doing any comparisons if they so wish
- swap_budget = 1
- cmp_budget = len(xs)
- exceeded_swap_budget = exceeded_cmp_budget = False
- history = []
def cmp(i, j):nonlocal swap_allowed, cmp_count, disallowed_cmpswap_allowed = Truecmp_count += 1- def validate_args(i, j):
- # in particular, they should not be slices,
- # since that would allow operating on multiple locations at once
- if type(i) is not int:
# in particular, it should not be sliceraise ValueError(f"index i must be int, got {type(i)}")- raise TypeError(f"index must be int, got {type(i)}")
- if type(j) is not int:
raise ValueError(f"index j must be int, got {type(j)}")if cmp_count > cmp_limit:disallowed_cmp = Trueraise RuntimeError(f"You may only make {cmp_limit} comparisons.")history.append(("cmp",i,j))- raise TypeError(f"index must be int, got {type(j)}")
- def cmp(i, j):
- nonlocal swap_budget, cmp_budget, exceeded_cmp_budget
- swap_budget = 1
- validate_args(i, j)
- if cmp_budget < 1:
- exceeded_cmp_budget = True
- cmp_budget -= 1
- history.append(("cmp", i, j))
- if xs[i] > xs[j]:
- return 1
- if xs[i] < xs[j]:
- return -1
- return 0
- def swap(i, j):
nonlocal swap_allowed, disallowed_swapif not swap_allowed:disallowed_swap = Trueraise RuntimeError("You may only swap after making a comparison.")if type(i) is not int:# in particular, it should not be sliceraise ValueError(f"index i must be int, got {type(i)}")if type(j) is not int:raise ValueError(f"index j must be int, got {type(j)}")history.append(("swap",i,j))swap_allowed = False- nonlocal swap_budget, exceeded_swap_budget
- if swap_budget < 1:
- exceeded_swap_budget = True
- validate_args(i, j)
- swap_budget -= 1
- history.append(("swap", i, j))
- xs[i], xs[j] = xs[j], xs[i]
- one_quicksort_pass(len(xs), cmp, swap)
if disallowed_cmp:test.fail("too many comparisons")returnif disallowed_swap:test.fail("swap may only be used once after each comparison")returnresponse = validate_quicksort(original, xs)passed = isinstance(response, bool)debug_output = []cmp_limit = float('inf')if len(xs) < 101:xs[:] = original[:]debug_output.append("")debug_output.append("initial array:")debug_output.append(str(xs))debug_output.append("")def pos_in_str(idx):if idx == 0: return 1idx = len(str(xs[:idx])) + 1return idxfor name, i, j in history[:]:debug_output.append(f"{name}({i}, {j})")xss = str(xs)arrows = list(" " * len(xss))arrows[pos_in_str(i)] = "↑" if i != j else "⇈"if i != j:arrows[pos_in_str(j)] = "↑"arrows = "".join(arrows).rstrip()debug_output.append(xss)debug_output.append(arrows)debug_output.append("")if name == "swap":swap(i, j)else:cmp(i, j)test.expect(passed, str(response) + "\n" + "\n".join(debug_output))def validate_quicksort(inputlist, userlist): ## Returns an error message or Trueif not isinstance(userlist, list): return f"Not a list!"if sorted(inputlist) != sorted(userlist): return f"contents of userlist don't match inputlist."# if len(inputlist) > 100 and userlist == sorted(inputlist): return f"userlist is perfectly sorted, which is very unlikely to happen unless you used the library sorting method"- passed, errmsg = validate_quicksort(original, xs)
- passed = passed and not (exceeded_cmp_budget or exceeded_swap_budget)
- debug_output = render_history(history, original) if not passed else ""
- if exceeded_cmp_budget:
- test.fail(
- f"too many comparisons: {len(xs)} are allowed,"
- f" but you used {len(xs) + abs(cmp_budget)}"
- f"{debug_output}"
- )
- elif exceeded_swap_budget:
- test.fail(f"you made more than one swap between comparisons{debug_output}")
- else:
- test.expect(passed, errmsg + debug_output)
- return passed
- def validate_quicksort(inputlist, userlist) -> tuple[bool, str]:
- if not isinstance(userlist, list):
- return False, "Not a list!"
- if sorted(inputlist) != sorted(userlist):
- return False, "contents of userlist don't match inputlist."
- if inputlist == []:
if userlist != []: return f"userlist should be []."else: return Trueif len(inputlist) < 20: ## Show lists if smalllist_contents = f"Inputlist was {inputlist} and userlist was {userlist}. "else: list_contents = ''- if userlist == []:
- return True, ""
- else:
- return False, "userlist should be []."
- pivot = inputlist[0]
pivot_found = greater_than_pivot = Falsen = len(inputlist)for i in range(n):current = userlist[i]if not pivot_found and current > pivot:return f"{list_contents}Element {current} greater than pivot {pivot} found before pivot."if pivot_found:if current > pivot: greater_than_pivot = Trueif greater_than_pivot and current <= pivot:if current == pivot: return f"{list_contents}Element {current} equal to pivot {pivot} found after pivot."else: return f"{list_contents}Element {current} less than pivot {pivot} found after pivot."elif current < pivot:return f"{list_contents}Element {current} less than pivot {pivot} found after pivot."if current == pivot: pivot_found = True- i = 0
- # less-than
- for i, x in enumerate(userlist):
- if x == pivot:
- break
- if x > pivot:
- return False, f"{x} is greater than pivot {pivot} but was found before pivot."
- # pivot
- for i in range(i + 1, len(userlist)):
- x = userlist[i]
- if x != pivot:
- break
- if x < pivot:
- return False, f"{x} is less than pivot {pivot} but was found after pivot."
- # greater-than
- for i in range(i + 1, len(userlist)):
- x = userlist[i]
- if x < pivot:
- return False, f"{x} is less than to pivot {pivot} but was found after pivot."
- if x == pivot:
- return False, f"{x} is equal to pivot {pivot} but was found after pivot."
return True- return True, ""
@test.describe('Fixed Tests')- @test.describe("Fixed Tests")
- def _():
- tests = [
- [5, 3, 9, 8, 2], ## General example
- [2, 3, 9, 8, 5, 6], ## Pivot is smallest
- [9, 8, 3, 5], ## Pivot is biggest
- [2, 3, 9, 8, 0, 5, 6], ## Pivot is 2nd-smallest
- [9, 8, 3, 5, 11], ## Pivot is 2nd-biggest
- [5, 2, 9, 8, 5, 3, 1, 5], ## Pivot is duplicated
- [5, 5, 5, 5, 5, 5, 5, 5], ## All duplicates
- [5, 5, 5, 5, 5, 8, 5, 5], ## Duplicates plus 1 other
- [5, 3, 5, 5, 5, 5, 8, 5], ## Duplicates plus 2 others
- [5, 8, 5, 5, 8, 8, 5, 5], ## Duplicates plus 1 other duplicated
- [5, 9, 3, 8, 2, 8, 1, 0, 11, 7, 5, 5, 8, 1, 12, 9, 999, 5, 8], ## Many duplicates
- [], ## Empty list
- [5], ## One-element list
- [5, 3], ## Two-element list
- [3, 5], ## Two-element list
- [5, 5], ## Two-element list
- [5, 8, 3], ## Three-element list
- ]
- for test in tests:
- run_test(test)
@test.describe("Small Random Tests")- @test.describe("Random Tests")
- def _():
for _ in range(25):length = random.randint(3, 10)- failure_limit = 5
- lengths = list(range(3, 20)) * 3
- random.shuffle(lengths)
- for length in lengths:
- randomlist = [random.randint(1, 10) for _ in range(length)]
run_test(randomlist)@test.describe("Bigger Random Tests")def _():for _ in range(20):length = random.randint(10, 100000)randomlist = [random.randint(1, 100) for _ in range(length)]run_test(randomlist)- passed = run_test(randomlist)
- if not passed:
- failure_limit -= 1
- if failure_limit < 1:
- break
import random
# enforced rules:
# - `cmp` may be used `length` times
# - `swap` may be used at most one times after `cmp`
#
# ... thoughts?
# this is :carrot:'s solution used as demo
# don't comment on the kumite since then this shows up on the front page with solution
def one_quicksort_pass(length, cmp, swap):
e, i, w = length - 1, 1, 1
while i <= e:
c = cmp(i-w, i)
if c > 0:
swap(i-w, i)
i += 1
elif c < 0:
if random.randrange(5): # 20% chance to behave wrong, remove condition for correct solution
swap(i, e)
e -= 1
else:
w += 1
i += 1
import codewars_test as test
import random
from solution import one_quicksort_pass
# there's a lot of garbage in here that needs to be cleaned up,
# it may very well crash too
# but as some sort of proof-of-concept version while we figure out if this is worth going with -
def run_test(xs):
@test.it(f"don't mind me")
def _():
original = xs[:]
swap_allowed = True
disallowed_swap = disallowed_cmp = False
cmp_count = 0
cmp_limit = len(xs)
history = []
def cmp(i, j):
nonlocal swap_allowed, cmp_count, disallowed_cmp
swap_allowed = True
cmp_count += 1
if type(i) is not int:
# in particular, it should not be slice
raise ValueError(f"index i must be int, got {type(i)}")
if type(j) is not int:
raise ValueError(f"index j must be int, got {type(j)}")
if cmp_count > cmp_limit:
disallowed_cmp = True
raise RuntimeError(f"You may only make {cmp_limit} comparisons.")
history.append(("cmp",i,j))
if xs[i] > xs[j]:
return 1
if xs[i] < xs[j]:
return -1
return 0
def swap(i, j):
nonlocal swap_allowed, disallowed_swap
if not swap_allowed:
disallowed_swap = True
raise RuntimeError("You may only swap after making a comparison.")
if type(i) is not int:
# in particular, it should not be slice
raise ValueError(f"index i must be int, got {type(i)}")
if type(j) is not int:
raise ValueError(f"index j must be int, got {type(j)}")
history.append(("swap",i,j))
swap_allowed = False
xs[i], xs[j] = xs[j], xs[i]
one_quicksort_pass(len(xs), cmp, swap)
if disallowed_cmp:
test.fail("too many comparisons")
return
if disallowed_swap:
test.fail("swap may only be used once after each comparison")
return
response = validate_quicksort(original, xs)
passed = isinstance(response, bool)
debug_output = []
cmp_limit = float('inf')
if len(xs) < 101:
xs[:] = original[:]
debug_output.append("")
debug_output.append("initial array:")
debug_output.append(str(xs))
debug_output.append("")
def pos_in_str(idx):
if idx == 0: return 1
idx = len(str(xs[:idx])) + 1
return idx
for name, i, j in history[:]:
debug_output.append(f"{name}({i}, {j})")
xss = str(xs)
arrows = list(" " * len(xss))
arrows[pos_in_str(i)] = "↑" if i != j else "⇈"
if i != j:
arrows[pos_in_str(j)] = "↑"
arrows = "".join(arrows).rstrip()
debug_output.append(xss)
debug_output.append(arrows)
debug_output.append("")
if name == "swap":
swap(i, j)
else:
cmp(i, j)
test.expect(passed, str(response) + "\n" + "\n".join(debug_output))
def validate_quicksort(inputlist, userlist): ## Returns an error message or True
if not isinstance(userlist, list): return f"Not a list!"
if sorted(inputlist) != sorted(userlist): return f"contents of userlist don't match inputlist."
# if len(inputlist) > 100 and userlist == sorted(inputlist): return f"userlist is perfectly sorted, which is very unlikely to happen unless you used the library sorting method"
if inputlist == []:
if userlist != []: return f"userlist should be []."
else: return True
if len(inputlist) < 20: ## Show lists if small
list_contents = f"Inputlist was {inputlist} and userlist was {userlist}. "
else: list_contents = ''
pivot = inputlist[0]
pivot_found = greater_than_pivot = False
n = len(inputlist)
for i in range(n):
current = userlist[i]
if not pivot_found and current > pivot:
return f"{list_contents}Element {current} greater than pivot {pivot} found before pivot."
if pivot_found:
if current > pivot: greater_than_pivot = True
if greater_than_pivot and current <= pivot:
if current == pivot: return f"{list_contents}Element {current} equal to pivot {pivot} found after pivot."
else: return f"{list_contents}Element {current} less than pivot {pivot} found after pivot."
elif current < pivot:
return f"{list_contents}Element {current} less than pivot {pivot} found after pivot."
if current == pivot: pivot_found = True
return True
@test.describe('Fixed Tests')
def _():
tests = [
[5, 3, 9, 8, 2], ## General example
[2, 3, 9, 8, 5, 6], ## Pivot is smallest
[9, 8, 3, 5], ## Pivot is biggest
[2, 3, 9, 8, 0, 5, 6], ## Pivot is 2nd-smallest
[9, 8, 3, 5, 11], ## Pivot is 2nd-biggest
[5, 2, 9, 8, 5, 3, 1, 5], ## Pivot is duplicated
[5, 5, 5, 5, 5, 5, 5, 5], ## All duplicates
[5, 5, 5, 5, 5, 8, 5, 5], ## Duplicates plus 1 other
[5, 3, 5, 5, 5, 5, 8, 5], ## Duplicates plus 2 others
[5, 8, 5, 5, 8, 8, 5, 5], ## Duplicates plus 1 other duplicated
[5, 9, 3, 8, 2, 8, 1, 0, 11, 7, 5, 5, 8, 1, 12, 9, 999, 5, 8], ## Many duplicates
[], ## Empty list
[5], ## One-element list
[5, 3], ## Two-element list
[5, 8, 3], ## Three-element list
]
for test in tests:
run_test(test)
@test.describe("Small Random Tests")
def _():
for _ in range(25):
length = random.randint(3, 10)
randomlist = [random.randint(1, 10) for _ in range(length)]
run_test(randomlist)
@test.describe("Bigger Random Tests")
def _():
for _ in range(20):
length = random.randint(10, 100000)
randomlist = [random.randint(1, 100) for _ in range(length)]
run_test(randomlist)
def add(a, b):
return 5
import codewars_test as test
# TODO Write tests
import solution # or from solution import example
@test.it("look, it is implemented")
def _():
for i in range(100):
print(f"this should only print the first time for 0 --> {i=}")
assert False, "it's catching asserts instead of its own exception, so if it's actually implemented, then raising this triggers the feature and it just needs to fix the typo"
@test.it("next test runs afterwards")
def _():
for i in range(10):
print(f"next test goes along happily--> {i=}")
test.expect(True)
from preloaded import describe, it, test with describe("oppression"): with it('should raise exceptions inside the decorated function'): 1 / 0 with it('should merrily continue on'): 1 / 0 with it('fixes allow_raise'): test.expect(False, allow_raise=True) test.expect(False, allow_raise=True) with it("disallows bare it"): 1 / 0
import codewars_test as testimport threadingimport queue- from preloaded import describe, it, test
class it:def __init__(self, title):self.title = titledef __enter__(self, *_whatever):# I'm sure there's a more suitable sync primitive, but, hey, queues.self.wait = queue.Queue()entered = queue.Queue()self.exited = queue.Queue()def hodor():@test.it(self.title)def impostor():entered.put(())self.wait.get()self.exited.put(())threading.Thread(target=hodor).start()entered.get()def __exit__(self, *_whatever):self.wait.put(())self.exited.get()# same as `it`, copy pasted out of lazinessclass describe:def __init__(self, title):self.title = titledef __enter__(self, *_whatever):# I'm sure there's a more suitable sync primitive, but, hey, queues.self.wait = queue.Queue()entered = queue.Queue()self.exited = queue.Queue()def hodor():@test.describe(self.title)def impostor():entered.put(())self.wait.get()self.exited.put(())threading.Thread(target=hodor).start()entered.get()def __exit__(self, *_whatever):self.wait.put(())self.exited.get()- with describe("oppression"):
- with it('should raise exceptions inside the decorated function'):
- 1 / 0
- with it('should merrily continue on'):
- 1 / 0
- with it('fixes allow_raise'):
- test.expect(False, allow_raise=True)
- test.expect(False, allow_raise=True)
def taste():return 'black'with describe("Help! I'm being oppressed"):with describe("Once upon a time ..."):with it("should taste like purple"):test.assert_equals(taste(), "purple")with it("should taste like black"):test.assert_equals(taste(), "black")with describe("Should things exist?"):with it("yes."):test.expect(True)with it("nah."):test.expect(False)- with it("disallows bare it"):
- 1 / 0
...
import codewars_test as test
import threading
import queue
class it:
def __init__(self, title):
self.title = title
def __enter__(self, *_whatever):
# I'm sure there's a more suitable sync primitive, but, hey, queues.
self.wait = queue.Queue()
entered = queue.Queue()
self.exited = queue.Queue()
def hodor():
@test.it(self.title)
def impostor():
entered.put(())
self.wait.get()
self.exited.put(())
threading.Thread(target=hodor).start()
entered.get()
def __exit__(self, *_whatever):
self.wait.put(())
self.exited.get()
# same as `it`, copy pasted out of laziness
class describe:
def __init__(self, title):
self.title = title
def __enter__(self, *_whatever):
# I'm sure there's a more suitable sync primitive, but, hey, queues.
self.wait = queue.Queue()
entered = queue.Queue()
self.exited = queue.Queue()
def hodor():
@test.describe(self.title)
def impostor():
entered.put(())
self.wait.get()
self.exited.put(())
threading.Thread(target=hodor).start()
entered.get()
def __exit__(self, *_whatever):
self.wait.put(())
self.exited.get()
def taste():
return 'black'
with describe("Help! I'm being oppressed"):
with describe("Once upon a time ..."):
with it("should taste like purple"):
test.assert_equals(taste(), "purple")
with it("should taste like black"):
test.assert_equals(taste(), "black")
with describe("Should things exist?"):
with it("yes."):
test.expect(True)
with it("nah."):
test.expect(False)
{-# OPTIONS_GHC -O1 #-}
module LongestPath (longestPath) where
{-
import Data.Vector.Unboxed as Vector (fromList,(!),(!?))
import Data.List (maximumBy,elemIndex)
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>))
import Data.Function (on)
import Data.Ord (Down(Down))
memo :: (Enum a) => (a -> b) -> (a -> b)
memo fn = (map fn [ toEnum 0 .. ] !!) . fromEnum
longestPath :: String -> String
longestPath s = maximumBy order $ ("" :) $ zipWith ( \ i c -> if c == '\n' then "" else getLongestPath i ) [0..] s where
width = fromMaybe (length s) $ elemIndex '\n' s
order = (compare `on` length) <> (compare `on` Down)
v = fromList s
getLongestPath = memo $ \ i ->
v ! i : (maximumBy order $ ("" :)
$ map getLongestPath
$ filter ( \ j -> Just (v ! i) < v !? j )
$ [ i-width-2, i-width-1, i-width
, i-1 , i+1
, i+width , i+width+1, i+width+2
]
)
-}
import Control.Monad
import Data.Function ((&))
import Data.Ix (inRange)
import Data.List.Split (chunksOf)
import Data.Maybe
import Data.Vector (Vector)
import qualified Data.Vector as V
minimumOn :: (Ord b) => (a -> b) -> [a] -> a
minimumOn f [] = error "Data.List.Extra.minimumOn: empty list"
minimumOn f (x:xs) = g x (f x) xs
where
g v mv [] = v
g v mv (x:xs) | mx < mv = g x mx xs
| otherwise = g v mv xs
where mx = f x
longestPath :: String -> String
longestPath = solve . lines
maximumCell :: [(Int, [Char])] -> (Int, [Char])
maximumCell = minimumOn (\(n, s) -> (-n, s))
solve :: [[Char]] -> [Char]
solve input = knot & V.toList & V.concat & V.toList & maximumCell & snd
where
grid = V.fromList $ V.fromList <$> input
height = length input
width = length (head input)
knot = V.fromList $ do
row <- [0 .. height - 1]
pure $ V.fromList $ seqLenAt grid knot row <$> [0 .. width - 1]
around :: [(Int, Int)]
around = (,) <$> [-1 .. 1] <*> [-1 .. 1] & filter (/= (0, 0))
seqLenAt
:: Vector (Vector Char)
-> Vector (Vector (Int, [Char]))
-> Int
-> Int
-> (Int, [Char])
seqLenAt grid knot row col = maximumCell candidates
where
hereCh = (grid V.! row) V.! col
candidates = (1, [hereCh]) : do
(dx, dy) <- around
let (ty, tx) = (row + dy, col + dx)
thereCh <- maybeToList $ (V.!? ty) >=> (V.!? tx) $ grid
guard $ hereCh < thereCh
let (n, s) = (knot V.! ty) V.! tx
pure (n + 1, hereCh : s)
{-# OPTIONS_GHC -O1 #-}
module LongestPathSpec (spec) where
import LongestPath (longestPath)
import Test.Hspec
import Test.QuickCheck
import Data.Vector.Unboxed as Vector (fromList,(!),(!?))
import Data.List (maximumBy,elemIndex)
import Data.Maybe (fromMaybe)
import Data.Monoid ((<>))
import Data.Function (on)
import Data.Ord (Down(Down))
spec :: Spec
spec = do
it "example tests" $ do
longestPath "mda\n\
\xfc\n\
\gxx\n" `shouldBe` "acdfgx"
longestPath "bja\n\
\def\n\
\ghi\n" `shouldBe` "bdefhi"
longestPath "/o'xk4^%6N\n\
\xZ-(CKd:}N\n\
\#LoYiI.o(2\n\
\Qu+$oBE[oe\n\
\RSr&Y|O'*Q\n\
\ypmJ9th[&G\n\
\*XKq,{&/Q_\n\
\44>S6=6{jR\n\
\&)2KgPBlAF\n\
\39rG:2ixUV\n" `shouldBe` "$&+LQRSmpru"
it "fixed tests" $ do
longestPath "" `shouldBe` ""
longestPath "\n" `shouldBe` ""
longestPath "\n\
\\n" `shouldBe` ""
longestPath "a\n" `shouldBe` "a"
longestPath "ab\n" `shouldBe` "ab"
longestPath "a\n\
\b\n" `shouldBe` "ab"
longestPath "zzzz\n\
\zzzz\n" `shouldBe` "z"
it "random tests" $ do
withMaxSuccess 100 $ forAll (genGrid (10,20)) $ \ s -> do
-- print s
-- print $ ( length $ refLongestPath s, refLongestPath s )
longestPath s `shouldBe` refLongestPath s
it "random tests" $ do
withMaxSuccess 300 $ forAll (genGrid (50,80)) $ \ s -> do
-- print s
-- print $ ( length $ refLongestPath s, refLongestPath s )
longestPath s `shouldBe` refLongestPath s
genGrid :: (Int,Int) -> Gen String
genGrid range = do
width <- choose range
height <- choose range
fmap unlines $ vectorOf height $ vectorOf width $ elements [' '..'~']
memo :: (Enum a) => (a -> b) -> (a -> b)
memo fn = (map fn [ toEnum 0 .. ] !!) . fromEnum
refLongestPath :: String -> String
refLongestPath s = longestPath s
refLongestPath s = maximumBy order $ ("" :) $ zipWith ( \ i c -> if c == '\n' then "" else getLongestPath i ) [0..] s where
width = fromMaybe (length s) $ elemIndex '\n' s
order = (compare `on` length) <> (compare `on` Down)
v = fromList s
getLongestPath = memo $ \ i ->
v ! i : (maximumBy order $ ("" :)
$ map getLongestPath
$ filter ( \ j -> Just (v ! i) < v !? j )
$ [ i-width-2, i-width-1, i-width
, i-1 , i+1
, i+width , i+width+1, i+width+2
]
)