バイナリ文字列をビット単位で反転する最短コード


79

ここでは、初心者が挑戦できるほど簡単な質問はないと思います!

課題:次のような1と0のランダムな入力文字列が与えられた場合:

10101110101010010100010001010110101001010

ビット単位の逆関数を出力する最短コードを次のように記述します。

01010001010101101011101110101001010110101

回答:


88

J、5バイト

入力文字列がvariableにあると仮定しますb

b='0'

これは、ほとんどの言語で行うことを行いません...

J比較演算子はただです==:そして=.、それぞれグローバル割り当てとローカル割り当てです)。ただし、=通常の==演算子とは異なり、アイテムごとに比較します。配列は次のように形成されることに注意してください0 2 3 2 3 1 2 3 42 = 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のbool 1 andであるため0、これはの and の配列に1なります0(これらは文字列ではなく、他のすべての文字10この配列になります。)これは印刷を必要としません。Jは式の結果を自動的に印刷します。これが適切な説明であったことを願っていますが、そうでない場合は、コメントでまだ明確ではない何かを尋ねてください。この答えも'0'&=(または=&'0')だったかもしれませんが、私はそれb='0'がより明確だと感じました。


1
私はJを試しました。それに心を曲げることはできません。良いドキュメントが見つからなかったと思います。ここでは、狂人であるために+1があります。
seequ 14年

1
そして、これが私がJを決して使わない理由です。
Qix 14年

2
@Qix Jとは異なり判読不能ですが、これは実際には私にとって理にかなっており、ベクトルLHSとスカラーRHSをとる演算子を持つ他の言語も同様に動作します。
hvd 14年

1
何?正しい結果を返しませんか?...結果は、(スペースなし)テキスト文字列となっているはずですが、Jの私の限られた知識で、私は、これは0 1 0 1 0の表示形式でブールリストを返すなると思う
アダム・

4
入力が特定の変数に格納されていると想定できないため、これは許可されません。=&'0'同じバイト数で機能します。
エソランジングフルーツ

43

GolfScript、5バイト

{1^}%

オンラインでお試しください。

使い方

  • GolfScriptは、STDINから入力全体を読み取り、文字列としてスタックに配置します。

  • {}% 文字列内のすべての文字を調べ、すべての文字に対してコードブロックを実行します。

  • 1^ ASCIIコードの1との排他的論理和を計算します。「0」はASCIIコード48に、「1」はASCIIコード49に対応します。

    以来48 ^ 1 = 4949 ^ 1 = 48、これが0のに1と1に0年代をオンにします。

  • 完了すると、GolfScriptは変更された文字列を出力します。


6
待って、golfscript
ToonAlfrink

あなたの質問を誤解していた。修正されました。
デニス14年

1
@tolos:回答を編集しました。
デニス14年

5
@ToonAlfrink GolfScriptなどのゴルフ言語は、「汎用」であるため、特定の課題向けに設計されていない限り、すべての課題で受け入れられます。
kitcar2000 14年

4
@ kitcar2000私は彼がそのような言語が存在することにもっと驚いたと思います。誰かがコードのゴルフの質問でGolfScriptを使用することを敢えてするショックではありません;)
クリスサイレフ


30

DOS上のx86マシンコード- 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にもう1バイト削ってくれてありがとう。

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を搭載したVMでは、意図したとおりに実行されます。

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バイト

これは、コマンドラインからの入力を受け入れました。DosBoxで.COMファイルとしてスムーズに実行されます。

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。
ケナー14年

1
xchg dx,axより1バイト短いmov dl,al
ninjalj

@ninjalj:わあ、ありがとう!それはなかった、すべての後に短い取得します!
マッテオイタリア

26

Bash + coreutils、8バイト

tr 01 10

STDINから入力を受け取ります。


または

sed、8バイト

y/01/10/

2
私は最近、Bash github.com/professorfish/bash-shelfのゴルフライブラリ/エイリアスセットを作成しました。あなたはそれで1つの文字をオフに剃ることができます:y 01 10

