logarithm flash cards in DHTML
kragen at pobox.com
kragen at pobox.com
Thu Sep 30 13:13:36 EDT 2004
Here's a DHTML set of flash-cards for two-place logarithms. Not
really interesting from an algorithmic perspective, but maybe fun.
<html><head><title>Logarithm flash cards</title>
<style type="text/css">
input { border-width: 0; font-family: serif }
</style>
<body onload="document.forms.tf.b.focus();renew()">
<h1>Logarithm flash cards</h1>
<form name="tf" onsubmit="renew();return false">
log<sub>10</sub>(<input name="a" size="2">) =
.<input name="b" onkeypress="changed()" size="3">
<p>Single digits will appear; your task is to type their base-10
logarithms to two digits as quickly as you can, without the preceding
decimal point. For example, for "2", type "30", and for "3", type
"48". When the red disappears, hit Enter (Return). Your response times are
displayed below.</p>
<input name="time" size="80">
</form>
<p><a href="javascript:window.vals=hardervals;tf=document.forms.tf;tf.b.style.backgroundColor='';renew();tf.time.value='';tf.b.focus();void 0">Switch from digits to 10%-covering values</a></p>
<script type="text/javascript"><!--
var vals = [
['1', '00'],
['2', '30'],
['3', '48'],
['4', '60'],
['5', '70'],
['6', '78'],
['7', '85'],
['8', '90'],
['9', '95'],
];
// optional 10%-tolerance set.
// The previous set should take a couple of minutes to learn and under
// an hour to become proficient; this set might take 15 minutes to learn and
// several hours to become proficient.
var hardervals = [
['1.0', '00'],
['1.1', '04'],
['1.3', '11'],
['1.5', '18'],
['1.7', '23'],
['1.9', '28'],
['2.0', '30'],
['2.2', '34'],
['2.5', '40'],
['2.8', '45'],
['3.0', '48'],
['3.14', '50'],
['3.3', '52'],
['3.7', '57'],
['4.0', '60'],
['4.3', '63'],
['4.7', '67'],
['5.0', '70'],
['5.5', '74'],
['6.0', '78'],
['6.5', '81'],
['7.0', '85'],
['7.5', '88'],
['8.0', '90'],
['8.5', '93'],
['9.0', '95'],
['9.5', '98'],
];
function random_item(alist) {
return alist[Math.floor(Math.random() * alist.length)];
}
function matching_item(alist, key) {
var i;
for (i = 0; i < alist.length; i++)if (alist[i][0] == key) return alist[i][1];
}
var checker;
function changed() {
if (checker) clearTimeout(checker);
checker = setTimeout("check()", 0);
}
document.forms.tf.b.onkeypress = function(kp) {
if (kp.keyCode == kp.DOM_VK_RETURN) renew();
changed();
}
function check() {
var obj = document.forms.tf.b;
if (obj.value == matching_item(vals, document.forms.tf.a.value)) {
obj.style.backgroundColor = "";
} else {
obj.style.backgroundColor = "red";
}
}
function report_date(fe, start) {
var now = new Date;
if (start != null) {
var diff = (now.getTime() - start.getTime()) / 1000.0;
fe.value = diff + " " + fe.value;
}
return now;
}
var start;
function renew() {
if (document.forms.tf.b.style.backgroundColor != 'red') {
document.forms.tf.a.value = random_item(vals)[0];
start = report_date(document.forms.tf.time, start);
}
document.forms.tf.b.value = '';
changed();
}
// -->
</script>
<p>Why would you want to do this? Well, multiplication and division
are a lot harder than addition and subtraction, and square and cube
roots are harder still. If approximate answers are good enough (that
is, whenever the numbers don't represent money, and usually even when
they do), a memorized table of logarithms can be quite handy.
</p>
<p>For example, if you want to know the cube root of 38 multiplied by
52, you can do it approximately as follows: log<sub>10</sub> of 37 is
1.57 (log<sub>10</sub>(3.7) = 0.57, plus 1 for the factor of 10); a
third of that is about 0.19 (long dividing in my head) + 0.33 = 0.52;
52 is roughly 50, whose log is 1.70, but if you want to approximate
better you can interpolate between 50 and 55 (whose log is 1.74), and
add 2/5 of .04 or about .02 to get 1.72. Then 1.72 + 0.52 = 2.24.
log<sub>10</sub>(1.7) is 0.23, so the answer is slightly more than
170; interpolating, the error is .01 of the .05 between log(1.7) and
log(1.9) (= .28), so we're off by about a fifth of 190 - 170 = 20, or
about 4, so the answer is close to 174. (It's actually about 174.8,
but it could easily have been off by 10%.)</p>
<p>This kind of crap is at its best when you're multiplying together a
whole bunch of quantities. log(7!) is about .30 + .48 + .60 + .70 +
.78 + .85 = 3.71, which gives about 5100 --- actually 5040. If you
want to know the number of combinations of three things out of seven,
that's 7!/(3!4!); log(3!) is .78, log(4!) is 1.38, so 3.71 - .78 -
1.38 = 1.55 --- about 35? Exactly 35 in fact. The symbolic route of
calculating (7 * 6 * 5) / 6 would have been easier in this case,
though.</p>
<p>You can even do hard stuff like logarithms to arbitrary bases in
your head. My co-worker told me that the price of bandwidth dropped
by 20% a year. I wanted to know how often it would halve: so I
calculated that log<sub>10</sub>(0.8) is about -.1 (in my head), and
log<sub>10</sub>(0.5) is about -.3, so it takes about three years for
the cost of bandwidth to halve --- in other words,
log<sub>0.8</sub>(0.5) is about 3. (I got it wrong, though, and said
6, at the time.)</p>
<p>Richard Feynman once told a story in which he handily beat an
abacist in a calculating contest in a bar; according to his story, he
was just about even with the guy on the easy stuff, so the abacist
thought he'd turn up the heat by switching to harder stuff. But
Feynman's knowledge of logarithms (among other tricks) enabled him to
beat the abacist more and more thoroughly as the math got harder.</p>
</body>
</html>
More information about the Kragen-hacks
mailing list