查找最多3个数字而不分支


17

这次围绕您的目标是不使用分支或循环来查找最多3个整数(从-(2 ^ 31)到2 ^ 31-1在二​​进制2的补码中)。

只能使用

  • 不等式/平等(==>>=<<=!=)这些计数为2个令牌。

  • 算术(+-*/

  • 逻辑运算符(!非,&&和,|| 或)

  • 位运算符(~未,&和,|或,^异或,<<>>>>>算术和逻辑左和右移位)

  • 常数。0个代币

  • 变量分配。0个代币

输入3个变量为abc。输出最大数量。

适用标准原子代码高尔夫球规则。如有任何疑问,请在评论中保留。带有特殊规则的上述任何一项都是令牌。


定义一个额外的功能呢?如果允许这样做,它算作多少令牌?
2014年

@voidpigeon您只能具有一项功能,该功能需要3个输入和输出。
qwr

1
乍一看,我想:我们以前有过。但是,我认为花费2的比较器会改变游戏。
primo

@primo我特别要求3个输入,因为它实际上允许一些有趣的改进
qwr

2
我们可以使用内置函数吗?
注册用户

Answers:


7

Javascript 10令牌

使用<和*而不是位摆弄进行编辑 -如注释中所指出的,位操作可能会在范围限制附近(超过30位)输入失败

function Max(x,y,z)
{
  var d=y-x;
  x=y-d*(d<0);
  d=x-z;
  return x-d*(d<0);
}

C 8代币

实际上,与语言无关的任何C语言都可以。挑剔的是,在标准C语言中它不是可移植的,因为右移可能不会扩展符号(但在常见的实现中会这样做)。

在C(我认为是C ++,C#和Java)中,我们可以使用较大的临时值轻松处理溢出问题:

int Max(int x, int y, int z)
{
    long long X = x;
    long long Y = y;
    long long Z = z;
    long long D = Y-X;
    X=Y-((D>>63)&D);
    D=X-Z;
    return (int) (X-((D>>63)&D));
}

1
我很挑剔,但是int对于x = 2147483647,y = -2,z = 0 ,使用C 不能使用您的代码。如果您要更改它,请选择
qwr

10

Java脚本

6个代币

function maxOf3(a, b, c) {
    (b>a) && (a=b);
    (c>a) && (a=c);
    return a;
}

6
+1我认为快捷方式评估是一种分支方式,但是在规则中并不禁止
edc65

11
我认为这是分支,哈哈
Justhalf 2014年

2
@ edc65是的。允许&&并且||很可能是疏忽,应该指出而不是加以利用。
2014年

@primo这是一个有趣的问题。我相信某些CISC架构的指令包含条件语句,所以我不确定如何计算这些条件。
qwr 2014年

2
我想这应该是4个令牌,即2 &&<>。将=用作分配和计数为0
克莱德路宝

6

C:10个代币

int max(int a, int b, int c)
{
    a += (b > a) * (b - a);
    a += (c > a) * (c - a);
    return a;
}

受@openorclose答案的启发,但转换为C并使用乘法而不是短路布尔运算符使其变为无分支。


3

Java脚本

14代币

function max (a, b, c)
{
    var ab = (a >= b) * a + (a < b) * b;
    return (ab >= c) * ab + (ab < c) * c;
}

1
您无权创建新功能
qwr14年

:(然后有14个令牌
Fabricio

2

许多语言(Python)(10个令牌)

def max3(x,y,z):
    m = x ^ ((x ^ y) & -(x < y))
    return m ^ ((m ^ z) & -(m < z))

print max3(-1,-2,-3) # -1
print max3(-1,2,10) # 10

https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax

哦,已经有人张贴了:)


您无权创建新功能
qwr14年

啊,好!没有阅读评论:)
Mardoxx

@qwr我不明白,你说:You are only allowed to have one function, the one that takes the 3 inputs and outputs.这正是这个答案。2张照片只是测试用例
Cruncher 2014年

1
@Cruncher我编辑了我max2(max2(x,y),z)最初做的答案:)
Mardoxx

@Mardoxx啊。+1
排排坐

1

C ++ 11:15个令牌

仅使用算术和按位运算符(因为相等和布尔逻辑运算符使它变得太容易了)...

#include <iostream>

auto max(int32_t a, int32_t b, int32_t c)->int32_t {
  return c - ((c - (a - ((a - b) & (a - b) >> 31))) & (c - (a - ((a - b) & (a - b) >> 31))) >> 31);
}

auto main()->int {
  // test harness
  std::cout << max(9, 38, 7) << std::endl;
  return EXIT_SUCCESS;
}


