String karakter alfanumerik ke daftar rentang rentang yang dipisahkan koma

12

Diberikan serangkaian karakter alfanumerik yang tidak disortir, mis

ABC321STPpJqZZr0

output "," - daftar rentang karakter yang dipisahkan, diurutkan berdasarkan nilai ASCII, mengabaikan case dan menghapus duplikat ( yaitu hanya mengeluarkan huruf besar dan karakter numerik), misalnya

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

Aturan

  • Panjang program Anda adalah skor dasar Anda, seperti biasa.
  • Anda harus menginisialisasi (hardcode) contoh di atas dalam program Anda, tetapi Anda dapat mendiskon panjang contoh itu dari panjang program Anda, misalnya untuk char* s="ABC321STPpJqZZr0";Anda dapat mendiskon 16 karakter, 11 karakter lainnya dihitung terhadap panjang program Anda.

Bonus (+50 hadiah)

  • Karena ini adalah masalah nyata yang dihadapi oleh rekan kerja saya hari ini, perlu ditulis dalam Tcl 8.0.5 (versi kuno, tidak memiliki banyak built-in Tcl terbaru), saya akan memberikan 50 poin kepada siapa pun yang menulis Tcl 8.0 terpendek .5 solusi, jika setidaknya ada 2 kiriman yang valid di Tcl 8.0.5.
Andrew Cheong
sumber
@FezVrasta - Saya sengaja menulis ", "untuk memasukkan spasi, tetapi kami dapat meninggalkan suntingan Anda dan membiarkan komentar ini berfungsi sebagai indikasi itu.
Andrew Cheong
Mengapa dengan sengaja menyertakan GolfScript? Mengapa tidak mengizinkan bahasa lain, seperti Befunge?
Justin
Bisa dibilang semuanya adalah permainan yang adil. Saya hanya tidak akan dapat memeriksa sebagian besar dari mereka dengan sangat mudah.
Andrew Cheong
Jadi, apakah itu tag Code-Golf?
VisioN
1
@ Chron - Tangkapan yang bagus. AB dalam kasus saya tetapi karena sudah ada banyak pengajuan, mari kita izinkan kedua cara.
Andrew Cheong

Jawaban:

5

Ruby, 87-16 = 71

EDIT: Harus menambahkan beberapa karakter sehingga rentang dua karakter ditampilkan dengan benar. Juga menggunakan ?[alih-alih ?Zmemperbaiki bug dengan rentang yang berakhiran Z.

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

Anda dapat melihat Ideone dijalankan di sini .

Paul Prestidge
sumber
+1 Untuk satu-liner. Penggunaan berbagai metode yang sangat pintar; Ini sangat brilian.
daniero
1
Perhatikan bahwa gsub(/[]/i)lebih pendek dari tr(''.upcase)2 karakter. Selain itu, scan(/.+/)-> splitmenghemat 5, dan $><<bukannya yang putslain.
Howard
@Howard Saran yang bagus, terima kasih!
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"

Tidak didukung oleh Ideone.com, dan mungkin akan hancur juga.

gggg
sumber
1
Bagaimanapun, terima kasih! Kendala Ideone.com hanya supaya saya bisa mengujinya, tetapi saya rasa saya bisa mempercayai integritas pegolf dan menghapus aturan itu. +1, pokoknya.
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));
    }
}
Makanan Tangan
sumber
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
sumber
Bisakah Anda menambahkan penjelasan kecil?
Justin
Iterate di atas string, mengumpulkan hitungan instance dari setiap karakter alfanumerik. Kemudian, ulangi semua karakter alfanumerik dalam urutan alfabet, tuliskan awal setiap rentang kompak dan, jika perlu, tanda hubung diikuti oleh akhir rentang. Jika ini bukan rentang pertama yang telah ditulis, tambahkan pemisah koma-ruang. Kode harus disematkan dalam fungsi utama () dengan header yang sesuai (stdio, string, ctypes) dimasukkan, jadi saya agak curang di sana.
warrenm
2

GolfScript 57 54 52

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

Coba di sini .

Kode pertama kali mengkapitalisasi segalanya:

{.95>32*-}%

Kemudian dapatkan karakter unik dan simpan dalam variabel:

.|:x

Lalu, kita mendapatkan karakter yang pendahulunya langsung tidak ada dalam string (sehingga mereka adalah bagian awal dari rentang):

..{)}%&-x

Kami juga mendapatkan ujung rentang dengan x..{)}%&-.

Sekarang benar-benar membentuk rentang dengan menggabungkan daftar, menyortir, dan membelah menjadi 2 kelompok:

+$2/

Sisanya hanya memformat, menggunakan *sebagai string bergabung.

Ben Reich
sumber
1
Dalam output, rentang perlu dipisahkan oleh ',' dan bukan hanya ','
Paul Prestidge
1
Juga .95>{32-}{}if-> .95>32*-menyimpan 5 karakter.
Howard
@Howard Hebat! Saya tahu bagian itu tidak optimal.
Ben Reich
1
@ Chron Memperbaiki masalah ruang!
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
sumber
1

Python 2.x, 304 - 16 = 288

Ini pasti bisa bermain golf lebih lanjut, semua komentar diterima!

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
sumber
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

Versi non-minified:

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
sumber
1

q [116 karakter]

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

Pemakaian

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

Ada cakupan menyimpan karakter, saya akan mencoba beberapa metode lain dan mempostingnya.

nyi
sumber
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 bytes)

Bermain-main dengan renameperintah menghasilkan beberapa trik menyenangkan! Saya sudah mendokumentasikannya di utas lain .

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) [Tidak stabil — tergantung pada $ 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

Kredit ke @JohannesKuhn untuk trik interaktif .

Andrew Cheong
sumber
1
Kadang-kadang Anda dapat menyimpan byte menggantikan whiledengan timekonstruk. codegolf.stackexchange.com/a/126236/29325
sergiol