<?php 
 
 
abstract  class  Question
{ 
	protected  $text ; 
	protected  $points ; 
	protected  $correctAnswer ; 
 
	abstract  function  getAsString( ) ; 
	abstract  function  checkAnswer( $answer ) ; 
} 
 
class  MultipleChoiceQuestion extends  Question
{ 
    protected  $answers ; 
    protected  $almostCorrectAnswer ; 
    protected  $hint ; 
 
	public  function  __construct
( $text ,  float 
$points ,  array $answers ,  $correctAnswer ,  $hint )  	{ 
		$this -> text  =  $text ; 
		$this -> points  =  $points ; 
		$this -> answers  =  $answers ; 
		$this -> correctAnswer  =  $correctAnswer ; 
		$this -> hint  =  $hint ; 
	} 
 
	public  function  addAlmostCorrectAnswer( $almostCorrectAnswer ) 
	{ 
		$this -> almostCorrectAnswer  =  $almostCorrectAnswer ; 
	} 
 
	public  function  getAsString( ) 
	{ 
		$string  =  "{$this->text} \n Варианты ответов:\n " ; 
 
		foreach  ( $this -> answers  as  $letter  =>  $answer )  { 
			$string  =  $string . "{$letter} . {$answer} \n " ; 
		} 
 
		return  $string ; 
	} 
 
	public  function  checkAnswer( $answer ) 
	{ 
		$points  =  $this -> points ; 
		$text  =  $this -> text ; 
		$hint  =  $this -> hint ; 
 
		if  ( $answer  ==  $this -> correctAnswer )  { 
			return  array ( 1 ,  $points ) ;   
		}  elseif  ( $answer  ==  $this -> almostCorrectAnswer )  { 
			return  array ( 1 ,  $points ,  '' ,  '' ,  1 ) ;   
		} 
 
		return  array ( 0 ,  $points ,  $text ,  $hint ) ;  	} 
 
} 
 
class  NumericalQuestion extends  Question
{ 
	protected  $deviation ; 
 
	function  __construct( $text ,  float $points ,  float $correctAnswer ,  float $deviation  =  0 ) 
	{ 
		$this -> text  =  $text ; 
		$this -> points  =  $points ; 
		$this -> correctAnswer  =  $correctAnswer ; 
		$this -> deviation  =  $deviation ; 
	} 
 
	public  function  getAsString( ) 
	{ 
		return  "{$this->text} \n " ; 
	} 
 
	public  function  checkAnswer( $answer ) 
	{ 
		$points  =  $this -> points ; 
		$text  =  $this -> text ; 
 
		if  ( $answer  ==  $this -> correctAnswer )  { 
			return  array ( 1 ,  $points ) ;   
		}  elseif  ( $this -> deviation  >  0 )  { 
 
			$leftDeviation  =  $this -> correctAnswer  -  $this -> deviation ; 
			$rightDeviation  =  $this -> correctAnswer  +  $this -> deviation ; 
 
			if  ( $leftDeviation  <  $answer  and $rightDeviation  >  $answer )  { 
				return  array ( 1 ,  $points ) ;  			} 
 
		} 
 
        return  array ( 0 ,  $points ,  $text ) ;  	} 
 
} 
 
