Dizi adımlarını alma


17

Meydan okuma

Bir sayı dizisi verildiğinde, dizi adımlarını döndüren bir işlev oluşturun.

  • Bir sekansın N >= 3
  • Sekans en az bir kez tekrarlanır
  • Sıra yalnızca doğal sayılar içerir
  • İşleviniz veya programınız mümkün olan en kısa adım dizisini döndürmelidir

Misal:

Giriş: [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]

Çıktı: [1, 1, 2]

Açıklama: İlk dizi başlar 1 => 2 (1 step), 2 => 3 (1 step), 3 => 5 (2 steps). Sonra tekrar eder. Çıktı daha sonra[1 step, 1 step, 2 steps] => [1, 1, 2]

Başka bir örnek:

Giriş: [2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]

Çıktı: [3, 1, 1, 1]

[2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20]
 \  /\ /\ /\ / 
  3   1  1  1  Then it repeats...

Test Durumları

Input: [1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28] => Output: [3,4,1,1]

Input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] => Output: [5,2]

Input: [2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47] => Output: [4,4,3,4]

Input: [5, 6, 7] => Output: [1]


Açıklamalar

  • Giriş uzunluğu - 1, çıkış uzunluğuna bölünebilir
  • Sıralamanın her zaman artacağını varsayalım

Bu , bu yüzden bayt en kısa cevap kazanmak.



6
Son zamanlarda çok sayıda açıklayıcı yorum yayınladığınız birkaç zorluk gördüm ve bir çift "belirsiz" olarak kapatıldı ve uygun düzenlemeleri yaptıktan sonra tekrar açıldı. Bunları birkaç gün / hafta boyunca kum havuzuna göndermeyi düşündünüz mü ? Oldukça ulaşılabilir oldukları için zorluklarınızdan zevk aldım, ancak ne kadar basit veya kim tarafından yayınlandıklarına bakılmaksızın, tüm zorluklar ayrıntılandırmayı kullanabilir.
Giuseppe

2
@Giuseppe Önerileriniz için teşekkürler. Kum kutusunda başka bazı zorluklar yayınladım (genellikle onunla bir meydan okuma oluşturmak için doğru yolu alamıyorsam siliyorum). Bu zorluklar için yeterince açık olduklarını düşündüm ve bu yüzden hemen yayınladım, ancak önce onları sanal alana göndermeye başlayacağım. Teşekkürler
Luis felipe De jesus Munoz

2
@LuisMendo Heretic! 0 doğal bir sayıdır! Billy Joel'in Peano Man'a adanmış bir albümü bile vardı!
ngm

1
@AdmBorkBork, bu daha çok keyfi uzunluktaki işlem listeleriyle uğraşmakla ilgilidir .
Peter Taylor

Yanıtlar:


10

Jöle , 9 7 bayt

IsJEƇḢḢ

Çevrimiçi deneyin!

Nasıl çalışır

IsJEƇḢḢ  Main link. Argument: A (array)

I        Increment; compute D, the array of A's forward differences.
  J      Indices; yield [1, ..., len(A)].
 s       Split D into chunks of length k, for each k in [1, ..., len(A)].
   EƇ    Comb equal; keep only partitions of identical chunks.
     Ḣ   Head; extract the first matching parititon.
      Ḣ  Head; extract the first chunk.

9

JavaScript (ES6), 58 bayt

Virgülle ayrılmış bir dize (önde gelen virgülle) çıktılar.

a=>(a.map(p=x=>-(p-(p=x)))+'').match(/N((,\d+)*?)\1*$/)[1]

Çevrimiçi deneyin!

Ya 56 bayt Kullandığımız takdirde ,-ayırıcı olarak ve biz dizi her zaman farz kesinlikle artar.

Nasıl?

İlk olarak a [] giriş dizisini aşağıdaki gibi birbirini izleyen farklar listesine dönüştürürüz :

a.map(p = x => -(p - (p = x)))

Çünkü s ilk sayısal olmayan bir değere ayarlanır (geri arama işlevi harita () ), birinci yineleme verir NaN .

Misal:

[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41]
[ NaN, 5, 2, 5, 2, 5, 2, 5, 2, 5, 2 ]

Sonrasında sonucu bir dizeye zorlarız:

"NaN,5,2,5,2,5,2,5,2,5,2"

Son olarak, "NaN" den hemen sonra başlayan ve dizenin sonuna kadar yinelenen en kısa 1 virgülle ayrılmış tamsayı ( ,\d+) deseni ararız:

match(/N((,\d+)*?)\1*$/)

1: açgözlü olmayan kullanma *?


Aynı normal ifade fikrine dayanan, ancak uygulamada çok farklı bir çözüm gönderiyorum. Tabii ki, benimkini geliştirmeden önce diğer çözümlere bakmadım ve yeterince farklı görünüyor, Ve belki de ilk kez sizden daha iyi skor yapmayı başardım.
edc65

1
53 bayt: /(,.+?)\1*$/.
Neil

6

Brachylog , 11 bayt

s₂ᶠ-ᵐṅᵐ~j₍t

Çevrimiçi deneyin!

Ardışık farklılıklar için yerleşik bir 5 olsaydı 5 bayt olurdu.

açıklama

Example input: [6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 

s₂ᶠ             Find all substrings of length 2: [[6,11],[11,13],…,[34,39],[39,41]]
   -ᵐ           Map subtraction: [-5,-2,-5,-2,-5,-2,-5,-2,-5,-2]
     ṅᵐ         Map negate: [5,2,5,2,5,2,5,2,5,2]
       ~j₍      Anti-juxtapose the list of differences; the shortest repeated list is found
                  first, with the biggest number of repetitions: [5,[5,2]]
            t   Tail: [5,2]

Bir bayt kurtarmak için kuyruktan sonra olumsuzlanabilir misiniz?
Rod

@Rod Hala haritaya ihtiyacım olacak, bu yüzden aynı uzunlukta olacaktı. Negate iki sayı arasındaki bir yüklemdir, diğer diller gibi listelere otomatik olarak vektörleştirmez (aksi takdirde bildirim programlarında yaygın olarak bilinen bilinmeyen giriş / çıkışlarla iyi çalışmaz)
18'de

5

Pyth, 11 bayt

<J.+Qf.<IJT

Burada deneyin

açıklama

<J.+Qf.<IJT
 J.+Q          Call the sequence of differences in the input J.
     f         Find the first positive integer T...
      .<IJT    ... where rotating J by T doesn't change it.
<J             Take that many elements of J.

5

Japt , 14 12 bayt

äa
¯@eUéX}aÄ

Dene


açıklama

              :Implicit input of array U
äa            :Consecutive absolute differences
\n            :Reassign to U
 @    }aÄ     :Return the first positive integer X that returns true
   UéX        :  Rotate U right X times
  e           :  Check equality with U
¯             :Slice U to that element

orijinal

äa
@eUîX}a@¯XÄ

Dene


5

R , 49 46 bayt

Tam program:

d=diff(scan());while(any((s=d[1:T])-d))T=T+1;s

Çevrimiçi deneyin!

R , 72 58 54 bayt

Tüm test senaryoları ile tek bir yerde orijinal işlev sunumu:

function(a,d=diff(a)){while(any((s=d[1:T])-d))T=T+1;s}

Çevrimiçi deneyin!

Tam program rotasını önerdiği için JayCe'ye ve işlev üzerindeki -4 bayt'a ve -3 için de Giuseppe'ya teşekkürler.



@JayCe de a<-burada gerek yok
Giuseppe

4

J , 22 19 bayt

FrownyFrog sayesinde 3 bayt kurtarıldı!

0{"1[:~./:|."{}.-}:

Çevrimiçi deneyin!

[Çevrimiçi deneyin!] [TIO-ji2uiwla]

Nasıl?

                 -      find the successive differences by subtracting 
                  }:    the list with last element dropped
               }.       from the list with the first element dropped 
           |."{         rotate the list of differences
         /:             0..length-1 times (the input graded up)
     [:~.               remove duplicating rows
 0{"1                   take the first element of each row

Eğer /:yerine #\, yapabilecekleriniz 0{"1[:~.1 byte kaydedin.
FrownyFrog

And "0 1is"{
FrownyFrog

@FrownyFrog Tekrar teşekkürler!
Galen Ivanov

1
bu muhteşem.
Jonah

@Jonah Evet, FrownyFrog sayesinde!
Galen Ivanov

4

05AB1E , 8 bayt

Kevin Cruijssen sayesinde 3 bayt kurtardı .

¥.œʒË}нн

Çevrimiçi deneyin!


05AB1E , 11 bayt

āεI¥ô}ʒË}нн

Çevrimiçi deneyin!

programI ¥ ô} ʒË} нн Tam program.
ā Uzunluk aralığı. [1 ... len (inp)] düğmesine basın.
 each} Her biri için ...
  I ¥ ô ... Deltaları ilgili büyüklükteki parçalara ayırın
      only} Yalnızca tüm öğelerini eşit tutanları saklayın.
         нн İlk önce ilk elemanını alın.

13 bayt

Sevimli bir alternatif, IMO:

¥©ηʒDg®ôÙ˜Q}н

Çevrimiçi deneyin!

¥©ηʒDg®ôÙ˜Q}н   Full program.
¥               Push the deltas.
 ©              Copy them to the register.
  ηʒ       }    And filter the prefixes by...
    D     Q     ... Is the prefix itself equal to...
     g®ô        ... The deltas, split into chunks of its length...
        Ù˜      ... Deduplicated and flattened?
            н   Head.

1
Kullanarak 8 bayt .
Kevin Cruijssen

3

Javascript, 49 56 bayt

Düzenle 7 bayt kurtardı teşekkürler (tahmin et kim?) Arnauld

Arnauld ile aynı normal ifade fikri, ama uygulamada merakla çok farklı ...

Adımlar virgülle ayrılmış bir dize döndürme (ve önde gelen virgül)

p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

Ölçek

var F=
p=>/N(.+?)\1+$/.exec(p.map(p=v=>[v-p,p=v][0]))[1]

;[[1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17]
,[1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28]
,[6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41] 
,[2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47]
,[5, 6, 7]]
.forEach(x=>console.log(x + ' -> ' + F(x)))


Kullanmak matchkötü bir kararımdı. Bana biraz daha fazla izin verebilirsin . :-)
Arnauld

3

MATL , 14 13 12 bayt

dt5YLFTF#Xu)

Çevrimiçi deneyin!

MATL'nin bir sirkülasyon fonksiyonuna sahip olduğunu keşfettim!

açıklama

d - Ardışık terimler arasındaki farkları bir dizi olarak alın

t5YL- kopyalayın, ardından ('sirkülasyon') seçeneği YLile 5(' galeri') işlevini çağırın . İlk satır olarak verilen vektörle bir matris oluşturur, ardından ardışık satırlar, etrafına sarılana kadar dairesel olarak kaydırılan aynı vektördür.

FTF#Xu- Benzersiz satırları kontrol edin ve satır numaralarını alın (bunu yapmanın daha kısa bir yolu olup olmadığından emin değilim). Dizi adımları tekrarlandığında, dairesel olarak kaydırılan satır ilk satırla aynı olur ve sonraki satırlar tekrarlanır. Bu, tekrarlamaya başlamadan önce dizi adımlarının ilk çalışmasının indekslerini alır.

) - cevabı almak için orijinal farklılıklar dizisine kullanarak dizin.


Daha eski:

d`tt@YS-a}@:)

Çevrimiçi deneyin!

(Giuseppe sayesinde -1 bayt)

Açıklama:

d   % Get the differences between successive terms, as an array
`   % Start do-while loop
  tt  % duplicate the difference array twice
  @   % push the current loop index value
  YS  % circularly shift the difference array by that amount
  -   % subtract the shifted diffs from the original diffs
  a   % see if the subtraction resulted in any non-zeros
    % if it did, shifted differences were not equal to original differences, so continue loop 
}@ % if it didn't, then get loop index
:) % get the differences upto the loop index, before they started repeating
   % implicit loop end

2

Python 2 , 101 bayt

def f(l):d=[y-x for x,y in zip(l,l[1:])];g=len(l);print[d[:k]for k in range(1,g+1)if g/k*d[:k]==d][0]

Çevrimiçi deneyin!

İlk delta oluşturur d daha sonra birinci ön ek bulur, p ve d tekrarlanan bu (L) ⌊len / len (p) ⌋ kez verimleri L , L giriş listesidir.



2

Java 10, 104100 bayt

a->{var t="";for(int i=a.length;i-->1;t+=a[i]-a[i-1]+" ");return t.replaceAll("( ?.+?)\\1*$","$1");}

Regex ( ?.+?)\1*$kısa için gelen alt dize yinelenen @Neil 'hakkında yaptığı yorum @Arnauld s JavaScript (ES6) yanıt' .

Çevrimiçi deneyin.

Açıklama:

a->{                        // Method with integer-array parameter and String return-type
  var t="";                 //  Temp-String, starting empty
  for(int i=a.length;i-->1; //  Loop backward over the input-array, skipping the first item
    t+=a[i]-a[i-1]          //   Calculate the difference between two adjacent items
       +" ");               //   And append this with a space to the temp-String
  return t.replaceAll("( ?.+?)\\1*$", 
                            //  Find the shortest repeating substring
                     "$1");}//  And only keep one such substring

1

APL + WIN, 39 bayt

Giriş istemi.

(↑((⍴v)=+/¨(⊂v)=(⍳⍴v)⌽¨⊂v)/⍳⍴v)↑v←-2-/⎕

Çevrimiçi deneyin! Dyalog Classic'in izniyle

Açıklama:

v←-2-/⎕ Prompt for input and take successive differences

(⍳⍴v)⌽¨⊂v create a nested vector ans sequentially rotate by one to length of v

+/¨(⊂v)= compare to original v and sum positions where there is match

(⍴v)= identify where all elements match

(↑(....) identify number of rotations giving a first complete match

(↑(...)↑v take first number of elements from above from v as repeated sequence

1

Python 2 , 86 85 bayt

def f(a,n=1):d=[y-x for x,y in zip(a,a[1:])];return d[:-n]==d[n:]and d[:n]or f(a,n+1)

Çevrimiçi deneyin!

Farklılıkları şu şekilde yapılandırın d; Eğer dbirim boyutuna sahip tekrarlar ndaha sonra d[n:]==d[:-n]; başka bir çare.


1

Retina 0.8.2 , 42 bayt

\d+
$*
(?<=(1+),)\1

1+(.+?)\1*$
$1
1+
$.&

Çevrimiçi deneyin! Bağlantı, test senaryolarını içerir. Çıktı önde gelen virgül içerir. Açıklama:

\d+
$*

Tekli'ye dönüştür.

(?<=(1+),)\1

Geride kalan ilk sayı hariç, ileriye doğru farklılıkları hesaplayın.

1+(.+?)\1*$
$1

Tekrarlanan farklılıkları eşleştirin.

1+
$.&

Ondalık biçime dönüştür.


1

05AB1E , 14 13 bayt

¥DηvÐNƒÁ}QD—#

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

@ Mr.Xcoder tarafından gönderilen iki kısa 05AB1E yanıtı olduğunu biliyorum , ancak rotasyon ve eşitlik kontrolünü kullanarak bu alternatif yaklaşımı denemek istedim.
Düşmeden birkaç bayt aşağı golf olabilir Á.

@Emigna'nın bir ucundan sonra -1 bayt global_variable kayıtlarını ( ©ve 2x ®) kaldırmak ve bunun yerine bir Duplicate ( D) ve Triplicate ( Ð) kullanmak.

Açıklama:

¥             # Calculate the deltas of the input-array
              #  i.e. [1,2,3,5,6,7,9] → [1,1,2,1,1,2]
 D            # Duplicate it
  η           # Push all its prefixes
              #  [1,1,2,1,1,2] → [[1],[1,1],[1,1,2],[1,1,2,1],[1,1,2,1,1],[1,1,2,1,1,2]]
v             # For-each over these prefixes
 Ð            #  Triplicate the (duplicated) deltas-list
  NƒÁ}        #  Rotate the deltas-list N+1 amount of times,
              #  where N is the prefix index (== prefix_length-1)
              #   i.e. [1,1,2] and [1,1,2,1,1,2] (rotate 3 times) → [1,1,2,1,1,2]
      Q       #  If the rotated deltas and initial deltas are equal
              #   [1,1,2,1,1,2] and [1,1,2,1,1,2] → 1
       D—#    #  Print the current prefix-list, and stop the for-each loop

1
İşte 9 (¥ η paylaşmasına rağmen, çok farklı bir algo olduğu için ayrı bir cevap).
Grimmy

@Grimy Tüm 05AB1E cevaplarımdan geçiyor ve her birini golf oynuyor musunuz? ; p Yine de güzel bir cevap (yine), benden +1.
Kevin Cruijssen

1
Hepsi değil, sadece bu yazıda bağlantılı olanlardan geçiyorum .
Grimmy

@Grimy Ah tamam, bu mantıklı. :)
Kevin Cruijssen

1

Haskell, 107 bayt

let i=map(uncurry(-))$zip(tail x)(init x)in head$filter(\s->take(length i)(concat$repeat s)==i)(tail$inits i)

x girdi dizisidir.


