นับการเปลี่ยนแปลงในอาร์เรย์


20

งานของคุณในวันนี้คือการเขียนโปรแกรมหรือฟังก์ชั่นที่ใช้อาร์เรย์จำนวนเต็มและนับจำนวนครั้งโดยอ่านจากซ้ายไปขวาว่าค่าเปลี่ยนไป นี่เป็นตัวอย่างที่แสดงได้ง่ายกว่า:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

กรณีทดสอบ:

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

นี่คือไบต์ที่น้อยที่สุดชนะ!


คำตอบของฉันถูกต้องหรือไม่หากผลลัพธ์นั้นคำนวณอย่างถูกต้องเสมอ แต่ถ้าเป็น 0 Falseจะพิมพ์ออกมาแทนหรือไม่
FlipTack

1
@FlipTack ขึ้นอยู่กับภาษา โดยทั่วไปถ้าฉันสามารถพูดได้2+Falseและมันผิดพลาดก็ไม่เป็นไร แต่ถ้าฉันได้รับ2มันก็ไม่เป็นไร
Pavel

@FlipTack โดยค่าเริ่มต้นนี่คือฉันทามติ
สิ้นเชิงมนุษย์

เอาต์พุตว่างสำหรับการ0ยอมรับหรือไม่
ติตัส

@Tios ใช่มันเป็น
Pavel

คำตอบ:



9

Python 3 , 38 ไบต์

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

ลองออนไลน์!


2
อืมรู้ว่าคุณสามารถใช้หาเรื่องเริ่มต้นแบบนั้นได้แล้วหาได้ดี
xnor


@Dennis ฟังก์ชั่นออกจากวนซ้ำเมื่ออาร์เรย์ว่างเปล่าได้อย่างไร ฉันไม่เห็นว่าสิ่งนี้จะไม่จบลงmaximum recursion depth exceededอย่างไร
โยอานส์

@Ioannes เมื่อมีเพียงองค์ประกอบเดียว ( x ) ที่เหลือy>()จะประเมินเป็นFalseดังนั้นโค้ดต่อไปนี้andจะไม่ถูกเรียกใช้
Dennis

7

Haskell , 33 ไบต์

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

ลองออนไลน์!


โบนัส:รุ่นเลขคณิตที่ไม่มีจุดอยากรู้อยากเห็น (44 ไบต์)

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

ลองออนไลน์!

ได้รับการป้อนข้อมูล[1,1,4,3,3,3]อันดับแรกเราจะใช้ความแตกต่างของรายการที่อยู่ติดกัน (คน[0,3,-1,0,0]) แล้วabsค่า [0,3,1,0,0]olute: การนำศูนย์ไปสู่พลังของแต่ละองค์ประกอบในครั้งแรกที่ได้รับผลตอบแทน[1,0,0,1,1]และครั้งที่สองกลับรายการ: [0,1,1,0,0]( (1-)จะทำงานที่นี่แทน(0^)) ในที่สุดเราใช้เวลาของรายการที่จะได้รับsum2



5

Brain-Flakขนาด 50 ไบต์

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

ลองออนไลน์!

ไม่มีผลใด ๆ กับ 0 ซึ่งเทียบเท่ากับการสะกิดในสมอง หากสิ่งนี้ไม่ได้รับการยอมรับให้ผนวกสิ่งนี้เป็น+4ไบต์:({})

คำอธิบาย:

#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 ทำได้ดีมาก! :)
DJMcMayhem


1
@Weateat ตัวช่วยสร้างฉันลองเช่นกัน แต่มันวนซ้ำตลอดไปในอินพุตว่าง -0+1 = 1
H.PWiz

5

Brain-Flakขนาด 50 ไบต์

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

ลองออนไลน์!

# 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!
Pavel

