В разобранном виде строки


39

Разве вам не нравятся те диаграммы с разбивкой по видам, на которых машина или объект разбиты на мелкие части?

введите описание изображения здесь

Давайте сделаем это со строкой!

Соревнование

Напишите программу или функцию, которая

  1. вводит строку, содержащую только печатаемые символы ASCII ;
  2. разбивает строку на группы непробельных одинаковых символов («кусочки» строки);
  3. выводит эти группы в любом удобном формате с некоторым разделителем между группами .

Например, учитывая строку

Ah, abracadabra!

на выходе будут следующие группы:

!
,

ааааа
бб
с
d
час
р-р

Каждая группа в выходных данных содержит одинаковые символы с удаленными пробелами. Новая строка была использована в качестве разделителя между группами. Подробнее о разрешенных форматах ниже.

правила

Вход должен быть строкой или массивом символов. Он будет содержать только печатные символы ASCII (включающий диапазон от пробела до тильды). Если ваш язык не поддерживает это, вы можете принять ввод в виде чисел, представляющих коды ASCII.

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

Выход должен состоять из символов (даже если вход с помощью ASCII - кодов). Между группами должен быть однозначный разделитель , отличный от любого непробельного символа, который может появиться во входных данных.

Если выходные данные выполняются через функцию return, это может быть также массив или строки, или массив массивов символов или аналогичная структура. В этом случае структура обеспечивает необходимое разделение.

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

Помимо этого, формат гибкий. Вот некоторые примеры:

  • Группы могут быть строками, разделенными символами новой строки, как показано выше.

  • Группы могут быть разделены любым не-ASCII символом, таким как ¬. Выход для указанного выше ввода будет строкой:

    !¬,¬A¬aaaaa¬bb¬c¬d¬h¬rr
    
  • Группы могут быть разделены n > 1 пробелами (даже если n переменная), с символами между каждой группой, разделенными одним пробелом:

    !  ,    A   a a a a a    b b  c       d   h  r r
    
  • Вывод также может быть массивом или списком строк, возвращаемых функцией:

    ['!', 'A', 'aaaaa', 'bb', 'c', 'd', 'h', 'rr']
    
  • Или массив массивов символов:

    [['!'], ['A'], ['a', 'a', 'a', 'a', 'a'], ['b', 'b'], ['c'], ['d'], ['h'], ['r', 'r']]
    

Примеры форматов, которые не разрешены, согласно правилам:

  • Запятую нельзя использовать в качестве разделителя ( !,,,A,a,a,a,a,a,b,b,c,d,h,r,r), потому что ввод может содержать запятые.
  • Не допускается удалять разделитель между группами ( !,Aaaaaabbcdhrr) или использовать один и тот же разделитель между группами и внутри групп ( ! , A a a a a a b b c d h r r).

Группы могут появляться в любом порядке в выходных данных. Например: алфавитный порядок (как в примерах выше), порядок первого появления в строке, ... Порядок не должен быть последовательным или даже детерминированным.

Обратите внимание , что ввод не может содержать символы новой строки, а Aи aразличные символы (группировка случай-sentitive ).

Самый короткий код в байтах побеждает.

Контрольные примеры

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

  • Тестовый пример 1:

    Ах, абракадабра!
    !
    ,
    
    ааааа
    бб
    с
    d
    час
    р-р
    
  • Контрольный пример 2:

    \ О / \ о / \ о /
    ///
    \\\
    ооо
    
  • Тестовый пример 3:

    Человек, план, канал: Панама!
    !
    ,,
    :
    
    п
    ааааааааа
    с
    Л.Л.
    мм
    нннн
    п
    
  • Контрольный пример 4:

    «Покажите мне, как вы делаете этот трюк, тот, который заставляет меня кричать», сказала она
    «»
    ,
    S
    ааааа
    куб.см
    дд
    eeeeeee
    HHHHHH
    б
    кк
    мммм
    N
    ооооо
    р-р
    ГССО
    TTTTTT
    U
    WW
    Y
    

1
Если мы используем символы не ASCII, такие как «¬», в качестве разделителя, можно ли считать его 1 байтом?
Утренняя монахиня

5
@LeakyNun Нет, он будет засчитан как соответствующий в зависимости от кодировки, используемой для исходного кода, как обычно
Luis Mendo

Допустим ли трейлинг-перевод строки после последней группы?
ДжастинМ - Восстановить Монику

Является ли приемлемым перевод строки?
DJMcMayhem

