การคำนวณระยะทาง mod N


13

คุณได้รวบรวมข้อมูลจากAdvanced Collecting Device Controller ™มาเป็นเวลานาน คุณตรวจสอบบันทึกและความสยองขวัญของคุณคุณพบว่ามีบางอย่างผิดปกติอย่างยิ่ง: ข้อมูลมีเพียงจำนวนบิตสุดท้าย!

โชคดีที่คุณรู้ค่าเริ่มต้นและค่าไม่เปลี่ยนแปลงอย่างรวดเร็ว นั่นหมายความว่าคุณสามารถกู้คืนที่เหลือโดยเพียงแค่ค้นหาระยะทางจากจุดเริ่มต้น

ท้าทาย

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

การเปลี่ยนแปลงระหว่างตัวเลขทุกคู่จะน้อยกว่าเสมอN/2ดังนั้นจะมีคำตอบที่ถูกต้องเพียงข้อเดียวสำหรับแต่ละกรณีทดสอบ

คุณจะได้รับเป็นอินพุตจำนวนเต็มN> 2 และรายการค่าในรูปแบบที่คุณเลือก อินพุตอาจถูกกำหนดผ่าน STDIN หรือบรรทัดรับคำสั่งหรืออาร์กิวเมนต์ของฟังก์ชัน

คุณจะส่งออกจำนวนเต็มเดียวจำนวนเงินที่มีการเปลี่ยนแปลงค่าเดิม เอาต์พุตอาจถูกพิมพ์ไปที่ STDOUT หรือส่งคืน

กฎระเบียบ

  • โปรแกรมต้องทำงานของคุณสำหรับระยะทางใด ๆ 2^20และโมดูลัสน้อยกว่า
  • คุณอาจคิดว่า:
    • N3เป็นอย่างน้อย
    • รายการมีค่าอย่างน้อย 2 ค่า
    • ค่าทั้งหมดในรายการอย่างน้อย 0 Nและน้อยกว่า
    • N/2การเปลี่ยนแปลงทั้งหมดในจำนวนที่น้อยกว่า
  • สิ่งอื่นใดคืออินพุตที่ไม่ถูกต้องและโปรแกรมของคุณอาจทำสิ่งที่มันต้องการ
  • ช่องโหว่มาตรฐานห้องสมุดที่ไม่ได้มาตรฐานและฟังก์ชั่นในตัวสำหรับจุดประสงค์ที่แน่นอนนี้เป็นสิ่งต้องห้าม
  • นี่คือดังนั้นโปรแกรมที่สั้นที่สุดในหน่วยไบต์ชนะ

ตัวอย่างกรณีทดสอบ

การป้อนข้อมูล:

3
0 1 2 2 0 1 0 2 1 2 0 1 2 1 1

เอาท์พุท:

4

คำอธิบาย (พร้อมค่าตัวอย่าง):

Value mod 3: 0 1 2 2 0 1 0 2 1 2 0 1 2 1 1
Value:       0 1 2 2 3 4 3 2 1 2 3 4 5 4 4

การป้อนข้อมูล:

10
5 2 8 9 5

เอาท์พุท:

-10

คำอธิบาย (พร้อมค่าตัวอย่าง):

Value mod 10:  5  2  8  9  5
Value:        15 12  8  9  5

อินพุตไม่ถูกต้อง:

2
0 0 0 0 0

(มอดุลัสเล็กเกินไป)

6
2 5 4 2

(เปลี่ยนแปลงมากเกินไประหว่าง 2 และ 5)


