Todos os caracteres ASCII com uma determinada contagem de bits

30

(Título com agradecimentos a @ChasBrown)

Caixa de areia

O fundo

Esse desafio é inspirado em uma pergunta que eu postei recentemente no Puzzling Stack Exchange . Por favor, sinta-se livre para seguir o link se você estiver interessado na pergunta original. Caso contrário, não vou aborrecê-lo com os detalhes aqui.

Os fatos

Cada caractere ASCII padrão imprimível tem um valor decimal entre 32 e 126, inclusive. Eles podem ser convertidos em seus números binários correspondentes no intervalo de 100000 a 1111110, inclusive. Quando você soma os bits desses números binários, sempre termina com um número inteiro entre 1 e 6, inclusive.

O desafio

Dado um número inteiro entre 1 e 6, inclusive como entrada, escreva um programa ou função que produzirá em qualquer formato aceitável todos os caracteres ASCII padrão imprimíveis, em que a soma dos bits de seu valor binário é igual ao número inteiro de entrada.

Os exemplos / casos de teste

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

Uma implementação de referência Python não-gasta está disponível aqui (TIO) .

As regras

  1. Suponha que a entrada sempre será um número inteiro (ou representação de string de um número inteiro) entre 1 e 6, inclusive.
  2. Você pode escrever um programa para exibir os resultados ou uma função para devolvê-los.
  3. A saída pode estar em qualquer formato razoável, mas deve ser consistente para todas as entradas . Se você optar por gerar uma string entre aspas, o mesmo tipo de aspas deverá ser usado para todas as entradas.
  4. Brechas padrão proibidas como de costume.
  5. Este é um código de golfe, pelo que o código mais curto em cada idioma vence.
ElPedro
fonte
É permitido retornar / imprimir uma lista dos valores decimais ascii ou precisamos tê-los na forma de caracteres (por exemplo, 63vs ?)?
Benjamin Urquhart
1
Devem ser os caracteres reais.
ElPedro 23/04
7
"o mesmo tipo de aspas deve ser usado para todas as entradas" Python, por exemplo, usa aspas simples ( ') para a representação de uma string por padrão, mas usa aspas duplas ( ") se a string contiver uma aspas simples e sem aspas duplas . Não que esse caso específico seja importante, pois é melhor você retornar a string real em vez de sua representação, e ainda assim você pode usar aspas simples nessa string para entrada, mas acho que vale a pena mencionar aqui.
Erik the Outgolfer
@EriktheOutgolfer Concordou. É por isso que pensei que poderia ser interessante apenas jogar isso como uma regra extra :-)
ElPedro
1
@ ElPedro Eu não tinha certeza do que fazer, pois provavelmente é uma boa ideia ter algumas aspas, pois há um espaço no primeiro exemplo, mas as aspas usuais aparecem na saída :) Editar: talvez use guillemets franceses ( « »)? : D
flawr 24/04

Respostas:

29

Montagem 8088, IBM PC DOS, 35 30 29 bytes

Código da máquina:

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

Listagem:

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

Programa executável autônomo do PC DOS, número de entrada da linha de comando. A saída é exibida na janela do console.

insira a descrição da imagem aqui

Faça o download e teste o ABCT.COM (AsciiBitCounT).

640KB
fonte
8
Por um momento, achei que dizia "Faça o download e teste no ABCT.COM", como se você tivesse registrado um domínio apenas para esta resposta.
Sparr 24/04
14

Montagem CP-1610 ( Intellivision ), 20 DECLEs 1 = 25 bytes

Leva em R0 e um ponteiro para o buffer de saída em R4 . Grava todos os caracteres correspondentes no buffer e marca o final dos resultados com 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

Saída para N = 2

NB: O parêntese de abertura se parece muito com um colchete de abertura na fonte Intellivision. Ambos os personagens são distintos, no entanto.

saída

captura de tela do jzIntv


1. Um código de operação CP-1610 é codificado com um valor de 10 bits, conhecido como 'DECLE'. Essa rotina dura 20 DECLEs, começando em US $ 4819 e terminando em US $ 482C (incluído).

Arnauld
fonte
5
+1 apenas por ser (a) uma solução para o Intellivision e (b) o primeiro código do Intellivision que eu já vi.
Oito Bits Guru
3
@ A codificação Oito BitGuru na Intellivision é bastante divertida. E os jogos caseiros de hoje são escritos em ROM de 16 bits, que libera toda a potência (ahem ...) da CPU. :)
Arnauld
Impressionante! Não fazia ideia que o Intellivision tinha um buffer de quadros e um conjunto de caracteres embutido. Muito mais avançado que o Atari 2600, com certeza. Muito bem feito!
640KB 24/04
2
@gwaugh O GROM (para ROM de gráficos) contém todos os caracteres ASCII imprimíveis e algumas formas gráficas comuns. Curiosidade: ele também contém algum código executável que não se encaixava na ROM principal.
Arnauld
Definitivamente mais avançado que o 2600, mas se a memória servir, a Mattel não revelou nenhum dos itens avançados ocultos na ROM; portanto, os desenvolvedores de terceiros se limitaram ao código de máquina direto ou tiveram que procurar por conta própria os itens sofisticados . Pode ser apócrifo.
brhfl 25/04
11

