Tous les caractères ASCII avec un nombre de bits donné

30

(Titre avec merci à @ChasBrown)

bac à sable

L'arrière-plan

Ce défi est inspiré d'une question que j'ai récemment publiée sur Puzzling Stack Exchange . N'hésitez pas à suivre le lien si vous êtes intéressé par la question d'origine. Sinon, je ne vous ennuierai pas avec les détails ici.

Les faits

Chaque caractère ASCII standard imprimable a une valeur décimale comprise entre 32 et 126 inclus. Ceux-ci peuvent être convertis en leurs nombres binaires correspondants dans la plage 100000 à 1111110 inclus. Lorsque vous additionnez les bits de ces nombres binaires, vous vous retrouverez toujours avec un entier compris entre 1 et 6 inclus.

Le défi

Étant donné un entier compris entre 1 et 6 inclus en entrée, écrivez un programme ou une fonction qui produira dans n'importe quel format acceptable tous les caractères ASCII standard imprimables où la somme des bits de leur valeur binaire est égale à l'entier en entrée.

Les exemples / cas de test

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

Une implémentation de référence Python non golfée est disponible ici (TIO) .

Les règles

  1. Supposons que l'entrée sera toujours un entier (ou une représentation sous forme de chaîne d'un entier) entre 1 et 6 inclus.
  2. Vous pouvez écrire un programme pour afficher les résultats ou une fonction pour les renvoyer.
  3. La sortie peut être dans n'importe quel format raisonnable mais doit être cohérente pour toutes les entrées . Si vous choisissez de sortir une chaîne entre guillemets, le même type de guillemets doit être utilisé pour toutes les entrées.
  4. Échappatoires standard interdites comme d'habitude.
  5. C'est le code golf, donc le code le plus court dans chaque langue l'emporte.
ElPedro
la source
Sommes-nous autorisés à retourner / imprimer une liste des valeurs ascii décimales ou devons-nous les avoir sous forme de caractères (par exemple, 63vs ?)?
Benjamin Urquhart
1
Doit être les personnages réels.
ElPedro
7
"le même type de guillemets doit être utilisé pour toutes les entrées" Python, par exemple, utilise des guillemets simples ( ') pour la représentation sous forme de chaîne d'une chaîne par défaut, mais utilise des guillemets doubles ( ") si la chaîne contient un guillemet simple et pas de guillemets doubles . Non pas que ce cas spécifique importera beaucoup, car vous feriez probablement mieux de renvoyer la chaîne réelle au lieu de sa représentation, et vous pouvez toujours utiliser des guillemets simples dans une telle chaîne pour l'entrée, mais je pense qu'il vaut la peine de mentionner ici.
Erik the Outgolfer
@EriktheOutgolfer a accepté. C'est pourquoi j'ai pensé qu'il pourrait être intéressant de simplement
ajouter
1
@ElPedro Je ne savais pas quoi faire car c'est probablement une bonne idée d'avoir des guillemets, car il y a un espace dans le premier exemple, mais les guillemets habituels apparaissent tous les deux dans la sortie :) Edit: peut-être utiliser des guillemets français ( « »)? : D
flawr

Réponses:

29

Assemblage 8088, IBM PC DOS, 35 30 29 octets

Langage machine:

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

Inscription:

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

Programme exécutable PC DOS autonome, entrez le numéro à partir de la ligne de commande. La sortie s'affiche dans la fenêtre de la console.

enter image description here

Téléchargez et testez ABCT.COM (AsciiBitCounT).

640 Ko
la source
8
Pour un moment , je pensais dire « Téléchargez et testez AT ABCT.COM », comme si vous aviez enregistré un domaine juste pour cette réponse.
Sparr
14

Ensemble CP-1610 ( Intellivision ), 20 DECLEs 1 = 25 octets

Prend N dans R0 et un pointeur vers le tampon de sortie dans R4 . Écrit tous les caractères correspondants dans le tampon et marque la fin des résultats avec NUL .

                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

Sortie pour N = 2

NB: La parenthèse ouvrante ressemble beaucoup à un crochet ouvrant dans la police Intellivision. Les deux personnages sont cependant distincts.

output

capture d'écran de jzIntv


1. Un opcode CP-1610 est codé avec une valeur de 10 bits, connue sous le nom de «DECLE». Cette routine dure 20 DECLEs, commençant à 4819 $ et se terminant à 482C $ (inclus).

Arnauld
la source
5
+1 juste pour être (a) une solution pour Intellivision, et (b) le premier code Intellivision que j'ai jamais vu.
Gourou de huit bits le
3
@ Eight-BitGuru Le codage sur Intellivision est assez amusant. Et les jeux homebrew d'aujourd'hui sont écrits en ROM 16 bits, ce qui déverrouille la pleine puissance (ahem ...) du CPU. :)
Arnauld
Impressionnant! Je ne savais pas que l'Intellivision avait un tampon de trame et un jeu de caractères intégré. Bien plus avancé que l'Atari 2600, c'est sûr. Très bien fait!
640 Ko le
2
@gwaugh Le GROM (pour Graphics ROM) contient tous les caractères ASCII imprimables et quelques formes graphiques courantes. Fait amusant: il contient également du code exécutable qui ne tenait pas dans la ROM principale.
Arnauld
Certainement plus avancé que le 2600, mais si la mémoire est bonne, Mattel n'a révélé aucun des éléments avancés cachés dans la ROM, de sorte que les développeurs tiers étaient limités au code machine simple ou devaient analyser eux-mêmes les éléments de fantaisie . Pourrait être apocryphe.
brhfl
11

