Robienie pozytywek

23

Twoim zadaniem jest pobranie sekwencji znaków (muzyki) jako danych wejściowych (w funkcji lub programie) i wydrukowanie (lub zwrócenie) muzyki tak, jak wyglądałaby w pozytywce.

Otrzymasz tylko znaki ABCDEFG.()jako dane wejściowe, a dane wejściowe nigdy nie będą puste. Możesz również otrzymać litery małymi literami, jeśli chcesz.

To jest pusta pozytywka o długości 3:

.......
.......
.......

Jak widać, wiersze mają 7 znaków, a ponieważ długość pozytywki wynosi 3, mamy 3 wiersze. Są tylko .tutaj, ponieważ pozytywka jest pusta. Dodajmy do tego trochę muzyki!

Najpierw tworzymy pozytywkę. W tym przykładzie wejście będzie CDAG.DAG.

Długość CDAG.DAGwynosi 8, więc potrzebujemy pozytywki o długości 8:

.......
.......
.......
.......
.......
.......
.......
.......

Następnie odczytujemy dane wejściowe, po jednym znaku na raz, i umieszczamy znak w Oodpowiednim miejscu.

Pierwszą postacią jest C, a położenie każdej nuty jest równoważne z tym (dodałem spacje dla przejrzystości):

 A B C D E F G
 . . . . . . .
 . . . . . . .
 (and so on)

Jeśli znakiem wejściowym jest a ., to po prostu wypisujemy pusty wiersz.......

Tak, Cbyłoby 3rd znak wzdłuż. Umieśćmy go w pozytywce na górze:

..O....
.......
.......
.......
.......
.......
.......
.......

Powtórzymy ten proces dla wszystkich pozostałych znaków (tekst w nawiasach ma tylko pokazać notatkę, której nie powinieneś wyprowadzać):

..O.... (C)
...O... (D)
O...... (A)
......O (G)
....... (.)
...O... (D)
O...... (A)
......O (G)

Ze względu na to, jak muzyka pudełka pracy, jeśli używamy znak inny niż O, .oraz <insert newline here>, takich jak miejsca, w naszej mocy, to nie będzie odgrywać właściwą muzykę!

To jest akord:

(ACE)

Akord ten poucza nas grać nuty A, Ca Ew tym samym czasie. Nigdy nie będzie pauzy (tj. A .) w akordzie.

Oto jak byłoby napisane:

O.O.O...

I tak to może wyglądać w muzyce: B(ACE)D

Nigdy nie otrzymasz akordu z akordu, tzn. To nie będzie ważne: (AB(CD)EF)ani to A(B()):, a akord nie będzie pusty, tzn. Nie będzie prawidłowy:A()B

Nigdy nie otrzymasz nieprawidłowego wejścia.

Przykłady:

B(ACE)D

.O.....
O.O.O..
...O...

B

.O.....

GGABC

......O
......O
O......
.O.....
..O....

...

.......
.......
.......

A..F.C(DA).

O......
.......
.......
.....O.
.......
..O....
O..O...
.......

.(ABCDEF)

.......
OOOOOO.

Dozwolone jest końcowe / białe spacje na wydruku.

Ponieważ jest to , wygrywa najkrótszy kod!

Okx
źródło
czy ciąg muzyczny może zawierać ()dwa razy (np . AB(CD)E(FG):)?
Pan Xcoder,
@ Mr.Xcoder Tak, może.
Okx,
Czy wyjściem może być lista / tablica znaków?
Rod
@ Jasne, zgodnie ze standardami
PPCG
Czy gwarantujemy, że nie dostaniemy dwóch takich samych dźwięków w tym samym akordzie?
Business Cat

Odpowiedzi:

0

Pip , 29 bajtów

28 bajtów kodu, +1 dla -lflagi.

'.X7RA_'OMz@?a@`\(\w+.|.`@XL

Pobiera dane pisane małymi literami jako argument wiersza polecenia. Wypróbuj online!

