具有给定位数的所有ASCII字符


30

(感谢@ChasBrown的称呼)

沙盒

背景

这个挑战的灵感来自于我最近在Puzzling Stack Exchange上发布的一个问题。如果您对原始问题感兴趣,请随时关注该链接。如果没有,那么我不会在这里给您带来细节。

事实

每个可打印的标准ASCII字符都有一个介于32到126之间的十进制值。可以将它们转换为100000到1111110之间的相应二进制数。当您对这些二进制数字的位求和时,您将总是以1到6之间的整数结尾。

挑战

给定一个介于1到6之间(含1和6)的整数作为输入,编写一个程序或函数,该程序或函数将以任何可接受的格式输出所有可打印的标准ASCII字符,其中其二进制值的位之和等于输入整数。

示例/测试用例

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

此处(TIO)提供未发布的Python参考实现。

规则

  1. 假设输入将始终是1到6之间的一个整数(或整数的字符串表示形式)。
  2. 您可以编写一个程序来显示结果,也可以编写一个函数来返回结果。
  3. 输出可以采用任何合理的格式,但对于所有输入都必须保持一致。如果选择输出带引号的字符串,则所有输入必须使用相同类型的引号。
  4. 照常禁止使用标准漏洞。
  5. 这是代码高尔夫球,因此每种语言中最短的代码获胜。

是否允许我们返回/打印十进制ascii值列表,还是需要以字符形式(例如63vs ?)使用它们?
Benjamin Urquhart,

1
必须是实际字符。
ElPedro

7
例如,“所有输入都必须使用相同类型的引号” Python,例如,'默认情况下使用单引号()表示字符串的字符串,但"如果字符串包含单引号且不包含双引号,则使用双引号() 。并不是说这个特定的情况有多大关系,因为您最好返回实际的字符串而不是它的表示形式,并且无论如何您仍然可以在这样的字符串中使用单引号作为输入,但是我觉得在这里值得一提。
暴民埃里克

@EriktheOutgolfer同意。这就是为什么我认为将其作为一条额外的规则可能会很有趣:-)
ElPedro

1
@ElPedro我不确定该怎么做,因为有一些引号可能是一个好主意,因为在第一个示例中有一个空格,但是通常的引号都出现在输出中:)编辑:也许使用法式海吉尔(« »)?:D
瑕疵

Answers:


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”,就好像您已经为该答案注册了一个域一样。
Sparr

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操作码使用10位值(称为“ DECLE”)进行编码。该例程的长度为20 DECLE,起始于$ 4819,结束于$ 482C(包括)。


5
+1只是(a)Intellivision的解决方案,以及(b)我见过的第一个Intellivision代码。
八位大师

3
Intellivision上的@ Eight-BitGuru编码非常有趣。今天的自制游戏是用16位ROM编写的,它可以释放CPU的全部功能。:)
Arnauld

令人印象深刻!不知道Intellivision有一个帧缓冲区和一个内置的字符集。肯定比Atari 2600先进得多。做得非常好!
640KB

2
@gwaugh GROM(用于图形ROM)包含所有可打印的ASCII字符和一些常见的图形形状。有趣的事实:它还包含一些不适合主ROM的可执行代码。
Arnauld

绝对比2600更先进,但是如果有内存可用,那么Mattel不会在ROM中显示任何高级内容,因此第三方开发人员要么局限于直接的机器代码,要么不得不自行保留这些花哨的内容。 。可能是伪造的。
brhfl


9

05AB1E,8个字节

žQʒÇbSOQ

在线尝试!

说明

žQ        # push the printable ascii characters
  ʒ       # filter, keep elements whose
   Ç      # character code
    b     # converted to binary
     SO   # has a digit sum
       Q  # equal to the input

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

我们可以通过将其解析为十进制数并乘以9取模来使用它来获取二进制数的数字总和,这是有效的,因为可以保证所使用的数字范围小于9位。当在数字上下文中使用Perl 6时,可以将二进制字符串自动转换为十进制数字,这有助于实现这一点。



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个字节
毛茸茸的

@蓬松的哦。很好
Arnauld

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

Japt,9个字节

;EƶXc¤è1

试试看测试所有输入

;EƶXc¤è1     :Implicit input of integer U
;E            :Printable ASCII
  Æ           :Filter each X
   ¶          :Test U for equality with
    Xc        :  Character code of X
      ¤       :  To binary string
       è1     :  Count the 1s

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将不使用数组作为参数)。


