сложение чисел со знаком
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 10:15
Оценка: 10 (1) -1
вот вам задачка:
написать сабж на C максимально короткий.
формат такой:
char*sum(char*a,char*b,int Z,int Y,int*W);
причем a,b = исходные строки, в которых записаны числа (от больших разрядов к меньшим),
Z и Y — знаки: 1 = число отрицательное, 0 = число положительное.
W = знак результата, 1 = результат отрицательный, 0 = положительный.

задачка абсолютно реальная, и возникла, когда друг попросил меня написать такую функцию. я сказал: ну... порядка 10 строк. Но ведь можно и короче
Я пока свернул сабж где-то в 400 символов (с учетом определения char* sum(bla-bla){}, "где-то" потому что ещё в процессе)
А кто сможет короче?

Формат ввода менять нельзя! разве что переменные поменять на более понятные...
Записать это надо в одну строчку и без define и inline-функций.
Остальные варианты — оффтопик ( ветку так и назовите )

p.s. Математические и прочие библиотеки не использовать! Только стандартные библиотеки Си.
У меня это —
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/bur
Re: сложение чисел со знаком
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 02.06.03 10:35
Оценка: +1
Здравствуйте, BUran, Вы писали:

BU>вот вам задачка:

BU>написать сабж на C максимально короткий.
BU>формат такой:
BU> char*sum(char*a,char*b,int Z,int Y,int*W);
BU>причем a,b = исходные строки, в которых записаны числа (от больших разрядов к меньшим),
BU>Z и Y — знаки: 1 = число отрицательное, 0 = число положительное.
BU>W = знак результата, 1 = результат отрицательный, 0 = положительный.

[]

Навскидку — 214 знаков, учитывая пробелы...

char* sum(char* a,char* b,int Z,int Y,int* W)
{
static char res[40] = {0};
int i1 = atoi(a);
int i2 = atoi(b);
if(Z) i1 = -i1;
if(Y) i2 = -i2;
i1 += i2;
*W = i1<0 ? 1 : 0;
sprintf(res,"%ld",i1);
return (*W ? &res[1] : res);
}
Re[2]: сложение чисел со знаком
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 10:40
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Навскидку — 214 знаков, учитывая пробелы...


Ну, не так быстро. Строки-то бывают любой длины! А иначе и смысла нету...
/bur
Re[3]: сложение чисел со знаком
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 02.06.03 10:44
Оценка:
Здравствуйте, BUran, Вы писали:

BU>Здравствуйте, Flamer, Вы писали:


F>>Навскидку — 214 знаков, учитывая пробелы...


BU>Ну, не так быстро. Строки-то бывают любой длины! А иначе и смысла нету...


Не понял... Вы о чем? всем вашим требованиям удовлетворяет... А проверять переданные указатели на NULL — лень Или вам проверку на NULL дописать? Ну плюс еще знаков 20...
Re[4]: сложение чисел со знаком
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 10:47
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Не понял... Вы о чем? всем вашим требованиям удовлетворяет... А проверять переданные указатели на NULL — лень Или вам проверку на NULL дописать? Ну плюс еще знаков 20...

Числа могут ни в int, не в long, ни даже в long long не влезть!

Надо было подписать: длиннннная аррифффмметиккка
/bur
Re[5]: сложение чисел со знаком
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 02.06.03 10:48
Оценка:
Здравствуйте, BUran, Вы писали:

[]

BU>Числа могут ни в int, не в long, ни даже в long long не влезть!


BU>Надо было подписать: длиннннная аррифффмметиккка


эээ... Ну так с этого и надо начинать было...
Re: Оффтопик
От: Apapa Россия  
Дата: 02.06.03 10:52
Оценка: :))) :)))
Здравствуйте, BUran, Вы писали:

BU>вот вам задачка:

BU>написать сабж на C максимально короткий.
BU>формат такой:
BU> char*sum(char*a,char*b,int Z,int Y,int*W);
BU>причем a,b = исходные строки, в которых записаны числа (от больших разрядов к меньшим),
BU>Z и Y — знаки: 1 = число отрицательное, 0 = число положительное.
BU>W = знак результата, 1 = результат отрицательный, 0 = положительный.

Пролог.
BU>Остальные варианты — оффтопик ( ветку так и назовите )

