Bagaimana menentukan apakah suatu angka ganjil atau bahkan tanpa operasi mod -atau- bitwise? [Tutup]

19

Bagaimana menentukan apakah suatu angka ganjil atau bahkan tanpa operasi mod -atau- bitwise?

Tantangan ini sangat tidak efisien, tetapi menantang kemampuan Anda untuk berpikir di luar kotak untuk solusi kreatif.

EDIT :

Silakan buat fungsi. Juga, sementara regex adalah menyenangkan respon, fungsi harus menerima setiap angka yang benar.

LATAR BELAKANG : Pertanyaan ini bermula dari masa pemrograman saya yang paling awal. Pekerjaan rumah untuk hari pertama kelas kami adalah menulis program sederhana yang dicetak 'aneh' atau 'datar'. Menjadi anak nakal saya, saya tidak membaca buku yang kami miliki untuk kelas di mana itu hanya menunjukkan kepada kita bagaimana menggunakannya%untuk menentukan itu. Saya menghabiskan sekitar setengah jam mondar-mandir di kamar saya mencoba memikirkan cara untuk melakukan ini dan ingat dari ceramah bahwa angka dapat kehilangan dan mendapatkan presisi karena mereka dilemparkan dari satu jenis primitif ke yang lain. Oleh karena itu, jika Anda mengambil nomor itu, membaginya menjadi dua dan kemudian mengalikannya kembali tidak sama dengan angka aslinya, maka Anda akan tahu bahwa jumlahnya aneh.

Saya terkejut pada hari berikutnya, ketika instruktur kami mengevaluasi program kami, bahwa ia berpikir bahwa itu adalah cara penyelesaian masalah yang paling orisinal, jika tidak efisien.

Wayne Hartman
sumber
3
Haruskah kita membuat fungsi atau program? Bagaimana seharusnya IO terjadi jika kita harus melakukan suatu program? Tolong, uraikan lebih lanjut.
Juan
2
Kriteria objektif apa yang akan menentukan jawaban yang diterima? Ukuran kode? Sesuatu yang lain
PleaseStand
Apakah itu pasti angka? Haruskah itu memberikan positif palsu untuk sebuah string?
William
Ini sudah ada sejak lama, tetapi sepertinya tidak ada kondisi kemenangan dalam bentuk apa pun, yang menurut saya berarti tidak ada permainan di sini.
dmckee

Jawaban:

40

Dalam sebagian besar bahasa pemrograman, pembagian mengembalikan hasil bagi bilangan bulat. Jadi, Anda cukup memeriksa ini

(i/2)*2==i
fR0DDY
sumber
6
Belum tentu sebagian besar, kataku. Mungkin banyak.
Joey
1
untuk memastikan itu berjalan dengan baik, Anda perlu memastikan Anda memasukkan semuanya ke dalam int/ longtype
warren
@warren Bergantung pada bahasa pemrograman / optimisasi kompiler / dll. Selain itu, Anda dapat menggunakan floor(). Itu bekerja dengan sempurna di C dan C ++.
Mateen Ulhaq
1
Apakah 0 angka genap?
pengguna tidak diketahui
4
@ penggunaunknown: Ya, nol bahkan genap.
Keith Thompson
71

Python

print('even' if (-1)**n==1 else 'odd')
dan04
sumber
10
Keindahan sederhana / kesederhanaan yang indah dari matematika ... sangat bagus!
jscs
Saya sangat suka yang ini.
Rob
Pelan tapi kreatif.
Mateen Ulhaq
21

Brainf *** (179)

Ini adalah salah satu masalah yang lebih menarik yang melibatkan logika kondisional yang telah saya lakukan di BF.

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

Dibutuhkan input teks dengan angka. Jika angkanya genap, maka akan keluar E, dan jika ganjil, maka akan keluar O.

Saya cukup bangga bahwa saya akan memamerkan bentuk yang lebih dapat dibaca manusia:

+[>,]                                                   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.
Peter Olson
sumber
21

Mathematica