@Pavel ขอบคุณ! ฉันใช้เวลาตลอดไปเพื่อให้ได้ไม่กี่ร้อยสุดท้าย ฉันยุ่งมากกับสิ่งอื่น ๆ :(
Riley

ฉันมีสิ่งนี้
H.PWiz

@ H.PWiz ฉันมีที่จุดหนึ่ง แต่ฉันชอบวิธีป๊อปยกเลิกความสูงสแต็ค
Riley

5

Haskell , 35 ไบต์

-8 ไบต์ขอบคุณ H.PWiz

ออกแข็งแรงเล่นกอล์ฟโดยรุ่น recursive Haskell นั้นดีที่สุดในการเรียกซ้ำและฉันก็พลาดมันไป > _ <

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

ลองออนไลน์!

มันคงจะดีมากถ้าใครคิดวิธีใช้เคล็ดลับนี้

โซลูชันสำรอง 36 ไบต์

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

ลองออนไลน์!



เคล็ดลับนั้นพลาดข้อเท็จจริงสำคัญที่คุณต้องใช้ในuncurryการทำงานfเพื่อให้ทำงานได้ นี่sum.map fromEnum.(zipWith(/=)=<<tail)อาจเป็นสิ่งที่ใกล้เคียงที่สุดที่คุณได้รับ แต่มันจะไม่ทำงานด้วย[]และเป็น 37 ไบต์ ..
พฤศจิกายน

5

Java (OpenJDK 8) , 65 ไบต์

ไม่สั้นอย่างที่ฉันต้องการ แต่นั่นเป็นเพียง Java สำหรับคุณ

ทดสอบโดยผ่านอาร์เรย์เป็นรายการที่คั่นด้วยจุลภาค

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

ลองออนไลน์!


2
หากอาเรย์ที่ว่างเปล่าไม่ใช่กรณีทดสอบ (และฉันไม่พบว่าเกี่ยวข้องจริงๆจริง ๆ ) ก็สามารถใช้: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 ไบต์)
Olivier Grégoire

@ OlivierGrégoireฉันรู้! ฉันเขียนมันออกมาและคิดว่าฉันสามารถลดจำนวนไบต์ได้ แต่ก็ล้มเหลวในกรณีแรก
Luke Stevens

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



4

ภาษา Wolfram (Mathematica) , 2324 26 29 ไบต์

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

ลองออนไลน์!

  • -1 ไบต์ขอบคุณ Martin Ender!
  • -2 ไบต์ขอบคุณ JungHwan Min! Split[]การใช้งานที่ดีของ
  • -3 ไบต์ขอบคุณโดยสิ้นเชิงมนุษย์!

คำอธิบายเล็กน้อย:

Splitจะแบ่งอาร์เรย์ลงในรายการของรายการ A (ขององค์ประกอบเดียวกัน), ที่อยู่, เปลี่ยนเข้าไป{1, 2, 2, 3, 1, 1} {{1}, {2, 2}, {3}, {1, 1}}ดังนั้นLength@Split@#ปริมาณ segements ต่อเนื่องคือ Max[*****-1, 0]ใช้เพื่อจัดการกับ{}อินพุต



1
24 ไบต์:Max[Length@Split@#-1,0]&
JungHwan Min

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


4

Python เป็นสัญลักษณ์ , 120 117 ไบต์

แข็งแรงเล่นกอล์ฟ 3 ไบต์โดยการเอานักแสดงอย่างชัดเจนเป็นจำนวนเต็ม (โดยใช้เอก+) สำหรับตัวแปรที่เคาน์เตอร์ - ที่นี้หมายถึงว่าถ้าไม่มีการเปลี่ยนแปลงในอาร์เรย์ผลลัพธ์จะFalseแทน0แต่นี้จะได้รับอนุญาตจากเมตา

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

ลองออนไลน์!

# 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
= _ = ตัวช่วยสร้างนี้คืออะไร?
สิ้นเชิงมนุษย์


3

K (oK) 8 ไบต์

วิธีการแก้:

+/1_~~':

ลองออนไลน์!

ตัวอย่าง:

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

คำอธิบาย:

ตีความจากขวาไปซ้าย:

+/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 ไบต์

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

ลองออนไลน์!

เช่นเดียวกับคำตอบ MATL ที่ใช้เพียงเนื่องจากไม่มีsum(!!diff))nnz


+1 ฉันคิดว่าการใช้rleจะสั้นกว่านี้ แต่ไม่length(rle()$v)ใช้อักขระมากเกินไป
Neal Fultz

