Najkrótszy kod do odwrócenia bitowego ciągu binarnego


79

Myślę, że nie ma tu wystarczająco łatwych pytań, na które mogliby spróbować początkujący!

Wyzwanie: Biorąc pod uwagę losowy ciąg wejściowy 1 i 0 takich jak:

10101110101010010100010001010110101001010

Napisz najkrótszy kod, który wypisuje bitową odwrotność w następujący sposób:

01010001010101101011101110101001010110101

Odpowiedzi:


88

J, 5 bajtów

Zakłada, że ​​ciąg wejściowy jest zmienny b.

b='0'

To nie robi tego, co zrobiłby w większości języków ...

Operator porównania J jest po prostu =( =:i =.jest odpowiednio przypisaniem globalnym i lokalnym). Jednak =nie działa jak zwykły ==operator: porównuje element po elemencie. Należy pamiętać, że tablica jest tworzony tak: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 4daje 0 1 0 1 0 0 1 0 0na przykład. Jest to podobne do łańcucha: 'a'='abcadcadda'nie po prostu wrócić 0, zwraca 1 0 0 1 0 0 1 0 0 1(to można ekstrapolować na myśli 0z */, co w zasadzie oznacza all). W tym przypadku jednak, zachowanie to jest doskonała, ponieważ chcemy ciąg zer i jedynek, lub prawda i fałsz. Ponieważ boole J 1 i 0, wynikiem tego jest tablica 1i0(Nie są to ciągi znaków, a każda inna postać oprócz 1tej również spowodowałaby powstanie 0tej tablicy). Nie wymaga drukowania: J automatycznie drukuje wynik wyrażenia. Mam nadzieję, że to było odpowiednie wyjaśnienie, jeśli nie, poproś o coś, co nie jest jeszcze jasne w komentarzach. Ta odpowiedź również mogła być '0'&=(lub =&'0'), ale czułem, że b='0'była wyraźniejsza.


1
Próbowałem J. Nie mogę się na to zgodzić. Chyba nie znalazłem dobrych dokumentów. Tutaj masz +1 za bycie wariatem.
patrz

1
I dlatego nigdy nie
użyję

2
@Qix Choć J jest nieczytelny, ten ma dla mnie sens, a inne języki, w których operatory pobierają wektor LHS i skalarny RHS, zachowują się podobnie.
hvd

1
Co? Nie zwraca właściwego wyniku, prawda? Wynik powinien być ciągiem tekstowym (bez spacji), ale przy mojej ograniczonej znajomości J, myślę, że zwróci listę boolowską o formie wyświetlania 0 1 0 1 0 ...
Adám

4
Jest to niedozwolone, ponieważ nie można zakładać, że dane wejściowe są przechowywane w określonej zmiennej. =&'0'działa dla tej samej liczby bajtów.
Esolanging Fruit

43

GolfScript , 5 bajtów

{1^}%

Wypróbuj online.

Jak to działa

  • GolfScript odczytuje całe dane wejściowe ze STDIN i umieszcza je na stosie jako ciąg.

  • {}% przechodzi przez wszystkie znaki w ciągu i wykonuje blok kodu dla wszystkich z nich.

  • 1^ oblicza wyłączną OR dla znaków ASCII z 1. „0” odpowiada kodowi ASCII 48, „1” oznacza kod ASCII 49.

    Od 48 ^ 1 = 49i 49 ^ 1 = 48, to zmienia 0 na 1, a 1 na 0.

  • Po zakończeniu GolfScript drukuje zmodyfikowany ciąg.


6
Czekaj, skrypt golfowy ?
ToonAlfrink

Źle zinterpretowałem twoje pytanie. Naprawiono teraz.
Dennis

1
@tolos: Zredagowałem swoją odpowiedź.
Dennis

5
@ToonAlfrink Języki gry w golfa, takie jak GolfScript, są akceptowane we wszystkich wyzwaniach, o ile mają one charakter „ogólnego zastosowania”, co oznacza, że ​​nie są przeznaczone do konkretnych wyzwań.
kitcar2000