SawtoothWave[x / 2] == 0
Exp[I Pi x] - 1 == 0
Sin[5 x / Pi] == 0
Ming-Tang
sumber
2
Bisakah Anda membagi dua solusi ini menjadi jawaban yang berbeda?
FUZxxl
Bukankah keempat solusi itu?
Joey
Sebenarnya, semua nama bawaan di Mathematica ditulis dengan huruf besar, jadi lucu seperti yang terlihat, Anda harus menggunakan Idan Pibukannya idan pi.
David Zhang
15

C

Dikalikan dengan sendirinya beberapa kali bilangan genap akan melimpah ke 0 diberi bilangan bulat ukuran terbatas, dan bilangan ganjil mana pun akan terus memiliki setidaknya set bit paling tidak signifikan.

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

Sunting: Sebagai fungsi sederhana:

int isOdd(long long input){
    int a;
    for(a=6;a;a--){
        input*=input;
    }
    return !!input;
}
aaaaaaaaaaaa
sumber
Pastikan untuk menggunakan bilangan bulat yang tidak ditandai. Overflow bilangan bulat yang ditandatangani adalah perilaku yang tidak terdefinisi dalam C, jadi optimisasi dapat melakukan sesuatu yang aneh jika diinginkan.
Joey Adams
13

Python (Lambat)

n=1234
while n > 1: n -= 2 #slow way of modulus.
print "eovdedn"[n::2]
st0le
sumber
1
Berfungsi untuk positif ... saya kira saya bisa menambahkan abs()panggilan di awal.
st0le
@Josh: Trik itu sudah muncul di sini beberapa kali sekarang :)
Joey
Kredit ke gnibblr :)
st0le
@ Joey: Saya tidak menganggap itu baru, tetapi gaya tidak harus asli. :)
jscs
12

JavaScript

/[02468]$/.test(i)

hasil trueuntuk bilangan genap. Ini hanya bekerja dengan bilangan bulat berukuran wajar (misalnya bukan notasi ilmiah ketika dikonversi ke string dan tidak memiliki bagian fraksional.)

Tolong berdiri
sumber
2
Untuk memenuhi persyaratan "fungsi", Anda dapat mengubahnya dengan sederhana /[02468]$/.test.
Ry-
Tidak terlalu jelas dalam pertanyaan, tetapi bisa jadi inputnya sama sekali bukan angka /[02468]$/.test('I am a fake even number 0'). Dalam hal ini yang bisa Anda lakukan/^[0-9].[02468]$/.test(i)
William
/-?^\d*[02468]$/akan sedikit lebih ketat dari regex Anda. Anda akan membutuhkan lebih banyak pekerjaan untuk ini agar berfungsi dengan benar untuk angka-angka yang menggunakan Strata menggunakan notasi ilmiah.
Thomas Eding
12

Python

Karena saya tidak begitu yakin apa kriteria penilaiannya, inilah banyak solusi yang saya buat untuk hiburan. Sebagian besar digunakan abs(n)untuk mendukung angka negatif. Sebagian besar, jika tidak semua, dari mereka tidak boleh digunakan untuk perhitungan nyata.

Yang ini agak membosankan:

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"

Dan ini adalah favorit saya walaupun sayangnya tidak bekerja (seperti yang ditunjukkan oleh Maret Ho di bawah ini: hanya karena semua bilangan genap adalah jumlah dari dua bilangan prima, tidak berarti bahwa semua bilangan ganjil tidak).

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"
jscs
sumber
Solusi lucu :-)
Joey
2
Benar-benar necro lama, tetapi bukankah dugaan Goldbach Anda mencetak Bahkan untuk 9? Sepertinya kasus yang menegaskan kekeliruan yang diakibatkannya
Ho March
Yup, Anda benar-benar seratus persen benar, @MarchHo. Telur di wajahku.
jscs
10

Haskell

Ini, tentu saja, sama sekali bukan solusi kreatif, pemikiran-di-luar-kotak yang Anda cari, tetapi berapa kali saya bisa mengirim jawaban Haskell lebih pendek dari GolfScript, benarkah? Sayang sekali ini bukan kode golf.