1
BASHはどこに関係していますか?BASH固有のものは何ですか?呼び出すことができるすべてのシェルtr...
イエティ

1
@yetiすべてのシェルがbashやzshなどのコマンドを呼び出すわけではありません。単独のコードに構文エラーがある一部のシェルで
mniip

5
それは...「シェル」は、ここで「POSIX互換シェル」を意味することを想定して、おそらく安全です
ホタル

@professorfishは1文字を削りますが、関数を含めることで48を追加します。それはどのように勝利ですか?
スティーブンペニー14年

20

CJam、4バイト

:~:!

元の文字列が既にスタック上にあると仮定します。変更された文字列を出力します。

次のコードを貼り付けて、オンラインで試してください

"10101110101010010100010001010110101001010":~:!

使い方

  • :~文字列の各文字を評価します。つまり、文字 0を整数 0 に置き換えます。

  • :!各整数の論理否定を計算します。これにより、0が1に変わり、1が0になります。


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
ランチャー14年

@Cruncherが追加されました。
kitcar2000 14年

なぜ長くなったのですか?「バグ修正」のせいですか?
ランチャー14年

1
@Cruncherはい、それが出力さaれるバグを修正する必要がありました11
kitcar2000 14年


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
  • からそれを引きます01持っ00いれば、または持っていれば1
  • ASCII値の追加0、それまでに
  • 文字を印刷します。
  • 繰り返す

10

C:29

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

こちらからオンラインでお試しください。

XORトリックを指摘してくれてありがとう、デニス。


8
よりシンプルで短い:i(char*s){while(*s)*s++^=1;}
edc65 14年

1
ありがとう、@ edc65!ただし、再帰的なソリューションではなく反復的なソリューションであるため、これは使用しません。私はそれを信用したくありません。それはあなたを置き換えることは注目に値しますwhilefor28文字の長さの、まだ結果。
ミリノン14年

6
あなたが好むように。再帰的な解決策は要求されておらず、私の意見では、可能であればいつでも、反復的な解決策は再帰的な解決策よりも優れています。この再帰呼び出しを10k文字列に適用して楽しんでください。
edc65

1
最後の呼び出しを除くすべての呼び出しは末尾再帰呼び出しであるため、コンパイラはスタックフレームを再利用するためにループに変換することに間違いはありません。
ミリノン14年

1
@ミリノン証明!
deed02392 14年

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'')

@TheRareのポインターのおかげで34から44に減少

python bin(-int)では-0bxxxを返すので、上記のように補数を見つけるのは困難です。


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

私は、その:)に感謝をしませんでした@TheRare
Bassem

1
レコードの場合:ゼロは偽であり、非ゼロは真です。あらゆる種類のシーケンス(リスト、文字列...)には同じルールが適用されますが、シーケンスの長さからチェックされます。このよう'' == False'hi' == True
seequ 2014年

1
いくつかのスペースを見逃したようです。また、reprt()の代わりにバックティックを使用できます。''.join(`1-int(x)`for x in'')
seequ 14年

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/、それは任意のフラグを必要としないので、しかし、1つのchar短い

4
ここでは一重引用符は必要ありません。
コンラッドボロスキー14年

7

Javascript(ES6)36

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

の入力を想定するとss.replace(/./g,x=>x^1)22文字です。
オリオール14年

2
実際に出力と入力が好きです。
nderscore 14年

@nderscore 2文字節約:p=prompt(p().replace(/./g,x=>x^1))
ガランタンドン14

@GaurangTandonである必要があり(p=prompt)(p().replace(/./g,x=>x^1))、それは同じ長さです。
アンダースコア14年

@nderscore私もそのように思っていましたが、奇妙なことに括弧なしでも機能しました。
ゴーランタンドン14年

7

ラビリンス、6バイト

(Labyrinthはこのチャレンジよりも新しいため、この答えは競合しません-とにかく勝っているというわけではありません...)

1,
.$@

このコードは、STDINに数字のみが含まれていることを前提としています(特に、末尾の改行はありません)。

