1
0

bef93-runner blogpost

This commit is contained in:
Mike Schwörer 2018-01-03 00:08:42 +01:00
parent a3c191a837
commit 4f7795c70b
Signed by: Mikescher
GPG Key ID: D3C7172E0A70F8CF
11 changed files with 324 additions and 97 deletions

View File

@ -53,6 +53,13 @@ body {
display: block;
width: 100%; }
.generic_hidden {
visibility: hidden !important; }
.generic_collapsed {
visibility: collapse !important;
display: none !important; }
#headerdiv {
z-index: 999;
background-color: #333;
@ -610,10 +617,17 @@ html, body {
background: #F8F8F8;
color: black;
border: 1px solid rgba(0, 0, 0, 0.15); }
.bce_code .bce_code_data {
.bce_code .bce_code_data, .bce_code .bce_code_editarea {
overflow-x: auto;
font-family: Consolas, Monaco, "Courier New", Menlo, monospace;
padding: 5px 9.5px;
line-height: 12pt;
font-size: 10pt; }
.bce_code .bce_code_editarea {
display: block;
resize: none;
box-sizing: border-box;
line-height: 12pt;
font-size: 10pt; }
.bce_code .bce_code_ctrl {
background: #BBB;
@ -722,8 +736,5 @@ html, body {
.bce_code_out .bce_code_out_right {
width: auto;
height: 150px; } }
.b93rnr_outpanel_hidden {
visibility: collapse;
display: none; }
/*# sourceMappingURL=styles.css.map */

View File

@ -5,11 +5,21 @@
color: black;
border: 1px solid rgba(0, 0, 0, 0.15);
.bce_code_data {
.bce_code_data, .bce_code_editarea {
overflow-x: auto;
font-family: $FONT_CODE;
padding: 5px 9.5px;
line-height: 12pt;
font-size: 10pt;
}
.bce_code_editarea {
display: block;
resize: none;
box-sizing: border-box;
line-height: 12pt;
font-size: 10pt;
}
@ -128,6 +138,4 @@
.bce_code_out_left { flex-grow: 0; height: 100px;}
.bce_code_out_right { width: auto; height: 150px;}
}
}
.b93rnr_outpanel_hidden { visibility: collapse; display: none; }
}

View File

@ -57,3 +57,6 @@ body {
display: block;
width: 100%;
}
.generic_hidden { visibility: hidden !important; }
.generic_collapsed { visibility: collapse !important; display: none !important; }

View File

