Kode terpendek untuk membalik bit-wise string biner


79

Saya pikir tidak ada cukup pertanyaan mudah di sini yang bisa dicoba oleh pemula!

Tantangannya: Diberikan string input acak 1 dan 0 seperti:

10101110101010010100010001010110101001010

Tulis kode terpendek yang menghasilkan invers bit-wise seperti:

01010001010101101011101110101001010110101

Jawaban:


88

J, 5 byte

Mengasumsikan string input dalam variabel b.

b='0'

Ini tidak melakukan apa yang akan dilakukan di sebagian besar bahasa ...

Operator perbandingan J adil =( =:dan =.masing-masing adalah penugasan global dan lokal). Namun, =tidak berfungsi seperti ==operator normal : ia membandingkan item per item. Perlu diingat bahwa sebuah array terbentuk seperti ini: 0 2 3 2 3 1 2 3 4. 2 = 0 2 3 2 3 1 2 3 4memberi 0 1 0 1 0 0 1 0 0misalnya. Ini mirip untuk sebuah string: 'a'='abcadcadda'tidak hanya mengembalikan 0, ia mengembalikan 1 0 0 1 0 0 1 0 0 1(Ini dapat diekstrapolasi untuk diartikan 0dengan */, yang pada dasarnya berarti all.) Namun dalam kasus ini, perilaku ini sangat baik, karena kami ingin string yang satu dan nol, atau benar dan salah. Karena bools J adalah 1 dan 0, ini menghasilkan array 1's dan0's (Mereka bukan string, dan setiap karakter selain selain 1juga akan menghasilkan dalam 0array ini.) Ini tidak perlu dicetak: J secara otomatis mencetak hasil ekspresi. Saya harap ini penjelasan yang memadai, jika tidak, silakan meminta sesuatu yang belum jelas di komentar. Jawaban ini juga bisa saja '0'&=(atau =&'0'), tetapi saya merasa b='0'itu lebih jelas.


1
Saya sudah mencoba J. Tidak bisa membengkokkan pikiran saya untuk itu. Kira saya belum menemukan dokumen yang bagus. Di sini, dapatkan +1 untuk menjadi orang gila.
seequ

1
Dan inilah mengapa saya tidak akan pernah menggunakan J.
Qix

2
@Qix Tidak terbaca seperti J, yang ini benar-benar masuk akal bagi saya, dan bahasa lain yang memiliki operator yang mengambil LHS vektor dan RHS skalar berperilaku sama.
hvd

1
Apa? Itu tidak mengembalikan hasil yang benar, bukan? Hasilnya seharusnya berupa string teks (tanpa spasi), tetapi dengan pengetahuan saya yang terbatas tentang J, saya pikir ini akan mengembalikan daftar boolean dengan bentuk tampilan 0 1 0 1 0 ...
Ad

4
Ini tidak diizinkan karena Anda tidak dapat menganggap input disimpan dalam variabel tertentu. =&'0'bekerja untuk jumlah byte yang sama.
Buah Esolanging

43

GolfScript , 5 byte

{1^}%

Cobalah online.

Bagaimana itu bekerja

  • GolfScript membaca seluruh input dari STDIN dan menempatkannya di tumpukan sebagai string.

  • {}% menelusuri semua karakter dalam string dan mengeksekusi blok kode untuk semuanya.

  • 1^ menghitung AT atau karakter eksklusif dari kode ASCII dengan 1. “0” sesuai dengan kode ASCII 48, “1” ke kode ASCII 49.

    Sejak 48 ^ 1 = 49dan 49 ^ 1 = 48, ini mengubah 0 menjadi 1 dan 1 menjadi 0.

  • Setelah selesai, GolfScript mencetak string yang dimodifikasi.


6
Tunggu, skrip golf ?
ToonAlfrink

Saya telah salah mengartikan pertanyaan Anda. Diperbaiki sekarang
Dennis

1
@tolos: Saya sudah mengedit jawaban saya.
Dennis

5
@ToonAlfrink Bahasa golf seperti GolfScript diterima di semua tantangan, asalkan 'tujuan umum' yang berarti bahwa mereka tidak dirancang untuk tantangan khusus.
kitcar2000

