Bir dizideki değişiklikleri sayma


20

Bugünkü göreviniz, bir dizi tamsayı alan ve soldan sağa doğru okuyarak, değerin değiştiği sayıları sayan bir program veya işlev yazmaktır. Bir örnekle bunu göstermek daha kolaydır:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Test durumu:

Input           |   Output
[]              |   0
[0]             |   0
[0 1]           |   1
[0 0]           |   0
[1 2 3 17]      |   3
[1 1 1 2 2 3]   |   2
[-3 3 3 -3 0]   |   3

Bu , en az bayt kazanır!


Sonuç her zaman doğru bir şekilde hesaplanırsa, ancak 0 ise False, bunun yerine yazdırılırsa cevabım geçerli mi?
FlipTack

1
@FlipTack Bu dile bağlıdır. Genel olarak, eğer söyleyebilir 2+Falseve hata verirse, bu iyi değil, ama alırsam 2, bu iyi.
Pavel

@FlipTack Varsayılan olarak, bu fikir birliğidir.
totallyhuman

Boş çıktı 0kabul edilebilir mi?
Titus

@ Titus evet öyle.
Pavel

Yanıtlar:



9

Python 3 , 38 bayt

f=lambda x=0,*y:y>()and(x!=y[0])+f(*y)

Çevrimiçi deneyin!


2
Huh, bunun gibi varsayılan bir arg kullanabileceğini biliyor muydun, güzel bul.
xnor


@Dennis Dizi boşken fonksiyon özyinelemeli döngüden nasıl çıkar? Bunun nasıl bitmediğini anlamıyorum maximum recursion depth exceeded.
Ioannes

@Ioannes Yalnızca bir öğe ( x ) kaldığında, False olaraky>() değerlendirilir , böylece aşağıdaki kod yürütülmez. and
Dennis

7

Haskell , 33 bayt

f(a:b:r)=sum[1|a/=b]+f(b:r)
f _=0

Çevrimiçi deneyin!


Bonus: Biraz meraklı noktasız aritmetik versiyon (44 bayt)

sum.(tail>>=zipWith((((0^).(0^).abs).).(-)))

Çevrimiçi deneyin!

Bir giriş göz önüne alındığında [1,1,4,3,3,3], ilk bitişik girişleri (farkını alır [0,3,-1,0,0]), sonra abs: olute değer [0,3,1,0,0]. Her elemanın gücüne sıfır almak ilk kez sonuç verir [1,0,0,1,1]ve ikinci kez listeyi tersine çevirir: [0,1,1,0,0]( (1-)yerine burada da çalışır (0^)). Sonunda almak için sumlisteyi alıyoruz 2.



5

Brain-Flak , 50 bayt

([][()]){{}({}[({})]){{}<>({}())(<>)}{}([][()])}<>

Çevrimiçi deneyin!

Brain-flak'ta eşdeğer olan 0 için hiçbir şey çıktılamaz. Bu kabul edilebilir değilse, +4bayt için bunu ekleyin :({})

Açıklama:

#Push stack-height-1
([][()])

#While true:
{

    #Pop the stack-height-1 off
    {}

    #If 'a' is the element on top of the stack, and 'b' is the element underneath it, then
    #Pop 'a' off, and push (a - b)
    ({}[({})])

    #If (a-b) is not 0...
    {
        #Pop (a-b) off
        {}

        #Switch stacks
        <>

        #Increment the value on the other stack
        ({}())

        #Push a 0 back to the main stack
        (<>)

    #Endif
    }

    #Pop either (a-b) or the 0 we pushed
    {}

    #Push stack-height-1
    ([][()])

#Endwhile
}

#Toggle to the alternate stack and display the counter
<>


@Riley Güzel bitti! :)
DJMcMayhem


1
@WheatWizard Ben de denedim, ama boş giriş sonsuza kadar döngüler. -0+1 = 1
H.PWiz

5

Brain-Flak , 50 bayt

(([][()]){[{}]<({}[({})])>{(<{}>)()}{}([][()])}<>)

Çevrimiçi deneyin!

# Get ready to push the answer
(

# Push stack height - 1
([][()])

# Loop until 0 (until the stack has a height of 1)
{

  # Pop the old stack height and subtract it 
  #(cancels the loop counter from the final answer)
  [{}]

  # Pop the top of the stack and subtract the next element from that
  # Don't include this in the final answer
  <({}[({})])>

  # If not 0
  {

    # Pop the difference between the last two numbers
    # Don't include this in the final answer
    (<{}>)

    # Add 1 to the final answer
    ()

  # End if
  }{}

  # Push stack height - 1
  ([][()])

# End while
}

# Switch to the off stack so we don't print anything extra
<>

# Push the total sum. This is the number of times the if was true
)

