Удалить чередование строк журнала [дубликат]
Вы унаследовали сервер, на котором работает несколько приложений, которые все выводят в один журнал.
Ваша задача - устранить чередование строк файла журнала по источникам. К счастью, каждая строка начинается с тега, указывающего, из какого она приложения.
Журналы
Каждая строка будет выглядеть примерно так:
[app_name] Something horrible happened!
- Теги приложений всегда заключаются в квадратные скобки и будут содержать только буквенно-цифровые символы и подчеркивания.
- Все строки будут иметь в начале тег приложения. Перед ним не будет пробелов или других символов.
- После тега приложения всегда будет хотя бы один пробел.
- Теги приложений не пусты
- Позже в любой данной строке могут быть другие квадратные скобки.
- После тега может быть или не быть сообщение
- Журнал может быть пустым
- Нет ограничений на количество уникальных тегов приложений, которые будут присутствовать в файле.
пример
Весь журнал может выглядеть так:
[weather] Current temp: 83F
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[stockmarket] PI +3.14
[barkeep] Fish leaves bar
[weather] 40% chance of rain detected
Что должно выводить три разных журнала:
[weather] Current temp: 83F
[weather] 40% chance of rain detected
[barkeep] Fish enters bar
[barkeep] Fish orders beer
[barkeep] Fish leaves bar
[stockmarket] PI +3.14
Вам не сообщают заранее названия тегов приложения. Вы должны определить их только путем анализа файла журнала.
Правила и подсчет очков
- Это код-гольф , поэтому побеждает самый короткий код.
- Применяются стандартные правила и лазейки
- Используйте любой удобный формат ввода-вывода, при условии, что каждая строка ввода представлена как строка, а не предварительно проанализированный тег + сообщение. Неисчерпывающий список разрешенных выходов:
- Несколько файлов, названных по каждому тегу
- Несколько списков строк
- Один объединенный список строк, содержащих строки, сгруппированные по тегу с разделителем или без него (разделитель не должен начинаться с тега)
- То же, что и выше, но в стандартный вывод или в файл.
- Порядок вывода разделенных журналов не имеет значения, однако строки журнала в каждой группе должны сохранять порядок, в котором они были найдены в исходном файле.
Ответы
R , 50 46 байт
function(r)split(r,substr(r,1,regexpr("]",r)))
Выводится как a list
с каждым элементом name
d с расширением [tag]
. Каждый элемент списка поддерживает порядок в своем теге. Возвращает пустой именованный список named list()
для пустого ввода.
По 2 байта спасибо Робину Райдеру и Доминику ван Эссену!
Pyth , 3 байта
ohc
Формат ввода - это список строк:
["[weather] Current temp: 83F","[barkeep] Fish enters bar","[barkeep] Fish orders beer","[stockmarket] PI +3.14","[barkeep] Fish leaves bar","[weather] 40% chance of rain detected"]
Как работает код:
o
: Сортировать поh
: Первый элементc
: Каждая строка разбивается на пробелы
Python , 44 байта
lambda a:sorted(a,key=lambda l:l.split()[0])
Свободный ввод-вывод позволяет нам взять и получить список строк. Поскольку нам не нужно разделять группы, проблема сводится к выполнению стабильной сортировки строк в префиксе каждой строки до первого пробела, также split()
будет разделен на некоторые другие символы пробела, но ни один не может присутствовать в часть тега приложения.
APL (расширенный Dyalog) , 10 байт ( SBCS )
Анонимная функция неявного префикса. Принимает в качестве аргумента список списков символов. Возвращает матрицу списков символов с одним журналом в каждой строке.
⊢⊢⌸⍨≠⊃⍤⊆¨⊢
⊢
по аргументу,
≠
используйте непробелы, чтобы…
⊆¨
разбивать каждый список на список списков (удаляет пробелы, сохраняет пробелы),
⊃⍤
затем сохраните первые [каждого] (т. е. теги),
⊢⌸⍨
использовать их как ключи для группировки…
⊢
Аргумент
vim, 13 11 байт
:sor/\w\+/r
исправление ошибок и сохранение байтов благодаря @Dingus!
Scala, 26 байт
_.sortBy(_.split("]")(0))
Возвращает List[String]
без разделителя между ними, но сортируется по тегу.
Возвращает Map[String,List[String]]
, 26 байт
_ groupBy(_.split("]")(0))
Принимает список строк и возвращает, Map[List[String]]
где ключи - это теги, а значения - журналы, связанные с этим тегом.
Предыдущее решение, 66 байт
_ groupBy{case s"[$t]$r"=>t}map(_._2 mkString "\n")mkString "\n"*2
Попробуйте в Scastie (по какой-то причине s
не работает в TIO)
Журналы каждого приложения разделены двумя символами новой строки (я мог бы сэкономить 2 байта, если бы это был только один символ новой строки). Входные данные - это список строк, а выход - одна большая строка.
05AB1E , 3 байта
Σ#¬
Ввод и вывод - это список журналов.
Пояснение:
Σ#¬
Σ Sort by:
# Split (each log) by spaces
¬ Head (which is the tagname)
При этом также сохраняется порядок журналов по мере необходимости.
Retina 0.8.2 , 14 13 байт
O$`(\w+).*
$1
Попробуйте онлайн! Объяснение: Поскольку разделитель групп вывода не требуется, строки просто сортируются по тегу приложения, что достигается путем фиксации совпадения \w+
и его указания $1
в качестве ключа сортировки. Сортировка в Retina стабильна, поэтому строки с одинаковым префиксом сохранят свой порядок. Изменить: сохранен 1 байт благодаря @FryAmTheEggman за указание более простого способа сопоставления тега приложения. Обратите внимание, что хотя совпадение не включает интерлиньяж [
, все строки начинаются с [
, так что это не влияет на результат сортировки.
AWK , 62 58 байт
Сохранено 4 байта благодаря Доминику ван Эссену !!!
{a[$1][i++]=$0}END{for(k in a)for(j in a[k])print a[k][j]}
Сохраняет все строки в двухмерном ассоциативном массиве a
. Первый ключ - это первое поле (разделенное пробелом). Таким образом, все строки, начинающиеся с одного поля, хранятся вместе. Второй ключ - это возрастающий целочисленный индекс. Самая подробная часть - это END
действие, которое печатает содержимое a
сгруппированных по первому полю в порядке появления.
Io , 73 байта
method(i,i map(split first)unique map(I,i select(split first==I))flatten)
Perl 6 , 16 байт
*.sort:{~m/\w+/}
Сортировка по первой строке буквенно-цифровых символов, которая должна быть именем приложения.
Python 3 , 148 127 байт
a={}
try:
while 1:
b=input();c=b.split("]")[0]
if 1-(c in a):a[c]=[]
a[c]+=[b]
except:[print(e)for k in a for e in a[k]]
V (vim) , 5 байт
úr/?]
Примечание: ?
указанное выше находится вместо непечатаемого байта \$\text{\x}81\$ (управляющий символ "No Break Here").
Обратите внимание, что это работает с нехваткой пробелов (даже с одним сразу после первой ]
скобки), с наличием []
скобок в сообщении журнала и с присутствием непомеченного приложения. Попробуйте онлайн!
Как?
úr/?]
ú - sort by:
r - with flag=r: use match (default behaviour is to use what's after the match)
/ - with the pattern:
? - (byte 83) a shortcut for .\{-}
. - match any character
\{-} - 0 or more times matching as few times as possible
] - match a literal ']' character
AutoHotkey, 74 байта
Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}
Читает из файла с именем f
и выводит в несколько файлов на основе тега.
SimpleTemplate 0.84, 109 байт
Да, это довольно долго, но работает!
{@callexplode intoL EOL,argv.0}{@eachL}{@if_ matches"@^(\[.*\])@"M}{@setS.[M.1]S.[M.1],_,EOL}{@/}{@/}{@echoS}
Этот код генерирует массив с расширением <old content>, line, <end of line>
.
{@echoS}
автоматически выравнивает массив и отображает его.
Без гольфа:
Да, беспорядок, но вот более чистая версия:
{@call explode into lines EOL, argv.0}
{@set storage null}
{@each lines as line}
{@if line matches "@^(\[.*\])@" match}
{@set storage.[match.1] storage.[match.1], line, EOL}
{@/}
{@/}
{@echo storage}
Функция explode
является стандартной функцией PHP, но доступна с моего языка.
Вы можете попробовать это на: http://sandbox.onlinephpfunctions.com/code/9c66f8bacc6315ae56e7c193170e430f9cf9d902
C # (.NET ядра) , 181 162 160 байт
input.GroupBy(l=>l.Split()[0]).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim('[').Trim(']')+".log")){foreach(var v in g)sw.WriteLine(v);}});
C # (интерактивный компилятор Visual C #) , 179 байт
i=>i.GroupBy((l)=>{return l.Split(' ')[0];}).ToList().ForEach((g)=>{using(var sw = new StreamWriter(g.Key.Trim(new char[]{'[',']'})+".log")){foreach(var v in g)sw.WriteLine(v);}})
Я не уверен, что первое решение совместимо с заливом кода, поэтому второе решение использует лямбда-выражение.
Ржавчина, 40 байт
|a|a.sort_by_key(|x|x.split("]").next())
Принимает изменяемую ссылку на фрагмент строк и сортирует ее.
Perl 5 -M5.10.0 -Msort = стабильный, 53 байта
say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>