Ромб
Вот мой вариант зарисовки ромба n-размера в консоле:
{
int i,j,n;
int size=27;
// Рисуем вверх ромба (то есть обычный треугольник)
for(n=0;n<=size;n++){
for(i=size-1;i>=n-1;i--)
cout<<" ";
cout<<"*";
for(j=0;j<=n-1;j++)
cout<<"**";
cout<<endl;
}
//----------------------------------
//Середина
for(int z=0;z<=j+n+1;z++)
cout<<"*";
cout<<endl;
//----------------------------------
// Низ ромба (перевернутый треугольник)
for(n=0;n<=size;n++){
for(i=0;i<=n;i++)
cout<<" ";
cout<<"*";
for(j=size-1;j>=n;j--)
cout<<"**";
cout<<endl;
}
}
Если кто подскажет где и как можно оптимизировать (сжать код, избавиться от мусора), буду благодарен....
Но все равно прикольно получилось :)
for(int y=0; y<Size; y++)
{
for(int x=0; x<Size; x++)
{
if(((x>=Size/2) && (y >= x-Size/2) && (y-Size/2 <= Size-x-1)) ||
((x<=Size/2) && (y >= Size/2-x) && (y-Size/2 <= x)))
{
cout << "*";
}
else
cout << " ";
}
cout << endl;
}
P.S Код годится для ромбов с углами 45. И с нечетным размером.
{
unsigned int half = width/2;
for(int i=0; i < half; ++i) {
cout << setw(half-i) << setfill(' ') << ' ' << setw(i*2+1) << setfill('*') << '*' << endl;
}
cout << setw(half*2+1) << setfill('*') << '*' << endl;
for(int i=half-1; i>=0; --i) {
cout << setw(half-i) << setfill(' ') << ' ' << setw(i*2+1) << setfill('*') << '*' << endl;
}
}
или такой вариант:
{
unsigned int half = width/2;
for(int i=0; i < half; ++i) {
cout << string(half-i, ' ') << string(i*2+1, '*') << endl;
}
cout << string(half*2+1, '*') << endl;
for(int i=half-1; i>=0; --i) {
cout << string(half-i,' ') << string(i*2+1, '*') << endl;
}
}
Я так понимаю у Тебя ВЦ7, он позволяет переопределять переменную (у Тебя int i).
Мое мнение - это плохо, что он такое позволяет. Или у Тебя другие соображения по этому поводу?
{
const int size=27;
char *a = new char[size+2];
strnset(a, 32, size+1);
char *chl = a + size/2;
char *chr = chl;
a[size+1] = 0;
*chl = '*';
while(chl>a)
{
cout << a << endl;
chr++;
*chr = '*';
chl--;
*chl = '*';
}
while(chl<=chr)
{
cout << a << endl;
*chr = ' ';
chr--;
*chl = ' ';
chl++;
}
delete[] a;
}
to Green:
Я так понимаю у Тебя ВЦ7, он позволяет переопределять переменную (у Тебя int i).
Мое мнение - это плохо, что он такое позволяет. Или у Тебя другие соображения по этому поводу?
По стандарту все ОК.
Я считаю, что это хорошо. :)
Т.к. четко видно, что i используется только внутри цикла.
четко видно, что i используется только внутри цикла.
Ну, если так смотреть, то да, все ОК.
Просто ВЦ6 считал по другому.
P.S. Любиш ты подъ####
{
const int size=27;
char *a = new char[size+2];
strnset(a, 32, size+1);
char *chl = a + size/2;
char *chr = chl;
a[size+1] = 0;
*chl = '*';
while(chl>a)
{
cout << a << endl;
chr++;
*chr = '*';
chl--;
*chl = '*';
}
while(chl<=chr)
{
cout << a << endl;
*chr = ' ';
chr--;
*chl = ' ';
chl++;
}
delete[] a;
}
Хорошее решение. Подрехтовать, так вообще классное.
Хорошее решение. Подрехтовать, так вообще классное.
По просьбе трудящихся.
void main()
{
char *a = new char[size+2];
strnset(a, 32, size/2);
char *chl = a + size/2;
char *chr = chl;
while(chl>a)
{
*chr = '*';
chr++;
*chr = 0;
cout << a << endl;
chl--;
*chl = '*';
}
*chr = '*';
chr++;
*chr = 0;
while(chl<=chr)
{
cout << a << endl;
chr--;
*chr = 0;
*chl = ' ';
chl++;
}
delete[] a;
}
{
COORD coord;
int size=25;
int k;
coord.X=size/2+1;
coord.Y=0;
HANDLE hout = ::GetStdHandle(STD_OUTPUT_HANDLE);
for(int j=0;j<size;j++)
{
::SetConsoleCursorPosition(hout,coord);
k=j<size/2?(2*j+1):k=j==size/2?k+2:k-2;
for(int i=0;i<k;i++)cout<<"*";
coord.X= j<size/2?coord.X-1:coord.X+1;
coord.Y=coord.Y+1;
}
}
Мин.число операций/мин. память. Программа настолько прямолинейна, что даже теореме Лобачевского: "прямые пересекаются в безкончности" - не удовлетворяет.
Программа и правду классная.
Но сейчас прийдет Грин и скажет, мол учитесь писать на С++, и т.д. и т.п.
Хотя может после моего поста, он этого не скажет.
Программа и правду классная.
Но сейчас прийдет Грин и скажет, мол учитесь писать на С++, и т.д. и т.п.
Хотя может после моего поста, он этого не скажет.
На месте этого Green-а я бы срочно доработал, никуда не годяющуюся програмку с топика "Разминка для ума", чтоб сильно не краснеть, после того как я выставлю свою.
На месте этого Green-а я бы срочно доработал, никуда не годяющуюся програмку с топика "Разминка для ума", чтоб сильно не краснеть, после того как я выставлю свою.
Этот Green говорит: давай, выставляй, а там посмотрим, кому краснеть.
Что же касается рихтовки, то я имел в виду привеси всё в более читабельный и интуитивно понятный вид.
Вот как бы отрехтовал я:
{
char* str = new char[size+2];
strnset(str, ' ', size);
str[size] = '\0';
str[size+1] = '\0';
char* left = str + size/2;
char* right = left;
while(left > str)
{
*right++ = '*';
*left-- = '*';
cout << str << endl;
}
*right = '*';
*left = '*';
cout << str << endl;
while(left < right)
{
*right-- = ' ';
*left++ = ' ';
cout << str << endl;
}
delete[] str;
}
Этот Green говорит: давай, выставляй, а там посмотрим, кому краснеть.
Слушай сюда, Этот Green! Ты не смотри на то, что у меня 30 с чем-то ответов, а у Тебя более 1700. А на мой ник вообще не обращай внимание, так как я был заграницей и забыл пароль от моего нормального ника. И благодаря одной недоделке mike-а, мне проще было определить чужой пароль, чем вспомнить свой. В выходные хотел уже войти под старым ником, но не получилось. Подумал, что mike заметил мое нахальство и забанил мой IP. Даже хотел отправить ему email и извиниться. Но вместо это mike извинился (извинение принимается :)), и пообещал, что больше это не повторится (Ok, будем надеяться :)).
На счет твоего "шедевра". Пока еще я мимоходом, мог осмыслить только первый шаг моей программы. Чтоб осмыслить второй шаг нужно бы писать код, а на это теперь нет времени.
Значит. Твоя прога:
1. Выделяется память 4*N*N байт.
2. Копируется матрица в эту память.
3. Определяется высота для каждой ячейки.
4. Определяется макс.область.
Вопрос, для чего выделять память, потом копировать значения, если каждый раз нужна высота только для текущей строки?
1. Выделяется память 4*N байт.
2. Первая строка копируется в эту память и сразу же имеем высоту для ячеек первой строки.
3. Определение макс. области начинается с 2й строки. Если текущий элемент = 0, тогда просто пишется в соответствующую позицию выделенной памяти 0. Если не 0, тогда берется значение из соотв. позиции, увеличивается на 1 и пишется обратно и ячейка обрабатывается.
4. Если в конце проверки макс.площадь меньше n, тогда проверяется первая строка.
Качество алгоритма определяет не только быстродействие, но и требуемая доп. память. У моей проге это будет порядка N, у твоей N^2.
Напр. для матриц с N=8192 моя прога выделит 32kB, твоя 256МБ.
[color=white]__ __[/color]32 768 байт против
268 435 456 байт.
Т.е. относительно памяти, твоя прога просто нигде.
На счет быстродействия.
Пару месяцев тому назад переделывал одну программу. В ней проверялся допустимы ли координаты x,y и если да, тогда значение ячейки менялось на 1. a[x][y] = 1;
[x][y] заменил на int* и убрал проверку диапозона. Только из-за этого прога начала работать быстрее более чем 5 раз.
Т.е. если я даже не оптимизирую второй шаг, а только так закодирую программу, то она будет работать быстрее от твоего в несколько раз. И если одна прога работает быстрее второй хотя бы два раз, то imho это означет, что программисты писавшие эти программы были не в одной категории. Так что всеж таки я на твоем месте срочно исправил бы программу. :)
Слушай сюда, Этот Green! Ты не смотри на то, что у меня 30 с чем-то ответов, а у Тебя более 1700. А на мой ник вообще не обращай внимание, так как я был заграницей и забыл пароль от моего нормального ника. И благодаря одной недоделке mike-а, мне проще было определить чужой пароль, чем вспомнить свой. В выходные хотел уже войти под старым ником, но не получилось. Подумал, что mike заметил мое нахальство и забанил мой IP. Даже хотел отправить ему email и извиниться. Но вместо это mike извинился (извинение принимается :)), и пообещал, что больше это не повторится (Ok, будем надеяться :)).
Надеюсь, ты выговорился о своих неоцененных по-достоинству заслугах перед человечеством и о суровых ударах сутьбы.
Теперь объясни, какое отношение твой отрывок из героической автобиографии имеет к теме данного раздела форума?
На счет твоего "шедевра". Пока еще я мимоходом, мог осмыслить только первый шаг моей программы. Чтоб осмыслить второй шаг нужно бы писать код, а на это теперь нет времени.
Мы, если ты мимоходом это не заметил, обсуждали алгоритм, а не реализацию (программу).
Значит. Твоя прога:
1. Выделяется память 4*N*N байт.
Ну если быть точнее, то (N+2)*(N+2)... :)
1. Выделяется память 4*N байт.
2. Первая строка копируется в эту память и сразу же имеем высоту для ячеек первой строки.
3. Определение макс. области начинается с 2й строки. Если текущий элемент = 0, тогда просто пишется в соответствующую позицию выделенной памяти 0. Если не 0, тогда берется значение из соотв. позиции, увеличивается на 1 и пишется обратно и ячейка обрабатывается.
4. Если в конце проверки макс.площадь меньше n, тогда проверяется первая строка.
Ты описал реализацию, предложенного мной алгоритма. Только и всего.
Совместил вместе два раздельных шага, что уже делал по-своему REmindER.
Реализаций этого алгоритма может быть множество, суть одна - два шага: нахождение проекций и обход этих проекций.
Я же доводил этот алгоритм в наиболее понятной форме. Для тех, кто в танке, ещё раз обращаю внимание:
"Во-первых, требовался оптимальный по сложности (скорости) АЛГОРИТМ, о реализации пока речи не было."
Ну и в топике соотв. ветки это указано.
Качество алгоритма определяет не только быстродействие, но и требуемая доп. память.
Ну во-первых, это зависит от критериев оценки.
В топике критерием значилась сложность, т.е. зависимоть кол-ва итераций от размеров матрицы.
Во-вторых, память - это вопрос реализации.
У моей проге это будет порядка N, у твоей N^2.
Напр. для матриц с N=8192 моя прога выделит 32kB, твоя 256МБ.
[color=white]__ __[/color]32 768 байт против
268 435 456 байт.
Т.е. относительно памяти, твоя прога просто нигде.
Ну пока твоей проги просто нет нигде... :D :D :D
Кроме того, я ещё раз говорю (до чего же люди бывают твердолобы):
Это всего-лишь интуитивно понятная реализация очень близкая к простому описанию.
Кстати, практика показывает, а умы программирования рекомендуют, что первая реализация должна быть наиболее простой. Оптимизация - это последующие шаги. Для начала надо удостовериться в работоспособности алгоритма.
На счет быстродействия.
Пару месяцев тому назад переделывал одну программу. В ней проверялся допустимы ли координаты x,y и если да, тогда значение ячейки менялось на 1. a[x][y] = 1;
[x][y] заменил на int* и убрал проверку диапозона. Только из-за этого прога начала работать быстрее более чем 5 раз.
Ну чтож , молодец. Этот процесс называется оптимизацией и начинается, когда есть работоспособный код.
Кстати, ты использовал unitesting?
А как определил увеличение производительности?
Каким способом профилировал программу?
Ты уверен, что в 5 раз, а не в 4.75 или 5.25 раз?
Это было самое слабое место в программе?
Какие ещё типы оптимизации рассматривались?
Т.е. если я даже не оптимизирую второй шаг, а только так закодирую программу, то она будет работать быстрее от твоего в несколько раз. И если одна прога работает быстрее второй хотя бы два раз, то imho это означет, что программисты писавшие эти программы были не в одной категории.
Ты хочешь доказать, что ты круче меня?
Флаг в руки, я не собираюсь с этим спорить.
Можешь прибить медаль себе на стену, если тебе от этого будет легче.
Так что всеж таки я на твоем месте срочно исправил бы программу. :)
"Исправил"?
Я не вижу ошибок, а сл-но она на данный момент может считаться исправной.
Может, ты путаешься в терминах? Хотел сказать "я на твоем месте срочно ОПТИМИЗИРОВАЛ бы программу " ?
Вопрос: а зачем?
Цель достигнута, - получена рабочая реализация алгоритма, которая интуитивно понятна.
Оптимизировать можно до бесконечности, был ла бы необходимость и были бы определены критерии оптимизации.
Я такой задачи в теме не ставил. Реализацию и то привел, для наглядности.
P.S. Если есть вопросы, предложения, мысли и ещё неинтересные истории из твоей нелегкой жизни, то пиши в соотв. теме. Эта тема "Ромб", на сколько мне известно.
2. На счет всего остального. Take it easy. ;)