在我看来很好:ideone.com/pEsvG3
Riot

您有没有仔细阅读评论?我认为20亿比0还大[ ideone.com/vlcnq9 ]
edc65

啊,我明白了;是的,当涉及到0时,您的其他注释中的数字确实存在问题。但不是您所说的2 ^ 30。 ideone.com/LicmXa
骚乱

它不是0。问题是大数字和溢出,请尝试max(2000000000,-200000000,1111111111)。
edc65 2014年

0

J(不参加比赛)

我只是想知道J中的解决方案是什么样子。这会使用a ,和a #,因此不会竞争。

((a<b),(b<c),(c<a))#b,c,a

这将与9个令牌竞争,但时间太长:

(b*a<:b)+(c*b<c)+(a*c<a)

0

我们有以下假设:

  • max(a; b)=(a + b + | ab |)/ 2

  • max(a; b; c)= max(max(a; b); c)

  • abs(a)=(a +(a >> 31))^(a >> 31)

我们可以使用伪代码:

函数max(a,b,c)

{

out1 =(((a + b)+(((ab)+((ab)>> 31))^((ab)>> 31)))div 2

out2 =((out1 + c)+(((out1-c)+((out1-c)>> 31))^((out1-c)>> 31)))div 2

返回2

}


请编写实际代码,并在答案中提供令牌数。
ProgramFOX

0

C#(第二次尝试)

我知道了...没有集成功能...

但是是否允许使用其他集成数据类型或仅使用普通int?如果允许,我建议:

int foo2(int a, int b, int c)
{
   var x = new SortedList<int,int>();

   x[a] = 1;
   x[b] = 1;
   x[c] = 1;

   return x.Keys[2];
}

0

javascript 8令牌

虽然类似于@openorclose的答案,但实际上我确实将逻辑运算符用于赋值本身。

function max( a, b, c ) {
    x=( a > b && a) || b;
    return ( x > c && x ) || c;
}

小提琴


0

R(10个代币)

function max(a, b, c) {
  max <- a
  max <- max + (b - max) * (b > max)
  max <- max + (c - max) * (c > max)
  return(max)
}

0

Brainfuck(不竞争)

>,[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<[-]>[-]>[-]<<<[->>>>+<<<<]>>>>[-<+>>>+<<]>,[-<+>>>+<<]>[>[-<->>]<<]<<

0

TIS-100,8次操作

MOV ACC UP #A
SUB UP     #B
SUB 999
ADD 999
ADD UP     #B
SUB UP     #C
SUB 999
ADD 999
ADD UP     #C
MOV ACC DOWN

提供程序(UP)仅执行MOV,因此未在代码中显示,而在距离999边缘太近时可能不起作用


-1

VBA(6个令牌)

 Function max3(a As Integer, b As Integer, c As Integer)
 i = IIf(a >= b And a >= c, a, IIf(b >= c, b, c))
 max3 = i
 End Function  

不知道这是否没有分支。


它是分支,仅内联。具体来说,普遍存在的三元运算符(实际上是三元运算符)不是允许的运算之一。
tomsmeding

感谢@tomsmeding,请问什么是普遍存在的三元运算符(我的代码中是IIF()吗?)
2014年

是的,很抱歉,我的意思是说它几乎以每种语言都存在,并且三元运算符是您的IIfInline-If。在大多数语言中,例如a>=b ? a : b。它确实在分支。
tomsmeding

-1

JavaScript:4个令牌(**基于对“赋值”的广泛解释!)

显然,我的4分非常慷慨/宽容!

为了达到该分数,我假设“分配”(问题中的代币价值为0)包括诸如加法运算,减法运算,乘法运算和XOR-ing(^=)运算之类的内容。

function f(a, b, c) {
  d = a;
  d -= b;
  d = d >= 0;

  a *= d;  //a = a if (a>=b), else 0
  d ^= true; //invert d
  b *= d;  //b = b if (b<a), else 0

  a += b;  //a is now max(a,b)

  d = a;
  d -= c;
  d = d >= 0;

  a *= d;  //a = a if (a>=c), else 0
  d ^= true; //invert d
  c *= d;  //c = c if (c<a), else 0
  a += c;  //a is now max(max(a,b),c)

  return a;
}

如果这些作业实际计数为14 :)


因为d -= b实际上与相同d = d - b,所以我要说您使用算术,并且应该将此作为记号。
ProgramFOX 2014年

是的,我意识到-我(在开玩笑)试图利用“任务”的含义。我想我说得很明显!
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.