4
@ kitcar2000 Saya pikir dia lebih terkejut bahwa bahasa seperti itu ada, daripada kaget seseorang yang berani menggunakan GolfScript dalam pertanyaan kode golf;)
Chris Cirefice

35

CJam - 4

q1f^

Ini untuk setiap karakter dengan 1.
Tidak seperti jawaban CJam lainnya, saya tidak menganggap input sudah ada di stack.

Cobalah di http://cjam.aditsu.net/


2
Jadi begitulah cara Anda menggunakannya f.
Dennis

@Dennis Memang. Anda dapat menggunakan forum sf untuk mengajukan pertanyaan btw :)
aditsu

30

kode mesin x86 pada DOS - 14 13 11 byte

Ya, memang jadi lebih pendek lagi! Setelah menulis solusi untuk tantangan yang tidak terkait , saya perhatikan bahwa trik yang sama dapat diterapkan bahkan di sini. Jadi di sini kita mulai:

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

Majelis yang dikomentari:

    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

Solusi sebelumnya - 13 byte

Saya pikir tidak jauh lebih pendek dari ini.Sebenarnya, itu benar! Terima kasih kepada @ninjalj karena telah mengurangi satu byte lagi.

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

Versi ini memiliki fitur interaktivitas lanjutan ™ - setelah menjalankannya dari baris perintah, ia mengeluarkan karakter "terbalik" selama Anda menulis digit input (yang tidak digaungkan); untuk keluar, cukup lakukan Ctrl-C.

Tidak seperti solusi sebelumnya, ini memiliki beberapa masalah dalam menjalankan DosBox - karena DosBox tidak mendukung Ctrl-C dengan benar , Anda terpaksa menutup jendela DosBox jika Anda ingin keluar. Dalam VM dengan DOS 6.0, sebagai gantinya, itu berjalan seperti yang dimaksudkan.

Sumber NASM:

org 100h

section .text

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

Solusi lama - 27 25 22 byte

Ini menerima inputnya dari baris perintah; berjalan dengan lancar sebagai file .COM di 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                                 |...|..|

Input 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 untuk kode mungkin tidak banyak mengerti.
Knerd

1
xchg dx,axlebih pendek 1 byte darimov dl,al
ninjalj

@ninjalj: woa, terima kasih! Itu memang semakin pendek!
Matteo Italia

26

Bash + coreutils, 8 byte

tr 01 10

Mengambil input dari STDIN.


Atau

sed, 8 byte

y/01/10/

2
Saya baru-baru ini membuat perpustakaan golf / alias ditetapkan untuk Bash github.com/professorfish/bash-shelf . Anda dapat mencukur satu char dengan itu:y 01 10

1
Di mana BASH terlibat di sini? Apa yang spesifik dengan BASH? Setiap shell dapat memanggil tr...
yeti

1
@ yeti Tidak semua shell memanggil perintah seperti bash atau zsh. Dalam beberapa shell, kode itu saja merupakan kesalahan sintaksis
mniip

5
Mungkin aman untuk berasumsi bahwa "shell" berarti "shell yang kompatibel dengan POSIX" di sini ...
FireFly

@profesional Anda mencukur satu char, tetapi kemudian menambahkan 48 dengan memasukkan fungsi. Bagaimana itu menang?
Steven Penny

20

CJam , 4 byte

:~:!

Mengasumsikan string asli sudah ada di tumpukan. Mencetak string yang dimodifikasi.

Cobalah online dengan menempelkan Kode berikut :

"10101110101010010100010001010110101001010":~:!

Bagaimana itu bekerja

  • :~mengevaluasi setiap karakter string, yaitu, menggantikan karakter 0 dengan integer 0.

  • :!menghitung TIDAK logis dari setiap integer. Ini mengubah 0 menjadi 1 dan 1 menjadi 0.


19

Brainfuck ( 70 71)

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

Penjelasan:

>,[>,]                       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
++++++++ [<++++++>> -] mengapa tidak ini untuk 48? 8 * 6 vs. 4 * 4 * 3
Cruncher

