Widok rozłożonego łańcucha

39

Czy nie podobają Ci się diagramy w widoku rozstrzelonym, w których maszyna lub obiekt są rozbierane na najmniejsze części?

wprowadź opis zdjęcia tutaj

Zróbmy to z łańcuchem!

Wyzwanie

Napisz program lub funkcję, która

  1. wprowadza ciąg zawierający tylko drukowalne znaki ASCII ;
  2. dzieli ciąg na grupy znaków spacji równych („części” ciągu);
  3. wysyła te grupy w dowolnym dogodnym formacie, z pewnym separatorem między grupami .

Na przykład, biorąc pod uwagę ciąg

Ah, abracadabra!

dane wyjściowe będą następujące grupy:

!
,
ZA
aaaaa
nocleg ze śniadaniem
do
re
h
rr

Każda grupa wyjściowa zawiera równe znaki, ze spacjami usuniętymi. Nowa linia została użyta jako separator między grupami. Więcej informacji o dozwolonych formatach poniżej.

Zasady

Dane wejściowe powinny być ciągiem znaków lub tablicą znaków. Będzie zawierał tylko znaki drukowalne ASCII (obejmujący zakres od spacji do tyldy). Jeśli twój język tego nie obsługuje, możesz wprowadzić dane w postaci liczb reprezentujących kody ASCII.

Możesz założyć, że dane wejściowe zawierają co najmniej jeden znak spacji .

Dane wyjściowe powinny składać się ze znaków (nawet jeśli dane wejściowe są dokonywane za pomocą kodów ASCII). Musi istnieć jednoznaczny separator między grupami , inny niż jakikolwiek znak spacji, który może pojawić się na wejściu.

Jeśli dane wyjściowe są przekazywane przez funkcję return, może to być również tablica lub ciągi znaków, lub tablica tablic znaków lub podobna struktura. W takim przypadku struktura zapewnia niezbędną separację.

Separator między znakami każdej grupy jest opcjonalny . Jeśli istnieje, obowiązuje ta sama zasada: nie może to być znak spacji, który może pojawić się na wejściu. Ponadto nie może być tego samego separatora, co używany między grupami.

Poza tym format jest elastyczny. Oto kilka przykładów:

  • Grupy mogą być ciągami oddzielonymi znakami nowej linii, jak pokazano powyżej.

  • Grupy mogą być oddzielone dowolnym znakiem spoza ASCII, takim jak ¬. Dane wyjściowe dla powyższego wejścia to ciąg:

    !¬,¬A¬aaaaa¬bb¬c¬d¬h¬rr
    
  • Grupy mogą być oddzielone n > 1 spacjami (nawet jeśli n jest zmienna), a znaki między każdą grupą oddzielone pojedynczą spacją:

    !  ,    A   a a a a a    b b  c       d   h  r r
    
  • Wyjściem może być również tablica lub lista ciągów zwracanych przez funkcję:

    ['!', 'A', 'aaaaa', 'bb', 'c', 'd', 'h', 'rr']
    
  • Lub tablica znaków char:

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

Przykłady formatów, które są niedozwolone, zgodnie z zasadami:

  • Przecinka nie można użyć jako separatora ( !,,,A,a,a,a,a,a,b,b,c,d,h,r,r), ponieważ dane wejściowe mogą zawierać przecinki.
  • Niedopuszczalne jest upuszczanie separatora między grupami ( !,Aaaaaabbcdhrr) lub używanie tego samego separatora między grupami i wewnątrz grup ( ! , A a a a a a b b c d h r r).

Grupy mogą pojawić się w dowolnej kolejności na wyjściu. Na przykład: kolejność alfabetyczna (jak w powyższych przykładach), kolejność pierwszego pojawienia się w ciągu, ... Kolejność nie musi być spójna, a nawet deterministyczna.

Zauważ, że dane wejściowe nie mogą zawierać znaków nowego wiersza Ai asą różnymi znakami (w grupowaniu rozróżniana jest wielkość liter ).

Najkrótszy kod w bajtach wygrywa.

Przypadki testowe

W każdym przypadku testowym wprowadzany jest pierwszy wiersz, a pozostałe wiersze są danymi wyjściowymi, a każda grupa znajduje się w innym wierszu.

  • Przypadek testowy 1:

    Ach, abrakadabra!
    !
    ,
    ZA
    aaaaa
    nocleg ze śniadaniem
    do
    re
    h
    rr
    
  • Przypadek testowy 2:

    \ o / \ o / \ o /
    ///
    \\\
    ooo
    
  • Przypadek testowy 3:

    Mężczyzna, plan, kanał: Panama!
    !
    ,,
    :
    ZA
    P.
    aaaaaaaaa
    do
    ll
    mm
    nnnn
    p
    
  • Przypadek testowy 4:

    „Pokaż mi, jak sobie radzisz z tą sztuczką, która sprawia, że ​​krzyczę” - powiedziała
    „”
    ,
    S.
    aaaaa
    cc
    dd
    eeeeeee
    hhhhhh
    ii
    kk
    mmmm
    n
    ooooo
    rr
    ssss
    tttttt
    u
    w W
    y
    
Luis Mendo
źródło
1
Jeśli użyjemy jako separatora symboli innych niż ASCII, takich jak „¬”, czy można je liczyć jako 1 bajt?
Leaky Nun
5
@LeakyNun Nie, zostanie policzone, ponieważ odpowiada, w zależności od kodowania użytego dla kodu źródłowego, jak zwykle
Luis Mendo
Czy końcowy znak nowej linii po ostatniej grupie jest akceptowalny?
JustinM - Przywróć Monikę
Czy wiodąca nowa linia produkcji jest akceptowalna?
DJMcMayhem
1
@RohanJhunjhunwala Dobra robota! :-) Tak, kilka newlines jak separatorów jest w porządku
Luis Mendo

Odpowiedzi:

11

Galaretka , 5 bajtów

ḟ⁶ṢŒg

Wypróbuj online!

Zwraca tablicę, tyle że po wydrukowaniu do STDOUT separator zniknął.

Jest to rzeczywiście funkcja, którą można wywołać jako taką (w Galaretce każda linia jest funkcją).

ḟ⁶ṢŒg
ḟ⁶      filter out spaces
  Ṣ     sort
   Œg   group
Leaky Nun
źródło
23

Python 3.5+, 77 46 44 41 bajtów

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

Dość proste. Przechodzi przez unikalne znaki w ciągu, konwertując go na zestaw (za pomocą rozszerzonego iterowalnego rozpakowywania w Pythonie 3.5), a następnie używa rozumienia listy do budowy rozłożonych diagramów, zliczając liczbę przypadków, w których każdy znak występuje w ciągu str.count. Filtrujemy spacje, usuwając je z zestawu.

Kolejność danych wyjściowych może się różnić w zależności od serii; zestawy są nieuporządkowane, więc nie można zagwarantować kolejności przetwarzania ich elementów, a tym samym wyników odpowiedzi.

To jest wyrażenie lambda; aby go użyć, przedrostek lambdaz f=.

Wypróbuj na Ideone! Ideone używa Python 3.4, co nie jest wystarczające.

Przykład użycia:

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

Zaoszczędź 3 bajty dzięki @shooqie!

Miedź
źródło
3
Gratulacje za 1k!
Luis Mendo,
2
W Pythonie> 3.5 można to zrobić {*s}za set(s).
shooqie,
11

Siatkówka, 13 bajtów

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

Sortowanie jest bardzo łatwe (jest wbudowane), separuje litery, które zajmują 9 bajtów. Wypróbuj online!

Pierwszy wiersz zawiera Owszystkie dopasowania wyrażenia regularnego .(czyli każdej postaci), dając nam !,Aaaaaabbcdhrr.

Dopasowanie jest domyślnym etapem dla ostatniego wiersza programu i !powoduje, że drukuje listę dopasowań wyrażenia regularnego oddzieloną od linii. Wyrażenie regularne szuka jednego lub więcej wystąpień znaku spacji w wierszu.

NinjaBearMonkey
źródło
8

Perl 6 , 28 bajtów

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

Pamiętaj, że Bag jak Hash lub Set jest nieuporządkowany, więc kolejność wyników nie jest gwarantowana.

Wyjaśnienie:

# 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")
Brad Gilbert b2gills
źródło
7

Vim, 50 , 46 bajtów

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

Wyjaśnienie / gif przyjdzie później.

DJMcMayhem
źródło
1
Po raz pierwszy rozwiązania Emacsa i vima wyglądają podobnie.
YSC
7

Pyth, 6

.gk-zd

Wypróbuj tutaj lub uruchom pakiet testowy .

Całkiem proste, -zdusuwa spacje z wejścia i .gkgrupuje każdy pozostały element według jego wartości. Niestety nie znalazłem sposobu na użycie zmiennych autouzupełniania. Zauważ, że dane wyjściowe są wyświetlane jako ciągi znaków w języku Python, więc niektóre znaki (czytaj: ukośniki odwrotne) są unikane. Jeśli chcesz, aby był bardziej czytelny, dodaj a jna początku kodu.

FryAmTheEggman
źródło
7

Haskell, 38 bajtów

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

Zasadniczo rozwiązanie nich , ale jawne sprawdzanie tylko liter pojawiających się w ciągu.

xnor
źródło
6

2sable , 7 bajtów

Kod:

Úð-vyÃ,

Wyjaśnienie:

Ú       # 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

Wykorzystuje kodowanie CP-1252 . Wypróbuj online!

Adnan
źródło
3
To wcale nie brzmi jak Dennis :-P
Luis Mendo
6

JavaScript (ES6), 41 bajtów

s=>[...s].sort().join``.match(/(\S)\1*/g)
Neil
źródło
Czy nie spowodowałoby to również wpisu " "w zwróconej tablicy? Nie jestem pewien, czy to dozwolone
Value Ink
@ValueInk Bah, pomyślałem o tym, kiedy zacząłem, ale szybko zapomniałem. Naprawiono teraz.
Neil,
Umm, jak join()się nazywa się tymi podwójnymi uderzeniami wstecznymi?
Tejas Kale
1
@TejasKale To jest ciąg szablonu ES6. Kiedy prefiksujesz metodę do ciągu szablonu, przekazuje szablon jako tablicę do metody, więc w tym przypadku kończy się wywołanie .join(['']). joinnastępnie konwertuje to na (pusty) ciąg i używa tego do łączenia elementów tablicy. Nie wszystkie metody konwertują swój parametr na ciąg, ale ta technika jest przydatna dla tych, które to robią.
Neil
5

Haskell, 40 bajtów

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

Przykład użycia: f "Ah, abracadabra!"-> ["!",",","A","aaaaa","bb","c","d","h","rr"].

Wzorzec v:wpasuje tylko do listy z co najmniej jednym elementem, więc wszystkie znaki spoza wejścia są ignorowane.

Również 40 bajtów:

import Data.List
group.sort.filter(>' ')
nimi
źródło
@ThreeFx: Ale też groupjest z Data.List. W każdym razie myślę, że ta składnia jest ghcitylko i wymaga REPL, więc jest to własny język . Chcę trzymać się standardowego Haskell.
nimi
4

Rubinowy, 41 + 1 = 42 bajty

+1 bajt dla -nflagi.

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

Pobiera dane wejściowe na standardowe wejście, np .:

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

C # 125 98 bajtów

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

Wyjaśnienie

//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()));
  • Dzięki @TheLethalCoder, który zasugerował użycie anonimowej funkcji, która pozwoliła mi również usunąć ToArraywywołanie i po prostu niejawnie zwrócić IEnumerable, który łącznie oszczędza 27 bajtów
JustinM - Przywróć Monikę
źródło
Możesz zapisać 18 bajtów (jeśli poprawnie policzyłem), kompilując je do Func<string, string[]>ies=>s.GroupBy....
TheLethalCoder
@TheLethalCoder czy jesteś pewien, że jest to akceptowalne zamiast funkcji, zawsze uważałem na to, ponieważ dodaje sporo dodatkowej płyty kotła, aby móc ją wykonać, a argument za tym, że wymaga użycia Linq po prostu wydaje się ... cóż, źle.
JustinM - Przywróć Monikę
Oto ostatni przykład, w którym to robię ... codegolf.stackexchange.com/a/91075/38550 usunie wszystkie płyty kotła , o ile funkcje są dozwolone
TheLethalCoder
@TheLethalCoder OK, to mi wystarczy. :) To pozwoliło mi również, aby usunąć wywołanie ToArray
JustinM - dozbrojenie Monica
4

R 198 189 96 95 bajtów

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

Nie golfowany:

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

To rozwiązanie nie działa obecnie w pełni, jeśli \są zaangażowane.
Teraz jest !

Dziękuję o wiele do @JDL do golfa z 102 bajtów!

Frédéric
źródło
@JDL: Proszę sugerować zmiany w komentarzach. Twoje zmiany są naprawdę interesujące, ale trochę niegrzecznie jest zmieniać kod innej osoby w ten sposób.
Frédéric,
1
przepraszam za to, ale nie miałem wtedy 50 reputacji i nie mogłem komentować. Zrobi to w przyszłości!
JDL
@JDL: Wystarczająco sprawiedliwe!
Frédéric
Spróbuj przypisać zmienną do funkcji: for(i in unique(a=strsplit(gsub(" ","",readline()),"")[[1]]))cat(rep(i,sum(a==i)),"\n",sep="")- zapisuje 2 bajty.
Andreï Kostyrka
@ AndreïKostyrka: Nie zapisuje bajtów w tej formie, ponieważ musisz umieścić całą część a = strsplit (...) między nawiasami: w zasadzie robi różnicę -2 + 2. Jednak użycie <-pozwoli zaoszczędzić 1 bajt!
Frédéric
4

Szybki, 105 91 bajtów

Dzięki @NobodyNada za 14 bajtów :)

Tak, jestem całkiem nowy w Swift ...

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

Znaki w grupie są oddzielone jedną nową linią. Grupy są oddzielone dwoma znakami nowej linii.

jrich
źródło
Możesz zapisać 13 bajtów, przyjmując dane wejściowe [Character]zamiast a String, ponieważ reguły mówią „Dane wejściowe powinny być ciągiem znaków lub tablicą znaków”. Ponadto, print("")może być zastąpiony tylko print().
NobodyNada - Przywróć Monikę
@NNNNada printbez argumentów nie działała z jakiegoś powodu, ale [Character]sugestia była solidna. Dzięki!
jrich
3

Oktawa , 61 bajtów

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

Jest to anoymiczna funkcja, która pobiera ciąg znaków na wejściu i wysyła tablicę komórek ciągów znaków.

Wypróbuj w Ideone .

Jak to działa

  • sortsortuje ciąg wejściowy. W szczególności spacje będą na początku.
  • strtrim usuwa wiodące spacje.
  • diff(+y) oblicza kolejne różnice między znakami (w celu wykrycia granic grupy) ...
  • ... diff(find([1 diff(+y) 1])daje wektor wielkości grup.
  • mat2cell następnie dzieli posortowany ciąg na kawałki o tych rozmiarach.
Luis Mendo
źródło
3

Mathematica, 36 bajtów

Wbudowane funkcje Gatheri Characterswiększość pracy tutaj.

Gather@Select[Characters@#,#!=" "&]&
Greg Martin
źródło
3

> <> , 49 bajtów

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

Bardzo obszernie marnotrawstwo w danych wyjściowych, ale zakładam, że nadal jest dozwolone ze względu na łagodność zasad

Wyjaśnienie:

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

zmieściłem niektóre rzeczy dość ciasno, nawet używając skoków, aby obejść niektóre funkcje, dzięki czemu mogłem uruchomić wskaźnik pionowo.

Zasadniczo powoduje to umieszczenie każdego znaku ASCII we własnej nowej linii, a jeśli żaden z tych znaków nie istnieje, wiersz będzie pusty

Wypróbuj online

Edycja: pomyliłem się, wystąpił błąd w kodzie, który spowodowałby, że nigdy się nie wypełnił, gdyby na wejściu było spacja

torcado
źródło
3

Pyth, 5 bajtów

.gksc

Wypróbuj tutaj!

Pobiera dane wejściowe jako ciąg znaków w języku Python (tzn. Jest zawijany w cudzysłów, w razie potrzeby jest poprzedzany cudzysłowami i ukośnikami).

Wyjaśnienie:

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

Jeśli zagwarantujesz przynajmniej jedno miejsce na wejściu, istnieje rozwiązanie 4-bajtowe:

t.gk

Wypróbuj tutaj!

Wyjaśnienie:

 .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)
Steven H.
źródło
3

PowerShell v2 +, 44 bajty

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

Pobiera dane wejściowe $args[0]jako ciąg literału argumentu wiersza poleceń. Rzuca to jako char-array i używa operatora -not eQual do wyciągania spacji (ASCII 32). Działa to, ponieważ rzutowanie ma pierwszeństwo wyższego rzędu, a gdy tablica jest używana jako operator po lewej stronie, a skalar jako prawa ręka, działa jak filtr.

Przekazujemy tę tablicę znaków Group-Object, która robi dokładnie to, co mówi. Zauważ, że ponieważ przekazujemy znaki , a nie ciągi znaków, odpowiednio grupuje się je z rozróżnianiem wielkości liter.

Teraz mamy niestandardowy obiekt (y), który ma nazwy grup, liczby itp. Jeśli po prostu wydrukujemy, będziemy mieli mnóstwo niepotrzebnych danych wyjściowych. Więc musimy rury te w pętlę |%{...}i każda iteracja razem w jeden ciąg. Te powstałe ciągi są pozostawione w potoku, a dane wyjściowe są niejawne po zakończeniu programu.-join.Group

Przykład

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
AdmBorkBork
źródło
2

Przetwarzanie, 109 bajtów

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

Jest to podejście brutalnej siły, posortuj tablicę, a następnie przejdź przez nią. Jeśli nie pasuje do ostatniego drukowanego znaku, najpierw wydrukuj nowy wiersz. Jeśli jest to biały znak, pomiń krok drukowania.

Cody
źródło
2

JavaScript (przy użyciu zewnętrznej biblioteki - Enumerable) ( 78 67 bajtów)

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

Link do lib: https://github.com/mvegh1/Enumerable

Wyjaśnienie kodu: Właśnie do tego został stworzony Enumerable! Załaduj ciąg do biblioteki, która konwertuje go na tablicę char. Odfiltruj białe znaki. Grupuj według char. Zapisz każdą grupę do wiersza zgodnie z określonym orzeczeniem. Ten predykat mówi, aby połączyć wszystkie elementy bieżącej grupy w ciąg bez separatora.

wprowadź opis zdjęcia tutaj

applejacks01
źródło
2

Perl6, 48 47 45

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

Dzięki manatwork za ulepszenia.

bb94
źródło
1
Niewielka poprawa, ale $a.trimwydaje się, że robi to w przypadku stanu.
manatwork
Wygląda na to, że operatory logiczne nadal nie potrzebują odstępów wokół nich, więc $^a.trim&&say $a x$^bdziała. (Przepraszam, że
dodałem
Mała literówka, przypadkowo usunąłeś otwór {.
manatwork
1

Rubinowy, 46 bajtów

Wypróbuj online!

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

Moja oryginalna pełna wersja programu, 48 bajtów po dodaniu nflagi:

p gsub(/\s/){}.chars.uniq.map{|c|c*$_.count(c)}
Wartość tuszu
źródło
Można zastąpić .count(c)z .count c?
Cyoce
@Cyoce nie, ponieważ *operator jest w pobliżu, więc parser będzie narzekał.
Wartość tuszu
s.chars- [''] | [] w nawiasach uniknąłby uniq
GB
@GB Tak, ale jeśli do maptego przyłożymy, to potrzebuje dodatkowych parens i ((s.chars-[' '])|[]).mapma taką samą liczbę znaków jak (s.chars-[' ']).uniq.map. A inny, krótszy sposób sprawdzania unikalnych znaków (przez regex) jest już objęty @Jordan w innej odpowiedzi
Value Ink
Działa w nawiasach, nie potrzebujesz dodatkowych nawiasów, ponieważ wyższy priorytet ma „-”.
GB
1

Python, 107

Może zostać skrócony przez lambdę, ale później

x=sorted(input())
i=0
while i<len(x):x[i:]=['  '*(x[i]!=x[i-1])]+x[i:];i-=~(x[i]!=x[i-1])
print("".join(x))
Zniszczalna cytryna
źródło
1

CJam, 10 bajtów

{S-$e`::*}

Nienazwany blok, który oczekuje ciągu na szczycie stosu i zastępuje go listą ciągów.

Wypróbuj online!

Wyjaśnienie

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.
Martin Ender
źródło
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))

Nie golfowany:

(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))

Nie najbardziej przyjazny język golfowi. Prawdopodobnie można to zmodyfikować, aby zwracać listę list zamiast wypisywać ciąg.

MatthewRock
źródło
1

Emacs, 36 klawiszy

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

Wynik

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

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

Wyjaśnienie

  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. Wybierz linię wprowadzania;
  2. Zadzwoń sort-regexp-fieldsz argumentami .i .;
    • Argument nr 1: Regexp scpecifying rekordy do sortowania
    • Argument nr 2: Regeksp klucz scpecifying w obrębie rekordów
  3. Wróć na początku linii;
  4. Zastosuj podstawienie wyrażenia regularnego \(\(.\)\2*\)-> \1\nwe wszystkich dopasowaniach.
YSC
źródło