Самый короткий код для побитового преобразования двоичной строки


79

Я думаю, что здесь нет достаточно простых вопросов, которые могут попробовать новички!

Задача: задана случайная входная строка из 1 и 0, например:

10101110101010010100010001010110101001010

Напишите кратчайший код, который выводит побитовую инверсию, вот так:

01010001010101101011101110101001010110101

Ответы:


88

J, 5 байт

Предполагается, что входная строка находится в переменной b.

b='0'

Это не делает то, что было бы на большинстве языков ...

Оператор сравнения J просто =( =:и =.это глобальное и локальное присваивание соответственно). Однако, =он не работает как обычный ==оператор: он сравнивает элемент за элементом. Имейте в виду , что массив формируется следующим образом: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 4дает 0 1 0 1 0 0 1 0 0например. Это похоже на строку: 'a'='abcadcadda'не просто возвращает 0, она возвращает 1 0 0 1 0 0 1 0 0 1(Это может быть экстраполировано, чтобы означать 0с */, что в основном означает all.) В этом случае, однако, это поведение превосходно, так как нам нужна строка из единиц и нулей, или правда и ложь. Поскольку J's bools есть 1 и 0, это приводит к массиву 1's и0's (Они не являются строками, и любой другой символ, кроме того, который 1может 0привести к появлению в этом массиве.) Это не требует печати: J автоматически печатает результат выражения. Я надеюсь, что это было адекватное объяснение, если нет, пожалуйста, попросите что-то, что еще не ясно в комментариях. Этот ответ также мог бы быть '0'&=(или =&'0'), но я чувствовал, что это b='0'было яснее.


1
Я пытался Дж. Не могу смириться с этим. Думаю, я не нашел хороших документов. Здесь есть +1 для того, чтобы быть сумасшедшим.
Seequ

1
И именно поэтому я никогда не буду использовать J.
Qix

2
@Qix Несмотря на то, что J не читается, этот язык на самом деле имеет для меня смысл, и другие языки, в которых есть операторы, использующие вектор LHS и скалярную RHS, ведут себя аналогично.
14:02

1
Какая? Это не возвращает правильный результат, не так ли? Результатом должна была стать текстовая строка (без пробелов), но,
учитывая

4
Это недопустимо, потому что вы не можете предполагать, что вход хранится в определенной переменной. =&'0'работает на такое же количество байтов.
Esolanging Fruit

43

GolfScript , 5 байт

{1^}%

Попробуйте онлайн.

Как это устроено

  • GolfScript читает весь ввод из STDIN и помещает его в стек в виде строки.

  • {}% проходит через все символы в строке и выполняет блок кода для всех них.

  • 1^ вычисляет исключающее ИЛИ символов ASCII-кода с 1. «0» соответствует ASCII-коду 48, «1» - ASCII-коду 49.

    Так как 48 ^ 1 = 49и 49 ^ 1 = 48это превращает 0 в 1 и 1 в 0.

  • После завершения GolfScript печатает измененную строку.


6
Подожди, сценарий для гольфа ?
ToonAlfrink

Я неверно истолковал ваш вопрос. Исправлено сейчас.
Деннис

1
@tolos: я отредактировал свой ответ.
Деннис

5
@ToonAlfrink Языки игры в гольф, такие как GolfScript, принимаются во всех задачах, если они являются «универсальными», что означает, что они не предназначены для конкретных задач.
kitcar2000

4
@ kitcar2000 Я думаю, что он был более удивлен, что такой язык существовал, а не шокировал кого-то, кто осмелился использовать GolfScript в вопросе о коде в гольф;)
Крис Сирфице

35

CJam - 4

q1f^

В этом xor каждый символ с 1.
В отличие от другого ответа CJam, я не предполагаю, что ввод уже находится в стеке.

Попробуйте это на http://cjam.aditsu.net/


2
Так вот как вы используете f.
Деннис

@ Деннис Действительно. Вы можете использовать форум sf, чтобы задавать вопросы между прочим :)
aditsu

30

машинный код x86 на DOS - 14 13 11 байт

Ну, это снова стало короче! После написания решения для несвязанного вызова я заметил, что тот же трюк можно применить даже здесь. Итак, поехали:

00000000  b4 08 cd 21 35 01 0a 86  c2 eb f7                 |...!5......|
0000000b

Комментируемая сборка:

    org 100h

section .text

start:
    mov ah,8        ; start with "read character with no echo"
lop:
    ; this loop runs twice per character read; first with ah=8,
    ; so "read character with no echo", then with ah=2, so
    ; "write character"; the switch is performed by the xor below
    int 21h         ; perform syscall
    ; ah is the syscall number; xor with 0x0a changes 8 to 2 and
    ; viceversa (so, switch read <=> write)
    ; al is the read character (when we did read); xor the low
    ; bit to change 0 to 1 and reverse
    xor ax,0x0a01
    mov dl,al       ; put the read (and inverted character) in dl,
                    ; where syscall 2 looks for the character to print
    jmp lop         ; loop

Предыдущее решение - 13 байт

Я думаю, что это не становится намного короче, чем это.На самом деле, это сделал! Спасибо @ninjalj за то, что сбрил еще один байт.

00000000  b4 08 cd 21 34 01 92 b4  02 cd 21 eb f3           |...!4.....!..|
0000000d

В этой версии реализована расширенная интерактивность ™ - после запуска из командной строки она выплевывает «перевернутые» символы до тех пор, пока вы пишете входные цифры (которые не отображаются); чтобы выйти, просто нажмите Ctrl-C.

В отличие от предыдущего решения, в DosBox возникают некоторые проблемы - поскольку DosBox не поддерживает правильно Ctrl-C , вы вынуждены закрыть окно DosBox, если хотите выйти. Вместо этого в виртуальной машине с DOS 6.0 она работает так, как задумано.

NASM источник:

org 100h

section .text

start:
    mov ah,8
    int 21h
    xor al,1
    xchg dx,ax
    mov ah,2
    int 21h
    jmp start

Старое решение - 27 25 22 байта

Это приняло его ввод из командной строки; работает как файл .COM в DosBox.

00000000  bb 01 00 b4 02 8a 97 81  00 80 f2 01 cd 21 43 3a  |.............!C:|
00000010  1e 80 00 7c f0 c3                                 |...|..|

Вход NASM:

    org 100h

section .text

start:
    mov bx, 1
    mov ah, 2
loop:
    mov dl, byte[bx+81h]
    xor dl, 1
    int 21h
    inc bx
    cmp bl, byte[80h]
    jl loop
exit:
    ret

2
+1 за код наверное не многие понимают.
Knerd

1
xchg dx,axна 1 байт меньше, чемmov dl,al
ninjalj

@ninjalj: Воу, спасибо! Он сделал все короче в конце концов!
Matteo Italia

26

Bash + coreutils, 8 байт

tr 01 10

Принимает участие от STDIN.


Или же

sed, 8 байт

y/01/10/

2
Недавно я создал библиотеку / псевдоним для игры в гольф для Bash github.com/profestivalfish/bash-shelf . Вы можете сбрить один символ с этим:y 01 10

1
Где здесь задействован BASH? Что такое BASH? Каждый снаряд может звонить tr...
Йети

1
@yeti Не каждая оболочка вызывает такие команды, как bash или zsh. В некоторых оболочках один только этот код является синтаксической ошибкой
mniip

5
Вероятно, можно с уверенностью предположить, что «shell» означает здесь «POSIX-совместимую оболочку» ...
FireFly

@professfishfish вы сбриваете один символ, но затем добавляете 48, включая функцию. Как это победа?
Стивен Пенни

20

CJam , 4 байта

:~:!

Предполагается, что исходная строка уже находится в стеке. Печатает измененную строку.

Попробуйте онлайн , вставив следующий код :

"10101110101010010100010001010110101001010":~:!

Как это устроено

  • :~оценивает каждый символ строки, т. е. заменяет символ 0 на целое число 0.

  • :!вычисляет логическое НЕ каждого целого числа. Это превращает 0 в 1 и 1 в 0.


19

Brainfuck ( 70 71)

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

Объяснение:

>,[>,]                       Read characters until there are none left.
<[<]                         Return to start
>[<                          Loop as long as there are characters to invert
  +++++++[>-------<-]        Subtract 49 (ASCII value of 1)
  >[++<]                     If not 0, add 2
  +++[<++++>-]<[>>++++<<-]>> Add 48
  .                          Print
  [-]                        Set current cell to 0
>]                           Loop

1
++++++++ [<++++++> -] почему бы не это за 48? 8 * 6 против 4 * 4 * 3
Cruncher

@Cruncher Добавлено.
kitcar2000

Почему это стало длиннее? это из-за "исправления ошибок"?
Cruncher

1
@Cruncher Да, я должен был исправить ошибку , где он будет выводить aна 11.
kitcar2000


11

Стек блин , 532 байта

Put this tasty pancake on top!
[]
Put this delicious pancake on top!
[#]
Put this  pancake on top!
How about a hotcake?
If the pancake is tasty, go over to "#".
Eat all of the pancakes!
Put this supercalifragilisticexpialidociouseventhoughtheso pancake on top!
Flip the pancakes on top!
Take from the top pancakes!
Flip the pancakes on top!
Take from the top pancakes!
Put this supercalifragilisticexpialidociouseventhoughthes pancake on top!
Put the top pancakes together!
Show me a pancake!
If the pancake is tasty, go over to "".

Предполагается, что ввод завершается нулевым символом. Стратегия заключается в следующем:

  • Взять символ ввода
  • Вычтите из этого значение ascii 1.
  • Вычтите это из 0(получая, 1если у нас было 0, или 0если у нас было 1)
  • Добавьте значение ASCii из 0к нему
  • Распечатать символ
  • Повторение

10

С: 29

i(char*s){*s^=*s?i(s+1),1:0;}

Попробуйте это онлайн здесь .

Спасибо, что указал на трюк с XOR, Деннис.


8
Проще и короче:i(char*s){while(*s)*s++^=1;}
edc65

1
Спасибо, @ edc65! Я не собираюсь этим пользоваться, поскольку это итеративное, а не рекурсивное решение. Я не хотел бы брать кредит на это. Стоит отметить , что замена whileс forеще результатами длиной 28 символов.
Миллинон

6
Как ты предпочитаешь. Рекурсивное решение не требуется, и, на мой взгляд, в любое время, когда это возможно, итеративное решение лучше, чем рекурсивное. Получайте удовольствие, применяя этот рекурсивный вызов к строке 10 КБ.
edc65

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

1
@millinon Доказательство!
deed02392

9

Python 2.7 - 34 *

Ох, сколько это первый отстой. Довольно некрасиво это 63 символа

print''.join([bin(~0)[3:] if x == '0' else bin(~1)[4:] for x in ''])

Этот немного лучше, но все же не такой модный. 44 символа

print''.join([str(int(not(int(x)))) for x in ''])

Так как int(x) and 1возвращается, int(x)если это не 0 и в противном случае False. Решение может быть дополнительно уменьшено до 36 символов.

print''.join([str(1-int(x)) for x in ''])

Поскольку join()берет генератор, скобки могут быть удалены. 32 символа

print''.join(str(1-int(x))for x in'')

И галочки могут быть использованы вместо str()

print''.join(`1-int(x)`for x in'')

Уменьшено до 44 с 34 благодаря указателям из @TheRare

Найти комплимент в Python сложно, так как bin(-int)возвращает -0bxxx, следовательно, и выше.


2
Я знаю,(int(x) and 1) == int(x)
seequ

@TheRare Я не сделал, спасибо за это :)
Bassem

1
Для записи: ноль - это ложь, а ненулевое - это правда. Для любой последовательности (список, строка ...) применяется то же правило, но оно проверяется по длине последовательности. Таким образом '' == Falseи'hi' == True
seequ

1
Похоже, вы пропустили некоторые пробелы. Кроме того, для замены repr () можно использовать обратные галочки. ''.join(`1-int(x)`for x in'')
Seequ

1
К repr(x)str(x)
вашему сведению

7

Perl, 9 символов

'y/10/01/'

9-й символ - это флаг 'p'

Использование:

$ echo '10101001' | perl -pe 'y/10/01/'

2
также работает как скрипт sed, y/10/01/но на один символ короче, потому что ему не нужны флаги