odd

Tetapi yang lebih serius:

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

sumber
terlihat lebih panjang daripada jawaban GolfScript untuk saya
warren
2
Saya merujuk ke blok pertama ( odd) yang merupakan fungsi builtin yang mengembalikan True jika nomornya ganjil. Itu jawaban yang lengkap dengan sendirinya dan lebih pendek dari jawaban GolfScript saat ini (yang pada saat penulisan ini adalah 10 karakter, tapi saya berharap itu turun). Pertanyaannya juga agak kurang spesifik, karena itu saya tegaskan itu oddsudah cukup. Itu mungkin berubah juga.
1
melewatkan jawaban pertama dalam jawaban Anda :)
warren
1
Paling tidak parityalgoritma bekerja pada semua Numinstance yang bilangan bulat. Itu panas! Meskipun saya mungkin akan melakukannya evens = [0,2..] >>= \n -> [-n, n]. Mirip dengan odds.
Thomas Eding
7

Menggunakan pembacaan yang sengaja disalahgunakan dari pertanyaan, "Bagaimana menentukan apakah suatu angka ganjil atau genap", inilah implementasi C (asumsikan booldan truedidefinisikan dengan tepat):

bool is_odd_or_even(int n)
{
    return true;
}
Keith Thompson
sumber
Pertanyaannya menyebutkan angka, bukan bilangan bulat. Angka seperti 0.5kembali trueketika seharusnya tidak.
Konrad Borowski
6

Apa, belum ada algoritma acak ??

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]);
}

Pasangkan angka secara acak dalam kisaran 0 .. n -1 hingga kurang dari 2 tersisa. Ini cukup luar biasa tidak efisien: O ( n 3 ).


Benar-benar berbeda:

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

Menggunakan fakta bahwa transformasi Fourier dari fungsi genap (misalnya \x->x^^4) adalah nyata, sedangkan transformasi Fourier dari fungsi aneh adalah imajiner.

berhenti mengubah counterclockwis
sumber
5

Windows PowerShell

function OddOrEven([long]$n) {
  if (0,2,4,6,8 -contains "$n"[-1]-48) {
    "Even"
  } else {
    "Odd"
  }
}
  1. Konversi ke string
  2. Pilih huruf terakhir (digit) (intinya sebuah mod 10).
  3. Periksa apakah 0, 2, 4, 6 atau 8.

Tidak ada operator bitwise, tidak ada modulus, seperti yang diminta.

Joey
sumber
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.

Sejauh yang saya tahu ini adalah entri coq pertama pada codegolf.

Bahkan lebih pendek (59):

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

Rubi

n.odd?

Jika Anda ingin mencetak hasilnya:

f[n] = ->(n){puts n.odd?? 'odd' : 'even'}
Lowjacker
sumber
Saya cukup menggunakan ruby ​​using mod dalam .odd?definisi.
MrZander
4

Unlambda

Dunia membutuhkan lebih banyak Unlambda.

Unlambda memiliki keunggulan pembunuh di sini: representasi default ( ahem ) untuk angka adalah angka Gereja, jadi semua yang diperlukan adalah menerapkannya ke fungsi biner-bukan berfungsi dengan benar. Mudah!

PS: Penurunan harga dan Unlambda jelas tidak dibuat untuk satu sama lain.

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

Verifikasi untuk beberapa bilangan bulat pertama:

```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
JB
sumber
3

Naskah Golf

~,2/),1=\;
KAMU
sumber
3

Python

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

Performa yang mirip dengan versi sebelumnya. Berfungsi untuk 0 sekarang.

Versi sebelumnya yang salah:

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

Tidak terlalu efisien; waktu dan memori keduanya jelas O (n): 32 msec untuk 1.000.000; 2,3 msec untuk 100000; 3,2 usec untuk 100. Bekerja dengan angka negatif. Melempar kesalahan untuk 0, karena 0 tidak genap atau ganjil.

jscs
sumber
3
Nol pasti genap. Lihat juga: en.wikipedia.org/wiki/Parity_of_zero
@ jloy: Ah, sial. Saya pikir itu "fitur, bukan bug". Revisi lainnya ...
jscs
3

Fraktran

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

diaplikasikan ke

63*2^abs(n)

hasil baik 5jika nganjil atau 1jika nbahkan.

Pembaruan : Jauh lebih pendek tetapi tidak begitu menarik:

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

adalah 2untuk aneh ndan 1bahkan n.

Howard
sumber
3

MMIX (4 Bytes)

Ini agak curang. Saya tidak menggunakan mod atau operasi sedikit pun. Ini agak bahwa pengujian untuk nomor ganjil / genap dibangun. Dengan asumsi yang $3berisi angka untuk diuji dan hasilnya masuk ke $2:

ZSEV $2,$3,1

diatur $2ke 1jika $3genap dan 0jika tidak. Mnemnoric ZSEVberarti zero-set even dan memiliki semantik berikut:

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

Untuk baris di atas, mmixalhasilkan empat byte perakitan ini:

7F 02 03 01
FUZxxl
sumber
3

Skema

Ini adalah solusi paling tidak efisien yang saya tahu.

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

Perl

Bagaimana dengan

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

JavaScript, 36

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

Mengembalikan truejika bahkan, falsejika tidak.

Ry-
sumber
2

Perl

$n x '0' =~ /^(00)*$/
Ming-Tang
sumber
2

Python

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

menguji kuadrat i, jadi itu berfungsi untuk angka negatif juga

gnibbler
sumber
2

F #

Rekursi timbal balik untuk menang.

Angka n bahkan jika itu nol atau (n-1) ganjil.

Angka n ganjil jika tidak sama dengan nol dan (n-1) genap.

(abs ditambahkan jika ada yang tertarik pada paritas angka negatif)

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

Clojure

  (defmacro even?[n]
  `(= 1 ~(concat (list *) (repeat n -1))))
Benjie Holson
sumber
2

Apa yang memenuhi syarat sebagai operasi bitwise? Di bawah tenda, pembagian integer oleh 2 kemungkinan akan diterapkan sebagai bit-shift.

Dengan asumsi bitshift tidak keluar:

C / C ++

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

sunting Beberapa kurung terlewatkan, dan akhirnya diubah untuk menghapus pergeseran agar lebih sedikit. Anda dapat menguji ini dengan yang berikut (di * 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

... meskipun di Linux / tcsh, saya harus melarikan diri dari backslash \nmeskipun itu dalam tanda kutip tunggal. Saya menguji sedikit & big-endian, itu berfungsi dengan baik di keduanya. Juga, saya menyalinnya secara manual; komputer yang saya posting dengan tidak memiliki kompiler, jadi mungkin ada kesalahan.

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

atau

            shl  al, 7

atau

            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

... diikuti oleh:

            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

Sebagai alternatif, shift & bandingkan barang dapat dilakukan dengan cara ini juga:

            sar al,1            # signed integer division by 2 on least-significant byte
            jc  odd_label       # jump if carry flag is set
Brian Vandenberg
sumber
BTW, shldan teman-teman tidak diizinkan ...
FUZxxl
2

Pada prosesor 68000 Anda bisa memindahkan nilai kata dari alamat yang ditentukan oleh nilai yang akan diuji:

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

dan biarkan jebakan perangkat keras untuk kesalahan alamat menentukan sifat ganjil / genap dari nilai - jika pengecualian dinaikkan, nilainya aneh, jika tidak, nilainya genap:

 <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

Tidak bekerja pada Intel x86 CPU karena lebih fleksibel tentang akses data.

Mendesis
sumber
2

Python

Saya memutuskan untuk mencoba solusi paling jelek dan paling membingungkan yang dapat saya pikirkan:

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]

Mencetak e jika genap, o jika aneh.

scleaver
sumber
2

Q

Terus kurangi 2 hingga x <2 lalu konversikan ke bool

{1b$-[;2]/[2<=;abs x]}
skeevey
sumber