Wyjaśnienie

                              a is 1st cmdline arg; XL is `[a-z]`; z is lowercase alphabet
             a@`\(\w+.|.`     List of all matches in a of this regex:
                               Either a ( followed by letters followed by another
                               character (i.e. the closing paren), or any one character
                         @XL  For each of those matches, a list of all matches of this
                               regex (effectively, split the match into a list of
                               characters and keep only the lowercase letters)
          z@?                 Find index of each letter in the lowercase alphabet
         M                    To that list of lists of indices, map this function:
'.X7                           Take a string of 7 periods
    RA_                        and replace the characters at all indices in the argument
       'O                      with O
                              Finally, autoprint the resulting list, with each item on
                              its own line (-l flag)

Oto przykład transformacji danych wejściowych:

"b.(ceg)"
["b" "." "(ceg)"]
[["b"] [] ["c" "e" "g"]]
[[1] [] [2 4 6]]
[".O....." "......." "..O.O.O"]
DLosc
źródło
6

Python 2 , 95 94 bajtów

-1 bajt dzięki Value Ink

x=1
for i in input():
 if x:o=['.']*7
 if'@'<i:o[ord(i)-65]='O'
 if'*'>i:x=i>'('
 if x:print o

Wypróbuj online! lub Wypróbuj wszystkie przypadki testowe

Wyjaśnienie

'@'<ijest sprawdzenie, czy ijest to litera, zastępując .Ona właściwej pozycji.
'*'>ijest sprawdzenie, czy ijest nawias, jeśli to x=i>'('będzie można umieścić 0na xzapobieganie Drukowanie / kasowanie o, kiedy i==')'będzie umieścić 1na xponowne jej włączanie Drukowanie / kasowanie o.
Kiedy i=='.'nic się nie zmieni i '.......'zostanie wydrukowane.
Kolejność znaków jest podana przez ich kod ASCII, gdzie'('<')'<'*'<'.'<'@'<'A'

Pręt
źródło
och, przegapiłem ten komentarz. NVM.
kwintopia,
Rów przecinek: ['.']*7. Być może jest to pozostałość po użyciu krotki, która wymagałaby przecinka. Mogę się również mylić, ale wydaje się, że wyświetla tablicę ['O', '.', '.', '.', '.', '.', '.']w wierszu i nie jestem pewien, czy jest to dozwolone?
Wartość tuszu
@ValueInk tak, OP dozwolone
Rod
Wspomniałeś o zmianie bajtów i zmieniłeś link do TIO, ale kod podany na Twoim poście jest nadal taki sam: V
Value Ink
1
@ValueInk ¯ \ _ (ツ) _ / ¯
Rod
4

Partia, 209 bajtów

@set s=%1
@set p=)
@for %%n in (a b c d e f g)do @set %%n=.
:g
@if %s:~,1% lss @ (set "p=%s:~,1%")else set %s:~,1%=O
@set s=%s:~1%
@if %p%==( goto g
@echo %a%%b%%c%%d%%e%%f%%g%
@if not "%s%"=="" %0 %s%

Działa poprzez kumulację liter i wyprowadzenie linii, jeśli ostatnim widocznym symbolem nie był a (.

Neil
źródło
4

Röda , 97 78 76 bajtów

{search`\(\w+\)|.`|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}

Wypróbuj online!

Jest to anonimowa funkcja, która odczytuje dane wejściowe ze strumienia. Używaj go tak: main { f={...}; push("ABCD") | f() }. Wykorzystuje regex z odpowiedzi ETHproductions.

Nie golfowany:

{
    search(`\(\w+\)|.`) | for chord do
        seq(ord("A"), ord("G")) | for note do
            if [ chr(note) in chord ] do
                push("O")
            else
                push(".")
            done
        done
        push("\n")
    done
}

Poprzednia odpowiedź:

f s{(s/"(?=([^()]*(\\([^()]*\\))?)*$)")|{|c|seq 65,71|{|l|["O"]if[chr(l)in c]else["."]}_;["
"]}_}

Wypróbuj online!

Działa poprzez dzielenie podanego ciągu w miejscach, w których ciąg zawiera tylko dopasowane nawiasy. Następnie dla każdego akordu iteruje się przez możliwe nuty i drukuje, Ojeśli nuta jest członkiem akordu i w .inny sposób.

fergusq
źródło
4

JavaScript (ES6), 86 85 76 bajtów

Zaoszczędź 9 bajtów dzięki @Neil

let f =
s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG
`.replace(r,c=>x.match(c)?"O":"."))
<input oninput="if(/^([A-G.]|\([A-G]+\))+$/.test(value))O.textContent=f(value)"><br>
<pre id=O></pre>

Wyjaśnienie

Najpierw dopasowujemy, co utworzy każdy wiersz wyniku: akordy i znaki, które nie są częścią akordu. Następnie dla każdej linii bierzemy ciąg ABCDEFG\ni zamieniamy w nim każdy znak nie będący Onowym wierszem na, jeśli linia go zawiera, i na .inny.

ETHprodukcje
źródło
Jeśli końcowy znak nowej linii jest akceptowalny, możesz zapisać 8 bajtów przy użyciu s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG\n`.replace(r,c=>x.match(c)?"O":".")).
Neil,
@Neil Wow, to niesamowite :-)
ETHproductions 10'17
Huh, teraz, gdy ponownie to zmierzę, powinno to być 10-bajtowe oszczędzanie ...
Neil
Może \)być .?
l4m2
2

JavaScript (ES6), 118 116 114 bajtów

f=([c,...t],s)=>c?((s?0:x=[...'.......'],c='ABCDEFG)('.indexOf(c))>6?c-7:(x[c]='O',s))?f(t,1):x.join``+`
`+f(t):''

Przypadki testowe

Arnauld
źródło
2

Rubinowy, 78 75 71 bajtów

->x{x.scan(/\(\w+\)|./).map{|x|l=?.*7
x.bytes{|x|x>47?l[x-65]=?O:1};l}}

Zwraca tablicę ciągów.

Niegolfowane + wyjaśnienie

def boxes string
  string.scan(/\(\w+\)|./)    # Split the string into an array of chords.
  .map do |chord|             # Replace each chord with...
    line = '.' * 7            # a line, where by default each character is a '.',
    chord.bytes do |note|     # but for each note in the chord...
      if note > '.'.ord       # (if it is in fact a note and not a dot or paren)
        line[note-65] = 'O'   # replace the corresponding dot with an 'O'.
      end
    end
    line               
  end
end
m-chrzan
źródło
Spróbuj x.gsub(...){l=?.*7;$&.bytes{...};l+$/}(zamień scanz gsub, usuń mapi pomiń pierwszy, |x|ponieważ możesz użyć, $&aby uzyskać dostęp do ostatniego dopasowania wyrażenia regularnego), aby zapisać 3 bajty i zamiast tego zwrócić ciąg wielu wierszy. ( $/Domyślnie mapowane jest również do nowej linii).
Wartość tuszu
1

PHP, 171 bajtów

preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m);foreach($m[0]as$l){if($l=='.')echo".......";else foreach([A,B,C,D,E,F,G]as$a)echo strpos($l,$a)!==false?O:'.';echo"\n";}

Awaria :

preg_match_all('#[A-G\.]|\([A-G]+\)#',$argv[1],$m); // Matches either one character in the range [A-G.] OR multiple [A-G] characters between parentheses
foreach($m[0]as$l)                                  // For each match :
    if($l=='.')                                     //   If no note is played
        echo".......";                              //     Echo empty music line
    else                                            //   Else
        foreach([A,B,C,D,E,F,G]as$a)                //     For each note in the [A-G] range
            echo strpos($l,$a)!==false?O:'.';       //       Echo O i the note is played, . if not
    echo"\n";                                       //  Echo new line
}