4
@ kitcar2000 Myślę, że był bardziej zaskoczony, że taki język istniał, niż szokiem kogoś, kto ośmiela się użyć GolfScript w pytaniu o kod golfa;)
Chris Cirefice

35

CJam - 4

q1f^

Ta xor to każda postać z 1.
W przeciwieństwie do innych odpowiedzi CJam, nie zakładam, że dane wejściowe są już na stosie.

Wypróbuj na http://cjam.aditsu.net/


2
Tak właśnie używasz f.
Dennis

@Dennis Indeed. Możesz użyć forum sf, aby zadawać pytania btw :)
aditsu

30

kod maszynowy x86 w systemie DOS - 14 13 11 bajtów

Cóż, znowu się skróciło! Po napisaniu rozwiązania niepowiązanego wyzwania zauważyłem, że tę samą sztuczkę można zastosować nawet tutaj. Więc zaczynamy:

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

Skomentowany montaż:

    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

Poprzednie rozwiązanie - 13 bajtów

Myślę, że nie jest dużo krótszy niż to.Tak się stało! Dzięki @ninjalj za wygolenie jeszcze jednego bajtu.

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

Ta wersja oferuje zaawansowaną interaktywność ™ - po uruchomieniu z wiersza poleceń wyrzuca „odwrócone” znaki, o ile piszesz cyfry wejściowe (które nie są powtarzane); aby wyjść, po prostu wykonaj Ctrl + C.

W przeciwieństwie do poprzedniego rozwiązania ma to pewne problemy z uruchomieniem w DosBox - ponieważ DosBox nie obsługuje poprawnie Ctrl-C , musisz zamknąć okno DosBox, jeśli chcesz wyjść. Zamiast tego działa na maszynie wirtualnej z systemem DOS 6.0 zgodnie z przeznaczeniem.

Źródło NASM:

org 100h

section .text

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

Stare rozwiązanie - 27 25 22 bajty

To zaakceptowało dane wejściowe z wiersza poleceń; działa płynnie jako plik .COM w 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                                 |...|..|

Wejście 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 za kod prawdopodobnie mało zrozumiały.
Knerd

1
xchg dx,axjest o 1 bajt krótszy niżmov dl,al
ninjalj 11.11.16

@ninjalj: woa, dziękuję! W końcu stało się krótsze!
Matteo Italia,

26

Bash + coreutils, 8 bajtów

tr 01 10

Pobiera dane wejściowe ze STDIN.


Lub

sed, 8 bajtów

y/01/10/

2
Niedawno stworzyłem bibliotekę golfową / zestaw aliasów dla Bash github.com/professorfish/bash-shelf . dzięki temu możesz ogolić jeden znak:y 01 10

1
Gdzie zaangażowana jest tutaj BASH? Co jest specyficzne dla BASH? Każda powłoka może zadzwonić tr...
yeti

1
@yeti Nie każda powłoka wywołuje polecenia takie jak bash lub zsh. W niektórych powłokach sam kod jest błędem składniowym
mniip

5
Prawdopodobnie bezpiecznie jest założyć, że „powłoka” oznacza tutaj „powłokę zgodną z POSIX” ...
FireFly

@professorfish golisz jeden znak, ale następnie dodajesz 48, włączając funkcję. Jak to jest zwycięstwo?
Steven Penny

20

CJam , 4 bajty

:~:!

Zakłada, że ​​oryginalny ciąg znaków znajduje się już na stosie. Wyświetla zmodyfikowany ciąg.

Wypróbuj online , wklejając następujący kod :

"10101110101010010100010001010110101001010":~:!

Jak to działa

  • :~ocenia każdy znak ciągu, tzn. zastępuje znak 0 liczbą całkowitą 0.

  • :!oblicza logiczne NIE dla każdej liczby całkowitej. To zmienia 0 na 1, a 1 na 0.


19

Brainfuck ( 70 71)

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

Wyjaśnienie:

>,[>,]                       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
++++++++ [<++++++> -] dlaczego nie dla 48? 8 * 6 vs. 4 * 4 * 3
Cruncher

@Cruncher Dodano.
kitcar2000

Dlaczego stało się dłużej? czy to z powodu „naprawy błędów”?
Cruncher

1
@Cruncher Tak, musiałem naprawić błąd, gdzie byłoby wyjście ana 11.
kitcar2000


11

Pancake Stack , 532 bajty

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 "".

Zakłada, że ​​wejście jest zakończone znakiem zerowym. Strategia jest następująca:

  • Weź charakter wejścia
  • Odejmij 1od niego wartość ascii .
  • Odejmij to od 0(dając a 1gdybyśmy mieli 0lub a 0gdybyśmy mieli 1)
  • Dodaj wartość ASCII 0do niego
  • Wydrukuj char.
  • Powtarzać

10

C: 29

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

Wypróbuj online tutaj .

Dzięki za wskazanie sztuczki XOR, Dennis.


8
Prostsze i krótsze:i(char*s){while(*s)*s++^=1;}
edc65

1
Dzięki, @ edc65! Nie zamierzam tego jednak używać, ponieważ jest to rozwiązanie iteracyjne, a nie rekurencyjne. Nie chciałbym tego przypisywać. Warto zauważyć, że wymieniając whilez forwynikami jeszcze o długości 28 znaków.
millinon

6
Jak wolisz. Rozwiązanie rekurencyjne nie jest wymagane i moim zdaniem, w każdym przypadku, gdy jest to możliwe, rozwiązanie iteracyjne jest lepsze niż rozwiązanie rekurencyjne. Baw się dobrze, stosując to rekurencyjne wywołanie do ciągu 10k.
edc65,

1
Ponieważ każde wywołanie, z wyjątkiem ostatniego, jest rekurencyjnym wywołaniem ogona, założę się, że kompilator przekształci go w pętlę, aby ponownie użyć ramki stosu.
millinon

1
@millinon Proof!
deed02392

9

Python 2.7 - 34 *

Och, jak bardzo ten pierwszy jest do bani. Całkiem brzydka, ta jest. 63 znaki.

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

Ten jest nieco lepszy, ale nadal nie jest tak fantazyjny. 44 znaki.

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

Ponieważ int(x) and 1zwraca, int(x)jeśli nie jest to 0, a inaczej False. Rozwiązanie można dodatkowo zredukować do 36 znaków.

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

Ponieważ join()pobiera generator, wsporniki można usunąć. 32 znaki.

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

Zamiast tego można zastosować backtyki str()

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

Zmniejszono do 44 z 34 dzięki wskaźnikom z @TheRare

Znalezienie uzupełnienia jest trudne w Pythonie, ponieważ bin(-int)zwraca -0bxxx stąd powyższe.


2
Wiesz,(int(x) and 1) == int(x)
patrz

@ TheRare Nie, dziękuję za to :)
Bassem

1
Dla przypomnienia: zero to fałsz, a niezerowe to prawda. Dla każdego rodzaju sekwencji (lista, ciąg ...) obowiązuje ta sama reguła, ale jest sprawdzana na podstawie długości sekwencji. Zatem '' == Falsei'hi' == True
patrz

1
Wygląda na to, że przegapiłeś jakieś spacje. Można również zastosować backticks w celu zastąpienia repr (). ''.join(`1-int(x)`for x in'')
patrz

1
Fyi, repr(x)dla x <maks. Jest równastr(x)
patrz

7

Perl, 9 znaków

'y/10/01/'

Dziewiąty znak to flaga „p”

Stosowanie:

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

2
działa również jako skrypt sed, y/10/01/ale o jeden znak krótszy, ponieważ nie wymaga żadnych flag

4
Nie potrzebujesz tutaj pojedynczych cytatów.
Konrad Borowski

7

JavaScript ( ES6 ) 36

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

Przy założeniu s, że s.replace(/./g,x=>x^1)są 22 znaki.
Oriol

2
Lubię właściwie wyprowadzać i wprowadzać dane.
nderscore