Глава 1-я и она же последняя.
Эпиграф.
BU>Записать это надо в одну строчку и без define и inline-функций.
BUran


2030 год...
Стандарт давно утвердил суперфункцию BUranа. Для нее даже выделили отдельный заголовочный файл: BUran.h, который уже давным-давно использовался в stdlib.h.
Мне оставалось только включить последний и написать:
#include <stdlib.h>

char *sum(char *a, char *b, int Z, int Y, int *W) {
    return BUran_BUran(a, b, Z, Y, W);
}


Эпилог.
Более коротких вариантов я не встречал...


Здесь могла бы быть Ваша реклама!
Re: Чушь
От: UgN  
Дата: 02.06.03 11:39
Оценка: 10 (1) -1
Здравствуйте, BUran, Вы писали:

BU>вот вам задачка:

BU>написать сабж на C максимально короткий.

А почему на С?

BU>формат такой:

BU> char*sum(char*a,char*b,int Z,int Y,int*W);

А почему не char*s(char*a,char*b,char c,char d,char e)?


BU>задачка абсолютно реальная, и возникла, когда друг попросил меня написать такую функцию. я сказал: ну... порядка 10 строк. Но ведь можно и короче


BU>Я пока свернул сабж где-то в 400 символов (с учетом определения char* sum(bla-bla){}, "где-то" потому что ещё в процессе)

BU>А кто сможет короче?

Ну и смысл?

Давай похерим все пробелы, все идентификаторы сделаем однобуквенными, наплюем на читабельность...

И что?
Твой вариант, на 400 символов, суперпуперсовсемтакойкороткийбезпробелов
компилятор отрыгнет в гораздо больший машинный код,
чем другой, внятный и более длинный.

Смысл твоего challenge?
Re[2]: Чушь
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 11:50
Оценка: -1
UgN>Ну и смысл?

А смысл твоего сообщения, на которое я сейчас отвечаю?

UgN>Давай похерим все пробелы, все идентификаторы сделаем однобуквенными, наплюем на читабельность...


В данной задачке-то? Ну давай! Я — за

UgN>Смысл твоего challenge?


А, так ты о смысле жизни

Я предложил задачку. Не хочешь — не решай. Только пальчиком попрошу не тыкать и умными словечками не бросаться не подумав.

P.S. Так значит, тебе в 400 символов укатать слабо?
/bur
Re[3]: Чушь
От: UgN  
Дата: 02.06.03 11:55
Оценка:
Здравствуйте, BUran, Вы писали:

BU>А смысл твоего сообщения, на которое я сейчас отвечаю?


Смысл моего сообщения в том, что твое задание в данном виде не является корректным.

Нужно уточнить и доработать.

UgN>>Давай похерим все пробелы, все идентификаторы сделаем однобуквенными, наплюем на читабельность...


BU>В данной задачке-то? Ну давай! Я — за


А я нет.

Ну ты покажи свой вариант, вместе и посмеемся.

UgN>>Смысл твоего challenge?


BU>А, так ты о смысле жизни


Нет, о твоей задаче.

BU>P.S. Так значит, тебе в 400 символов укатать слабо?


Пиписьками меряться собрался?
Re[3]: Сойдет? :-\
От: UgN  
Дата: 02.06.03 12:15
Оценка:
Здравствуйте, BUran, Вы писали:

BU>P.S. Так значит, тебе в 400 символов укатать слабо?



Считай сам, сколько символов...
char*sum(char*A,char*B,int X,int Y,int*Z){
int e=strlen(A)+1,f=strlen(B)+1,g=max(e,f)+1;char*C=new char[g];
do{char*pc=C+g;*pc=(e?*(A+--e):0)+(f?*(B+--f):0);*(pc-1)=*pc/10;*pc%=10;}while (--g);
*Z= X^Y;return C;}


ЗЫ: Не дай бог так программы писать... А если в них разбираться...
Re[4]: Сойдет? :-\
От: UgN  
Дата: 02.06.03 12:16
Оценка:
Здравствуйте, UgN, Вы писали:


UgN>Считай сам, сколько символов...