@NealFultz มันอาจจะคุ้มค่าที่จะโพสต์เป็นคำตอบ! ดีเสมอที่จะเห็นวิธีการอื่น และคุณควรจะใช้sum(rle()$v|1)แทนการlengthอยู่แล้ว :)
Giuseppe

3

Cubix , 24 ไบต์

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

ลองออนไลน์

โปรดทราบว่า Cubix ใช้ 0 เพื่อระบุว่าไม่มีอินพุตเพิ่มเติมดังนั้น 0 จึงไม่สามารถอยู่ในรายการได้

คำอธิบาย

กางออก:

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

เราเริ่มต้นที่0กดตัวนับ (เริ่มต้นด้วย0) และอินพุตแรก ( I) ลงบนสแต็ก

จากนั้นเราเข้าสู่วง Iที่ทวนของแต่ละวงที่เราได้รับการป้อนข้อมูลต่อไปด้วย ถ้าเป็น 0 เราหมดอินพุตดังนั้นเราจึงหมุนตัวนับไปที่ด้านบน ( p) Output และ exit ( @)

มิฉะนั้นเราจะรับผลต่างขององค์ประกอบสองอันดับแรก p)qถ้ามันไม่ใช่ศูนย์ที่เราหมุนเคาน์เตอร์ไปด้านบนเพิ่มมันและหมุนกลับไปด้านล่างด้วย จากนั้นเราก็เติมความแตกต่างด้วย;ก่อนที่จะย้ายไปทำซ้ำครั้งต่อไป

อักขระทั้งหมดที่ไม่ได้กล่าวถึงที่นี่เป็นเพียงการควบคุมการไหล มีแนวโน้มที่จะมีจำนวนมากในโปรแกรม Cubix


