Mesafelerin hesaplanması mod N


13

Uzun zamandır bir Gelişmiş Toplama Cihazı Denetleyicisi ™' nden veri topluyorsunuz . Günlükleri kontrol edersiniz ve dehşetinize göre bir şeyin çok yanlış gittiğini fark edersiniz: veriler sadece sayıların son bitlerini içerir!

Neyse ki, başlangıç ​​değerini biliyorsunuz ve değerin asla hızlı değişmediğini biliyorsunuz. Bu, en başından itibaren mesafeyi bularak geri kalanını kurtarabileceğiniz anlamına gelir.

Meydan okuma

Bir modül Nve ara değerler modulo listesi verildiğinde, bir değerin değiştiği miktarı hesaplamak için bir program veya işlev yazacaksınız N.

Her sayı çifti arasındaki değişim her zamankinden daha azdırN/2 , bu nedenle her test durumu için yalnızca bir geçerli cevap olacaktır.

İstediğiniz Nformatta bir tamsayı > 2 ve bir değerler listesi gireceksiniz. Giriş STDIN veya komut satırı veya işlev bağımsız değişkenleri aracılığıyla verilebilir.

Orijinal değerin değiştiği miktar olan tek bir tam sayı çıktısı alırsınız. Çıktı STDOUT'a yazdırılabilir veya iade edilebilir.

kurallar

  • Programınız herhangi bir mesafe ve katsayı için çalışmalıdır 2^20.
  • Şunu varsayabilirsiniz:
    • Nen azından 3.
    • Listede en az 2 değer var.
    • Listedeki tüm değerler en az 0 ve daha küçüktür N.
    • Rakamlardaki tüm değişiklikler küçüktür N/2.
  • Başka bir şey geçersiz bir girdidir ve programınız istediği her şeyi yapabilir.
  • Bu boşluk için standart boşluklar, standart olmayan kütüphaneler ve yerleşik fonksiyonlar yasaktır.
  • Bu , bu yüzden bayttaki en kısa program kazanır.

Örnek test örnekleri

Giriş:

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

Çıktı:

4

Açıklama (örnek değerle):

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

Giriş:

10
5 2 8 9 5

Çıktı:

-10

Açıklama (örnek değerle):

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

Geçersiz girişler:

2
0 0 0 0 0

(çok küçük modül)

6
2 5 4 2

(2 ile 5 arasında çok büyük değişiklik)


Seçtiğiniz bir format kaygan bir eğimdir. GolfScript çözümüm aşağıdaki gibi bir girdi listesine dayanabilir :^;[5 2 8 9 5](\ mi?
Lynn

3
@Mauris Genel olarak, hayır ... "seçtiğiniz bir biçim" genellikle "seçtiğiniz dilde geleneksel bir temsil" anlamına gelir.
Martin Ender

Bununla birlikte, "10 5 2 8 9 5" veya "10,5 2 8 9 5" veya "10 5,2,8,9,5" gibi görünen giriş listesine güvenebilirsiniz.
Sparr

Yanıtlar:


2

TI-BASIC, 15 bayt

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

Listeyi Ansve modülü alır Input.

                       π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 bayt

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

Süper düz ileri cevap. Daha kısa bir yol olup olmadığını merak ediyorum.


Biraz özledim. Teşekkürler.
Lynn

@ Jakube Zaten yaptım - .:_2Cevabınızı görene kadar çift oluşturmanın farkında değildim - Zip kullanıyordum.
orlp

1
@Jakube 19'a
indirdim

7

Mathematica, 30 bayt

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

Bu iki argüman alan anonim bir fonksiyondur. Örnek kullanım:

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 *)

Bu alarak çalışır Differencesaralığına sarılarak, birbirini takip eden elemanlar arasında -n/2hiç +n/2ile Moddaha sonra toplam alma, ve ofset parametre Tr(matris iz, çapraz elementlerin toplamı).


Yasadışı bile olsa sadece 43 bayt olduğunu unutmayın!

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

