Створення музичних коробок


23

Ваше завдання - взяти послідовність символів (музику) як вхід (у функції чи програмі) та надрукувати (або повернути) музику так, як вона виглядала б у музичній скриньці.

Ви будете отримувати символи лише ABCDEFG.()як вхідні дані, і вхід ніколи не буде порожнім. Ви також можете отримати листи в малі літери, якщо цього бажаєте.

Це порожня музична скринька, довжиною 3:

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

Як бачите, рядки мають 7 символів, а оскільки довжина музичного поля становить 3, у нас є 3 рядки. Тут є лише .s, оскільки музична скринька порожня. Давайте покладемо в нього трохи музики!

Спочатку ми створюємо музичну скриньку. У цьому прикладі вхід буде CDAG.DAG.

Довжина CDAG.DAGстановить 8, тому нам потрібна музична скринька довжиною 8:

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

Потім ми читаємо введення, по одному символу за раз, і розміщуємо Oна відповідному місці.

Перший символ є C, і розташування кожної ноти еквівалентно цьому (я додав пробіли для наочності):

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

Якщо символом введення є а ., ми просто надрукуємо порожній рядок.......

Отже, the Cбуде третім персонажем разом. Давайте покладемо його в нашу музичну скриньку вгорі:

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

Ми повторимо цей процес для всіх інших символів (текст у дужках лише для того, щоб показати вам замітку, ви не повинні виводити це):

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

Через те, як працюють музичні скриньки, якщо ми використовуємо інший символ O, .а не <insert newline here>такий, як пробіл, у своєму виході, він не відтворюватиме правильну музику!

Це акорд:

(ACE)

Цей акорд вказує нам грати на нотах A, Cі Eводночас. Ніколи не буде паузи (тобто а .) в акорді.

Ось як було б написано:

O.O.O...

Ось як це може виглядати в музиці: B(ACE)D

Ви ніколи не отримаєте акорд в акорді, тобто це не буде дійсним: (AB(CD)EF)або це:, A(B())і акорд не буде порожнім, тобто це не буде дійсним:A()B

Ви ніколи не отримаєте недійсний вхід.

Приклади:

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.

Дозволений / провідний пробіл на виході дозволений.

Оскільки це , виграє найкоротший код!


може музичний рядок містити ()двічі (наприклад AB(CD)E(FG):) ??
Містер Xcoder

@ Mr.Xcoder Так, це може.
Окс

Чи може висновок бути списком / масивом символів?
Пруд

@ Упевнений, згідно зі стандартами
PPCG

Ми гарантовано не отримаємо двох однакових нот в одному акорді?
Ділова кішка

Відповіді:


0

Піп , 29 байт

28 байт коду, +1 для -lпрапора.

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

Вводить введення в малі регістри як аргумент командного рядка. Спробуйте в Інтернеті!

Пояснення

                              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)

Ось зразок того, як трансформується вхід:

"b.(ceg)"
["b" "." "(ceg)"]
[["b"] [] ["c" "e" "g"]]
[[1] [] [2 4 6]]
[".O....." "......." "..O.O.O"]

6

Python 2 , 95 94 байт

-1 байт завдяки величині 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

Спробуйте в Інтернеті! або Спробуйте всі тестові приклади

Пояснення

'@'<iщоб перевірити , якщо iцей лист, замінивши .на Oна правильному положенні.
'*'>iщоб перевірити, iє дужкою, якщо він x=i>'('поставить 0на , xщоб запобігти друк / очищення o, коли i==')'він буде ставити 1на xповторному включенні друку / очищення o.
Коли i=='.'нічого не зміниться, '.......'буде надруковано.
Порядок найменування задається їх кодом ASCII, де'('<')'<'*'<'.'<'@'<'A'


о, я пропустив цей коментар. нвм.
Кінтопія

Канава коми: ['.']*7. Можливо, це утримування з того часу, коли ви використовували кортеж, для якого знадобиться кома. Також я можу помилитися, але, здається, це виводить масив ['O', '.', '.', '.', '.', '.', '.']на рядок, і я не впевнений, чи дозволено це?
Значення чорнила


Ви згадали про зміну байтів і змінили посилання TIO, але код, вказаний у вашій публікації, все одно той же: V
Значення чорнила

1
@ValueInk ¯ \ _ (ツ) _ / ¯
стрижень

4

Пакет, 209 байт

@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%

Працює, накопичуючи літери та виводячи рядок, якщо останній помічений символ не був a (.


4

Рода , 97 78 76 байт

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

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

Це анонімна функція, яка зчитує вхід з потоку. Використовуйте його так: main { f={...}; push("ABCD") | f() }. Він використовує регулярний вираз з відповіді ETHproductions.

Безголівки:

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

Попередня відповідь:

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

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

Він працює, розбиваючи заданий рядок у місцях, де наступний рядок містить лише відповідні дужки. Потім для кожного акорда він повторюється через можливі ноти та друкує, Oякщо нота є членом акорду та .іншим чином.


4

JavaScript (ES6), 86 85 76 байт

Збережено 9 байт завдяки @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>

Пояснення

По-перше, ми співставимо те, що буде формувати кожен рядок виводу: акорди та символи, які не є частиною акорду. Потім для кожного рядка беремо рядок ABCDEFG\nі замінюємо кожен символ, що не є новим рядком, на рядок, Oякщо рядок містить його, і .іншим.


Якщо прийнятний новий рядок прийнятний, ви можете зберегти 8 байт за допомогою s=>s.replace(r=/\(\w+\)|./g,x=>`ABCDEFG\n`.replace(r,c=>x.match(c)?"O":".")).
Ніл

@Neil Вау, це дивовижно :-)
ETHproductions