1
@RohanJhunjhunwala Молодцы! :-) Да, несколько новых строк в качестве разделителей в порядке
Луис Мендо

Ответы:


11

Желе , 5 байт

ḟ⁶ṢŒg

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

Он возвращает массив, только когда он печатается в STDOUT, разделитель исчезает.

Это действительно функция, которая может быть вызвана как таковая (в Jelly каждая строка является функцией).

ḟ⁶ṢŒg
ḟ⁶      filter out spaces
  Ṣ     sort
   Œg   group

23

Python 3.5+, 77 46 44 41 байт

lambda s:[a*s.count(a)for a in{*s}-{' '}]

Довольно просто Проходит через уникальные символы в строке, преобразовывая ее в набор (используя расширенную итеративную распаковку в Python 3.5), затем использует понимание списка для построения разнесенных диаграмм, подсчитывая количество раз, когда каждый символ встречается в строке сstr.count . Мы отфильтровываем пробелы, удаляя их из набора.

Порядок вывода может варьироваться от запуска к запуску; множества неупорядочены, поэтому порядок, в котором обрабатываются их элементы, и, следовательно, этот ответ, не может быть гарантирован.

Это лямбда-выражение; чтобы использовать его, префикс lambdaсf= .

Попробуйте это на Ideone! Ideone использует Python 3.4, которого недостаточно.

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

>>> f=lambda s:[a*s.count(a)for a in{*s}-{' '}]
>>> f('Ah, abracadabra!')
[',', 'A', 'aaaaa', 'd', '!', 'bb', 'h', 'c', 'rr']

Сохранено 3 байта благодаря @shooqie!


3
Поздравляю на 1к!
Луис Мендо

2
В Python> 3.5 вы можете сделать {*s}для set(s).
shooqie

11

Сетчатка, 13 байт

O`.
!`(\S)\1*

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

Первая строка Oсодержит все совпадения регулярного выражения .(каждый символ), давая нам !,Aaaaaabbcdhrr .

Соответствие является этапом по умолчанию для последней строки программы, и !она выводит список совпадений регулярного выражения, разделенный переводом строки. Регулярное выражение ищет один или несколько экземпляров непробельного символа в строке.


Что это ! Делать?
Downgoat


8

Perl 6 , 28 байт

*.comb(/\S/).Bag.kv.map(*x*)

Обратите внимание, что Bag как Hash или Set неупорядочен, поэтому порядок результатов не гарантируется.

Объяснение:

# Whatever lambda 「*」


# grab the characters
*.comb(
  # that aren't white-space characters
  /\S/
)
# ("A","h",",","a","b","r","a","c","a","d","a","b","r","a","!")


# Turn into a Bag ( weighted Set )
.Bag
# {"!"=>1,","=>1,"A"=>1,"a"=>5,"b"=>2,"c"=>1,"d"=>1,"h"=>1,"r"=>2}


# turn into a list of characters and counts
.kv
# ("!",1,",",1,"A",1,"a",5,"b",2,"c",1,"d",1,"h",1,"r",2)


# map over them 2 at a time
.map(
  # string repeat the character by the count
  * x *
)
# ("!",",","A","aaaaa","bb","c","d","h","rr")

7

Vim, 50 , 46 байтов

i <esc>:s/./&\r/g
:sor
qq:%s/\v(.)\n\1/\1\1
@qq@qD

Объяснение / GIF придет позже.


1
На этот раз решения Emacs & vim выглядят одинаково.
СМУ

7

Пиф, 6

.gk-zd

Попробуйте здесь или запустите Test Suite .

Довольно просто, -zdудаляет пробелы из входных данных и .gkгруппирует каждый оставшийся элемент по его значению. К сожалению, я не нашел способа использовать переменные автозаполнения. Обратите внимание, что выходные данные отображаются в виде строк Python, поэтому определенные символы (читай: обратная косая черта) экранируются. Если вы хотите, чтобы он был более читабельным, добавьте jв начало кода.


7

Haskell, 38 байт

f s=[filter(==c)s|c<-['!'..],elem c s]

В основном решение Ними , но явно проверяет только буквы, появляющиеся в строке.


6

2sable , 7 байтов

Код:

Úð-vyÃ,

Объяснение:

Ú       # Uniquify the string, aabbcc would result into abc
 ð-     # Remove spaces
   vy   # For each character...
     Ã  #   Keep those in the string, e.g. 'aabbcc', 'a' would result into 'aa'
      , #   Pop and print with a newline

Использует кодировку CP-1252 . Попробуйте онлайн!