@işlevi köşeli parantezle çağırdığınızda gereksizdir. Her ikisine de sahip olmak bir sözdizimi hatasıdır.
David Zhang

@DavidZhang Hata! Ne düşündüğümü bilmiyorum. Mathematica'yı açmadan cevap vermeye çalıştığım için bana doğru hizmet veriyor!
2012rampiyon

5

J, 24 bayt

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

Kullanımı:

   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

Daha fazla golf yapmaya çalışacak ve bundan sonra biraz açıklama ekleyeceğiz.

Burada çevrimiçi deneyin.


1
CJ'nin değil J'nin olduğundan emin misiniz? : P
Doktor

4

Pyth, 20 19 bayt

sm-J/Q2%+-FdJQ.:vw2

Stole .:_2Jakube, Mauris gelen fikirden.


3

R, 38 bayt

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

Bu, tamsayı ve vektörü girdi olarak kabul eden ve tek bir tamsayı döndüren adsız bir işlev oluşturur. Bunu aramak için bir ad verin, örn f=function(n,v)....

Ungolfed + açıklaması:

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)
}

Örnekler:

> 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 bayt

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

Özür dilerim, bu web sitesindeki ilk cevabım. Bunu ans(modulus_value, [intermediate_values])MatLab'a yazdıktan sonra girdiyi kullanmak istediğiniz değeri döndürür; burada 'modulus_value' modül katsayısı değeridir ve 'medium_values', boşluk veya virgülle ayrılmış ara değerlerin bir listesidir.

Misal:

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

Anonim işlev Matlab'ı en yararlanır mod, diffve sumcevap hesaplamak için fonksiyonlar. İlk olarak, ara değerlerin her biri arasındaki fark hesaplanır. Sonuç daha sonra modülün ikiye bölünmesiyle dengelenir ve sonuç olarak [modül / 2 modül / 2] ile bağlanan bir dizi fark değeri elde edilir. Sonuç daha sonra dengelenir ve tekrar toplanır.

Bu daha golf olabilir düşünüyorum, ben yakında bir güncelleme ile döneceğim. Fikir için @ 2012rcampion'a özel teşekkürler.

Düzenleme: Matlab'ın unwrapişlevi neredeyse burada çalışıyor, ancak golf zor. Aşağıdaki kod, son değerin ilk değerin değiştirdiği miktar olduğu bir dizi döndürür: @(x,y)unwrap(y/x*2*pi)/2/pi*x-y(1)

Ara değerler [-pi pi] aralığına ölçeklendirilir, ardından ardışık değer pi'den fazla olmayacak şekilde "sarılmamış" olur. Bu değerler daha sonra yeniden ölçeklendirilir ve kaydırılır, bu da başlangıç ​​değerinden bir dizi uzaklığa neden olur.

İlginç, ancak bu meydan okuma için çok pratik değil: D


2

Pyth, 29 bayt

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

Çevrimiçi deneyin: Pyth Derleyici / Yönetici


Giriş boşlukla ayrılmıştır, virgülle ayrılmamıştır; programınız bunu ele almıyor gibi görünüyor.
Lynn

2
@Mauris "istediğiniz formatta bir değer listesi"
Jakube

Ah benim hatam! Spesifikasyonun bu kısmını tamamen kaçırdım.
Lynn


2

Pip , 39 bayt

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

Komut satırı argümanları olarak veri listesini ve STDIN üzerindeki modülü gerektirir. Bu çok fazla bir gerginlik varsa, 5 bayt daha fazla iki komut satırı argümanı alan bir sürümüm var.

Açıklama:

                                         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)

Ve sadece bu kadar rekabetçi olmayan puanın golf becerilerime kendi dilimden daha fazla yansıtıcı olduğunu kanıtlamak için, Mauris'in Python çözümünün 30 baytlık bir limanı :

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

2

Jöle , rakipsiz

6 bayt Zorluk Jelly'nin yaratılmasından önce geldiğinden bu cevap rakipsizdir.

Iæ%H}S

Çevrimiçi deneyin!

Nasıl çalışır

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.
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.