如何确定数字是否为奇数或偶数而无模或按位运算?[关闭]


19

如何确定数字是否为奇数或偶数而无模或按位运算?

这项挑战的效率非常低,但挑战了您思考创新解决方案的能力。

编辑

请创建一个函数。同样,尽管正则表达式是一个有趣的响应,但该函数应接受任何有效数字。

背景:这个问题源于我最早的编程时代。我们上课第一天的作业是写一个简单的程序,打印“ odd”或“ even”。身为臭小子,我没有读过我们上课时使用的那本书,只是向我们展示了如何使用它%来确定这一点。我花了大约半个小时在房间里来回跳动,试图想办法做到这一点,并从讲座中记住,数字在从一种原始类型转换为另一种原始类型时可能会丢失并获得精度。因此,如果您将数字取下,然后将其除以二,然后再相乘,则该数字不等于原始数字,那么您将知道该数字是奇数。

第二天,当我们的老师评估我们的程序时,我感到震惊,他认为这是解决问题的最原始的方法,即使效率低下。


3
我们应该创建一个函数还是程序?如果必须执行程序,IO应该如何发生?请进一步详细说明。
胡安

2
什么样的客观标准将决定接受的答案?代码大小?还有吗
PleaseStand 2011年

绝对是数字吗?它应该给字符串带来误报吗?
威廉

这已经存在了很长时间,但是似乎没有任何一种获胜条件,在我看来这意味着这里没有比赛。
dmckee

Answers:


40

在大多数编程语言中,除法返回整数的商。所以你可以简单地检查一下

(i/2)*2==i

6
我会说不一定是大多数。也许很多。
Joey

1
为确保其正常运行,您需要确保将所有内容都转换为一个int/ long类型
warren

@warren取决于编程语言/编译器优化/等。此外,您可以使用floor()。在C和C ++中可以完美地工作。
Mateen Ulhaq

1
0是偶数吗?
用户未知,

4
@userunknown:是的,零为偶数。
基思·汤普森

71

蟒蛇

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

10
简单的美丽/数学的简单...非常好!
2011年

我非常喜欢这个。
罗布

缓慢但富有创造力。
Mateen Ulhaq

21

Brainf ***(179)

这是我在BF中完成的涉及条件逻辑的更有趣的问题之一。

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

它需要带有数字的文本输入。如果数字是偶数,则输出E;如果数字是奇数,则输出O

我为此感到非常自豪,因此我将展示一种更易理解的形式:

+[>,]                                                   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
您可以将这两种解决方案分为不同的答案吗?
FUZxxl 2011年

这四个解决方案不是吗?
乔伊,

实际上,Mathematica中所有内置名称都是大写的,因此看起来很有趣,您应该使用IPi代替iand pi
张大卫

15

C

给定一个有限大小的整数,任何偶数都将自身乘以几倍,则溢出到0,而任何奇数将至少继续设置最低有效位。

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

编辑:作为一个简单的功能:

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

确保使用无符号整数。有符号整数的溢出是C语言中未定义的行为,因此如果需要的话,优化可能会做一些奇怪的事情。
乔伊·亚当斯

13

Python(慢)

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

1
对于肯定的作品...我想我可以abs()在开始时添加一个电话。
st0le 2011年

@Josh:这个技巧现在已经在这里出现过几次了:)
Joey

感谢gnibblr :)
st0le 2011年

@Joey:我不认为它是新的,但是风格不必是原始的。:)
jscs 2011年

12

的JavaScript

/[02468]$/.test(i)

产量true为偶数。这仅适用于大小合理的整数(例如,转换为字符串且不包含小数部分时,不能使用科学计数法。)


2
为了满足“功能”要求,您可以将其更改为simple /[02468]$/.test
Ry- 2011年

这个问题尚不十分清楚,但是输入可能根本不是数字/[02468]$/.test('I am a fake even number 0')。在那种情况下,您可以做/^[0-9].[02468]$/.test(i)
威廉

/-?^\d*[02468]$/比您的正则表达式要严格一点。您将需要更多的工作才能使其正确使用科学记数法对toString进行编号。
Thomas Eding

12

蟒蛇

由于我不太确定评分标准,因此出于娱乐考虑,我提出了许多解决方案。它们中的大多数abs(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"

这是我最喜欢的,尽管不幸的是它不起作用(正如下面的March Ho指出的:仅仅因为所有偶数都是两个质数之和,并不意味着所有奇数都不是)。

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"

可爱的解决方案:-)
Joey

2
确实是一个古老的死灵,但您的哥德巴赫猜想没有印上偶数9吗?似乎肯定了随之而来的谬误的情况
March Ho'7

是的,您绝对正确,@ MarchHo。鸡蛋在我的脸上。
jscs

10

哈斯克尔

当然,这绝对不是您要寻找的创造性,即席即用的解决方案,但是我真的可以发布几次比GolfScript更短的Haskell答案,真的吗?这不是代码高尔夫,真是遗憾。