3
Это совсем не похоже на Денниса :-P
Луис Мендо

6

JavaScript (ES6), 41 байт

s=>[...s].sort().join``.match(/(\S)\1*/g)

Не приведет ли это также " "к существованию записи в возвращаемом массиве? Не уверен, что это разрешено
Value Ink

@ValueInk Бах, я думал об этом, когда начал, но быстро забыл. Исправлено сейчас.
Нил

Хм, как join()называется с этими двойными бэктиксами?
Техас Кале

1
@TejasKale Это строка шаблона ES6. Когда вы добавляете метод к строке шаблона, он передает шаблон как массив в метод, поэтому в этом случае он заканчивается вызовом .join(['']). joinзатем преобразует это в (пустую) строку и использует это для соединения элементов массива. Не все методы преобразуют свои параметры в строку, но этот метод удобен для тех, кто это делает.
Нил


5

Haskell, 40 байт

f x=[v:w|d<-['!'..],v:w<-[filter(==d)x]]

Пример использования: f "Ah, abracadabra!"-> ["!",",","A","aaaaa","bb","c","d","h","rr"].

Шаблон v:wсоответствует только списку хотя бы с одним элементом, поэтому все символы, отсутствующие во входных данных, игнорируются.

Также 40 байтов:

import Data.List
group.sort.filter(>' ')

@ThreeFx: Но groupэто Data.Listтоже из. Во всяком случае, я думаю, что этот синтаксис ghciтолько и нуждается в REPL, так что это собственный язык . Я хочу придерживаться стандартного Haskell.
Ними

4

Рубин, 41 + 1 = 42 байта

+1 байт за -nфлаг.

gsub(/(\S)(?!.*\1)/){puts$1*$_.count($1)}

Принимает ввод на стандартный ввод, например:

$ echo 'Ah, abracadabra!' | ruby -ne 'gsub(/(\S)(?!.*\1)/){puts$1*$_.count($1)}'
A
h
,
c
d
bb
rr
aaaaa
!

4

C # 125 98 байт

using System.Linq;s=>s.GroupBy(c=>c).Where(g=>g.Key!=' ').Select(g=>new string(g.Key,g.Count())));

объяснение

//Using anonymous function to remove the need for a full signature 
//And also allow the implicit return of an IEnumerable
s =>

    //Create the groupings
    s.GroupBy(c => c)

    //Remove spaces
    .Where(g=> g.Key!=' ')

    //Generate a new string using the grouping key (the character) and repeating it the correct number of times
    .Select(g => new string(g.Key, g.Count()));
  • Спасибо @TheLethalCoder, который предложил использовать анонимную функцию, которая также позволила мне удалить ToArrayвызов и просто неявно вернуть IEnumerable, который в совокупности экономит 27 байтов

Вы можете сэкономить 18 байт (если я правильно посчитал), скомпилировав их в то Func<string, string[]>естьs=>s.GroupBy....
TheLethalCoder

@TheLethalCoder вы уверены, что это приемлемо вместо функции, я всегда был осторожен с этим, потому что он добавляет довольно много дополнительного шаблона для возможности его выполнения, и с аргументом для требования использования Linq это просто кажется ... хорошо не так.
ДжастинМ - Восстановить Монику

Вот недавний пример, где я это делаю ... codegolf.stackexchange.com/a/91075/38550 это удалит все ваши шаблоны, если функции разрешены
TheLethalCoder

@TheLethalCoder Хорошо, это достаточно хорошо для меня. :) Это также позволило мне удалить ToArray вызов
JustinM - восстановим Моника

4

R, 198 189 96 95 байт

