Skip to content

Instantly share code, notes, and snippets.

@kmcallister
Created March 27, 2014 17:26
Show Gist options
  • Save kmcallister/9813132 to your computer and use it in GitHub Desktop.
Save kmcallister/9813132 to your computer and use it in GitHub Desktop.
physics homework solution generator (I wrote this like 10 years ago…)
#!/usr/bin/perl -w
use strict;
sub shuffle {
my @new;
while(scalar(@_) > 0) {
push @new, (splice @_, rand(scalar(@_)), 1);
}
return @new;
}
#use List::Util qw(shuffle);
srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
sub preamble {
return <<EOF;
\\documentclass{article}
\\usepackage{amsmath}
\\usepackage{amssymb}
\\begin{document}
EOF
}
sub postamble {
return <<EOF;
\\end{document}
EOF
}
sub rand_num {
my @nums = (2,3,5);
shuffle @nums;
return (shift @nums);
}
my @scalars; my @consts; my @vectors; my @infts; my @int_bounds;
sub rand_term {
@scalars = shuffle("r", "R", "a", "b", "\\alpha", "\\gamma", "\\rho", "s", "k", "\\ell", "N", "\\sigma", "I", "q", "\\mathcal{E}". "Q", "\\phi", "\\varepsilon");
@consts = shuffle("", (rand_num() . "\\pi"), ("\\sqrt{" . rand_num() . "}"), "c", "e");
@vectors = shuffle("\\vec \\beta", "\\vec E", "\\vec F", "\\vec J", "\\vec B", "\\vec A", "\\vec v", "\\vec n", "\\vec r", "\\hat x", "\\hat y", "\\hat z", "\\hat r", "\\hat \\theta", "\\nabla");
@infts = shuffle("d \\vec r", "d \\vec a", "d \\vec l", "d \\vec s");
@int_bounds = shuffle(["C",""], ["S",""], ["V",""], ["z_1","z_2"]);
my $is_frac = (rand() < 0.6 ? 1 : 0);
my $is_int = (rand() < 0.4 ? 1 : 0);
my $expr = "";
sub rand_simpleterm {
my $nscalars = int(rand(2)) + 1;
my $has_vec = (rand() < 0.4 ? 1 : 0);
my $has_prime = (rand() < 0.2 ? 1 : 0);
my $has_sub = (rand() < 0.2 ? 1 : 0);
my $expr = "";
$expr .= (shift @consts) . " ";
for (1..$nscalars) {
my $has_exp = (rand() < 0.2 ? 1 : 0);
$expr .= (shift @scalars);
if ($has_prime) { $expr .= "'"; }
if ($has_exp) {
my $exp = int(rand(2)) + 2;
$expr .= "^$exp";
}
if ($has_sub) {
my @subs = shuffle("a", "b", "i", "f", "x", "y", "z", "0");
$expr .= "_" . (shift @subs);
}
$expr .= " ";
}
if ($has_vec) {
$expr .= "\\left(" . (shift @vectors) . (rand() < 0.5 ? " \\cdot " : " \\times ") . (shift @vectors) . "\\right)";
}
return $expr;
}
if ($is_int) {
my $bounds = shift @int_bounds;
$expr .= "\\int_{" . $bounds->[0] . "}" . ($bounds->[1] eq "" ? "" : "^{" . $bounds->[1] . "}");
}
if ($is_frac) {
$expr .= "\\frac{" . rand_simpleterm() . "}{" . rand_simpleterm() . "}";
} else {
$expr .= rand_simpleterm();
}
if ($is_int) {
$expr .= (rand() < 0.5 ? " \\cdot " : " \\times ") . (shift @infts);
}
return $expr;
}
sub rand_principle {
my @principles = shuffle("relativistic invariance", "charge conservation", "superposition", "the Hall effect", "Poisson's equation", "the right-hand rule");
return (shift @principles);
}
my @laws = shuffle("Amp\\`ere's law", "Gauss's law", "the Biot-Savart formula", "the Clausius-Mossotti relation", "Faraday's law", "the Lorentz transformation", "Gauss's theorem", "Lenz\'s law", "Maxwell's equations", "Oersted's law", "Ohm's law", "Stokes' theorem", "Th\\'evenin's theorem", "the Ti\\'ente theorem");
sub rand_law {
my @connectors = shuffle("with", "with respect to", "in conjunction with", "as dictated by");
my $has_principle = (rand() < 0.3 ? 0 : 1);
my $expr = "";
$expr .= (shift @laws);
if ($has_principle) { $expr .= (" " . (shift(@connectors)) . " " . rand_principle()); }
return $expr;
}
my @objects = shuffle("a point charge", "an infinite solonoid", "a half-infinite solonoid", "a particle moving at relativistic speed", "a conducting sheet", "a torus of rectangular cross-section", "two long straight parallel wires", "an insulating sphere", "a sphere of uniform charge density", "a rotating charged disk", "a loop of wire");
my @adjs = shuffle("at rest", "centered at the origin", "oriented in the \$\\hat z\$ direction", "moving at relativistic speed", "at time \$t=0\$", "an infinite distance from the origin", "that accelerates rapidly at time \$t=t_0\$");
sub rand_obj {
return (shift @objects) . " " . (shift @adjs);
}
sub rand_filler {
my @fillers = shuffle("it is clear that", "clearly,", "by symmetry,", "we make the justified assumption that", "it can be shown that", "it was shown in class that", "in the general case,", "it is trivial to see that", "trivially,", "obviously");
return (shift @fillers);
}
sub cap {
my $arg = shift;
substr($arg, 0, 1) =~ tr/a-z/A-Z/;
return $arg;
}
sub rand_setup {
my $expr = "";
my $is_superp = (rand() < 0.4 ? 1 : 0);
if ($is_superp) {
$expr .= cap(rand_filler()) . " we can consider the object in question as the superposition of " . rand_obj() . " and " . rand_obj() . ".";
} else {
$expr .= cap(rand_filler()) . " the object behaves like " . rand_obj() . ".";
}
}
my @verbs = shuffle("Applying", "By", "Considering", "According to", "Substituting into", "Equating this by", "Expressing this using", "Calculating using");
sub rand_step() {
return (shift(@verbs) . " " . rand_law() . ",\n\\begin{displaymath}\n" . rand_term() . " = " . rand_term() . ".\n\\end{displaymath}\n");
}
print preamble();
my $nsteps = int(rand(4)) + 3;
print rand_setup() . " \n";
for (1..$nsteps) { print rand_step(); }
print cap(rand_filler()) . " by combining the above, we obtain the result\n";
print "\\begin{displaymath}\n";
print "\\frac{\\sqrt{5}}{3}.\n";
print "\\end{displaymath}\n";
print postamble();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment