Làm thế nào để xác định xem một số là số lẻ hay thậm chí không có hoạt động mod-bit-bitwise? [đóng cửa]


19

Làm thế nào để xác định xem một số là số lẻ hay thậm chí không có hoạt động mod-bit-bitwise?

Thách thức này là không hiệu quả, nhưng thách thức khả năng suy nghĩ của bạn cho một giải pháp sáng tạo.

CHỈNH SỬA :

Vui lòng tạo một chức năng. Ngoài ra, trong khi regex là một phản hồi thú vị, hàm sẽ chấp nhận bất kỳ số hợp lệ nào .

ĐẶT VẤN ĐỀ : Câu hỏi này bắt nguồn từ những ngày lập trình sớm nhất của tôi. Bài tập về nhà cho ngày đầu tiên đến lớp của chúng tôi là viết một chương trình đơn giản có in 'lẻ' hoặc 'chẵn'. Là đứa trẻ đầu tiên, tôi đã không đọc cuốn sách chúng tôi có cho lớp học, nơi nó chỉ đơn giản chỉ cho chúng tôi cách sử dụng%để xác định điều đó. Tôi đã dành khoảng nửa giờ để quay trở lại trong phòng để cố gắng nghĩ cách làm điều này và đã nhớ từ bài giảng rằng các con số có thể mất và đạt được độ chính xác khi chúng được chuyển từ loại nguyên thủy này sang loại nguyên thủy khác. Do đó, nếu bạn lấy số, chia cho hai và sau đó nhân số đó không bằng số ban đầu, thì bạn sẽ biết rằng số đó là số lẻ.

Tôi đã choáng váng vào ngày hôm sau, trong khi người hướng dẫn của chúng tôi đang đánh giá các chương trình của chúng tôi, rằng anh ấy nghĩ rằng đó là cách giải quyết vấn đề nguyên bản nhất, nếu không hiệu quả.


3
Chúng ta nên tạo ra một chức năng hoặc một chương trình? IO nên xảy ra như thế nào nếu chúng ta phải làm một chương trình? Xin vui lòng, giải thích thêm.
Juan

2
Tiêu chí khách quan nào sẽ quyết định câu trả lời được chấp nhận? Kích thước mã? Thứ gì khác?
Xin vui lòng

Nó chắc chắn là một con số? Nó có nên cung cấp dương tính giả cho một chuỗi?
William

Điều này đã tồn tại khá lâu, nhưng dường như không có điều kiện chiến thắng dưới bất kỳ hình thức nào, mà theo tôi có nghĩa là không có trò chơi nào ở đây.
dmckee

Câu trả lời:


40

Trong hầu hết các ngôn ngữ lập trình phân chia trả về thương cho số nguyên. Vì vậy, bạn có thể chỉ cần kiểm tra này

(i/2)*2==i

6
Không nhất thiết là hầu hết, tôi muốn nói. Nhiều, có thể.
Joey

1
để đảm bảo nó chạy đúng, bạn cần chắc chắn rằng bạn đã đúc mọi thứ thành một int/ longloại
warren

@warren Phụ thuộc vào ngôn ngữ lập trình / tối ưu hóa trình biên dịch / v.v. Ngoài ra, bạn có thể sử dụng floor(). Điều đó hoạt động hoàn hảo trong C và C ++.
Mateen Ulhaq

1
Là 0 một số chẵn?
người dùng không xác định

4
@userunknown: Có, số 0 chẵn.
Keith Thompson

71

Con trăn

print('even' if (-1)**n==1 else 'odd')

10
Vẻ đẹp đơn giản / đẹp đơn giản của toán học ... rất đẹp!
jscs

Tôi thích cái này rất nhiều.
Cướp

Chậm mà sáng tạo.
Mateen Ulhaq

21

Brainf *** (179)

Đây là một trong những vấn đề thú vị hơn liên quan đến logic có điều kiện mà tôi đã thực hiện trong BF.

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

Nó có một đầu vào văn bản với một số. Nếu số là số chẵn, nó xuất ra Evà nếu là số lẻ, nó xuất ra O.

Tôi tự hào về điều đó rằng tôi sẽ thể hiện một hình thức dễ đọc hơn của con người:

+[>,]                                                   steps through input until it reaches eof.
<---------------------------------------                gets the numerical value of the last digit
>>+++++[>+++++++++++++>+++++++++++++++<<-]>++++>++++    store E and O
<<+<+<                                                  store a bit indicating parity, and a temporary bit
-[>-<                                                   !1
  -[>+<                                                 && !2
    -[>-<                                               && !3
      -[>+<                                             && !4
        -[>-<                                           && !5
          -[>+<                                         && !6
            -[>-<                                       && !7
              -[>+<                                     && !8
                -[>-<[-]]                               && !9
              ]
            ]
          ]
        ]
      ]
    ]
  ]
]
>[>>>.<<-<-]>[>.<-]                                     Display E or O based on the value of the parity bit.

21

Toán học

SawtoothWave[x / 2] == 0
Exp[I Pi x] - 1 == 0
Sin[5 x / Pi] == 0

2
Bạn có thể chia hai giải pháp này thành các câu trả lời khác nhau?
FUZxxl

Không phải là bốn giải pháp?
Joey

Trên thực tế, tất cả các tên tích hợp trong Mathematica đều được viết hoa, vì vậy thật buồn cười, bạn nên sử dụng IPithay vì ipi.
David Zhang

15

C

Nhân với chính nó một vài lần bất kỳ số chẵn nào sẽ tràn về 0 với một số nguyên kích thước hữu hạn và bất kỳ số lẻ nào sẽ tiếp tục có ít nhất là tập bit nhỏ nhất.

#include "stdio.h"
long long input=123;
int main(){
    int a;
    for(a=6;a;a--){
        input*=input;
    }
    if(input){
        printf("Odd");
    }
    else{
        printf("Even");
    }
    return 0;
}

Chỉnh sửa: Là một chức năng đơn giản:

int isOdd(long long input){
    int a;
    for(a=6;a;a--){
        input*=input;
    }
    return !!input;
}

Hãy chắc chắn để sử dụng số nguyên không dấu. Tràn số nguyên đã ký là hành vi không xác định trong C, vì vậy tối ưu hóa có thể làm điều gì đó kỳ lạ nếu muốn.
Joey Adams

13

Python (Chậm)

n=1234
while n > 1: n -= 2 #slow way of modulus.
print "eovdedn"[n::2]

1
Hoạt động cho tích cực ... tôi cho rằng tôi có thể thêm một abs()cuộc gọi ngay từ đầu.
st0le

@Josh: Thủ thuật đó đã xuất hiện ở đây một vài lần rồi :)
Joey

Tín dụng cho gnibblr :)
st0le

@Joey: Tôi không nghĩ nó là mới, nhưng phong cách không phải là bản gốc. :)
jscs

12

JavaScript

/[02468]$/.test(i)

sản lượng truecho một số chẵn. Điều này chỉ hoạt động với các số nguyên có kích thước hợp lý (ví dụ: không phải là ký hiệu khoa học khi được chuyển đổi thành chuỗi và không có phần phân số.)


2
Để đáp ứng yêu cầu "chức năng", bạn có thể thay đổi nó thành đơn giản /[02468]$/.test.
Ry-

Nó không chính xác rõ ràng trong câu hỏi nhưng có thể đầu vào không phải là một con số , /[02468]$/.test('I am a fake even number 0'). Trong trường hợp đó bạn có thể làm/^[0-9].[02468]$/.test(i)
William

/-?^\d*[02468]$/sẽ nghiêm ngặt hơn một chút so với regex của bạn. Bạn sẽ cần nhiều công việc hơn để điều này hoạt động chính xác cho những con số được sử dụng bằng ký hiệu khoa học.
Thomas Eding

