Невизуализировать код Парсонса


22

Введение

Код Парсонса - это просто простой способ описать изменения высоты звука в музыкальном произведении, независимо от того, выше или ниже нота по сравнению с предыдущей.

Даже если вы не любите запоминать мелодии, вы все равно можете вспомнить, идет ли нота вверх или вниз, поэтому код Парсонса может помочь вам идентифицировать музыку с помощью поисковой системы.


Описание

Каждый вариант представлен одним символом, который является одним из следующих:

  • Rесли примечание то же , чем предыдущий (означает « R EPEAT» )
  • Uесли нота выше, чем предыдущая (означает « U )
  • Dесли нота ниже, чем предыдущая (означает « D own» )

Начальная нота написана как *.


пример

Вот пример кода Парсонса (начало «Ода радости» ):

*RUURDDDDRUURDR

Вы можете фактически визуализировать это, как это:

      *-*                    
     /   \                   
    *     *                  
   /       \                 
*-*         *         *-*    
             \       /   \   
              *     *     *-*
               \   /         
                *-*          

Теперь мы будем называть это контуром .

Правила рисования таких графов считаются самоочевидными в приведенном выше примере.



Вызов

Теперь наступает настоящий вызов.

Напишите программу, которая, учитывая входной контур, выводит соответствующий ему код Парсонса.

Вас не просят нарисовать контур, а наоборот.
Из контура найдите оригинальный код Парсонса.


правила

  • Применяются обычные правила для игры в гольф
  • Победит самая короткая программа по количеству байтов
  • Вход является контуром, а выход должен быть действительным кодом Парсонса.
  • Подробности о лишних пробелах для ввода не имеют значения, делайте все, что лучше для вас
  • Вы не можете жестко, так или иначе, жестко кодировать части вывода и / или программу, используя дополнительные пробелы из-за предыдущего правила

Заметки



Так должно начаться с того, *что ничего не делает?
Никель

Что вы имеете в виду? когда вход просто *? Нет. Это должно напечатать, *я полагаю. Я добавлю этот угловой случай.
Хельге фон Кох

1
@nicael Да, это должно начаться с *. Всегда.
Хельге фон Кох

Ответы:


4

Pyth - 28 25 27 25 байт

2 байта спасены благодаря @Jakube.

s+\*@L"RDU"-VFtBxR\*%2C.z

Попробуйте это онлайн здесь .


1
Это не работает *как вход. Вывод *0пока что должен быть просто *. Появился злой дикий конечный ноль.
Хельге фон Кох

@HelgevonKoch исправлено
Maltysen

@ Якуб, спасибо!
Maltysen

Вы поменялись местами Uи D, кстати. В остальном молодец.
Хельге фон Кох

@HelgevonKoch ой
Maltysen

24

CJam, 21 байт

qN/:.e>(o2%:i"DRXU"f=

Сложите линии ( :) путем векторизации (). ) максимально символьной операции e>. Поскольку в каждом столбце есть только один непробельный символ, он будет результатом, так как пробел имеет меньший код ASCII, чем все печатные непробельные символы.

Снимите и напечатайте первую звездочку (o, затем сопоставьте все остальные ( 2%) оставшиеся символы сUDR использованием модульной индексации.

Старое решение (29 байт)

'*qN/z2%'*f#0+2ew);::-"RDU"f=

qN/ получает входные строки. zтранспонирует эту матрицу символов. 2%падает каждый нечетный ряд. '*f#находит индекс звездочки в каждой строке. 0+2ew);получает все последовательные пары индексов. ::-вычисляет их различия, и "RDU"f=отображает их на письма ( с помощью модульной индексации: 0 → R, 2 → U, -2 ≡ 1 → D). Ведущий '*стоит перед звездочкой.

EDIT : Я изменил 2ewк 0+2ew);труду вокруг CJ не обрабатываетew (последовательные фрагменты) в слишком короткие списки. Это заставляет код работать для входной строки *.

Попробуй здесь или посмотрите в действии:

              

7
Это действительно здорово смотреть.
Джил Шах

2
Я согласен! +1 за код, хотелось бы +10 за GIF.
ETHproductions

Кстати, мне нравится смайлик с длиной кода 17:-p
ETHproductions

1
Я согласен, это здорово смотреть. Это не работает *как вход, хотя. Я получаю хороший RuntimeExceptionвместо этого.
Хельге фон Кох

Тьфу, я считаю, что ошибка CJam: [X]2ewдолжна возвращаться, []а не выдавать ошибку. Я добавлю обходной путь, хотя.
Линн

4

Python 3, 129 108 98 86 байт

Вероятно, есть несколько способов сыграть в гольф, но мне скорее нравится, что все сводится к одной линии.

Изменить: теперь с помощью''.translate()

Редактировать: Большое спасибо wnnmaw .

Редактировать: я изменил формат ввода на массив строк вместо строки, разделенной новой строкой, чтобы сохранить байты. Кроме того, в последнем редактировании я перепутал Uи R, таким образом, я исправил это.

lambda a:'*'+"".join(('UR'[j<'/']+'D')[j>'/']for l in zip(*a)for j in l if j in'-/\\')