Python 2 , 62 octets

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

Essayez-le en ligne!

Lynn
la source
1
sum(map(int,bin(i)[2:]))==npeut devenir bin(i).count('1')==npour économiser 7 octets.
mypetlion
9

05AB1E , 8 octets

žQʒÇbSOQ

Essayez-le en ligne!

Explication

ž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
la source
8

Perl 6 , 41 34 octets

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

Essayez-le en ligne!

Bloc de code anonyme qui prend un nombre et renvoie une chaîne de caractères valides.

Explication:

{                                }  # 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

On peut prouver que pour tout nombre n dans la base b , ndigitsum(n)(modb1) (indice: rappelez-vous queb(modb1)=1 ).

Nous pouvons l'utiliser pour obtenir la somme des chiffres de notre nombre binaire en l'analysant comme un nombre décimal et en le modulant par 9, ce qui est valide car la plage de nombres que nous utilisons est garantie d'avoir moins de 9 bits. Ceci est aidé par la conversion automatique de Perl 6 de la chaîne binaire en nombre décimal lorsqu'elle est utilisée dans un contexte numérique.

Jo King
la source
7

Gelée , 8 octets

ØṖOB§=ʋƇ

Essayez-le en ligne!

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

JavaScript (Node.js) , 60 octets

Utiliser l'astuce modulo de Jo King

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

Essayez-le en ligne!


JavaScript (Node.js) ,  70  69 octets

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

Essayez-le en ligne!

Commenté

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
la source
60 octets en utilisant l'astuce modulo de Jo.
Shaggy
@Shaggy Oh. Voilà une belle.
Arnauld
6

Brachylog , 7 octets

∈Ṭ&ạhḃ+

Essayez-le en ligne!

Un prédicat qui fonctionne comme un générateur , prend l'entrée via sa variable de sortie et produit chaque caractère via sa variable d'entrée. Parce que 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).
Chaîne indépendante
la source
5

Japt , 9 octets

;EƶXc¤è1

Essayez-le ou testez toutes les entrées

;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
Hirsute
la source
5

Excel (2016 ou version ultérieure), 76 octets

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

Prend l'entrée de A1, sort dans la cellule dans laquelle vous mettez cette formule. Il s'agit d'une formule matricielle, vous devez donc appuyer sur Ctrl+ Shift+ Enterpour la saisir. Le "2016 ou plus tard" est dû au fait qu'il a besoin de la CONCATfonction (le déconseillé CONCATENATEne prendra pas un tableau comme argument).