Wypróbuj tutaj!

roberto06
źródło
1

Siatkówka , 120 bajtów

O`(?<=\([^)]*)[^)]
T`L.`d
(?<=\([^)]*)\d
$*x 
\)
m¶
+`\b(x+) \1(x+) m
$1 m$2 
 m?x

T`x m(`.\O_
\d
$*.O¶
¶
6$*.¶
%7>`.

Jestem pewien, że jest miejsce na grę w golfa, ale teraz działa, więc spróbuję zagrać w golfa później.

Wypróbuj online!

Jak to działa

Zasadniczo program działa poprzez zmianę każdego znaku na liczbę, a następnie przypisanie Odo tej pozycji w wierszu. Odwzorowuje się ABCDEFG.na 01234569.

Aby wygenerować linie pojedynczej nuty, wystarczy wstawić Opo odpowiedniej liczbie .s, a następnie uzupełnić linię do 7 znaków.

Jednak akordy są nieco trudniejsze do wykonania. Zastosowano podobny proces, ale liczby należy przeliczyć na przyrosty, tzn. Pierwsza nuta akordu (cokolwiek), druga to pozycje X po pierwszej, trzecia to pozycje Y po tym itd.

Kod

O`(?<=\([^)]*)[^)]

Zacznij od uporządkowania wszystkich znaków w akordach.

