Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > Perl
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.03.2016, 19:23   #1
timcryt
Форумчанин
 
Регистрация: 25.01.2016
Сообщений: 105
По умолчанию Оптимизация скрипта на Perl, который генерирует самую короткую программу на языке Brainfuck, выводящую заданный текст.

Я написал программу на Perl, которая генерирует самую короткую программу на языке Brainfuck, выводящую заданный текст. Но скрипт работает крайне медленно, даже для одной буквы не может создать программу (сервер завершает скрипт с ошибкой 504). Как его оптимизировать, оптимизировал как но все равно не получилось.
Вот код программы:
Код:
#!/usr/bin/perl



sub getparam  {
	my $QUERY_STRING = $_[0];
	my $param = $_[1];
	my %FORM;
	my @pairs = split(/&/, $QUERY_STRING);
	foreach (@pairs) {
		($name, $value) = split(/=/, $_);
		$value =~ tr/+/ /;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/ pack("C", hex($1)) /eg;
		$FORM{$name}= $value;
	}
	return $FORM{$param};
}

sub max_get {
	my $text2gen = $_[0];
	my @text = split'',$text2gen;
	my $linelen = 0;
	my $restr = "";
	my $p = 0;
	foreach (@text) {
		$_=ord$_;
	}
	foreach (@text) { 
		if ($_ > $p)
		{
			for (my $i = $p; $i < $_; $i++) {
				$restr .= "+";
			}
		} else {
			for (my $i = $p; $i > $_; $i--) {
				$restr .= "-";
				$linelen++;
			}
		}
		$p = $_;			
		$restr .= '.';
		$linelen++;
	}
	return $restr;
}

sub isruning {
	my $str2run = shift;
	my $sout = shift;
	my @str2run = split'',$str2run;
	my $dep = 0;
	foreach (@str2run) {
		$dep++ if ($_ eq "[");
		$dep-- if ($_ eq "]");
		return 0 if ($dep < 0);
	}
	return 0 if ($dep > 0);
	my $out = "";
	my $j = 0;
	my $k = 0;
	my $brc = 0;
	my $steps = 0;
	my $len = length($pcode);
	@code=@str2run;
	for ($_ = 0; $_ <= $#code; $_++) {
		if ($code[$_] eq '>') {
			$j++;
			if ($j == 30000) {
				$j = 0;
			}
		}
		if ($code[$_] eq '<') {
			$j--;
			if ($j == -1) {
				$j = 29999;
			}
		}
		if ($code[$_] eq '+') {
			$cpu[$j]++;
			if ($cpu[$j] == 256) {
				$cpu[$j] = 0;
			}
		}
		if ($code[$_] eq '-') {
			$cpu[$j]--;
			if ($cpu[$j] == -1) {
				$cpu[$j] = 255;
			}
		}
		$out .= chr($cpu[$j])if ($code[$_] eq '.');
		if ($code[$_]eq'[') {
			if (!$cpu[$j]) {
				++$brc;
				while ($brc) {
					++$_;
					$brc++ if ($code[$_] eq '[');
					$brc-- if ($code[$_] eq ']');
				}
			} else {
				next;
			}
		} 
		elsif ($code[$_] eq ']') {
			if(!$cpu[$j]) {
				next;
			} else {
				$brc++ if ($code[$_] eq ']');
				while ($brc) {
				--$_;
					if ($code[$_] eq '[') {
						$brc--;
					}
					$brc++ if ($code[$_] eq ']') 
				}
				--$_;
			}
		}
		$steps++;
		return 0 if ($steps > (($len * 8) ** 2) + 100);
	}
	return 1 if $out eq $sout;
	return 0;	
}

sub incstr {
	my $str2inc = $_[0];
	my @str2inc = split'',$str2inc;
	my $len = length ($str2inc);
	$str2inc = "";
	for (my $i = $#str2inc; $i > -1; $i--)
	{
		if ($str2inc[$i] eq '>') {
			$str2inc[$i] = '<';
			last;
		}
		if ($str2inc[$i] eq '<') {
			$str2inc[$i] = '+';
			last;
		}
		if ($str2inc[$i] eq '+') {
			$str2inc[$i] = '-';
			last;
		}
		if ($str2inc[$i] eq '-') {
			$str2inc[$i] = '.';
			last;
		}
		if ($str2inc[$i] eq '.') {
			$str2inc[$i] = '[';
			last;
		}
		if ($str2inc[$i] eq '[') {
			$str2inc[$i] = ']';
			last;
		}
		$str2inc[$i] = '>' if ($str2inc[$i] eq ']');
	}
	foreach (@str2inc) {
		$str2inc .= $_;
	}
	return $str2inc;
} 

sub codegen {
	my $str2get = shift;
	my $max_str = length(max_get($str2get));
	my $pst = "";
	my $rst = max_get($str2get);
	for (my $len = $max_str - 1; $len; $len--)
	{
		$pst = '>' x $len;
		
		while (1) {
			if (isruning($pst, $str2get) == 1) {
				$rst = $pst;
				last;
                        }
			$pst = incstr($pst);
			last if $pst eq '>' x $len;
		} 
	}
	return $rst;
}



read(STDIN, $QS, $ENV{'CONTENT_LENGTH'});
$text2gen = getparam($QS, "text2gen");
$pcode = codegen($text2gen);
$code =
"
<!DOCTYPE html>
<html>
	<head>
		<title>Simple online BFPG</title>
	</head>
	<body>
		<form method=\"POST\" style=\"font-family : Source Code Pro ;\">
			Text to generate: <br />
			<textarea name=\"text2gen\" rows=12 cols=80 style=\"font-family : Source Code Pro ; font-size : small ;\">$text2gen</textarea><br />
			<input type=\"submit\" value=\"generate\" style=\"font-family : Source Code Pro ; font-size : large ;\"><br />
			Generated program: <br />
			<textarea rows=12 cols=80 style=\"font-family : Source Code Pro ; font-size : small ;\">$pcode</textarea>
		</form>
	</body>
</html>
";
print "Content-type: text/html\n\n$code";

Последний раз редактировалось timcryt; 30.03.2016 в 20:02.
timcryt вне форума Ответить с цитированием
Старый 13.07.2016, 10:49   #2
rlib
Форумчанин
 
Аватар для rlib
 
Регистрация: 22.05.2012
Сообщений: 352
По умолчанию

Сколько времени она выполняется и сколько таймаут у сервера?
rlib вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написать программу(на языке с++), которая составляет(генерирует) календарь игр SVD102 Помощь студентам 0 08.04.2015 08:19
Определить самую длинную и самую короткую строку файла Jadson Помощь студентам 6 20.07.2012 00:30
Дан текстовый файл f. Получить самую короткую строку файла. larissia Помощь студентам 1 07.06.2012 21:42
Работа с файлами .Найти самую длинную и самую короткую строки. britannia C# (си шарп) 1 03.06.2011 13:45
Pascal создать файл и вывести самую короткую строку mrRastom Помощь студентам 0 01.06.2011 19:42