Değerler listesinden aralıkları belirleme


18

Benzersiz, pozitif tamsayıların sıralanmamış bir listesi verildiğinde, sıralı tamsayıların mümkün olan en uzun aralıklarının en kısa listesini çıktılar.

GİRİŞ

  • Benzersiz, pozitif tam sayıların sıralanmamış bir listesi
    • Örneğin 9 13 3 11 8 4 10 15
  • Giriş aşağıdakilerden herhangi birinden alınabilir:
    • stdin
    • komut satırı bağımsız değişkenleri
    • işlev argümanları

ÇIKTI

  • Stdout'a veya dilinize en yakın benzer çıktıya bir satırda yazdırılmış aralıkların veya ayrı ayrı değerlerin listesi.
    • İki veya daha fazla sıralı tamsayı varsa (listedeki konuma göre değil, değere göre sıralı), bunlar - - ör. 8-11
    • Diğer tüm tamsayılar başka bir gösterim olmadan yazdırılır
    • Tek bir boşluk çıktıyı sınırlar
  • Giriş mevcut olmayan sayılar çıkış olmamalıdır, örneğin 3 5 6kısaltılmış edilemez 3-6, çünkü 4mevcut değildir

ÖRNEKLER

Başarılı:

 IN> 9 13 3 11 8 4 10 15 6
OUT> 3-4 6 8-11 13 15

 IN> 11 10 6 9 13 8 3 4 15
OUT> 3-4 6 8-11 13 15

 IN> 5 8 3 2 6 4 7 1
OUT> 1-8

 IN> 5 3 7 1 9
OUT> 1 3 5 7 9

Yanlış:

 IN> 9 13 3 11 8 4 10 15
OUT> 3-15

Aralık, girişte olmayan değerler içeriyor

 IN> 9 13 3 11 8 4 10 15
OUT> 3 4 8 9 10 11 13 15

Tüm sıralı değerler bir aralık olarak temsil edilmelidir

 IN> 9 13 3 11 8 4 10 15
OUT> 3-4 8-9 10-11 13 15

Bölünmüş aralık 8-9ve 10-11olmalıdır8-11

 IN> 9 13 3 11 8 4 10 15
OUT> 8-9 13 10-11 3-4 15

Çıktı doğru şekilde sipariş edilmedi

KURALLAR

PUANLAMA

  • En az bayt kazanır

1
İlk cümle gerçekten kafa karıştırıcı. "Sıralı tamsayıların mümkün olan en uzun aralıklarının en kısa listesini çıktılayın" demenizi tavsiye ederim. Aksi takdirde, güzel bir meydan okuma!
Nathan Merrill

2
Daha önce bu sorunu yaşadığımıza eminim, ancak doğru arama terimlerini bulamıyorum. Hatırlayan var mı?
xnor

4
@CoreyOgburn Bu arada, PPCG'de yayın göndermenize ne neden oldu? Neden bir sürü yeni kullanıcı geldiğimizi anlamaya çalışıyoruz.
xnor

2
@xnor Aylardır siteye göz kulak oldum. Kullandığım dillerden hiçbiri genellikle cevaplar için iyi aday değildir ve bugüne kadar gönderecek bir sorum olmadı.
Corey Ogburn

1
@xnor: Maltysen'in ödev listesine bir benziyor ama aynı değil.
Alex

Yanıtlar:


9

Python 2, 123120 bayt

N=sorted(map(int,raw_input().split(' ')));print(''.join((''if n+1in N else'-'+`n`)if n-1in N else' '+`n`for n in N)[1:])

Giriş bir işlev bağımsız değişkeni olarak bir liste olabilirse (koşullu için teşekkürler mbomb007 ve xnor)

93 90 81 bayt

def f(N):print''.join((' '+`n`,`-n`*-~-(n+1in N))[n-1in N]for n in sorted(N))[1:]

(Önde gelen boşluk kabul edilebilirse 77 bayt - finali düşür [1:])


Değişebilirsin str(n)için `n`Python 2. geçerseniz, birkaç byte kaydetmek
mbomb007

Ayrıca kullanmak yerine girdi olarak bir listesini alır bir işlev oluşturabilir raw_input()ve değiştirebilirsiniz '-'+`n`için `-n`. Ve şimdi Python 2 kullandığınız için, parantezleri print.
mbomb007

Dizeyi parça parça oluşturmak zekidir. Bayt tasarrufu için, liste seçimi veya aritmetik gibi koşulların yapılması genellikle daha kısadır def f(N):print''.join([' '+`n`,`-n`*(n+1 not in N)][n-1 in N]for n in sorted(N))[1:](bu da daha fazla golf yapılabilir).
xnor

Bunun set(N)yerine kullanabilirsiniz sorted(N); bu, cPython kullanırken doğrudan en küçükten en düşüke doğru yinelenir, ancak tüm uygulamalar için çalışacağı garanti edilmez, bu nedenle bunun geçerli olup olmadığı hakkında bazı sorular vardır.
KSab

6

JavaScript (ES6): 171 154 140 137 bayt

