Liczba znaków w kodzie źródłowym

12

Napisz program, który wyświetli listę liczby wystąpień każdego unikalnego znaku w kodzie źródłowym.

Na przykład ten hipotetyczny program {Source_Print_1};powinien generować takie dane wyjściowe:

; 1
P 1
S 1
_ 2
c 1
e 1
i 1
n 1
o 1
p 1
r 2
t 1
u 1
{ 1
} 1

Formatowanie powinno pasować do tego przykładu. Żadne obce białe znaki nie są dozwolone, z wyjątkiem opcjonalnego końcowego nowego wiersza.

Twój program może nie odczytać własnego kodu źródłowego z pliku źródłowego.

Wymienione postacie muszą być w jednym z dwóch rzędów. Albo kolejność wartości znaków w kodowaniu znaków używanych przez Twój język (prawdopodobnie ASCII), albo kolejność znaków w twoim źródle.

To pytanie zainspirowany tym komentarzem przez Jana Dvoraka .

Sparr
źródło
1
Program o zerowej długości działałby w kilku językach. Czy to się liczy jako standardowa luka ?
Cyfrowa trauma
2
Chodźmy z ... tak.
Sparr
@DigitalTrauma: Dodano do listy.
Dennis
1
@ user23013 dobre pytanie. Nie rozważałem nowych linii. Myślę, że jeśli je uwzględnisz, zaakceptowałbym odpowiedź, która wypisuje je dosłownie, więc w pliku byłaby gdzieś jedna podwójna nowa linia.
Sparr

Odpowiedzi:

7

CJam, 14 bajtów

{S2N`/}`{S2N}/

Wypróbuj tutaj .

Dane wyjściowe są w kolejności, w jakiej się najpierw pojawiają:

{ 2
S 2
2 2
N 2
` 2
/ 2
} 2

Po prostu dołącza się <SP>2<NL>do każdej postaci w {S2N`/}.

jimmy23013
źródło
18

/// , 12 bajtów

  4
4 4

 4

Ogromne podziękowania należą się @ @ user23013, który zasugerował to ulepszenie w stosunku do mojego kodu CJam, przechytrzając swoją własną, najlepiej ocenianą odpowiedź.

Postacie są sortowane według wyglądu. Ten kod działa w dowolnym języku, który po prostu drukuje własny kod źródłowy w danych okolicznościach (PHP, ASP itp.).


CJam, 20 bajtów

''S5N'5S5N'NS5N'SS5N

W tym podejściu nie ma wbudowanego liczenia znaków.

Wypróbuj online w interpretatorze CJam .

Jak to działa

''S5N e# Push a single quote, a space, the integer 5 and a linefeed.
'5S5N e# Push the character 5, a space, the integer 5 and a linefeed.
'NS5N e# Push the character N, a space, the integer 5 and a linefeed.
'SS5N e# Push the character S, a space, the integer 5 and a linefeed.
Dennis
źródło
5
+1 za niestosowanie standardowych technik quine.
Martin Ender
Naprawdę mam nadzieję, że ten pozostanie związany na czele. Z przyjemnością dam mu znak zaznaczenia nad jego odpowiednikiem w quine.
Sparr
Teraz nowe linie są dozwolone. Myślę, że ta odpowiedź powinna być lepiej zintegrowana z twoją.
jimmy23013
@ user23013: To nawet krótsze niż odpowiedź na CJam. Dzięki!
Dennis
9

CJam, 20 bajtów

{`"_~"+$e`{)S@N}%}_~

Jak to działa

Najpierw zaczynamy od jednego ze standardowych quine w CJam

