Bir sayının tek veya çift modlu veya çift yönlü işlemleri olmadan nasıl belirlenir? [kapalı]


19

Bir sayının tek veya çift modlu veya çift yönlü işlemleri olmadan nasıl belirlenir?

Bu zorluk son derece verimsizdir, ancak yaratıcı bir çözüm için kutunun dışında düşünme yeteneğinizi zorlar.

DÜZENLE :

Lütfen bir işlev oluşturun. Ayrıca, normal ifade eğlenceli bir yanıt olsa da, işlev geçerli herhangi bir sayıyı kabul etmelidir .

ARKA PLAN : Bu soru en erken programlama günlerimden kaynaklanıyor. Sınıfımızın ilk gününün ödevi, 'tek' veya 'çift' basılan basit bir program yazmaktı. Olduğum velet olarak, sadece bize%bunu belirlemek içinnasıl kullanılacağını gösteren sınıf için sahip olduğumuz kitabı okumadım. Bunu yapmak için bir yol düşünmeye çalışırken yaklaşık yarım saat ileri geri odamda geçirdi ve bir ilkel türden diğerine dökülürken sayılar kaybedebilir ve hassasiyet kazanabilirsiniz dersten hatırladı. Bu nedenle, sayıyı aldıysanız, ikiye böldükten sonra geri çarparsanız, orijinal sayıya eşit değildi, o zaman sayının garip olduğunu bilirsiniz.

Ertesi gün, eğitmenlerimiz programlarımızı değerlendirirken hayrete düştüler, sorunun çözülmesinin en özgün, verimsiz yol olduğunu düşündü.


3
Bir işlev veya program oluşturmalı mıyız? Bir program yapmak zorunda kalırsak nasıl olur? Lütfen, daha fazla ayrıntı verin.
Juan

2
Kabul edilen cevabı hangi nesnel kriter belirler? Kod boyutu? Başka bir şey?
11:47

Kesinlikle bir sayı mı? Bir dize için yanlış pozitif mi vermelidir?
William

Bu oldukça uzun bir süredir var, ancak herhangi bir tür kazanan bir koşul yok gibi görünüyor, bence burada oyun yok.
dmckee

Yanıtlar:


40

Çoğu programlama dilinde bölüm tamsayılar için bölüm verir. Böylece bunu kontrol edebilirsiniz

(i/2)*2==i

6
Mutlaka çoğu değil, söyleyebilirim. Pek çok, belki.
Joey

1
düzgün çalıştığından emin olmak için, her şeyi bir int/ longtüre dönüştürdüğünüzden emin olmanız gerekir
warren

@warren Programlama diline / derleyici optimizasyonlarına / vb. bağlıdır. Ayrıca, kullanabilirsiniz floor(). C ve C ++ 'da mükemmel çalışır.
Mateen Ulhaq

1
0 çift sayı mı?
kullanıcı bilinmiyor

4
@userunknown: Evet, sıfır bile.
Keith Thompson

71

piton

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

10
Matematiğin basit güzelliği / güzel sadeliği ... çok güzel!
jscs

Bunu çok beğendim.
Rob

Yavaş ama yaratıcı.
Mateen Ulhaq

21

Brainf *** (179)

Bu, BF'de yaptığım koşullu mantığı içeren daha ilginç sorunlardan biridir.

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

Sayı içeren bir metin girişi alır. Sayı çiftse çıktı verir Eve tuhafsa çıktı verir O.

Daha insan tarafından okunabilir bir form göstereceğimden gurur duyuyorum:

+[>,]                                                   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

Mathematica

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

2
Bu iki çözümü farklı cevaplara bölebilir misiniz?
FUZxxl

Bu dört çözüm değil mi?
Joey

Aslında hepsi yerleşik isimler Mathematica böylece komik göründüğü kadar, kullanmak gerekir, aktifleştirilmektedir Ive Piyerine ive pi.
David Zhang

15

C

Sonlu büyüklükte bir tamsayı göz önüne alındığında herhangi bir çift sayının birkaç kez kendi kendine çarpımı 0'a taşacak ve herhangi bir tek sayı en azından en az anlamlı bit ayarına sahip olmaya devam edecektir.

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

Düzenleme: Basit bir işlev olarak:

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

İmzasız tam sayılar kullandığınızdan emin olun. İmzalı tam sayıların taşması C'de tanımlanmamış bir davranıştır, bu nedenle optimizasyon isterse garip bir şey yapabilir.
Joey Adams

13

Python (Yavaş)

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

1
Olumlu çalışır ... Ben abs()başlangıçta bir çağrı ekleyebilirsiniz sanırım .
st0le

@Josh: Bu hile şimdiye kadar birkaç kez burada ortaya çıktı :)
Joey