function  createQuestions( )  { 
	$questions  =  [ ] ; 
 
	$text  =  'Какая планета располагается четвертой по счету от Солнца?' ; 
	$answers  =  array ( 'a'  =>  'Венера' ,  'b'  =>  'Марс' ,  'c'  =>  'Юпитер' ,  'd'  =>  'Меркурий' ) ;  	$hint  =  'Одноименное название носит шоколадный батончик.' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  10 ,  $answers ,  'b' ,  $hint ) ; 
 
	$questions [ ]  =  $q ; 
 
	$text  =  'Какой город является столицей Великобритании?' ; 
	$answers  =  array ( 'a'  =>  'Париж' ,  'b'  =>  'Москва' ,  'c'  =>  'Нью-Йорк' ,  'd'  =>  'Лондон' ) ;  	$hint  =  '%Городнейм% из кэпитал оф грейт британ.' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  5 ,  $answers ,  'd' ,  $hint ) ; 
 
	$questions [ ]  =  $q ; 
 
	$text  =  'Кто придумал теорию относительности?' ; 
	$answers  =  array ( 'a'  =>  'Джон Леннон' ,  'b'  =>  'Джим Моррисон' ,  'c'  =>  'Альберт Эйнштейн' ,  'd'  =>  'Исаак Ньютон' ) ;  	$hint  =  'Этим парнем был...' ; 
	$q  =  new  MultipleChoiceQuestion( $text ,  30 ,  $answers ,  'c' ,  $hint ) ; 
	$q -> addAlmostCorrectAnswer ( 'b' ) ; 
 
	$questions [ ]  =  $q ; 
 
	$q  =  new  NumericalQuestion( 'Чему равна скорость света в км/с?' ,  15 ,  300000 ) ; 
 
	$questions [ ]  =  $q ; 
 
	$q  =  new  NumericalQuestion( 'Чему равно число Пи?' ,  30 ,  3.14 ,  0.01 ) ; 
 
	$questions [ ]  =  $q ; 
 
	$q  =  new  NumericalQuestion( 'В каком году закончилась вторая мировая война?' ,  10 ,  1945 ) ; 
 
	$questions [ ]  =  $q ; 
 
	return  $questions ; 
} 
 
function  printQuestions( $questions )  { 
 
	$number  =  1 ; 
 
	foreach  ( $questions  as  $question )  { 
		echo  "\n {$number} . " ; 
		echo  $question -> getAsString ( ) ; 
 
		$number  ++; 
	} 
 
} 
 
function  checkAnswers( $questions ,  $answers ) 
{ 
        die ( "Число ответов и вопросов не совпадает\n " ) ;      } 
 
    $pointsTotal  =  0 ; 
    $pointsMax  =  0 ; 
    $correctAnswers  =  0 ; 
 
    $totalQuestions  =  count ( $questions ) ;   
    for  ( $i  =  0 ;  $i  <  count ( $questions ) ;  $i ++ )  {   
        $question  =  $questions [ $i ] ; 
        $answer  =  $answers [ $i ] ; 
 
        $resultOfCheck  =  $question -> checkAnswer ( $answer ) ; 
 
        $pointsMax  +=  $resultOfCheck [ 1 ] ; 
 
        if  ( $resultOfCheck [ 0 ] )  { 
            $correctAnswers  ++; 
 
            if  ( ! empty ( $resultOfCheck [ 4 ] ) )  {              	$pointsTotal  +=  $resultOfCheck [ 1 ]  /  2 ; 
            }  else  { 
            	$pointsTotal  +=  $resultOfCheck [ 1 ] ; 
            } 
 
        }  else  { 
            $number  =  $i  +  1 ; 
            echo  "\n Неправильный ответ на вопрос №{$number}  ({$resultOfCheck[2]} )\n " ; 
 
            if  ( ! empty ( $resultOfCheck [ 3 ] ) )  {              	echo  "\n Подсказка: {$resultOfCheck[3]} \n " ; 
            } 
 
        } 
 
    } 
 
    echo  "\n Правильных ответов: {$correctAnswers}  из {$totalQuestions} , баллов набрано: $pointsTotal  из $pointsMax \n " ; 
} 
 
