指定されたビットカウントのすべてのASCII文字


30

(@ChasBrownのおかげでタイトル)

サンドボックス

背景

この挑戦は、私が最近Puzzling Stack Exchangeに投稿した質問に触発されました。元の質問に興味がある場合は、リンクをたどってください。そうでない場合は、ここで詳細を説明しません。

事実

印刷可能な標準ASCII文字はすべて、32〜126の10進数値を持ちます。これらは、100000から1111110までの範囲の対応する2進数に変換できます。これらの2進数のビットを合計すると、常に1〜6の整数になります。

チャレンジ

入力として1〜6の整数を指定し、バイナリ値のビットの合計が入力整数に等しい印刷可能な標準ASCII文字をすべて受け入れ可能な形式で出力するプログラムまたは関数を作成します。

例/テストケース

1 -> ' @'
2 -> '!"$(0ABDHP`'
3 -> '#%&)*,1248CEFIJLQRTXabdhp'
4 -> ''+-.3569:<GKMNSUVYZ\cefijlqrtx'
5 -> '/7;=>OW[]^gkmnsuvyz|'
6 -> '?_ow{}~'

未使用のPythonリファレンス実装は、こちら(TIO)から入手できます

ルール

  1. 入力は常に1〜6の整数(または整数の文字列表現)であると仮定します。
  2. 結果を表示するプログラム、または結果を返す関数を作成できます。
  3. 出力は合理的な形式であるかもしれませんが、すべての入力に対して一貫してなければなりません。引用符付き文字列を出力することを選択した場合、すべての入力に同じタイプの引用符を使用する必要があります。
  4. 通常の禁止されている標準的な抜け穴。
  5. これはコードゴルフなので、各言語の最短コードが勝ちます。

10進数のASCII値のリストを返す/印刷することは許可されていますか、それとも文字の形式(例:63vs ?)にする必要がありますか?
ベンジャミンアーカート

1
実際の文字でなければなりません。
エルペドロ

7
「すべての入力に同じ種類の引用符を使用する必要があります」たとえば、Pythonでは、'デフォルトで文字列の文字列表現に単一引用符()を使用しますが"、文字列に単一引用符が含まれ、二重引用符がない場合は二重引用符()を使用します。表現の代わりに実際の文字列を返す方がおそらく良いので、この特定のケースは重要ではありません、とにかく入力のためにそのような文字列で一重引用符を使用することができますが、ここで言及する価値があると感じています。
アウトゴルファーのエリック

@EriktheOutgolfer同意しました。それが、私がそれを特別なルールとして投げ入れるだけで面白いかもしれないと思った理由です:-)
ElPedro

1
@ElPedro最初の例にはスペースがあるので、おそらく引用符を付けることをお勧めしますが、通常の引用符は両方とも出力に表示されますので、どうすればいいのかわかりませんでした:« »)?:D
flawr

回答:


29

8088アセンブリ、IBM PC DOS、 35 30 29バイト

マシンコード:

be81 00ad 8afc b330 b108 d0c8 12dd e2fa 3afb 7504 b40e cd10 fec0 79ea c3

リスト:

BE 0081     MOV  SI, 081H   ; SI = memory address of command line string
AD          LODSW           ; AL = start ASCII value (init to 20H from space on cmd line)
8A FC       MOV  BH, AH     ; BH = target number of bits (in ASCII)
        CHR_LOOP:
B3 30       MOV  BL, '0'    ; BL = counter of bits, reset to ASCII zero
B1 08       MOV  CL, 8      ; loop through 8 bits of AL
        BIT_LOOP:
D0 C8       ROL  AL, 1      ; rotate LSB of AL into CF
12 DD       ADC  BL, CH     ; add CF to BL (CH is always 0) 
E2 FA       LOOP BIT_LOOP   ; loop to next bit
3A FB       CMP  BH, BL     ; is current char the target number of bits?
75 04       JNE  NO_DISP    ; if not, do not display
B4 0E       MOV  AH, 0EH    ; BIOS write char to screen function
CD 10       INT  10H        ; display ASCII char in AL (current char in loop)
        NO_DISP: 
FE C0       INC  AL         ; increment char to next ASCII value
79 EA       JNS  CHR_LOOP   ; if char <= 127, keep looping
C3          RET             ; return to DOS

スタンドアロンPC DOS実行可能プログラム、コマンドラインからの入力番号。出力はコンソールウィンドウに表示されます。

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

ABCT.COM(AsciiBitCounT)をダウンロードしてテストします。


8
この回答のためだけにドメインを登録したかのように、「AT ABCT.COMをダウンロードしてテストしてください」とちょっと思った。
スパー

