Tìm tối đa 3 số mà không phân nhánh


17

Lần này, mục tiêu của bạn là tìm tối đa 3 số nguyên (từ - (2 ^ 31) đến 2 ^ 31 - 1 trong phần bù 2 của nhị phân) mà không cần sử dụng phân nhánh hoặc vòng lặp.

Bạn chỉ được phép sử dụng

  • Bất bình đẳng / Bình đẳng ( ==, >, >=, <, <=, !=) Những tính là 2 thẻ.

  • Số học ( +, -, *, /)

  • Toán tử logic ( !không, &&và, || hoặc)

  • Bitwise Operators ( ~không, &và, |hoặc, ^xor, <<, >>, >>>số học và logic trái và thay đổi bên phải)

  • Hằng số. 0 mã thông báo

  • Phân công biến. 0 mã thông báo

Nhập 3 biến là a, bc. Xuất số lượng tối đa.

Tiêu chuẩn quy tắc golf-golf nguyên tử áp dụng. Nếu bạn có bất kỳ câu hỏi xin vui lòng để lại trong các ý kiến. Một mã thông báo là bất kỳ ở trên với các quy tắc đặc biệt.


Điều gì về việc xác định một chức năng bổ sung? Nếu điều này được cho phép, thì nó được tính là bao nhiêu?
xa

@voidpigeon Bạn chỉ được phép có một chức năng, một chức năng có 3 đầu vào và đầu ra.
qwr

1
Thoạt nhìn tôi đã nghĩ, " chúng ta đã có cái này trước đây. " , Nhưng tôi nghĩ bộ so sánh có giá 2 thay đổi trò chơi khá nhiều.
primo

@primo Tôi đặc biệt yêu cầu 3 đầu vào vì nó thực sự cho phép một số cải tiến thú vị
qwr

2
Chúng ta có thể sử dụng các hàm inbuilt không?
Người dùng đã đăng ký

Câu trả lời:


7

Mã thông báo Javascript 10

Chỉnh sửa bằng cách sử dụng <và * thay vì xử lý bit - như được chỉ ra trong các nhận xét, thao tác bit có thể không thành công cho đầu vào gần giới hạn phạm vi (trên 30 bit)

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

Mã thông báo C 8

Ngôn ngữ bất khả tri trong thực tế, bất kỳ ngôn ngữ C nào cũng sẽ làm được. Để được kén chọn, trong tiêu chuẩn C, nó không thể di động được vì sự thay đổi bên phải có thể không mở rộng dấu hiệu (nhưng trong các triển khai chung thì có).

Trong C (và C ++, C # và Java tôi nghĩ) chúng ta có thể dễ dàng xử lý các sự cố tràn bằng cách sử dụng các giá trị tạm thời lớn hơn:

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
Tôi rất kén chọn, nhưng sử dụng C ints, mã của bạn không hoạt động với x = 2147483647, y = -2, z = 0. Sự lựa chọn của bạn nếu bạn muốn thay đổi nó
qwr

10

Javascript

6 mã thông báo

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

6
+1 Tôi thấy đánh giá lối tắt là một loại phân nhánh, nhưng nó không bị cấm trong các quy tắc
edc65

11
Tôi sẽ coi đây là sự phân nhánh, haha
justhalf

2
@ edc65 Đó là. Cho phép &&||có khả năng là một sự giám sát, cần được chỉ ra, thay vì khai thác.
primo

@primo Đây là một vấn đề thú vị. Tôi tin rằng một số kiến ​​trúc CISC có các hướng dẫn bao gồm các câu điều kiện, vì vậy tôi không chắc chúng sẽ được tính như thế nào.
qwr

2
Tôi đoán nó phải được 4 tokens tức là 2 &&, <>. Nó =được sử dụng như một nhiệm vụ và được tính là 0
Clyde Lobo

6

C: 10 mã thông báo

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

Lấy cảm hứng từ câu trả lời của @ openorclose, nhưng đã chuyển đổi thành C và không phân nhánh bằng cách sử dụng phép nhân thay vì các toán tử boolean ngắn mạch.


3

Javascript

14 mã thông báo

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

1
Bạn không được phép tạo các chức năng mới
qwr

:( 14 mã thông báo sau đó
Fabricio

2

Nhiều ngôn ngữ (Python) (10 mã thông báo)

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

Ồ, ai đó đã đăng nó rồi :)


Bạn không được phép tạo các chức năng mới
qwr

À, được rồi! Không đọc các bình luận :)
Mardoxx