T`L.`d

Wykonaj transliterację (mapowanie) z liter na cyfry.

(?<=\([^)]*)\d
$*x 

Zamień wszystkie cyfry w nawiasach na jednoargumentową reprezentację (używając xs), a następnie spację.

\)
m¶

Zastąp wszystkie nawiasy zamykające mnastępującymi znakami nowej linii. mBędzie wykorzystana jako znacznik rodzajów dla nadchodzącego pętli:

+`\b(x+) \1(x+) m
$1 m$2 

Jest to etap wymiany, który zapętla się, dopóki nie będzie można go wymienić. Bierze dwie ostatnie sekwencje xs przed mi odejmuje pierwszą od drugiej, przesuwając do mtyłu. Znacznik mjest potrzebny, ponieważ musi wykonać tę operację od prawej do lewej.

 m?x

Usuń pierwszą xw każdej sekwencji oprócz pierwszej.

T`x m(`.\O_

Transliterate zastępując xz ., z przestrzenią Oi usuwanie mi (.

W tym momencie wszystkie linie dla akordów zostały utworzone. Teraz należy utworzyć linie pojedynczej nuty.

\d
$*.O¶

Zamień każdą cyfrę na tyle .s, a następnie na Oi nową linię.

¶
6$*.¶
%7>`.

Wypełnij każdą linię do długości 7, dodając .s po prawej stronie. Działa to poprzez dodanie 6 .s na końcu każdej linii (każda linia będzie miała co najmniej 1 inny znak), a następnie zastąpienie każdego znaku po pierwszych 7 w każdej linii niczym. (Od .map do 9, Ozostaną one wycięte na tych liniach)

Business Cat
źródło
1

Perl, 87 71 45 + 2 ( -nlflaga) = 47 bajtów

#!/usr/bin/env perl -nl
use v5.10;
say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g

Za pomocą:

perl -nlE 'say map$&=~/$_/i?O:".",a..g while/\(\w+\)|./g' <<< "A..F.C(DA)."

Wypróbuj na Ideone.

Denis Ibaev
źródło
0

Perl 5-78 + 1 (flaga) + 2 (cudzysłowy) = 81 bajtów

for(;/(\([a-g]+\)|[a-g\.])/g;){$i=$1;print$i=~/$_/?'o':'.'for(a..g);print"\n"}

Można uruchomić tak:

perl -n <name of file holding script> <<< <input in quotations>
CraigR8806
źródło
Czy nie sądzisz, że dane wejściowe w cudzysłowach byłyby liczone jako 2 dodatkowe bajty? Mogę się mylić, ponieważ może istnieć meta konsensus w tej sprawie, stwierdzając inaczej.
Okx,
@Okx zaktualizował moje bytecount. Nie byłem pewien, czy się do tego dodał, wciąż trochę tu nowy :)
CraigR8806
0

Rubinowy, 68 bajtów