14

CP-1610アセンブリ(Intellivision)、20 DECLE 1 = 25バイト

R0でを取り、R4で出力バッファーへのポインターを取ります。バッファに一致するすべての文字を書き込み、結果の最後にNULをマークします。N

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            EIS                     ; enable interrupts

4801            MVII    #$103,    R4    ; set the output buffer at $103 (8-bit RAM)
4803            MVII    #2,       R0    ; test with N = 2
4805            CALL    getChars        ; invoke our routine

4808            MVII    #$103,    R4    ; R4 = pointer into the output buffer
480A            MVII    #$215,    R5    ; R5 = backtab pointer

480C  draw      MVI@    R4,       R0    ; read R0 from the buffer
480D            SLL     R0,       2     ; R0 *= 8
480E            SLL     R0
480F            BEQ     done            ; stop if it's zero

4811            ADDI    #7-256,   R0    ; draw it in white
4815            MVO@    R0,       R5

4816            B       draw            ; go on with the next entry

4818  done      DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      getChars  PROC

4819            MVII    #32,      R1    ; start with R1 = 32

481B  @loop     MOVR    R1,       R3    ; copy R1 to R3
481C            CLRR    R2              ; clear R2
481D            SETC                    ; start with the carry set

481E  @count    ADCR    R2              ; add the carry to R2
481F            SARC    R3              ; shift R3 to the right (the least
                                        ; significant bit is put in the carry)
4820            BNEQ    @count          ; loop if R3 is not zero

4822            CMPR    R2,       R0    ; if R2 is equal to R0 ...
4823            BNEQ    @next

4825            MVO@    R1,       R4    ; ... write R1 to the output buffer

4826  @next     INCR    R1              ; advance to the next character
4827            CMPI    #127,     R1    ; and loop until 127 is reached
4829            BLT     @loop

482B            MVO@    R3,       R4    ; write NUL to mark the end of the output

482C            JR      R5              ; return

                ENDP

N = 2の出力

注意:開き括弧は、Intellivisionフォントの開き角かっこによく似ています。ただし、両方の文字は区別されます。

出力

jzIntvのスクリーンショット


1. CP-1610オペコードは、「DECLE」として知られる10ビット値でエンコードされます。このルーチンの長さは20 DECLEで、4819ドルで始まり、482ドルで終わります(含まれています)。


5
+1(a)Intellivisionのソリューション、および(b)私が見た最初のIntellivisionコードであるためだけに。
8ビットの達人

3
Intellivisionの@ Eight-BitGuruコーディングはとても楽しいです。そして、今日の自作ゲームは16ビットROMで書かれており、CPUのフルパワー(...)のロックを解除します。:)
Arnauld

印象的!Intellivisionにはフレームバッファと組み込みの文字セットがありませんでした。確かにAtari 2600よりもはるかに高度です。とてもうまくできました!
640KB

2
@gwaugh GROM(グラフィックスROM用)には、すべての印刷可能なASCII文字といくつかの一般的なグラフィカル図形が含まれています。面白い事実:メインROMに収まらない実行可能コードも含まれています。
アーナウルド

2600よりも確かに高度ですが、メモリが提供される場合、マテルはROMに隠れている高度なものを一切明らかにしなかったため、サードパーティの開発者はストレートマシンコードに限定されるか、独自の派手なものを調べなければなりませんでした。偶然かもしれません。
brhfl



8

Perl 6の41の 34バイト

{chrs grep *.base(2)%9==$_,^95+32}

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

数字を受け取り、有効な文字列を返す匿名コードブロック。

説明:

{                                }  # Anonymous code block taking a number
      grep                ,^95+32   # Filter from the range 32 to 126
           *.base(2)                # Where the binary of the digit
                    %9                # When parsed as a decimal modulo 9
                      ==$_            # Is equal to the input
 chrs                               # And convert the list of numbers to a string

nbndigitsum(n)(modb1)b(modb1)=1

これを使用して2進数を10進数として解析し、9でモジュロ化することで2進数の桁数を取得できます。これは、使用している数値の範囲が9ビット未満であることが保証されているため有効です。これは、数値コンテキストで使用された場合に、Perl 6がバイナリ文字列を10進数に自動的にキャストすることで役立ちます。



7

JavaScript(Node.js)、60バイト

Jo Kingのモジュロトリックの使用

n=>(g=x=>x>>7?'':Buffer(x.toString(2)%9-n?0:[x])+g(x+1))(32)

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


JavaScript(Node.js) 70  69バイト