@Cruncher Ditambahkan.
kitcar2000

Kenapa bisa lebih lama? apakah itu karena "perbaikan bug"?
Cruncher

1
@Cruncher Ya, saya harus memperbaiki bug di mana ia akan output auntuk 11.
kitcar2000


11

Pancake Stack , 532 bytes

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

Diasumsikan input diakhiri oleh karakter nol. Strateginya adalah sebagai berikut:

  • Ambil karakter input
  • Kurangi nilai ascii 1dari itu.
  • Kurangi itu dari 0(menghasilkan 1jika kita punya 0, atau 0jika kita punya 1)
  • Tambahkan nilai ascii 0untuk itu
  • Cetak char.
  • Ulangi

10

C: 29

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

Cobalah online di sini .

Terima kasih telah menunjukkan trik XOR, Dennis.


8
Lebih sederhana & lebih pendek:i(char*s){while(*s)*s++^=1;}
edc65

1
Terima kasih, @ edc65! Saya tidak akan menggunakan itu, karena ini merupakan solusi berulang daripada solusi rekursif. Saya tidak ingin mengambil kredit untuk itu. Perlu dicatat bahwa mengganti Anda whiledengan forhasil diam dengan panjang 28 karakter.
milinon

6
Terserah Anda. Solusi rekursif tidak diminta, dan menurut saya, kapan pun memungkinkan, solusi berulang lebih baik daripada solusi rekursif. Bersenang-senang menerapkan panggilan rekursif ini ke string 10k.
edc65

1
Karena setiap panggilan kecuali yang terakhir adalah panggilan rekursif ekor, saya berani bertaruh bahwa kompiler akan mengubahnya menjadi loop untuk menggunakan kembali frame tumpukan.
milinon

1
@ Millinon Proof!
deed02392

9

Python 2.7 - 34 *

Oh, betapa ini yang pertama menyebalkan. Cukup jelek, ini. 63 karakter.

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

Yang ini sedikit lebih baik tapi tetap tidak mewah. 44 karakter.

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

Sejak int(x) and 1kembali int(x)jika bukan 0 dan sebaliknya False. Solusinya dapat dikurangi menjadi 36 karakter.

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

Sejak join()mengambil generator, tanda kurung dapat dilepas. 32 karakter.

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

Dan backticks bisa digunakan sebagai gantinya str()

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

Dikurangi menjadi 44 dari 34 berkat pointer dari @TheRare

Menemukan komplemen seseorang sulit di python karena bin(-int)mengembalikan -0bxxx karenanya di atas.


2
Ya'know,(int(x) and 1) == int(x)
seequ

@ Theare Saya tidak, terima kasih untuk itu :)
Bassem

1
Sebagai catatan: nol adalah salah dan bukan nol benar. Untuk segala jenis urutan (daftar, string ...) aturan yang sama berlaku, tetapi diperiksa dari panjang urutan. Jadi '' == Falsedan'hi' == True
seequ

1
Sepertinya Anda melewatkan beberapa ruang. Juga, backticks dapat digunakan untuk mengganti repr (). ''.join(`1-int(x)`for x in'')
seequ

1
Fyi, repr(x)untuk x <maxint sama denganstr(x)
seequ

7

Perl, 9 karakter

'y/10/01/'

Karakter ke-9 adalah bendera 'p'

Pemakaian:

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

2
juga berfungsi sebagai skrip sed y/10/01/tetapi satu karakter lebih pendek karena tidak memerlukan flag

4
Anda tidak perlu tanda kutip tunggal di sini.
Konrad Borowski

7

Javascript ( ES6 ) 36

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

Dengan asumsi input s, s.replace(/./g,x=>x^1)adalah 22 karakter.
Oriol

2
Saya suka benar-benar output dan input.
nderscore

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

@ GaurangTandon itu harus (p=prompt)(p().replace(/./g,x=>x^1))dan itu panjangnya sama.
nderscore

@nderscore Saya juga berpikir seperti itu, tetapi bekerja tanpa tanda kurung juga, anehnya.
Gaurang Tandon

7

Labirin , 6 byte

