<?php session_start(); // ユーザーからの入力を取得 $input = isset($_GET['input'] ? $_GET['input']: ""; // CAPTCHAと入力フォームのタグを定義 $captch = "<img src='genImage.php'>"; $msg = "5文字のひらがなを入力してください。"; $form = <<< END_OF_FORM <form method="GET"> <input type="text" name="input"> <input type="submit" value="OK"> </form> END_OF_FORM; //CAPTCHAのコードが入力されたときの処理 if (isset($_SESSION["CAPTCH"]) && $_SESSION["CAPTCH"] === $input) { $msg = "<h3>正解です!</h3><a href='form.php'>もう一度試す</a>"; $captch = $form = "-"; } else { if ($input != ""){ $msg = "間違い!もう一度、{$msg}"; } } // HTMLを出力 echo <<< END_OF_HTML <html><head><meta charset="UTF-8"></head> <body> <h1>CAPTCHA TEST</h1> <p>$captcha</p> <p>$msg</p> <p>$form</p> END_OF_HTML;
Category: other topics
imageMagicを使って反転と回転を行う
<?php // コマンドラインから画像を取得 if (count($argv) <= 1){ echo "no input"; exit; } $input = $argv[1]; $outfile = preg_replace('/\.(jpeg|jpg)$/', '-out.jpeg', $input); $cmpfile = preg_replace('/\.(jpeg|jpg)$/', '-cmp.jpeg', $input); $i = new Imagick(); $i->readImage($input); $i->stripImage(); $i->writeImage($cmpfile); echo " 回転前: $outfile\n"; // 回転用に画像を処理 $img = new Imagick(); $img->readImage($input); // 画像の向きを自動回転 img_auto_rotate($img); // 画像を保存 $img->writeImage($outfile); echo " 回転後: $outfile\n"; // 画像の向きを自動回転 function img_auto_rotate(Imagick $img){ switch ($img->getImageOrientation()){ case Imagick::ORIENTATION_TOPLEFT: break; case Imagick::ORIENTATION_TOPRIGHT: $img->flopImage(); break; case Imagick::ORIENTATION_BOTTOMRIGHT: $img->rotateImage("#000, 180"); break; case Imagick::ORIENTATION_LEFTTOP: $img->flopImage(); $img->rotateImage("#000", -90); break; case Imagick::ORIENTATION_RIGHTTOP: $img->rotateImage("#000", 90); break; case Imagick::ORIENTATION_RIGHTBOTTOM: $img->flopImage(); $img->rotateImage("#000", 90); break; case Imagick::ORIENTATION_LEFTBOTTOM: $img->rotateImage("#000", -90); break; default: break; } $img->setImageOrientation(Imagick::ORIENTATION_TOPLEFT); return $img; }
マルコフ連鎖の実装
形態素解析をしてそれを辞書に登録し、辞書を元に作文を行います。
3) array_shift($tmp); set_word($dic, $tmp); if ($w == "。 "){ $tmp = ["@"]; continue; } } return $dic; } // 辞書に単語を登録 function set_word(&$dic, $tmp){ $w1 = $tmp[0]; $w2 = $tmp[1]; $w3 = $tmp[2]; if (empty($dic[$w1])) $dic[$w1] = []; if (empty($dic[$w1][$w2])) $dic[$w1][$w2] = []; if (empty($dic[$w1][$w2][$w3])) $dic[$w1][$w2][$w3] = 0; $dic[$w1][$w2][$w3]++; } // 辞書から作文する function make_sentence($dic, $count){ $ret = []; for ($i = 0; $i < $count; $i++){ $top = $dic["@"]; if (!$top) break; $w1 = choice_word($top); $w2 = choice_word($top[$w1]); $ret[] = $w1; $ret[] = $w2; for (;;) { $w3 = choice_word($dic[$w1][$w2]); $ret[] = $w3; if ($w3 == "。")break; $w1 = $w2; $w2 = $w3; } } return implode("", $ret); } function choice_word($o){ if (!is_array($o)) return "。 "; $ks = array_keys($o); return $ks[mt_rand(0, count($ks)-1)]; }
ASCIIコード表
<?php // 特殊記号 $sp = ['NULL','SOH','STX','ETX','EOT','ENQ','ACK','BEL','BS','HT','LF','VT', 'FF','CR','SO','SI','DLE','DC1','DC2','DC3','DC4','NAL','SYN','ETV','CAN'm 'EM','SUB','ESC','FS','GS','RS','US','SPC']; $sp[127] = 'DEL'; // header $html = "<tr><th></th>"; for($j = 0; $j < 16; $j++){ $html .= "<th>".sprintf("%X",$j)."</th>"; } $html .= "</tr>"; // characters for ($i = 0; $i <= 7; $i++){ $html .= "<tr><th>{$i}x</th>"; for ($j = 0; $j < 16; $j++){ $code = ($i * 16) + $j; $ch = isset($sp[$code]) ? $sp[$code] : chr($code); $html .= "<td>$ch</td>"; } $html .= "</tr>"; } echo <<< EOS <style> * { margin:0; padding:0; } table { margin: 12px; } td, th { font-size: 12px, padding: 4px; width: 32px; text-align: center; border-bottom: 1px solid silver; border-right: 1px solid silver; } th { color: white; background-color: blue; } </style> <table> $html </table> EOS;
月間カレンダーの描画
<html><body> <style> .cal td { border-bottom: 1px solid silver; padding: 4px; } .cur { font-size: 14px; color: black; } .oth { font-size: 9px; color: silver; } .sun { color: red; } </style> <?php // カレンダーの描写 echo make_calendar(2018,2); function make_calendar($year, $month){ // 月初めをセット $t = new DateTime(); $t->setDate($year, $month, 1); // その週の月曜日(カレンダー左上の日)を得る $t->modify("Mon this week"); // 月終わりをセット $end_t = new DateTime(); $end_t->setDate($year,$month, 1); $end_t->modify("Sun"); $html = "<p>{$year}年 {$month}月</p>"; $html .= "<table class='cal'>"; for (;;){ $d = $t->format("d"); $w = $t->format("w"); $c_week = ($w == 0) ? "sun" : (($w == 6) ? "sat" : ""); $c_mon = ((int)$t->format("m") == $month) ? 'cur' : 'oth'; if ($w == 1){ $html .= "<tr>"; } $html .= "<td class='$c_mon $c_week'>$d</td>"; if ($w == 0){ $html .= "</tr>"; } $diff = $end_t->diff($t); if ($diff->days == 0) break; $t->modify("+1 days"); } $html .= "</table>"; return $html; } ?></body></html>
3ヶ月後の日数
<?php $t = strtotime("2018-1-1"); $t = month_add($t, 3); echo date('Y-m-d', $t)."\n"; function month_add($t, $n){ $year = date('Y', $t); $month = (int)date('m', $t); $mm = [1=>31, 2=>28, 3=>31, 4=>30, 5=>31, 6=>30, 7=>31, 8=>31, 9=>30, 10=>31, 11=>30, 12=>31]; $isleap = ($year%4)==0 && ($year%100)!=0 || ($year%400)==0; $mm[2] = $isleap ? 29 :28; // nヶ月後の日数計算 $days = 0; for ($i = 0; $i < $n; $i++){ $m = $month + $i; $m = ($m > 12) ? $m - 12 : $m; $days += $mm[$m]; } $DAY_SEC = 60 * 60 * 24; return $t + ($days + $DAY_SEC); }
再帰を使わずに中置記法
<?php $str = "(1 + 2) * 3"; $res = calc_str2($str); echo $res."\n"; function calc_str2($str){ $stack = []; $polish = []; while ($str != ""){ $t = get($str); if ($t == '(') { $stack[] = $t; continue; } if ($t == ')') { while (count($stack) > 0){ $s_top = array_pop($stack); if ($s_top == '(') break; $polish[] = $s_top; } continue; } while (count($stack) > 0){ $s_top = $stack[count($stack)-1]; if(priority($t) > priority($s_top)) break; $polish[] = array_pop($stack); } $stack[] = $t; } while(count($stack) > 0) $polish[] = array_pop($stack); echo "[".implode(" ", $polish)."]\n"; foreach ($polish as $t){ if (preg_match('#^\d+$#', $t)){ $tack[] = intval($t); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t){ case '+': $c = $a + $b; break; case '-': $c = $a - $b; break; case '*': $c = $a * $b; break; case '/': $c = $a / $b; break; default: throw new Exception("未知の文字:$t"); } $stack[] = $c; } return array_pop($stack); } function priority($c){ $pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1, '('=>0]; return isset($pri[$c]) ? $pri[$c] : $pri['num']; } function get(&$str){ $str = trim($str); $c = substr($str, 0, 1); if (strpos("()+-*/", $c) !== false){ $str = substr($str, 1); return $c; } if (preg_match('#^(\d+)#', $str, $m)){ $str = substr($str, strlen($m[1])); return $m[1]; } throw new Exception("未知の文字: $c"); }
中置記法の計算方法
<?php $str = "1 + 2 * 3"; $res = calc_str($str); echo $res."\n"; function calc_str($str){ $stack = []; $polish = []; while ($str != "") { $t = get($str); while (count($stack) > 0){ $s_top = $stack[count($stack)-1]; if (priority($t) > priority($s_top))break; $polish[] = array_pop($stack); } $stack[] = $t; } while (count($stack) > 0) $polish[] = array_pop($stack); echo "[".implode(" ", $polish)."]\n"; foreach ($polish as $t){ if (preg_match('#^\d+$#', $t)){ $stack[] = intval($t); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t) { case '+': $c = $a + $b; break; case '-': $c = $a - $b; break; case '*': $c = $a * $b; break; case '/': $c = $a / $b; break; default: throw new Exception("未知の文字:$t"); } $stack[] = $c; } return array_pop($stack); } function priority($c) { $pri = ['num'=>3, '*'=>2, '/'=>2, '+'=>1, '-'=>1]; return isset($pri[$c]) ? $pri[$c] : $pri['num']; } function get(&$str) { $str = trim($str); $c = substr($str, 0, 1); if (strpos("+-*/", $c) !== false){ $str = substr($str, 1); return $c; } if (preg_match('#^(\d+)#', $str, $m)){ $str = substr ($str, strlen($m[1])); return $m[1]; } throw new Exception("未知の文字: $c"); }
中置記法の計算方法
<?php // check input $inp = isset($_GET["inp"]) ? $_GET["inp"] : "(1+2)*(3+4)"; // calculate $answer = calcInfix($inp); // calculate function calcInfix($str){ global $input_str; $input_str = $str; // main transaction return plus_minus(); } // add, minus function plus_minus() { $v = mul_div(); while(peek() == "+" || peek() == "-"){ $op = get(); if ($op == "+") $v += mul_div(); if ($op == "-") $v -= mul_div(); } return $v; } function mul_div(){ $v = paren(); while(peek() == "*" || peek() == "/"){ $op = get(); if ($op == "*") $v *= paren(); if ($op == "/") $v /= paren(); } return $v; } function paren(){ $v = get(); if ($v == '(') { $v = plus_minus(); $t = get(); if ($t != ")") throw new Exception("カッコ未対応"); } return $v; } function get(){ global $input_str; $input_str = ltrim($input_str); $c = substr($input_str, 0, 1); if (strpos("+-*/()", $c) !== false){ $input_str = substr($input_str, 1); return $c; } if (preg_match('#^([0-9]+)#', $input_str, $m)){ $input_str = substr($input_str, strlen($m[1])); return intval($m[1]); } } function unget($t){ global $input_str; $input_str = $t . $input_str; } function peek(){ $c = get(); unget($c); return $c; } $inp_ = htmlentities($inp, ENT_QUOTES); echo <<< EOS <!DOCTYPE html><meta charset="UTF-8"> <form> 式:<input name="inp" value="inp_" size="30"> <input type="submit" value="calculate"> </form><hr> <div>答え: $answer</div> EOS;
逆ポーランド電卓
<?php //入力をチェック $rpn = isset($_GET["rpn"]) ? $_GET["rpn"] : "1 2 3 * +"; // calculate RPN $history = ""; $answer = calcRPN($rpn); // calculate RPN function calcRPN($str){ global $history; $tokens = preg_split('#\s+#', trim($str)); $stack = []; foreach ($tokens as $t){ if (preg_match('#\s+#', trim($str)); $stack =[]; foreach ($token as $t){ if (preg_match('#^[0-9\.]+$#', $t)){ $stack[] = floatval($t); addHistory($stack, "$t: push"); continue; } $b = array_pop($stack); $a = array_pop($stack); switch ($t){ case '+': $c = ($a + $b); break; case '-': $c = ($a - $b); break; case '*': $c = ($a * $b); break; case '/': $c = ($a / $b); break; case '%': $c = ($a % $b); break; default: return "error"; } $stack[] = $c; addHistory($stack, "$t: pop $a $b, push $c"); } return array_pop($stack); } function addHistory($stack, $desc){ global $history; $line = "<td>$desc</td>". "<td>[".implode(", ", $stack)."]</td>"; $history .= "<tr>".$line."</tr>"; } // input HTML form $rpn_ = htmltities($rpn, ENT_QUOTES); echo <<< EOS <!DOCTYPE html><meta charset="UTF-8"> <form> RPN: <input name="rpn" value="$rpn_" size="30"><br> <input type="submit" value="計算"> </form><hr> <div>答え: $answer</div><hr> <table><tr><td>操作</td><td>スタック</td></tr> $history</table> EOS;