1
10k temsilci için tebrikler!
Pavel

@Pavel Teşekkürler! Son yüzümü almak sonsuza dek sürdü. Diğer şeylerle çok meşguldüm :(
Riley

Ben bu
H.PWiz

@ H.PWiz Bir noktada bunu yaptım, ama pop'un yığın yüksekliği itmesini nasıl iptal ettiğini seviyorum.
Riley

5

Haskell , 35 bayt

H.PWiz sayesinde -8 bayt.

Özyinelemeli bir sürümle golf . Haskell neredeyse özyineleme en iyisidir ve özledim. > _ <

f l=sum[1|x<-zipWith(/=)l$tail l,x]

Çevrimiçi deneyin!

Herkes istihdam nasıl anladım eğer müthiş olurdu bu ipucunu .

Alternatif çözüm, 36 bayt

f l=sum[1|True<-zipWith(/=)l$tail l]

Çevrimiçi deneyin!



Bu ipucu uncurry, çalışmasını fsağlamak için işleve ihtiyaç duyacağınız önemli gerçeği kaçırır . Bu sum.map fromEnum.(zipWith(/=)=<<tail)muhtemelen olsun en yakın, ancak birlikte çalışma olmayacak [].. ve 37 bayt
ბიმო

5

Java (OpenJDK 8) , 65 bayt

İstediğim kadar kısa değil, ama bu sadece sizin için Java.

Diziyi virgülle ayrılmış bir liste olarak geçirerek test edin.

a->{int s=0,i=1;for(;i<a.length;s+=a[i-1]!=a[i++]?1:0);return s;}

Çevrimiçi deneyin!


2
Boş dizi bir test durumu olmasaydı (ve gerçekten alakalı bulmuyordum), bir tanesi kullanılmış olabilirdi: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 bayt).
Olivier Grégoire

@ OlivierGrégoire biliyorum! Bunu yazdım ve baytları azaltmayı başardığımı düşündüm ama ilk davada başarısız oldu.
Luke Stevens

3
56 bayt:a->{int s=0;for(int i:a)s+=a[0]!=(a[0]=i)?1:0;return s;}
Nevay

4

Kabuk , 3 bayt

Ltg

Çevrimiçi deneyin!

açıklama

Ltg    Input: [1,1,1,2,2,3]
  g    Group equal elements together: [[1,1,1],[2,2],[3]]
 t     Drop the first group (if any): [[2,2],[3]]
L      Return the length of the list: 2


4

Wolfram Dili (Mathematica) , 2324 26 29 bayt

Length@Split@#~Max~1-1&

Çevrimiçi deneyin!

  • Martin Ender sayesinde -1 bayt!
  • JungHwan Min sayesinde -2 bayt! güzel kullanımı Split[].
  • Tamamen insanlık sayesinde -3 byte!

biraz açıklama:

Splitbir diziyi bir liste listesine (aynı öğelerin), yani dönüştürülecek şekilde {1, 2, 2, 3, 1, 1}böler {{1}, {2, 2}, {3}, {1, 1}}. Yani, Length@Split@#ardışık segmentlerin miktarı. girdi Max[*****-1, 0]ile uğraşmak için kullanılır {}.