(Labyrinth lebih baru dari tantangan ini, jadi jawaban ini tidak bersaing - bukankah itu menang ...)

1,
.$@

Kode ini mengasumsikan bahwa STDIN hanya berisi digit (khususnya, tidak ada baris baru).

Pointer instruksi (IP) dimulai di sudut kiri atas ke kanan. Sementara ada angka untuk membacanya akan berputar dalam lingkaran yang ketat melalui blok 2x2 sebelah kiri: 1tekan 1, ,baca satu digit, $XOR dengan 1 untuk beralih bit terakhir, .cetak hasilnya. IP mengambil loop ini karena bagian atas tumpukan positif setelah XOR, sehingga akan berbelok ke kanan. Saat kami menekan EOF, sebagai gantinya ,kembali -1. Kemudian XOR akan menghasilkan -2dan dengan nilai negatif ini IP mengambil belok kiri ke @dan program berakhir.

Solusi ini harus optimal untuk Labyrinth: Anda perlu ,dan .untuk I / O loop dan @untuk mengakhiri program. Anda memerlukan setidaknya dua karakter (di sini 1dan $) untuk mengganti bit terakhir. Dan Anda memerlukan setidaknya satu baris baru untuk satu loop yang dapat diakhiri.

Kecuali ... jika kita mengabaikan STDERR, yaitu mengizinkan penghentian dengan kesalahan kita dapat menyimpan @dan kita juga tidak perlu cara untuk beralih di antara dua jalur. Kami terus membaca dan mencetak sampai kami tidak sengaja mencoba mencetak nilai negatif -2. Ini memungkinkan untuk setidaknya dua solusi 5-byte:

1,
.$
,_1$.


5

Kode Mesin Turing, 32 byte (1 status - 3 warna)

Menggunakan sintaks tabel aturan yang diperlukan oleh simulator TM online ini. Dipinjam dari posting yang saya buat ke blog pengguna Googology Wiki saya beberapa bulan yang lalu.

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

Anda juga dapat menguji ini menggunakan implementasi java ini.


4

Python 2.x - 44 byte

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

Mengapa membuatnya rumit, atau menggunakan beberapa variabel curang?


Mungkin untuk menyimpan beberapa karakter tambahan seperti ini: print''.join('1-int(x)'for x in'input()'). Saya tidak bisa mendapatkan backticks dalam kode komentar sehingga menggantikannya dengan '.
Willem