命令ポインター(IP)は、左上隅から右に向かって始まります。読み取る数字がある間、それは左側の2x2ブロックを通るタイトループで循環します1。1をプッシュし,、数字を読み取り、1と$XORして最後のビットを切り替え.、結果を出力します。XORの後、スタックのトップが正であるため、IPはこのループを取り、右折します。EOFをヒットすると、代わりに,戻ります-1。次に、XORが生成さ-2れ、この負の値でIPは左折し@、プログラムは終了します。

このソリューションは、ラビリンスに最適です。I / Oループが必要,で、プログラムを終了する必要があります。最後のビットを切り替えるには、少なくとも2つの文字(ここと)が必要です。また、終了できるループには少なくとも1つの改行が必要です。.@1$

STDERRを無視する場合、つまりエラーで終了することを許可しない限り、保存することができ、@2つのパスを切り替える方法も必要ありません。誤って負の値(-2)を印刷しようとするまで、読み取りと印刷を続けます。これにより、少なくとも2つの5バイトソリューションが可能になります。

1,
.$
,_1$.



4

Python 2.x-44バイト

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

なぜ複雑にしたり、チートな変数を使用したりするのですか?


このようないくつかの余分な文字を保存することが可能print''.join('1-int(x)'for x in'input()')です:。コメントコードでバッククォートを取得できなかったため、 'で置き換えました。
ウィレム14年

@willem将来の参照のために、バックスラッシュでエスケープできます:`a\`b`-> a`b
nyuszika7h 14年

@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 wikiのリストアプリケーションをご覧ください。私はそれが小さいので、コンパイルされたバージョンを使用しています:

»*r>Õ¸r

16進数で:

BB 2A 72 3E D5 B8 72

説明

»*r -関数入力を文字列として受け取り、リストに変換します

> -与えられたリストを次のオペレーターにパイプする

Õ¸r -リストの逆を返します


最後のスペースは»*r>Õ¸r 何ですか?
kitcar2000 14

@ kitcar2000おっと、その後HEXを使用していました。しかし、移動した後、スペースを削除するのを忘れてしまった...今やった。
ティムテック

次のことに注意してください。1.計算機では、これはとして表示されexpr(Ans:Returnnot(Ansます。2.文字列はカンマで区切られておらず、a {で始まっていないため、リストではなく1000010011のような整数に評価されます。3. Return書いたとおりに機能しない。4.これにより、文字列ではなくリストとして出力されます。
リスト管理者

3

Haskell、22バイト

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

この挑戦に対するHaskellソリューションの欠如に驚いたので、ここに1つあります。文字列を取り、その逆を返す関数に評価されます。

説明

ここには何も派手なものはありません。

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 nullターミネータとして\ 0をプッシュします

>~1+:#v_ 入力ループで、asciiを読み取り、1を追加してEOF + 1 = 0をチェックし、

^ -1< そうでない場合は1を減算し、プッシュされたASCII値をスタックに残します。

$>:#,_@ スタックの先頭にゼロの余分なコピーをドロップし、バイナリ文字列を上から下に出力します

空のスタックが0の場合、2バイトを保存します

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

EOF = 0の場合、この同じアルゴリズムを使用して15バイト前後のバージョンを使用できますが、テストに便利な実装はありません。




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=''ただの,意志なしで動作します:)-スペースがないことを気にしない限り
ハリー・ビードル14年

@BritishColour、いいえ、それはPython2です。Python3のprint関数ではend、各印刷の終わりで改行を抑制するためにパラメーターを調整する必要があります。また、OPの仕様によれば、スペースがないことを気にかけていると思います。:)コメントありがとうございます!
DLosc 14年

ああ、クール、私はそれを知りませんでした!私は主に2.7で働いています:/
ハリー・ビードル14年

2

J-11文字

Jのブール値は整数0およびとして表されます1。これはもちろん配列(この場合は2文字の配列'01')の有効なインデックスです。

'01'{~'0'&=

この答えは、文字列ではなくブール配列を出力するトップJの答えよりも技術的には正しいと思います。
ガー14年

投稿したとき、私は実際にトップランクの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

ハイライト付き:

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.