Ага, тепер, коли я його знову вимірюю, це має бути економія на 10 байт ...
Ніл

Може \)бути .?
l4m2

2

JavaScript (ES6), 118 116 114 байт

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):''

Тестові справи


2

Рубі, 78 75 71 байт

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

Повертає масив рядків.

Ungolfed + пояснення

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

Спробуйте x.gsub(...){l=?.*7;$&.bytes{...};l+$/}(своп scanз gsub, REMOVE map, і пропустити перший , |x|так як ви можете використовувати , $&щоб отримати доступ останнього матчу регулярного виразу) , щоб зберегти 3 байт і повертає рядок з декількох рядків замість цього. (Також $/за замовчуванням відображається новий рядок.)
Значення чорнила

1

PHP, 171 байт

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";}

Зламатися :

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
}

Спробуйте тут!


1

Сітківка , 120 байт

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>`.

Я впевнений, що є місце для гольфу, але він працює зараз, тому я спробую пізніше взяти участь у гольфі.

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

Як це працює

По суті, програма працює, змінюючи кожен символ на число, а потім присвоює a Oдо цієї позиції в рядку. Це карти ABCDEFG.на 01234569.

Щоб генерувати єдині рядки нот, все, що потрібно зробити, - це поставити знак Oпісля відповідної кількості .s, а потім викласти рядок довжиною до 7 символів.

Однак акорди трохи складніше робити. Використовується аналогічний процес, але цифри повинні бути переведені з кроком, тобто перша нота в акорді - це (що завгодно), друга - X позицій після першої, третя - Y позицій після цього тощо.

Код

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

Почніть з сортування всіх символів у акордах.

T`L.`d

Виконайте транслітерацію (зіставлення) з букв до цифр.

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

Замініть всі цифри в дужках одинарним поданням (за допомогою xs), а потім пробілом.

\)
m¶

Замініть всі кронштейни, що закриваються, mнаступними рядками. mБуде використовуватися в якості маркерів сортів для майбутнього циклу:

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

Це етап заміни, який циклізує, поки він більше не може замінити. Він приймає останні дві послідовності xs перед an mі віднімає перше з другого, рухаючи mназад. Маркер mпотрібен, оскільки він повинен виконувати цю операцію справа наліво.

 m?x

Видаліть перше xв кожній послідовності, крім першої.

T`x m(`.\O_

Transliterate шляхом заміни xз ., з простором O, і видалення mі (.

У цей момент створено всі рядки для акордів. Тепер потрібно створити рядки для однієї ноти.

\d
$*.O¶

Замініть кожну цифру на стільки .s, а потім - Oі новий рядок.

¶
6$*.¶
%7>`.

Прокладіть кожен рядок довжиною 7, додавши .s праворуч. Це працює, додавши 6 .s до кінця кожного рядка (кожен рядок матиме принаймні 1 інший символ), а потім замінювати кожен символ після перших 7 у кожному рядку нічим. (Оскільки .карти до 9, то Oв цих рядках буде вирізано)



0

Perl 5 - 78 + 1 (прапор) + 2 (Вхідні котирування) = 81 Байт

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

Можна запустити так:

perl -n <name of file holding script> <<< <input in quotations>

Ви не думаєте, що вхід у лапки вважатиметься двома додатковими байтами? Я можу помилятися, оскільки може бути мета-консенсус щодо цього, тверджуючи інакше.
Окс

@Okx оновив мій рахунок. Не був впевнений, чи додано до нього, все-таки щось нове тут :)
CraigR8806

0

Рубін, 68 байт

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

Ідея полягає в тому, щоб змінити рядок ....... щоразу, коли ми знаходимо букву, а потім виводити і скидати її, але лише тоді, коли ми знаходимось поза дужками. (вимикає вихід. )і .обидва вмикають / залишають вихід увімкнутим, але останній не має значення, оскільки він ніколи не знайдеться всередині дужки.

Ungolfed в тестовій програмі

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)"]

0

Python 3, 94 байти

Анонімна функція

import re
lambda s:[''.join('.O'[c in x]for c in'ABCDEFG')for x in re.findall(r'\(\w+\)|.',s)]

0

Haskell , 101 байт

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=[]

Спробуйте в Інтернеті! Використання:p "AB.(CA)D" . Повертає список рядків.

Пояснення:

Функція pповторюється через рядок. Якщо він знайде дужку, що відкривається, '('то (x,_:t)<-span(')'<)rрозділить решту рядка rв рядки xдо появи дужки, що закривається, ')'і tпісля неї. В іншому випадку поточний символ xперетворюється на рядок [x]. В обох випадках функція ?викликається поточним рядком приміток та рядком решти. ?відображає функцію #над рядком "ABCDEFG", де #замінюються всі символи, які не містяться в поточному рядку нотаток '.'. Отримана лінія музичної скриньки передбачена рекурсивним викликом pу списку відпочинку r.


0

Сітківка 0,8,2 , 52 байти

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

Спробуйте в Інтернеті! Вводить малі регістри. Пояснення:

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

Розділіть музику на акорди або ноти і починайте створювати вихід, додаючи список еквівалентів нот.

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

Для кожної ноти у кожному акорді змініть висновок на an Oта видаліть ноту з акорду.

T`().l`___.

Видаліть всю вже сторону музику, а всі незрівняні ноти змініть на порожні.


0

PHP, 93 байти

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

Запуск труби з -nRабо спробувати його в Інтернеті .

зламатися

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