->s{w=?.*m=7
s.bytes{|i|i>64?w[i-65]=?O:m=i!=40;m&&(puts w;w=?.*7)}}

Chodzi o to, aby zmodyfikować ciąg za .......każdym razem, gdy znajdziemy literę, a następnie wyprowadzamy ją i resetujemy, ale tylko wtedy, gdy znajdujemy się poza nawiasami. (wyłącza wyjście.)i .oba włączają / wyłączają wyjście, ale to drugie jest nieistotne, ponieważ nigdy nie zostanie znalezione w nawiasie.

Niegolfowany w programie testowym

f=->s{w=?.*m=7              #set m to a truthy value (7) and w to seven .'s
  s.bytes{|i|               #for each byte in the string
    i>64?w[i-65]=?O:m=i!=40 #if a letter, modify the appropriate character of w ELSE set m to false if inside brackets, true otherwise.
    m&&(puts w;w=?.*7)      #if m is true, output the contents of w and reset to seven .'s
  }
}

p 1
f["B(ACE)D"]
p 2
f["B"]
p 3
f["GGABC"]
p 4
f["A..F.C(DA)."]
p 5
f[".(ABCDEF)"]
Level River St
źródło
0

Python 3, 94 bajty

Anonimowa funkcja

import re
lambda s:[''.join('.O'[c in x]for c in'ABCDEFG')for x in re.findall(r'\(\w+\)|.',s)]
RootTwo
źródło
0

Haskell , 101 bajtów

c#s|elem c s=c|1<3='.'
s?r=map(#s)"ABCDEFG":p r
p('(':r)|(x,_:t)<-span(')'<)r=x?t
p(x:r)=[x]?r
p e=[]

Wypróbuj online! Zastosowanie: p "AB.(CA)D". Zwraca listę ciągów.

Wyjaśnienie:

Funkcja ppowraca nad ciągiem. Jeśli stwierdzi nawias otwierający '('następnie (x,_:t)<-span(')'<)rdzieli ciąg odpoczynek rdo ciągów xprzed wystąpieniem wspornika zamknięcia ')'i tpo nim. W przeciwnym razie bieżący znak xzostanie przekształcony w ciąg [x]. W obu przypadkach funkcja ?jest wywoływana z bieżącym ciągiem nut i pozostałym ciągiem. ?odwzorowuje funkcję #na ciąg "ABCDEFG", gdzie #zastępuje wszystkie znaki, które nie znajdują się w bieżącym ciągu notatek '.'. Powstała linia pozytywki jest dołączana do rekurencyjnego wywołania pna liście pozostałych r.

Laikoni
źródło
0

Retina 0.8.2 , 52 bajty

\(\w+\)|.
abcdefg$&¶
+`([a-g])(.*)\1
O$2
T`().l`___.

Wypróbuj online! Wprowadza dane pisane małymi literami. Wyjaśnienie:

\(\w+\)|.
abcdefg$&¶

Podziel muzykę na akordy lub nuty i zacznij budować wyjście, dodając listę ekwiwalentów nut.

+`([a-g])(.*)\1
O$2

Dla każdej nuty każdego akordu zmień wyjście na Oi usuń nutę z akordu.

T`().l`___.

Usuń całą obcą muzykę i zmień wszystkie niedopasowane nuty na puste.

Neil
źródło
0

PHP, 93 bajty

for($s=$t="
.......";$c=ord($argn[$i++]);$d||$s=$t.!print$s)$c<65?$c-46&&$d=~$c&1:$s[$c&7]=O;

Uruchom jako potok z -nRlub spróbuj online .

awaria

for($s=$t="\n.......";      // init
    $c=ord($argn[$i++]);    // loop through characters
    $d||                        // 2. if chord flag is unset
        $s=$t.!print$s)             // then print and reset chord
    $c<65                       // 1. if not note
        ?$c-46                      // and not dot
            &&$d=~$c&1              // then set or clear chord flag
        :$s[$c&7]=O             // else set note in chord
    ;
Tytus
źródło