我喜欢这个。我是Lotus Notes和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;}

仅使用标准库函数。感谢@gastropner,将其从74字节改进到67字节。

在线尝试!



@gastropner,这是一个了不起的改进!谢谢!
克里斯塔

1
我认为您需要从索引31开始,以便在这种f(1)情况下占用空间(因为++i跳过了它)。
LambdaBeta

@LambdaBeta您完全正确,谢谢!
克里斯塔

5

R77 68字节

使用for循环的方法

-9字节归功于Giuseppe

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

在线尝试!

先前:

R78 69 66字节

-12字节归功于Giuseppe

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

将数字32到126转换为位矩阵,然后对各行求和以找到与输入数字匹配的行。

在线尝试!


1
使用intToBits(x)>0而不是as.single
Giuseppe,

很好,我尝试|0并遇到一个错误,只是假设逻辑运算符将无法工作。
亚伦·海曼

1
使用“ sapply而不是”的“上一个”方法为66个字节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);}

-24个字节感谢NahuelFouilleul

在线尝试。

说明:

包含具有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
-24bytes使用Long.bitCount
纳乌艾尔乌Fouilleul

@NahuelFouilleul啊,我总是忘记Java中的内置函数!非常感谢。使用可以再保存3个字节n.bitCount。:)
Kevin Cruijssen

是的,Java再次击败了JavaScript!我喜欢那些角色挑战:P
OlivierGrégoire

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
来自非静态上下文接收者的静态访问。谢谢。
Benjamin Urquhart,

Long.toBinaryString(i)可能是Long.toString(i,2);
Kevin Cruijssen

1
@KevinCruijssen,这就是我的第一条评论
过期数据

1
@KevinCruijssen你说得对。这是固定版本:(仍然)71个字节。是的,我看到了你的版本,我upvoted不到10分钟前)
奥利维尔·格雷瓜尔


4

Dyalog APL扩展,24 22字节

ucs a⌿⍨⎕=+⌿2a32126

在线尝试!

-2个字节,感谢ngn

ngn在常规Dyalog APL中替代22字节:

ucs 32+⍸⎕=32↓+/↑,⍳72

在线尝试!


(expr- )∘=> ⎕=expr
ngn

无延伸:⎕ucs 32+⍸⎕=32↓+/↑,⍳7⍴2(⎕io←0)
NGN


3

盖亚 10字节

₵R⟪¤cbΣ=⟫⁇

在线尝试!

		| implicit input, n
₵R		| push printable ascii
  ⟪	⟫⁇	| filter the list where:
   ¤cbΣ		| the sum of the code point in binary
       =	| is equal to n

3

J31 27字节

-4字节感谢Galen

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

在线尝试!

原始答案

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

在线尝试!

  • 2#:@i.@^8:产生0到255之间的二进制数字(2 ^ 8是256)
  • 1#. 总结每个
  • ]= 产生一个二进制掩码,显示总和等于原始输入的位置
  • a.#~ mask 使用该二进制掩码过滤J的完整ascii字母 a.
  • &(95{.32}.]) 但在这样做之前,请仅从字母和掩码中获取元素32 ... 126


谢谢盖伦。您可以做的事情i.@95
约拿


3

K(ngn / k),20字节

解:

`c$32+&(+/2\32+!95)=

在线尝试!

说明:

从右到左评估:

`c$32+&(+/2\32+!95)= / the solution
                   = / equals?
       (          )  / do this together
               !95   / range 0..94
            32+      / add 32, so range 32..126
          2\         / break into base-2
        +/           / sum up
      &              / indices where true
   32+               / add 32
`c$                  / cast to character

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仿真器上使用。

受到Ryan Russell的回答的启发。输入在CPU地址$ 60处给出。输出到控制台的图像处理单元内存。


2
您好,欢迎来到PPCG。除了构建盒式磁带(即(在线)仿真器或规格)之外,还有什么方法可以验证您的解决方案?
Jonathan Frech

@JonathanFrech我添加了一个完整的程序,该程序可以组装并在本地运行。据我了解,NES环境并不是真正适用于代码高尔夫的标准。


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; group编成0s和1s;获取该[1]分组的索引;拿走.count它,并检查它是否-eq对我们的输入数字$n有用。然后将这些数字转换为char-array并留在管道中。输出是隐式的,元素之间带有换行符。



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




By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.