Все символы ASCII с заданным количеством битов

30

(Название с благодарностью @ChasBrown)

песочница

Фон

Эта проблема вдохновлена ​​вопросом, который я недавно разместил на бирже стека Puzzling . Пожалуйста, не стесняйтесь переходить по ссылке, если вас интересует оригинальный вопрос. Если нет, то я не буду утомлять вас деталями здесь.

Факты

Каждый печатный стандартный символ ASCII имеет десятичное значение от 32 до 126 включительно. Их можно преобразовать в соответствующие им двоичные числа в диапазоне от 100000 до 1111110 включительно. Когда вы суммируете биты этих двоичных чисел, вы всегда получите целое число от 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. Это кодовый гольф, поэтому выигрывает самый короткий код на каждом языке.
ElPedro
источник
Разрешено ли нам возвращать / распечатывать список десятичных значений ascii или нам нужно иметь их в виде символов (например, 63vs ?)?
Бенджамин Уркхарт
1
Должны быть настоящие персонажи.
ElPedro
7
«одинаковые кавычки должны использоваться для всех входных данных» Например, Python 'по умолчанию использует одинарные кавычки ( ) для строкового представления строки, но использует двойные кавычки ( "), если строка содержит одинарные кавычки и не содержит двойных кавычек. , Не то чтобы этот конкретный случай имел большое значение, так как вам, вероятно, лучше возвращать реальную строку вместо ее представления, и вы все равно можете использовать одинарные кавычки в такой строке для ввода, но я чувствую, что стоит упомянуть здесь.
Эрик Outgolfer
@EriktheOutgolfer Согласен. Вот почему я подумал, что было бы интересно
добавить
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

Автономная исполняемая программа для ПК с DOS, введите номер из командной строки. Выход отображается в окне консоли.

введите описание изображения здесь

Загрузите и протестируйте ABCT.COM (AsciiBitCounT).

640 КБ
источник
8
Какое-то время я думал, что там написано «Скачайте и протестируйте AT ABCT.COM», как будто вы зарегистрировали домен только для этого ответа.
Спарр
14

Сборка CP-1610 ( Intellivision ), 20 DECLEs 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

NB. Открывающая круглая скобка очень похожа на открывающую квадратную скобку в шрифте Intellivision. Хотя оба персонажа различны.

выход

скриншот с jzIntv


1. Код операции CP-1610 кодируется 10-битным значением, известным как «DECLE». Длина этой процедуры составляет 20 DECLE, начиная с 4819 долларов США и заканчивая 482 долларов США (в комплекте).

Arnauld
источник
5
+1 только за то, что (а) решение для Intellivision, и (б) первый код Intellivision, который я когда-либо видел.
Восьмибитный Гуру
3
@ Eight-BitGuru Кодирование на Intellivision - это довольно весело. А сегодняшние доморощенные игры написаны в 16-битном ПЗУ, которое разблокирует полную мощность (хм ...) процессора. :)
Арно
Впечатляет! Не знал, что Intellivision имеет рамочный буфер и встроенный набор символов. Конечно, намного более продвинутый, чем Atari 2600. Очень красиво сделано!
640KB
2
@gwaugh GROM (для графического ПЗУ) содержит все печатные символы ASCII и несколько распространенных графических фигур. Интересный факт: он также содержит некоторый исполняемый код, который не помещается в основном ПЗУ.
Арно
Определенно более продвинутый, чем 2600, но если память не откажется, Mattel не обнаружит каких-либо продвинутых вещей, скрывающихся в ПЗУ, поэтому сторонние разработчики либо ограничивались прямым машинным кодом, либо должны были сами разобраться в причудливых вещах. , Может быть апокрифическим.
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
Emigna
источник
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 байт

Используя трюк по модулю Джо Кинга

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
Arnauld
источник
60 байтов, используя трюк по модулю Джо.
лохматый
@ Шэгги Ох. Это хорошо.
Арно
6

Брахилог , 7 байт

