mod-or-ビット演算を使用せずに、数値が奇数か偶数かを判断する方法は?[閉まっている]


19

mod-or-ビット演算を使用せずに、数値が奇数か偶数かを判断する方法は?

この課題は非常に非効率的ですが、創造的なソリューションのために枠を超えて考える能力に課題があります。

編集

関数を作成してください。また、正規表現は楽しい応答ですが、関数は有効な数値を受け入れる必要があります。

背景:この質問は、私がプログラミングを始めたばかりの頃に由来します。クラス初日の宿題は、「奇数」または「偶数」を出力する簡単なプログラムを書くことでした。私が小学生だったので、それ%を決定するためにどのように使用するかを単に示したクラスのために持っていた本を読みませんでした。私はこれを行う方法を考えようとして部屋で前後に約30分ペースを費やし、講義から、あるプリミティブ型から別の型にキャストされると数値が精度を失い、獲得する可能性があることを思い出しました。したがって、数値を取得し、それを2で割ってから元の数値と等しくなかった場合は、その数値が奇数であることがわかります。

翌日、私たちのインストラクターがプログラムを評価している間、私はit然としました。彼はそれが最も効率的ではないにしても、問題を解決する方法であると考えていました。


3
関数またはプログラムを作成する必要がありますか?プログラムを実行する必要がある場合、IOはどのように発生しますか?さらに詳しく説明してください。
フアン

2
どの客観的基準が受け入れられた答えを決定しますか?コードサイズ?他に何か?
プリーズスタンド

それは間違いなく数字ですか?文字列に誤検知を与えるべきですか?
ウィリアム

これはかなり前からありましたが、どんな種類の勝利条件も存在しないようです。これは、ここではゲームがないことを意味します。
dmckee

回答:


40

ほとんどのプログラミング言語では、除算は整数の商を返します。これを簡単に確認できます

(i/2)*2==i

6
必ずしもほとんどとは言えません。多くの、多分。
ジョーイ

1
正しく実行されるようにするには、すべてをint/ long型にキャストする必要があります。
ウォーレン

@warrenプログラミング言語/コンパイラの最適化/などに依存します。さらに、を使用できますfloor()。これは、CおよびC ++で完全に機能します。
Mateen Ulhaq

1
0は偶数ですか?
ユーザー不明

4
@userunknown:はい、ゼロは偶数です。
キーストンプソン

71

Python

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

10
数学のシンプルな美しさ/美しいシンプルさ...とても素敵!
-jscs

私はこれが大好きです。
ロブ

遅いが創造的。
Mateen Ulhaq

21

Brainf ***(179)

これは、BFで行った条件付きロジックに関連するより興味深い問題の1つです。

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

数値を含むテキスト入力を受け取ります。数が偶数の場合はを出力し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
これらの2つのソリューションを異なる答えに分割できますか?
-FUZxxl

これらの4つのソリューションではありませんか?
ジョーイ

実際、Mathematicaのすべての組み込み名は大文字で始まるため、見た目はおかしいので、IandのPi代わりに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

@ジョシュ:そのトリックはすでにここに数回現れました:)
ジョーイ

:) gnibblrにクレジット
st0le

@Joey:新しいものだとは思いませんでしたが、スタイルは独創的である必要はありません。:)
jscs

12

JavaScript

/[02468]$/.test(i)

利回りtrue偶数ため。これは、適切なサイズの整数でのみ機能します(たとえば、文字列に変換され、小数部を持たない科学表記法ではありません)。


2
「機能」要件を満たすために、それを単にに変更できます/[02468]$/.test
Ry-

質問では明確ではありませんでしたが、入力がまったく数値ではない可能性があります/[02468]$/.test('I am a fake even number 0')。その場合、できること/^[0-9].[02468]$/.test(i)
ウィリアム

/-?^\d*[02468]$/あなたの正規表現よりも少し厳しいでしょう。科学表記法を使用してtoStringされた数値に対して適切に機能するには、これ以上の作業が必要です。
トーマスエディング

12

Python

採点基準が本当にわからないので、娯楽のために私が考え出した多くの解決策があります。それらのほとんどは使用します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"

残念ながら機能しませんが、これは私のお気に入りです(以下の3月Hoで指摘されているように、すべての偶数が2つの素数の合計であるという理由だけで、すべての奇数が機能しないわけではありません)。

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"

かわいいソリューション:
ジョーイ

2
本当に古いネクロですが、あなたのゴールドバッハの推測は9でも答えを印刷しませんか?結果の誤acy
3月Ho

うん、あなたは絶対に、百パーセント正しい、@ 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]。オッズも同様です。
トーマスエディング

7

「数字が奇数か偶数かを判断する方法」という質問を故意に逆読みして、Cの実装を示します(適切に定義されているboolと仮定しtrueます)。

bool is_odd_or_even(int n)
{
    return true;
}

質問は整数ではなく数に言及しています。あるべきではない数が0.5返されますtrue
コンラッドボロウスキ14年

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未満になるまでランダムに組み合わせます。これはかなり驚くほど非効率的だ:Onは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

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.

私が知る限り、これは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を使用しています。
-MrZander

4

ウンラムダ

世界にはより多くのUnlambdaが必要です。

ここで、Unlambdaには大きな利点があります:そのデフォルト(ahem数値の)表現は教会の数字であるため、必要なのは、それらを関数trueではなく関数binaryに適用することだけです。簡単!

PS: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

Python

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

以前のバージョンと同様のパフォーマンス。現在は0で動作します。

不適切な以前のバージョン:

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

特に効率的ではありません。時間とメモリの両方が明らかにO(n):1,000,000で32ミリ秒。100000の場合2.3ミリ秒。3.2 100のusec。負の数で動作します。0は偶数でも奇数でもないため、0に対してエラーをスローします。


3
ゼロは間違いなく偶数です。参照:en.wikipedia.org/wiki/Parity_of_zero

@jloy:ああ、くだらない。これは「バグではなく機能」だと思いました。その他の改訂
...-jscs

3

フラクトラン

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

に適用されます

63*2^abs(n)

5if nが奇数または1ifのどちらかですn

更新:はるかに短いがそれほど面白くない:

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

2、奇数n1偶数nです。


3

MMIX(4バイト)

これは一種の不正行為です。mod操作もビット操作操作も使用していません。むしろ、奇数/偶数のテストが組み込まれています。$3テストする数値が含まれ、結果が次のようになると仮定します$2

ZSEV $2,$3,1

if が偶数で、ifがそうでない場合に設定$2します。mnemnoric はゼロセット偶数を意味し、次のセマンティクスを持ちます。1$30ZSEV

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

上記の行では、mmixal次の4バイトのアセンブリを生成します。

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


2

JavaScript、36

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

true偶数の場合、falseそうでない場合を返します。



2

Python

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

iの2乗をテストするため、負の数でも機能します


2

F#

勝利のための相互再帰。

数値nは、ゼロまたは(n-1)が奇数の場合でも偶数です。

数値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、一重引用符で囲まれていても、バックスラッシュをエスケープする必要がありました。リトルエンディアンでテストしましたが、両方で正しく動作します。また、私はこれを手でコピーしました。私が投稿しているコンピューターにはコンパイラーがないため、間違いがあるかもしれません。

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

または

            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

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

Python

私は考えることができる最もgliい、最も混乱するソリューションを試してみることにしました:

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

Q

x <2まで2を減算し続けてからboolに変換します

{1b$-[;2]/[2<=;abs x]}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.