@nderscore Zapisz 2 znaki:p=prompt(p().replace(/./g,x=>x^1))
Gaurang Tandon

@GaurangTandon musiałby być (p=prompt)(p().replace(/./g,x=>x^1))i to jest tej samej długości.
nderscore

@nderscore Ja również myślałem, że tak jest, ale dziwnie zadziałało także bez nawiasu.
Gaurang Tandon

7

Labirynt , 6 bajtów

(Labirynt jest nowszy od tego wyzwania, więc ta odpowiedź nie konkuruje - nie dlatego, że i tak wygrywa ...)

1,
.$@

Ten kod zakłada, że ​​STDIN zawiera tylko cyfry (w szczególności brak znaku nowej linii).

Wskaźnik instrukcji (IP) zaczyna się w lewym górnym rogu, w prawo. Podczas gdy istnieją cyfry do odczytania, będzie on przechodził w ciasną pętlę przez lewy blok 2x2: 1naciśnij 1, ,przeczytaj cyfrę, $XOR z 1, aby przełączyć ostatni bit, .wydrukuj wynik. IP bierze tę pętlę, ponieważ górna część stosu jest dodatnia po XOR, tak że skręci w prawo. Gdy trafimy EOF, zamiast tego ,wraca -1. Wtedy XOR ustąpi, -2a przy tej wartości ujemnej IP skręci w lewo na @i program się zakończy.

To rozwiązanie powinno być optymalne dla Labiryntu: potrzebujesz ,i .dla pętli we / wy i @do zakończenia programu. Potrzebujesz co najmniej dwóch znaków (tutaj 1i $), aby przełączyć ostatni bit. I potrzebujesz przynajmniej jednej nowej linii dla pętli, która może zostać zakończona.

Chyba że ... jeśli zignorujemy STDERR, tzn. Zezwolimy na zakończenie z błędem, możemy zapisać plik @i nie potrzebujemy żadnego sposobu przełączania się między dwiema ścieżkami. Po prostu czytamy i drukujemy, dopóki przypadkowo nie spróbujemy wydrukować wartości ujemnej (the -2). Pozwala to na co najmniej dwa rozwiązania 5-bajtowe:

1,
.$
,_1$.



4

Python 2.x - 44 bajty

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

Po co go komplikować lub używać niektórych oszukańczych zmiennych?


Jego można zaoszczędzić jakieś dodatkowe znaki takie jak ten: print''.join('1-int(x)'for x in'input()'). Nie mogłem uzyskać tylnych zwrotów w kodzie komentarza, więc zastąpiłem je znakiem „.
Willem,

