Belirli bir bit sayısına sahip tüm ASCII karakterleri


30

(@ChasBrown sayesinde başlık)

Kum havuzu

Arkaplan

Bu zorluk, son zamanlarda Puzzling Stack Exchange'de yayınladığım bir sorudan ilham aldı . Orijinal soru ile ilgileniyorsanız, lütfen bağlantıyı takip etmekten çekinmeyin. Eğer değilse o zaman sizi burada ayrıntılarla sıkmayacağım.

Gerçekler

Her yazdırılabilir standart ASCII karakteri, 32 ile 126 arasında bir ondalık değere sahiptir. Bunlar, 100000 ila 1111110 dahil, karşılık gelen ikili sayılarına dönüştürülebilir. Bu ikili sayıların bitlerini topladığınızda, her zaman 1 ile 6 arasında bir tamsayı ile sonuçlanır.

Meydan okuma

Giriş olarak 1 ile 6 arasında bir tamsayı verildiğinde, ikili değerlerinin bitlerinin toplamının giriş tamsayısına eşit olduğu, yazdırılabilir standart ASCII karakterlerinin tümünü herhangi bir kabul edilebilir formatta çıkartacak bir program veya işlev yazın.

Örnekler / Test Durumları

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

Burada bir ungolfed Python referans uygulaması (TIO) bulunmaktadır .

Kurallar

  1. Girişin her zaman 1 ile 6 arasında bir tamsayı (veya bir tamsayı dizgi gösterimi) olacağını varsayalım.
  2. Sonuçları görüntülemek için bir program veya bunları döndürmek için bir işlev yazabilirsiniz.
  3. Çıktı herhangi bir makul formatta olabilir, ancak tüm girdiler için tutarlı olmalıdır . Bir alıntı dizge çıkarmayı seçerseniz, tüm girdiler için aynı tipte alıntılar kullanılmalıdır.
  4. Her zaman olduğu gibi standart boşluklar yasaktır.
  5. Bu kod golf, yani her dilde en kısa kod kazanıyor.

Ondalık ascii değerlerinin bir listesini döndürmemize / yazdırmamıza izin veriyor mu, yoksa karakter biçiminde (örneğin, 63vs ?) olması gerekiyor mu?
Benjamin Urquhart

1
Gerçek karakterler olmalı.
ElPedro

7
"tüm girdiler için aynı tipte alıntılar kullanılmalıdır" Python, örneğin, 'bir dizenin dizgi gösterimi için tekli tırnak ( ) kullanır, ancak "dizge tek bir alıntı içeriyorsa ve çift tırnak içermiyorsa çift ​​tırnak işareti ( ) kullanır. . Bu özel durum çok önemli olmayacaktır, muhtemelen temsili yerine gerçek dizgiyi döndürmekten daha iyi durumdasınızdır ve yine de girdi için böyle bir dizgede tek tırnaklar kullanabilirsiniz, ancak burada bahsetmeye değer olduğunu düşünüyorum.
Outgolfer Erik,

@EriktheOutgolfer Anlaşıldı. Bu yüzden, bunu sadece bir kural olarak
eklemenin

1
@ElPedro İlk örnekte yer olduğundan, bazı alıntılara sahip olmak için iyi bir fikir olacağından emin olamadım, ancak normal alıntıların her ikisi de çıktıda görünüyor :) Düzenleme: belki fransız guillemets ( « »)? : D
kusur

Yanıtlar:


29

8088 derleme, IBM PC DOS, 35 30 29 bayt

Makine kodu:

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

Liste:

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

Bağımsız PC DOS çalıştırılabilir program, komut satırından giriş numarası. Konsol penceresine çıkış görüntülenir.

görüntü tanımını buraya girin

ABCT.COM'u (AsciiBitCounT) indirin ve test edin .


8
Bir an için sanki sadece bu cevap için bir etki alanı kaydettirmişsiniz gibi "ABCT.COM AT indirin ve test edin" dediğini sanıyordum .
Sparr

14

CP-1610 montajı ( Intellivision ), 20 DECLEs 1 = 25 bayt

Alır N- bölgesindeki R0 ve çıktı tamponunda bir işaretçi R4 . Tüm eşleşen karakterleri arabellekte yazar ve sonuçların sonunu NUL ile işaretler .

                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 için çıktı

Not: Açılış parantezi, Intellivision fontundaki açılış köşeli parantezi gibi görünür. Her iki karakter de farklı.

çıktı

ekran görüntüsü jzIntv


1. Bir CP-1610 opcode 'DECLE' olarak bilinen 10 bitlik bir değerle kodlanmıştır. Bu rutin 20 DECLEs uzunluğunda, 4819 $ 'dan başlayıp 482C $' da bitiyor.


5
+1 sadece (a) Intellivision için bir çözüm olduğu ve (b) şimdiye kadar gördüğüm ilk Intellivision kodu olduğu için.
Sekiz Bit Gurusu

