# All ASCII characters with a given bit count

(Title with thanks to @ChasBrown)

The Background

This challenge is inspired by a question that I recently posted on Puzzling Stack Exchange. Please feel free to follow the link if you are interested in the original question. If not then I won't bore you with the details here.

The Facts

Every printable standard ASCII character has a decimal value between 32 and 126 inclusive. These can be converted to their corresponding binary numbers in the range 100000 to 1111110 inclusive. When you sum the bits of these binary numbers you will always end up with an integer between 1 and 6 inclusive.

The Challenge

Given an integer between 1 and 6 inclusive as input, write a program or function which will output in any acceptable format all of the printable standard ASCII characters where the sum of the bits of their binary value is equal to the input integer.

The Examples/Test Cases

1 -> ' @'
2 -> '!"$(0ABDHP' 3 -> '#%&)*,1248CEFIJLQRTXabdhp' 4 -> ''+-.3569:<GKMNSUVYZ\cefijlqrtx' 5 -> '/7;=>OW[]^gkmnsuvyz|' 6 -> '?_ow{}~' An ungolfed Python reference implementation is available here (TIO). The Rules 1. Assume the input will always be an integer (or string representation of an integer) between 1 and 6 inclusive. 2. You may write a program to display the results or a function to return them. 3. Output may be in any reasonable format but must be consistent for all inputs. If you choose to output a quoted string then the same type of quotes must be used for all inputs. 4. Standard loopholes prohibited as usual. 5. This is code golf so shortest code in each language wins. • Are we allowed to return/print a list of the decimal ascii values or do we need to have them in the form of characters (eg. 63 vs ?)? – Benjamin Urquhart Apr 23 '19 at 19:27 • Must be the actual characters. – ElPedro Apr 23 '19 at 19:29 • "the same type of quotes must be used for all inputs" Python, for example, uses single quotes (') for the string representation of a string by default, but uses double quotes (") if the string contain a single quote and no double quotes. Not that this specific case will matter much, as you're probably better off returning the actual string instead of its representation, and you can still use single quotes in such a string for input anyway, but I feel it's worth mentioning here. – Erik the Outgolfer Apr 23 '19 at 19:59 • @EriktheOutgolfer Agreed. That is why I thought it might be interesting just to throw that in as an extra rule :-) – ElPedro Apr 23 '19 at 23:03 • @ElPedro I wasn't sure what to do as it is probably a good idea to have some quotes, as there is a space in the first example, but the usual quotes both appear in the output:) Edit: maybe use french guillemets (« »)? :D – flawr Apr 24 '19 at 13:11 ## 52 Answers # 8088 assembly, IBM PC DOS, 3530 29 bytes Machine code: be81 00ad 8afc b330 b108 d0c8 12dd e2fa 3afb 7504 b40e cd10 fec0 79ea c3 Listing: 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 Standalone PC DOS executable program, input number from command line. Output is displayed to console window. Download and test ABCT.COM (AsciiBitCounT). • For a moment I thought it said "Download and test AT ABCT.COM", as if you had registered a domain just for this answer. – Sparr Apr 24 '19 at 1:16 # CP-1610 assembly (Intellivision), 20 DECLEs1 = 25 bytes Takes $$\N\$$ in R0 and a pointer to the output buffer in R4. Writes all matching characters in the buffer and marks the end of the results with 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 ### Output for N=2 NB: The opening parenthesis looks a lot like an opening square bracket in the Intellivision font. Both characters are distinct, though. screenshot from jzIntv 1. A CP-1610 opcode is encoded with a 10-bit value, known as a 'DECLE'. This routine is 20 DECLEs long, starting at$4819 and ending at $482C (included). • +1 just for being (a) a solution for the Intellivision, and (b) the first Intellivision code I've ever seen. – Eight-Bit Guru Apr 24 '19 at 8:11 • @Eight-BitGuru Coding on the Intellivision is pretty fun. And today's homebrew games are written in 16-bit ROM, which unlocks the full power (ahem...) of the CPU. :) – Arnauld Apr 24 '19 at 8:23 • Impressive! Had no idea the Intellivision had a frame buffer and a built in character set. So much more advanced than the Atari 2600 for sure. Very nicely done! – 640KB Apr 24 '19 at 14:04 • @gwaugh The GROM (for Graphics ROM) contains all printable ASCII characters and a few common graphical shapes. Fun fact: it also contains some executable code that did not fit in the main ROM. – Arnauld Apr 24 '19 at 14:09 • Definitely more advanced than the 2600, but if memory serves, Mattel didn’t reveal any of the advanced stuff hiding out in ROM, so third-party devs were either limited to straight machine code or had to suss out the fancy stuff on their own. Might be apocryphal. – brhfl Apr 25 '19 at 23:40 # Python 2, 62 bytes lambda n:[chr(i)for i in range(32,127)if bin(i).count('1')==n] Try it online! • sum(map(int,bin(i)[2:]))==n can become bin(i).count('1')==n to save 7 bytes. – mypetlion May 1 '19 at 22:14 # 05AB1E, 8 bytes žQʒÇbSOQ Try it online! Explanation ž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 # Perl 6, 41 34 bytes {chrs grep *.base(2)%9==$_,^95+32}

Try it online!

Anonymous code block that takes a number and returns a string of valid characters.

### Explanation:

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

Try it online!

# K (ngn/k), 20 bytes

Solution:

c$32+&(+/2\32+!95)= Try it online! Explanation: Evaluated right-to-left: 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
c$/ cast to character # 6502 assembly (NES), 22 bytes Machine code: a0 1f a6 60 c8 98 30 fb ca 0a b0 fc d0 fb e8 d0 f1 8c 07 20 f0 ec Assembly: 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 Full program. Tested with FCEUX 2.2.3, should work on any standard NES emulator. Inspired by Ryan Russell's answer. Input given at CPU address$60. Outputs to the console's Picture Processing Unit memory.

• Hello and welcome to PPCG. Is there any way to verify your solution apart from building a cartridge, i.e. an (online) emulator or specification? – Jonathan Frech Apr 28 '19 at 21:03
• @JonathanFrech I've added a full program that can be assembled and run locally. As I understand, the NES environment is not really standardized for codegolf. – negative seven Apr 29 '19 at 9:30

# Wolfram Language (Mathematica), 70 bytes

FromCharacterCode/@Select[32~Range~126,s=#;Tr@IntegerDigits[#,2]==s&]&

Try it online!

param($n)[char[]](32..126|?{([convert]::ToString($_,2)|% t*y|group)[1].count-eq$n}) Try it online! Takes input$n, constructs a range from 32 to 126 and pulls out those numbers where |?{}: the number, converted ToString in base 2; converted toCharArray; grouped into 0s and 1s; taking the [1] index of that grouping; taking the .count thereof, and checking that it's -equal to our input $number. Those numbers are then cast as a char-array and left on the pipeline. Output is implicit, with newlines between elements. # Ruby, 48 bytes ->n{(' '..?~).select{|x|x.ord.digits(2).sum==n}} Try it online! # Charcoal, 10 bytes Φγ⁼Σ↨℅ι²Ｉθ 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 Ｉ Cast to integer Implicitly printed # PHP, 72 bytes for($x=31;$x++<126;)echo$argn==count_chars(decbin($x),1)[49]?chr($x):'';

Try it online!

• count_chars(decbin($x),1)[49] can just be decbin($x)%9 – Jo King Apr 24 '19 at 10:00

# 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!

# Octave with Communications Package, 32 bytes

@(n)t(sum(de2bi(t=' ':'~')')==n)

Try it online!

# Factor, 94 bytes

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

Try it online!

• That is an impressive amount of necessary whitespace – Unrelated String Apr 24 '19 at 21:09
• @Unrelated String yes, it is :) – Galen Ivanov Apr 25 '19 at 3:55