Sophia Lechner
la source
J'aime ça. Je suis un mec Lotus Notes et 123 donc ça marche pour moi :-)
ElPedro
5

C (bibliothèque standard), 74 67 octets

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

Utilisation uniquement des fonctions de bibliothèque standard. Merci à @gastropner pour l'amélioration de 74 à 67 octets.

Essayez-le en ligne!

Krista
la source
1
67 octets
gastropner
@gastropner c'est une amélioration incroyable! Merci!
Krista
1
Je pense que vous devez commencer à l'index 31 afin de prendre de la place dans le f(1)boîtier (car le ++isaute).
LambdaBeta
@LambdaBeta Vous avez absolument raison, merci!
Krista
5

R , 77 68 octets

Approche utilisant pour boucle

-9 octets grâce à Giuseppe

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

Essayez-le en ligne!

Précédemment:

R , 78 69 66 octets

-12 octets grâce à Giuseppe

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

Transforme les nombres 32 à 126 en une matrice de bits, puis additionne les lignes pour trouver celles qui correspondent au numéro d'entrée.

Essayez-le en ligne!

Aaron Hayman
la source
1
Utilisez intToBits(x)>0plutôt queas.single
Giuseppe
Bien, j'ai essayé |0et obtenu une erreur et j'ai simplement supposé que les opérateurs logiques ne fonctionneraient pas.
Aaron Hayman
1
66 octets pour l'approche "précédente" en utilisant sapplyplutôt quematrix
Giuseppe
4

Java 10, 98 97 94 70 67 octets

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

-24 octets grâce à NahuelFouilleul .

Essayez-le en ligne.

Explication:

Contient un caractère non imprimable avec une valeur 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
la source
1
-24 octets utilisant Long.bitCount
Nahuel Fouilleul
@NahuelFouilleul Ah, j'oublie toujours ce builtin en Java! Merci beaucoup. Et 3 octets supplémentaires peuvent être enregistrés en utilisant n.bitCount. :)
Kevin Cruijssen
Ouais, Java bat encore JavaScript! J'adore ces défis de caractère: P
Olivier Grégoire
4

Java 8, 131 71 octets

-60 octets merci à tout le monde dans les commentaires

Retourne un java.util.stream.IntStreamdes codepoints

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

Essayez-le en ligne!

Utilisation de HashSet, 135 octets. Renvoie un 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(""));}}

Essayez-le en ligne!

Benjamin Urquhart
la source
128 octets
Données expirées le
1
Accès statique à partir du contexte non statique reeeeeee. Merci.
Benjamin Urquhart
Long.toBinaryString(i)peut êtreLong.toString(i,2);
Kevin Cruijssen
1
@KevinCruijssen c'est ce que fait mon premier commentaire
Expired Data
1
@KevinCruijssen Vous avez raison. Voici la version fixe: (toujours) 71 octets . Et oui, j'ai vu votre version que j'ai votée il y a moins de 10 minutes;)
Olivier Grégoire
4

C # (Visual C # Interactive Compiler) , 86 octets

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

Merci à @ExpiredData de m'avoir donné l'idée d'utiliser Sum()! Quand je reviens à mon PC, je vais remplacer la chaîne "0123456"par des non imprimables, économisant trois octets.

Essayez-le en ligne!

Incarnation de l'ignorance
la source
1
Sum et - au lieu de Count et ==
Données expirées le
@ExpiredData Merci pour l'idée d'utiliser Sum()!
Incarnation de l'ignorance
4

Dyalog APL Extended, 24 22 octets

ucs a⌿⍨⎕=+⌿2a32126

Essayez-le en ligne!

-2 octets grâce à ngn

Alternative 22 octets dans Dyalog APL régulier par ngn:

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

Essayez-le en ligne!

dzaima
la source
(expr )∘=-> ⎕=expr
ngn
sans extension: ⎕ucs 32+⍸⎕=32↓+/↑,⍳7⍴2(⎕io ← 0)
ngn
3

