Afficher la liste des notes de musique

27

Cette tâche est simple: écrire un programme ou une fonction qui génère la liste de toutes les notes de musique (en utilisant les noms de notes en anglais) de A ♭ à G♯.

Toutes les notes sans nom composé d'une seule lettre (c'est-à-dire les notes noires sur un clavier musical) devraient avoir leur nom imprimé deux fois, une fois comme la netteté d'une note, une fois comme le plat d'une. Les notes nettes ou plates qui peuvent être décrites avec une seule lettre, comme B♯ (C) ou F ♭ (E) ne doivent pas être émises.

Voici un exemple de sortie:

Ab, A, A#, Bb, B, C, C#, Db, D, D#, Eb, E, F, F#, Gb, G, G#

Caractéristiques

  • Le programme ou la fonction ne doit prendre aucune entrée.

  • Les notes peuvent être imprimées dans n'importe quel ordre et dans n'importe quelle sortie de liste autorisée par nos règles d'E / S standard

  • Les symboles Unicode nets et plats (♯ / ♭) peuvent être remplacés par b et#

  • Comme toujours, les échappatoires standard sont interdites.

  • Comme il s'agit de , le plus petit programme, en octets, gagne.

TheOnlyMrCat
la source
3
en relation
Jonathan Allan
1
Pouvons-nous produire "C "au lieu de "C"?
Arnauld
1
@Arnauld oui vous pouvez
TheOnlyMrCat
7
Soit dit en passant, B # existe en notation musicale; c'est par exemple dans la signature de clé pour la clé de C #, où il sert de ton principal.
Kaz
2
Je ne sais pas, on dirait que Cb manque ici;)
AJFaraday

Réponses:

13

Malbolge , 482 370 353 octets