3
@ Sekiz BitGuru Intellivision'daki kodlama oldukça eğlenceli. Ve bugünün homebrew oyunları 16-bit ROM'da yazılmıştır, ki bu CPU'nun tam gücünü (ahem ...) açar. :)
Arnauld

Etkileyici! Intellivision'un bir çerçeve tamponu ve yerleşik bir karakter setine sahip olduğunu bilmiyordum. Atari 2600'den çok daha gelişmiş. çok iyi yapmışsın!
640KB

2
@gwaugh GROM (Grafik ROM için) tüm yazdırılabilir ASCII karakterlerini ve birkaç genel grafik şeklini içerir. Eğlenceli gerçek: aynı zamanda ana ROM'a uymayan bazı çalıştırılabilir kodlar içeriyor.
Arnauld

2600'den kesinlikle daha gelişmiş, ancak bellek işe yararsa, Mattel ROM'da saklanan gelişmiş şeylerin hiçbirini ortaya çıkarmadı, bu yüzden üçüncü taraf geliştiriciler ya düz makine koduyla sınırlıydılar ya da süslü şeyleri kendi başlarına bırakmak zorunda kaldılar. . Kıyamet olabilir.
brhfl


9

05AB1E , 8 bayt

žQʒÇbSOQ

Çevrimiçi deneyin!

açıklama

ž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

8

Perl 6 , 41 34 bayt

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

Çevrimiçi deneyin!

Sayı alan ve geçerli bir karakter dizesi döndüren adsız kod bloğu.

Açıklama:

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

Bunu, ikili sayımızın rakamını ondalık sayı olarak ayrıştırıp 9'a ayarlayarak elde etmek için kullanabiliriz, çünkü kullandığımız sayıların aralığının 9 bit'den az olması garanti edilir. Bu, Perl 6'nın sayısal dizgide kullanıldığında ikili dizinin otomatik dökümünü ondalık sayıya almasına yardımcı olur.



7

JavaScript (Node.js) , 60 bayt

Kullanılması Jo King'in modülo hile

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

Çevrimiçi deneyin!


JavaScript (Node.js) ,  70  69 bayt

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

Çevrimiçi deneyin!

Yorumlananlar

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

Jo'nun modulo numarasını kullanarak 60 bayt .
Shaggy

@Shaggy Ah. Bu iyi bir tane.
Arnauld

6

Brachylog , 7 bayt

∈Ṭ&ạhḃ+

Çevrimiçi deneyin!

Bir dayanak fonksiyonları bir jeneratör olarak , çıkış değişkeni üzerinden girdi alır ve kendi girdi değişkeni ile her bir karakteri üretir. Çünkü 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).


5

Excel (2016 veya üstü), 76 bayt

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

A1'den girdi alır, bu formülü koyduğunuz hücreden çıkar. Bu bir dizi formülüdür, bu yüzden girmek için Ctrl+ Shift+ tuşlarına basmanız Entergerekir. "2016 veya üstü", CONCATfonksiyona ihtiyaç duymasından kaynaklanmaktadır (kullanımdan kaldırılmış CONCATENATEbir parametre argüman olarak kabul edilmez).


Bunu severim. Ben bir Lotus Notes ve 123 adamıyım, bu yüzden bu benim için çalışıyor :-)
ElPedro

5

C (standart kütüphane), 74 67 bayt

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

Sadece standart kütüphane fonksiyonlarını kullanma. 74'den 67 bayta kadar gelişme için @gastropner'a teşekkürler.

Çevrimiçi deneyin!



@gastropner bu inanılmaz bir gelişmedir! Teşekkür ederim!
Krista

1
Sanırım f(1)durumda yer açmak için endeks 31'den başlamanız gerekiyor (çünkü bunu ++iatlar).
LambdaBeta

@LambdaBeta Kesinlikle haklısın, teşekkür ederim!
Krista

5

R , 77 68 bayt

Döngü için yaklaşım kullanma

Giuseppe sayesinde -9 bayt

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

Çevrimiçi deneyin!

Önceden:

R , 78 69 66 bayt

Giuseppe sayesinde -12 bayt

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

32 ila 126 arasındaki sayıları bir bit matrisine dönüştürür, daha sonra giriş numarasıyla eşleşenleri bulmak için satırlar boyunca toplanır.

Çevrimiçi deneyin!


1
Kullanım intToBits(x)>0yerineas.single
Giuseppe

Güzel, denedim |0ve bir hata yaptım ve sadece mantık operatörlerinin işe yaramayacağını varsaydım.
Aaron Hayman

1
Bununsapply yerine "önceki" yaklaşım için 66 baytmatrix
Giuseppe

4

Java 10, 98 97 94 70 67 bayt

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

Nahuel Fouilleul sayesinde -24 bayt .

Çevrimiçi deneyin.

Açıklama:

Unicode değerine sahip yazdırılamayan bir karakter içeriyor 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