Python 2 , 62 bytes

lambda n:[chr(i)for i in range(32,127)if bin(i).count('1')==n]

Experimente online!

Lynn
fonte
1
sum(map(int,bin(i)[2:]))==npode tornar bin(i).count('1')==n- se para salvar 7 bytes.
mypetlion
9

05AB1E , 8 bytes

žQʒÇbSOQ

Experimente online!

Explicação

ž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
Emigna
fonte
8

Perl 6 , 41 34 bytes

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

Experimente online!

Bloco de código anônimo que pega um número e retorna uma sequência de caracteres válidos.

Explicação:

{                                }  # 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)(modb-1)b(modb-1)=1

Podemos usar isso para obter o dígito do nosso número binário, analisando-o como um número decimal e modulando por 9, o que é válido porque o intervalo de números que estamos usando é garantido para ter menos de 9 bits. Isso é ajudado pela conversão automática do Perl 6 da string binária para um número decimal quando usado em um contexto numérico.

Brincadeira
fonte
7

Gelatina , 8 bytes

ØṖOB§=ʋƇ

Experimente online!

ØṖ       printable ascii character list
  OB     to binary
    §    popcount
     =   equal to input?
      ʋƇ filter (implicitly output)
Zylviij
fonte
7

JavaScript (Node.js) , 60 bytes

Usando o truque de módulo de Jo King

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

Experimente online!


JavaScript (Node.js) ,  70  69 bytes

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

Experimente online!

Comentado

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
Arnauld
fonte
60 bytes usando o truque de módulo de Jo.
Shaggy
@Shaggy Oh. Essa é boa.
Arnauld
6

Braquilog , 7 bytes

∈Ṭ&ạhḃ+

Experimente online!

Um predicado que funciona como um gerador , recebe entrada através de sua variável de saída e produz cada caractere através de sua variável de entrada. Porque 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).
String não relacionada
fonte
5

Japonês , 9 bytes

;EƶXc¤è1

Experimente ou teste todas as entradas

;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
Shaggy
fonte
5

Excel (2016 ou posterior), 76 bytes

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

Pega a entrada de A1, sai em qualquer célula que você coloca nesta fórmula. Esta é uma fórmula de matriz, então você precisa pressionar Ctrl+ Shift+ Enterpara inseri-la. O "2016 ou posterior" é porque precisa da CONCATfunção (o obsoleto CONCATENATEnão aceita uma matriz como argumento).

Sophia Lechner
fonte
Eu gosto disso. Eu sou um Lotus Notes e 123, então isso funciona para mim :-)
ElPedro
5

C (biblioteca padrão), 74 67 bytes

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

Usando apenas funções de biblioteca padrão. Agradecemos a @gastropner para melhorar de 74 a 67 bytes.

Experimente online!

Krista
fonte
1
67 bytes
gastropner 24/04
@gastropner que é uma melhoria incrível! Obrigado!
Krista
1
Eu acho que você precisa começar no índice 31 para ganhar espaço no f(1)caso (porque o ++iignora).
LambdaBeta 24/04
@LambdaBeta Você está absolutamente certo, obrigado!
Krista
5

R , 77 68 bytes

Abordagem usando o loop for

-9 bytes graças a Giuseppe

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

Experimente online!

Anteriormente:

R , 78 69 66 bytes

-12 bytes graças a Giuseppe

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

Transforma os números 32 a 126 em uma matriz de bits e depois soma nas linhas para descobrir qual corresponde ao número de entrada.

Experimente online!

Aaron Hayman
fonte
1
Use em intToBits(x)>0vez deas.single
Giuseppe
Bom, tentei |0e obtive um erro e presumi que os operadores lógicos não funcionariam.
Aaron Hayman
1
66 bytes para a abordagem "anterior" usando em sapplyvez dematrix
Giuseppe
4

Java 10, 98 97 94 70 67 bytes

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

-24 bytes graças a NahuelFouilleul .

Experimente online.

Explicação:

Contém um caractere não imprimível com valor 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
Kevin Cruijssen
fonte
1
-24bytes usando Long.bitCount
Nahuel Fouilleul
@NahuelFouilleul Ah, eu sempre esqueço o que é embutido em Java! Muito obrigado. E mais 3 bytes podem ser salvos usando n.bitCount. :)
Kevin Cruijssen 24/04
Sim, Java vence o JavaScript mais uma vez! Eu amo os desafios dos personagens: P
Olivier Grégoire
4

Java 8, 131 71 bytes

-60 bytes graças a todos nos comentários

Retorna um java.util.stream.IntStreamdos pontos de código

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

Experimente online!

Usando HashSet, 135 bytes. Retorna a 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(""));}}

