产生最短的程序,该程序将两个有符号整数作为输入(通过stdin或作为参数)并显示3个不同的输出,具体取决于第一个数字是(1)大于,(2)小于还是(3)等于第二个数字数。
赶上
您不能在程序中使用以下任何一项:
- 该标准比较操作符:
<
,>
,<=
,>=
,==
,!=
。 - 任何库文件除
conio
,stdio
或iostream
。 - 任何非ASCII或不可打印的ASCII字符。
赢家
字符数最少的程序获胜。
产生最短的程序,该程序将两个有符号整数作为输入(通过stdin或作为参数)并显示3个不同的输出,具体取决于第一个数字是(1)大于,(2)小于还是(3)等于第二个数字数。
赶上
您不能在程序中使用以下任何一项:
<
,>
,<=
,>=
,==
,!=
。conio
,stdio
或iostream
。赢家
字符数最少的程序获胜。
Answers:
也许我遗漏了规则中的某些内容,但是...
main(a,b){scanf("%d%d",&a,&b);long long l=a;l-=b;printf("%lld%d",--l>>63,l>>63);}
。OUPUTS 00
如果a > b
,-10
如果a == b
,和-1-1
如果a < b
。
long long
可能会超过64位,int
可能会太大而导致溢出,右移负值的结果由实现定义。几乎所有源自C的答案都有类似的问题。
sizeof
。
如果可以使用stdio
,为什么不使用其格式化功能进行比较呢?
main(a,b){scanf("%d%d",&a,&b);snprintf(&a,2,"%d",b-a);a&=63;putchar(51-!(a-45)-!!(a-48));}
假定与ASCII兼容的编码和低字节序。
商将取整为零,但右移(实际上)为“取整”。那真是太死了。
main(a,b){scanf("%d%d",&a,&b);a-=b;putchar(a?a|=1,a/2-(a>>1)?60:62:61);}
负数的另一个显着特性是它们产生负模。这个根本不依赖于整数表示。它甚至可以在我的8位Extra-127多士炉上使用!哦,既然可以使用了conio
,为什么不保存两个字节putch
呢?现在,如果我只能找到我的TurboC副本...
main(a,b){scanf("%d%d",&a,&b);long long d=a;d-=b;putch(d?d|=1,d%2-1?60:62:61);}
编辑:处理大差异假设long long
比宽int
。
%d
s 之间使用定界符scanf
来明确解析两个整数。好主意!
a = 1, b = 23
和a = 12, b = 3
。123
两种情况下都不需要戴STDIN吗?
1 23
和12 3
作为输入)。
main(a,b){scanf("%d%d",&a,&b);for(a-=b;a/2;a/=2);putchar(a);}
分别打印小于,等于或大于-1、0和1的字符值。
此实现依赖于b
类型int
为undefined 且输入范围INT_MIN / 2
为to的未定义行为INT_MAX / 2
。在有符号溢出环绕的平台上,无论是2s补码(基本上都是2s补码)还是符号幅度,它都会在25%的有效对中失败int
。有趣的是(无论如何对我而言),它将在签名溢出饱和的平台上正常工作。
a-b
溢出,则无法使用。
-(2^14)
以及2^14 - 1
在所有兼容平台上的所有输入,并且可能在大多数平台上适用于更大范围的输入。此时所有其他答案都对类型的大小,类型的相对大小或表示形式进行了假设。
main(a,b)
已经是未定义的行为,因此不能保证所有答案都有效。没关系的便携性。
main(a,b,c,d,e){scanf("%d %d",&a,&b);e=1<<31;c=a&e;d=b&e;putchar(a-b?c&~d?48:d&~c?49:a-b&e?48:49:50);}
从STDIN读取整数并打印0
(a <b),1
(a> b)或2
(a == b)。
编辑:现在它也应该适用于太大而无法容纳32位整数的差异。我敢肯定,嵌套三元数可以通过一些位魔术来缩短。
可悲的是,这仅适用于正整数,但我认为使用纯算术运算符的概念很有趣:
main(a,b){scanf("%d%d",&a,&b);putchar(b%a/b-a%b/a);}
putchar(a/b-b/a)
则要短很多。
54个字符,如gcc这样的编译器,它不拒于main(x,y)
:
main(x,y){scanf("%d%d",&x,&y);y-=x;putchar(y>>31|!y);}
否则为59个字符:
main(){int x,y;scanf("%d%d",&x,&y);y-=x;putchar(y>>31|!y);}
输出:
main(x,y)
可以在gcc中使用,因此请随时从字符数中删除这5个字节。
main(x,y,z){scanf("%d%d",&x,&y);putchar((z=x-y)?(z&(z>>31))?50:49:51);}
z=x-y
,我很确定它们是必需的。您也可以直接使用49,
50` 保存两个字符51
,而不用添加48
。
-2000000000 2000000000
,以及导致减法溢出的整数的任何其他组合,均失败。
main(a,b){scanf("%d%d",&a,&b);a+=1<<31;b+=1<<31;for(;a&&b;a--)b--;putchar(a?b?48:49:50);}
首先在1<<31
(INT_MIN
a)和(b)上加上(),现在0对应INT_MIN
。然后循环并递减a和b直到每次循环为0,然后根据a,b或两者均为0来打印0、1或2。
main(a,b,c){scanf("%d%d",&a,&b);c=1<<31;a^=c;b^=c;for(c~=c;!c;c/=2)if(a&c^b&c){putchar(a?48:49);return;}putchar(50);}
这不是最短的解决方案,但可能比我更好的高尔夫球手打了一点球。(或者只是比我更了解C的人)
这个想法是屏蔽每个位,从左边开始,并检查不等式。其余的应该自己解释。由于负数以1位开始,因此我首先用反转第一位a^=1<<31
。
;)
笑脸应该是悲伤的);
笑脸。2. a&b
仅测试a
和b
是否具有相同的位;你需要&&
。
我想我什至不会尝试编写短代码。我将尝试以按照C99规范可移植的方式执行此比较。
int a, b; // Let's assume these are initialized
int sign_a = a ? ((a|7)^2)%2 + ((a|7)^3)%2 : 0;
模运算符保留符号,但它很可能会产生零(包括负零),因此我们确保要检查它具有奇数和偶数(即使不知道我们是否使用补数)。算术运算可能会溢出,但按位运算不会溢出,通过确保同时设置和清除了一些位,我们避免了无意中将数字转换为负零或陷阱值的情况。奇怪的是,需要执行两个操作这一事实无关紧要,因为可能的陷阱表示在放入左值之前不会引起未定义的行为。切换位0来执行操作可确保我们得到恰好一个非零的余数。有了两个信号的知识,我们就可以决定如何进行比较。
char result="\0<<>=<>>\0"[4+3*sign_a+sign_b]
if (!result) { // signs matching means subtraction won't overflow
int diff=a-b;
int sign_diff=diff ? (diff|7^2)%2 + (diff|7^3)%2 : 0;
result = ">=<"[1-sign_diff];
}
此方法可能是允许提取整数负零的正负号的几种方法之一。我们通过显式检查零来解决该问题。如果我们真正打高尔夫,我们当然可以允许两个零的比较也执行减法。
不带stdio.h的64个字符
a,b;main(){scanf("%d%d",&a,&b);puts((a-b)>>31?"<":a^b?">":"=");}
如果a> b,则输出'>';如果a <b,则输出'<';如果a == b,则输出'='。int溢出为UB。只是不要溢出。
// declare a and b as ints
a,b;
// defaults to int
main()
{
scanf("%d%d",&a,&b);
/*
* (a-b)>>31 signbit of a-b
* a^b a xor b -> 0 if they are equal
*/
puts(((a-b)>>31) ? "<" : (a^b) ? ">" : "=");
}
abs
不包含库文件的东西(因为编译器仍然知道它)?