Найкоротший код для інвертування бітового рядка


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 є 1 і 0, це призводить до масиву 1s і0's (Вони не є рядками, і будь-який інший символ, окрім того 1, також може призвести до 0цього масиву.) Для цього не потрібно друкувати: J автоматично друкує результат вираження. Я сподіваюся, що це було адекватним поясненням, якщо ні, будь ласка, запитайте про щось, що ще не зрозуміло в коментарях. Ця відповідь також могла бути '0'&=(або =&'0'), але я вважав, що це b='0'було зрозуміліше.


1
Я спробував Дж. Не можу на це схилитися. Гадаю, я не знайшов хороших документів. Тут є +1 за те, що я був божевільним.
seequ

1
І тому я ніколи не буду користуватися Дж.
Qix

2
@Qix Як нечитабельний J, цей насправді має для мене сенс, а інші мови, у яких є оператори, які приймають векторний LHS та скалярний RHS, поводяться аналогічно.
hvd

1
Що? Це не повертає правильний результат, чи не так? Результатом повинен був стати текстовий рядок (без пробілів), але, з моїми обмеженими знаннями J, я думаю, що це поверне булевий список із формою відображення 0 1 0 1 0 ...
Adám

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 у кодовому питанні про гольф;)
Chris Cirefice

35

CJam - 4

q1f^

У цього xor кожен символ з 1.
На відміну від іншої відповіді CJam, я не припускаю, що вхід вже є в стеку.

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


2
Отже , так ви використовуєте f.
Денніс

@Dennis Дійсно. Ви можете скористатися форумом sf, щоб задати питання btw :)
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 для коду, мабуть, мало хто розуміє.
Кнерд

1
xchg dx,axна 1 байт коротший, ніжmov dl,al
ніндзя

@ninjalj: woa, дякую! Це все коротше!
Маттео Італія

26

Bash + coreutils, 8 байт

tr 01 10

Бере вхід від STDIN.


Або

sed, 8 байт

y/01/10/

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

1
Де тут бере участь BASH? Що конкретно BASH? Кожен снаряд може зателефонувати tr...
yeti

1
@yeti Не кожна оболонка викликає команди, такі як bash або zsh. У деяких оболонках цей код є лише синтаксичною помилкою
mniip

5
Напевно, можна припустити, що "оболонка" означає тут "сумісну з POSIX оболонкою" ...
FireFly

@professorfish ви збрили один шар, але потім додали 48, включивши функцію. Як це виграш?
Стівен Пенні

20

CJam , 4 байти

:~:!

Припускає, що початковий рядок вже є в стеку. Друкує змінений рядок.

Спробуйте в Інтернеті , вставивши наступний код :

"10101110101010010100010001010110101001010":~:!

Як це працює

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

  • :!обчислює логічне НЕ кожного цілого числа. Це перетворює "0" в "1" і "" на "1".


19

Мозговий ебать ( 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(вихід a, 1якщо у нас був 0, або a, 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
Як вам зручніше. Рекурсивне рішення не запитується, і, на мою думку, будь-який час, коли це можливо, ітеративне рішення краще, ніж рекурсивне. Приємно застосувати цей рекурсивний виклик до рядка 10k.
edc65

1
Оскільки кожен виклик, окрім останнього, є хвостовим рекурсивним викликом, я ставлю на облік, що компілятор перетворить його у цикл для повторного використання кадру стека.
мільйон

1
@millinon Доказ!
de0202392

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, інакше помилково. Розчин можна додатково зменшити до 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
Ya'know,(int(x) and 1) == int(x)
seequ

@TheRare Я не, дякую за це :)
Бассем

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

1
Здається, ви пропустили деякі місця. Крім того, зворотні посилання можна використовувати для заміни repr (). ''.join(`1-int(x)`for x in'')
seequ

1
Fyi, repr(x)для x <maxint дорівнюєstr(x)
seequ

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 символів.
Оріол

2
Мені подобається насправді виводити та вводити дані.
nderscore

@nderscore Збережіть 2 символи:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon

@GaurangTandon це має бути, (p=prompt)(p().replace(/./g,x=>x^1))і це така ж довжина.
nderscore

@nderscore Я теж вважав, що це саме так, але це діяло і без дужок, як не дивно.
Gaurang Tandon

7

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

(Лабіринт новіший за цей виклик, тому ця відповідь не конкурує - не те, що все одно виграє ...)

1,
.$@

Цей код передбачає, що STDIN містить лише цифри (зокрема, немає останнього рядка).

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

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

Якщо ... якщо ми ігноруємо STDERR, тобто дозволяємо закінчити помилку, ми можемо зберегти @і нам також не потрібен спосіб перемикання між двома шляхами. Ми просто продовжуємо читати та друкувати, поки ми випадково не спробуємо надрукувати негативне значення (the -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 і не думав про ці випадки. Тож так, що ваше рішення добре
Віллем

@willem Real легко забути про подібні речі. :)
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. Це дає вихід у вигляді списку, а не рядка.
ліртосіаст

3

Хаскелл, 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параметра для придушення нового рядка в кінці кожного друку. Крім того, згідно специфікації ОП, я думаю, мені все одно, що не буде пробілів. :) Дякую за коментар, хоча!
DLosc

Ау, класно, я цього не знав! Я в основному працюю в 2.7: /
Гаррі Бідл

2

J - 11 символів

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

'01'{~'0'&=

Я думаю, що ця відповідь технічно правильніша, ніж відповідь верхнього J, яка виводить булевий масив замість рядка.
гар

Я фактично не помічав J-рішення, що займає перше місце, коли я розміщував повідомлення (не знаю, як я пропустив це, але я це зробив). Справедливість до цього рішення прямо говорить: "це не робить те, що роблять інші рішення". До речі, ще один спосіб виразити це (буквальне виведення) рішення у 11 символів - це [:, ": @ = & '' 0 ''.
Ден Брон

Привіт, дякую за ще один код! Я буду вчитися більше J від вас, хлопці. Щодо цього твердження, я думаю, що він мав на увазі знак рівності, що він порівнює кожен предмет замість призначення.
гар

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.