R1: Suppression des virgules entre les deux (comme cela n'est pas requis par le défi)

R2: raser quelques octets

('<;_#!=6Z|{8xUwvt,PrqonKmk)"FhCUTdb?`+<;:[Z7YtVU2T|/g-O+i(gJrHc#EC~B{@zZxw:tt'r5Qo"!l/K-hUfe?bP``_Lo~[}|X2VCTR3Q+N`_^9+7Hji3ffdAc~w|u;]\wpon4VUSSQ.PONcb(JI^]#DCYX|@?>=<:u9NMRKo32MFj.C,Ae)>'<%:^"!~5:3WxwwuRts0q(Lnml)"Fhgfe"y?a`_zyxq7YXWlUj0RgfkjMb(JI^c\[Z~BAV?T=Rv987Mq44310FEi-,G@)>b&%#"8=6Z{{yyw/Sut1*)('Km$k(!Efe{zyx>`uz]r8ZXnm3TTih.PkNchg`&HFF[DY}Az

Essayez-le en ligne!

Krzysztof Szewczyk
la source
12

Assemblage CP-1610 ( Intellivision ), 31 DECLEs 1 = 39 octets

Une routine prenant un pointeur de sortie en R4 et y écrivant les notes, séparées par des espaces. Dans l'exemple de code, nous écrivons directement à l'écran.

Vidage hexadécimal (routine uniquement)

275 001 2BD 03C 048 1DB 2B8 012 044 2A9 2BA 108 078 201 003 262
261 263 2FA 008 37A 140 225 00B 089 22C 011 2B7 018 210 000

Source complète

                ROMW    10              ; use 10-bit ROM width
                ORG     $4800           ; map this program at $4800

                ;; ------------------------------------------------------------- ;;
                ;;  test code                                                    ;;
                ;; ------------------------------------------------------------- ;;
4800            SDBD                    ; set up an interrupt service routine
4801            MVII    #isr,     R0    ; to do some minimal STIC initialization
4804            MVO     R0,       $100
4806            SWAP    R0
4807            MVO     R0,       $101

4809            EIS                     ; enable interrupts

480A            MVII    #$200,    R4    ; R4 = backtab pointer
480C            CALL    notes           ; invoke our routine

480F            DECR    R7              ; loop forever

                ;; ------------------------------------------------------------- ;;
                ;;  ISR                                                          ;;
                ;; ------------------------------------------------------------- ;;
      isr       PROC

4810            MVO     R0,       $0020 ; enable display

4812            CLRR    R0
4813            MVO     R0,       $0030 ; no horizontal delay
4815            MVO     R0,       $0031 ; no vertical delay
4817            MVO     R0,       $0032 ; no border extension
4819            MVII    #$D,      R0
481B            MVO     R0,       $0028 ; light-blue background
481D            MVO     R0,       $002C ; light-blue border

481F            JR      R5              ; return from ISR

                ENDP

                ;; ------------------------------------------------------------- ;;
                ;;  routine                                                      ;;
                ;; ------------------------------------------------------------- ;;
      notes     PROC

4820            PSHR    R5              ; save return address

4821            SDBD                    ; R5 = pointer to @@chr
4822            MVII    #@@chr,   R5
4825            CLRR    R3              ; R3 = 0 (space)
4826            MVII    #$12,     R0    ; R0 = bitmask = $12
4828            SWAP    R0,       2     ; extend it to $1212

4829  @@loop    MVI@    R5,       R1    ; R1 = next symbol
482A            MVII    #('A'-32)*8, R2 ; R2 = 'A' character

482C  @@note    SARC    R0              ; right shift the bitmask
482D            BC      @@next          ; skip this note if the carry is set

482F            MVO@    R2,       R4    ; append the note
4830            MVO@    R1,       R4    ; append the symbol
4831            MVO@    R3,       R4    ; append a space

4832  @@next    ADDI    #8,       R2    ; advance to the next note
4834            CMPI    #('H'-32)*8, R2 ; is it now a 'H'?
4836            BLT     @@note          ; if not, process the inner loop

4838            TSTR    R1              ; was the symbol a space?
4839            BNEQ    @@loop          ; if not, process the outer loop

483B            PULR    R7              ; return

483C  @@chr     DECLE   ('#'-32)*8      ; '#'
483D            DECLE   ('b'-32)*8      ; 'b'
483E            DECLE   0               ; space

                ENDP

Sortie

sortie

capture d'écran de jzIntv


1. Un opcode CP-1610 est codé avec une valeur de 10 bits, appelée «DECLE». Cette routine dure 31 DECLEs, commençant à 4820 $ et se terminant à 483E $ (inclus).

Arnauld
la source
9

Python 3 , 50 octets

print(*map(''.join,zip(3*'ADGBCEF',7*' '+5*'#b')))

Essayez-le en ligne!

Python 2:48 octets

Ce code peut être ajusté pour inclure B # et Cb, sans aucun octet supplémentaire. Ceci peut être réalisé en remplaçant 5par 6.


De plus, il est (enfin) plus court que la simple sortie de la chaîne simple:

Python 3 , 51 octets

exit('Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#')

Essayez-le en ligne!

Python 2:50 octets

Jitse
la source
2
Ceci est une solution très créative
TheOnlyMrCat
7

05AB1E , 16 15 13 octets

Au…b #âŽ7×bûÏ

-2 octets grâce à @maxb .

Essayez-le en ligne.

Sorties sous forme de liste, où les notes à caractère unique sont avec un espace de fin.

Explication:

Au             # Push the lowercase alphabet, and uppercase it
  b #         # Push string "b #"
      â        # Take the cartesian product of both strings to create all possible pairs:
               #  ["Ab","A ","A#","Bb","B ","B#",...,"Zb","Z ","Z#"]
       Ž7×     # Push compressed integer 1999
          b    # Convert it to a binary string "11111001111"
           û   # Palindromize it to "111110011111110011111"
            Ï  # Only leave the notes in the list at the truthy values (1), (the trailing
               # items beyond the length of this binary string are also discarded)
               # (after which the result is output implicitly)

Voir cette astuce 05AB1E (section Comment compresser les grands entiers? ) Pour comprendre pourquoi Ž7×est 1999.

Ž7×pourrait également être ₄·<(1000, double, diminution de 1) pour le même nombre d'octets.

Kevin Cruijssen
la source
3
Est-ce vraiment nécessaire? Semble bien fonctionner sans elle.
maxb
6

Gelée , 18? * 20 octets

ØAḣ7µp⁾b#Żs6ḣ€4ẎḊ;W€

Un lien monadique renvoyant une liste de listes de personnages.

* Si une liste mixte de (a) listes de caractères et (b) caractères est acceptable, supprimez la fin W€de 18.

Essayez-le en ligne!

Comment?

ØAḣ7µp⁾b#Żs6ḣ€4ẎḊ;W€ - Link: no argument
ØA                   - list of characters     [A-Z]
  ḣ7                 - head to 7              "ABCDEFG"
    µ                - new monadic link (call that X)
      ⁾b#            - list of characters     "b#"
     p               - Cartesian product      ["Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
         Ż           - prepend a zero       [0,"Ab","A#","Bb","B#","Cb","C#","Db","D#","Eb","E#","Fb","F#","Gb","G#"]
          s6         - split into sixes    [[0,"Ab","A#","Bb","B#","Cb"],["C#","Db","D#","Eb","E#","Fb"],["F#","Gb","G#"]]
            ḣ€4      - head each to 4      [[0,"Ab","A#","Bb"],["C#","Db","D#","Eb"],["F#","Gb","G#"]]
               Ẏ     - tighten              [0,"Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
                Ḋ    - dequeue                ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#"]
                  W€ - wrap each (of X)       ["A","B","C","D","E","F","G"]
                 ;   - concatenate            ["Ab","A#","Bb","C#","Db","D#","Eb","F#","Gb","G#","A","B","C","D","E","F","G"]
Jonathan Allan
la source
@mirabilos c'est 20 octets de code source, les caractères Unicode représentent chacun un octet du code source - voir la page de code liée par le mot bytesdans l'en-tête.
Jonathan Allan
5

Retina 0.8.2 , 33 octets


ABCDEFG
.
 $&b $& $&#
 [BE]#...

Essayez-le en ligne! Explication:


ABCDEFG

Insérez les noms des notes de base.

.
 $&b $& $&#

Développez chaque note pour inclure des versions plates et nettes.

 [BE]#...

Supprimer B#, E#ainsi que les notes qui les suivent ( Cbet Eb).

Neil
la source
5

Perl 6 , 41 octets

{S:g/[E|B]\#...//}o{'A'..'G'X~'b #'.comb}

Essayez-le en ligne!

Produit croisé simple des notes et des objets tranchants / plats, suivi de la suppression des notes supplémentaires non valides. Il s'agit d'un bloc de code anonyme qui produit la chaîne:

Ab A  A# Bb B   C  C# Db D  D# Eb E   F  F# Gb G  G#
Jo King
la source
4

R , 50 octets

cat("Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#")

Essayez-le en ligne!

Réponse ennuyeuse.

R , 60 octets

cat(outer(LETTERS[1:7],c("#","","b"),paste0)[-c(2,5,17,20)])

Essayez-le en ligne!

Giuseppe
la source
1
Je pense que la liste d'exemples de notes redondantes n'est pas censée être exhaustive - l'exemple de sortie omet également Cbet E#.
Unrelated String
4

Fusain , 21 octets

Φ⪪⭆…α⁷⭆b #⁺ι벧↨⊖⊘φ²κ

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

    α                   Predefined variable uppercase alphabet
   … ⁷                  First 7 letters i.e. `ABCEDFG`
  ⭆                     Map over characters and join
       b #              Literal string `b #`
      ⭆                 Map over characters and join
          ⁺ιλ           Concatenate outer and inner characters
 ⪪           ²          Split back into substrings of length 2
Φ                       Filter where nonzero
                  φ     Predefined variable 1000
                 ⊘      Halved i.e. 500
                ⊖       Decremented i.e 499
               ↨   ²    Converted to base 2 i.e. [1, 1, 1, 1, 1, 0, 0, 1, 1]
              §     κ   Cyclically indexed by outer index
                        Implicitly print matching values on separate lines
Neil
la source
3

Japt , 23 22 octets

;B¯7
ï"b #" fÏÄ %9%8<6

Essayez-le

;B          Alphabet
  ¯7        First seven characters ("ABCDEFG")
            Assign to U
ï"b #"       Cartesian product with "b #" ("Ab,A ,A#,Bb,B ,B#,Cb,C ,C#,Db,D ,D#,Eb,E ,E#,Fb,F ,F#,Gb,G ,G#")
f           Filter:
 ÏÄ           Is index + 1
   %9%8       Mod 9 Mod 8
     <6       Less than 6
            End filter ("Ab,A ,A#,Bb,B ,C ,C#,Db,D ,D#,Eb,E ,F ,F#,Gb,G ,G#")
Incarnation de l'ignorance
la source
Votre code contient <6mais il est <5dans l'explication.
TheOnlyMrCat
@TheOnlyMrCat Edited
Embodiment of Ignorance
2

dzaima / APL REPL, 38 28 25 octets

(⊤2056111)⌿,' b#'∘.,⍨7↑⎕A

Essayez-le en ligne!

dzaima
la source
Je pense que vous pouvez supprimer le ⎕←.
Erik the Outgolfer
@EriktheOutgolfer hmm ouais, si je passe à REPL
dzaima
Oh oui, j'ai oublié de compter le {}LOL.
Erik the Outgolfer
2

Rubis , 43 octets

p (2..18).map{|i|"FCGDAEB"[i%7]+"b #"[i/7]}

Essayez-le en ligne!

Avec la gamme, 0..20cela imprimerait un tableau contenant tous les appartements, tous les naturels et tous les objets tranchants. Les indésirables Fb Cb E# B#sont omis en utilisant la plage2..18

Les notes sont imprimées ordonnées selon https://en.wikipedia.org/wiki/Circle_of_fifths , ou en d'autres termes ascendantes de 7 demi-tons (un rapport de fréquence de presque exactement 1,5) à chaque fois.

Cela conduit à l'ordre des lettres de notes donné, dans lequel chaque note est de cinq degrés inclus (connue sous le nom de "cinquième") au-dessus de la précédente. Par exemple F->CestFGABC

Level River St
la source
J'aime que vous montiez par cinquième. Agréable.
Wayne Conrad
2

brainfuck , 106 octets

+++[[-<+>>++<]>]<<[-<->]++<<++<,+<-<[->+>+<<]<+[>>>>>+>-[<.<<<.>.[<]]>[>]<+[---<.<.<.[<]]>[>]<++<.<<.<<<-]

Essayez-le en ligne!

Sort chaque note séparée par des retours chariot.

Jo King
la source
2

Zsh , 36 octets

<<<${${(F):-{A..G}{b,,#}}//[BE]#???}

Une solution plus laide, mais elle enregistre deux caractères. (F)rejoint une liste sur les retours à la ligne et //[BE]#???supprime les parties de la chaîne dont nous avons besoin.

Essayez-le en ligne!


Zsh , 38 octets

<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}

J'apprécie toujours quand Zsh bat Perl (j'espère que je ne parlerai pas trop tôt ...).

<<<${${:-{A..G}{b,,#}}:#([BE]#|[CF]b)}
     ${:-             }                 # empty-fallback, basically an anonymous parameter expansion
         {A..G}{b,,#}                   # Cross product range A-G with b,(nothing),#
   ${                 :#             }  # Remove matching elements
                        ([BE]#|[CF]b)   # B#, E#, Cb, Fb
<<<                                     # Print to stdout

Essayez-le en ligne!

GammaFunction
la source
1

Brachylog , 36 octets

"#b"ẹ,Ẹ↺;Ṇh₇ᵗ↔{∋ᵐc}ᶠ⟨h₅ct₁₄⟩⟨h₁₂ct₅⟩

Essayez-le en ligne!

Je suis actuellement en train de forcer brutalement l'index du jeu de puissance qui me permettrait de me débarrasser de ⟨h₅ct₁₄⟩⟨h₁₂ct₅⟩ (et par extension , car la sortie n'a pas besoin d'être dans le même ordre que l'exemple de sortie), mais cela prend un certain tandis que ... je devrais peut-être mettre une minute de côté pour déterminer dans quel ordre les sous-listes sont générées et calculer l'index de cette façon ...

Chaîne indépendante
la source
1

Toile , 23 octets

Z7m{#+¹¹b+]{“╷!↕„2┬²@?P

Essayez-le ici!

22 octets avec des sauts de ligne supplémentaires dans la sortie

dzaima
la source
1

PHP , 65 octets

Fait la liste avec une boucle. Les éléments sont séparés par _un séparateur de fin.

for(;$l=ABCDEFG[$i++];)echo$l._.[$a="$l#_",$a.$b=$l.b_,$b][$i%3];

Essayez-le en ligne!


PHP , 43 octets

PHP sort tout ce qui est, lorsqu'il n'est pas à l'intérieur <?phpet les ?>balises.

Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#

Essayez-le en ligne!

Nuit2
la source
1

Pyth , 23 21 octets

s<R7c.>*<r1G7"b #"2 9

Essayez-le en ligne!

s<R7c.>*<r1G7"b #"2 9   Implicit: G=lowercase alphabet
         r1G            Convert G to upper case
        <   7           First 7 characters
       *     "b #"      Cartesian product with "b #"
     .>           2     Rotate the above 2 places to the right
    c               9   Chop into pieces of length 9
 <R7                    Trim each to length 7
s                       Flatten, implicit print

Edit: Réécriture partielle pour économiser 2 octets, version précédente: s%2c*<r1G7"b #"xLG"fhoq Essayez-le en ligne!

Sok
la source
1

Commodore C64 / TheC64 Mini (probablement d'autres variantes BASIC Commodore 8 bits) - 52 octets BASIC à jeton

 0?"{CTRL+N}Ab A A# Bb B C C# Db D D# Eb E F F# Gb GG#

Appuyez sur la CTRLtouche plusN du clavier C64, vous passez en «mode entreprise» sur le jeu de caractères pour les caractères majuscules / minuscules. Nous pouvons imprimer ceci dans une chaîne dans un octet / jeton; et comme nous avons 40 colonnes, l'espace de G à G # n'est pas requis.

Nous n'avons pas besoin de fermer la chaîne dans ce cas car il ne s'agit pas d'une ligne multi-instructions avec un : séparateur.

À quoi cela ressemble sur un écran Commodore C64 (et compatibles) est illustré ci-dessous.

Commodore 64 notes de musique

Shaun Bebbers
la source
1

Tonnelet , 43 octets

La chaîne, compressée.

AbAA\#BbBCC\#DbDD\#EbEFF\#GbGG\#(:H<[ $]')'

TIO

UNE
la source
0

APL (Dyalog Unicode) , 45 octets

2↓(,¨⎕A)⎕R', &''AbAA#BbBCC#DbDD#EbEFF#GbGG#'

Essayez-le en ligne!

⎕ROpération eplace simple , en ajoutant ,à chaque élément de la chaîne qui correspond à chaque lettre de l' ⎕Aalphabet, puis en supprimant les 2 premiers caractères qui le sont ,.

J. Sallé
la source
0

Brainfuck, 214 octets

>>>>++++++++[<++++<++++<++++++++++++<++++++++>>>>-]<<+++<++<+.>.>>.<<<.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<+.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<+.>>>.<<<.>>.>.<<<+.>.>>.<<<.>>>.<<<.>>.>.<<<+

Essayez-le en ligne!

Coton Zachary
la source
0

JavaScript (Node.js) , 84 octets

_=>[...'ABCDEFG'].map((n,i)=>`${i%3!=2?n+'b,':''}${n}${i%3!=1?`,${n}#`:''}`).join`,`

Essayez-le en ligne!

Le simple retour de la chaîne (comme illustré ci-dessous) serait plus court de 36 octets, mais où est le plaisir?

_=>'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'
T. Dirks
la source
0

brainfuck , 255 115 octets

--[----->+<]>-----[<+>>+>+<<-]>>+<<<-[->+++<]>+++[->>>+>+<
<<<]>>>>--->+++++++[-<<<<.>.>>.<<<.>>>.<<<.>>.>.<<<+>>>>]

Essayez-le en ligne!

Krzysztof Szewczyk
la source
1
Je voterais en faveur de cela, mais c'est faux. Il n'y a pas de note noire entre B et C, ou entre E et F. Donc, vous n'êtes pas censé produire. B #, Cb, E # ou Fb. De plus, je ne vois rien dans la spécification sur le fait qu'il soit OK d'utiliser des minuscules.
Level River St
@LevelRiverSt le défi n'a indiqué nulle part que nous n'avons pas de notes entre B et C & E et F
Krzysztof Szewczyk
All notes without a name consisting of a single letter (i.e. black notes on a musical keyboard) should have their name printed twice, once as the sharp of a note, once as the flat of one. Sharp or flat notes that can be described with a single letter, like B♯ (C) or F♭ (E) should not be outputted.Cela me semble assez clair et je ne vois aucun historique de modification sur l'OP sur mon écran.
Level River St
0

Bash 5 , 42 octets

x=`echo {A..G}{b,,#}`;echo ${x//[BE]#???/}

Sortie:

Ab A A# Bb B C C# Db D D# Eb E F F# Gb G G#
Thorsten
la source
0

T-SQL, 124 octets

SELECT value+a
FROM STRING_SPLIT('A-B-C-D-E-F-G','-')
    ,(VALUES('b'),(''),('#'))b(a)
WHERE value+a NOT IN ('B#','E#','Cb','Fb')

Les sauts de ligne sont uniquement à des fins d'affichage.

Plus longue mais beaucoup plus intéressante que la version triviale (50 octets) :

PRINT'Ab,A,A#,Bb,B,C,C#,Db,D,D#,Eb,E,F,F#,Gb,G,G#'
BradC
la source
0

Z80Golf , 31 29 octets

00000000: 9d5b dc6d df7f 0603 3e40 d13c cb3a 3008  .[.m....>@.<.:0.
00000010: fff5 7b2f ffaf fff1 20f1 10ec 76         ..{/.... ...v

Essayez-le en ligne!

Explication :

Z80Golf n'est qu'une simple machine fantastique basée sur le processeur Z80 8 bits. Le programme est chargé à l'emplacement de la mémoire 0x0000et le reste de la mémoire est rempli de zéros. La sortie se fait en appelant 0x8000, qui affichera la valeur du registre A sous forme de caractère.

Le programme démarre avec les données qui seront traitées, 6 octets au total. Chaque paire d'octets spécifie un suffixe de note et un masque de bits contrôlant laquelle des lettres peut être combinée avec cette note. Pour économiser des octets, le caractère suffixe est inversé ( xor 0xff) - cela permet aux données d'être exécutées sous forme d'instructions avec peu d'effets secondaires, ce qui permet de supprimer un saut qui saute ces données:

               ;    GFEDCBA
    db 0xff^'b', 0b01011011 ; Ab Bb Db Eb Gb
    db 0xff^'#', 0b01101101 ; A# C# D# F# G#
    db 0xff^' ', 0b01111111 ; A  B  C  D  E  F  G
skip_data:

Voici comment le CPU décode ceci:

    sbc a, l  ; a subtraction with carry on registers we don't care about
    ld e, e   ; put the E register back into itself. This instruction is useless
              ; but still exists to make the encoding regular.
    call c, 0xdf6d ; if the carry flag is set, call a function. The carry flag isn't set
              ; because of the initial register values (all zeroes) when the sbc above
              ; was executed
    ld a, a   ; as above, put A back into itself.

Ces données sont lues deux octets à la fois dans la paire de registres DE. Le pointeur de pile est utilisé pour pointer vers l'élément suivant. Il commence à 0 et, comme le Z80 utilise une pile pleine et décroissante, tous les pops liront la prochaine paire de données - toutes les opérations de pile sont en 16 bits.

La boucle externe est implémentée avec un compteur décrémentant dans le registre B, pour lequel le Z80 fournit un support spécial sous la forme de l' djnzinstruction:

    ld b, 3
process_pair:
    ...
    djnz process_pair
    halt

La lettre actuelle est conservée dans le registre A. Parce que l'incrément s'adapte bien au début de la boucle, nous chargeons un de moins que la valeur de démarrage réelle de A:

process_pair:
    ld a, 'A'-1
    pop de ; D = bitmask, E = suffix character
process_note:
    inc a
    srl d ; put the current bitmask bit in the carry flag
          ; also sets the zero flag if this is the last note in the pair
    jr nc, skip
    ; Print the note. Note that we need to preserve the zero flag to check it in the
    ; loop condition later.
    rst $38 ; Short encoding of call $0038.
            ; Because the program is so short, the memory in the 0038..8000 range
            ; is filled with zeroes, which happens to be the encoding for a no-op.
            ; The execution will therefore fall-through to the character-print hook.
    push af ; Save the letter on the stack (which will be just to the left of the
            ; unprocessed data) to free up A for printing other characters.
            ; (only 16-bit register pairs can be saved, so we also push the flags)
    ld a, e
    cpl     ; Undo the inversion used to make the execution fall-through the data.
            ; Done again each iteration because it takes less bytes to operate
            ; on the A register.
    rst $38 ; Print the suffix.
    xor a   ; Standard assembly practice of setting a register to zero by XORing it
            ; with itself. Saves a byte over a simple `ld a, 0`.
    rst $38 ; Print a null byte as a separator.
    pop af  ; Restore the current letter from the stack.
skip:
    jr nz, process_note ; If the zero flag (last changed at the srl d) is not set,
                        ; loop once again
    djnz process_pair
    halt
NieDzejkob
la source