$questions  =  createQuestions( ) ; 
printQuestions( $questions ) ; 
checkAnswers
( $questions ,  array ( 'b' ,  'c' ,  'b' ,  300000 ,  3.14444444 ,  1945 ) ) ; PD9waHAKCmVycm9yX3JlcG9ydGluZyhFX0FMTCk7CgphYnN0cmFjdCBjbGFzcyBRdWVzdGlvbgp7Cglwcm90ZWN0ZWQgJHRleHQ7Cglwcm90ZWN0ZWQgJHBvaW50czsKCXByb3RlY3RlZCAkY29ycmVjdEFuc3dlcjsKCglhYnN0cmFjdCBmdW5jdGlvbiBnZXRBc1N0cmluZygpOwoJYWJzdHJhY3QgZnVuY3Rpb24gY2hlY2tBbnN3ZXIoJGFuc3dlcik7Cn0KCmNsYXNzIE11bHRpcGxlQ2hvaWNlUXVlc3Rpb24gZXh0ZW5kcyBRdWVzdGlvbgp7CiAgICBwcm90ZWN0ZWQgJGFuc3dlcnM7CiAgICBwcm90ZWN0ZWQgJGFsbW9zdENvcnJlY3RBbnN3ZXI7CiAgICBwcm90ZWN0ZWQgJGhpbnQ7CgoJcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCR0ZXh0LCBmbG9hdCAkcG9pbnRzLCBhcnJheSAkYW5zd2VycywgJGNvcnJlY3RBbnN3ZXIsICRoaW50KQoJewoJCSR0aGlzLT50ZXh0ID0gJHRleHQ7CgkJJHRoaXMtPnBvaW50cyA9ICRwb2ludHM7CgkJJHRoaXMtPmFuc3dlcnMgPSAkYW5zd2VyczsKCQkkdGhpcy0+Y29ycmVjdEFuc3dlciA9ICRjb3JyZWN0QW5zd2VyOwoJCSR0aGlzLT5oaW50ID0gJGhpbnQ7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGFkZEFsbW9zdENvcnJlY3RBbnN3ZXIoJGFsbW9zdENvcnJlY3RBbnN3ZXIpCgl7CgkJJHRoaXMtPmFsbW9zdENvcnJlY3RBbnN3ZXIgPSAkYWxtb3N0Q29ycmVjdEFuc3dlcjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXNTdHJpbmcoKQoJewoJCSRzdHJpbmcgPSAieyR0aGlzLT50ZXh0fVxu0JLQsNGA0LjQsNC90YLRiyDQvtGC0LLQtdGC0L7QsjpcbiI7CgoJCWZvcmVhY2ggKCR0aGlzLT5hbnN3ZXJzIGFzICRsZXR0ZXIgPT4gJGFuc3dlcikgewoJCQkkc3RyaW5nID0gJHN0cmluZy4ieyRsZXR0ZXJ9LiB7JGFuc3dlcn1cbiI7CgkJfQoKCQlyZXR1cm4gJHN0cmluZzsKCX0KCglwdWJsaWMgZnVuY3Rpb24gY2hlY2tBbnN3ZXIoJGFuc3dlcikKCXsKCQkkcG9pbnRzID0gJHRoaXMtPnBvaW50czsKCQkkdGV4dCA9ICR0aGlzLT50ZXh0OwoJCSRoaW50ID0gJHRoaXMtPmhpbnQ7CgoJCWlmICgkYW5zd2VyID09ICR0aGlzLT5jb3JyZWN0QW5zd2VyKSB7CgkJCXJldHVybiBhcnJheSgxLCAkcG9pbnRzKTsKCgkJfSBlbHNlaWYgKCRhbnN3ZXIgPT0gJHRoaXMtPmFsbW9zdENvcnJlY3RBbnN3ZXIpIHsKCQkJcmV0dXJuIGFycmF5KDEsICRwb2ludHMsICcnLCAnJywgMSk7CgoJCX0KCgkJcmV0dXJuIGFycmF5KDAsICRwb2ludHMsICR0ZXh0LCAkaGludCk7Cgl9Cgp9CgpjbGFzcyBOdW1lcmljYWxRdWVzdGlvbiBleHRlbmRzIFF1ZXN0aW9uCnsKCXByb3RlY3RlZCAkZGV2aWF0aW9uOwoKCWZ1bmN0aW9uIF9fY29uc3RydWN0KCR0ZXh0LCBmbG9hdCAkcG9pbnRzLCBmbG9hdCAkY29ycmVjdEFuc3dlciwgZmxvYXQgJGRldmlhdGlvbiA9IDApCgl7CgkJJHRoaXMtPnRleHQgPSAkdGV4dDsKCQkkdGhpcy0+cG9pbnRzID0gJHBvaW50czsKCQkkdGhpcy0+Y29ycmVjdEFuc3dlciA9ICRjb3JyZWN0QW5zd2VyOwoJCSR0aGlzLT5kZXZpYXRpb24gPSAkZGV2aWF0aW9uOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBc1N0cmluZygpCgl7CgkJcmV0dXJuICJ7JHRoaXMtPnRleHR9XG4iOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBjaGVja0Fuc3dlcigkYW5zd2VyKQoJewoJCSRwb2ludHMgPSAkdGhpcy0+cG9pbnRzOwoJCSR0ZXh0ID0gJHRoaXMtPnRleHQ7CgoJCWlmICgkYW5zd2VyID09ICR0aGlzLT5jb3JyZWN0QW5zd2VyKSB7CgkJCXJldHVybiBhcnJheSgxLCAkcG9pbnRzKTsKCgkJfSBlbHNlaWYgKCR0aGlzLT5kZXZpYXRpb24gPiAwKSB7CgoJCQkkbGVmdERldmlhdGlvbiA9ICR0aGlzLT5jb3JyZWN0QW5zd2VyIC0gJHRoaXMtPmRldmlhdGlvbjsKCQkJJHJpZ2h0RGV2aWF0aW9uID0gJHRoaXMtPmNvcnJlY3RBbnN3ZXIgKyAkdGhpcy0+ZGV2aWF0aW9uOwoKCQkJaWYgKCRsZWZ0RGV2aWF0aW9uIDwgJGFuc3dlciBhbmQgJHJpZ2h0RGV2aWF0aW9uID4gJGFuc3dlcikgewoJCQkJcmV0dXJuIGFycmF5KDEsICRwb2ludHMpOwoJCQl9CgoJCX0KCiAgICAgICAgcmV0dXJuIGFycmF5KDAsICRwb2ludHMsICR0ZXh0KTsKCX0KCn0KCmZ1bmN0aW9uIGNyZWF0ZVF1ZXN0aW9ucygpIHsKCSRxdWVzdGlvbnMgPSBbXTsKCgkkdGV4dCA9ICfQmtCw0LrQsNGPINC/0LvQsNC90LXRgtCwINGA0LDRgdC/0L7Qu9Cw0LPQsNC10YLRgdGPINGH0LXRgtCy0LXRgNGC0L7QuSDQv9C+INGB0YfQtdGC0YMg0L7RgiDQodC+0LvQvdGG0LA/JzsKCSRhbnN3ZXJzID0gYXJyYXkoJ2EnID0+ICfQktC10L3QtdGA0LAnLCAnYicgPT4gJ9Cc0LDRgNGBJywgJ2MnID0+ICfQrtC/0LjRgtC10YAnLCAnZCcgPT4gJ9Cc0LXRgNC60YPRgNC40LknKTsKCSRoaW50ID0gJ9Ce0LTQvdC+0LjQvNC10L3QvdC+0LUg0L3QsNC30LLQsNC90LjQtSDQvdC+0YHQuNGCINGI0L7QutC+0LvQsNC00L3Ri9C5INCx0LDRgtC+0L3Rh9C40LouJzsKCSRxID0gbmV3IE11bHRpcGxlQ2hvaWNlUXVlc3Rpb24oJHRleHQsIDEwLCAkYW5zd2VycywgJ2InLCAkaGludCk7CgoJJHF1ZXN0aW9uc1tdID0gJHE7CgoJJHRleHQgPSAn0JrQsNC60L7QuSDQs9C+0YDQvtC0INGP0LLQu9GP0LXRgtGB0Y8g0YHRgtC+0LvQuNGG0LXQuSDQktC10LvQuNC60L7QsdGA0LjRgtCw0L3QuNC4Pyc7CgkkYW5zd2VycyA9IGFycmF5KCdhJyA9PiAn0J/QsNGA0LjQticsICdiJyA9PiAn0JzQvtGB0LrQstCwJywgJ2MnID0+ICfQndGM0Y4t0JnQvtGA0LonLCAnZCcgPT4gJ9Cb0L7QvdC00L7QvScpOwoJJGhpbnQgPSAnJdCT0L7RgNC+0LTQvdC10LnQvCUg0LjQtyDQutGN0L/QuNGC0LDQuyDQvtGEINCz0YDQtdC50YIg0LHRgNC40YLQsNC9Lic7CgkkcSA9IG5ldyBNdWx0aXBsZUNob2ljZVF1ZXN0aW9uKCR0ZXh0LCA1LCAkYW5zd2VycywgJ2QnLCAkaGludCk7CgoJJHF1ZXN0aW9uc1tdID0gJHE7CgoJJHRleHQgPSAn0JrRgtC+INC/0YDQuNC00YPQvNCw0Lsg0YLQtdC+0YDQuNGOINC+0YLQvdC+0YHQuNGC0LXQu9GM0L3QvtGB0YLQuD8nOwoJJGFuc3dlcnMgPSBhcnJheSgnYScgPT4gJ9CU0LbQvtC9INCb0LXQvdC90L7QvScsICdiJyA9PiAn0JTQttC40Lwg0JzQvtGA0YDQuNGB0L7QvScsICdjJyA9PiAn0JDQu9GM0LHQtdGA0YIg0K3QudC90YjRgtC10LnQvScsICdkJyA9PiAn0JjRgdCw0LDQuiDQndGM0Y7RgtC+0L0nKTsKCSRoaW50ID0gJ9Ct0YLQuNC8INC/0LDRgNC90LXQvCDQsdGL0LsuLi4nOwoJJHEgPSBuZXcgTXVsdGlwbGVDaG9pY2VRdWVzdGlvbigkdGV4dCwgMzAsICRhbnN3ZXJzLCAnYycsICRoaW50KTsKCSRxLT5hZGRBbG1vc3RDb3JyZWN0QW5zd2VyKCdiJyk7CgoJJHF1ZXN0aW9uc1tdID0gJHE7CgoJJHEgPSBuZXcgTnVtZXJpY2FsUXVlc3Rpb24oJ9Cn0LXQvNGDINGA0LDQstC90LAg0YHQutC+0YDQvtGB0YLRjCDRgdCy0LXRgtCwINCyINC60Lwv0YE/JywgMTUsIDMwMDAwMCk7CgoJJHF1ZXN0aW9uc1tdID0gJHE7CgoJJHEgPSBuZXcgTnVtZXJpY2FsUXVlc3Rpb24oJ9Cn0LXQvNGDINGA0LDQstC90L4g0YfQuNGB0LvQviDQn9C4PycsIDMwLCAzLjE0LCAwLjAxKTsKCgkkcXVlc3Rpb25zW10gPSAkcTsKCgkkcSA9IG5ldyBOdW1lcmljYWxRdWVzdGlvbign0JIg0LrQsNC60L7QvCDQs9C+0LTRgyDQt9Cw0LrQvtC90YfQuNC70LDRgdGMINCy0YLQvtGA0LDRjyDQvNC40YDQvtCy0LDRjyDQstC+0LnQvdCwPycsIDEwLCAxOTQ1KTsKCgkkcXVlc3Rpb25zW10gPSAkcTsKCglyZXR1cm4gJHF1ZXN0aW9uczsKfQoKZnVuY3Rpb24gcHJpbnRRdWVzdGlvbnMoJHF1ZXN0aW9ucykgewoKCSRudW1iZXIgPSAxOwoKCWZvcmVhY2ggKCRxdWVzdGlvbnMgYXMgJHF1ZXN0aW9uKSB7CgkJZWNobyAiXG57JG51bWJlcn0uICI7CgkJZWNobyAkcXVlc3Rpb24tPmdldEFzU3RyaW5nKCk7CgoJCSRudW1iZXIgKys7Cgl9Cgp9CgpmdW5jdGlvbiBjaGVja0Fuc3dlcnMoJHF1ZXN0aW9ucywgJGFuc3dlcnMpCnsKICAgIGlmIChjb3VudCgkcXVlc3Rpb25zKSAhPSBjb3VudCgkYW5zd2VycykpIHsKICAgICAgICBkaWUoItCn0LjRgdC70L4g0L7RgtCy0LXRgtC+0LIg0Lgg0LLQvtC/0YDQvtGB0L7QsiDQvdC1INGB0L7QstC/0LDQtNCw0LXRglxuIik7CiAgICB9CgogICAgJHBvaW50c1RvdGFsID0gMDsKICAgICRwb2ludHNNYXggPSAwOwogICAgJGNvcnJlY3RBbnN3ZXJzID0gMDsKCiAgICAkdG90YWxRdWVzdGlvbnMgPSBjb3VudCgkcXVlc3Rpb25zKTsKCiAgICBmb3IgKCRpID0gMDsgJGkgPCBjb3VudCgkcXVlc3Rpb25zKTsgJGkrKykgewoKICAgICAgICAkcXVlc3Rpb24gPSAkcXVlc3Rpb25zWyRpXTsKICAgICAgICAkYW5zd2VyID0gJGFuc3dlcnNbJGldOwoKICAgICAgICAkcmVzdWx0T2ZDaGVjayA9ICRxdWVzdGlvbi0+Y2hlY2tBbnN3ZXIoJGFuc3dlcik7CgogICAgICAgICRwb2ludHNNYXggKz0gJHJlc3VsdE9mQ2hlY2tbMV07CgogICAgICAgIGlmICgkcmVzdWx0T2ZDaGVja1swXSkgewogICAgICAgICAgICAkY29ycmVjdEFuc3dlcnMgKys7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRyZXN1bHRPZkNoZWNrWzRdKSkgewogICAgICAgICAgICAJJHBvaW50c1RvdGFsICs9ICRyZXN1bHRPZkNoZWNrWzFdIC8gMjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCSRwb2ludHNUb3RhbCArPSAkcmVzdWx0T2ZDaGVja1sxXTsKICAgICAgICAgICAgfQoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkbnVtYmVyID0gJGkgKyAxOwogICAgICAgICAgICBlY2hvICJcbtCd0LXQv9GA0LDQstC40LvRjNC90YvQuSDQvtGC0LLQtdGCINC90LAg0LLQvtC/0YDQvtGBIOKElnskbnVtYmVyfSAoeyRyZXN1bHRPZkNoZWNrWzJdfSlcbiI7CgogICAgICAgICAgICBpZiAoIWVtcHR5KCRyZXN1bHRPZkNoZWNrWzNdKSkgewogICAgICAgICAgICAJZWNobyAiXG7Qn9C+0LTRgdC60LDQt9C60LA6IHskcmVzdWx0T2ZDaGVja1szXX1cbiI7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQoKICAgIH0KCiAgICBlY2hvICJcbtCf0YDQsNCy0LjQu9GM0L3Ri9GFINC+0YLQstC10YLQvtCyOiB7JGNvcnJlY3RBbnN3ZXJzfSDQuNC3IHskdG90YWxRdWVzdGlvbnN9LCDQsdCw0LvQu9C+0LIg0L3QsNCx0YDQsNC90L46ICRwb2ludHNUb3RhbCDQuNC3ICRwb2ludHNNYXhcbiI7Cn0KCiRxdWVzdGlvbnMgPSBjcmVhdGVRdWVzdGlvbnMoKTsKcHJpbnRRdWVzdGlvbnMoJHF1ZXN0aW9ucyk7CmNoZWNrQW5zd2VycygkcXVlc3Rpb25zLCBhcnJheSgnYicsICdjJywgJ2InLCAzMDAwMDAsIDMuMTQ0NDQ0NDQsIDE5NDUpKTs=