12

Con trăn

Vì tôi không thực sự chắc chắn các tiêu chí chấm điểm là gì, đây là một loạt các giải pháp tôi đưa ra để giải trí. Hầu hết trong số họ sử dụng abs(n)để hỗ trợ số âm. Hầu hết, nếu không phải tất cả, chúng không bao giờ nên được sử dụng để tính toán thực sự.

Đây là một loại nhàm chán:

from __future__ import division
def parity(n):
    """An even number is divisible by 2 without remainder."""
    return "Even" if n/2 == int(n/2) else "Odd"

def parity(n):
    """In base-10, an odd number's last digit is one of 1, 3, 5, 7, 9."""
    return "Odd" if str(n)[-1] in ('1', '3', '5', '7', '9') else "Even"

def parity(n):
    """An even number can be expressed as the sum of an integer with itself.

    Grossly, even absurdly inefficient.

    """
    n = abs(n)
    for i in range(n):
        if i + i == n:
            return "Even"
    return "Odd"

def parity(n):
    """An even number can be split into two equal groups."
    g1 = []
    g2 = []
    for i in range(abs(n)):
        g1.append(None) if len(g1) == len(g2) else g2.append(None)
    return "Even" if len(g1) == len(g2) else "Odd"

import ent # Download from: http://wstein.org/ent/ent_py
def parity(n):
    """An even number has 2 as a factor."""
    # This also uses modulo indirectly
    return "Even" if ent.factor(n)[0][0] == 2 else "Odd"

Và đây là mục ưa thích của tôi mặc dù không may là nó không hoạt động (như được chỉ ra bởi March Ho bên dưới: chỉ vì tất cả các số chẵn là tổng của hai số nguyên tố, không có nghĩa là tất cả các số lẻ không có).

import itertools
import ent    # Download from: http://wstein.org/ent/ent_py
def parity(n)
    """Assume Goldbach's Conjecture: all even numbers greater than 2 can
    be expressed as the sum of two primes.

    Not guaranteed to be efficient, or even succeed, for large n.

    """
    # A few quick checks
    if n in (-2, 0, 2): return "Even"
    elif n in (-1, 1): return "Odd"
    if n < 0: n = -n    # a bit faster than abs(n)
    # The primes generator uses the Sieve of Eratosthenes
    # and thus modulo, so this is a little bit cheating
    primes_to_n = ent.primes(n)
    # Still one more easy way out
    if primes_to_n[-1] == n: return "Odd"
    # Brutish!
    elif n in (p1+p2 for (p1, p2) in itertools.product(primes_to_n, primes_to_n)):
        return "Even"
    else:
        return "Odd"

Giải pháp dễ thương :-)
Joey

2
Thực sự là một hoại tử cũ, nhưng không phải câu trả lời phỏng đoán của Goldbach thậm chí cho 9? Có vẻ như một trường hợp khẳng định sai lầm hậu quả
Ho tháng ba

Yup, bạn hoàn toàn đúng, một trăm phần trăm đúng, @MarchHo. Trứng trên mặt tôi.
jscs

10

Haskell

Tất nhiên, đây không phải là giải pháp sáng tạo, tư duy bên ngoài mà bạn đang tìm kiếm, nhưng thực sự tôi sẽ phải đăng câu trả lời Haskell bao nhiêu lần so với GolfScript? Thật xấu hổ vì đây không phải là một môn đánh gôn.

odd

Nhưng nghiêm túc hơn:

data Parity = Even | Odd
            deriving (Show)

parity = p evens odds
  where p (x:xs) (y:ys) i | i == x = Even
                          | i == y = Odd
                          | otherwise = p xs ys i
        evens = interleave [0,2..] [-2,-4..]
        odds = interleave [1,3..] [-1,-3..]
        interleave (x:xs) ys = x : interleave ys xs

có vẻ dài hơn câu trả lời của GolfScript đối với tôi
warren

2
Tôi đã đề cập đến khối đầu tiên ( odd) là hàm dựng sẵn trả về True nếu số đó là số lẻ. Đó là một câu trả lời hoàn toàn theo cách riêng của nó và ngắn hơn câu trả lời GolfScript hiện tại (mà tại thời điểm viết bài này là 10 ký tự, nhưng tôi hy vọng điều đó sẽ đi xuống). Câu hỏi cũng có một chút chưa được xác định rõ, đó là lý do tại sao tôi khẳng định điều đó oddlà đủ. Điều đó cũng có thể thay đổi.

1
bỏ lỡ câu trả lời đầu tiên trong câu trả lời của bạn :)
warren

1
Ít nhất thì paritythuật toán hoạt động trên tất cả các Numtrường hợp là số nguyên. Thật là hấp dẫn! Mặc dù tôi có lẽ đã làm được evens = [0,2..] >>= \n -> [-n, n]. Tương tự cho tỷ lệ cược.
Thomas Eding

7

Sử dụng cách đọc có chủ ý của câu hỏi, "Cách xác định xem một số là số lẻ hay số chẵn", đây là cách triển khai C (giả sử booltrueđược xác định một cách thích hợp):

bool is_odd_or_even(int n)
{
    return true;
}

Câu hỏi đề cập đến số lượng, không phải số nguyên. Số như 0.5trả về truekhi không nên.
Konrad Borowski

6

Cái gì, chưa có thuật toán ngẫu nhiên nào ??

C

#include<stdio.h>
#include<stdlib.h>

void prt_parity_of(int n){
  int i,j=2;
  char o[]="eovdedn"
     , f[n=abs(n)]; for(i=n;i-->0;f[i]=1);

  while(j>1){
    while((i=rand()%n)
       == (j=rand()%n)
       || (f[i]&f[j]>0)
       && (f[i]=f[j]=0)
    );for(i=j=0; ++i<n; j+=f[i])
  ;}for(;j<7;j+=2)putchar(o[j]);
}

Cặp số ngẫu nhiên trong phạm vi 0 .. n -1 cho đến khi ít hơn 2 còn lại. Nó khá ngạc nhiên không hiệu quả: O ( n 3 ).


Hoàn toàn khác nhau:

Haskell

import Data.Complex

ft f = (\ω -> sum[ f(t) * exp(0:+2*pi*ω*t) | t<-[-1,-0.9..1] ] )

data Parity = Even | Odd deriving (Show)

parity n
  | all (\(re:+im) -> abs re > abs im) [ft ((:+0).(^^n)) ω | ω<-[0..20]]  = Even
  | otherwise                                                             = Odd

Sử dụng thực tế là biến đổi Fourier của hàm chẵn (ví dụ \x->x^^4) là có thật, trong khi biến đổi Fourier của hàm lẻ là tưởng tượng.


5

Windows PowerShell

function OddOrEven([long]$n) {
  if (0,2,4,6,8 -contains "$n"[-1]-48) {
    "Even"
  } else {
    "Odd"
  }
}
  1. Chuyển đổi thành chuỗi
  2. Chọn chữ cái cuối cùng (chữ số) (về cơ bản là mod 10).
  3. Kiểm tra nếu nó là 0, 2, 4, 6 hoặc 8.

Không có toán tử bitwise, không có mô-đun, theo yêu cầu.


5

Coq, 103

Fixpoint even n:=match n with O=>true|S n=>odd n end with odd n:=match n with O=>false|S n=>even n end.

Theo như tôi có thể nói đây là mục nhập coq đầu tiên trên codegolf.

Thậm chí ngắn hơn (59):

Fixpoint even n:=match n with O=>true|S n=>negb(even n)end.

4

Hồng ngọc

n.odd?

Nếu bạn muốn in ra kết quả:

f[n] = ->(n){puts n.odd?? 'odd' : 'even'}

Tôi khá sử dụng ruby ​​sử dụng mod trong .odd?định nghĩa.
MrZander 15/03/13

4

Unlambda

Thế giới cần thêm Unlambda.

Unlambda có một lợi thế sát thủ ở đây: mặc định của nó ( ahem đại diện ) cho các số là số Church, vì vậy tất cả những gì cần thiết là áp dụng chúng cho hàm nhị phân - không hoạt động đúng. Dễ dàng!

PS: Markdown và Unlambda chắc chắn không được tạo ra cho nhau.

true  = i
false = `ki
not   = ``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki
even? = ``s``si`k``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki`ki

Xác minh cho một vài số nguyên đầu tiên:

```s``si`k``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki`ki`ki                   => i
```s``si`k``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki`kii                     => `ki
```s``si`k``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki`ki``s``s`kski           => i
```s``si`k``s``s``s`k``s``si`k`kk`k`kii`k`ki`ki`ki``s``s`ksk``s``s`kski =>`ki


3

Con trăn

print (["even"] + (["odd", "even"] * abs(n)))[abs(n)]

Hiệu suất tương tự như phiên bản trước. Làm việc cho 0 bây giờ.

Phiên bản trước đó không chính xác:

print ((["odd", "even"] * abs(n))[:abs(n)])[-1]

Không đặc biệt hiệu quả; thời gian và bộ nhớ rõ ràng là O (n): 32 msec cho 1.000.000; 2,3 ms cho 100000; 3,2 usec cho 100. Hoạt động với số âm. Ném một lỗi cho 0, bởi vì 0 thậm chí không phải là lẻ.


3
Zero chắc chắn là thậm chí. Xem thêm: vi.wikipedia.org/wiki/Parity_of_zero

@jloy: Aw, tào lao. Tôi nghĩ rằng đó là "một tính năng, không phải là một lỗi". Nhiều sửa đổi hơn ...
jscs

3

Fractran

[65/42,7/13,1/21,17/7,57/85,17/19,7/17,1/3]

áp dụng cho

63*2^abs(n)

sản lượng hoặc 5nếu nlà số lẻ hoặc1 nếu nlà số chẵn.

Cập nhật : Ngắn hơn nhiều nhưng không thú vị lắm:

[1/4](2^abs(n))

2cho lẻ n1cho chẵn n.


3

MMIX (4 byte)

Đây là loại gian lận. Tôi sử dụng các hoạt động không mod và bit. Thay vào đó, việc kiểm tra các số lẻ / chẵn được tích hợp. Giả sử $3có chứa số cần kiểm tra và kết quả sẽ được đưa vào $2:

ZSEV $2,$3,1

đặt $2thành 1nếu $3là chẵn và 0nếu không. Mnemnoric ZSEVcó nghĩa là zero-set chẵn và có các ngữ nghĩa sau:

ZSEV a,b,c: if (even b) a = c; else a = 0;

Đối với dòng trên, mmixaltạo bốn byte lắp ráp này:

7F 02 03 01

3

Kế hoạch

Đây là giải pháp không hiệu quả nhất mà tôi biết.

(letrec ([even? (lambda (n)
                 (if (zero? n) "even"
                     (odd? (- n 2))))]
         [odd? (lambda (n)
                 (if (= n 1) "odd"
                     (even? (- n 2))))])
  (even? (read)))

3

Perl

Thế còn

use Math::Trig;
print(cos(pi*@ARGV[0])>0?"even":"odd")

2

JavaScript, 36

function(i){while(i>0)i-=2;return!i}

Trả về truenếu chẵn, falsenếu không.



2

Con trăn

zip((False, True)*(i*i), range(i*i))[-1][0]

kiểm tra bình phương của i, vì vậy nó cũng hoạt động cho các số âm


2

F #

Đệ quy lẫn nhau cho chiến thắng.

Số n là số chẵn nếu nó bằng 0 hoặc (n-1) là số lẻ.

Một số n là số lẻ nếu nó không bằng 0 và (n-1) là số chẵn.

(abs được thêm vào trong trường hợp bất kỳ ai quan tâm đến tính chẵn lẻ của số âm)

let rec even n = n = 0 || odd (abs n - 1) 
    and odd n = n <> 0 && even (abs n - 1)


2

Những gì đủ điều kiện là hoạt động bitwise? Dưới mui xe, phép chia số nguyên cho 2 có thể được thực hiện dưới dạng dịch chuyển bit.

Giả sử bithifts không ra:

C / C ++

(unsigned char)((unsigned char)(n > 0 ? n : -n) << 7) > 0 ? "odd" : "even"

chỉnh sửa Thiếu một số dấu ngoặc đơn và cuối cùng đã thay đổi để xóa ca làm cho nó ít hơn. Bạn có thể kiểm tra điều này với các mục sau (trong * nix):

echo 'main(){ std::cout<< (unsigned char)((unsigned char)(n > 0 ? n : -n) << 7) > 0 \
        ? "odd\n" : "even\n";}' \
  | gcc --include iostream -x c++ -o blah -
./blah

... mặc dù trong Linux / tcsh, tôi đã phải thoát khỏi dấu gạch chéo ngược trên \n mặc dù nó nằm trong dấu ngoặc đơn. Tôi đã thử nghiệm trong ít & endian lớn, nó hoạt động chính xác trong cả hai. Ngoài ra, tôi đã sao chép bằng tay này; máy tính tôi đang đăng không có trình biên dịch, vì vậy nó có thể có lỗi.

x86 asm

            mov eax, n          # Get the value
            cmp eax,0           # Is it zero?
            jge pos_label       # If >= 0, skip the next part
            neg eax
pos_label:

.

            imul al, 128

hoặc là

            shl  al, 7

hoặc là

            lea  eax, [eax*8]    # Multiply by 2^3 (left-shift by 3 bits)
            lea  eax, [eax*8]    # ... now it's n*2^6
            lea  eax, [eax*2]    # ... 2^7, or left-shift by 7 bits

... theo dõi bởi:

            cmp al,  0          # Check whether the low byte in the low word is zero or not
            jz  even_label      # If it's zero, then it was an even number
            odd_label           # ... otherwise it wasn't

Ngoài ra, việc thay đổi và so sánh cũng có thể được thực hiện theo cách này:

            sar al,1            # signed integer division by 2 on least-significant byte
            jc  odd_label       # jump if carry flag is set

BTW shlvà bạn bè không được phép ...
FUZxxl

2

Trên bộ xử lý 68000, bạn có thể di chuyển một giá trị từ từ địa chỉ được xác định bởi giá trị sang kiểm tra:

 move.l <number to test>,a0
 move.w (a0),d0
 ; it's even if the next instruction is executed

và để bẫy phần cứng cho lỗi địa chỉ xác định tính chất lẻ / chẵn của giá trị - nếu ngoại lệ được đưa ra, giá trị là số lẻ, nếu không, giá trị là chẵn:

 <set up address error trap handler>
 move.l <pointer to even string>,d1
 move.l <number to test>,a0
 move.w (a0),d0
 <reset address error trap handler>
 <print string at d1>
 <end>

 address_error_trap_handler:
 move.l <pointer to odd string>,d1
 rte

Không hoạt động trên CPU Intel x86 vì chúng linh hoạt hơn về truy cập dữ liệu.


2

Con trăn

Tôi quyết định thử giải pháp xấu nhất, khó hiểu nhất mà tôi có thể nghĩ ra:

n=input();r=range(n+1)
print [j for i in zip(map(lambda x:str(bool(x))[4],[8&7for i in r]),
map(lambda x:str(x)[1],[[].sort()for x in r])) for j in i][n]

In e nếu chẵn, o nếu lẻ.


2

Q

Tiếp tục trừ 2 cho đến x <2 rồi chuyển sang bool

{1b$-[;2]/[2<=;abs x]}
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.