Python 2 , 69 octets

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

Essayez-le en ligne!

Neil
la source
1
C'est exactement ce que j'ai obtenu lorsque j'ai joué à mon implémentation d'arbitrage. +1
ElPedro
3

Gaia , 10 octets

₵R⟪¤cbΣ=⟫⁇

Essayez-le en ligne!

		| 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
la source
3

J , 31 27 octets

-4 octets grâce à Galen

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

Essayez-le en ligne!

Réponse originale

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

Essayez-le en ligne!

  • 2#:@i.@^8: produit les nombres binaires 0 à 255 (2 ^ 8 soit 256)
  • 1#. somme chacun
  • ]= produit un masque binaire indiquant où la somme est égale à l'entrée d'origine
  • a.#~ mask utilise ce masque binaire pour filtrer l'alphabet ascii complet de J a.
  • &(95{.32}.]) mais avant de le faire, ne prenez que les éléments 32 ... 126 de l'alphabet et du masque
Jonas
la source
[:u:32+[:I.]=1#.32#:@+i.@95pour 27 octets
Galen Ivanov
Merci Galen. TIL que vous pourriez fairei.@95
Jonah
3

Perl 5 -a , 50 43 octets

@NahuelFouilleul économise 7 octets

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

Essayez-le en ligne!

Xcali
la source
pourrait sauver un octet en utilisant "@F"au lieu de$F[0]
Nahuel Fouilleul
48 octets
Nahuel Fouilleul
1
43 octets en utilisant %9astuce par @JoKing
Nahuel Fouilleul
3

K (ngn / k) , 20 octets

Solution:

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

Essayez-le en ligne!

Explication:

Évalué de droite à gauche:

`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
streetster
la source
3

6502 assembly (NES), 22 octets

Langage machine:

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

Assemblée:

    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

Programme complet . Testé avec FCEUX 2.2.3, devrait fonctionner sur n'importe quel émulateur NES standard.

Inspiré par la réponse de Ryan Russell. Entrée donnée à l'adresse CPU 60 $. Sorties vers la mémoire de l'unité de traitement d'images de la console.

sept négatif
la source
2
Bonjour et bienvenue chez PPCG. Existe-t-il un moyen de vérifier votre solution en dehors de la construction d'une cartouche, c'est-à-dire un émulateur (en ligne) ou une spécification?
Jonathan Frech
@JonathanFrech J'ai ajouté un programme complet qui peut être assemblé et exécuté localement. Si je comprends bien, l'environnement NES n'est pas vraiment standardisé pour codegolf.
négatif sept
2

PowerShell , 83 octets

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

Essayez-le en ligne!

Prend des entrées $n, construit une plage de 32à 126et extrait ces nombres où |?{}: le nombre, convertéd ToStringen base 2; toCharArra converti y; grouped en 0s et 1s; prendre l' [1]index de ce regroupement; en prenant .countcelui - ci, et en vérifiant qu'il est -equal à notre $nombre d' entrée . Ces nombres sont ensuite charconvertis en tableau et laissés sur le pipeline. La sortie est implicite, avec des retours à la ligne entre les éléments.

AdmBorkBork
la source
2

Charcoal, 10 bytes

Φγ⁼Σ↨℅ι²Iθ

Try it online! Link is to verbose version of code. Explanation:

 γ          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
la source
2

PHP, 72 bytes

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

Try it online!

Russ G
la source
1
count_chars(decbin($x),1)[49] can just be decbin($x)%9
Jo King
2

Red, 92 bytes

func[n][repeat k 95[if n = length? replace/all enbase/base c: form #"^_"+ k 2"0"""[prin c]]]

Try it online!

Galen Ivanov
la source
2

Factor, 94 bytes

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

Try it online!

Galen Ivanov
la source
That is an impressive amount of necessary whitespace
Unrelated String
1
@Unrelated String yes, it is :)
Galen Ivanov