Đếm các thay đổi trong một mảng


20

Nhiệm vụ của bạn hôm nay là viết một chương trình hoặc hàm lấy một mảng các số nguyên và đếm số lần, đọc từ trái sang phải, rằng giá trị thay đổi. Điều này dễ dàng hơn để hiển thị với một ví dụ:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Trường hợp thử nghiệm:

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

Đây là , ít byte thắng nhất!


Câu trả lời của tôi có hợp lệ không nếu kết quả luôn được tính toán chính xác, nhưng nếu là 0, Falseđược in thay thế?
FlipTack

1
@FlipTack Điều đó phụ thuộc vào ngôn ngữ. Nói chung, nếu tôi có thể nói 2+Falsevà nó sai, điều đó không ổn, nhưng nếu tôi nhận được 2, thì tốt.
Pavel

@FlipTack Theo mặc định, đây là sự đồng thuận.
hoàn toàn là

Là đầu ra trống cho 0chấp nhận?
Tít

@Titus đúng vậy.
Pavel

Câu trả lời:



9

Python 3 , 38 byte

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

Hãy thử trực tuyến!


2
Huh, đã biết bạn có thể sử dụng một đối số mặc định như vậy, tìm thấy tốt đẹp.
xnor


@Dennis Làm thế nào để hàm thoát khỏi vòng lặp đệ quy khi mảng trống? Tôi không thấy làm thế nào điều này không kết thúc trong một maximum recursion depth exceeded.
Ioannes

@Ioannes Khi chỉ còn một phần tử ( x ), y>()sẽ đánh giá thành Sai , do đó, đoạn mã sau andkhông được thực thi.
Dennis

7

Haskell , 33 byte

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

Hãy thử trực tuyến!


Phần thưởng: Một số phiên bản số học không có điểm gây tò mò (44 byte)

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

Hãy thử trực tuyến!

Đưa ra một đầu vào [1,1,4,3,3,3], trước tiên chúng ta lấy sự khác biệt của các mục liền kề ( [0,3,-1,0,0]), sau đó là absgiá trị olute : [0,3,1,0,0]. Lấy số không cho sức mạnh của mỗi phần tử trong lần đầu tiên mang lại [1,0,0,1,1]và lần thứ hai đảo ngược danh sách: [0,1,1,0,0]( (1-)cũng sẽ hoạt động ở đây thay vì (0^)). Cuối cùng chúng tôi lấy sumdanh sách để có được 2.



5

Brain-Flak , 50 byte

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

Hãy thử trực tuyến!

Đầu ra không có gì cho 0, mà trong flak não là tương đương. Nếu điều này không được chấp nhận, hãy nối nó với +4byte:({})

Giải trình:

#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 Hoàn thành tốt! :)
DJMcMayhem


1
@WheatWizard Tôi cũng đã thử điều đó, nhưng nó lặp lại mãi mãi với đầu vào trống. -0+1 = 1
H.PWiz

5

Brain-Flak , 50 byte

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

Hãy thử trực tuyến!

# 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
Chúc mừng đại diện 10k!
Pavel

@Pavel Cảm ơn! Tôi phải mất mãi mãi để có được vài trăm cuối cùng. Tôi đã quá bận rộn với những thứ khác :(
Riley

Tôi đã có cái này
H.PWiz

@ H.PWiz Tôi đã có điều đó tại một thời điểm, nhưng tôi thích cách pop hủy bỏ việc đẩy chiều cao ngăn xếp.
Riley

5

Haskell , 35 byte

-8 byte nhờ H.PWiz.

Out-golfed bởi một phiên bản đệ quy . Haskell là khá nhiều tốt nhất trong đệ quy và tôi đã bỏ lỡ nó. > _ <

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

Hãy thử trực tuyến!

Thật tuyệt vời nếu có ai tìm ra cách sử dụng mẹo này .

Giải pháp thay thế, 36 byte

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

Hãy thử trực tuyến!



Mẹo đó bỏ lỡ một thực tế quan trọng là bạn cần có uncurrychức năng fđể làm cho nó hoạt động. Đây sum.map fromEnum.(zipWith(/=)=<<tail)có thể là gần nhất bạn nhận được, nhưng nó sẽ không hoạt động []và có 37 byte ..
ბიმო

5

Java (OpenJDK 8) , 65 byte

Không ngắn như tôi muốn, nhưng đó chỉ là Java dành cho bạn.

Kiểm tra bằng cách chuyển mảng dưới dạng danh sách được phân cách bằng dấu phẩy.

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

Hãy thử trực tuyến!


2
Nếu mảng trống không phải là trường hợp thử nghiệm (và thực tế tôi không thấy nó thực sự có liên quan), thì người ta có thể đã sử dụng: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 byte).
Olivier Grégoire