∈Ṭ&ạhḃ+

Попробуйте онлайн!

Предикат, который функционирует как генератор , получает входные данные через свою выходную переменную и создает каждый символ через свою входную переменную. Потому что брахилог.

           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не будет принимать массив в качестве аргумента).

София Лехнер
источник
Мне это нравится. Я Lotus Notes и 123 парня, так что это работает для меня :-)
ElPedro
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 байт.

Попробуйте онлайн!

Криста
источник
1
67 байт
гастропнер
@gastropner - это удивительное улучшение! Спасибо!
Криста
1
Я думаю, что вам нужно начать с индекса 31, чтобы занять место в f(1)футляре (потому что ++iпропускает его).
LambdaBeta
@LambdaBeta Вы абсолютно правы, спасибо!
Криста
5

R , 77 68 байт

Подход, используя для цикла

-9 байт благодаря Джузеппе

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

Попробуйте онлайн!

Ранее:

R , 78 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
Джузеппе
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 .

Попробуйте онлайн.

Объяснение:

Содержит непечатаемый символ со значением Юникода 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
-24 байта с использованием Long.bitCount
Науэль Фуйе
@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(""));}}

Попробуйте онлайн!

Бенджамин Уркхарт
источник
128 байтов
просроченные данные
1
Статический доступ из нестатического контекста получателя. Спасибо.
Бенджамин Уркхарт
Long.toBinaryString(i)может бытьLong.toString(i,2);
Кевин Круйссен
1
@KevinCruijssen это то, что делает мой первый комментарий
действия данных
1
@KevinCruijssen Ты прав. Вот исправленная версия: (все еще) 71 байт . И да, я видел вашу версию, за которую проголосовал менее 10 минут назад;)
Оливье Грегуар
4

C # (интерактивный компилятор Visual C #) , 86 байт

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

Спасибо @ExpiredData за предоставленную мне идею использовать Sum()! Когда я вернусь к своему ПК, я заменю строку "0123456"непечатаемыми, сохраняя три байта.

Попробуйте онлайн!

Воплощение невежества
источник
1
Сумма и - вместо количества и ==
просроченные данные
@ExpiredData Спасибо за идею, чтобы использовать Sum()!
Воплощение Невежества
4

Dyalog APL Extended, 24 22 байта

ucs a⌿⍨⎕=+⌿2a32126

Попробуйте онлайн!

-2 байта благодаря ngn

Альтернатива 22 байта в обычном Dyalog APL от ngn:

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

Попробуйте онлайн!

dzaima
источник
(expr )∘=-> ⎕=expr
ngn
без продления: ⎕ucs 32+⍸⎕=32↓+/↑,⍳7⍴2(⎕io ← 0)
нгн
3

J , 31 27 байт

-4 байта благодаря Галену

[: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 использует эту двоичную маску для фильтрации полного алфавита ASCII J a.
  • &(95{.32}.]) но перед этим возьмите только элементы 32 ... 126 из алфавита и маски
Ион
источник
[:u:32+[:I.]=1#.32#:@+i.@95для 27 байтов
Гален Иванов
Спасибо, Гален. TIL вы могли бы сделатьi.@95
Иона
3

К (нгн / к) , 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
streetster
источник
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.

Вдохновлен ответом Райана Рассела. Ввод данных по адресу процессора $ 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и вытаскивает те числа, где |?{}: число, converted ToStringв базе 2; преобразованная tоЧарАрра y; groupедь в 0с и 1с; взять [1]индекс этой группировки; взяв .countих, и проверив, что все в порядке -eqс нашими входными $nданными. Эти числа затем выводятся как char-array и оставляются на конвейере. Вывод неявный, с символами новой строки между элементами.

AdmBorkBork
источник
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
Нил
источник
2

Фактор , 94 байта

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

Попробуйте онлайн!

Гален Иванов
источник
Это внушительное количество необходимого пробела
Несвязанная строка
1
@ Несвязанная строка да, это так :)
Гален Иванов