{`"_~"}_~

który wypycha pierwszy blok na stos, kopiuje go i uruchamia kopię, co powoduje, że w końcu drukuje sam kod źródłowy.

Następnie dodajemy logikę do obliczenia liczby znaków z kodu źródłowego:

{`"_~"+                         e# At this point, we have the full source code with us
       $e`                      e# Sort to get similar characters together and run RLE to
                                e# get count of each character as [count char] array
          {    }%               e# Run each array element through this loop
           )S@N                 e# Pop the character, put a space, rotate the count after
                                e# space and then finally put a newline after the trio
                 }_~            e# Second half of the standard quine explained above

Wypróbuj online tutaj

Optymalizator
źródło
4

Python 3.5.0b1 , 107 73 bajtów

s="t='s=%r;exec(s)'%s;[print(c,t.count(c))for c in sorted({*t})]";exec(s)

Zamiast zwykłego quinu zastępującego ciąg znaków, który wymaga napisania wszystkiego dwa razy, oto execquine.

Sp3000
źródło
3

Mathematica, 101 bajtów

Apply[Print[#1, " ", #2] &, Tally[Characters[StringJoin[ToString[#0, InputForm], "[];"]]], {1}] & [];

Niestety, nie mogę użyć dowolnego z normalnych sztuczek golfowych jak usuwanie białych znaków, <>dla StringJoin, #zamiast #1, @dla wywołań funkcji przedrostek lub @@@zamiast Apply[...,{1}], ponieważ ToString[...,InputForm]uważa, że ma ładnego drukowania wszystkiego ...

Spowoduje to wydrukowanie znaków w kolejności, w jakiej występują po raz pierwszy w kodzie. Jeśli mogę założyć, że nie działa to w środowisku REPL (co jest dość niezwykłe w przypadku Mathematica), mogę zapisać dwa bajty, pomijając dwa ;.

Martin Ender
źródło
InputFormjest denerwujący ... OutputFormjest lepszy, ale nie cytuje ciągów znaków.
LegionMammal978
2

Haskell, 178 bajtów

main=putStr(unlines[s:' ':show t|(s,t)<-zip" \"'(),-0123456789:<=S[\\]aehilmnoprstuwz|"[3,3,3,3,3,41,4,1,6,19,12,5,5,2,2,2,2,3,2,2,2,3,3,3,2,2,2,4,2,2,4,2,3,2,5,5,3,2,2,2]])--178

Nic fajnego. Wszystkie znaki programu znajdują się na liście dosłownej (String). Podobnie jak częstotliwości. Spakuj obie listy i wydrukuj. Wynik:

  3
" 3
' 3
( 3
) 3
, 41
- 4
0 1
1 6
2 19
3 12
4 5
5 5
6 2
7 2
8 2
9 2
: 3
< 2
= 2
S 2
[ 3
\ 3
] 3
a 2
e 2
h 2
i 4
l 2
m 2
n 4
o 2
p 3
r 2
s 5
t 5
u 3
w 2
z 2
| 2 
nimi
źródło
1

Dart - 214 127

Wersja bezpośrednia:

main(){print("  22\n\" 3\n( 3\n) 3\n1 3\n2 15\n3 8\n4 1\n5 2\n8 2\n; 2\n\\ 23\na 2\ni 3\nm 2\nn 23\np 2\nr 2\nt 2\n{ 2\n} 2");}

„4” jest po prostu błahostką, by sumować liczby. Zobacz / uruchom DartPad .

Oryginał: Standardowa taktyka quine, a nazwy funkcji Dart są trochę za długie, by grać w golfa dobrze.

main({m,v,q:r'''main({m,v,q:r''}'')''{m={};for(v in q.split(''))m[v]=m[v]==null?2:m[v]+2;m.forEach((k,v)=>print("$k $v"));}'''}){m={};for(v in q.split(''))m[v]=m[v]==null?2:m[v]+2;m.forEach((k,v)=>print("$k $v"));}

Zobacz / uruchom go na DartPad .

lrn
źródło
0

Haskell , 146 bajtów

main=mapM putStrLn[a:" "++show s|a<-[' '..],s<-[sum[2|b<-show"main=mapM putStrLn[a: ++show s|a<-[' '..],s<-[sum[2|b<-show,a==b]],s>0]",a==b]],s>0]

Wypróbuj online!

Wynik:

  8
" 4
' 4
+ 4
, 6
- 6
. 4
0 2
2 2
: 2
< 6
= 6
> 2
L 2
M 2
S 2
[ 8
] 8
a 10
b 4
h 4
i 2
m 6
n 4
o 4
p 4
r 2
s 12
t 4
u 4
w 4
| 4

(Plus dodatkowa nowa linia)

Wyjaśnienie:

Kod jest

main=mapM putStrLn[a:" "++show s|a<-[' '..],s<-[sum[2|b<-show"<code>",a==b]],s>0]

gdzie "<code>"jest ciąg kodu programu bez ".

aprzechodzi przez znaki ascii zaczynając od spacji. sum[2|b<-show"<code>",a==b]liczy, jak często znak pojawia się w ciągu, a każde wystąpienie jest liczone dwukrotnie. a:" "++show sbuduje ciąg bieżącego znaku, spację i liczbę znaków. WreszciemapM putStrLn drukuje każdy ciąg na liście z końcowym znakiem nowej linii.

Najtrudniejszą częścią było zliczenie "trafności. Użycie just b<-"<code>"spowoduje zliczenie zerowych cudzysłowów, ponieważ nie ma żadnych w ciągu. Użycie show"<code>"dodaje a "do przodu i końca łańcucha, co daje liczbę czterech. Musiałem więc wstawić dwa dodatkowe znaki cudzysłowu w kodzie, więc zamiast (krótszego) a:' ':show sużyłem a:" "++show s.

Laikoni
źródło