UgN>
UgN>char*sum(char*A,char*B,int X,int Y,int*Z){
UgN>int e=strlen(A)+1,f=strlen(B)+1,g=max(e,f)+1;char*C=new char[g];
UgN>do{char*pc=C+g;*pc=(e?*(A+--e):0)+(f?*(B+--f):0);*(pc-1)=*pc/10;*pc%=10;}while (--g);
UgN>*Z= X^Y;return C;}
UgN>


Пример использования:
int x = 0;
char* z = sum( "\1\2\3\4", "\1\2\3\4\5", 1, 0, &x );
Re[4]: Сойдет? :-\
От: UgN  
Дата: 02.06.03 12:20
Оценка:
Здравствуйте, UgN, Вы писали:


BU>>P.S. Так значит, тебе в 400 символов укатать слабо?


UgN>Считай сам, сколько символов...

UgN>
UgN>char*sum(char*A,char*B,int X,int Y,int*Z){
UgN>int e=strlen(A)+1,f=strlen(B)+1,g=max(e,f)+1;char*C=new char[g];
UgN>do{char*pc=C+g;*pc=(e?*(A+--e):0)+(f?*(B+--f):0);*(pc-1)=*pc/10;*pc%=10;}while (--g);
UgN>*Z= X^Y;return C;}
UgN>


Типа исходник. Для проверки алгоритма. Особо не напрягался, поэтому мог и накосячить, да и оптимизировать еще можно.
Но ломает...

char* sum ( char* pszA, char* pszB, int ASign, int BSign, int* pResSign )
{
    int ALen = strlen( pszA ) + 1;
    int BLen = strlen( pszB ) + 1;
    int CLen = max( ALen, BLen ) + 1;
    char* pszC = new char[ CLen ];
    do
    {
        char *pc = pszC + CLen;
        *pc = ( ALen?* ( pszA + --ALen ) : 0 )  + ( BLen ? *( pszB + --BLen ) : 0);
        *(pc - 1) = *pc/10;
        *pc %= 10;
    } while( --CLen );
    
    *pResSign = ASign^BSign;
    return pszC;    
}


2BUran: Давай свой вариант, меряться будем!!!
Re: сложение чисел со знаком
От: WFrag США  
Дата: 02.06.03 12:28
Оценка: 6 (1)
Здравствуйте, BUran, Вы писали:

BU>вот вам задачка:

BU>написать сабж на C максимально короткий.
BU>формат такой:
BU> char*sum(char*a,char*b,int Z,int Y,int*W);
BU>причем a,b = исходные строки, в которых записаны числа (от больших разрядов к меньшим),
BU>Z и Y — знаки: 1 = число отрицательное, 0 = число положительное.
BU>W = знак результата, 1 = результат отрицательный, 0 = положительный.

BU>задачка абсолютно реальная, и возникла, когда друг попросил меня написать такую функцию. я сказал: ну... порядка 10 строк. Но ведь можно и короче

BU>Я пока свернул сабж где-то в 400 символов (с учетом определения char* sum(bla-bla){}, "где-то" потому что ещё в процессе)
BU>А кто сможет короче?

BU>Формат ввода менять нельзя! разве что переменные поменять на более понятные...

BU>Записать это надо в одну строчку и без define и inline-функций.
BU>Остальные варианты — оффтопик ( ветку так и назовите )

BU>p.s. Математические и прочие библиотеки не использовать! Только стандартные библиотеки Си.

BU>У меня это -
BU> #include <stdio.h>
BU> #include <stdlib.h>
BU> #include <string.h>

Вот что-то есть. Не уверен за абсолютную правильность, программа очень нежная, чувствительная к внешним условиям, особенно ко входным данным. Но что-то она считает...

char*sum(char*a,char*b,int Z,int Y,int*W){static char r[10000];int u=strlen(a),v=strlen(b),x,i,p,t,f=2-2*abs(Z-Y),f2=u-v;char*y;memset(r,'0',10000);if(f2<0&&*a<*b)f2=-1;if(f2<0){y=b;x=v;p=u;}else{y=a;x=u;p=v;}*W=(f2<0)?Y:Z;memcpy(r+x-p+1,a+(b-y),p);p=0;r[x+1]=0;for(i=x-1;i>=0;i--){t=(y[i]-r[i+1]+f*(r[i+1]-48)+p);p=t<0?t+=10,-1:t/10;r[i+1]=t%10+48;}r[0]=p+48;return r;}


