Как определить, является ли число нечетным или четным без мод-или-побитовых операций? [закрыто]


19

Как определить, является ли число нечетным или четным без мод-или-побитовых операций?

Эта задача крайне неэффективна, но ставит под сомнение вашу способность мыслить нестандартно для творческого решения.

РЕДАКТИРОВАТЬ :

Пожалуйста, создайте функцию. Кроме того, хотя регулярное выражение является забавным ответом, функция должна принимать любое допустимое число.

ПРЕДПОСЫЛКИ : Этот вопрос связан с моими самыми ранними днями программирования. Домашняя работа для нашего первого дня класса состояла в том, чтобы написать простую программу, которая напечатала бы «нечетный» или «четный». Будучи ребёнком, которым я был, я не читал книгу, которую мы имели для класса, где он просто показал нам, как использовать это,%чтобы определить это. Я провёл около получаса в своей комнате, пытаясь придумать, как это сделать, и из лекции вспомнил, что числа могут терять и приобретать точность, когда они преобразуются из одного примитивного типа в другой. Поэтому, если вы взяли число, поделили его на два, а затем умножили на обратное, не равное исходному числу, то вы бы знали, что число нечетное.

На следующий день я был ошеломлен, когда наш инструктор оценивал наши программы, и он думал, что это самый оригинальный, хотя и неэффективный, способ решения проблемы.


3
Должны ли мы создать функцию или программу? Как должно произойти IO, если мы должны сделать программу? Пожалуйста, уточните дальше.
Хуан,

2
Какой объективный критерий будет определять принятый ответ? Размер кода? Что-то другое?
Пожалуйста, постой

Это определенно номер? Должен ли он дать ложные срабатывания для строки?
Уильям

Это было в течение достаточно долгого времени, но, похоже, нет условий для выигрыша, что, на мой взгляд, означает, что здесь нет игры.
dmckee

Ответы:


40

В большинстве языков программирования деление возвращает частное для целых чисел. Так что вы можете просто проверить это

(i/2)*2==i

6
Не обязательно большинство, я бы сказал. Многие, может быть.
Джои

1
чтобы убедиться, что он работает правильно, вы должны убедиться, что все приведено в int/ longtype
warren

@warren Зависит от языка программирования / оптимизации компилятора / и т. д. Кроме того, вы можете использовать floor(). Это прекрасно работает в C и C ++.
Матин Улхак

1
0 - четное число?
пользователь неизвестен

4
@userunknown: Да, ноль четен.
Кит Томпсон

71

питон

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

10
Простая красота / красивая простота математики ... очень приятно!
ОАО

Мне это очень нравится.
Роб

Медленно, но креативно.
Матеин Улхак,

21

Брейнф *** (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

Разве это не четыре решения?
Джои

На самом деле, все встроенные имена в Mathematica пишутся с заглавной буквы, так что, как это ни смешно, вы должны использовать Iи Piвместо iи pi.
Дэвид Чжан,

15

С

Умноженное само по себе несколько раз, любое четное число будет переполнено до 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

@Josh: этот трюк уже появлялся здесь уже несколько раз :)
Joey

Кредиты для gnibblr :)
st0le

@Joey: я не думал, что это было новым, но стиль не должен быть оригинальным. :)
ОАО

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'ed с использованием научной записи.
Томас Эдинг

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"

И это мой фаворит, хотя, к сожалению, он не работает (как указывает март Хо ниже: только то, что все четные числа являются суммой двух простых чисел, не означает, что все нечетные числа не являются).

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? Похоже на случай подтверждения последовавшей ошибки
март Хо,

Да, вы абсолютно на сто процентов правы, @MarchHo. Яйцо на моем лице.
ОАО

10

Haskell

Это, конечно, ни в коем случае не творческое, нестандартное решение, которое вы ищете, но сколько раз я собираюсь опубликовать ответ на Haskell короче, чем GolfScript, правда? Это действительно позор, это не код гольф.

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когда не должно быть.
Конрад Боровски

6

Что, никаких рандомизированных алгоритмов еще нет?

С

#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. Это довольно удивительно неэффективно: O ( п 3 ).


Полностью отличается:

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

Использует тот факт, что преобразование Фурье четной функции (например, \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. Выберите последнюю букву (цифру) (по сути, мод 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.

Насколько я могу судить, это первая запись coq на codegolf.

Еще короче (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?определении.
MrZander

4

Unlambda

Мир нуждается в большем количестве Unlambda.

Unlambda имеет преимущество убийца здесь: его значение по умолчанию ( гм ) для чисел - это церковные цифры, поэтому все, что нужно, это применить их к двоичной функции, а не к функции true. Легко!

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

питон

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

Аналогичная производительность для более ранней версии. Работает на 0 сейчас.

Неверная более ранняя версия:

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

Не особенно эффективно; время и память, очевидно, O (n): 32 мсек на 1000000; 2,3 мс на 100000; 3.2 usec за 100. Работает с отрицательными числами. Выдает ошибку для 0, потому что 0 не является ни четным, ни нечетным.


3
Ноль определенно ровный. Смотрите также: en.wikipedia.org/wiki/Parity_of_zero

@jloy: Ой, дерьмо. Я думал, что это «особенность, а не ошибка». Больше ревизий ...
ОАО

3

Fractran

[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для нечетных nи 1для четных n.


3

MMIX (4 байта)

Это своего рода обман. Я не использую ни мод, ни битовые операции. Скорее, тестирование на нечетные / четные числа встроено. Предполагая, что $3содержит число для проверки и результат входит в $2:

ZSEV $2,$3,1

наборы $2к , 1если $3даже и в противном 0случае. Мнемнорика 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)))




2

питон

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

тестирование квадрата я, так что это работает и для отрицательных чисел


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"

edit Пропущены некоторые скобки, и в конечном итоге изменено, чтобы убрать сдвиг, чтобы сделать его меньше. Вы можете проверить это с помощью следующего (в * 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 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, так как они более гибки в доступе к данным.


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

Q

Продолжайте вычитать 2 до x <2, а затем конвертировать в bool

{1b$-[;2]/[2<=;abs x]}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.