偶数バイトのみ


64

シナリオ

最近、お気に入りのテキストエディターで奇妙な動作に気づいています。最初は、ディスクに書き込むときにコード内のランダムな文字を無視しているように見えました。しばらくすると、パターンに気付きました。ASCII値が奇数の文字は無視されていました。さらに詳しく調べてみると、8ビットごとにゼロの場合にのみファイルに適切に書き込むことができることがわかりました。ここで、貴重なファイルがこの奇妙なバグの影響を受けているかどうかを知る必要があります。

タスク

ファイルに奇数バイトが含まれているかどうかを判断する完全なプログラムを作成する必要があります(破損していないことを示します)。ただし、テキストエディタのため、ソースコードに奇数バイトを書き込むことはできません。入力には既存のエンコーディングを想定できますが、文字だけでなく個々のバイトごとにチェックする必要があります。

入力

プログラムは、stdinまたはコマンドラインからファイルの内容またはファイルへのパスを取得します。

出力

プログラムは、指定されたファイルに奇数バイトが含まれている場合は真偽値を、8ビットごとにゼロの場合は偽をstdoutに出力します。

基準

これは、タスクを完了する最短のプログラムであるコードゴルフです。ファイルのソースコードの8ビットごとに有効な送信を行うには、ゼロでなければなりません。提出物にソースコードのバイナリのコピーを含めることをお勧めします。

標準抜け穴適用されます。

テストケース

(ASCIIエンコード)入力:

"$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~

Output:
falsy

Input:
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}

Output:
truthy

Input:
LOREMIPSVMDOLORSITAMETCONSECTETVRADIPISCINGELITSEDDOEIVSMODTEMPORINCIDIDVNTVTLABOREETDOLOREMAGNAALIQVA
VTENIMADMINIMVENIAMQVISNOSTRVDEXERCITATIONVLLAMCOLABORISNISIVTALIQVIPEXEACOMMODOCONSEQVAT
DVISAVTEIRVREDOLORINREPREHENDERITINVOLVPTATEVELITESSECILLVMDOLOREEVFVGIATNVLLAPARIATVR
EXCEPTEVRSINTOCCAECATCVPIDATATNONPROIDENTSVNTINCVLPAQVIOFFICIADESERVNTMOLLITANIMIDESTLABORVM

Output:
truthy

ヒント

  • 言語を賢く選択してください。この課題はすべての言語で可能とは限りません

  • Unixコマンドxxd -b <file name>は、ファイルのバイナリをコンソールに出力します(いくつかの追加のフォーマット設定要素とともに)。

  • UTF-8など、ASCII以外の他のエンコードを使用する場合は、他のすべての規則に従ってください。


2
一部の言語は複数行の入力を読むのに苦労しますが、この課題が簡単であることを意図しているわけではないので、おそらく大丈夫です。:P入力を空にすることはできますか?
デニス

9
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}気にする人のために、禁止されている印刷可能なASCII文字です。許可される印刷可能なASCII文字がある" $&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
パトリック・ロバーツ

9
すべての母音が禁止されていることは非常に便利です...
;

4
ウェルプ、BFがこのチャレンジにチャンスを持っていることは、これだけです。
TLW

2
また、DOS / Windowsファイルに改行がある場合[CR]、奇数ビットがあることに注意してください。ホワイトスペースが安全であることを望んでいましたが、悲しいかな[TAB]。古い学校に行きたい場合、EBCDICは3つの母音を与えます。
GuitarPicker 16

回答:


26

GS2、4つのバイト

