Усі символи ASCII з заданим числом біт


30

(Назва з подякою @ChasBrown)

Пісочниця

Фон

Цей виклик натхненний питанням, яке я нещодавно опублікував на Puzzling Stack Exchange . Будь ласка, не соромтесь перейти за посиланням, якщо вас цікавить оригінальне запитання. Якщо ні, то я не набридаю вам тут деталями.

Факти

Кожен стандартний символ 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. Це код гольфу, тому найкоротший код на кожній мові виграє.

Чи дозволено нам повернути / роздрукувати список значень десяткової ассії чи нам потрібно мати їх у вигляді символів (наприклад, 63vs ?)?
Бенджамін Уркхарт

1
Повинні бути фактичні символи.
ElPedro

7
"однаковий тип лапок повинен використовуватися для всіх входів" Python, наприклад, використовує одиночні лапки ( ') для представлення рядка рядка за замовчуванням, але використовує подвійні лапки ( "), якщо рядок містить одну цитату і немає подвійних лапок . Не те, що цей конкретний випадок матиме велике значення, оскільки вам, мабуть, краще повернути фактичний рядок замість його подання, і ви все одно можете використовувати одинарні лапки в такому рядку для введення, але я вважаю, що тут варто згадати.
Ерік Аутгольфер

@EriktheOutgolfer Погодився. Ось чому я подумав, що це може бути цікаво просто закинути це як додаткове правило :-)
ElPedro

1
@ElPedro Я не був упевнений, що робити, тому що, мабуть, гарна ідея мати кілька цитат, оскільки в першому прикладі є пробіл, але звичайні цитати з'являються у висновку :) Редагувати: можливо, використовувати французькі гільємети ( « »)? : D
недолік

Відповіді:


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, номер введення з командного рядка. Вихід відображається у вікні консолі.

enter image description here

Завантажте та протестуйте ABCT.COM (AsciiBitCounT).


8
На мить я подумав , що сказав «Завантажити та тест AT ABCT.COM», як якщо б ви зареєстрували домен тільки для цієї відповіді.
Спарр

14

Збірка CP-1610 ( Intellivision ), 20 DECLE 1 = 25 байт

Бере N в R0 і вказівник на вихідний буфер в R4 . Записує всі відповідні символи в буфер і позначає кінець результатів 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

Вихід для N = 2

Примітка: вхідні дужки дуже схожі на квадратний дужку, що відкривається, шрифтом Intellivision. Хоча обидва символи відрізняються.

output

скріншот від jzIntv


1. Оптокод CP-1610 кодується з 10-бітовим значенням, відомим як "DECLE". Ця програма триває 20 DECLE, починаючи з $ 4819 і закінчуючи $ 482C (включно).


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

3
@ Вісім-BitGuru кодування на Intellivision досить весело. І сьогоднішні домашні ігри написані в 16-бітному ПЗУ, який розблоковує всю потужність (ах ...) ЦП. :)
Арнольд

Вражає! Поняття не мало, Intellivision мав буфер кадру та вбудований набір символів. Настільки просунутіший, ніж Atari 2600 точно. Дуже красиво зроблено!
640 Кб

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

Можна довести, що для будь-якого числа n в основі b , ndigitsum(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 байт, використовуючи модульний трюк Джо.
Кудлатий

@Shaggy О. Це приємне.
Арнольд

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 .

Спробуйте в Інтернеті.

Пояснення:

Містить недрукувальний символ зі значенням 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

1
-24байт за допомогою Long.bitCount
Nahuel Fouilleul

@NahuelFouilleul О, я завжди забуваю про те, що вбудовано в Яву! Дуже дякую. І ще 3 байти можна зберегти за допомогою n.bitCount. :)
Кевін Круїссен

Так, Java знову перемагає JavaScript! Мені подобаються такі виклики персонажів: P
Олів'є Грегоар

4

Java 8, 131 71 байт

-60 байт дякую всім у коментарях

Повертається ajava.util.stream.IntStream кодові точки

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

Спробуйте в Інтернеті!

Використовуючи HashSet, 135 байт. Повертає aSet<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
Статичний доступ з нестатичного контексту reeeeeee. Спасибі.
Бенджамін Уркхарт

Long.toBinaryString(i)може бутиLong.toString(i,2);
Кевін Круїссен

1
@KevinCruijssen ось що робить мій перший коментар
Термін дії закінчився

1
@KevinCruijssen Ти маєш рацію. Ось виправлена ​​версія: (досі) 71 байт . І так, я бачив вашу версію, яку я порушив менше 10 хвилин тому;)
Олів'є Грегоар

4

C # (Visual C # Interactive Compiler) , 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 використовує цю двійкову маску для фільтрації J-алфавіту повного алфавіту a.
  • &(95{.32}.]) але перед цим візьміть лише елементи 32 ... 126 як з алфавіту, так і з маски


Дякую Гален. TIL ви могли зробитиi.@95
Jonah


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 насправді не стандартизоване для кодегольфа.
негативна сім’я


2

PowerShell , 83 байти

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

Спробуйте в Інтернеті!

Приймає вхідний сигнал $n, створює діапазон від 32до 126і витягує ці цифри , де |?{}: число, convertEd ToStringв базі 2; перетворена toCharArra y; groupед в 0с і 1с; прийняття [1]індексу цієї групи; взявши .countйого і перевіривши, чи не -eqвідповідає цьому нашому вхідному $nзнаку. Ці цифри потім виводяться як charмасив і залишаються на конвеєрі. Вихід неявний, з новими рядками між елементами.







Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.