@ -1,6 +1,15 @@
const BefState = Object.freeze ({ UNINIITIALIZED: {}, INITIAL: {}, RUNNING: {}, PAUSED: {} });
const BefSpeed = Object.freeze ({ SLOW: {str:'0'}, NORMAL: {str:'+'}, FAST: {str:'++'}, SUPERFAST: {str:'3+'}, MAX: {str:'4+'} });
const BefState = Object.freeze ({ INITIAL: {}, RUNNING: {}, PAUSED: {}, FINISHED: {}, EDIT: {} });
const BefSpeed = Object.freeze (
{
SLOW: {val:0,str:'0' },
NORMAL: {val:1,str:'+' },
FAST: {val:2,str:'++'},
SUPERFAST: {val:3,str:'3+'},
MAX: {val:4,str:'4+'},
get: function(i){ for (let x of Object.values(BefSpeed)) if (typeof(x)==='object' && String(x.val) === String(i)) return x; return null; },
max: function( ){let max = 0; for (let x of Object.values(BefSpeed)) if (typeof(x)==='object' ) max = Math.max(x.val); return max; },
});
Array.prototype.peek = function() { return this[this.length - 1]; };
Array.prototype.revjoin = function(sep) {
@ -14,14 +23,17 @@ function BefObject(domBase) {
this.btnStop = domBase.getElementsByClassName('b93rnr_pause')[0];
this.btnReset = domBase.getElementsByClassName('b93rnr_reset')[0];
this.btnSpeed = domBase.getElementsByClassName('b93rnr_speed')[0];
this.btnEdit = domBase.getElementsByClassName('b93rnr_edit')[0];
this.pnlCode = domBase.getElementsByClassName('b93rnr_data')[0];
this.pnlEditArea = domBase.getElementsByClassName('b93rnr_editarea')[0];
this.pnlBottom = domBase.getElementsByClassName('b93rnr_outpanel')[0];
this.pnlOutput = domBase.getElementsByClassName('b93rnr_output')[0];
this.pnlStack = domBase.getElementsByClassName('b93rnr_stack')[0];
this.lblStackSize = domBase.getElementsByClassName('b93rnr_stacksize')[0];
this.state = BefState.UNINIITIALIZED;
this.initial = atob(this.pnlCode.getAttribute('data-befcode'));
this.state = BefState.INITIAL;
this.initial = atob(this.pnlCode.getAttribute('data-b93rnr_code'));
this.simspeed = BefSpeed.get(domBase.hasAttribute('data-b93rnr_initialspeed') ? domBase.getAttribute('data-b93rnr_initialspeed') : '4');
this.code = [];
this.width = 0;
this.height = 0;
@ -32,10 +44,13 @@ function BefObject(domBase) {
this.stack = [];
this.timer = null;
this.psteps = 0;
this.simspeed = BefSpeed.SUPERFAST;
this.init();
this.updateUI();
}
BefObject.prototype.Init = function() {
BefObject.prototype.init = function() {
this.state = BefState.INITIAL;
let parse = this.parseBef(this.initial);
@ -51,8 +66,21 @@ BefObject.prototype.Init = function() {
this.psteps = 0;
};
BefObject.prototype.setTimer = function() {
let me = this;
let delay = (this.simspeed === BefSpeed.SLOW) ? 50 : 0;
this.timer = setTimeout(function()
{
me.step();
if (me.state!==BefState.RUNNING) return;
me.setTimer();
}, delay);
};
BefObject.prototype.start = function() {
if (this.state === BefState.UNINIITIALIZED) this.Init();
if (this.state === BefState.EDIT) { this.finishEdit(); return; }
if (this.delta[0]===0 && this.delta[1]===0) {
this.updateUI();
@ -68,34 +96,27 @@ BefObject.prototype.start = function() {
this.setTimer();
};
BefObject.prototype.setTimer = function() {
let me = this;
let delay = (this.simspeed === BefSpeed.SLOW) ? 50 : 0;
this.timer = setTimeout(function()
{
me.step();
if (me.state!==BefState.RUNNING) return;
me.setTimer();
}, delay);
};
BefObject.prototype.stop = function() {
this.state = BefState.PAUSED;
clearTimeout(this.timer);
// pause
this.updateUI();
this.updateDisplay();
};
BefObject.prototype.finishRun = function() {
this.state = BefState.FINISHED;
clearTimeout(this.timer);
this.updateUI();
this.updateDisplay();
};
BefObject.prototype.reset = function() {
if (this.state === BefState.EDIT) { this.abortEdit(); return; }
if (this.state === BefState.RUNNING) this.stop();
this.state = BefState.INITIAL;
this.Init();
this.state = BefState.INITIAL;
this.init();
this.updateUI();
this.updateDisplay();
@ -103,15 +124,44 @@ BefObject.prototype.reset = function() {
BefObject.prototype.incSpeed = function() {
if (this.simspeed === BefSpeed.SLOW) this.simspeed = BefSpeed.NORMAL;
else if (this.simspeed === BefSpeed.NORMAL) this.simspeed = BefSpeed.FAST;
else if (this.simspeed === BefSpeed.FAST) this.simspeed = BefSpeed.SUPERFAST;
else if (this.simspeed === BefSpeed.SUPERFAST) this.simspeed = BefSpeed.MAX;
else if (this.simspeed === BefSpeed.MAX) this.simspeed = BefSpeed.SLOW;
this.simspeed = BefSpeed.get((this.simspeed.val + 1) % (BefSpeed.max()+1));
this.updateUI();
};
BefObject.prototype.startEdit = function() {
if (this.state === BefState.RUNNING) this.stop();
this.pnlEditArea.value = this.getDisplayRaw();
this.pnlEditArea.style.width = this.pnlCode.clientWidth + 'px';
this.pnlEditArea.style.height = this.pnlCode.clientHeight + 'px';
this.state = BefState.EDIT;
this.updateUI();
};
BefObject.prototype.finishEdit = function() {
if (this.state !== BefState.EDIT) return;
this.initial = this.pnlEditArea.value;
this.init();
this.updateUI();
this.updateDisplay();
};
BefObject.prototype.abortEdit = function() {
if (this.state !== BefState.EDIT) return;
this.pnlEditArea.value = '';
this.init();
this.updateUI();
this.updateDisplay();
};
BefObject.prototype.step = function() {
if (this.simspeed === BefSpeed.NORMAL || this.simspeed === BefSpeed.SLOW) {
@ -160,7 +210,7 @@ BefObject.prototype.stepSingle = function() {
if (this.delta[0]===0 && this.delta[1]===0) {
console.log('Finished in ' + this.psteps + ' steps');
this.stop();
this.finishRun();
}
};
@ -252,16 +302,63 @@ BefObject.prototype.gridget_i = function(x,y) { if (x < 0 || y < 0 || x >= thi
BefObject.prototype.updateUI = function() {
classListSet(this.btnStart, 'ctrl_btn_disabled', this.state === BefState.RUNNING || this.state === BefState.PAUSED);
classListSet(this.btnStop, 'ctrl_btn_disabled', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL);
classListSet(this.btnReset, 'ctrl_btn_disabled', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL);
classListSet(this.pnlBottom, 'b93rnr_outpanel_hidden', this.state === BefState.UNINIITIALIZED || this.state === BefState.INITIAL);
switch (this.state) {
case BefState.INITIAL:
cssCtrlState(this.btnStart, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnSpeed, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnStop, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnReset, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnEdit, 'ctrl_btn_disabled', true);
cssCtrlState(this.pnlBottom, 'generic_collapsed', false);
cssCtrlState(this.pnlEditArea, 'generic_collapsed', false);
cssCtrlState(this.pnlCode, 'generic_collapsed', true);
break;
case BefState.RUNNING:
cssCtrlState(this.btnStart, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnSpeed, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnStop, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnReset, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnEdit, 'ctrl_btn_disabled', false);
cssCtrlState(this.pnlBottom, 'generic_collapsed', true);
cssCtrlState(this.pnlEditArea, 'generic_collapsed', false);
cssCtrlState(this.pnlCode, 'generic_collapsed', true);
break;
case BefState.PAUSED:
cssCtrlState(this.btnStart, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnSpeed, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnStop, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnReset, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnEdit, 'ctrl_btn_disabled', false);
cssCtrlState(this.pnlBottom, 'generic_collapsed', true);
cssCtrlState(this.pnlEditArea, 'generic_collapsed', false);
cssCtrlState(this.pnlCode, 'generic_collapsed', true);
break;
case BefState.FINISHED:
cssCtrlState(this.btnStart, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnSpeed, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnStop, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnReset, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnEdit, 'ctrl_btn_disabled', false);
cssCtrlState(this.pnlBottom, 'generic_collapsed', true);
cssCtrlState(this.pnlEditArea, 'generic_collapsed', false);
cssCtrlState(this.pnlCode, 'generic_collapsed', true);
break;
case BefState.EDIT:
cssCtrlState(this.btnStart, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnSpeed, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnStop, 'ctrl_btn_disabled', false);
cssCtrlState(this.btnReset, 'ctrl_btn_disabled', true);
cssCtrlState(this.btnEdit, 'ctrl_btn_disabled', false);
cssCtrlState(this.pnlBottom, 'generic_collapsed', false);
cssCtrlState(this.pnlEditArea, 'generic_collapsed', true);
cssCtrlState(this.pnlCode, 'generic_collapsed', false);
break;
}
this.btnSpeed.innerHTML = this.simspeed.str;
};
BefObject.prototype.updateDisplay = function() {
BefObject.prototype.getDisplayHTML = function() {
let str = '';
for (let y=0; y < this.height; y++) {
for (let x=0; x < this.width; x++) {
@ -278,7 +375,22 @@ BefObject.prototype.updateDisplay = function() {
}
str += '<br/>';
}
this.pnlCode.innerHTML = str;
return str;
};
BefObject.prototype.getDisplayRaw = function() {
let str = '';
for (let y=0; y < this.height; y++) {
for (let x=0; x < this.width; x++) {
str += String.fromCharCode(this.code[y][x]);
}
str += '\n';
}
return str;
};
BefObject.prototype.updateDisplay = function() {
this.pnlCode.innerHTML = this.getDisplayHTML();
this.pnlOutput.innerHTML = htmlescape(this.output);
@ -307,13 +419,16 @@ BefObject.prototype.parseBef = function(str) {
return [result, max, result.length];
};
function classListSet(e, cls, active) {
if (active) {
if (e.classList.contains(cls)) return;
e.classList.add(cls);
} else {
function cssCtrlState(e, cls, state) {
if (e === undefined) return;
if (state) {
if (!e.classList.contains(cls)) return;
e.classList.remove(cls);
} else {
if (e.classList.contains(cls)) return;
e.classList.add(cls);
}
}
@ -334,9 +449,19 @@ window.onload = function ()
let befungeObject = new BefObject(elem);
befungeObject.btnStart.onclick = function () { if (befungeObject.btnStart.classList.contains('ctrl_btn_disabled')) return; befungeObject.start(); };
befungeObject.btnStop.onclick = function () { if (befungeObject.btnStop.classList.contains('ctrl_btn_disabled')) return; befungeObject.stop(); };
befungeObject.btnReset.onclick = function () { if (befungeObject.btnReset.classList.contains('ctrl_btn_disabled')) return; befungeObject.reset(); };
befungeObject.btnSpeed.onclick = function () { if (befungeObject.btnSpeed.classList.contains('ctrl_btn_disabled')) return; befungeObject.incSpeed(); };
if (befungeObject.btnStart !== undefined)
befungeObject.btnStart.onclick = function () { if (befungeObject.btnStart.classList.contains('ctrl_btn_disabled')) return; befungeObject.start(); };
if (befungeObject.btnStop !== undefined)
befungeObject.btnStop.onclick = function () { if (befungeObject.btnStop.classList.contains('ctrl_btn_disabled')) return; befungeObject.stop(); };
if (befungeObject.btnReset !== undefined)
befungeObject.btnReset.onclick = function () { if (befungeObject.btnReset.classList.contains('ctrl_btn_disabled')) return; befungeObject.reset(); };
if (befungeObject.btnSpeed !== undefined)
befungeObject.btnSpeed.onclick = function () { if (befungeObject.btnSpeed.classList.contains('ctrl_btn_disabled')) return; befungeObject.incSpeed(); };
if (befungeObject.btnEdit !== undefined)
befungeObject.btnEdit.onclick = function () { if (befungeObject.btnEdit.classList.contains('ctrl_btn_disabled')) return; befungeObject.startEdit(); };
}
};

View File

@ -1,9 +1,13 @@
<?php
require_once (__DIR__ . '/../internals/base.php');
global $PARAM_CODE;
global $PARAM_URL;
global $PARAM_INTERACTIVE;
global $PARAM_BEFUNGE93RUNNER;
$code = $PARAM_BEFUNGE93RUNNER['code'];
$url = $PARAM_BEFUNGE93RUNNER['url'];
$interactive = $PARAM_BEFUNGE93RUNNER['interactive'];
$initspeed = $PARAM_BEFUNGE93RUNNER['speed'];
$editable = $PARAM_BEFUNGE93RUNNER['editable'];
function fmtBef($str) {
$str = htmlspecialchars($str);
@ -18,25 +22,31 @@ function fmtBef($str) {
$result = '';
if ($PARAM_INTERACTIVE) {
$result .= '<div class="bce_code b93rnr_base">' . "\n";
$result .= ' <div class="bce_code_data b93rnr_data" data-befcode="' . base64_encode($PARAM_CODE) . '">' . fmtBef($PARAM_CODE) . '</div>' . "\n";
if ($interactive) {
$speed_attr = '';
if (isset($initspeed) && $initspeed != NULL && $initspeed>0) $speed_attr = ' data-b93rnr_initialspeed="'.$initspeed.'" ';
$code_attr = '';
$code_attr = 'data-b93rnr_code="' . base64_encode($code) . '"';
$result .= '<div class="bce_code b93rnr_base" ' . $speed_attr . '>' . "\n";
$result .= ' <div class="bce_code_data b93rnr_data" '.$code_attr.'>' . fmtBef($code) . '</div>' . "\n";
$result .= ' <textarea class="bce_code_editarea b93rnr_editarea generic_collapsed"></textarea>' . "\n";
$result .= ' <div class="bce_code_ctrl">' . "\n";
$result .= ' <div class="ctrl_btn_left">' . "\n";
$result .= ' <div class="ctrl_btn_group">' . "\n";
$result .= ' <div class="ctrl_btn ctrl_btn_ll b93rnr_start">Start</div>' . "\n";
$result .= ' <div class="ctrl_btn ctrl_btn_rr b93rnr_speed">3+</div>' . "\n";
$result .= ' <div class="ctrl_btn ctrl_btn_rr b93rnr_speed">??</div>' . "\n";
$result .= ' </div>' . "\n";
$result .= ' <div class="ctrl_btn b93rnr_pause ctrl_btn_disabled">Pause</div>' . "\n";
$result .= ' <div class="ctrl_btn b93rnr_reset ctrl_btn_disabled">Reset</div>' . "\n";
$result .= ' </div>' . "\n";
if ($PARAM_URL !== '') {
$result .= ' <div class="ctrl_btn_right">' . "\n";
$result .= ' <a class="ctrl_btn" href="' . $PARAM_URL . '" download target="_blank">Download</a>' . "\n";
$result .= ' </div>' . "\n";
}
$result .= ' <div class="ctrl_btn_right">' . "\n";
if ($editable && $interactive) $result .= ' <div class="ctrl_btn b93rnr_edit">Edit</div>' . "\n";
if ($url !== '') $result .= ' <a class="ctrl_btn" href="' . $url . '" download target="_blank">Download</a>' . "\n";
$result .= ' </div>' . "\n";
$result .= ' </div>' . "\n";
$result .= ' <div class="bce_code_out b93rnr_outpanel b93rnr_outpanel_hidden">' . "\n";
$result .= ' <div class="bce_code_out b93rnr_outpanel generic_collapsed">' . "\n";
$result .= ' <div class="bce_code_out_left">' . "\n";
$result .= ' <b>Output:</b>' . "\n";
$result .= ' <div class="bce_code_out_text b93rnr_output"></div>' . "\n";
@ -53,13 +63,11 @@ if ($PARAM_INTERACTIVE) {
else
{
$result .= '<div class="bce_code">' . "\n";
$result .= ' <div class="bce_code_data">' . fmtBef($PARAM_CODE) . '</div>' . "\n";
$result .= ' <div class="bce_code_data">' . fmtBef($code) . '</div>' . "\n";
$result .= ' <div class="bce_code_ctrl">' . "\n";
if ($PARAM_URL !== '') {
$result .= ' <div class="ctrl_btn_right">' . "\n";
$result .= ' <a class="ctrl_btn" href="' . $PARAM_URL . '" download target="_blank">Download</a>' . "\n";
$result .= ' </div>' . "\n";
}
$result .= ' <div class="ctrl_btn_right">' . "\n";
if ($url !== '') $result .= ' <a class="ctrl_btn" href="' . $url . '" download target="_blank">Download</a>' . "\n";
$result .= ' </div>' . "\n";
$result .= ' </div>' . "\n";
$result .= '</div>' . "\n";
}

View File

@ -47,12 +47,18 @@ $max = ceil($max / 20) * 20;
<b>Solution:</b>
<?php
global $PARAM_CODE;
global $PARAM_URL;
$PARAM_CODE = file_get_contents($problem['file_code']);
$PARAM_URL = $problem['url_raw'];
$PARAM_INTERACTIVE = !$problem['abbreviated'];
global $PARAM_BEFUNGE93RUNNER;
$PARAM_BEFUNGE93RUNNER =
[
'code' => file_get_contents($problem['file_code']),
'url' => $problem['url_raw'],
'interactive' => !$problem['abbreviated'],
'speed' => null,
'editable' => false,
];
echo require (__DIR__ . '/../fragments/befunge93_runner.php');
if ($problem['abbreviated']) echo '<i>This program is too big to display/execute here, click [download] to get the full program. </i><br/>';
?>
<br/>
@ -67,7 +73,7 @@ $max = ceil($max / 20) * 20;
</tr>
<tr>
<td><b>Execution time</b> (<a href="/programs/view/BefunGen">BefunExec</a>):</td>
<td><?php echo $problem['time'] . ' ms <i>(=' . number_format(($problem['steps']/$problem['time'])/1000, 2, '.', '') . ' MHz)</i>'; ?></td>
<td><?php echo $problem['time'] . ' ms <i>(=' . (($problem['time']===0) ? '?' : number_format(($problem['steps']/$problem['time'])/1000, 2, '.', '')) . ' MHz)</i>'; ?></td>
</tr>
<tr>
<td><b>Program size:</b></td>

View File

@ -1,4 +1,4 @@
<div id="footerdiv" class="content-responsive">
<hr />
made with vanilla PHP and MySQL, no frameworks, no bootstrap, no bullshit
made with vanilla PHP and MySQL, no frameworks, no bootstrap, no unnecessary javascript
</div>

View File

@ -22,15 +22,36 @@ class ParsedownCustom extends ParsedownExtra
$Block['custom'] = false;
if (isset($Block['element']['text']['attributes']) && in_array('language-befungerunner', $Block['element']['text']['attributes']))
if (isset($Block['element']['text']['attributes']))
{
$Block['element']['handler'] = 'handleBef93';
$Block['custom'] = true;
}
else if (isset($Block['element']['text']['attributes']) && in_array('language-bfjoustrunner', $Block['element']['text']['attributes']))
{
$Block['element']['handler'] = 'handleBFJoust';
$Block['custom'] = true;
foreach ($Block['element']['text']['attributes'] as $attr)
{
$spl = explode('__', $attr);
if ($spl[0] === 'language-befungerunner')
{
$Block['element']['handler'] = 'handleBef93';
$Block['custom'] = true;
$Block['element']['text']['b93_speed'] = null;
$Block['element']['text']['b93_interactive'] = true;
$Block['element']['text']['b93_editable'] = true;
foreach ($spl as $param)
{
if (startsWith($param, 'speed-')) $Block['element']['text']['b93_speed'] = intval( substr($param, strlen('speed-')));
if (startsWith($param, 'interactive-')) $Block['element']['text']['b93_interactive'] = boolval(substr($param, strlen('interactive-')));
if (startsWith($param, 'editable-')) $Block['element']['text']['b93_editable'] = boolval(substr($param, strlen('editable-')));
}
return $Block;
}
else if ($spl[0] === 'language-bfjoustrunner')
{
$Block['element']['handler'] = 'handleBFJoust';
$Block['custom'] = true;
return $Block;
}
}
}
return $Block;
@ -60,14 +81,15 @@ class ParsedownCustom extends ParsedownExtra
protected function handleBef93(array $Element)
{
global $PARAM_CODE;
global $PARAM_URL;
global $PARAM_INTERACTIVE;
$PARAM_CODE = $Element['text'];
$PARAM_URL = '';
$PARAM_INTERACTIVE = true;
global $PARAM_BEFUNGE93RUNNER;
$PARAM_BEFUNGE93RUNNER =
[
'code' => $Element['text'],
'url' => '',
'interactive' => $Element['b93_interactive'],
'speed' => $Element['b93_speed'],
'editable' => $Element['b93_editable'],
];
return require (__DIR__ . '/../fragments/befunge93_runner.php');
}
}

View File

@ -26,6 +26,7 @@ class Blog
[ 'id' => 8, 'date' => '2014-11-05', 'visible' => true, 'title' => 'Rapla Enhancement Script', 'fragment' => 'rapla_css.md', 'type' => 'markdown', 'cat' => 'blog' ],
[ 'id' => 20, 'date' => '2015-01-09', 'visible' => true, 'title' => 'More Befunge with Project Euler', 'fragment' => 'more_euler.md', 'type' => 'markdown', 'cat' => 'log' ],
[ 'id' => 9, 'date' => '2016-10-22', 'visible' => true, 'title' => 'A complete sudoku solver in Befunge-93', 'fragment' => 'sudoku_befunge.md', 'type' => 'markdown', 'cat' => 'blog' ],
[ 'id' => 21, 'date' => '2018-01-02', 'visible' => true, 'title' => 'A simple javascript befunge-93 runner', 'fragment' => 'js_befrunner.md', 'type' => 'markdown', 'cat' => 'blog' ],
];
return array_map('self::completeSingle', $all);

View File

@ -0,0 +1,41 @@
Primarily for my [project euler solutions](/blog/1/Project_Euler_with_Befunge) I wrote a small
javascript befunge-93 runner (without befunge93 size restrictions, as with most stuff on this site).
The code is note really optimized and will only run on newer browsers, but it's good enough to play a bit around.
Press **[Start]** to run the code, **[Edit]** to change the code and change the interpreter speed with the button on the right side of the **[Start]** button.
~~~befungerunner__speed-2
0".omed s"v
" >v
i 8
4
s > > ^*
i >99+0g1+#^_77+0g#^_188+0p099+0p> v
h ^ < # <
T >88+0g1+#^_66+0g#^_088+0p01-99+0p^
" ^ < <# #<
> v >99+0g1-#^_77+0g8-#^_01-88+0p099+0p^
| >#:>#,< ^ < <# <2
>88+0g1-#^_66+0g8-#^_088+0p199+0p^2
>0>:"#"\0p:5 v ^ $ g
v_^#!\+1\!`+4< ^p0+77+g0+99g0+77< >66+0g1+v v
>1-:"#"\v >66+0g88+0g+66+0p^ v+1g0+77< 8
|`0:p+19< ^ g 4
>:"#"\0\p:v> ^< - *
|\+1\!`+45<^p0+< v" "_"@"v -
>1-:"#"\ v>p099^^ < >66+v+66< #
|`0:p\+19<^0+88<^ p+1g0+77+1g0< >" " #< v
$>-66+0p077+0p1^ vp+2g0+67+2g0+56 < pp0+67:0+560<|#<
01 : # v p0 +76+1g< >"#" #< ^
>^ >65+0g6- #v_01-65+0p67+0^
^ $ <>76+0gv#
^ <> 7-v
^_v#!<
#
>+56+0p^
^1g0+56<
~~~
You can find the code either directly by looking at the file *blogpost_bef93runner.js* on this site, or on [github](https://github.com/Mikescher/www.mikescher.com).

View File

@ -1 +1,3 @@
These kinds of problems are fun in Befunge because you can just copy the input into your program and it becomes a part of your source code.
These kinds of problems are fun in Befunge because you can just copy the input into your program and it becomes a part of your source code.
The rest is just walking through all possible values and printing the largest