Chaîne de caractères alphanumériques dans une liste triée de plages séparées par des virgules

12

Étant donné une chaîne de caractères alphanumériques non triés, par exemple

ABC321STPpJqZZr0

afficher une liste de plages de caractères séparées par ",", triées par valeur ASCII, en ignorant la casse et en supprimant les doublons ( c'est-à-dire en ne sortant que des caractères majuscules et numériques), par exemple

0-3, A-C, J, P-T, Z

Règles

  • La durée de votre programme est votre score de base, comme d'habitude.
  • Vous devez initialiser (code dur) l'exemple ci-dessus dans votre programme, mais vous pouvez actualiser la longueur de cet exemple à partir de la longueur de votre programme, par exemple pour char* s="ABC321STPpJqZZr0";vous pouvez actualiser 16 caractères, les 11 autres caractères comptant pour la longueur de votre programme.

Bonus (+50 primes)

  • Comme c'était un vrai problème rencontré par mon collègue aujourd'hui, ayant besoin d'être écrit en Tcl 8.0.5 (une version ancienne, manquant de la plupart des dernières intégrations Tcl), je vais attribuer 50 points à celui qui écrit le Tcl 8.0 le plus court .5 solution, s'il y a au moins 2 soumissions valides dans Tcl 8.0.5.
Andrew Cheong
la source
@FezVrasta - J'ai intentionnellement écrit ", "pour inclure l'espace, mais nous pouvons laisser votre modification et laisser ce commentaire servir d'indication.
Andrew Cheong
Pourquoi inclure intentionnellement GolfScript? Pourquoi ne pas autoriser d'autres langues, comme le Befunge?
Justin
Nous pouvons dire que tout va bien. Je ne pourrai pas vérifier la plupart d'entre eux très facilement.
Andrew Cheong
C'est donc une balise Code-Golf alors?
VisioN
1
@Chron - Bonne prise. AB dans mon cas, mais puisqu'il y a déjà eu de nombreuses soumissions, admettons les deux façons.
Andrew Cheong

Réponses:

5

Rubis, 87-16 = 71

EDIT: J'ai dû ajouter quelques caractères pour que les plages de deux caractères s'affichent correctement. Utiliser également ?[au lieu de ?Zpour corriger un bogue avec des plages se terminant par Z.

$><<[*?0..?[].join.gsub(/[^ABC321STPpJqZZr0]/i,$/).gsub(/\B.+\B/,?-).scan(/.-.|./)*', '

Vous pouvez voir la course d'Ideone ici .

Paul Prestidge
la source
+1 Pour une doublure. Utilisation très intelligente de diverses méthodes; C'est vraiment génial.
daniero
1
Notez qu'il gsub(/[]/i)est plus court que tr(''.upcase)2 caractères. De plus, scan(/.+/)-> splitenregistre 5, et $><<au lieu d' putsun autre.
Howard
@Howard Excellentes suggestions, merci!
Paul Prestidge
2

Julia, 131

julia> l=sort(unique(uppercase("ABC321STPpJqZZr0")))
julia> prod([!(c+1 in l)?"$c"*(c==l[end]?"":", "):!(c-1 in l)?"$c":(c+1 in l)&&!(c+2 in l)?"-":"" for c in l])

"0-3, A-C, J, P-T, Z"

Non pris en charge par Ideone.com, et sera probablement écrasé de toute façon.

gggg
la source
1
Merci quand même! La contrainte Ideone.com était uniquement pour que je puisse la tester, mais je suppose que je peux faire confiance à l'intégrité des golfeurs et supprimer cette règle. +1, de toute façon.
Andrew Cheong
2

C #, 221 octets

class P{
    static void Main(){
        var s="ABC321STPpJqZZr0";
        var l=new int[257];
        foreach(int c in s.ToUpper())
            l[c]=1;
        var r="";
        for(int i=0;i<255;){
            if(l[i++]-l[i]<0)
                r+=", "+(char)i;
            else if(l[i+1]-l[i]<0)
                r+="-"+(char)i;
        }
        System.Console.Write(r.Substring(2));
    }
}
Hand-E-Food
la source
2

C, 193

char*s="ABC321STPpJqZZr0";
int c[99];memset(c,0,396);while(*s){++c[toupper(*s++)];}for(int i=0,f=1,r=0;
i<=99;++i){if(!r&&c[i])r=i;if(r&&!c[i]){if(!f)printf(", ");putchar(r);
if(i-r>1)printf("-%c",i-1);r=f=0;}}
warrenm
la source
Pouvez-vous ajouter une petite explication?
Justin
Itérer sur la chaîne, accumulant un nombre d'instances de chaque caractère alphanumérique. Ensuite, parcourez tous les caractères alphanumériques dans l'ordre alphabétique, en écrivant le début de chaque plage compacte et, le cas échéant, un tiret suivi de la fin de la plage. Si ce n'est pas la première plage qui a été écrite, ajoutez le séparateur virgule-espace. Le code doit être intégré dans une fonction main () avec des en-têtes appropriés (stdio, string, ctypes) inclus, donc j'ai un peu triché là-bas.
warrenm
2

GolfScript 57 54 52

 'ABC321STPpJqZZr0'
 {.95>32*-}%.|:x..{(}%&-x..{)}%&-+$2/{.|'-'*}%', '*

Essayez-le ici .

Le code met d'abord tout en majuscule:

{.95>32*-}%

Obtient ensuite des caractères uniques et l'enregistre dans une variable:

.|:x

Ensuite, nous obtenons les caractères dont les prédécesseurs directs ne sont pas dans la chaîne (de sorte qu'ils sont la partie de début d'une plage):

..{)}%&-x

Nous obtenons également les extrémités des plages avec x..{)}%&-.

Maintenant, formez les plages en concaténant les listes, en les triant et en les divisant en groupes de 2:

+$2/

Le reste n'est que du formatage, en utilisant *comme jointure de chaîne.

Ben Reich
la source
1
Dans la sortie, les plages doivent être séparées par ',' et pas seulement ','
Paul Prestidge
1
Aussi .95>{32-}{}if-> .95>32*-enregistre 5 caractères.
Howard
@Howard Great! Je savais que cette partie n'était pas optimale.
Ben Reich
1
@Chron Correction du problème d'espace!
Ben Reich
2

Q, 94

{","sv(,/){{"-"sv(?) -1 1#\:x}'[cut[;a]0,1_(&)1<(-':)"i"$'a:asc upper[x]inter y]}[x]'[.Q`n`A]}
tmartin
la source
1

Python 2.x, 304-16 = 288

Cela peut sûrement être joué plus loin, tous les commentaires sont les bienvenus!

e=[""]*11;f=[""]*27
for c in"ABC321STPpJqZZr0".lower():e["0123456789".find(c)]=f["abcdefghijklmnopqrstuvwxyz".find(c)]=c
e[-1]=f[-1]=""
def h(j):
 g=[];k=l=i=0
 for e in j:
  if e:
   if not l:k=i;l=1
  elif l:l=g.append((k,i-1))
  i+=1
 print", ".join([j[m],j[m]+"-"+j[n]][n-m>1]for m,n in g)
h(e);h(f)
ChristopheD
la source
1

Rebol (218 - 16 = 202)

m: s: sort uppercase unique"ABC321STPpJqZZr0"i: :to-integer f: does[either 1 = length? x: copy/part m s[x][rejoin[x/1"-"last x]]]while[not tail? s: next s][if(1 + i pick back s 1)!=(i s/1)[prin join f", "m: s]]print f

Version non minifiée:

m: s: sort uppercase unique "ABC321STPpJqZZr0"
i: :to-integer

f: does [
    either 1 = length? x: copy/part m s [x] [rejoin [x/1 "-" last x]]
]

while [not tail? s: next s][
    if (1 + i pick back s 1) != (i s/1) [
        prin join f ", "
        m: s
    ]
]

print f
draegtun
la source
1

q [116 caractères]

{.a:();{m:6h$x;.a:.a,$[m[1]=1+m[0];45;m[0],44,m 1];1_x}/[x:asc distinct upper x];p where differ 6h$p:-3_10h$x[0],.a}

Usage

{.a:();{m:6h$x;.a:.a,$[m[1]=1+m[0];45;m[0],44,m 1];1_x}/[x:asc distinct upper x];p where differ 6h$p:-3_10h$x[0],.a}"ABC321STPpJqZZr0"
Production
"0-3,A-C,J,P-T,Z"

Il est possible d'enregistrer des caractères, je vais essayer une autre méthode et la publier.

nyi
la source
0

Tcl 8.0.5, 344 (360 octets)

set a ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
set s string
set x [join [lsort [split [$s toupper ABC321STPpJqZZr0] ""]] ""]
regsub -all (.)\\1+ $x \\1 x
set i 36
while {[incr i -1]} {set j -1
while {$i+[incr j]<36} {set y [$s range $a $j [expr $i+$j]]
regsub $y $x [$s index $y 0]-[$s index $y end],\  x}}
while {[regsub -all {(\w)(\w)} $x {\1, \2} x]} {}
puts $x

Tcl 8.0.5, 340 (356 octets)

Bricoler avec la renamecommande a donné quelques astuces amusantes! Je les ai documentés dans un autre fil .

rename rename &
& set =
& regsub R
& string S
& while W
= a ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
= x [lsort [split [S toupper ABC321STPpJqZZr0] ""]]
R -all {(.) \1+| } $x \\1 x
= i 36
W {[incr i -1]} {= j -1
W {$i+[incr j]<36} {= y [S range $a $j [expr $i+$j]]
R $y $x [S index $y 0]-[S index $y end],\  x}}
W {[R -all {(\w)(\w)} $x {\1, \2} x]} {}
puts $x

Tcl 8.0.5, 332 (348 octets) [Instable - dépend de $ PATH]

info script ""
set tcl_interactive 1
set a ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
set x [lso [sp [st toupper ABC321STPpJqZZr0] ""]]
regs -all {(.) \1+| } $x \\1 x
set i 36
wh {[inc i -1]} {set j -1
wh {$i+[inc j]<36} {set y [st range $a $j [exp $i+$j]]
regs $y $x [st index $y 0]-[st index $y end],\  x}}
wh {[regs {(\w)(\w)} $x {\1, \2} x]} {}
pu $x

Crédit @JohannesKuhn pour l'affaire interactive .

Andrew Cheong
la source
1
Parfois, vous pouvez enregistrer des octets en les remplaçant whilepar des timeconstructions. codegolf.stackexchange.com/a/126236/29325
sergiol