#!/usr/bin/env perl

use strict;
use CGI qw(:standard);
use CGI::Carp 'fatalsToBrowser';

my $bits = param("b");
my $seed = param("s");
my $check = param("f");
my $co = $check;

$bits = 3 unless defined $bits and $bits =~ /^[1-9]$/;
$seed = time() unless defined $seed and $bits =~ /^\d+$/;

srand($seed);

my ($knf, $dnf, $mb) = ("", "", $bits - 1);

if (defined $check) {
  $check =~ s/\s+//g;
  (undef $co, undef $check) unless $check =~ /^([!+*()]|x[0-$mb]|[01])+$/;
}

if (defined $check) {
  $check =~ s/([^(!+*])([x!])/$1*$2/g;
  $check =~ s/\+/ or /g;
  $check =~ s/\*/ and /g;
  $check =~ s/x(\d)/\$x\[$1\]/g;
}

print <<EOF
Content-type: text/html

<html>

<head>
  <title>Programiranje 1: Normalne forme</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body bgcolor="#ffffda" text="#400000" link="#a00000" alink="#ff2020" vlink="#a00000" onLoad="document.f.b.focus();">

<h1>Programiranje 1: Normalne forme</h1>

<form action="knfdnf.pl" method="get" name="f">
<p>Broj bitova (1-9): <input type="text" name="b" maxlength="1" size="5" value="$bits" style="text-align: center;" /> <input type="submit" value="Generiraj zadatak" /></p>
</form>
EOF
;

print <<EOF
<h2>Zadatak:</h2>

<table border="0" cellspacing="0" cellpadidng="4">

  <tr class="head">
EOF
;

foreach my $b (1..$bits) {
  print "    <th>x<sub>", $bits - $b, "</sub></th>\n";
}
print "    <th class=\"f\">f</th>\n";
print "    <th class=\"sol\">Rj</th>\n" if defined $check;
print "  </tr>\n\n";

foreach my $x (0..(1<<$bits) - 1) {
  my ($xt, $s, %bits, @x) = ($x, "");
  foreach my $b (1..$bits) {
    $s = "    <td>".($bits{$b} = $xt & 1)."</td>\n".$s;
    $x[$b - 1] = $xt & 1 if defined $check;
    $xt >>= 1;
  }
  my $b = int(rand(2));
  $s .= "    <td class=\"f\">$b</td>\n";
  if (defined $check) {
    my $res = (eval($check) ? 1 : 0);
    $s .= "    <td class=\"".($b == $res ? "ok" : "bad")."\">$res</td>\n";
  }
  print "  <tr>\n$s  </tr>\n\n";
  if ($b) {
    $dnf .= ($dnf ? " + " : "");
    my $s = "";
    foreach my $b (1..$bits) {
      $s .= ($s ? "&sdot;" : "").($bits{$bits - $b + 1} ? "x<sub>".($bits - $b)."</sub>" : "<span class=\"o\">x</span><sub>".($bits - $b)."</sub>");
    }
    $dnf .= $s;
  } else {
    $knf .= ($knf ? " &sdot; " : "")."(";
    my $s = "";
    foreach my $b (1..$bits) {
      $s .= ($s ? " + " : "").($bits{$bits - $b + 1} ? "<span class=\"o\">x</span><sub>".($bits - $b)."</sub>" : "x<sub>".($bits - $b)."</sub>");
    }
    $knf .= "$s)";
  }
}
print "</table>\n";

print "<p><a href=\"knfdnf.pl?b=$bits&s=$seed\">Direktni link na zadatak</a> - služi za učitavanje stranice s točno ovim zadatkom (inače svako učitavanje generira novi zadatak).</p>\n\n";

$dnf = "0" unless $dnf;
$knf = "1" unless $knf;

print <<EOF
<h2>Rješenje:</h2>

<p style="line-height: 1cm;">DNF: $dnf<br />
KNF: $knf</p>

<h2>Provjera rješenja:</h2>

<p>Ovdje možete provjeriti svoje rješenje koje ne mora nužno biti u normalnoj formi.</p>

<form action="knfdnf.pl" method="post">
<p>Provjera rješenja: <input type="text" size="40" name="f" value="$co" /> <input type="submit" value="Provjeri!" /></p>
<input type="hidden" name="b" value="$bits" />
<input type="hidden" name="s" value="$seed" />
</form>
<p><b>Uputa:</b> Izraz se zadaje pomoću x-eva: x0,x1,x2,...<br />
Operator "i" se zapisuje zvjezdicom ("*"), a operator "ili" plusom ("+"). Negacija se zapisuje pomoću uskličnika ("!") ispred izraza koji se negira.<br />
Na primjer, izraz<br />
<span class="o">x</span><sub>2</sub>&sdot;<span class="o">x</span><sub>1</sub>&sdot;x<sub>0</sub> + <span class="o">x</span><sub>2</sub>&sdot;x<sub>1</sub>&sdot;x<sub>0</sub><br />
zapisujemo ovako:<br />
<tt>!x2*!x1*x0+!x2*x1*x0</tt><br />
Pogrešno zadani izrazi će uvijek vratiti nulu!<br />
Provjeravati možete i pojednostavljene izraze, a dozvoljena je i upotreba zagrada.</p>

<p>Pitanja, komentari, pohvale i slično: <a href="http://degiorgi.math.hr/forum/viewtopic.php?t=5327">na Forumu</a>.</p>

<hr align="left" width="17%" />

<address>Created by Vedran Šego, 2005</address>

</body>

</html>
EOF
;
