Все символы 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. Это кодовый гольф, поэтому выигрывает самый короткий код на каждом языке.

Разрешено ли нам возвращать / распечатывать список десятичных значений 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).


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 долларов США (в комплекте).


5
+1 только за то, что (а) решение для Intellivision, и (б) первый код Intellivision, который я когда-либо видел.
Восьмибитный Гуру

3
@ Eight-BitGuru Кодирование на Intellivision - это довольно весело. А сегодняшние доморощенные игры написаны в 16-битном ПЗУ, которое разблокирует полную мощность (хм ...) процессора. :)
Арно

Впечатляет! Не знал, что Intellivision имеет рамочный буфер и встроенный набор символов. Конечно, намного более продвинутый, чем Atari 2600. Очень красиво сделано!
640KB

2
@gwaugh GROM (для графического ПЗУ) содержит все печатные символы ASCII и несколько распространенных графических фигур. Интересный факт: он также содержит некоторый исполняемый код, который не помещается в основном ПЗУ.
Арно

Определенно более продвинутый, чем 2600, но если память не откажется, Mattel не обнаружит каких-либо продвинутых вещей, скрывающихся в ПЗУ, поэтому сторонние разработчики либо ограничивались прямым машинным кодом, либо должны были сами разобраться в причудливых вещах. , Может быть апокрифическим.
brhfl



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

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 байт.

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



@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(""));}}

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



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"непечатаемыми, сохраняя три байта.

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



@ExpiredData Спасибо за идею, чтобы использовать Sum()!
Воплощение Невежества




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 из алфавита и маски


Спасибо, Гален. 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

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 и оставляются на конвейере. Вывод неявный, с символами новой строки между элементами.







Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.