@ OlivierGrégoire Tôi biết! Tôi đã viết nó ra và nghĩ rằng tôi đã cố gắng cắt giảm các byte nhưng nó đã thất bại trong trường hợp đầu tiên đó.
Luke Stevens

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

4

Husk , 3 byte

Ltg

Hãy thử trực tuyến!

Giải trình

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

Ngôn ngữ Wolfram (Mathicala) , 2324 26 29 byte

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

Hãy thử trực tuyến!

  • -1 byte nhờ Martin Ender!
  • -2 byte nhờ JungHwan Min! sử dụng tốt đẹp của Split[].
  • -3 byte nhờ hoàn toàn nhân văn!

một lời giải thích nhỏ:

Splitsẽ chia một mảng thành một danh sách các danh sách (có cùng các phần tử), nghĩa là chuyển {1, 2, 2, 3, 1, 1}thành {{1}, {2, 2}, {3}, {1, 1}}. Vì vậy, Length@Split@#là số lượng phân chia liên tiếp. Max[*****-1, 0]được sử dụng để đối phó với {}đầu vào.



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

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


4

Python tượng trưng , 120 117 byte

Đã đánh 3 byte bằng cách loại bỏ một biểu thức rõ ràng thành số nguyên (sử dụng unary +) cho biến đếm - điều này có nghĩa là nếu không có thay đổi nào trong mảng thì đầu ra sẽ Falsethay thế 0, nhưng điều này được cho phép bởi meta .

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

Hãy thử trực tuyến!

# 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
= _ = phù thủy này là gì?
hoàn toàn là

3

Thạch , 3 byte

ITL

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

ITL - Chương trình đầy đủ.

Tôi - Tăng (deltas).
 T - Lấy chỉ số của các giá trị trung thực (lấy chỉ mục của các phần tử khác 0).
  L - Chiều dài.

3

K (oK) , 8 byte

Dung dịch:

+/1_~~':

Hãy thử trực tuyến!

Ví dụ:

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

Giải trình:

Giải thích từ phải sang trái:

+/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 byte

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

Hãy thử trực tuyến!

Giống như câu trả lời MATL, chỉ được sử dụng sum(!!diff))vì không có nnz.


+1 Tôi nghĩ việc sử dụng rlesẽ ngắn hơn, nhưng không, length(rle()$v)sử dụng quá nhiều ký tự và bị tắt bởi một ký tự.
Neal Fultz

@NealFultz có lẽ vẫn đáng để đăng lên như một câu trả lời! Luôn luôn tốt để xem một cách tiếp cận khác. Và bạn nên sử dụng sum(rle()$v|1)thay vì lengthanyway. :)
Giuseppe

3

Khối , 24 byte

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

Dùng thử trực tuyến

Lưu ý rằng Cubix sử dụng 0 để chỉ ra rằng không có thêm đầu vào, vì vậy 0 không thể có trong danh sách.

Giải trình

Mở ra:

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

Chúng tôi bắt đầu tại 0, đẩy bộ đếm (khởi tạo với 0) và đầu vào đầu tiên ( I) lên ngăn xếp.

Chúng tôi sau đó vào vòng lặp. Ở mỗi lần lặp của vòng lặp, chúng ta sẽ nhận được đầu vào tiếp theo I. Nếu là 0, chúng tôi đã hết đầu vào, vì vậy chúng tôi xoay bộ đếm lên trên cùng ( p), Output và exit ( @).

Mặt khác, chúng tôi lấy sự khác biệt của hai yếu tố hàng đầu. Nếu nó khác, chúng ta xoay bộ đếm lên trên cùng, tăng nó và xoay nó trở lại xuống dưới cùng p)q. Sau đó chúng tôi bật sự khác biệt với ;trước khi chuyển sang lần lặp tiếp theo.

Tất cả các nhân vật không được đề cập ở đây chỉ là dòng điều khiển. Có xu hướng có rất nhiều những người trong các chương trình Cubix.