370 байт.

P.S. А, ну и одна неточность — она выдает число, начинающееся нулями.
7. О чем невозможно говорить, о том следует молчать.
Re[5]: Сойдет? :-\
От: Dmitry Kukushkin  
Дата: 02.06.03 12:30
Оценка:
Здравствуйте, UgN, Вы писали:

UgN>Типа исходник. Для проверки алгоритма. Особо не напрягался, поэтому мог и накосячить, да и оптимизировать еще можно.

UgN>Но ломает...

char* sum ( char* pszA, char* pszB, int ASign, int BSign, int* pResSign )
{
    int ALen = strlen( pszA ) + 1;
    int BLen = strlen( pszB ) + 1;
    int CLen = max( ALen, BLen ) + 1;
    char* pszC = new char[ CLen ];
    do
    {
        char *pc = pszC + CLen;
        *pc = ( ALen?* ( pszA + --ALen ) : 0 )  + ( BLen ? *( pszB + --BLen ) : 0); 
        *(pc - 1) = *pc/10;
        *pc %= 10;
    } while( --CLen );
    
    *pResSign = ASign^BSign; 
    return pszC;    
}


При всем уважении знак суммы вычисляется не так ( это же не произведение ).
Легче всего еще умножать на знак (-1,1) значения из разных char * — ей.
Re[5]: Сойдет? :-\
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 12:32
Оценка:
Здравствуйте, UgN, Вы писали.

Почему ты думаешь, что я глупый???
1) строки в виде чисел. А не кодов от 0 до 9
пример: sum("1234","12345",1,0,&x)
2) я говорил С а не С вперемежку с С++
косяк поэтому при компиляции — у меня в libc max нету...
3) ты подумал вообще о том, что числа со знаком бывают???

мой тест N1:
int main(){
    int s;
    printf("1000-2543=", sum("1000","2543",0,1,&s), s);
}
/bur
Re[6]: Сойдет? :-\
От: UgN  
Дата: 02.06.03 12:35
Оценка:
Здравствуйте, Dmitry Kukushkin, Вы писали:

DK>При всем уважении знак суммы вычисляется не так ( это же не произведение ).

DK>Легче всего еще умножать на знак (-1,1) значения из разных char * — ей.

Э-э-э, я как раз для умножения и написал... Исправлю.

Там еще косяк сейчас увидел.. Правлю...
Re[6]: Сойдет? :-\
От: UgN  
Дата: 02.06.03 12:36
Оценка:
Здравствуйте, BUran, Вы писали:

BU>Почему ты думаешь, что я глупый???

BU>1) строки в виде чисел. А не кодов от 0 до 9

Где это в условии. Покажи пальцем.

BU>2) я говорил С а не С вперемежку с С++

BU>косяк поэтому при компиляции — у меня в libc max нету...

Буду я щас тебе проверять C это или C++

BU>3) ты подумал вообще о том, что числа со знаком бывают???


Тут накосячил... Бывает...
Re[4]: Сойдет? :-\
От: Les Россия  
Дата: 02.06.03 12:50
Оценка:
Здравствуйте, UgN, Вы писали:

UgN>ЗЫ: Не дай бог так программы писать... А если в них разбираться...


Да ладно тебе, не придирайся. В кои-то веки задача на программирование. А то мы тут совсем заматематирели.
Re[7]: Сойдет? :-\
От: BUran Россия http://www.buriy.com/
Дата: 02.06.03 12:50
Оценка:
BU>>Почему ты думаешь, что я глупый???
BU>>1) строки в виде чисел. А не кодов от 0 до 9
UgN>Где это в условии. Покажи пальцем.

"причем a,b = исходные строки, в которых записаны числа"
согласен, не очень чеканная формулировка. Я имел в виду символы с кодами от 48 (aka '0') до 57 (aka '9')
ну извини , тебе же не сложно будет переделать

BU>>2) я говорил С а не С вперемежку с С++

BU>>косяк поэтому при компиляции — у меня в libc max нету...

UgN>Буду я щас тебе проверять C это или C++

Ага А в условии про C написано:
"сабж на C", "только стандартные библиотеки Си",
И ещё один отличительный признак С — operator new не определен. Знать надо
/bur
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.