for(i in unique(a<-strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")

Ungolfed:

a<-strsplit(gsub(" ","",readline()),"")[[1]] #Takes the input from the console

for(i in unique(a)) #loop over unique characters found in variable a

cat(rep(i,sum(a==i)),"\n",sep="") # print that character n times, where n was the number of times it appeared

Это решение в настоящее время не совсем работает, когда \участвуют.
Теперь это !

Спасибо намного вам @JDL для игры в гольф из 102 байт!


@JDL: Пожалуйста, предлагайте правки в комментариях. Ваши изменения действительно интересны, но немного грубо менять чужой код подобным образом.
Фредерик

1
извиняюсь за это, но у меня не было 50 репутации в то время и я не мог комментировать. Будет делать в будущем, хотя!
JDL

@JDL: достаточно справедливо!
Фредерик

Попробуйте назначить переменную внутри функции: for(i in unique(a=strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")- сохраняет 2 байта.
Андрей Костырка

@ AndreïKostyrka: он не сохраняет байты в этой форме, потому что вы должны поместить целую часть a = strsplit (...) в скобки: в основном разница составляет -2 + 2. Тем не менее, использование <-сэкономит 1 байт!
Фредерик

4

Swift, 105 91 байт

Спасибо @NobodyNada за 14 байтов :)

Да, я довольно новичок в Swift ...

func f(a:[Character]){for c in Set(a){for d in a{if c==d && c != " "{print(c)}}
print("")}}

Символы в группе разделены одной новой строкой. Группы разделены двумя новыми строками.


Вы можете сэкономить 13 байтов, взяв ввод [Character]вместо a String, поскольку правила гласят: «Ввод должен быть строкой или массивом символов». Также print("")можно заменить на просто print().
NobodyNada - Восстановить Монику

@NobodyNada printбез аргументов не работал по какой-то причине, но [Character]предложение было твердым. Благодарность!
рождения

3

Октава , 61 байт

@(x)mat2cell(y=strtrim(sort(x)),1,diff(find([1 diff(+y) 1])))

Это аномальная функция, которая принимает строку в качестве входных данных и выводит массив ячеек строк.

Попробуйте в Ideone .

Как это работает

  • sortсортирует входную строку. В частности, пробелы будут в начале.
  • strtrim удаляет ведущие пробелы
  • diff(+y) вычисляет последовательные различия между символами (чтобы определить границы группы) ...
  • ... так diff(find([1 diff(+y) 1])дает вектор размеров группы.
  • mat2cell затем разбивает отсортированную строку на куски с этими размерами.

3

Mathematica, 36 байт

Встроенные функции Gatherи Charactersбольшая часть работы здесь.

Gather@Select[Characters@#,#!=" "&]&

3

> <> , 49 байтов

i:0(?v
84}0~/&{!*
v!?: <}/?=&:&:<
>&1+&}aol1-?!;^

Очень пространно расточительно в выводе, но я предполагаю, что все еще разрешено, учитывая снисходительность правил

Объяснение:

i:0(?v           Collects text from input
84}0~/&{!*       adds 32 (first ascii starting at space) to register and 0 to stack
v!?: <}/?=&:&:<  checks all characters to the current register, if equal:
       o         prints the character and continues looping
>&1+&}aol1-?!;^  when all characters are checked, adds 1 to register, prints a newline,
                 checks the stack length to halt the program if 0, and starts looping again

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

В основном это помещает каждый символ ASCII на собственную новую строку, и если ни один из этих символов не существует, строка будет пустой

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

Редактировать: я был не прав, в коде произошла ошибка, из-за которой он никогда не завершился, если во входе был пробел


3

Pyth, 5 байт

.gksc

Попробуй это здесь!

Принимает ввод в виде строки Python (то есть, заключенный в кавычки, экранированные кавычки и косые черты при необходимости).

Объяснение:

    c    Split (implied) input on whitespace
   s     Sum together
.gk      Group by value

Если вы гарантируете хотя бы один пробел во вводе, есть 4-байтовое решение:

t.gk

Попробуй это здесь!

Объяснение:

 .gk (Q)  groups the characters in the string by their value
           this sorts them by their value, which guarantees that spaces are first
t         Remove the first element (the spaces)

3

PowerShell v2 +, 44 байта

[char[]]$args[0]-ne32|group|%{-join$_.Group}

Принимает ввод $args[0]как аргумент командной строки. charПриводит его как -array и использует оператор -not equal для выделения пробелов (ASCII32 ). Это работает, потому что приведение имеет приоритет более высокого порядка, и когда массив используется в качестве левого оператора со скаляром в качестве правого, он действует как фильтр.

Мы передаем этот массив символов Group-Object, который делает именно то, что говорит. Обратите внимание, что, поскольку мы передаем символы , а не строки, это правильно группирует с учетом регистра.

Теперь у нас есть пользовательский объект (ы) с именами групп, количеством и т. Д. Если мы просто напечатаем, у нас будет множество посторонних выводов. Таким образом, мы должны трубы те в петлю , |%{...}и каждая итерация вместе в одну строку. Эти результирующие строки остаются в конвейере, и вывод завершается неявно при завершении программы.-join.Group

пример

PS C:\Tools\Scripts\golfing> .\exploded-view-of-substrings.ps1 'Programming Puzzles and Code Golf'
PP
rr
ooo
gg
aa
mm
i
nn
u
zz
ll
ee
s
dd
C
G
f


2

Обработка, 109 байт

void s(char[] x){x=sort(x);char l=0;for(char c:x){if(c!=l)println();if(c!=' '&&c!='\n'&&c!='\t')print(c);l=c;}}

Это метод грубой силы, сортировка массива, затем цикл по нему. Если он не совпадает с последним напечатанным символом, сначала выведите новую строку. Если это пробел, пропустите шаг печати.


2

Javascript (с использованием внешней библиотеки - перечисляемый) ( 78 67 байт)

 n=>_.From(n).Where(y=>y!=' ').GroupBy(x=>x).WriteLine(y=>y.Write())

Ссылка на lib: https://github.com/mvegh1/Enumerable

Объяснение кода: это то, что Enumerable был создан, чтобы сделать! Загрузите строку в библиотеку, которая преобразует ее в массив символов. Отфильтруйте записи пробелов. Группировать по символу Запишите каждую группу в строку в соответствии с указанным предикатом. Этот предикат говорит, что все элементы текущей группы должны быть объединены в строку без разделителя.

введите описание изображения здесь



2

Perl6, 48 47 45

slurp.comb.Bag.kv.map:{$^a.trim&&say $a x$^b}

Спасибо manatwork за улучшения.


1
Не большое улучшение, но, $a.trimкажется, делает это для состояния.
manatwork

Кажется, логические операторы до сих пор не нуждаются в пробелах вокруг них, поэтому $^a.trim&&say $a x$^bработает. (Извините за добавление подсказок побайтно, но это моя первая попытка на Perl6.)
manatwork

Маленькая опечатка, вы случайно удалили отверстие {.
manatwork

1

Рубин, 46 байт

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

->s{(s.chars-[' ']).uniq.map{|c|c*s.count(c)}}

Моя оригинальная полная версия программы, 48 байтов после добавления nфлага:

p gsub(/\s/){}.chars.uniq.map{|c|c*$_.count(c)}

Вы можете заменить .count(c)на .count c?
Cyoce

@ Нет, потому что *рядом есть оператор, поэтому парсер будет жаловаться.
Стоимость чернил

s.chars- [''] | [] внутри скобок позволит избежать уникальности
GB

@GB Это было бы, но если мы приковываем это к map ему нужны дополнительные парены, и ((s.chars-[' '])|[]).mapколичество символов в них равно (s.chars-[' ']).uniq.map. И другой, более короткий способ проверки уникальных символов (с помощью регулярных выражений) уже описан @Jordan в другом ответе
Value Ink

Он работает внутри скобок, вам не нужны дополнительные скобки, потому что приоритет «-» выше.
GB


1

CJam, 10 байтов

{S-$e`::*}

Безымянный блок, который ожидает строку в верхней части стека и заменяет ее списком строк.

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

объяснение

S-  Remove spaces.
$   Sort.
e`  Run-length encode, gives pairs [R C], where R is the run-length and
    C is the character.
::* Repeat the C in each pair R times.

1

Common Lisp, 123

(lambda(s &aux(w(string-trim" "(sort s'char<))))(princ(elt w 0))(reduce(lambda(x y)(unless(char= x y)(terpri))(princ y))w))

Ungolfed:

(lambda (s &aux (w (string-trim " " (sort s 'char<))))
  (princ (elt w 0))
  (reduce
    (lambda (x y) 
      (unless (char= x y) (terpri))
      (princ y))
  w))

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


1

Emacs, 36 нажатий клавиш

C-SPACE C-EM-xsort-rTABRETURN.RETURN.RETURNC-AC-M-S-%\(\(.\)\2*\)RETURN\1C-QC-JRETURN!

Результат

A man, a plan, a canal: Panama! ->

!
,,
:
A
P
aaaaaaaaa
c
ll
mm
nnnn
p

объяснение

  1. C-SPACE C-E
  2. M-x sort-rTAB RETURN .RETURN .RETURN
  3. C-A
  4. C-M-S-% \(\(.\)\2*\)RETURN\1 C-Q C-JRETURN !

  1. Выберите строку ввода;
  2. Звони sort-regexp-fieldsс аргументами .и. ;
    • Аргумент № 1: регулярное выражение, указывающее записи для сортировки
    • Аргумент № 2: регулярное выражение определяющего ключа в записях
  3. Возврат в начало строки;
  4. Применить регулярное выражение \(\(.\)\2*\)-> \1\nна все совпадения.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.