Удалить чередование строк журнала [дубликат]

Aug 18 2020

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

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

Журналы

Каждая строка будет выглядеть примерно так:

[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

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

Правила и подсчет очков

  • Это код-гольф , поэтому побеждает самый короткий код.
  • Применяются стандартные правила и лазейки
  • Используйте любой удобный формат ввода-вывода, при условии, что каждая строка ввода представлена ​​как строка, а не предварительно проанализированный тег + сообщение. Неисчерпывающий список разрешенных выходов:
    • Несколько файлов, названных по каждому тегу
    • Несколько списков строк
    • Один объединенный список строк, содержащих строки, сгруппированные по тегу с разделителем или без него (разделитель не должен начинаться с тега)
    • То же, что и выше, но в стандартный вывод или в файл.
  • Порядок вывода разделенных журналов не имеет значения, однако строки журнала в каждой группе должны сохранять порядок, в котором они были найдены в исходном файле.

Ответы

9 Noodle9 Aug 18 2020 at 03:22

Bash , 4 11 байт

Добавлено 7 байт, чтобы исправить ошибку, любезно указанную Шэгги .

sort -sk1,1

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

Выполняет стабильную сортировку ( sаргумент командной строки) на основе первого поля ( k1,1), разделенного пробелом.

7 Giuseppe Aug 18 2020 at 01:35

R , 50 46 байт

function(r)split(r,substr(r,1,regexpr("]",r)))

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

Выводится как a listс каждым элементом named с расширением [tag]. Каждый элемент списка поддерживает порядок в своем теге. Возвращает пустой именованный список named list()для пустого ввода.

По 2 байта спасибо Робину Райдеру и Доминику ван Эссену!

5 isaacg Aug 18 2020 at 04:48

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: Каждая строка разбивается на пробелы

4 JonathanAllan Aug 18 2020 at 01:55

Python , 44 байта

lambda a:sorted(a,key=lambda l:l.split()[0])

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

Свободный ввод-вывод позволяет нам взять и получить список строк. Поскольку нам не нужно разделять группы, проблема сводится к выполнению стабильной сортировки строк в префиксе каждой строки до первого пробела, также split()будет разделен на некоторые другие символы пробела, но ни один не может присутствовать в часть тега приложения.

3 Adám Aug 18 2020 at 01:49

APL (расширенный Dyalog) , 10 байт ( SBCS )

Анонимная функция неявного префикса. Принимает в качестве аргумента список списков символов. Возвращает матрицу списков символов с одним журналом в каждой строке.

⊢⊢⌸⍨≠⊃⍤⊆¨⊢

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

 по аргументу,

 используйте непробелы, чтобы…

⊆¨ разбивать каждый список на список списков (удаляет пробелы, сохраняет пробелы),

⊃⍤ затем сохраните первые [каждого] (т. е. теги),

⊢⌸⍨ использовать их как ключи для группировки…

 Аргумент

3 nmjcman101 Aug 18 2020 at 03:14

vim, 13 11 байт

:sor/\w\+/r

исправление ошибок и сохранение байтов благодаря @Dingus!

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

3 user Aug 18 2020 at 01:28

Scala, 26 байт

_.sortBy(_.split("]")(0))

Возвращает List[String]без разделителя между ними, но сортируется по тегу.

Попробуй в Scastie


Возвращает Map[String,List[String]], 26 байт

_ groupBy(_.split("]")(0))

Принимает список строк и возвращает, Map[List[String]]где ключи - это теги, а значения - журналы, связанные с этим тегом.

Попробуй в Scastie


Предыдущее решение, 66 байт

_ groupBy{case s"[$t]$r"=>t}map(_._2 mkString "\n")mkString "\n"*2

Попробуйте в Scastie (по какой-то причине sне работает в TIO)

Журналы каждого приложения разделены двумя символами новой строки (я мог бы сэкономить 2 байта, если бы это был только один символ новой строки). Входные данные - это список строк, а выход - одна большая строка.

2 SomoKRoceS Aug 18 2020 at 04:41

05AB1E , 3 байта

Σ#¬

Ввод и вывод - это список журналов.

Пояснение:

Σ#¬
Σ          Sort by:
 #         Split (each log) by spaces
  ¬        Head (which is the tagname)

При этом также сохраняется порядок журналов по мере необходимости.

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

2 Neil Aug 18 2020 at 02:27

Retina 0.8.2 , 14 13 байт

O$`(\w+).*
$1

Попробуйте онлайн! Объяснение: Поскольку разделитель групп вывода не требуется, строки просто сортируются по тегу приложения, что достигается путем фиксации совпадения \w+и его указания $1в качестве ключа сортировки. Сортировка в Retina стабильна, поэтому строки с одинаковым префиксом сохранят свой порядок. Изменить: сохранен 1 байт благодаря @FryAmTheEggman за указание более простого способа сопоставления тега приложения. Обратите внимание, что хотя совпадение не включает интерлиньяж [, все строки начинаются с [, так что это не влияет на результат сортировки.

2 Noodle9 Aug 18 2020 at 03:42

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сгруппированных по первому полю в порядке появления.

1 Shaggy Aug 18 2020 at 01:32

Japt , 4 байта

Принимает входные данные как массив строк, выдает 2D-массив.

ü_¸g

Попытайся

1 Noname Aug 18 2020 at 07:14

Io , 73 байта

method(i,i map(split first)unique map(I,i select(split first==I))flatten)

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

1 JoKing Aug 18 2020 at 21:44

Perl 6 , 16 байт

*.sort:{~m/\w+/}

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

Сортировка по первой строке буквенно-цифровых символов, которая должна быть именем приложения.

1 DanielH. Aug 18 2020 at 01:11

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

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

1 JonathanAllan Aug 19 2020 at 01:02

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
1 EngineerToast Aug 19 2020 at 03:09

AutoHotkey, 74 байта

Loop,Read,f
{
s:=A_LoopReadLine
FileAppend,%s%`n,% StrSplit(s,"]","[")[1]
}

Читает из файла с именем fи выводит в несколько файлов на основе тега.

1 IsmaelMiguel Aug 19 2020 at 19:09

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

1 BlackPanther Aug 18 2020 at 20:56

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

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

Я не уверен, что первое решение совместимо с заливом кода, поэтому второе решение использует лямбда-выражение.

1 corvus_192 Aug 20 2020 at 03:43

Haskell, 37 байт

import Data.List
f=sortOn(head.words)

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

1 corvus_192 Aug 20 2020 at 03:57

Ржавчина, 40 байт

|a|a.sort_by_key(|x|x.split("]").next())

Принимает изменяемую ссылку на фрагмент строк и сортирует ее.

Попробуйте на детской площадке Rust

DominicvanEssen Aug 18 2020 at 20:30

Perl 5 -M5.10.0 -Msort = стабильный, 53 байта

say sort{(split('\]',$a))[0]cmp(split('\]',$b))[0]}<>

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