@NahuelFouilleul Ah, ben her zaman Java'da yerleşik olduğunu unutuyorum! Çok teşekkürler. Ve 3 bayt daha kullanılarak kaydedilebilir n.bitCount. :)
Kevin Cruijssen

Evet, Java bir kez daha JavaScript'i yeniyor! Bu karakter zorluklarını seviyorum: P
Olivier Grégoire

4

Java 8, 131 71 bayt

-60 yorumlarda herkes sayesinde bayt

bir İade java.util.stream.IntStreamcodepoints arasında

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

Çevrimiçi deneyin!

HashSet'i kullanarak, 135 bayt. A döner 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(""));}}

Çevrimiçi deneyin!



1
Statik olmayan içerik reeeeeee'den statik erişim. Teşekkürler.
Benjamin Urquhart

Long.toBinaryString(i)olabilirLong.toString(i,2);
Kevin Cruijssen

1
@KevinCruijssen ilk yorumumun yaptığı şey bu
Süresi dolmuş veri

1
@KevinCruijssen Haklısın. İşte sabit sürüm: (hala) 71 bayt . Ve evet, 10 dakikadan daha kısa bir süre önce yenmiş olduğum versiyonunuzu gördüm;)
Olivier Grégoire

4

C # (Visual C # Etkileşimli Derleyici) , 86 bayt

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

Bana kullanma fikrini verdiğim için @ExpiredData'ya teşekkürler Sum()! Bilgisayarıma geri döndüğümde "0123456", üç baytı koruyarak dizeyi yazdırılamaz ile değiştireceğim .

Çevrimiçi deneyin!



@ExpiredData Kullandığınız fikri için teşekkür ederiz Sum()!
Ignorance'ın

4

Dyalog APL Extended, 24 22 bayt

ucs a⌿⍨⎕=+⌿2a32126

Çevrimiçi deneyin!

Ngn sayesinde -2 bayt

Normal Dyalog APL'deki alternatif 22 bayt: ngn:

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

Çevrimiçi deneyin!


(expr )∘=-> ⎕=expr
ngn

uzatılmadan: ⎕ucs 32+⍸⎕=32↓+/↑,⍳7⍴2(←io ← 0)
ngn


3

Gaia , 10 bayt

₵R⟪¤cbΣ=⟫⁇

Çevrimiçi deneyin!

		| implicit input, n
₵R		| push printable ascii
  ⟪	⟫⁇	| filter the list where:
   ¤cbΣ		| the sum of the code point in binary
       =	| is equal to n

3

J , 31 27 bayt

Galen sayesinde -4 bayt

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

Çevrimiçi deneyin!

Orijinal cevap

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

Çevrimiçi deneyin!

  • 2#:@i.@^8:0 - 255 arasındaki ikili sayıları üretir ( 2 ^ 8256)
  • 1#. her birini toplar
  • ]= toplamın asıl girişe eşit olduğunu gösteren bir ikili maske üretir
  • a.#~ mask J'nin tam ascii alfabesini filtrelemek için bu ikili maskeyi kullanır a.
  • &(95{.32}.]) fakat bunu yapmadan önce hem alfabeden hem de maskeden yalnızca 32 ... 126 elemanlarını alın.


Sağol Galen. Yapabileceğini TILi.@95
Jonah


3

K (ngn / k) , 20 bayt

Çözüm:

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

Çevrimiçi deneyin!

Açıklama:

Sağdan sola değerlendirildi:

`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 montajı (NES), 22 bayt

Makine kodu:

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

Montaj:

    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

Tam bir program . FCEUX 2.2.3 ile test edilmiş, herhangi bir standart NES emülatörü üzerinde çalışmalıdır.

Ryan Russell'ın cevabından ilham aldı. CPU adresinde 60 $ verilen giriş. Konsolun Picture Processing Unit belleğine çıkar.


2
Merhaba ve PPCG'ye hoş geldiniz. Çözümünüzü bir kartuş (yani bir (çevrimiçi) emülatör veya şartname) oluşturmaktan başka doğrulamanın bir yolu var mı?
Jonathan Frech

@JonathanFrech Yerel olarak toplanıp çalıştırılabilen tam bir program ekledim. Anladığım kadarıyla, NES ortamı kod kodlayıcı için standart hale gelmedi.
negatif yedi


2

PowerShell , 83 bayt

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

Çevrimiçi deneyin!

Girişi alır $n, bir dizi oluşturur 32için 126ve bu sayıları çeker |?{}: numarası converted ToStringbaz 2; dönüştürülmüş toCharArra y; groupiçine ed 0s ve 1s; [1]bu gruplandırma indeksini alarak ; Bunları alarak ve bizim girişimiz için geçerli .countolup olmadığını kontrol -eqedin $n. Bu sayılar daha sonra bir chardizi olarak dökülür ve boru hattında bırakılır. Çıktı, öğeler arasındaki yeni satırlarla birlikte örtüktür.



2

Kömür , 10 bayt

Φγ⁼Σ↨℅ι²Iθ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

 γ          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




Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.