@qwr Tôi không hiểu, bạn nói: You are only allowed to have one function, the one that takes the 3 inputs and outputs.Đó chính xác là câu trả lời này. 2 bản in chỉ là trường hợp thử nghiệm
Cruncher

1
@Cruncher Tôi đã chỉnh sửa câu trả lời tôi đã làm max2(max2(x,y),z)ban đầu :)
Mardoxx

@Mardoxx ah. Vâng +1
Cruncher

1

C ++ 11: 15 mã thông báo

Chỉ sử dụng các toán tử số học và bitwise (vì các toán tử logic đẳng thức và boolean làm cho nó quá dễ dàng) ...

#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;
}

Thất bại với số lượng lớn (> 2 ^ 30), xem bình luận codegolf.stackexchange.com/questions/32476/#comment68870_32477
edc65

Có vẻ tốt với tôi: ideone.com/pEsvG3
Riot

Bạn đã đọc bình luận? Tôi nghĩ rằng 2 tỷ đồng lớn hơn 0 [ ideone.com/vlcnq9 ]
edc65

Ah tôi thấy; vâng, nó có vấn đề với những con số trong bình luận khác của bạn, khi có 0 liên quan. Nhưng không phải trong 2 ^ 30 như bạn đã nói. ideone.com/LicmXa
Riot

Nó không phải là 0 liên quan. Vấn đề là số lượng lớn và tràn, hãy thử tối đa (2000000000, -200000000, 1111111111).
edc65

0

J (Không thi đấu)

Tôi chỉ tự hỏi một giải pháp trong J sẽ như thế nào. Điều này sử dụng một ,#mặc dù, vì vậy nó sẽ không cạnh tranh.

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

Điều này sẽ cạnh tranh, nhưng quá dài, với 9 mã thông báo:

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

0

chúng tôi có các giả định sau:

  • tối đa (a; b) = (a + b + | ab |) / 2

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

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

chúng ta có thể sử dụng mã giả:

hàm 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

trả lại2

}


Vui lòng viết mã thực tế và cung cấp số lượng mã thông báo trong câu trả lời của bạn.
Chương trìnhFOX

0

C # (lần thử thứ 2)

Tôi hiểu rồi ... Không có chức năng tích hợp ...

Nhưng nó có được phép sử dụng các kiểu dữ liệu tích hợp khác hay chỉ đơn giản là int? Nếu được phép tôi sẽ đề xuất:

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 mã thông báo

Mặc dù tương tự như câu trả lời của @ openorclose, tôi thực sự sử dụng các toán tử logic cho chính bài tập đó.

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

vĩ cầm


0

R (10 mã thông báo)

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

0

Brainfuck (Không thi đấu)

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

0

TIS-100, 8 hoạt động

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

Nhà cung cấp (UP) chỉ thực hiện MOV nên không được hiển thị trong mã Có thể không hoạt động khi quá gần cạnh 999


-1

VBA (6 mã thông báo)

 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  

không chắc chắn nếu điều này không phân nhánh.


Nó là phân nhánh, chỉ nội tuyến. Cụ thể, toán tử ternary phổ biến (mà điều này thực chất là) không phải là một trong những hoạt động được phép.
tomsmeding

Cảm ơn @tomsmeding, tôi có thể hỏi toán tử ternary phổ biến (có phải là IIF () trong mã của tôi không?)
Alex

vâng xin lỗi, với sự phổ biến tôi có nghĩa là nó có mặt ở hầu hết mọi ngôn ngữ và toán tử ternary là IIf, Inline-If của bạn. Trong hầu hết các ngôn ngữ, nó là, ví dụ , a>=b ? a : b. Nó thực sự phân nhánh.
tomsmeding

-1

JavaScript: 4 mã thông báo (** dựa trên giải thích rộng về "chuyển nhượng"!)

Rõ ràng điểm 4 của tôi là vô cùng hào phóng / khoan dung!

Để đạt được số điểm đó, tôi đã giả sử "gán" (trị giá 0 mã thông báo trong câu hỏi) bao gồm những thứ như phép gán cộng, phép trừ trừ, phép nhân và phép gán 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;
}

Nếu những bài tập đó thực sự đếm số điểm là 14 :)


Bởi vì d -= bthực sự giống như d = d - b, tôi sẽ nói rằng bạn sử dụng số học và bạn nên tính đây là mã thông báo.
Chương trìnhFOX

Vâng, tôi nhận ra rằng - tôi đã (đùa) cố gắng tận dụng ý nghĩa của "chuyển nhượng". Tôi nghĩ rằng tôi đã làm điều đó khá rõ ràng!
jcdude
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.