@MickyT วิธีการที่ดี แต่ดูเหมือนว่าคุณจะ overcounting โดย 1 คุณสามารถสลับ0สำหรับ a (แต่นั่นล้มเหลวในการป้อนข้อมูลที่ว่างเปล่า

ขออภัยจะมองมันอีกครั้ง
MickyT

3

Brain-Flakขนาด 50 ไบต์

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

ลองออนไลน์!

เนื่องจากทุกคนกำลังโพสต์โซลูชั่น 50 ไบต์ที่นี่เป็นของฉัน (ฉันมี48 ไบต์แต่เป็นการดัดแปลง DjMcMayhem ง่าย ๆ ดังนั้นฉันรู้สึกว่ามันคุ้มค่าที่จะโพสต์)

คำอธิบาย

คำตอบนี้ใช้การยกเลิกค่าอย่างกว้างขวาง

Un-golfed ดูเหมือนว่า

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

ที่นี่เราคำนวณเดลต้าจนกว่าสแต็กจะมีหนึ่งรายการที่เหลือแต่ละครั้งที่เราสะสมหนึ่งค่าจากลูปด้านในหากเดลต้าไม่ใช่ศูนย์

นี่เป็นวิธีการทำตรงไปตรงมา

เพื่อให้กอล์ฟนี้เราเริ่มต้นการยกเลิกค่า อันแรกและอันที่ควรจะเห็นได้จากนักกอล์ฟที่มีสมองที่แข็งกระด้างคือความสูงของกอง มันเป็นความจริงที่รู้จักกันดีว่า

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

เป็นเช่นเดียวกับ

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

เมื่อค่าถูกแก้ไขโดยหนึ่งค่าเดียวกันจะถูกเก็บไว้ สิ่งนี้ทำให้เรา

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

คุณอาจสังเกตเห็นว่าสิ่งนี้ไม่ได้ช่วยให้เราประหยัดไบต์ แต่ไม่ต้องกังวลว่ามันจะมีประโยชน์มากขึ้นเมื่อเราดำเนินการต่อไป

เราสามารถดำเนินการลดลงอีกหากคุณเห็นคำสั่ง

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

คุณสามารถลดได้จริง

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

สิ่งนี้ทำงานได้เพราะถ้าเราเข้าสู่ลูป[(...)]และ{}จะยกเลิกและหากเราไม่ได้ค่า[(...)]เป็นศูนย์ในตอนแรกและไม่จำเป็นต้องถูกยกเลิก เนื่องจากเรามีรูปแบบนี้เกิดขึ้นในรหัสของเราเราจึงสามารถลดได้

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

นั่นช่วยเราได้ 2 ไบต์ แต่มันยังใส่ negs สองตัวที่อยู่ติดกัน สิ่งเหล่านี้สามารถนำมารวมกันเพื่อช่วยเราอีก 2

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

และนั่นคือรหัสของเรา



3

Gaia 2 ไบต์

ėl

ลองออนไลน์!

สิ่งนี้เป็นการละเมิดข้อบกพร่อง (หรือฟีเจอร์?) ของ Gaia การเข้ารหัสแบบรันไทม์ไม่ได้คำนึงถึงองค์ประกอบล่าสุดในการพิจารณา โปรดทราบว่าฉันได้ตรวจสอบสองครั้งมันทำงานได้กับทุกกรณีทดสอบ

  • ė - เรียกใช้การเข้ารหัสความยาว (โดยมีตำหนิตามที่อธิบายไว้ข้างต้น)
  • l - ความยาว.

2

JavaScript (ES6), 35 ไบต์

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

ฉันสงสัยว่ามันจะสั้นลงหรือไม่โดยใช้การเรียกซ้ำ แต่ความพยายามที่ดีที่สุดของฉันคือ 35 ด้วย:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@Annauld ฉันก็ลองทำเช่นนั้น แต่คิดผิดและคิดว่ามันเป็น 36 ไบต์มิฉะนั้นฉันจะเพิ่มมันเข้าไปแทน
Neil


2

APL (Dyalog) 8 ไบต์

+/2≠/⊃,⊢

ลองออนไลน์!

อย่างไร?

⊃,⊢ - รายการที่มีค่าแรกซ้ำสำหรับกรณีขององค์ประกอบเดียว

2≠/ - รายการการเปลี่ยนแปลงไม่เท่ากันสำหรับทุกองค์ประกอบ 2

+/ - ผลรวม




2

Ruby , 31 ไบต์

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

ลองออนไลน์!


แทนที่จะ.drop(1)ทำอย่างนั้น[1..-1]
Cyoce

@Cyoce น่าเสียดายที่dropส่งคืน Enumerator ไม่ใช่ Array ดังนั้นมันจึงไม่ทำงาน
Jordan

ฮะ. มันส่งคืน Array ในเวอร์ชั่นของฉัน
Cyoce

@Cyoce เวอร์ชันไหน?
Jordan

ฉันใช้ 1.9.3 อยู่ แต่ทำไมคุณไม่เอาsizeArray ไปใช้ล่ะ?
Cyoce

2

C (gcc 5.4.0), 61 ไบต์

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

ลองออนไลน์!

f เป็นฟังก์ชั่นที่ใช้ความยาวของอาร์เรย์และตัวชี้ไปยังองค์ประกอบแรกของอาร์เรย์และคืนค่าจำนวนการเปลี่ยนแปลงในอาร์เรย์

การส่งนี้ใช้พฤติกรรมที่ไม่ได้กำหนด ( *p++!=*p, p ถูกใช้สองครั้งในนิพจน์ที่มีการเปลี่ยนแปลง), ซึ่งทำงานบนเครื่องของฉัน (gcc 5.4.0) และ TIO แต่อาจไม่ทำงานกับการใช้งานหรือรุ่นอื่น ๆ

คำอธิบาย:

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
}

คุณสามารถเพิ่มลิงก์ไปยังสภาพแวดล้อมการทดสอบออนไลน์ได้หรือไม่?
Jonathan Frech


2

05AB1E , 3 ไบต์

γ¦g

ลองออนไลน์!

อีกทางเลือกหนึ่งสำหรับคำตอบของ Erik

Fullg ~ โปรแกรมเต็มรูปแบบ

γ ~ จัดกลุ่มเป็นองค์ประกอบที่อยู่ติดกัน
 ¦ ~ ลบกลุ่มแรก (ถ้ามี)
  g ~ ความยาว

อาพลาดว่าเป็นกรณี
Magic Octopus Urn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.