dΦ("

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

Hexdump

0000000: 64 e8 28 22                                      d.("

使い方

      (implicit) Read all input and push it on the stack.
 Φ    Map the previous token over all characters in the string:
d       Even; push 1 for even characters, 0 for odd ones.
  (   Take the minimum of the resulting list of Booleans.
   "  Negate the minimum.

21

Befunge、36バイト

これは古い質問であることは知っていますが、Befungeで興味深い挑戦になると思ったので、試してみたいと思いました。

>~:0`|
>20`:>$.@
|` " "<
*8*82<^p24*

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

1入力が破損している(奇数バイトが含まれている)0場合、およびOKの場合に出力します。

説明

問題は、/(divide)または%(modulo)コマンドにアクセスせずに奇数バイトを決定する方法です。解決策は、値に128(シーケンス28*8**)を掛けて、その結果をプレイフィールドに書き込むことでした。厳密に標準的なインタープリターでは、プレイフィールドセルは8ビット値に署名されるため、128を掛けた奇数は-1に切り捨てられ、偶数は0になります。

もう1つの方法は、g(get)コマンドにアクセスせずに、プレイフィールドから-1または0を読み取ることです。これの回避策は、既存の文字列シーケンスの途中に値を書き込むことでした(" ")そのシーケンスを実行して、囲まれた値をスタックにプッシュします。その時点で、バイトの奇数を判断することは、単純なゼロ未満のテストです。

議論する価値のある最後の側面は出力です。偽の場合、>$.スタック上の値が1つだけのシーケンスに到達するため$、スタックをクリアして.出力をゼロにします。本当の場合、パスをたどります20`:>$.。2はゼロより大きいので、比較により1がスタックにプッシュされ、:重複コピーが作成されるため、$出力される前に削除されません。


1
これは遅くて新しいかもしれませんが、すでに私のお気に入りの答えです。
小麦ウィザード

@WheatWizard私は今、この答えが非常に注目されている理由に気付いたばかりです。バウンティをありがとう!
ジェームズホルダーネス

12

CJam(11バイト)

"r2":(~f&2b

オンラインデモ

奇数バイトを避けるためにトリックを取り除き、これは

q1f&2b

入力を読み取り、ビットごとのANDをでマップし1、ベース変換を実行します。ANDがすべてゼロの場合はゼロになります。


3
このコードは悲しいです:(
betseg

それだけで文字@betsegの半分持つことができるので
ローマグラーフ

9

印刷可能な.COMファイル、100バイト

^FZjfDXVL\,LPXD$$4"PXD,lHPXDjJXDRDX@PXDjtXDH,nPXDj@XD4`@PXD,ZHPXD4,@PXD4:4"PXDH,\PXD4"PXD,hPXDRDX@P\

Hexdump:

00000000  5e 46 5a 6a 66 44 58 56  4c 5c 2c 4c 50 58 44 24  |^FZjfDXVL\,LPXD$|
00000010  24 34 22 50 58 44 2c 6c  48 50 58 44 6a 4a 58 44  |$4"PXD,lHPXDjJXD|
00000020  52 44 58 40 50 58 44 6a  74 58 44 48 2c 6e 50 58  |RDX@PXDjtXDH,nPX|
00000030  44 6a 40 58 44 34 60 40  50 58 44 2c 5a 48 50 58  |Dj@XD4`@PXD,ZHPX|
00000040  44 34 2c 40 50 58 44 34  3a 34 22 50 58 44 48 2c  |D4,@PXD4:4"PXDH,|
00000050  5c 50 58 44 34 22 50 58  44 2c 68 50 58 44 52 44  |\PXD4"PXD,hPXDRD|
00000060  58 40 50 5c                                       |X@P\|
00000064

人間が合理的に入力できるものとして非常に緩やかなソースの定義を使用し、EICAR標準アンチウイルステストファイルに触発されます(詳細については、「EICARテストファイルをお楽しみください、Bugtraqの)。

印刷可能な非奇数ASCIIバイトのみを使用します(サイドノート:単語に影響するオペコードは奇数である傾向があり、Wビットは一部のオペコードのlsbです)。 、そして実行は最終的に生成されたコードに落ちて行きます。

スタックには最初にPSPの開始へのニアポインターが含まれており、PSPの開始にはINT 20h命令が含まれているという事実を使用します(これに関する詳細は、https://stackoverflow.com/questions/12591673/を参照してください)。

実際のソース:

; we want to generate the following fragment of code

;  5E                pop si             ; zero SI (pop near pointer to start of PSP)
;  46                inc si             ; set SI to 1
; loop:
;  B406              mov ah,0x6         ; \
;  99                cwd                ; >
;  4A                dec dx             ; > D-2106--DLFF
;  CD21              int 0x21           ; > DIRECT CONSOLE INPUT
;  7405              jz end             ; > jump if no more input
;  40                inc ax             ; > lsb 0/1 odd/even
;  21C6              and si,ax          ; > zero SI on first odd byte
;  EBF3              jmp short loop     ; /
; end:
;  96                xchg ax,si         ; return code
;  B44C              mov ah,0x4c        ; D-214C
;  CD21              int 0x21           ; TERMINATE WITH RETURN CODE

 pop si             ; this two opcodes don't need to be encoded
 inc si

 pop dx             ; DX = 20CD (int 0x20 at start of PSP)
 push byte +0x66
 inc sp
 pop ax
 push si
 dec sp
 pop sp             ; SP = 0x0166
 sub al,0x4c        ; B4
 push ax
 pop ax
 inc sp
 and al,0x24
 xor al,0x22        ; 06
 push ax
 pop ax
 inc sp
 sub al,0x6c
 dec ax             ; 99
 push ax
 pop ax
 inc sp
 push byte +0x4a    ; 4A
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 push byte +0x74    ; 74
 pop ax
 inc sp
 dec ax
 sub al,0x6e        ; 05
 push ax
 pop ax
 inc sp
 push byte +0x40    ; 40
 pop ax
 inc sp
 xor al,0x60
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 sub al,0x5a
 dec ax             ; C6
 push ax
 pop ax
 inc sp
 xor al,0x2c
 inc ax             ; EB
 push ax
 pop ax
 inc sp
 xor al,0x3a
 xor al,0x22        ; F3
 push ax
 pop ax
 inc sp
 dec ax
 sub al,0x5c        ; 96
 push ax
 pop ax
 inc sp
 xor al,0x22        ; B4
 push ax
 pop ax
 inc sp
 sub al,0x68        ; 4C
 push ax
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax
 push ax            ; 21
 pop sp             ; now get the stack out of the way

9

MATL、7バイト

l$Z$2\z

ソースコードはUTF-8エンコーディングを使用します。したがって、ソースバイトは(10進数で)

108    36    90    36    50    92   122

入力はファイル名であり、単一引用符で囲まれた文字列として取得されます。出力は、ファイル内の奇数バイトの数であり、非ゼロの場合は真実です。

説明

l    % Push a 1. We use `l` instead of `1` to have an even value
$    % Input specificication. This indicates that the next function takes 1 input
Z$   % Input file name implicitly, read its raw bytes and push them as an array of chars
2\   % Modulo 2
z    % Number of nonzero values. This gives the number of odd bytes. Implicitly display

8

CJam、18 17 15バイト

"<rj":(((*~:|X&

ロケールがLatin-1に設定されていると仮定します。オンラインでお試しください!

使い方

簡単な解決策は次のとおりです。

q       e# Read all input from STDIN and push it as a string on the stack.
 :i     e# Cast each character to its code point.
   :|   e# Take the bitwise OR of all code points.
     X  e# Push 1.
      & e# Take the bitwise AND of the logical OR and 1.

残念ながら、文字がq及びi、ソースコードに表示することはできません。この問題を回避するには、上記のソースコードの一部を動的に作成し、文字列を評価します。

"<rj"         e# Push that string on the stack.
     :(       e# Decrement all characters, pushing ";qi".
       (      e# Shift out the first character, pushing "qi" and ';'.
        (     e# Decrement ';' to push ':'.
         *    e# Join "qi" with separator ':', pushing "q:i". 
          ~   e# Evaluate the string "q:i", which behaves as explained before.

7

Pyth、20 13バイト

vj0>LhZ.BRj.z

またはバイナリで:

00000000: 01110110 01101010 00110000 00111110 01001100 01101000  vj0>Lh
00000006: 01011010 00101110 01000010 01010010 01101010 00101110  Z.BRj.
0000000c: 01111010                                               z

オンラインで試す

使い方

           .z   all lines of input
          j     join on newline
       .BR      convert each character to binary
   >LhZ         take the last (0 + 1) characters of each binary string
 j0             join on 0
v               evaluate as an integer

結果の整数は、いずれかのバイトが奇数である場合に真(ゼロ以外)です。



4

網膜、106バイト

許可されているすべての文字を削除してから、残りの文字と一致します。真の値は、見つかった文字の数です。偽の値はになります0

`"| |\$|&|\(|\*|,|\.|0|2|4|6|8|:|<|>|@|B|D|F|H|J|L|N|P|R|T|V|X|Z|\\|\^|`|b|d|f|h|j|l|n|p|r|t|v|x|z|\||~

.

オンラインで試す

以来.、デフォルトでは改行と一致していない、私はそれらを削除する必要はありません。


1

Perl 5 +-p0、136バイト

他の回答と同様に、これは偶数バイトをすべて削除し、奇数バイトを残します(これは真実です)。

tr<�
 "$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~€‚„†ˆŠŒŽ’”–˜šœž ¢¤¦¨ª¬®°²´¶¸º¼¾ÀÂÄÆÈÊÌÎÐÒÔÖØÚÜÞàâäæèêìîðòôöøúüþ><>d

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


-0改行には何もしませ。入力を分割する方法のみを決定、文字を削除しません。
Ørjanヨハンセン

痛いです。
Ørjanヨハンセン

@ØrjanJohansenそうですね、-0ブロック全体をひとまとめにしてやりたかったのですが、それは問題ではありませんが、これを回避することはできません...残念です!これらのコメントを整理します。頭を上げてくれてありがとう!
ドムヘイスティングス

それで今は動作しますか?コメントの一部を削除する必要があると思います。編集差分から、プログラムのすべての偶数バイトが含まれていることがわかります。これらのすべてのキャラクターが表示されるわけではないので、(少なくとも私にとっては)明示的に言いたいと思うかもしれません。
Ørjanヨハンセン

@ØrjanJohansenはい!私は今それを持っていると思います。他のすべての答えも偶数バイトすべてをカバーするとは思わない。いくつかは印刷可能なASCIIでしか機能しないと思う。これは今私が望んでいたことをしていると確信しています。とにかくそう願っています!
ドムヘイスティングス

0

Japt、10バイト

ø0ôH² ®dZÄ

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

JaptのコードページはISO-8859-1です。コードはfalse、それ自体が文字列として入力されると、それゆえ有効な送信を提供します。

開梱と仕組み

Uø0ôHp2  mZ{ZdZ+1

Uø      Does input string contain any element in the following array...?
0ôHp2     Range of 0 to 32**2, inclusive
mZ{       Map...
ZdZ+1       Convert the number Z to a char having charcode 2*Z+1

持っていないString.c(文字コードを取得する、または文字コードをマップする)ことは苦痛でしたが、幸いにもNumber.d(数値を文字に変換する)があります。

JaptがCJam、Pyth Jellyに勝っていることがわかります:)


制限なしで、6バイトでそれを行うにはいくつかの方法があります(CJamとJellyと同じようになります):

®c uÃn

Unpacked: UmZ{Zc u} n

UmZ{   Map on each char...
Zc u     Convert to charcode modulo 2
}
n      Convert the resulting string to number

"000..000"長さに関係なく、数字の0(偽)に変換されます。一方、1を含むものはすべて、非ゼロdoubleに変換されるかInfinity、大きすぎる場合(両方とも真実)に変換されます。

¬d_c u

Unpacked: q dZ{Zc u

q    Convert to array of chars
dZ{  Is something true when mapped with...
Zc u   Convert each char to charcode modulo 2

trueまたはを直接生成するより簡単なアプローチfalse

または、フラグの助けを借りて5バイトの解決策も可能-dです:

¨c u

Unpacked: q mZ{Zc u

q     Convert to array of chars
mZ{   Map...
Zc u    Convert to charcode modulo 2

      Result is array of zeros and ones
-d    Apply .some() on the resulting array
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.