İpuçları için edc65 ve vihan1086 teşekkürler! [...n]çok güzel, ancak bu durumlarda çok basamaklı sayılar nedeniyle çalışmaz.

f=n=>{s=e=o='';n.split` `.map(Number).sort((a,b)=>a-b).map(v=>{s=s||v;if(e&&v>e+1){o+=`${s<e?s+'-'+e:s} `;s=v}e=v});return o+(s<e?s+'-'+e:e)}

ES5 varyantı 198 184 183 174 bayt

f=function(n){s=e=o='';n.split(' ').map(Number).sort(function(a,b){return a-b}).map(function(v){s=s||v;if(e&&v>e+1){o+=(s<e?s+'-'+e:s)+' ';s=v}e=v});return o+(s<e?s+'-'+e:e)}


hiçbir parantez olmadan split benim için tamamen yeni! Ama [...n]daha iyi
edc65

@ edc65 Teşekkürler, dizeyi bu şekilde açmayı hiç düşünmemiştim.
rink.attendant.6


... ama ... örneklerden herhangi biriyle çalışıyor mu? çok haneli sayılar vardır, bu nedenle "" (boş alan) üzerinde değil "" (boş dize) üzerinde bir bölmeye ihtiyacınız vardır. Muhtemelen size yanlış ipucu verdim
edc65

@ edc65 Bir şeyin farklı göründüğünü düşündüm ve test senaryolarının başarısız olduğunu fark ettim. Yine de yeni bir şey öğrenmek için iyi
rink.attendant.6

4

Yakut, 86 84 bayt

s=->*a{puts a.sort.slice_when{|i,j|i+1!=j}.map{|e|e.size<2?e:[e[0],e[-1]]*"-"}*" "}

# demo
s[9, 13, 3, 11, 8, 4, 10, 15, 6]
# => 3-4 6 8-11 13 15

Bu için docs bir örnekten biraz golfed versiyonudur slice_when .


4

CJam, 35 bayt