1
24 bayt:Max[Length@Split@#-1,0]&
JungHwan Min

23:Length@Split@#~Max~1-1&
Martin Ender


4

Sembolik Python , 120 117 bayt

+Sayaç değişkeni için tamsayıya (unary kullanılarak ) açık bir kademe kaldırarak 3 bayt golf - bu, dizide herhangi bir değişiklik olmazsa çıktının Falseyerine izin verileceği0 , ancak metaya izin verildiği anlamına gelir .

___=-~(_==_)
__('___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)')
__('__=___=_>_'+';___+=_[__]!=_[-~__];__=-~__'*___)
_=___

Çevrimiçi deneyin!

# LINE 1: Generate value '2' for utility
___=-~(_==_)

# LINE 2: Get len(input) - 1
__('___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)')
   '___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)'     # Generate string '___=~-len(_)'
            `_>_`[___::___]                       #    'le' spliced from 'False'
                           +`__`[-~___]           #    'n' indexed from '<function ...>'
   '___=~-'+                           +'(_)'     #    Remaining characters in plaintext
__(                                          )    # Execute this to get len(input) - 1

# LINE 3: Main calculation loop
__('__=___=_>_'+';___+=_[__]!=_[-~__];__=-~__'*___) 
__(                                               ) # Execute:
   '__=___=_>_'                                     #   Set var1, var2 to 0
               +';                           '*___  #   len(input) - 1 times do:
                       _[__]!=_[-~__]               #   Compare input[var1, var1 + 1]
                  ___+=              ;              #   Add this to var2
                                      __=-~__       #   Increment var1

# LINE 4: Set output variable ('_') to the result calculated.
_=___                                       

2
= _ = bu sihirbaz nedir?
totallyhuman

3

Jöle , 3 bayt

ITL

Çevrimiçi deneyin!

Nasıl çalışır

ITL - Tam program.

I - Artışlar (deltalar).
 T - Doğru değerlerin indekslerini alın (0 olmayan elemanların indekslerini alır).
  L - Uzunluk.

3

K (oK) , 8 bayt

Çözüm:

+/1_~~':

Çevrimiçi deneyin!

Örnekler:

+/1_~~':1 1 1 2 2 5 5 5 5 17 3
4
+/1_~~':()
0
+/1_~~':-3 3 3 -3 0
3

Açıklama:

Sağdan sola yorumlandı:

+/1_~~': / the solution
     ~': / equal each-previous
    ~    / not (ie differ)
  1_     / 1 drop, remove first as this is different to null
+/       / sum up trues



3

R , 24 bayt

cat(sum(!!diff(scan())))

Çevrimiçi deneyin!

MATL cevabı ile aynı, sadece sum(!!diff))olmadığı için kullanılır nnz.


+1 Kullanmanın rledaha kısa olacağını düşündüm , ama hayır, length(rle()$v)çok fazla karakter kullanıyor ve bir tane kapalı.
Neal Fultz

@NealFultz muhtemelen cevap olarak göndermeye değer! Başka bir yaklaşım görmek her zaman iyidir. Ve yine de sum(rle()$v|1)yerine kullanmalısınız length. :)
Giuseppe

3

Cubix , 24 bayt

UpO@0I>I!^-u>q.uvv$!^;)p

Çevrimiçi deneyin

Cubix'in başka girdi olmadığını belirtmek için 0 kullandığını unutmayın, bu nedenle 0 listede olamaz.

açıklama

Kırımsız:

    U p
    O @
0 I > I ! ^ - u
> q . u v v $ !
    ^ ;
    ) p

0Sayaç (ile başlatıldı 0) ve ilk girişi ( I) yığına iterek başlıyoruz .

Sonra döngüye giriyoruz. Döngünün her yinelemesinde, bir sonraki girdiyi alırız I. 0 ise, girişlerimiz tükenmiştir, bu nedenle sayacı üste ( p), Output ve exit ( @) konumuna döndürürüz .

Aksi takdirde, ilk iki elementin farkını alırız. Sıfır değilse, sayacı tepeye döndürür, arttırır ve ile tekrar tabana döndürürüz p)q. Daha sonra bir ;sonraki yinelemeye geçmeden önce farkı fark ederiz .

Burada belirtilmeyen tüm karakterler sadece kontrol akışıdır. Cubix programlarında birçoğu var.