4
Вам не нужны одинарные кавычки здесь.
Конрад Боровски

7

Javascript ( ES6 ) 36

alert(prompt().replace(/./g,x=>x^1))

Предполагая ввод s, s.replace(/./g,x=>x^1)22 символа.
Oriol

2
Мне нравится на самом деле вывод и ввод.
nderscore

@nderscore Сохранить 2 символа:p=prompt(p().replace(/./g,x=>x^1))
Гауранг Тандон

@GaurangTandon это должно быть, (p=prompt)(p().replace(/./g,x=>x^1))и это такая же длина.
nderscore

@nderscore Я тоже думал, что так и будет, но, как ни странно, тоже без скобок.
Гауранг Тандон

7

Лабиринт , 6 байт

(Лабиринт новее, чем этот вызов, поэтому этот ответ не конкурирует - не то, что он все равно выигрывает ...)

1,
.$@

Этот код предполагает, что STDIN содержит только цифры (в частности, нет завершающего перевода строки).

Указатель инструкций (IP) начинается в верхнем левом углу и идет вправо. В то время как есть цифры для чтения, он будет циклически проходить по левому блоку 2x2: 1нажмите 1, ,прочитайте цифру, $XOR с 1, чтобы переключить последний бит, .напечатайте результат. IP принимает этот цикл, потому что вершина стека положительна после XOR, так что он будет поворачивать направо. Когда мы нажимаем EOF, вместо этого ,возвращается -1. Тогда XOR даст, -2и с этим отрицательным значением IP повернет налево на @и программа завершится.

Это решение должно быть оптимальным для Лабиринта: вам нужно ,и .для цикла ввода-вывода, и @для завершения программы. Вам нужно как минимум два символа (здесь 1и $) для переключения последнего бита. И вам нужен хотя бы один символ новой строки для цикла, который можно завершить.

Если ... если мы игнорируем STDERR, то есть разрешаем завершение с ошибкой, мы можем сохранить @и нам также не нужен способ переключения между двумя путями. Мы просто продолжаем читать и печатать, пока не попытаемся случайно напечатать отрицательное значение ( -2). Это позволяет использовать как минимум два 5-байтовых решения:

1,
.$
,_1$.


5

Код машины Тьюринга, 32 байта (1 состояние - 3 цвета)

Использование синтаксиса таблицы правил, требуемого этим онлайн-симулятором TM. Заимствовано из сообщения, которое я сделал в своем блоге пользователя Googology Wiki несколько месяцев назад.

0 0 1 r *
0 1 0 r *
0 _ _ * halt

Вы также можете проверить это, используя эту реализацию Java.


4

Python 2.x - 44 байта

print''.join(`1-int(x)`for x in raw_input())

Зачем делать это сложным или использовать некоторые обманчивые переменные?


Его можно сохранить некоторые дополнительные символы , как это: print''.join('1-int(x)'for x in'input()'). Я не мог получить обратные пометки в коде комментария, поэтому заменил их на '.
Виллем