@willem W celu uzyskania informacji w przyszłości możesz uciec przed nimi ukośnikiem odwrotnym: `a\`b`-> a`b.
nyuszika7h

@willem To nie działa dla danych zaczynających się od 0 lub danych, które są większe niż maxint (w base10).
patrz

Dzięki @ nyuszika7h i nie myślałem o tych sprawach. Rzadko, więc twoje rozwiązanie jest dobre
Willem

@willem Naprawdę łatwo zapomnieć o takich rzeczach. :)
patrz

4

R, 27 znaków

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

Stosowanie:

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



3

TI-BASIC, 7 bajtów

Jest to funkcja, która pobiera ciąg binarny (przez Ans) jako dane wejściowe i zwraca dane wyjściowe jako ciąg odwrócony (nie odwrócony), jak określono. Aby uzyskać więcej pomocy, możesz przeczytać listę aplikacji przez not(na wiki TI-BASIC. Używam skompilowanej wersji, ponieważ jest mniejsza:

»*r>Õ¸r

W hex:

BB 2A 72 3E D5 B8 72

Wyjaśnienie

»*r - Weź wejście funkcji jako ciąg znaków i przekonwertuj na listę

> - Prześlij listę do kolejnych operatorów

Õ¸r - Zwraca odwrotność listy


jakie są wszystkie spacje na końcu »*r>Õ¸r ?
kitcar2000

@ kitcar2000 Ups, potem miałem HEX. Ale po przeniesieniu zapomniałem usunąć spacje ... Zrobiłem to teraz.
Timtech

Warto zauważyć, że: 1. Na kalkulatorze jest to wyświetlane jako expr(Ans:Returnnot(Ans; 2. Ponieważ ciąg nie jest oddzielony przecinkami i nie zaczyna się od a {, będzie ewaluowany do liczby całkowitej takiej jak 1000010011, a nie listy; 3. Returnnie działa tak, jak to napisałeś; 4. Daje to wynik jako listę, a nie ciąg.
lirtosiast

3

Haskell, 22 bajty

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

Byłem zaskoczony brakiem rozwiązań Haskell do tego wyzwania, więc oto jedno. Zwraca wartość do funkcji, która pobiera ciąg znaków i zwraca jego odwrotność.

Wyjaśnienie

Nic szczególnego tutaj.

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 bajtów

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

Zakładając, że pusty stos i EOF zarówno czytają -1.

0 wypycha \ 0 jako terminator zerowy

>~1+:#v_ jest pętlą wejściową, odczytuje ascii, dodaje 1, sprawdza EOF + 1 = 0,

^ -1< w przeciwnym razie odejmuje 1 i pozostawia wypchniętą wartość ascii na stosie.

$>:#,_@ upuszcza dodatkową kopię zera na stos, a następnie drukuje ciąg binarny od góry do dołu

Jeśli pusty stos ma wartość 0, zapisz 2 bajty za pomocą

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

Możliwe jest wykonanie około 15 bajtów przy użyciu tego samego algorytmu, jeśli EOF = 0, ale nie mam takiej implementacji przydatnej do przetestowania.




2

Python3, 39

Methinks Python nie jest najlepszym językiem do tego. :)

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

Jeśli zależy ci na nowej linii po wyjściu, oto 43-znakowa alternatywa:

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

Kod będzie działać bez end=''prostu ,zrobi :) - jeśli nie dbają o nie będąc bez spacji
Harry Beadle

@BritishColour, nie, to jest Python2. Funkcja Python3 printwymaga dostrajania endparametru, aby ukryć nowy wiersz na końcu każdego wydruku. Ponadto, zgodnie ze specyfikacją OP, myślę, że zależy mi na tym, aby nie było spacji. :) Ale dziękuję za komentarz!
DLosc

Aww, spoko, nie wiedziałem o tym! Pracuję głównie w wersji 2.7: /
Harry Beadle

2

J - 11 znaków

Wartości logiczne w J są reprezentowane jako liczby całkowite 0i 1, które oczywiście są również poprawnymi indeksami w tablicach (w tym przypadku tablica 2-znakowa '01')

'01'{~'0'&=

Myślę, że ta odpowiedź jest technicznie bardziej poprawna niż górna odpowiedź J, która generuje tablicę boolowską zamiast ciągu.
gar

Właściwie nie zauważyłem najlepszego rozwiązania J, kiedy pisałem (nie wiem, jak to przegapiłem, ale tak zrobiłem). Aby być sprawiedliwym wobec tego rozwiązania, wyraźnie mówi „nie robi to, co robią inne rozwiązania”. BTW, innym sposobem wyrażenia tego (dosłownego wyjścia) rozwiązania w 11 znakach jest [:, ": @ = & '' 0 ''.
Dan Bron

Cześć, dzięki za kolejny kod! Będę uczyć się więcej J od was. Jeśli chodzi o to stwierdzenie, myślę, że miał na myśli znak równości, że porównuje on każdą pozycję zamiast przypisania.
gar

2

C #, 131 bajtów

Trochę późno na przyjęcie, ale tu jest moje. :)

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 bajtów

@(x)[97-x '']

Po uruchomieniu powyższego wywołaj funkcję z łańcuchem wejściowym, aby uzyskać odwrócony ciąg. Na przykład bieganie:

ans('10101110101010010100010001010110101001010')

drukuje:

01010001010101101011101110101001010110101

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.