@MickyT İyi yaklaşım, ancak sen takas olabilir 1 ile fazla sayım gibi görünüyor 0bir için (, ama bu boş girişi başarısız olur.

özür dilerim, tekrar bakacağız
MickyT

3

Brain-Flak , 50 bayt

(([][()]){[{}({}[({})])]{{}()(<()>)}{}([][()])}<>)

Çevrimiçi deneyin!

Herkes 50 baytlık çözümlerini burada paylaştığım için benim ( 48 baytlık bir tane var ama DjMcMayhem'in basit bir modifikasyonuydu, bu yüzden göndermeye değer hissettim)

açıklama

Bu cevap, değer iptal etmeyi yoğun olarak kullanmaktadır.

Golf oynanmamış gibi görünüyor

([][()])({<{}({}[({})])>{<{}>()(<()>)}{}<([][()])>}<>)

Burada, yığında bir öğe kalıncaya kadar deltayı hesaplıyoruz, eğer delta sıfır değilse, iç döngüden her bir değer biriktirdiğimizde.

Bu, bunu yapmanın oldukça basit bir yoludur.

Bu golf yapmak için değer iptal etmeye başlıyoruz. Birincisi ve herhangi bir sertleştirilmiş beyin-flak golfçüsü için açık olması gereken, yığın yüksekliğidir. İyi bilinen bir gerçektir

([])({<{}>...<([])>}{})

aynıdır

(([]){[{}]...([])}{})

Değerler bir değiştirildiği zaman aynı kalır. Bu bize

(([][()]){[{}]<({}[({})])>{<{}>()(<()>)}{}([][()])}<>)

Bunun bizi bayt tasarruf etmediğini fark edebilirsiniz, ancak devam ettikçe daha kullanışlı hale geleceğinden korkmayın.

Bir ifade görürseniz başka bir indirim yapabiliriz

<(...)>{<{}> ...

bunu aslında

[(...)]{{} ...

Bu eserler biz döngüye girmesine çünkü eğer [(...)]ve {}iptal edecek ve biz değil değerini yaparsanız [(...)]zaten ilk etapta sıfırdı ve iptal edilmesi gerekmez. Kodumuzda bu paternin ortaya çıkması nedeniyle onu azaltabiliriz.

(([][()]){[{}][({}[({})])]{{}()(<()>)}{}([][()])}<>)

Bu bize 2 bayt kurtardı ama aynı zamanda yan yana iki hata koydu. Bunlar bizi başka 2 kurtarmak için birleştirilebilir.

(([][()]){[{}({}[({})])]{{}()(<()>)}{}([][()])}<>)

Ve bu bizim kodumuz.



3

Gaia , 2 bayt

ėl

Çevrimiçi deneyin!

Bu, Gaia'nın bir hatasını (veya özelliğini?) Kötüye kullanır, çalışma uzunluğu kodlamasının, öğelerin son çalışmasını dikkate almaz. Çift kontrol ettiğimi, tüm test senaryolarında işe yaradığını unutmayın.

  • ė - Çalışma uzunluğu kodlaması (yukarıda açıklanan hata ile).
  • l - Uzunluk.

2

JavaScript (ES6), 35 bayt

a=>a.filter((e,i)=>e-a[i+1]).length

Acaba özyineleme kullanılarak kısaltılabilir mi? Ama en iyi girişimim de 35:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@ Ben de denedim, ama yanlış sayım ve 36 bayt olduğunu düşündüm, aksi takdirde alternatif olarak ekledi olurdu.
Neil




2

J, 10 bayt

[:+/2~:/\]

Uzunluk 2 ekleri ... eşit değil mi? 2 ~:/\ ]

Ortaya çıkan 0s ve 1s listelerini toplayın:+/

Çevrimiçi deneyin!


[:+/0=-/\ Sanırım 9 bayt için çalışmalıyım.
cole

2

Ruby , 31 bayt

->a{a.chunk{|x|x}.drop(1).size}

Çevrimiçi deneyin!


Yerine .drop(1)yapabileceğiniz[1..-1]
Cyoce

@Cyoce Ne yazık ki dropbir Array değil bir Enumerator döndürür, bu yüzden çalışmaz.
Ürdün

ha. Sürümümde bir Array döndürüyor.
Cyoce

@Cyoce Hangi sürüm?
Ürdün

1.9.3'deyim ama neden sizebir diziyi yine de alamıyorsun ?
Cyoce

2

C (gcc 5.4.0), 61 bayt

f(c,v)int*v;{int*p=v,s=0;for(;p<v+c-1;s+=*p++!=*p);return s;}

Çevrimiçi deneyin!

f dizinin uzunluğunu ve dizinin ilk öğesine bir işaretçi alan ve dizideki değişiklik sayısını döndüren bir işlevdir;

Bu gönderim *p++!=*p, makinemde (gcc 5.4.0) ve TIO'da çalışan, ancak diğer uygulamalar veya sürümlerde çalışmayabilen tanımlanmamış davranış (( p değiştirildiği bir ifadede iki kez kullanılır) kullanır .

Açıklama:

f(c,v)int*v;{ // old-style declaration for v, and implicit-int for c and return value
    int*p=v,s=0; // p is a pointer to the current item, s is the number of changes
    for(;p<v+c-1;s+=*p++!=*p); // for each consecutive pair of integers, if they are different, add one to the number of changes
    return s; // return the number of changes
}

Çevrimiçi test ortamına bir bağlantı ekleyebilir misiniz?
Jonathan Frech


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.