Nombre de caractères dans le code source

12

Écrivez un programme qui génère une liste du nombre d'occurrences de chaque caractère unique dans son code source.

Par exemple, ce programme hypothétique {Source_Print_1};devrait produire cette sortie:

; 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

Le formatage doit correspondre à cet exemple. Aucun espace étranger n'est autorisé, à l'exception d'une nouvelle ligne finale facultative.

Votre programme peut ne pas lire son propre code source à partir du fichier source.

Les caractères répertoriés doivent être dans l'un des deux ordres. Soit l'ordre des valeurs de caractères dans le codage de caractères utilisé par votre langue (probablement ASCII), soit l'ordre dans lequel les caractères apparaissent dans votre source.

Cette question s'inspire de ce commentaire de Jan Dvorak .

Sparr
la source
3
Similaire: codegolf.stackexchange.com/questions/34431/…
Calvin's Hobbies
1
Un programme de longueur nulle fonctionnerait dans plusieurs langues. Est-ce que cela compte comme une échappatoire standard ?
Digital Trauma
2
Allons-y avec ... oui.
Sparr
@DigitalTrauma: ajouté à la liste.
Dennis
1
@ user23013 bonne question. Je n'ai pas envisagé de nouvelles lignes. Je suppose que si vous les incluez, j'accepterais une réponse qui les imprime littéralement, donc il y aurait un double retour à la ligne quelque part dans le fichier.
Sparr

Réponses:

7

CJam, 14 octets

{S2N`/}`{S2N}/

Essayez-le ici .

La sortie est dans l'ordre où elle apparaît en premier:

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

Il s'ajoute simplement <SP>2<NL>à chaque personnage dans {S2N`/}.

jimmy23013
la source
18

/// , 12 octets

  4
4 4

 4

Un grand merci à @ user23013, qui a suggéré cette amélioration par rapport à mon code CJam, devançant sa propre réponse avec le score le plus élevé dans le processus.

Les personnages sont triés par apparence. Ce code fonctionne dans n'importe quel langage qui imprime simplement son propre code source dans les circonstances données (PHP, ASP, etc.).


CJam, 20 octets

''S5N'5S5N'NS5N'SS5N

Cette approche n'utilise aucun comptage de caractères intégré.

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

''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
la source
5
+1 pour ne pas utiliser les techniques de quine standard.
Martin Ender
J'espère vraiment que celui-ci restera à égalité en tête. Je vais volontiers lui donner la coche sur son homologue quine.
Sparr
Désormais, les retours à la ligne sont autorisés. Je pense que cette réponse devrait être mieux fusionnée avec la vôtre.
jimmy23013
@ user23013: C'est encore plus court que votre réponse CJam. Merci!
Dennis
9

CJam, 20 octets

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

Comment ça fonctionne

Nous commençons d'abord avec l'un des quine standard dans CJam

{`"_~"}_~

qui pousse le premier bloc sur la pile, le copie et exécute la copie, ce qui lui fait finalement imprimer le code source lui-même.

Ensuite, nous ajoutons la logique pour calculer le nombre de caractères à partir du code source:

{`"_~"+                         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

Essayez-le en ligne ici

Optimiseur
la source
4

Python 3.5.0b1 , 107 73 octets

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

Plutôt que le quine de remplacement de chaîne habituel, qui nécessite de tout écrire deux fois, voici un execquine.

Sp3000
la source
3

Mathematica, 101 octets

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

Malheureusement, je ne peux utiliser aucune des astuces de golf normales comme la suppression des espaces blancs, <>car StringJoin, #au lieu de #1, @pour les appels de fonction de préfixe ou à la @@@place de Apply[...,{1}], car ToString[...,InputForm]pense qu'il doit tout imprimer ...

Cela imprime les caractères dans l'ordre où ils apparaissent pour la première fois dans le code. Si je peux supposer que cela ne fonctionne pas dans un environnement REPL (ce qui est plutôt inhabituel pour Mathematica), je peux économiser deux octets en omettant les deux ;.

Martin Ender
la source
InputFormest ennuyeux ... OutputFormc'est mieux mais il ne cite pas de chaînes.
LegionMammal978
2

Haskell, 178 octets

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

Rien d'extraordinaire. Tous les caractères du programme sont dans une liste littérale (chaîne). Les fréquences aussi. Compressez les deux listes et imprimez. Production:

  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
la source
1

Fléchette - 214 127

Une version directe:

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

Le "4" n'est qu'un facteur pour jouer les chiffres. Voir / exécuter sur DartPad .

Original: tactique standard et les noms de fonction de Dart sont un peu trop longs pour un bon golf.

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

Voir / exécuter sur DartPad .

lrn
la source
0

Haskell , 146 octets

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]

Essayez-le en ligne!

Production:

  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 une nouvelle ligne supplémentaire)

Explication:

Le code est

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

"<code>"est une chaîne du code du programme sans le ".

apasse par les caractères ascii en commençant par un espace. sum[2|b<-show"<code>",a==b]compte la fréquence à laquelle le caractère apparaît dans la chaîne, chaque occurrence étant comptée deux fois. a:" "++show sconstruit une chaîne du caractère actuel, un espace et le nombre de caractères. mapM putStrLnImprime enfin chaque chaîne de la liste avec une nouvelle ligne de fin.

La partie la plus difficile était d'obtenir le décompte des "bons. Utiliser juste b<-"<code>"compterait zéro guillemets car il n'y en a pas dans la chaîne. L'utilisation show"<code>"ajoute un "à l'avant et à la fin de la chaîne, ce qui donne un nombre de quatre. J'ai donc dû mettre deux guillemets supplémentaires dans le code, donc au lieu du (plus court) que a:' ':show sj'ai utilisé a:" "++show s.

Laikoni
la source