รูปแบบที่คุณเลือกคือความลาดชันลื่น โซลูชัน GolfScript ของฉันสามารถพึ่งพารายการอินพุตที่มีลักษณะ:^;[5 2 8 9 5](\ อย่างไร
Lynn

3
@Mauris โดยทั่วไปแล้วไม่ ... "รูปแบบที่คุณเลือก" มักจะถือว่ามีความหมายว่า "การแสดงแบบดั้งเดิมในภาษาที่คุณเลือก"
Martin Ender

อย่างไรก็ตามคุณสามารถพึ่งพารายการอินพุตที่มีลักษณะเช่น "10 5 2 8 9 5" หรือ "10,5 2 8 9 5" หรือ "10 5,2,8,9,5"
Sparr

คำตอบ:


2

TI-BASIC ขนาด 15 ไบต์

Input N
sum(N/πtan⁻¹(tan(ΔList(πAns/N

รับรายการจากและโมดูลัสจากAnsInput

                       πAns/N    ; Normalize the list to [0,π)
                 ΔList(          ; Take differences, which are in the range (-π,π)
       tan⁻¹(tan(                ; Modulo, but shorter. Now elements are in (-π/2,π/2)
    N/π                          ; Multiply by N/π. These are displacements at each step.
sum(                             ; Add up all the displacements

9

Python 2, 53 ไบต์

lambda n,l:sum((b-a+n/2)%n-n/2for a,b in zip(l,l[1:]))

คำตอบที่ตรงไปตรงสุด ฉันสงสัยว่ามีวิธีที่สั้นกว่านี้หรือไม่


ฉันพลาดบิตนั้นไป ขอบคุณ
Lynn

@Jakube ฉันทำไปแล้ว - ฉันไม่รู้ที่.:_2จะสร้างคู่จนกระทั่งฉันเห็นคำตอบของคุณ - ฉันใช้รหัสไปรษณีย์
orlp

1
@Jakube ฉันได้มันลงไป 19 :)
orlp

7

Mathematica ขนาด 30 ไบต์

Tr@Mod[Differences@#2,#,-#/2]&

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อซึ่งใช้เวลาสองข้อโต้แย้ง ตัวอย่างการใช้งาน:

Tr@Mod[Differences@#2,#,-#/2]&[3, {0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1}]
(* 4 *)
Tr@Mod[Differences@#2,#,-#/2]&[10, {5, 2, 8, 9, 5}]
(* -10 *)

สิ่งนี้ทำงานโดยการใช้Differencesระหว่างองค์ประกอบที่ต่อเนื่องห่อมันไว้ในช่วง-n/2ที่+n/2มีModและพารามิเตอร์ออฟเซ็ตของมันจากนั้นนำผลรวมด้วยTr(เมทริกซ์ติดตามผลรวมขององค์ประกอบในแนวทแยง)


โปรดทราบว่าแม้ ungolfed เพียง 43 ไบต์!

f[n_, l_] := Total[Mod[Differences[l], n, -n/2]]

@ไม่จำเป็นเมื่อคุณกำลังเรียกใช้ฟังก์ชันด้วยเครื่องหมายวงเล็บเหลี่ยม การมีทั้งคู่เป็นข้อผิดพลาดทางไวยากรณ์
เดวิดจาง

@ DavidZhang อ๊ะไม่รู้ว่าฉันคิดอะไรอยู่ ทำหน้าที่ฉันถูกต้องสำหรับการพยายามที่จะตอบโดยไม่ต้องเปิด Mathematica!
2012rcampion

5

J, 24 ไบต์

[+/@(]-(>-:)~*[)[|2-~/\]

การใช้งาน:

   f=:[+/@(]-(>-:)~*[)[|2-~/\]

   3 f 0 1 2 2 0 1 0 2 1 2 0 1 2 1 1
4

   10 f 5 2 8 9 5
_10

จะพยายามตีกอล์ฟเพิ่มและเพิ่มคำอธิบายหลังจากนั้น

ลองออนไลน์ได้ที่นี่


1
แน่ใจว่ามันไม่ใช่ JAM และ CJam? : P
เครื่องมือเพิ่มประสิทธิภาพ


3

R, 38 ไบต์

function(n,v)sum((diff(v)+n/2)%%n-n/2)

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่รับจำนวนเต็มและเวกเตอร์เป็นอินพุตและส่งกลับจำนวนเต็มเดียว f=function(n,v)...เรียกว่าให้มันชื่อเช่น

คำอธิบาย Ungolfed +:

f <- function(n, v) {
    # Compute the differences between sequential elements of v
    d <- diff(v)

    # Add n/2 to the differences and get the result modulo n
    m <- (d + n/2) %% n

    # Subtract n/2 then sum the vector
    sum(m - n/2)
}

ตัวอย่าง:

> f(3, c(0, 1, 2, 2, 0, 1, 0, 2, 1, 2, 0, 1, 2, 1, 1))
[1] 4

> f(10, c(5, 2, 8, 9, 5))
[1] -10

3

MatLab, 33 ไบต์

@(x,y)sum(mod(diff(y)+x/2,x)-x/2)

คำขอโทษของฉันนี่เป็นคำตอบแรกของฉันในเว็บไซต์นี้ การพิมพ์สิ่งนี้ใน MatLab จากนั้นใช้อินพุตans(modulus_value, [intermediate_values])จะคืนค่าที่ร้องขอโดยที่ 'modulus_value' คือค่าโมดูลัสและ 'ตัวกลาง _values' คือรายการของค่ากลางคั่นด้วยช่องว่างหรือเครื่องหมายจุลภาค

ตัวอย่าง:

ans(3, [0 1 2 2 0 1 0 2 1 2 0 1 2 1 1])

ฟังก์ชั่นที่ไม่ระบุชื่อใช้ประโยชน์จากของ MATLAB mod, diffและsumฟังก์ชั่นการคำนวณคำตอบ ขั้นแรกให้คำนวณความแตกต่างระหว่างค่ากลางแต่ละค่า ผลลัพธ์จะถูกชดเชยด้วยโมดูลัสหารด้วยสองส่งผลให้ชุดของค่าความแตกต่างที่ถูกผูกไว้ด้วย [-modulus / 2 โมดูลัส / 2] ผลลัพธ์จะถูกชดเชยและหาผลรวมอีกครั้ง

ฉันคิดว่านี่สามารถเล่นกอล์ฟได้มากกว่านี้ฉันจะกลับมาอีกครั้งพร้อมกับการอัปเดต ขอขอบคุณเป็นพิเศษกับ @ 2012rcampion สำหรับแนวคิดนี้

แก้ไข:unwrapฟังก์ชั่นของ Matlab เกือบจะใช้งานได้ที่นี่ แต่มันยากที่จะเล่นกอล์ฟ โค้ดต่อไปนี้จะคืนค่าอาเรย์โดยที่ค่าสุดท้ายคือจำนวนเงินที่มีการเปลี่ยนแปลงค่าแรก: @(x,y)unwrap(y/x*2*pi)/2/pi*x-y(1)

ค่ากลางจะถูกปรับสัดส่วนให้อยู่ในช่วงของ [-pi pi] จากนั้น "คลาย" เพื่อไม่ให้มีค่าต่อเนื่องเกินกว่าค่า pi ที่แยกกัน ค่าเหล่านี้จะถูกปรับขนาดและเปลี่ยนใหม่ทำให้เกิดอาร์เรย์ของระยะทางจากค่าเริ่มต้น

น่าสนใจ แต่ไม่เป็นประโยชน์สำหรับความท้าทายนี้: D


2

Pyth, 29 ไบต์

+sm**._K-Fdvz>y.aKvz.:Q2-eQhQ

ลองใช้งานออนไลน์: Pyth Compiler / Executor


อินพุตถูกคั่นด้วยช่องว่างไม่ใช่คั่นด้วยเครื่องหมายจุลภาค ดูเหมือนว่าโปรแกรมของคุณจะจัดการกับสิ่งนี้ไม่ได้
Lynn

2
@Mauris "รายการของค่าในรูปแบบที่คุณเลือก"
Jakube

โอ้ฉันไม่ดี! ฉันพลาดส่วนหนึ่งของสเป็คนั้นโดยสิ้นเชิง
Lynn


2

Pip , 39 ไบต์

Qn$+({a>n/2?a-na<-n/2?a+na}Mg@>1-g@<-1)

ต้องการรายการข้อมูลเป็นอาร์กิวเมนต์บรรทัดคำสั่งและมอดุลัสบน STDIN หากยืดออกมากเกินไปฉันมีเวอร์ชันที่ใช้บรรทัดคำสั่งสองบรรทัดเพิ่มอีก 5 ไบต์

คำอธิบาย:

                                         g is list of cmdline args (implicit)
Qn                                       Read n from stdin
                            g@>1         All but the first of the cmdline args
                                -g@<-1   ...minus all but the last of the cmdline args
                                         (i.e. a list of the differences of adjacent items)
     {                    }M             ...to which, map the following function:
      a>n/2?a-n                            If diff is too big, subtract n;
               a<-n/2?a+n                  else if too small, add n;
                         a                 else return unchanged
  $+(                                 )  Sum; print (implicit)

และเพื่อพิสูจน์ว่าคะแนนที่ไม่ให้การแข่งขันนี้สะท้อนให้เห็นถึงทักษะการเล่นกอล์ฟของฉันมากกว่าภาษาของฉันนี่เป็นพอร์ตของโซลูชัน Python ของ Mauris ใน30 ไบต์ :

Qn$+({(n/2-$-a)%n-n/2}MgZg@>1)

2

เยลลี่ไม่ใช่การแข่งขัน

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

Iæ%H}S

ลองออนไลน์!

มันทำงานอย่างไร

Iæ%H}S    Main link. Left input: A (list). Right input: N (integer).

I         Compute the increments (deltas of consecutive elements) of A.
   H}     Halve the right input (N).
 æ%       Mod the increments into (-N/2, N/2].
     S    Take the sum of all results.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.