Experimente online!

Benjamin Urquhart
fonte
128 bytes
Dados expirados
1
Acesso estático a partir de beneficiário de contexto não estático. Obrigado.
Benjamin Urquhart
Long.toBinaryString(i)pode serLong.toString(i,2);
Kevin Cruijssen 24/04
1
@KevinCruijssen, é o que meu primeiro comentário faz
Data de
1
@KevinCruijssen Você está certo. Aqui está a versão fixa: (ainda) 71 bytes . E sim, eu vi sua versão que votei há menos de 10 minutos;)
Olivier Grégoire
4

Dyalog APL estendido, 24 22 bytes

ucs a⌿⍨⎕=+⌿2a32126

Experimente online!

-2 bytes graças a ngn

Alternativa 22 bytes no Dyalog APL regular por ngn:

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

Experimente online!

dzaima
fonte
(expr )∘=-> ⎕=expr
ngn
sem extensão: ⎕ucs 32+⍸⎕=32↓+/↑,⍳7⍴2(←io ← 0)
ngn
3

Python 2 , 69 bytes

lambda n:[chr(i)for i in range(32,127)if sum(map(int,bin(i)[2:]))==n]

Experimente online!

Neil
fonte
1
Foi exatamente isso que recebi quando joguei minha implementação de árbitro. +1
ElPedro 23/04
3

Gaia , 10 bytes

₵R⟪¤cbΣ=⟫⁇

Experimente online!

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

J , 31 27 bytes

-4 bytes graças a Galen

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

Experimente online!

Resposta original

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

Experimente online!

  • 2#:@i.@^8:produz os números binários de 0 a 255 ( 2 ^ 8é 256)
  • 1#. soma cada um
  • ]= produz uma máscara binária mostrando onde a soma é igual à entrada original
  • a.#~ mask usa essa máscara binária para filtrar o alfabeto ascii completo de J a.
  • &(95{.32}.]) mas antes de fazer isso, pegue apenas os elementos 32 ... 126 do alfabeto e da máscara
Jonah
fonte
[:u:32+[:I.]=1#.32#:@+i.@95para 27 bytes
Galen Ivanov
Obrigado Galen. Até que você poderia fazeri.@95
Jonah
3

Perl 5 -a , 50 43 bytes

@NahuelFouilleul salva 7 bytes

map{$_=chr;unpack('B*')%9-"@F"||say}32..126

Experimente online!

Xcali
fonte
poderia salvar um byte usando em "@F"vez de$F[0]
Nahuel Fouilleul
48 bytes
Nahuel Fouilleul 24/04
1
43 bytes using %9trick por @JoKing
Nahuel Fouilleul 24/04
3

K (ngn / k) , 20 bytes

Solução:

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

Experimente online!

Explicação:

Avaliada da direita para a esquerda:

`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
rua
fonte
3

6502 assembly (NES), 22 bytes

Código da máquina:

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

Montagem:

    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

Programa completo . Testado com o FCEUX 2.2.3, deve funcionar em qualquer emulador NES padrão.

Inspirado pela resposta de Ryan Russell. Entrada fornecida no endereço da CPU $ 60. Saídas para a memória da unidade de processamento de imagens do console.

sete negativos
fonte
2
Olá e bem-vindo ao PPCG. Existe alguma maneira de verificar sua solução além da construção de um cartucho, ou seja, um emulador ou especificação (online)?
Jonathan Frech
@ JonathanFrech Adicionei um programa completo que pode ser montado e executado localmente. Pelo que entendi, o ambiente NES não é realmente padronizado para o codegolf.
negativo sete
2

PowerShell , 83 bytes

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

Experimente online!

Recebe entrada $n, constrói um intervalo de 32até 126e retira esses números onde |?{}: o número, converted ToStringna base 2; toCharArra convertido y; grouped em 0s e 1s; tomando o [1]índice desse agrupamento; pegando o .countmesmo e verificando se é -eqútil para o nosso número de entrada $n. Esses números são lançados como uma charmatriz e deixados no pipeline. A saída é implícita, com novas linhas entre elementos.

AdmBorkBork
fonte
2

Carvão , 10 bytes

Φγ⁼Σ↨℅ι²Iθ

Experimente online! Link é a versão detalhada do código. Explicação:

 γ          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
Neil
fonte
2

PHP , 72 bytes

for($x=31;$x++<126;)echo$argn==count_chars(decbin($x),1)[49]?chr($x):'';

Experimente online!

Russ G
fonte
1
count_chars(decbin($x),1)[49]pode apenas serdecbin($x)%9
Jo King
2

Fator , 94 bytes

: f ( n -- n s ) 94 [0,b] [ 32 + 2 >base [ 49 = ] count over = ] filter [ 32 + ] map >string ;

Experimente online!

Galen Ivanov
fonte
Essa é uma quantidade impressionante de espaço em branco necessário
Unrelated String
1
@ String não relacionada sim, é :)
Galen Ivanov