Özellikle PPCG ve Haskell golf hoş geldiniz! Girdinin belirli bir değişkende var olduğunu varsayamazsınız, ancak bu, önceden eklenerek kolayca düzeltilebilir f x=. Ayrıca, Prelude'un bir parçası olmadığı için kullanımı initsgerekir import Data.List: Çevrimiçi deneyin!
Laikoni

However you can save quite a few bytes: (init x) can just be x because zip truncates automatically if one of the lists is longer than the other one. And for map(uncurry(-))$zip exists an build-in: zipWith(-). Instead of f x=let i=...in you can use a pattern guard: f x|i<-...=.
Laikoni

Furthermore you can use a list comprehension instead of filter, !!0 instead of head and cycle instead of concat$repeat: Try it online!
Laikoni

@Laikoni Thanks a lot for your improvements! You are right, my code needs a function declaration and an import for Data.List.inits. But I was wondering, should that be added to the length of the code? I'm asking because some of the other code samples rely on some extra code as well.
misja111

Yes, it is general consensus that those bytes are included in the score. We have a guide to golfing rules in Haskell which covers most of these cases.
Laikoni

1

Stax, 8 6 bytes

░»F\☺»

Run and debug it

Here's an unpacked annotated version to show how it works.

:-  pairwise differences
:(  all leftward rotations of array
u   keep only unique rotations
mh  output the first element from each unique rotation

Run this one


1

Perl 6, 57 bytes

{~(.rotor(2=>-1).map:{.[1]-.[0]})~~/^(.+?){}" $0"+$/;~$0}

Test it

Output is space separated ("1 1 2")

Expanded:

{      # bare block lambda with implicit parameter $_

  ~(   # stringify (space separated)

    .rotor( 2 => -1 )     # from the input take 2 backup 1, repeat
    .map: { .[1] - .[0] } # subtract each pair to find the differences
  )

  ~~   # smartmatch

  /    # regex

    ^  # beginning of string

    ( .+? ) # match at least one character, but as few as possible
    {}      # make sure $0 is set (probably a compiler bug)
    " $0"+  # match $0 one or more times (with a leading space)

    $  # end of string
  /;

  ~$0  # return the stringified $0
}

The whole first part can be ~(.skip Z-$_)
Jo King

1

05AB1E, 9 bytes

¥©η.ΔÞ®Å?

Explanation:

          # take input implicitly
¥         # deltas, eg [4, 5, 7, 8, 10] -> [1, 2, 1, 2]
 ©        # save this to the global register
  η       # prefixes, eg [1, 2, 1, 2] -> [[1], [1, 2], ...]
   .Δ     # find the first one such that
     Þ    # cycled infinitely, eg [1, 2] -> [1, 2, 1, 2, ...]
       Å? # starts with
      ®   # the global register
          # and implicitly print the found element

Alternative 9-byte:

¥η.ΔÞ.¥-Ë

Same algo, but instead of comparing to the list of deltas (which needs to be saved/restored), this uses (undelta) then compares to the (implicit) input.

Try it online!


0

K4, 30 bytes

Solution:

(*&d~/:c#'(!c:#d)#\:d)#d:1_-':

Examples:

q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 5, 6, 7, 8, 11, 12, 13, 14, 17, 18, 19, 20
3 1 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17
1 1 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':1, 4, 8, 9, 10, 13, 17, 18, 19, 22, 26, 27, 28
3 4 1 1
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':6, 11, 13, 18, 20, 25, 27, 32, 34, 39, 41
5 2
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':2, 6, 10, 13, 17, 21, 25, 28, 32, 36, 40, 43, 47
4 4 3 4
q)k)(*&d~/:c#'(!c:#d)#\:d)#d:1_-':5 6 7
,1

Explanation:

Seems hefty for what we're trying to solve. Get the deltas of the input and then build sequences and determine the shortest one that matches it.

(*&d~/:c#'(!c:#d)#\:d)#d:1_-': / the solution
                           -': / deltas 
                         1_    / drop first
                       d:      / save as d
                      #        / take (#) from
(                    )         / do this together
                 #\:d          / take (#) each-left (\:) from d
          (     )              / do this together
              #d               / count length of d
            c:                 / save as c
           !                   / range 0..c-1
       c#'                     / take c copies of each
   d~/:                        / d equal (~) to each right (/:)
  &                            / where true
 *                             / first one


0

Perl 5 -p, 55 bytes

s/\d+ (?=(\d+))/($1-$&).$"/ge;s/\d+$//;s/^(.+?)\1*$/$1/

Try it online!

Numbers are input as a space separated list. Output is the same format.

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.