Skip to content

Instantly share code, notes, and snippets.

@mvasilkov
Forked from Apkawa/generate_infix.c
Created January 19, 2012 22:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mvasilkov/1643235 to your computer and use it in GitHub Desktop.
Save mvasilkov/1643235 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define OPEN_BRACKET_STATE 1
#define CLOSE_BRACKET_STATE 2
#define NUMBER_STATE 3
#define OPERATOR_STATE 4
char OPERATORS[] = {'/', '*', '-', '+'};
const char OPEN_BRACKET = '(';
const char CLOSE_BRACKET = ')';
const char SPACE = ' ';
void write_symbol(char ch) {
printf("%c", ch);
}
void write_int(int ch) {
printf("%i", ch);
}
int randint(int from, int to) {
return from + rand() % to;
}
int rand_choice_int(int *array, int array_length) {
return array[randint(0, array_length)];
}
char rand_choice_char(char *array, int array_length) {
return array[randint(0, array_length)];
}
char get_operator(void) {
return rand_choice_char(OPERATORS, 4);
}
char get_number(void) {
return randint(0, 5000);
}
void generate_infix(long max_symbol_count) {
int open_bracket_number_array[] = {OPEN_BRACKET_STATE, NUMBER_STATE};
int state = rand_choice_int(open_bracket_number_array, 2);
long bracket_num = 0;
long i;
for (i = 0; i <= max_symbol_count; i++) {
switch (state) {
case OPEN_BRACKET_STATE:
{
state = NUMBER_STATE;
bracket_num++;
write_symbol(OPEN_BRACKET);
break;
}
case CLOSE_BRACKET_STATE:
{
bracket_num--;
state = OPERATOR_STATE;
write_symbol(CLOSE_BRACKET);
break;
}
case NUMBER_STATE:
{
if (bracket_num) {
if (randint(0, 1) == 1) {
state = OPERATOR_STATE;
} else {
state = CLOSE_BRACKET_STATE;
}
}
else {
state = OPERATOR_STATE;
}
write_int(get_number());
break;
}
case OPERATOR_STATE:
{
state = rand_choice_int(open_bracket_number_array, 2);
write_symbol(SPACE);
write_symbol(get_operator());
write_symbol(SPACE);
break;
}
}
}
if (state == OPERATOR_STATE)
{
write_symbol(SPACE);
write_symbol(get_operator());
write_symbol(SPACE);
state = NUMBER_STATE;
}
if (state == OPEN_BRACKET_STATE) {
state = NUMBER_STATE;
}
if (state == NUMBER_STATE) {
write_int(get_number());
}
if (bracket_num > 0) {
for (i = 0; i < bracket_num; i++) {
write_symbol(CLOSE_BRACKET);
}
}
}
int main(int argc, const char *argv[])
{
unsigned long max_symbol_count;
srand(time(NULL));
if (argc > 1)
{
max_symbol_count = strtol(argv[1], NULL, 10);
} else {
max_symbol_count = 1024;
}
generate_infix(max_symbol_count);
return 0;
}
# -*- coding: utf-8 -*-
import sys
import random
OPERATORS = '*/-+'
OPEN_BRACKET = 1
CLOSE_BRACKET = 2
NUMBER = 3
OPERATOR = 4
def get_operator():
rnd = random.random()
rate = 0.0
rate += 0.10
if rnd <= rate:
return random.choice("/*")
return random.choice("-+")
def get_number():
return random.randint(1, 1000)
def generate_infix(max_symbol=1024):
state = random.choice([OPEN_BRACKET, NUMBER])
bracket_num = 0
for i in xrange(max_symbol):
if state == OPEN_BRACKET:
state = NUMBER
bracket_num += 1
yield "("
elif state == CLOSE_BRACKET:
bracket_num -= 1
state = OPERATOR
yield ")"
elif state == NUMBER:
next_states = [OPERATOR]
if bracket_num:
next_states.append(CLOSE_BRACKET)
state = random.choice(next_states)
yield get_number()
elif state == OPERATOR:
state = random.choice([NUMBER, OPEN_BRACKET])
yield " "
yield get_operator()
yield " "
if state == OPERATOR:
yield get_operator()
state = NUMBER
if state == OPEN_BRACKET:
state = NUMBER
if state == NUMBER:
yield get_number()
if bracket_num > 0:
for i in xrange(bracket_num):
yield ")"
def test():
for i in xrange(1024):
for r in xrange(100):
try:
result = " ".join(map(str, generate_infix(i)))
result, ' = ', eval(result)
print "OK"
except ZeroDivisionError:
print "ZeroDivisionError"
def main():
try:
length = int(sys.argv[1])
except:
length = 1024
#f = open("test.txt", "wb")
f = sys.stdout
for symbol in generate_infix(length):
f.write(str(symbol))
if __name__ == '__main__':
#test()
main()
#include <stdio.h>
#include <stdlib.h>
#define size_array(array) (sizeof array)/(sizeof array[0])
char OPERATION[] = {'*', '/', '-', '+'};
char NUMBER[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
char OPEN_BRACKET[] = {'('};
char CLOSE_BRACKET[] = {')'};
int priority_char(char ch)
{
switch (ch){
case '(':
return 0;
case ')':
return 0;
case 'e':
return 0;
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
}
}
int char_in_array(char ch, char *array, int array_len) {
int i;
for (i = 0; i < array_len; i++) {
if (ch == array[i]) {
return 1;
}
}
return 0;
}
void write_result(char ch) {
printf("%c", ch);
}
void infix2postfix(FILE * file) {
int i;
int c;
char stack[255];
char ch;
char number_str[255];
int number_str_len = 0;
i = 0;
stack[0] = 'e';
while ((ch = (char)fgetc(file)) != -1) {
if (!char_in_array(ch, NUMBER, size_array(NUMBER)) && number_str_len) {
printf("%s ", number_str);
number_str_len = 0;
}
if (char_in_array(ch, OPERATION, size_array(OPERATION)))
{
while (1)
{
if (priority_char(ch) > priority_char(stack[i]))
{
i++;
stack[i] = ch;
break;
}
else {
write_result(stack[i]);
i--;
}
}
continue;
}
if (char_in_array(ch, NUMBER, size_array(NUMBER)))
{
number_str[number_str_len] = ch;
number_str[number_str_len + 1] = '\0';
number_str_len++;
continue;
}
if (char_in_array(ch, OPEN_BRACKET, size_array(OPEN_BRACKET)))
{
i++;
stack[i] = ch;
continue;
}
if (char_in_array(ch, CLOSE_BRACKET, size_array(CLOSE_BRACKET)))
{
while (1)
{
if (char_in_array(stack[i], OPEN_BRACKET, size_array(OPEN_BRACKET)))
{
i--;
break;
}
else
{
write_result(stack[i]);
i--;
}
}
continue;
}
}
int j;
for (j = 1; i < j; j++) {
write_result(stack[i]);
}
}
int main(int argc, const char *argv[])
{
FILE * file;
if (argc > 1)
{
file = fopen(argv[1], "r");
} else {
file = stdin;
}
infix2postfix(file);
printf("\n");
return 0;
}
# -*- coding: utf-8 -*-
import sys
import string
OPERATION = ['*', '/', '-', '+']
NUM = string.digits
ALPHA = string.ascii_lowercase
ALPHANUM = NUM + ALPHA
EMPTY = string.whitespace
OPEN_BRACKET = ['(']
CLOSE_BRACKET = [')']
def priority_char(ch):
'''
Функция приоритета
'''
if ch in ['(', ')', 'e']:
return 0
if ch in ['+', '-']:
return 1
if ch in ['*', '/']:
return 2
def infix2postfix(str_iter):
'''
python style
'''
stack = []
number_str = ''
stack.append('e')
for ch in str_iter:
if ch not in NUM and number_str:
yield number_str
number_str = ''
if ch in OPERATION:
while True:
if priority_char(ch) > priority_char(stack[-1]):
stack.append(ch)
break
else:
yield stack.pop()
elif ch in ALPHANUM:
number_str += ch
elif ch in OPEN_BRACKET:
stack.append(ch)
elif ch in CLOSE_BRACKET:
while True:
ch = stack.pop()
if ch in OPEN_BRACKET:
break
else:
yield ch
if number_str:
yield number_str
for s in reversed(stack[1:]):
yield s
FUNC_MAP = {
'+': lambda x, y: x + y,
'-': lambda x, y: x - y,
'/': lambda x, y: x / y,
'*': lambda x, y: x * y,
}
def postfix_calculate(iterator, stack=None):
if not stack:
stack = []
for char in iterator:
try:
stack.append(float(char))
except ValueError:
func = FUNC_MAP[char]
y = stack.pop()
x = stack.pop()
stack.append(func(x, y))
return stack[0]
def test():
result = list(infix2postfix("(1+2)/(3*2)-5"))
assert " ".join(result) == '1 2 + 3 2 * / 5 -', result
assert postfix_calculate(result) == -4.5
result = list(infix2postfix("(1+12)/(30*232)-50"))
assert " ".join(result) == '1 12 + 30 232 * / 50 -', result
assert -49.9 >= postfix_calculate(result) >= -50.0
result = list(infix2postfix("1 + 2 * (3 - 4) / 5"))
assert " ".join(result) == '1 2 3 4 - * 5 / +', result
assert postfix_calculate(result) == (1. + 2. * (3. - 4.) / 5.)
result = list(infix2postfix("(1) + (1)"))
assert " ".join(result) == '1 1 +', result
assert postfix_calculate(result) == (1 + 1)
def file_reader(file_obj, buf_size=1024):
'''
Посимвольное чтение из файла
'''
str_buf = file_obj.read(buf_size)
while str_buf:
for ch in str_buf:
yield ch
str_buf = file_obj.read(buf_size)
def main():
try:
file_obj = open(sys.argv[1])
except IndexError:
file_obj = sys.stdin
print postfix_calculate(infix2postfix(file_reader(file_obj)))
def main_final():
try:
file_obj = open(sys.argv[1])
except IndexError:
file_obj = sys.stdin
for symbol in infix2postfix(file_reader(file_obj)):
sys.stdout.write(str(symbol))
print
if __name__ == '__main__':
if "--calc" in sys.argv:
sys.argv.remove("--calc")
main()
else:
main_final()
#test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment