Thanos sıralama algoritmasını uygulayın


93

Sıralama algoritması şöyle gider:

Liste sıralanmamışken tüm öğelerin yarısını hizalayın (listeden kaldırın). Liste sıralanana veya yalnızca bir öğe kalana kadar devam edin (varsayılan olarak sıralanır). Bu sıralama algoritması, uygulamaya bağlı olarak farklı sonuçlar verebilir.

Öğe kaldırma prosedürü karar verecek uygulamaya bağlıdır, ancak listenin bir öğe kaldırma prosedüründen geçtikten sonraki sürenin yarısı kadar olması gerekir. Algoritmanız, ilk yarıyı veya listeyi, listenin son yarısını, tüm tek öğeleri, hatta tüm öğeleri, listenin yarısı kadar olana veya birinden bahsedilmeyene kadar bir kerede kaldırmaya karar verebilir.

Giriş listesi yalnızca 2 ^ öğenin mükemmel şekilde bölünebilir listelerini değil, isteğe bağlı miktarda öğe içerebilir (gerekçede 1000'e kadar diyelim). Çalışma zamanı sırasında liste garip, kodlanmış veya rasgele karar verilmişse (n + 1) / 2 veya (n-1) / 2 öğelerini kaldırmanız gerekir. Kendinize karar verin: evren tuhaf miktarda canlılar içeriyorsa Thanos ne yapar?

Hiçbir öğe önceki öğeden daha küçük değilse, liste sıralanır. Çoğaltmalar girişte oluşabilir ve çıktıda oluşabilir.

Programınız bir tamsayı dizisi almalıdır (stdin veya parametreler olarak, tek tek öğeler veya bir dizi parametresi) ve sıralanan diziyi döndürmelidir (veya stdout'a yazdırmalıdır).

Örnekler:

// A sorted list remains sorted
[1, 2, 3, 4, 5] -> [1, 2, 3, 4, 5]

// A list with duplicates may keep duplicates in the result
[1, 2, 3, 4, 3] -> [1, 3, 3] // Removing every second item
[1, 2, 3, 4, 3] -> [3, 4, 3] -> [4, 3] -> [3] // Removing the first half
[1, 2, 3, 4, 3] -> [1, 2] // Removing the last half

[1, 2, 4, 3, 5] farklı sonuçlar verebilir:

// Removing every second item:
[1, 2, 4, 3, 5] -> [1, 4, 5]

veya:

// Removing the first half of the list
[1, 2, 4, 3, 5] -> [3, 5] // With (n+1)/2 items removed
[1, 2, 4, 3, 5] -> [4, 3, 5] -> [3, 5] // With (n-1)/2 items removed

veya:

// Removing the last half of the list
[1, 2, 4, 3, 5] -> [1, 2] // With (n+1)/2 items removed
[1, 2, 4, 3, 5] -> [1, 2, 4] // With (n-1)/2 items removed

veya:

// Taking random items away until half (in this case (n-1)/2) of the items remain
[1, 2, 4, 3, 5] -> [1, 4, 3] -> [4, 3] -> [4]

Birden fazla farklı yapışma algoritması için birden fazla enstantane gerektiren bir test senaryosuna sahip olmak çok yararlı olacaktır.
İlişkisi Olmayan Dize

22
Cevapların yarısını
ayırıp yok etmemize

4
Önerilen test durumu: [9, 1, 1, 1, 1]. Bu algoritmada kendi algoritmam başarısız oldu
Conor O'Brien,

Yanıtlar:





12

Brachylog (v2), 6 bayt

≤₁|ḍt↰

Çevrimiçi deneyin!

Bu bir işlev sunumu. Soldan giriş, her zamanki gibi sağdan çıkış. (TIO bağlantısı, işlevi otomatik olarak tam bir programa sararken bir komut satırı argümanı kullanır, böylece eylemde görebilirsiniz.)

açıklama

≤₁|ḍt↰
≤₁       Assert that {the input} is sorted {and output it}
  |      Handler for exceptions (e.g. assertion failures):
   ḍ     Split the list into two halves (as evenly as possible)
    t    Take the last (i.e. second) half
     ↰   Recurse {and output the result of the recursion}

Bonus turu

≤₁|⊇ᵇlᵍḍhtṛ↰

Çevrimiçi deneyin!

Çıtçıt rastgele olmalı, değil mi? İşte hayatta kalan unsurları rastgele seçen programın bir versiyonudur (bu yarının her turda hayatta kalmasını sağlarken).

≤₁|⊇ᵇlᵍḍhtṛ↰
≤₁            Assert that {the input} is sorted {and output it}
  |           Handler for exceptions (e.g. assertion failures):
   ⊇ᵇ         Find all subsets of the input (preserving order)
     lᵍ       Group them by length
       ḍht    Find the group with median length:
         t      last element of
        h       first
       ḍ        half (split so that the first half is larger)
          ṛ   Pick a random subset from that group
           ↰  Recurse

Elemanları yeniden düzenleyebilseydik bu daha kısa olurdu, ama neden bir sıralama algoritması bunu yapmak istesin ki ?


12
Sonsuzluk taşı başına bir bayt.
djechlin

@djechlin sonsuzluk baytı neden baş ve özellikle çene için gitmeniz gerektiğidir.
Büyük Ördek

10

Perl 6 , 30 bayt

$!={[<=]($_)??$_!!.[^*/2].&$!}

Çevrimiçi deneyin!

Liste sıralanana kadar listenin ikinci yarısını kaldıran özyinelemeli işlev.

Açıklama:

$!={                         }    # Assign the function to $!
    [<=]($_)??                    # If the input is sorted
              $_                  # Return the input
                !!                # Else
                  .[^*/2]         # Take the first half of the list (rounding up)
                         .&$!     # And apply the function again


8

Java 10, 106 97 bayt

L->{for(;;L=L.subList(0,L.size()/2)){int p=1<<31,f=1;for(int i:L)f=p>(p=i)?0:f;if(f>0)return L;}}

@ OlivierGrégoire sayesinde 9 bayt .

Çevrimiçi deneyin.

Her yinelemede yalnızca listenin ilk yarısını bırakın ve kaldırırn+12

Açıklama:

L->{               // Method with Integer-list as both parameter and return-type
  for(;;           //  Loop indefinitely:
      L=L.subList(0,L.size()/2)){
                   //    After every iteration: only leave halve the numbers in the list
    int p=1<<31,   //   Previous integer, starting at -2147483648
        f=1;       //   Flag-integer, starting at 1
    for(int i:L)   //   Inner loop over the integer in the list:
      f=p>(p=i)?   //    If `a>b` in a pair of integers `a,b`:
         0         //     Set the flag to 0
        :          //    Else (`a<=b`):
         f;        //     Leave the flag the same
    if(f>0)        //   If the flag is still 1 after the loop:
      return L;}}  //    Return the list as result

n->{for(;n.reduce((1<<31)+0d,(a,b)->a==.5|b<a?.5:b)==.5;n=n.skip(n.count()/2));return n;} akışları kullanarak daha kısa, ancak java.lang.IllegalStateException: stream has already been operated upon or closedakışı geri döndürdükten sonra hatanın nasıl önleneceğini
çözemedim

@Emodimentofungnorance bu olur çünkü reduceakımı kapatan bir terminal operasyonu Hiç aramak mümkün olmayacaktır reduceaynı akışta iki kez. Yine de yeni bir akış oluşturabilirsiniz.
Olivier Grégoire


@ OlivierGrégoire Bu sıra şimdi çok basit görünüyor, onu görüyorum. Bazen, başlangıçta sanırım özlediğim bariz diğerlerini görmek bazen başka bir açıdan bakar. :) Teşekkürler!
Kevin Cruijssen

1
Endişeye gerek yok, apaçık belli değildi: Oraya ulaşmak için çalıştım. Bunu bulmadan önce en az 10 versiyon test ettim;)
Olivier Grégoire


7

JavaScript (ES6),  49  48 bayt

@Tsh sayesinde 1 bayt kaydedildi

Her 2. öğeyi kaldırır.

f=a=>a.some(p=c=>p>(p=c))?f(a.filter(_=>a^=1)):a

Çevrimiçi deneyin!


p++&1->a^=1
tsh


6

05AB1E , 8 7 bayt

[Ð{Q#ιн

@Emigna sayesinde -1 bayt .

Her yineleme işleminde tüm 0 dizinli öğeleri kaldırır, böylece kaldırırn12

Çevrimiçi deneyin veya bazı test durumlarını doğrulayın (veya her yineleme için adım adım test testlerini doğrulayın ).

@Grimy'den 7 byte alternatif :

ΔÐ{Ê>äн

Son kaldırırn2n12

Çevrimiçi deneyin veya bazı test durumlarını doğrulayın (veya her yineleme için adım adım test testlerini doğrulayın ).

Açıklama:

[        # Start an infinite loop:
 Ð       #  Triplicate the list (which is the implicit input-list in the first iteration)
  {Q     #  Sort a copy, and check if they are equal
    #    #   If it is: Stop the infinite loop (and output the result implicitly)
  ι      #  Uninterweave: halve the list into two parts; first containing all even-indexed
         #  items, second containing all odd-indexed items (0-indexed)
         #   i.e. [4,5,2,8,1] → [[4,2,1],[5,8]]
   н     #  And only leave the first part

Δ        # Loop until the result no longer changes:
 Ð       #  Triplicate the list (which is the implicit input-list in the first iteration)
       #  Sort a copy, and check if they are NOT equal (1 if truthy; 0 if falsey)
    >    #  Increase this by 1 (so 1 if the list is sorted; 2 if it isn't sorted)
     ä   #  Split the list in that many parts
      н  #  And only leave the first part
         # (and output the result implicitly after it no longer changes)

3
Diğer tüm element stratejilerini tutmaya geçerseniz ιyerine kullanabilirsiniz .
Emigna

1
Alternatif 7 "son yarıyı kaldır" stratejisini kullanarak:ΔÐ{Ê>äн
Grimy

@Grimy Bu da oldukça hoş bir yaklaşım. Yazıma ekleyeyim mi (elbette sizi alacak), yoksa ayrı bir cevap olarak mı göndermek istiyorsunuz?
Kevin Cruijssen

Eklemek için çekinmeyin.
Grimy

6

TI-BASIC (TI-84), 47 42 45 44 bayt

@SolomonUcko! İle -1 bayt teşekkürler!

Ans→L1:Ans→L2:SortA(L1:While max(L1≠Ans:iPart(.5dim(Ans→dim(L2:L2→L1:SortA(L1:End:Ans

Giriş listesi içeride Ans.
Çıktı Ansiçeride ve dolaylı olarak yazdırılıyor.

Açıklama:

Ans→L1                  ;store the input into two lists
Ans→L2
SortA(L1                ;sort the first list
                        ; two lists are needed because "SortA(" edits the list it sorts
While max(L1≠Ans        ;loop until both lists are strictly equal
iPart(.5dim(Ans→dim(L2  ;remove the latter half of the second list
                        ; removes (n+1)/2 elements if list has an odd length
L2→L1                   ;store the new list into the first list (updates "Ans")
SortA(L1                ;sort the first list
End
Ans                     ;implicitly output the list when the loop ends

Not: TI-BASIC belirtilmiş bir dildir. Karakter sayısı bayt sayısına eşit değil .


Bir bayt kurtarmak için not(min(L1=Ansile değiştirebilirsiniz max(L1≠Ans.
Solomon Ucko



3

Oktav , 49 bayt

l=input('');while(~issorted(l))l=l(1:2:end);end;l

Çevrimiçi deneyin! Bu, daha sıkılmanın daha iyi olduğu bir yolculuktu. Aşağıdaki çok daha ilginç iki girişi not edin:

50 bayt

function l=q(l)if(~issorted(l))l=q(l(1:2:end));end

Çevrimiçi deneyin! İlginç olmayan zorunlu çözüm yerine, yalnızca bir ek bayt için özyinelemeli bir çözüm yapabiliriz.

53 bayt

f(f=@(g)@(l){l,@()g(g)(l(1:2:end))}{2-issorted(l)}())

Çevrimiçi deneyin! Evet. Bir özyinelemeli anonim işlev, @ ceilingcat en sayesinde parlak cevap benim üzerinde soru. Argüman listesinde kendini tanımlayarak özyinelemeli anonim bir işlev döndüren adsız bir işlev. İsimsiz fonksiyonları severim. Mmmmm.


2

MATL , 11 bayt

tv`1L)ttS-a

Çevrimiçi deneyin!

Bu, her ikinci öğeyi kaldırarak çalışır.

açıklama

t      % Take a row vector as input (implicit). Duplicate
v      % Vertically concatenate the two copies of the row vector. When read with
       % linear indexing (down, then across), this effectively repeats each entry
`      % Do...while
  1L)  %   Keep only odd-indexed entries (1-based, linear indexing)
  t    %   Duplicate. This will leave a copy for the next iteration
  tS   %   Duplicate, sort
  -a   %   True if the two arrays differ in any entry
       % End (implicit). A new iteration starts if the top of the stack is true
       % Display (implicit). Prints the array that is left on the stack

2
İlk sıralananlar listesi için kırılmış: [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] olarak kalmalı
Falco

@ Foco Teşekkürler! Şimdi düzeltildi
Luis Mendo

2

Japt , 10 bayt

eUñ)?U:ßUë

Dene

eUñ)?U:ßUë     :Implicit input of array U
e              :Compare equality with
 Uñ            :  U sorted
   )           :End compare
    ?U:        :If true then return U else
       ß       :Run the programme again with input
        Uë     :  Every second element of U



2

Kabuğu , 6 5 bayt

Zgarb sayesinde 1 bayt kurtarıldı

ΩΛ<Ċ2

Çevrimiçi deneyin!

açıklama

ΩΛ<Ċ2
Ω         Repeat until
 Λ<         all adjacent pairs are sorted (which means the list is sorted)
   Ċ2         drop every second element from the list

Bu 11 bayttır, 6 değil. ›Echo -n" ΩΛ <(← ½ "| wc
Mike Holler


@MikeHoller Diğer birçok golf dili olarak Husk, daha farklı karakterlere erişebilmek için özel bir kod sayfası kullanıyor: github.com/barbuz/Husk/wiki/Codepage
Leo

Teşekkür ederim, bugün bir şey öğrendim :)
Mike Holler

1
Bir bayt kaydetmek için Ċ2yerine kullanın (←½.
Zgarb

2

Gaia , 9 8 bayt

eo₌⟨2%⟩↻

Çevrimiçi deneyin!

Açıklama:

e		| eval input as a list
       ↻	| until
 o		| the list is sorted
  ₌		| push additional copy
   ⟨2%⟩  	| and take every 2nd element

2

Julia 1.0 , 30 bayt

-x=x>sort(x) ? -x[1:2:end] : x

Çevrimiçi deneyin!

Sıralanmamışsa dizinin her ikinci elemanını alır.


-20 bayt gibi bir ASCII operatörü kullanın . Ayrıca neredeyse her zaman karakter saymazız: | bu yüzden başlıktan kaldırılmış olsaydı iyi olurdu
ASCII-sadece

Bunu değiştirdim. 2 bayt için teşekkürler!
niczky12

2

C ++ (gcc) , 103 bayt

Yorum yapamam, ama içeriklerini azaltarak ve otomatik kullanarak sürümü movatica'dan geliştirdim.

-2 Bayt: ceilingcat
-2 Bayt: Yalnızca ASCII

#include<regex>
auto f(auto l){while(!std::is_sorted(l.begin(),l.end()))l.resize(l.size()/2);return l;}

Çevrimiçi deneyin!


1
Sadece kullanamamanın bir sebebi var l.size()/2mı?
ASCII-sadece

Evet, bu şekilde çalışmıyor :)
peterzuger

1
ne demek istiyorsun? bir boyut listesi döndürmek (n+1)/2veya (n-1)/2her ikisi de geçerlidir. hmm ....
ASCII-sadece

Ohh oops bu teşekkür görmedim
peterzuger

1

VDM-SL , 99 bayt

f(i)==if forall x in set inds i&x=1or i(x-1)<=i(x) then i else f([i(y)|y in set inds i&y mod 2=0]) 

Daha önce hiç vdm olarak gönderilmedi, dile özgü kurallar konusunda kesin değil. Bu yüzden bir seq of intve alır bir fonksiyon tanımı olarak gönderdimseq of int

Çalıştırmak için tam bir program şöyle görünebilir:

functions
f:seq of int +>seq of int
f(i)==if forall x in set inds i&x=1or i(x-1)<=i(x) then i else f([i(y)|y in set inds i&y mod 2=0]) 

1

Pyth, 10 bayt

.W!SIHhc2Z

Burada çevrimiçi deneyin . Bu, her yinelemenin ikinci yarısını yuvarlayarak kaldırır. Yuvarlama, ilk yarıyı kaldırmak için değiştirmek için, değiştirmek hiçin e.

.W!SIHhc2ZQ   Q=eval(input())
              Trailing Q inferred
  !SIH        Condition function - input variable is H
   SIH          Is H invariant under sorting?
  !             Logical not
      hc2Z    Iteration function - input variable is Z
       c2Z      Split Z into 2 halves, breaking ties to the left
      h         Take the first half
.W        Q   With initial value Q, execute iteration function while condition function is true

Listenin diğer tüm elemanlarını almak daha kısa. Değiştir hcile %. Bu ayrıca, takip eden lambda değişkenini silmenize Zve Pyth'in toplam 2 bayt için dolaylı olarak doldurmasına izin verir.
hakr14

1

C ++ (gcc) , 139 137 116 bayt

Tavana, -2 bayt thanx, PeterZuger'a -21 bayt teşekkür

#include<regex>
auto f(std::vector<int>l){while(!std::is_sorted(l.begin(),l.end()))l.resize(-~l.size()/2);return l;}

Vektör, sıralanana kadar ilk yarısına kadar yeniden boyutlandırın.

Çevrimiçi deneyin!


1
İthalatların bayt sayımına dahil edilmesi zorunludur, bu nedenle includes
Ignorance uygulamasının

Thanx, onları ekleyeceğim.
movatica

1

K (oK) , 22 20 bayt

Çözüm:

{(*2 0N#x;x)x~x@<x}/

Çevrimiçi deneyin!

Sıralanıncaya kadar girişin üzerinde yineleyin ... sıralanmamışsa ilk n / 2 öğeyi alın.

{(*2 0N#x;x)x~x@<x}/ / the solution
{                 }/ / lambda that iterates
                <x   / indices that sort x ascending (<)
              x@     / apply (@) these indices back to x
            x~       / matches (~) x? returns 0 or 1
 (       ; )         / 2-item list which we index into
          x          / original input (ie if list was sorted)
       #x            / reshape (#) x
   2 0N              / as 2 rows
  *                  / take the first one      

Düzenlemeler:

  • Ngn sayesinde -2 bayt

1
(.5*#x)#x->*2 0N#x
ngn

2 0NYapmayı düşündüm ama daha uzun olacağını varsaydım (test etmeden), teşekkürler!
Streetster


0

Retina , 38 bayt

\d+
*
/(_+),(?!\1)/+`,_+(,?)
$1
_+
$.&

Çevrimiçi deneyin! Virgülle ayrılmış sayıları alır. Açıklama:

\d+
*

Birliğe dönüştür.

/(_+),(?!\1)/+`

Liste sıralanmamışken tekrarlayın ...

,_+(,?)
$1

... her elemanı sil.

_+
$.&

Ondalık dönüştür.


0

C (gcc) , 66 bayt

Her yinelemenin listesinin ikinci yarısını keser ( n/2+1uzunluk tek ise elemanlar).

Çevrimiçi deneyin!

Girdiyi bir dizinin başlangıcına, intardından uzunluğuna işaretçi olarak alır . Dizinin yeni uzunluğunu döndürerek çıkar (yerinde sıralar).

t(a,n,i)int*a;{l:for(i=0;i<n-1;)if(a[i]>a[++i]){n/=2;goto l;}a=n;}

Ungolfed versiyonu:

t(a, n, i) int *a; { // take input as a pointer to an array of int, followed by its length; declare a loop variable i
  l: // jump label, will be goto'ed after each snap
  for(i = 0; i < n - 1; ) { // go through the whole array …
    if(a[i] > a[++i]) { // … if two elements are in the wrong order …
      n /= 2; // … snap off the second half …
      goto l; // … and start over
    }
  }
  a = n; // implicitly return the new length
}

Öner ~i+nyerinei<n-1
ceilingcat
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.