Входные данные должны быть массивом строк. Для приведенного выше примера это выглядит примерно так:

["      *-*                    ","     /   \                   ","    *     *                  ","   /       \                 ","*-*         *         *-*    ","             \       /   \   ","              *     *     *-*","               \   /         ","                *-*          "]

Ungolfed:

def f(a):
    s = ''
    for c in zip(*a):           # transpose
        for d in c:             # for each letter in column c
            if e in "-/\\":     # if that letter is either -,/,\
                if e < '/':     # if < '/' (same as if == '-')
                    s += "R"
                elif e > '/':   # if > '/' (same as if == '\')
                    s += "D"
                else:           # if == '/'
                    s += "U"
        return "*" + s          # in the code we ''.join() it all together
                                # in this ungolfing, we add to an empty string

Я не хочу давать новый ответ, потому что я многое позаимствовал у вас, но lambda s:'*'+"".join((('D','R')[j=='-'],'U')[j=='/']for l in zip(*s.split('\n'))for j in l if j in'\\/-')получил 105 байтов. Основное отличие заключается в использовании условного кортежа вместо translate
wnnmaw

Спасибо @wnnmaw! Я думаю, что я могу сыграть в гольф еще дальше!
Sherlock9

Хороший гольф на условном фронте, это очень умно!
wnnmaw

Ах, чёрт! Спасибо за подсказку @wnnmaw
Sherlock9

3

Рубин, 87 байт

Требует в конце входных пробелов, чтобы все строки имели одинаковую длину.

$><<?*+$<.readlines.map(&:chars).transpose.join.gsub(/./,{?-=>:R,?/=>:U,?\\=>:D}).strip

4
Конечно, это вредоносный код, так как он содержит >:D.
Алекс А.

3

Japt, 38 байт 40 41 45 46 48

Сохранено 2 байта благодаря @ETHproductions

'*+U·y £Yu ?"RUD"g1+(XrS c -47 g):P} q

Если бы была команда обрезки, это было бы только 38 байтов; -; добавлю объяснение, когда я закончу играть в гольф. Это :Pне программа, которая пытается быть забавной, это программа, которая игнорирует символы, которые не важны.

Попробуйте онлайн


Когда я увидел, что существует проблема, практически требующая транспонирования массива, и что Doᴡɴɢᴏᴀᴛ ответил на это, я понял, что это должен быть Джапт.
ETHproductions

Кстати, я добавлю функцию обрезки в, xа также транспонирую и вращаю функции в yи z(разделить на новые строки, использовать функцию массива, объединить с
новыми строками

Вы можете сохранить два байта следующим образом:Yu ?"RUD"g1+(XrS c -47 g):P
ETHproductions

Спасибо @ETHproductions, до 40 байтов!
Вниз

3

Haskell, 89 байт

import Data.List
m '/'="U"
m '-'="R"
m '\\'="D"
m _=""
('*':).(>>=(>>=m)).transpose.lines

Пример использования:

*Main> ('*':).(>>=(>>=m)).transpose.lines $ "      *-*                    \n     /   \\                   \n    *     *                  \n   /       \\                 \n*-*         *         *-*    \n             \\       /   \\   \n              *     *     *-*\n               \\   /         \n                *-*          "
"*RUURDDDDRUURDR"

*Main> ('*':).(>>=(>>=m)).transpose.lines $ "*"
"*"

Перенесите ввод и замените символы // -/ \одиночными строками "U"/ "R"/ "D". Все другие символы заменяются пустыми строками "", которые позже исчезают при объединении всего. Наконец, добавьте звездочку *.


2

Mathematica, 103 байта

"*"<>(Differences@Position[Thread@Characters@StringSplit[#,"
"],"*"][[;;,2]]/.{-2->"U",0->"R",2->"D"})&

Короче говоря, учитывая, что это проблема обработки строк.


2

JavaScript (ES6) 90

Анонимная функция. Сканирует входную строку char по char, учитывая положение в текущей строке. Делая это, он строит выходной массив subsituting U D Rдля / \ -в нужном месте

c=>[...c].map(c=>c>'*'?t[i++]=c>'/'?'D':c<'/'?'R':'U':c<' '?i=0:++i,t=['*'],i=0)&&t.join``

2

Matlab, 62 байта

r=@(s)[85-(s<14)*3-(s>59)*17,''];@(p)r(sum(p(:,2:2:end)-32))

Это требует, чтобы ввод был прямоугольным (одинаковое количество символов в каждой строке). Например

    ['      *-*                    ';    '     /   \                   ';    '    *     *                  ';    '   /       \                 ';    '*-*         *         *-*    ';    '             \       /   \   ';    '              *     *     *-*';    '               \   /         ';    '                *-*          '];

объяснение

sum(p(:,2:2:end)-32)        % exctract every second column, substract 32 (spaces->zeros) 
                            % and sum column wise (results in a vector of 3 different values)
[85-(s<14)*3-(s>59)*17,'']  % map each of the values to the corresponding value of the letter and convert back to characters
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.