odd

但更严重的是:

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

看起来比GolfScript对我的回答更长
沃伦

2
我指的是第一个块(odd),它是一个内置函数,如果数字为奇数,则返回True。这是一个完整的答案,比当前的GolfScript答案要短(在撰写本文时为10个字符,但我希望它会下降)。这个问题也没有odd得到充分说明,这就是为什么我断言这足够了。那也可能会改变。

1
错过了您的答案的第
一句话

1
至少,该parity算法适用于所有Num整数实例。好烫!虽然我可能会做evens = [0,2..] >>= \n -> [-n, n]。赔率相似。
Thomas Eding

7

故意歪曲阅读问题:“如何确定数字是奇数还是偶数”,这是一个C实现(假定booltrue适当定义):

bool is_odd_or_even(int n)
{
    return true;
}

问题提到数字,而不是整数。像这样的数字在不应该0.5返回true时返回。
Konrad Borowski 2014年

6

什么,还没有随机算法?

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的数字,直到少于2。这是相当惊人的效率低下:Øñ 3)。


完全不同:

哈斯克尔

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

使用偶数函数(例如\x->x^^4)的傅立叶变换是实数,而奇数函数的傅立叶变换是虚数的事实。


5

Windows PowerShell

function OddOrEven([long]$n) {
  if (0,2,4,6,8 -contains "$n"[-1]-48) {
    "Even"
  } else {
    "Odd"
  }
}
  1. 转换为字符串
  2. 选择最后一个字母(数字)(本质上是mod 10)。
  3. 检查它是0、2、4、6还是8。

没有按需运算符,没有模数。


5

辅酶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.

据我所知,这是codegolf上的第一个coq条目。

甚至更短(59):

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

4

红宝石

n.odd?

如果要打印结果:

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

我相当在.odd?定义中使用ruby use mod 。
MrZander 2013年

4

Unlambda

世界需要更多Unlambda。

Unlambda在这里具有杀手advantage优势:默认值(ahem)表示是教堂数字,因此所需要做的就是将它们应用于二进制函数而不是true。简单!

附言:Markdown和Unlambda绝对不是一对。

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

验证前几个整数:

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

蟒蛇

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

与早期版本相似的性能。现在适用于0。

不正确的早期版本:

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

效率不高;时间和内存都明显为O(n):32毫秒,持续1,000,000;100毫秒为2.3毫秒;3.2 usec为100。可使用负数。为0引发错误,因为0既不是偶数也不是奇数。


3
零绝对是偶数。另请参见:en.wikipedia.org/wiki/Parity_of_zero

@jloy:噢,胡扯。我以为那是“功能而不是错误”。更多修订...
jscs 2011年

3

Fractran

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

应用于

63*2^abs(n)

产率或者5如果n是奇数或1如果n是偶数。

更新:更短,但没那么有趣:

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

2奇数n1偶数n


3

MMIX(4字节)

这是一种作弊。我既不使用mod也不进行任何摆弄操作。而是内置了奇数/偶数测试。假设其中$3包含要测试的数字,则结果为$2

ZSEV $2,$3,1

设置$21if $3是偶数,0如果不是。mnemnoric ZSEV表示偶数集为零,并具有以下语义:

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

对于上面的行,mmixal生成这四个汇编字节:

7F 02 03 01

3

方案

这是我所知道的最无效的解决方案。

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

3

佩尔

关于什么

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

2

JavaScript,36

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

返回true偶数,false否则返回。



2

蟒蛇

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

测试i的平方,所以它也适用于负数


2

F#

相互递归取胜。

即使n为零或(n-1)为奇数,数字n也是。

如果数字n不等于零且(n-1)为偶数,则它为奇数。

(如果有人对负数的均价感兴趣,则添加abs)

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


2

什么才算是按位运算?在幕后,将整数除以2可能会实现为移位。

假设没有发生移位:

C / C ++

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

编辑 遗漏了一些括号,并最终进行了更改,以删除一个使其变少的移位。您可以使用以下命令(在* 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

...尽管在Linux / tcsh中,我不得不在 \n即使在单引号中。我在little&big-endian中进行了测试,在两者中均正常工作。另外,我手工复制了这个。我要发布的计算机没有编译器,因此可能有错误。

x86汇编

            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

要么

            shl  al, 7

要么

            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

... 其次是:

            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

或者,也可以通过这种方式完成移位和比较的工作:

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

顺便说一句,shl和朋友都不允许...
FUZxxl 2012年

2

在68000处理器上,您可以将一个单词值从该值定义的地址中移出进行测试:

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

并让地址错误的硬件陷阱确定该值的奇/偶性质-如果引发异常,则该值为奇数;否则,该值为偶数:

 <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,因为它们在数据访问方面更灵活。


2

蟒蛇

我决定尝试我能想到的最丑陋,最令人困惑的解决方案:

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,奇数打印o。


2

继续减去2直到x <2然后转换为bool

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