l~${__0=f-ee::=0+0#/((oW>Wf*S+oe_}h

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

l~$     e# Read a line from STDIN, evaluate it and sort the result.
{       e# Do:
  _     e#   Push a copy of the array.
  _0=f- e#   Subtract the first element from all array elements.
  ee    e#   Enumerate the differences: [0 1 4] -> [[0 0] [1 1] [2 4]]
  ::=   e#   Vectorized quality: [i j] -> (i == j)
  0+    e#   Append a zero.
  0#    e#   Push the first index of 0.
  /     e#   Split the array into chunks of that size.
  (     e#   Shift out the first chunk.
  (o    e#   Print its first element.
  W>    e#   Discard all remaining elements (if any) except the last.
  Wf*   e#   Multiply all elements of the remainder by -1.
  S+o   e#   Append a space and print.
  e_    e#   Flatten the rest of the array.
}h      e# Repeat while the array is non-empty.

4

Ruby, 70 bayt

Bunlar gibi sorunlar bana uygun yöntemler için Ruby API'sini kontrol etme eğilimindedir ve bugün yeni bir tane keşfettim:, Array#slice_whenRuby v2.2'de yeni tanıtıldı ve görünüşte bu kesin durum için tasarlandı :)

f=->a{puts a.sort.slice_when{|i,j|j-i>1}.map{|x|x.minmax.uniq*?-}*' '}

Diziyi sıraladıktan ve uygun şekilde dilimledikten sonra, her alt diziyi alır ve en yüksek ve en düşük öğeden bir dize oluşturur ve ardından tüm dizeyi bir dizeye ekler.

Misal:

f.call [9,13,3,11,8,4,10,15,6] baskılar 3-4 6 8-11 13 15


4

SWI-Prolog 165 162 159 bayt

b(Z,C,[D|E]):-Z=[A|B],(A=:=D+1,(B=[],put(45),print(A);b(B,C,[A,D|E]));(E=[],tab(1),print(A);writef('-%t %t',[D,A])),b(B,A,[A]));!.
a(A):-sort(A,B),b(B,_,[-1]).

Oldukça kötü ama yine de Prolog korkunç bir golf dilidir

Örnek: a([9,13,3,11,8,4,10,15,6]).çıktılar3-4 6 8-11 13 15


3

CJam, 38 33 bayt

@Dennis tarafından önerilen fikirleri ve kod parçalarını kullanan yeni sürüm:

l~$_,,.-e`{~T+\_T+:T;(_2$+W*Q?S}/

Çevrimiçi deneyin

Giriş formatı köşeli parantez içindeki bir CJam dizisidir.

Burada temel fikir, önce sıralı giriş dizisinden bir monotonik dizisi çıkarmak olmasıdır:

3  4  8  9 10 11 13 15
0  1  2  3  4  5  6  7  (-)
----------------------
3  3  6  6  6  6  7  8

Bu farkta, aynı aralığın parçası olan değerler aynı değere sahiptir. CJam RLE operatörünün bu farka uygulanması doğrudan aralıkları numaralandırır.

Çıkarma sırasında çıkarılan sıralı değerlerin geri eklenmesi gerekir. Kodumda nasıl yapıldığından tamamen memnun değilim. Bunu daha zarif bir yolla birkaç bayt tasarruf edebileceğimden şüpheleniyorum.

Aralıklarının çıkışı üretilmesi için bu üretim ilgilenir son değeri, negatif bir sayı oluşturmak Dennis fikrini kullanan -ve aynı zamanda yalnızca tek bir değer ihtiyaçları aralık boyutuna bağlı olarak ihmal / eklenecek için mantık kolaylaştırır .

Açıklama:

l~    Get input.
$     Sort it.
_,,   Create monotonic sequence of same length.
.-    Calculate vector difference between the two.
e`    Calculate RLE of difference vector.
{     Loop over entries in RLE.
  ~     Unpack the RLE entry, now have length/value on stack.
  T+    Add position to get original value for start of interval.
  \     Bring length of interval to top of stack.
  _T+:T;  Add length of interval to variable T, which tracks position.
  (     Decrement interval length.
  _     Copy it, we need it once for calculating end value, once for ternary if condition.
  2$    Copy interval start value to top...
  +     ... and add interval length - 1 to get end value.
  W*    Negate end value.
  Q?    Output end value if interval length was > 1, empty string otherwise.
  S     Add a space.
}%    End loop.

Bu RLE'nin akıllıca bir kullanımı! Cevabımdan aralık işleme ve giriş formatını ödünç alarak 34 bayta düşebilirsiniz:l~$_,,.-e`{~T+\_T+:T;,f+(\W>Wf*S}/
Dennis

Başlangıçta çözümünüze baktığımda -, kodda görünmeden ve bir koşul olmadan çıktıya nasıl girdiğinize dair gizemli biriydim . Şimdi anladım: Son değeri negatif bir sayıya dönüştürmek geliyor! Bunu asla bulamazdım, bu yüzden kopyalama konusunda kendimi kötü hissederdim. Bir dahaki sefere ondan öğrenmeye çalışacağım! :)
Reto Koradi

Yeterince adil. l~$_,,.-e{~ T + _T +: T; (_ 2 $ + W * Q? S} / `? Peki , kendi kodunuza çok daha benzer ve sadece 33 bayt ağırlığında.
Dennis

@Dennis Tamam, ısrar edersen. :) Aslında, aralık sonu için negatif bir değer üretme konusundaki anahtar fikri dikkate alarak, bunu uygulamak için oldukça basit bir yol gibi görünüyor. Teşekkürler.
Reto Koradi

2

CoffeeScript, 178 161 bayt

Tıpkı JavaScript yanıtım gibi. Anlayışları kullanmanın daha kısa kodla sonuçlanıp sonuçlanmayacağını bulmam gerekiyor.

f=(n)->s=e=o='';n.split(' ').map(Number).sort((a,b)->a-b).map((v)->s=s||v;(o+=s+(if s<e then'-'+e else'')+' ';s=v)if(e&&v>e+1);e=v);o+(if s<e then s+'-'else'')+e

Orijinal:

f=(n)->o='';s=e=0;n.split(' ').map(Number).sort((a,b)->a-b).forEach((v,i)->if!i then s=v else(o+=s+(if s<e then'-'+e else'')+' ';s=v)if(v!=e+1);e=v);o+(if s<e then s+'-'else'')+e

1

Piton 2, 126 122 121 bayt

Bunun daha kısa olabileceğini biliyorum, sadece nerede olduğunu bilmiyorum .. Formda giriş gerektirir [#, #, #, #, ..., #].

l=sorted(input());s=`l[0]`;c=0;x=1
while x<len(l):y,z=l[x],l[x-1];s+=(('-'+`z`)*c+' '+`y`)*(y-z>1);c=(y-z<2);x+=1
print s

execSıklıkla çözüm buluyorsunuz .
mbomb007

@ mbomb007 Xnor düşünüyor olabilirsiniz :) Ve bu durumda döngü aynı uzunlukta, hatta daha kısa olabilir (henüz yeterince oynamadı).
Kade

1
Sen yerine gerekir while x<len(l)ile while l[x:]birkaç bayt tasarruf etmek.
mathmandan

1

Java, 191 bayt

void f(int[]a){java.util.Arrays.sort(a);for(int b=a.length,c=b-1,i=0,j=a[0],l=j;++i<b;){if(a[i]!=++j||i==c){System.out.print((l+1==j?l+(i==c?" "+a[c]:""):l+"-"+(i==c?j:j-1))+" ");l=j=a[i];}}}

Aralıkları kontrol eder ve uygun şekilde yazdırır. Ne yazık ki dizi son öğe veya aralık yazdırılmadan program sonlandırılacağı için dizideki son öğe için özel bir durum yapmak zorunda kaldı.


1

Java, 171162 bayt

String s(int[] n){Arrays.sort(n);int p=0,b=0;String r="",d="";for(int c:n){if(c==++p)b=1;else{if(b==1){r+="-"+--p+d+c;p=c;b=0;}else{r+=d+c;p=c;}d=" ";}}return r;}

Girdiyi int dizisi olarak alır, çıktıyı boşlukla ayrılmış bir Dize listesi olarak döndürür

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.