?

Log in

No account? Create an account

Программистская загадка - Общество дровосеков Бердичева по изучению Мишны

Apr. 12th, 2011

02:00 pm - Программистская загадка

Previous Entry Share Next Entry


Сгодится в качестве простенькой для интервью.
Заполните пропуски так, чтобы программа печатала "1 0 1" (для непрограммистов, заглянувших под кат: это соответствует "истина ложь истина"):

#define A пропуск_1
#define B пропуск_2

main() {
        printf("%d %d %d\n",
        A < B,
        A+1 < B,
        A+2 < B);
}


Сколько вариантов решения можно предложить?

Upd: комментарии больше не скрываются. Хорошо видны два принципиально различных класса подходов к решению.

Comments:

[User Picture]
From:ygam
Date:April 12th, 2011 09:19 pm (UTC)
(Link)
#define A 2147483646
#define B 2147483647
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 12:56 am (UTC)
(Link)
Например; а в случае с
#define A -2
#define B ~0 // vs 0xFFFFFFFF
получается любопытнее.
(Reply) (Parent) (Thread)
[User Picture]
From:kcmamu
Date:April 12th, 2011 09:25 pm (UTC)
(Link)
#define A 1,0,1,0
#define B 0 // doesn't matter
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 12:57 am (UTC)
(Link)
Вот так людей на интервью и сортируют. :) См. комменты.
(Reply) (Parent) (Thread)
From:rezkiy
Date:April 12th, 2011 09:42 pm (UTC)
(Link)
#define A 1, 0, 1); 1
#define B (1


Edited at 2011-04-13 12:38 am (UTC)
(Reply) (Thread)
From:rezkiy
Date:April 12th, 2011 10:24 pm (UTC)
(Link)
#define A (unsigned)-2
#define B (unsigned)-1

КОмпилятор может не ругнуться (а может и ругнуться, считаем, что int 32-битный)


#define A -2
#define B 0xFFFFFFFF

но я что-то не уверен в том, что это будет работать везде. Потому что

#define A -2
#define B ~0

не работает, а

#define A -2
#define B (unsigned)~0

работает.

Edited at 2011-04-13 12:46 am (UTC)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 12:53 am (UTC)
(Link)
Отож. ~0 - целое со знаком, сиречь -1, а 0xFFFFFFFF - целое без знака, поэтому больше нуля, но тем не менее равно -1.
(Reply) (Parent) (Thread)
From:rezkiy
Date:April 12th, 2011 10:33 pm (UTC)
(Link)
#define A __LINE__
#define B (__LINE__ -13)*(__LINE__ -13) * 1000

int main () {
printf("%d %d %d\n",
A < B,
A+1 < B, <-- эта строка 13я
A+2 < B);
}

Edited at 2011-04-13 12:37 am (UTC)
(Reply) (Thread)
[User Picture]
From:lev
Date:April 12th, 2011 11:09 pm (UTC)
(Link)
INT_MAX-1
INT_MAX
(Reply) (Thread)
From:rezkiy
Date:April 12th, 2011 11:20 pm (UTC)
(Link)
#define A ((printf("1 0 1\n"), exit(0)), main())
#define B ((printf("1 0 1\n"), exit(0)), main())


Edited at 2011-04-13 12:37 am (UTC)
(Reply) (Thread)
[User Picture]
From:_windwalker_
Date:April 12th, 2011 11:59 pm (UTC)
(Link)
Вот за это C и не любят - когда int неявно приводится к логическому типу либо наоборот :)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 12:03 am (UTC)
(Link)
Си и выросшие из него языки, в том числе Верилог (из которого эта загадка выросла), можно много за что не любить, но в данном случае трюк не в этом.
(Reply) (Parent) (Thread)
[User Picture]
From:vgramagin
Date:April 13th, 2011 12:12 am (UTC)
(Link)
Эту задачу можно переформулировать под другой язык (скажем, Java) - или она целиком основана на синтаксисе C?
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 12:22 am (UTC)
(Link)
Требуется найти два константных выражения A и B таких, что A < B истинно, A+1 < B ложно, A+2 < B истинно.
(Reply) (Parent) (Thread) (Expand)
From:rezkiy
Date:April 13th, 2011 12:34 am (UTC)
(Link)
#define A -1 + (1 << sizeof(int)*8-2) << 0
#define B (1 << sizeof(int)*8-2)


Edited at 2011-04-13 12:36 am (UTC)
(Reply) (Thread)
[User Picture]
From:6zow
Date:April 13th, 2011 02:52 am (UTC)
(Link)
#define A 1 << 29
#define B 1 << 30
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 02:55 am (UTC)
(Link)
Вот я и говорю про два класса подходов к решению.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:ramlamyammambam
Date:April 13th, 2011 03:39 am (UTC)
(Link)
#define A ~0U-1
#define B ~0U

Еще два варианта: UL и ULL.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 05:14 am (UTC)
(Link)
Сразу видно честного человека!
Трюк, собственно, в том, что в Си константа, вылезающая за диапазон чисел со знаком, автоматически становится беззнаковой, даже без приписывания U в конце.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:yatur
Date:April 13th, 2011 03:51 am (UTC)
(Link)

Если разрешить плюсы, то можно развернуться. Типа,

#define A 0
#define B C()
class C {}
int operator < (int x, C y)
{
    return x==1;
}

main() {
        printf("%d %d %d\n",
        A < B,
        A+1 < B,
        A+2 < B);
}
(Reply) (Thread)
[User Picture]
From:yatur
Date:April 13th, 2011 03:52 am (UTC)
(Link)
Т.е, пардон, в операторе надо return x!=1;
Но идея, я думаю, ясно
(Reply) (Parent) (Thread)
[User Picture]
From:_navi_
Date:April 13th, 2011 04:29 am (UTC)
(Link)
не подсматривая в другие ответы:
#define A 0xfffffffeu
#define B 0xffffffffu
// Альтернативно:
// #define A 0x7ffffffe
// #define B 0x7fffffff

main() {
        printf("%d %d %d\n",
        A < B,
        A+1 < B,
        A+2 < B);
}
ну или можно в стиле Bobby Tables (я удивился, что gcc по этому поводу не ругнулся, но похоже это из-за того, что printf неявно объявлён):
#define A 0
#define B 1,0,1

main() {
        printf("%d %d %d\n",
        A < B,
        A+1 < B,
        A+2 < B);
}
(Reply) (Thread)
[User Picture]
From:spamsink
Date:April 13th, 2011 05:19 am (UTC)
(Link)
Даже в первом варианте в Си u не обязательно (и, похоже, в каждом языке программирования приписывание знаковости полноразрядным константам устроено как бог на душу положит). А кто о каком стиле сперва подумает (математическом vs Bobby Tables) - это уже дополнительная информация.
(Reply) (Parent) (Thread) (Expand)