Kredi gnibblr :)
st0le

@Joey: Yeni olduğunu düşünmedim, ama stilin orijinal olması gerekmiyor. :)
jscs

12

JavaScript

/[02468]$/.test(i)

trueçift ​​sayı verir . Bu yalnızca makul büyüklükte tamsayılarla çalışır (örneğin, bir dizeye dönüştürüldüğünde ve kesirli kısmı olmayan bilimsel gösterim değil).


2
"İşlev" gereksinimini karşılamak için basitçe değiştirebilirsiniz /[02468]$/.test.
Ry-

Soruda tam olarak açık değildi, ancak girdinin bir sayı olmaması mümkün olabilir /[02468]$/.test('I am a fake even number 0'). Bu durumda/^[0-9].[02468]$/.test(i)
William

/-?^\d*[02468]$/regex'inizden biraz daha katı olurdu. Bilimsel gösterimi kullanarak dize edilecek sayılar için düzgün çalışması için daha fazla çalışmaya ihtiyacınız olacaktır.
Thomas Eding

12

piton

Puanlama ölçütlerinin ne olduğundan tam olarak emin olmadığım için, işte eğlence adına bulduğum birçok çözüm var. Çoğu abs(n)negatif sayıları desteklemek için kullanır . Hepsi olmasa da çoğu gerçek hesaplama için asla kullanılmamalıdır.

Bu biraz sıkıcı:

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"

Ne yazık ki işe yaramasa da bu benim favorim (aşağıdaki Mart Ho tarafından işaret edildiği gibi: sadece çift sayılar iki asalın toplamı olduğu için, tüm tek sayıların olmadığı anlamına gelmez).

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"

Şirin çözümler :-)
Joey

2
Gerçekten eski bir nekro, ama Goldbach'ın varsayım yanıtı 9 için bile yazdırılmıyor mu? Ortaya çıkan yanlışlığı teyit eden
Mart Ho

Evet, kesinlikle yüzde yüz haklısın, @MarchHo. Yüzümde yumurta.
jscs

10

Haskell

Bu, elbette, hiçbir şekilde aradığınız yaratıcı, düşünmenin dışında bir çözüm değil, ama kaç kez GolfScript'ten daha kısa bir Haskell cevabı göndereceğim? Bu bir kod golf değil gerçekten bir utanç.

odd

Ama daha ciddisi:

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

bana GolfScript'in cevabından daha uzun görünüyor
warren

2
oddSayı tekse True döndüren bir yerleşik işlev olan ilk blok ( ) atıfta . Bu kendi başına tam bir cevaptır ve mevcut GolfScript cevabından daha kısadır (bu yazı yazarken 10 karakterdir, ancak aşağı inmesini beklerim). Soru da biraz yetersiz, bu yüzden oddyeterli olduğunu iddia ediyorum . Bu da değişebilir.

1
Cevabınızdaki ilk cevabı kaçırdınız :)
warren

1
En azından parityalgoritma Num, tamsayı olan tüm örneklerde çalışır . Bu sıcak! Ama muhtemelen yapardım evens = [0,2..] >>= \n -> [-n, n]. Oranlar için benzer.
Thomas Eding

7

"Bir sayının tek veya çift olup olmadığını belirleme" sorusunun kasten sapkın bir okumasını kullanarak, burada bir C uygulaması (varsayalım boolve trueuygun şekilde tanımlanmıştır):

bool is_odd_or_even(int n)
{
    return true;
}

Soru tamsayıdan değil sayıdan bahsediyor. Olmaması gerektiği gibi 0.5döndürür gibi sayı true.
Konrad Borowski

6

Ne, henüz rastgele algoritmalar yok ??

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

0 .. n -1 aralığındaki sayıları, 2'den az kalana kadar rastgele eşleştirir . Oldukça şaşırtıcı verimsiz: Ey ( n 3 ).


Tamamen farklı:

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

Çift bir işlevin (örneğin \x->x^^4) Fourier dönüşümünün gerçek olduğunu, tek bir işlevin Fourier dönüşümünün hayali olduğunu kullanır.


5

Windows PowerShell

function OddOrEven([long]$n) {
  if (0,2,4,6,8 -contains "$n"[-1]-48) {
    "Even"
  } else {
    "Odd"
  }
}
  1. Dizeye dönüştür
  2. Son harfi (rakam) seçin (esas olarak bir mod 10).
  3. 0, 2, 4, 6 veya 8 olup olmadığını kontrol edin.

İstendiği gibi bitsel operatör yok, modül yok.


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.

Bildiğim kadarıyla bu kodgolf ilk coq girişi olduğunu.

Daha da kısa (59):

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

4

Yakut

n.odd?