n=>(g=x=>x>>7?'':Buffer((h=x=>x&&x%2+h(x>>1))(x)-n?0:[x])+g(x+1))(32)

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

コメント済み

n => (              // n = input
  g = x =>          // g = recursive function, taking a byte x
    x >> 7 ?        //   if x = 128:
      ''            //     stop recursion and return an empty string
    :               //   else:
      Buffer(       //     create a Buffer:
        (h = x =>   //       h = recursive function taking a byte x
          x &&      //         stop if x = 0
          x % 2 +   //         otherwise, add the least significant bit
          h(x >> 1) //         and do a recursive call with floor(x / 2)
        )(x)        //       initial call to h
        - n ?       //       if the result is not equal to n:
          0         //         create an empty Buffer (coerced to an empty string)
        :           //       else:
          [x]       //         create a Buffer consisting of the character x
      ) +           //     end of Buffer()
      g(x + 1)      //     append the result of a recursive call to g with x + 1
)(32)               // initial call to g with x = 32

Joのモジュロトリックを使用した60バイト
シャギー

@Shaggy Oh。それはいいものです。
アーナウルド

6

Brachylog、7バイト

∈Ṭ&ạhḃ+

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

ジェネレーターとして機能する述語は、出力変数を介して入力を受け取り、入力変数を介して各文字を生成します。なぜならBrachylog。

           The input variable (which is an element of the output)
∈          is an element of
 Ṭ         the string containing every printable ASCII character
  &        and the input
   ạh      converted to a codepoint
     ḃ     converted to a list of binary digits
      +    sums to
           the output variable (which is the input).


5

Excel(2016以降)、76バイト

=CONCAT(IF(LEN(SUBSTITUTE(DEC2BIN(ROW(32:126)),0,))=A1,CHAR(ROW(32:126)),""))

A1から入力を受け取り、この数式を入力したセルに出力します。これは配列式なので、Ctrl+ Shift+ Enterを押して入力する必要があります。「2016以降」は、CONCAT関数が必要であるためです(廃止予定CONCATENATEは引数として配列を取りません)。


私はこれが好き。私はロータスノーツで123人ですので、これでうまく
いき

5

C(標準ライブラリ)、74 67バイト

i;j;k;f(n){for(i=31;i<126;k||puts(&i))for(k=n,j=++i;j;j/=2)k-=j&1;}

標準ライブラリ関数のみを使用します。74バイトから67バイトに改善してくれた@gastropnerに感謝します。

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



@gastropnerそれは驚くべき改善です!ありがとうございました!
クリスタ

1
f(1)ケース内のスペースを確保するために、インデックス31から開始する必要があると思います(++iスキップするため)。
ラムダベータ

@LambdaBetaあなたは絶対に正しい、ありがとう!
クリスタ

5

R77 68バイト

forループを使用するアプローチ

ジュゼッペのおかげで-9バイト

n=scan();for(i in 32:126)if(sum(intToBits(i)>0)==n)cat(intToUtf8(i))

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

以前:

R78 69 66バイト

ジュゼッペのおかげで-12バイト

a=32:126;cat(intToUtf8(a[colSums(sapply(a,intToBits)>0)==scan()]))

32から126までの数値をビットのマトリックスに変換し、行全体で合計して、入力数値に一致するものを見つけます。

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


1
使用するintToBits(x)>0よりもas.single
ジュゼッペ

ニース、私は試し|0たがエラーになり、論理演算子が機能しないと仮定した。
アーロンヘイマン

1
66のバイトを用いて「前へ」のアプローチのためsapplyではなくmatrix
Giuseppeの

4

Java 10、98 97 94 70 67バイト

n->{for(var c='';c-->31;)if(n.bitCount(c)==n)System.out.print(c);}

NahuelFouilleulのおかげで-24バイト。

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

説明:

Unicode値を持つ印刷できない文字が含まれています127

n->{                         // Method with Integer parameter and no return-type
  for(var c='';c-->31;)     //  Loop character `c` in the range ['~', ' '] / (127,31):
    if(n.bitCount(c)         //   If the amount of 1-bits in the two's complement binary
                             //   representation of the current characters
                    ==n)     //   equals the input:
      System.out.print(c);}  //    Print the current character

1
Long.bitCountを使用して-24バイト
Nahuel Fouilleul

@NahuelFouilleulああ、私はいつもJavaに組み込まれていることを忘れています!どうもありがとう。を使用すると、さらに3バイトを保存できますn.bitCount。:)
ケビン・クルーッセン

