Перевірка біт


28

Напишіть програму / функцію, яка приймає два цілих числа в діапазоні від до включно і повертає, чи двійкові форми чисел точно на один біт.0255

Наприклад, і мають бінарні форми і , які є один біт. Так само і є, і тому вони повертаються справжніми.10000000010000000015224010011000000011000

Однак ваш код повинен бути незайманим , таким чином, якщо будь-який біт у вашій програмі перевернутий, він може призвести до помилки. Наприклад, якщо у вашій програмі був один байтa(01100001), то всі 8 можливих модифікованих програм:

á ! A q i e c `

повинен викинути помилку. Переконайтеся, що ви змінюєте байти (наприклад á, там, де насправді є байт , а не два байти ).225á

Тестові приклади:

0,1     => Truthy
1,0     => Truthy
152,24  => Truthy
10,10   => Falsey
10,11   => Truthy
11,12   => Falsey
255,0   => Falsey

Правила:

  • Надайте тестовий фреймворк, який зможе переконатися, що ваша програма належним чином, оскільки буде багато можливих програм (кількість байтів * 8), інакше повний доказ первозданності.
    • Будь ласка, переконайтесь, що ваша програма діє перед її публікацією.
  • Вихідні дані повинні бути або truthy / falsey (або навпаки, це добре), або ще два чіткі значення помилки
  • Помилками можуть бути час виконання, компілятор, інтерпретатор тощо.

7
Якщо хтось шукає спосіб генерувати всі можливі варіанти їх рішення, ця програма Japt повинна (хтось, будь ласка, перевірте) виконати роботу: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy

4
Ось такий і в Python: Спробуйте в Інтернеті!
TFeld

Функції заборонені, оскільки ви згадали про програму?
Кевін Круїссен

5
@KevinCruijssen Я уточнив, що подання функцій у порядку
Jo King

4
Цей коментар має більше +1s, ніж більшість моїх останніх рішень! : \
Shaggy

Відповіді:


16

Python 2 , 35 байт

lambda a,b:(a^b)&-(a^b)in[a^b or[]]

Спробуйте в Інтернеті!

Використовує перевірку потужності двох n&-n==n, усуваючи n==0помилковий позитив.

Для довідки, це пари одночарових бінарних операторів, які розташовані один на одного, що робить їх важкими у використанні:

+ /
- /
* +
% -
< |
< >

На щастя, &і ^серед них немає.

Також зауважте, що ==може стати <=і +може стати символом коментаря #.


Python 2 , 41 байт

lambda a,b:bin(a^b).count(`+True`)is+True

Спробуйте в Інтернеті!

Беручи TFeld - х lambda a,b:bin(a^b).count('1')==1 і робить його недоторканим, змінюючи 1, щоб +Trueі ==в is. Завдяки Джо Кінгу за 1 байт.


9

Python 2 , 72 67 50 байт

lambda a,b:sum(map(int,'{:b}'.format(a^b)))is+True

Спробуйте в Інтернеті!

-5 байт, завдяки Джо Кінгу


Повернення True/ Falseдля truthy / falsey.

Програма в основному така сама lambda a,b:bin(a^b).count('1')==1, але без чисел та інших символів, які працюють при переверненні бітів.

Працює, переконуючись, що майже все є іменованою функцією (які всі досить незаймані)

Простий тест в кінці гортає один біт (на кожен біт) і намагається функцію на вході. Якщо це працює (правильно чи ні), ця версія надрукується. Немає друкованих програм = незаймана функція.


8

Java 8, 68 61 56 45 байт

a->b->(a.bitCount(a^b)+"").equals(-~(a^a)+"")

-11 байт завдяки @EmbodimentOfIgnorance , замінюючи константу java.awt.Font.BOLD на -~(a^a).

Спробуйте в Інтернеті.

Пояснення:

Найкоротшою базовою функцією буде:

a->b->a.bitCount(a^b)==1

Спробуйте в Інтернеті.

Це змінено, щоб у ньому не було жодної цифри, =ані одного з +/*операндів для числових обчислень (тому +для String-конкатенації добре):

+""І .equalsповинні порівнювати по String.equals(String)а int==int.
ПРИМІТКА: Integer.equals(int)тут можна використовувати, але було б більше байтів, оскільки обидва .bitCountі java.awt.Font.BOLDє примітивними intзамість Integer-об'єктів, тому new Integer(...)для перетворення одного з двох в Integer-об'єкт потрібно мати додатковий , перш ніж ми зможемо використовувати .equals.


(Ціле) Math.log (Math.E) становить 21 байт
Expired даних


@ExpiredData Спасибі, насправді я просто знайшов коротший констант java.awt.Font.BOLD, але ваш Objects.equalsприємний гольф, спасибі!
Кевін Круїссен

@ExpiredData Насправді Objectsє частиною java.util.імпорту, тому я маю додати, що до підрахунку байтів я боюся, зробивши це 69 байт .. :(
Кевін Крейсейсен

3
Працював би -~(a^a)для 1?
Втілення невігластва

7

C (gcc) , 56 байт

d(a,b){return(sizeof((char)d))^__builtin_popcount(a^b);}

Спробуйте в Інтернеті!

Повертається, 0якщо пара відрізняється на 1, не дорівнює нулю інакше. Злегка незвично для C, якщо ви не вважаєте, що він повертається, EXIT_SUCCESSякщо пара відрізняється на 1, будь-яке інше значення в іншому випадку.

Використовує sizeof((char)d))для створення константи 1первозданним способом, одночасно змушуючи назву функції первозданною.

Тоді XOR, що 1 з попкодом XOR аргументів. На щастя, ^символ легко зберегти первозданним, як і дуже довгий ідентифікатор __builtin_popcount.

Тим часом, ось сценарій, який використовується для тестування рішення:

#!/bin/bash

SOURCE_FILE=$1
FOOT_FILE=$2
TMP_SRC=temp.c

LENGTH="$(wc -c <"$SOURCE_FILE")"
BITS=$((LENGTH*8))

cat "$SOURCE_FILE" >"$TMP_SRC"
cat "$FOOT_FILE" >>"$TMP_SRC"
if gcc -w $TMP_SRC -o t.out >/dev/null 2>&1; then
    if ./t.out; then
        echo "Candidate solution..."
    else
        echo "Doesn't even work normally..."
        exit
    fi
else
    echo "Doesn't even compile..."
    exit
fi

for i in $(seq 1 $BITS); do
    ./flipbit "$i" <"$SOURCE_FILE" >"$TMP_SRC"
    cat "$FOOT_FILE" >>"$TMP_SRC"
    if gcc -w $TMP_SRC -o t.out >/dev/null 2>&1; then
        echo "Testing flipped bit $i:"
        cat "$TMP_SRC"

        ./t.out >/dev/null 2>&1
        STATUS=$?
        if [ "$STATUS" -eq 0 ]; then
            echo "It works!"
            exit
        elif [ "$STATUS" -eq 1 ]; then
            echo "It doesn't work..."
            exit
        else
            echo "It crashes"
        fi
    fi
done

Який ./flipbitінструмент я написав, джерелом якого є просто:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int bittoflip = atoi(argv[1]) - 1;
    int ch;

    while ((ch = fgetc(stdin)) != EOF) {
        if (bittoflip < 8 && bittoflip >= 0) {
            putchar(ch ^ (1 << bittoflip));
        } else {
            putchar(ch);
        }

        bittoflip -= 8;
    }

    return 0;
}

Хитрі шматочки:

  • Пробіли: у всіх пробілах (включаючи нові рядки) є незаймані близнюки, які працюватимуть аналогічно
  • Порівняння: =не працює добре, оскільки може бути порівнянням у кожному випадку, коли воно може з’явитися. Так -само не працює добре. Таким чином ^використовується для ствердження рівності з 1.
  • Імена змінних: f зіткнеться з b, тому довелося замість цього використовувати d як ім'я функції.

Як ви тримаєте ^оператора незайманим? Якщо біти на цьому були змінені, що не дозволяє йому стати іншим оператором? Це все-таки складеться, але просто дасть неправильну відповідь. Я щось тут нерозумію щодо значення слова "незайманий"?
Коді Грей

4
Перегортаючи лише один біт, ^його можна змінити лише на будь-який _\ZVN~Þабо недрукований символ у кодовій точці 30. ~Єдиним із тих, що є оператором, але це лише одинарний оператор.
Непов’язана струна

1
Або навіть використовувати __LINE__замість sizeof(char). Я думаю, що добре вважати, що ваша функція буде знаходитись у рядку 1 вашого файлу .c. Або навіть unixвизначено 1 на TIO, і, мабуть, більшість інших Linux.
Цифрова травма

2
Основна причина розміщеного на графіку розміру полягає в тому, щоб dзапектися в джерело найменшими байтами. Інакше d(або як би ви не назвали цю функцію) можна просто змінити, і код все одно буде працювати. Навіть (__LINE__)при d();звичайній роботі, тому що d();її можна змінити на будь-яку іншу букву, і вона все одно буде компілюватися, оскільки функцію ніколи не потрібно викликати, тому вона не пов'язана.
LambdaBeta

1
@LambdaBeta Якщо назва функції зміниться, виникла помилка посилання, навіть якщо d не є самореференційною. Я думаю, цього достатньо, особисто.
Цифрова травма

7

R , 38 37 байт

-1 байт завдяки Ніку Кеннеді.

dpois(log2(bitwXor(scan(),scan())),T)

Спробуйте в Інтернеті! (Дякую Джузеппе, що правильно налаштував TIO.)

Доказ того, що це незаймане (за допомогою шашки Ніка Кеннеді ).

Вихідні показники 0 для фальси, і позитивне значення для truthy, яке, наскільки я розумію, є прийнятним, оскільки R буде інтерпретувати їх як False та True.

Пояснення: bitwXor(a,b)дає (як ціле число) побітовий XOR між aта b. Щоб перевірити, чи є потужність 2, перевірте, чи є її журнал у базі 2 цілим числом. Функція dpoisдає функцію щільності ймовірності розподілу Пуассона: її значення дорівнює 0 для не цілих значень, а щось позитивне для невід’ємних цілих чисел. Це Tє тому, що dpoisпотрібен другий аргумент (будь-який позитивний реальний твір і Tінтерпретується як 1).

Якщо ми наполягаємо на виведенні різних значень, наступна версія виводить FALSE або TRUE у 42 байти (завдяки Джузеппе за -8 байт):

dpois(log2(bitwXor(scan(),scan())),T)%in%F

а також незайманий . Спробуйте в Інтернеті!


2
Молодці, щоб отримати щось таке набагато менше, ніж моє! Ви могли б замінити piз , Tщоб зберегти байти ( до сих пір незаймані). Також ваш TIO наразі не відповідає вашій відповіді.
Нік Кеннеді

@NickKennedy Дякую! (І дякую, що написали код, щоб перевірити його незайманість!). TIO, до якого я пов’язаний, - це модифікована версія, яка перевіряє всі тестові випадки. Я додам TIO до фактичного коду, але не можу зрозуміти, як змусити TIO правильно працювати з двома дзвінками до scan(); у вас є ідея? (Код добре працює на комп’ютері.)
Робін Райдер

2
@NickKennedy Можливо, щось подібне? для отримання TIO та коду для відповідності?
Джузеппе

@Giuseppe Чудово, дякую!
Робін Райдер

1
Ваша друга версія може використовуватись Fзамість exp(-Inf)того ж, що і Ніка T:-)
Джузеппе

6

R , 83 байти

t(identical(sum(.<-as.double(intToBits(Reduce(bitwXor,scan())))),sum(T^el(.[-T]))))

Спробуйте в Інтернеті!

Доказ того, що це незаймане

Працюючи навколо того , що as.integer, і as.doubleт.д. є лише трохи від is.integer, і is.doubleт.д. був найважчий біт. Врешті-решт, найкраще, що я міг зробити , sum(T^el(.[-T])як спосіб генерування одиниці та перевірки as.doubleповернення вектора довжини> 1. Обгортка t- це впоратися з тим, що інакше identicalможе стати ide~tical.


5

Джулія 0,7 , 20 байт

(a,b)->ispow2(ab)

Спробуйте в Інтернеті!

Ось незайманий валідатор, який намагається запустити кожну модифіковану анонімну функцію проти деякого вводу, і жоден не проходить успішно. Зауважте, що код має багатобайтовий однокодовий символ, а деякі можливі виходи з бітового перегортання навіть не включаються, оскільки вони створюють недійсні рядки UTF-8.


xі yвони однакові, тому я вважаю, що це протилежний приклад. yі xтакож 1 раз відключені 9і 6відповідно.
Термін дії даних

Чорт, думаючи про складні речі, я абсолютно пропустив найпростіший. Сподіваємось, зміна змінних виправить це.
Кирило Л.


4

C # (Visual C # Interactive Compiler) , 128 101 77 70 61 74 байт

-27 байт завдяки Ascii-Only

a=>b=>{var d=Math.Log(a^b,(int)Math.E);return d.Equals((int)Math.Abs(d));}

Спробуйте в Інтернеті!

Ви повинні бути досить креативними, щоб отримувати номери в C #, не використовуючи літери. Використовує лише ^ оператор. Змінні a, b все більше, ніж на один біт, а все інше - це ключове слово / ім'я.


Вам не потрібно вважати біти - перевірка , якщо це сила 2 між 1 і 128 включно буде досить
ASCII-тільки

@ ASCII - лише удача, перевіривши це у розумній кількості байтів, коли ми не можемо використовувати цілі числа, ні +/*=для математичних чи перевіряючих операцій ;)
Кевін Круїссен

@KevinCruijssen C # теж має перерахунки :(. Damnit
лише для ASCII


1
O_o інший -24. btw ви більше не використовуєте+
лише для ASCII

3

JavaScript (ES6 в суворому режимі), 61 байт

(y,z,e)=>eval(`(y${(e='^=z)*!(y&~-y)')!='^=z)*!(y&~-y)'||e}`)

Спробуйте в Інтернеті! або Переконайтесь, що всі модифіковані програми неправильні


О мій боже, я не зрозумів, що натиснув на кодове посилання на гольф і побачив цю відповідь поза контекстом і мало не серцевий напад. Мовляв, OMG NO
Марі

4
@Marie Обережно! Ви можете дивитися на цей код лише сертифікованими очками для гольфу. В іншому випадку це може опік сітківки. : p
Арнольд


1

MATLAB, 37 байт

@(c,e)eq(nnz(de2bi(bitxor(c,e))),eye)

Вибачте, немає посилання TIO, тому що я не можу отримати тестовий набір для роботи під Octave. Дякуємо @ExpiredData за корисні коментарі.

Тестовий набір:

program = '@(c,e)eq(nnz(de2bi(bitxor(c,e))),eye)';
number_of_characters = nnz(program);
success = [];
for character_counter = 0 : number_of_characters
    for bit_no = 1:8
        prog_temp = program;
        if(character_counter > 0)
            prog_temp(character_counter) = bitxor(double(prog_temp(character_counter)),2^(bit_no-1));
        elseif(bit_no<8) % Test the unmodified program once
            continue
        end
        try
            eval(prog_temp);
            eval('ans(2,3)');
            disp(prog_temp)
            success(end+1)=1;   
        catch
            success(end+1)=0;
        end 
    end
end
assert(nnz(success)==1)


@ExpiredData Дякую за пропозицію. Я numelзамість цього поїхав на MATLAB , оскільки, схоже, мій тестовий набір не працює в Octave.
Санчіз

38 байт, можливо .. не отримав ліцензію на Matlab, але повинен працювати
Термін дії закінчився

1
@ExpiredData Спасибі, можна насправді зробити один байт краще eye!
Санчіз

1
@ExpiredData Я знаю, мене дуже дратує Октава. Але використання програми Python в коментарях до програми OP зручно зрозуміти, чи можна без проблем ввести нового персонажа.
Санчіз

1

Perl 6 , 77 43 байт

Завдяки Джо Кінгу за -33 байти.

{elems(i)eq(sum [+^](@_).polymod(+@_ xx*))}

Це еквівалентно

{1 eq(sum [+^](@_).polymod(2 xx*))}

1було переписано як elems([""]). 2було переписано як sum(elems([""]),elems([""])); elems(["",""])може здатися, що він працює, але elems([""-""])він також дійсний і, здається, висить тестер.

Спробуйте в Інтернеті!


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.