Sonucu yazdırmak istiyorsanız:

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

Ben .odd?tanımında yakut kullanır mod kullanıyorum .
MrZander

4

Unlambda

Dünyanın daha fazla Unlambda'ya ihtiyacı var.

Unlambda'nın burada katil bir avantajı var: sayılar için varsayılan ( ahem ) temsili Kilise rakamlarıdır, bu yüzden gerekli olan tek şey onları doğru işlev görmemek için ikili işleve uygulamaktır. Kolay!

Not: Markdown ve Unlambda kesinlikle birbirleri için yapılmıyor.

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

İlk birkaç tamsayı için doğrulama:

```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

piton

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

Önceki sürüme benzer performans. 0 için çalışıyor.

Yanlış Önceki sürüm:

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

Özellikle verimli değil; zaman ve bellek her ikisi de açıkça O (n): 1.000.000 için 32 ms; 100000 için 2,3 milisaniye; 3.2 için 3.2 usec. Negatif sayılarla çalışır. 0 için bir hata atar, çünkü 0 ne çift ne de tektir.


3
Sıfır kesinlikle eşittir. Ayrıca bakınız: en.wikipedia.org/wiki/Parity_of_zero

@jloy: Hata! Bunun "bir hata değil bir özellik" olduğunu düşündüm. Diğer düzeltmeler ...
jscs

3

Fractran

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

uygulanan

63*2^abs(n)

verim ya da 5eğer ntek veya 1eğer ndaha olduğunu.

Güncelleme : Çok daha kısa ama çok ilginç değil:

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

olduğu 2tek için nve 1hatta için n.


3

MMIX (4 Bayt)

Bu bir tür hile. Ne mod ne de bit uğraştırma operasyonları kullanıyorum. Daha ziyade tek / çift sayıları test etmek yerleşiktir. $3Test edilecek sayıyı içerdiğini ve sonucun gittiğini varsayarsak $2:

ZSEV $2,$3,1

setleri $2için 1eğer $3bile olduğunu ve 0eğer. Mnemnoric ZSEV, sıfır kümesi eşittir ve aşağıdaki semantiğe sahiptir:

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

Yukarıdaki satır için, mmixalbu dört bayt montajı oluşturur:

7F 02 03 01

3

düzen

Bu bildiğim en verimsiz çözüm.

(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

Ne dersin

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

2

JavaScript, 36

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

Eğer değilse true, döndürür false.



2

piton

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

i karesini test ediyoruz, bu yüzden negatif sayılar için de çalışıyor


2

F #

Kazanmak için karşılıklı özyineleme.

N sayısı sıfır olsa veya (n-1) tek olsa bile.

N sayısı, sıfıra eşit değilse ve (n-1) eşitse tektir.

(Negatif sayıların paritesiyle ilgilenmesi durumunda abs eklendi)

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


2

Bitsel işlem olarak nitelendirilen nedir? Kaputun altında, 2'ye tamsayı bölmesinin bir bit kaydırma olarak uygulanması muhtemeldir.

Bitshiftlerin dışarıda olmadığı varsayılırsa:

C / C ++

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

düzenlemek Missed some parantez ve sonuçta daha az yapmak için bir vardiya kaldırmak için değiştirildi. Bunu aşağıdakilerle test edebilirsiniz (* nix'te):

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

... Linux / tcsh'de \nolsa da, tek tırnak içinde olmasına rağmen ters eğik çizgiden kaçmak zorunda kaldım . Küçük ve big-endian'da test ettim, her ikisinde de doğru çalışıyor. Ayrıca, bunu el ile kopyaladım; Gönderdiğim bilgisayarın bir derleyicisi yok, bu yüzden hataları olabilir.

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

veya

            shl  al, 7

veya

            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

... bunu takiben:

            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

Alternatif olarak, üst karakter değiştir ve karşılaştır şu şekilde de yapılabilir:

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

BTW shlve arkadaşlarına izin verilmiyor ...
FUZxxl

2

68000 işlemcide, bir kelime değerini test edilecek değerle tanımlanan adresten taşıyabilirsiniz:

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

ve adres hatası için donanım tuzağının değerin tek / çift niteliğini belirlemesine izin verin - istisna yükseltilmişse, değer garipti, değilse değer çiftti:

 <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

Intel x86 CPU'larda çalışmaz, çünkü bunlar veri erişimi konusunda daha esnektir.


2

piton

Düşünebileceğim en çirkin, en kafa karıştırıcı çözümü denemeye karar verdim:

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]

E çiftse, o tekse yazdırır.


2

S

X <2 olana kadar 2 çıkartmaya devam edin, sonra boole dönüştürün

{1b$-[;2]/[2<=;abs x]}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.