ええ、JavaはJavaScriptを再び打ち負かしました 私はそれらのキャラクターの挑戦が大好きです:P
オリビエグレゴワール

4

Java 8、131 71バイト

コメントのすべての人に-60バイトの感謝コードポイントを

返しますjava.util.stream.IntStream

n->java.util.stream.IntStream.range(32,127).filter(i->n.bitCount(i)==n)

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

HashSetを使用して、135バイト。を返しますSet<Object>

n->new java.util.HashSet(){{for(int i=31;i++<126;add(Long.toBinaryString(i).chars().map(c->c-48).sum()==n?(char)i+"":""),remove(""));}}

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



1
非静的コンテキストからの静的アクセス。ありがとう。
ベンジャミンアーカート

Long.toBinaryString(i)することができますLong.toString(i,2);
ケビンクルーイセン

1
@KevinCruijssenそれが私の最初のコメントがすることです
期限切れのデータ

1
@KevinCruijssenそうですね。修正版は次のとおりです:(まだ)71バイト。そして、はい、私は10分未満前に投票したあなたのバージョンを見ました;)
オリヴィエ・グレゴワール

4

C#(Visual C#Interactive Compiler)、86バイト

n=>Enumerable.Range(32,95).Where(x=>"0123456".Sum(g=>x>>g-48&1)==n).Select(x=>(char)x)

@ExpiredDataを使用してアイデアをくれてありがとうSum()!PCに戻ったら、文字列"0123456"を印刷不能文字に置き換え、3バイトを節約します。

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



@ExpiredData使用するアイデアをありがとうSum()
無知の具現化




3

J31 27バイト

Galenのおかげで-4バイト

[:u:32+[:I.]=1#.32#:@+i.@95

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

元の回答

a.#~&(95{.32}.])]=1#.2#:@i.@^8:

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

  • 2#:@i.@^8:0から255までの2進数を生成します(2 ^ 8256です)
  • 1#. それぞれを合計する
  • ]= 合計が元の入力と等しい場所を示すバイナリマスクを生成します
  • a.#~ mask そのバイナリマスクを使用して、Jの完全なASCIIアルファベットをフィルタリングします a.
  • &(95{.32}.]) しかし、そうする前に、アルファベットとマスクの両方から要素32 ... 126のみを取得します


ガレン、ありがとう。あなたができるTILi.@95
ジョナ



3

6502アセンブリ(NES)、22バイト

マシンコード:

a0 1f a6 60 c8 98 30 fb ca 0a b0 fc d0 fb e8 d0 f1 8c 07 20 f0 ec

アセンブリ:

    ldy #$1f ; Y holds the current character code
NextCharacter:
    ldx $60 ; load parameter into X
    iny
    tya
    bmi (NextCharacter + 1) ; exit at char 128, #$60 is the return opcode

CountBits:
    dex
Continue:
    asl
    bcs CountBits
    bne Continue

CompareBitCount:
    inx ; fixes off-by-one error and sets Z flag if bit count matches
    bne NextCharacter
    sty $2007
    beq NextCharacter ; always branches

完全なプログラム。FCEUX 2.2.3でテストされ、標準のNESエミュレーターで動作するはずです。

ライアンラッセルの答えに触発されました。CPUアドレス60ドルで入力します。コンソールの画像処理装置メモリへの出力。


2
こんにちは、PPCGへようこそ。カートリッジ、つまり(オンライン)エミュレーターまたは仕様を作成する以外に、ソリューションを検証する方法はありますか?
ジョナサンフレッチ

@JonathanFrech組み立ててローカルで実行できる完全なプログラムを追加しました。私が理解しているように、NES環境はcodegolf用に実際には標準化されていません。
負の


2

PowerShell、83バイト

param($n)[char[]](32..126|?{([convert]::ToString($_,2)|% t*y|group)[1].count-eq$n})

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

入力を受け取り$n、範囲を構築32する126と、それらの数字引き出す|?{}:数は、convertToStringベースにします2。変換されたtoCharArra y; sおよびsにgroup編入されます。そのグループのインデックスを取得します。それを取得し、それが入力アンバーに当てはまることを確認します。これらの数値は-array としてキャストされ、パイプラインに残ります。出力は暗黙的で、要素間に改行があります。01[1].count-eq$nchar



2

、10バイト

Φγ⁼Σ↨℅ι²Iθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

 γ          Predefined ASCII characters
Φ           Filtered by
      ι     Current character's
     ℅      ASCII code
    ↨       Converted to base
       ²    Literal 2
   Σ        Summed
  ⁼         Equals
         θ  First input
        I   Cast to integer
            Implicitly printed




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