@willem Для дальнейшего использования вы можете избежать обратной косой черты: `a\`b`-> a`b.
nyuszika7h

@willem Это не работает для ввода, начинающегося с 0, или ввода, который больше, чем maxint (в base10).
seequ

Спасибо @ nyuszika7h и не думал об этих случаях TheRare, так что ваше решение хорошо
Виллем

@ Willem Очень легко забыть о таких вещах. :)
seequ

4

R, 27 символов

chartr("01","10",scan(,""))

Использование:

> chartr("01","10",scan(,""))
1: 10101110101010010100010001010110101001010
2: 
Read 1 item
[1] "01010001010101101011101110101001010110101"



3

TI-BASIC, 7 байтов

Это функция, которая принимает двоичную строку (сквозную Ans) в качестве входных данных и возвращает выходные данные в виде инвертированной (не обращенной) строки, как указано. Для получения дополнительной помощи вы можете прочитать список приложений not(на вики-сайте TI-BASIC. Я использую скомпилированную версию, потому что она меньше:

»*r>Õ¸r

В шестнадцатеричном виде:

BB 2A 72 3E D5 B8 72

объяснение

»*r - Возьмите ввод функции как строку и конвертируйте в список

> - передать данный список следующим операторам

Õ¸r - вернуть обратный список


каковы все места в конце »*r>Õ¸r ?
kitcar2000

@ kitcar2000 Ой, у меня был HEX после этого. Но после того, как я переместил его, я забыл удалить пробелы ... Я сделал это сейчас.
Timtech

Следует отметить, что: 1. На калькуляторе это отображается как expr(Ans:Returnnot(Ans; 2. Поскольку строка не разделена запятыми и не начинается с {, она будет вычисляться как целое число, например 1000010011, а не как список; 3. Returnне работает так, как вы это написали; 4. Это дает вывод в виде списка, а не строки.
lirtosiast

3

Haskell, 22 байта

map(\c->"10"!!read[c])

Я был удивлен отсутствием решений Haskell для этой задачи, так что вот один. Он оценивает функцию, которая принимает строку и возвращает ее инверсию.

объяснение

Здесь нет ничего особенного.

map(\c->             )  -- For each character c in the input string:
                  [c]   -- wrap c into a string,
              read      -- convert to integer,
        "10"!!          -- and index the string "10" with it.

3

Befunge 93, 25 байт

0>~1+:#v_$>:#,_@
 ^   -1<

Предполагая, что пустой стек и EOF оба читают -1.

0 толкает \ 0 как нулевой терминатор

>~1+:#v_ это цикл ввода, он читает ascii, добавляет 1, проверяет EOF + 1 = 0,

^ -1< else вычитает 1 и оставляет заданное значение ascii в стеке.

$>:#,_@ сбрасывает лишнюю копию нуля сверху стека, затем печатает двоичную строку сверху вниз

Если пустой стек читает 0, сохраните 2 байта с

>~:1+#v_$>:#,_@
^   -1<

Возможна версия около 15 байтов с использованием этого же алгоритма, если EOF = 0, но у меня нет такой реализации, с которой можно было бы тестировать.




2

Python3, 39

Methinks Python - не лучший язык для этого. :)

for i in input():print(1-int(i),end='')

Если вас интересует наличие новой строки после вывода, вот альтернатива из 43 символов:

print(''.join("01"[i<"1"]for i in input()))

Код будет работать без end=''единой ,воли :) - если вы не заботитесь об отсутствии пробелов
Гарри Бидл

@BritishColour, нет, это Python2. Функция Python3 printтребует настройки endпараметра для подавления новой строки в конце каждой печати. Кроме того, в соответствии со спецификацией OP, я думаю, что меня волнует отсутствие пробелов. :) Спасибо за комментарий, хотя!
DLosc

Оу, круто, я этого не знал! Я в основном работаю в 2.7: /
Гарри Бидл

2

J - 11 символов

Логические значения в J представлены в виде целых чисел 0и 1, конечно, также являются допустимыми индексами в массивах (в данном случае это 2-символьный массив '01')

'01'{~'0'&=

Я думаю, что этот ответ технически более корректен, чем ответ в верхнем J, который выводит логический массив вместо строки.
Гар

Я действительно не заметил топ-решение J, когда я написал (не знаю, как я пропустил, но я сделал). Чтобы быть справедливым по отношению к этому решению, оно прямо говорит: «это не делает то, что делают другие решения». Кстати, еще один способ выразить это (буквальный вывод) решение в 11 символов: [:, ": @ = & '' 0 ''.
Дэн Брон

Привет, спасибо за другой код! Я буду больше учиться у вас, ребята. Что касается этого утверждения, я думаю, что он имел в виду знак равенства, который сравнивает каждый элемент вместо назначения.
Гар

2

C #, 131 байт

Немного опоздал на вечеринку, но вот мой. :)

using System;class R{static void Main(string[]a){foreach(var v in a[0].ToCharArray()){Console.Write(int.Parse(v.ToString())^1);}}}

2

MATLAB, 13 байт

@(x)[97-x '']

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

ans('10101110101010010100010001010110101001010')

печатает:

01010001010101101011101110101001010110101

2

BotEngine , 4x8 = 32

Неконкурентоспособен, так как язык ставит вопрос на задний план.

Iv2 0 12
 >e>S SS
    e1e0
   ^< <P

С подсветкой:

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.