@willem Untuk referensi di masa mendatang, Anda dapat menghindarinya dengan backslash: `a\`b`-> a`b.
nyuszika7h

@willem Itu tidak berfungsi untuk input yang dimulai dengan 0 atau input yang lebih besar dari maxint (di base10).
seequ

Terima kasih @ nyuszika7h dan tidak memikirkan kasus-kasus TheRare sehingga solusi Anda baik
Willem

@willem Nyata mudah melupakan hal-hal seperti itu. :)
seequ

4

R, 27 karakter

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

Pemakaian:

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



3

TI-BASIC, 7 byte

Ini adalah fungsi yang mengambil string biner (melalui Ans) sebagai input dan mengembalikan output sebagai string terbalik (tidak terbalik), seperti yang ditentukan. Untuk bantuan lebih lanjut, Anda dapat membaca aplikasi daftar melalui not(wiki TI-BASIC. Saya menggunakan versi kompilasi karena lebih kecil:

»*r>Õ¸r

Dalam hex:

BB 2A 72 3E D5 B8 72

Penjelasan

»*r - Ambil input fungsi sebagai string dan konversikan ke daftar

> - Pipa diberikan daftar ke operator selanjutnya

Õ¸r - Kembalikan kebalikan dari daftar


apa semua ruang di akhir »*r>Õ¸r ?
kitcar2000

@ kitcar2000 Ups, dulu saya punya HEX setelah itu. Tetapi setelah saya memindahkannya, saya lupa untuk menghapus spasi ... Saya telah melakukannya sekarang.
Timtech

Harus bermanfaat untuk dicatat bahwa: 1. Pada kalkulator ini ditampilkan sebagai expr(Ans:Returnnot(Ans; 2. Karena string tidak dipisahkan oleh koma, dan itu tidak dimulai dengan a {, itu akan mengevaluasi ke bilangan bulat seperti 1000010011, bukan daftar; 3. Returntidak berfungsi seperti yang Anda tulis; 4. Ini memberikan output sebagai daftar, bukan string.
lirtosiast

3

Haskell, 22 byte

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

Saya terkejut dengan kurangnya solusi Haskell untuk tantangan ini, jadi inilah satu. Ini mengevaluasi ke fungsi yang mengambil string dan mengembalikan kebalikannya.

Penjelasan

Tidak ada yang mewah di sini.

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

Melewati 93, 25 byte

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

Dengan asumsi tumpukan kosong dan EOF keduanya baca -1.

0 mendorong \ 0 sebagai terminator nol

>~1+:#v_ adalah loop input, berbunyi ascii, menambahkan 1, memeriksa EOF + 1 = 0,

^ -1< lain mengurangi 1 dan meninggalkan nilai ascii yang didorong pada tumpukan.

$>:#,_@ menjatuhkan salinan tambahan nol di atas tumpukan, lalu mencetak string biner dari atas ke bawah

Jika tumpukan kosong bertuliskan 0, simpan 2 byte dengan

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

Versi sekitar 15 byte dimungkinkan menggunakan algoritma yang sama ini jika EOF = 0, tetapi saya tidak memiliki implementasi yang mudah untuk diuji.


3

Javascript ES6, 26 karakter

s=>s.replace(/\d/g,x=>x^1)

3
Mengapa / \ d / g tidak /./g
l4m2


2

Python3, 39

Methinks Python bukan bahasa terbaik untuk ini. :)

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

Jika Anda ingin memiliki baris baru setelah keluaran, berikut ini adalah alternatif 43 karakter:

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

Kode akan bekerja tanpa end=''hanya ,kehendak :) - kecuali jika Anda peduli tidak ada spasi
Harry Beadle

@BritishColour, tidak, itu Python2. Fungsi Python3 printmembutuhkan penyesuaian endparameter untuk menekan baris baru di akhir setiap cetak. Juga, menurut spesifikasi OP, saya pikir saya peduli tidak ada spasi. :) Terima kasih atas komentarnya!
DLosc

Aww, keren, aku tidak tahu itu! Saya terutama bekerja di 2,7: /
Harry Beadle

2

J - 11 karakter

Nilai Boolean dalam J direpresentasikan sebagai integer 0dan 1, yang tentu saja juga merupakan indeks yang valid ke dalam array (dalam hal ini, array 2 karakter '01')

'01'{~'0'&=

Saya pikir jawaban ini secara teknis lebih benar daripada jawaban J atas, yang menghasilkan array boolean daripada string.
gar

Saya sebenarnya tidak memperhatikan solusi J peringkat teratas ketika saya memposting (tidak tahu bagaimana saya melewatkannya, tapi saya tahu). Agar adil terhadap solusi itu, ia secara eksplisit mengatakan "ini tidak melakukan apa yang dilakukan solusi lain". BTW, cara lain untuk mengekspresikan solusi (literal output) ini dalam 11 karakter adalah [:, ": @ = & '' 0 ''.
Dan Bron

Hai, terima kasih untuk kode lainnya! Saya akan belajar lebih banyak J dari kalian. Tentang pernyataan itu, saya pikir dia mengacu pada tanda sama, bahwa itu membandingkan setiap item, bukan tugas.
gar

2

C #, 131 byte

Sedikit terlambat ke pesta, tapi ini milikku. :)

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 byte

@(x)[97-x '']

Setelah menjalankan hal di atas, cukup panggil fungsi dengan string input Anda untuk mendapatkan string terbalik. Misalnya menjalankan:

ans('10101110101010010100010001010110101001010')

cetakan:

01010001010101101011101110101001010110101

2

BotEngine , 4x8 = 32

Tidak berkompetisi karena bahasa sudah mengeposkan pertanyaan.

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

Dengan menyoroti:

masukkan deskripsi gambar di sini

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.