@MickyT Cách tiếp cận tốt, nhưng dường như bạn đang vượt qua 1. Bạn có thể trao đổi 0cho a (, nhưng thất bại ở đầu vào trống.

xin lỗi, sẽ xem xét lại
MickyT

3

Brain-Flak , 50 byte

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

Hãy thử trực tuyến!

Vì mọi người đều đăng các giải pháp 50 byte của họ ở đây là của tôi (tôi có một byte 48 byte nhưng đó là một sửa đổi đơn giản của DjMcMayhem nên tôi cảm thấy nó đáng để đăng)

Giải trình

Câu trả lời này sử dụng rộng rãi hủy bỏ giá trị.

Un-golfed nó trông giống như

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

Ở đây chúng ta tính toán delta cho đến khi ngăn xếp còn lại một mục, mỗi lần chúng ta tích lũy một giá trị từ vòng lặp bên trong nếu delta bằng không.

Đây là một cách khá thẳng về phía trước để làm điều đó.

Để làm cho golf này, chúng tôi bắt đầu hủy bỏ giá trị. Cái đầu tiên và cái rõ ràng nhất đối với bất kỳ tay golf cứng não nào là chiều cao chồng. Đó là một thực tế nổi tiếng rằng

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

giống như

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

Khi các giá trị được sửa đổi bởi một, cùng giữ. Điều này cho chúng ta

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

Bạn có thể nhận thấy điều này thậm chí không tiết kiệm cho chúng tôi byte, nhưng đừng băn khoăn nó sẽ trở nên hữu ích hơn khi chúng ta tiếp tục.

Chúng tôi có thể thực hiện giảm khác, nếu bạn thấy một tuyên bố

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

bạn thực sự có thể giảm nó xuống

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

Điều này hoạt động bởi vì nếu chúng ta vào vòng lặp [(...)]{}sẽ hủy, và nếu chúng ta không có giá trị [(...)]bằng 0 ở vị trí đầu tiên và không cần phải hủy bỏ. Vì chúng tôi có sự xuất hiện của mẫu này trong mã của chúng tôi, chúng tôi có thể giảm nó.

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

Điều đó đã tiết kiệm cho chúng tôi 2 byte nhưng nó cũng đặt hai phủ định cạnh nhau. Đây có thể được kết hợp để tiết kiệm cho chúng tôi 2.

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

Và đó là mã của chúng tôi.


3

Perl 6 , 18 byte

{sum $_ Z!= .skip}

Kiểm tra nó

Mở rộng:

{ # bare block lambda with implicit parameter 「$_」

  sum         # count the number of True values

      $_      # the input
    Z!=       # zip using &infix:«!=»
      .skip   # the input, but starting from the second value
              # (implicit method call on 「$_」
}

3

Gaia , 2 byte

ėl

Hãy thử trực tuyến!

Điều này lạm dụng một lỗi (hoặc tính năng?) Của Gaia, rằng mã hóa độ dài chạy không tính đến lần chạy cuối cùng của các phần tử. Lưu ý rằng tôi đã kiểm tra hai lần, nó hoạt động cho tất cả các trường hợp thử nghiệm.

  • ė - Chạy mã hóa chiều dài (với lỗ hổng được mô tả ở trên).
  • l - Chiều dài.

2

JavaScript (ES6), 35 byte

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

Tôi tự hỏi nếu nó có thể được rút ngắn bằng cách sử dụng đệ quy. Nhưng nỗ lực tốt nhất của tôi cũng là 35:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@Arnauld Tôi cũng đã thử điều đó, nhưng đã nhầm lẫn và nghĩ rằng đó là 36 byte, nếu không tôi đã thêm nó vào như một giải pháp thay thế.
Neil


2

APL (Dyalog) , 8 byte

+/2≠/⊃,⊢

Hãy thử trực tuyến!

Làm sao?

⊃,⊢ - danh sách, với giá trị đầu tiên được lặp lại cho trường hợp phần tử đơn

2≠/ - danh sách thay đổi, không bằng nhau cho mỗi 2 yếu tố

+/ - tổng



2

J, 10 byte

[:+/2~:/\]

Infixes có độ dài 2 ... chúng có bằng nhau không? 2 ~:/\ ]

Tính tổng danh sách kết quả của 0s và 1s:+/

Hãy thử trực tuyến!


[:+/0=-/\ Tôi phải làm việc cho tôi nghĩ 9 byte.
cole

2

Ruby , 31 byte

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

Hãy thử trực tuyến!


Thay vì .drop(1)bạn có thể làm[1..-1]
Cyoce

@Cyoce Thật không may droptrả về một Enumerator, không phải là Array, vì vậy nó không hoạt động.
Jordan

Huh. Nó trả về một mảng trên phiên bản của tôi.
Cyoce

@Cyoce Phiên bản nào?
Jordan

Tôi đang ở trên 1.9.3 nhưng tại sao bạn không thể lấy sizeMảng nào?
Cyoce

2

C (gcc 5.4.0), 61 byte

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

Hãy thử trực tuyến!

f là một hàm lấy độ dài của mảng và một con trỏ tới phần tử đầu tiên của mảng và trả về số lượng thay đổi trong mảng;

Trình này sử dụng hành vi không xác định (*p++!=*p , p được sử dụng hai lần trong một biểu thức được thay đổi), hoạt động trên máy của tôi (gcc 5.4.0) và trên TIO, nhưng có thể không hoạt động trên các triển khai hoặc phiên bản khác.

Giải trình:

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
}

Bạn có thể thêm một liên kết đến một môi trường thử nghiệm trực tuyến?
Jonathan Frech


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.