Stringa di caratteri alfanumerici in un elenco ordinato di intervalli separati da virgola


12

Data una stringa di caratteri alfanumerici non ordinati, ad es

ABC321STPpJqZZr0

emette un elenco "," di intervalli di caratteri separati, ordinati per valore ASCII, ignorando maiuscole e minuscole e rimuovendo duplicati ( es. solo caratteri maiuscoli e numerici), ad es.

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

Regole

  • La durata del programma è il punteggio di base, come al solito.
  • È necessario inizializzare (hardcode) l'esempio sopra all'interno del programma, ma è possibile scartare la lunghezza di quell'esempio dalla lunghezza del programma, ad esempio perché char* s="ABC321STPpJqZZr0";si possono scartare 16 caratteri, mentre gli altri 11 caratteri contano per la lunghezza del programma.

Bonus (+50 taglia)

  • Poiché questo è stato un vero problema riscontrato dal mio collega oggi, che deve essere scritto in Tcl 8.0.5 (una versione antica, privo di molti degli ultimi incorporati Tcl), assegnerò 50 punti a chiunque scriva il Tcl 8.0 più corto .5 soluzione, se ci sono almeno 2 invii validi in Tcl 8.0.5.

@FezVrasta - Ho scritto intenzionalmente ", "per includere lo spazio, ma possiamo lasciare la tua modifica e lasciare che questo commento serva da tale indicazione.
Andrew Cheong,

Perché includere intenzionalmente GolfScript? Perché non consentire altre lingue, come Befunge?
Giustino,

Possiamo dire che tutto è giusto. Non sarò in grado di controllarli molto facilmente.
Andrew Cheong,

Quindi è un tag Code-Golf allora?
VisioN,

1
@Chron - Buona cattura. AB nel mio caso, ma poiché ci sono già state molte osservazioni, consentiamo entrambi i modi.
Andrew Cheong,

Risposte:


5

Rubino, 87-16 = 71

EDIT: ho dovuto aggiungere alcuni caratteri in modo che gli intervalli di due caratteri fossero visualizzati correttamente. Anche usando ?[invece di ?Zcorreggere un bug con intervalli che terminano in Z.

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

Puoi vedere l'Ideone correre qui .


+1 per un liner. Uso molto intelligente di vari metodi; Questo è davvero geniale.
daniero,

1
Si noti che gsub(/[]/i)è più breve di tr(''.upcase)2 caratteri. Inoltre, scan(/.+/)-> splitsalva 5 e $><<invece di putsun altro.
Howard,

@Howard Ottimi suggerimenti, grazie!
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 supportato da Ideone.com, e probabilmente sarà comunque schiacciato.


1
Grazie comunque! Il vincolo di Ideone.com era solo per poterlo testare ma suppongo di potermi fidare dell'integrità dei giocatori di golf e di rimuovere quella regola. +1, comunque.
Andrew Cheong,

2

C #, 221 byte

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

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

Puoi aggiungere una piccola spiegazione?
Giustino,

Scorrere sulla stringa, accumulando un numero di istanze di ciascun carattere alfanumerico. Quindi, scorrere su tutti i caratteri alfanumerici in ordine alfabetico, scrivendo l'inizio di ciascun intervallo compatto e, se appropriato, un trattino seguito dalla fine dell'intervallo. Se questo non è il primo intervallo che è stato scritto, aggiungi il separatore spazio-virgola. Il codice deve essere incorporato in una funzione main () con le intestazioni appropriate (stdio, string, ctypes) incluse, quindi ho barato lì.
warrenm,

2

GolfScript 57 54 52

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

Provalo qui .

Il codice in primo luogo capitalizza tutto:

{.95>32*-}%

Quindi ottiene caratteri unici e lo salva in una variabile:

.|:x

Quindi, otteniamo i personaggi i cui predecessori diretti non sono nella stringa (in modo che siano la parte iniziale di un intervallo):

..{)}%&-x

Allo stesso modo otteniamo le estremità degli intervalli con x..{)}%&-.

Ora forma gli intervalli concatenando gli elenchi, ordinando e suddividendo in gruppi di 2:

+$2/

Il resto è solo formattazione, usando *come join stringa.


1
Nell'output, gli intervalli devono essere separati da ',' e non solo ','
Paul Prestidge,

1
Inoltre .95>{32-}{}if-> .95>32*-salva 5 caratteri.
Howard,

@Howard Ottimo! Sapevo che quella parte non era ottimale.
Ben Reich,

1
@Chron Risolto il problema di spazio!
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]}

1

Python 2.x, 304-16 = 288

Questo può sicuramente essere ulteriormente risolto, tutti i commenti sono benvenuti!

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)

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

Versione non minimizzata:

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

1

q [116 caratteri]

{.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}

uso

{.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"
Produzione
"0-3,A-C,J,P-T,Z"

C'è una possibilità di salvare i caratteri, proverò qualche altro metodo e pubblicherò.


0

Tcl 8.0.5, 344 (360 byte)

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

Armeggiare con il renamecomando ha prodotto alcuni trucchi divertenti! Li ho documentati in un altro thread .

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 byte) [Instabile — dipende da $ PERCORSO]

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

Ringraziamo @JohannesKuhn per il trucco interattivo .


1
A volte è possibile salvare i byte sostituendoli whilecon timecostrutti. codegolf.stackexchange.com/a/126236/29325
sergiol
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.