En büyük ve en küçük sayıları yapın


13

Puzzling'deki bu yayından ilham aldı . Bu bulmaca için spoiler aşağıda.

Girdi olarak üç pozitif tamsayı verildiğinde (x, y, z), kapsayıcı aralığı yapılandırın, [x, y]bu aralığı birleştirin, ardından zmümkün olan en büyük ve en küçük pozitif tamsayıları üretmek için ardışık olmayan basamakları kaldırın . Baştaki sıfırlara izin verilmez (yani sayılarla başlamalıdır [1-9]). Bu iki sayıyı her iki sırayla çıktılayın.

Şaşırtıcı görevinden Örneğin, giriş için (1, 100, 100), mümkün olan en büyük sayı 99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100,
en küçük sayıdır 10000012340616263646566676869707172737475767778798081828384858687888990919293949596979899100,
gelen mantık altında aşağıdaki jafe en yayınlanmıştır cevap var:

  • Sayının uzunluğunu (sabit sayıda basamak vardır) etkileyemeyiz, bu nedenle değeri en üst düzeye çıkarmak için maksimum ilk basamağı, ardından ikinci basamağı vb. Alırız.
  • İlk dokuz dokuz olmayanı (kaldırmak için 16 hane kaldı) kaldırın: 999995051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • Sonraki 17 basamaktaki en büyük sayı 7'dir, bu nedenle buradan cevaptaki bir sonraki basamak en fazla 7 olabilir (16 basamaktan fazlasını kaldıramayız). Yani 15 olmayan 7'yi kaldırın ... (kaldırmak için 1 haneli kaldı):999997585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • Buradan sonraki basamak en fazla 8 olabilir, bu nedenle 8'den olmayan birini ortadan kaldırın: 99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • Benzer mantık, ancak tersine çevrilir (yani, en küçük sayı için 1öncülük etmek yerine öncülük etmek istiyoruz 9).

İşte küçük bir örnek: (1, 10, 5).

Aralığı oluşturur 12345678910ve hangi 5rakamları kaldırabileceğimize karar veririz. Açıkçası, çıktının uzunluğunu etkileyemediğimiz için, ön basamağı en üst düzeye çıkarmak istiyoruz. Yani, çıkarırsak 12345, kalırız 678910ve yapabileceğimiz en büyük şey budur. En küçük olanı yapmak biraz daha zordur, çünkü sayıları ortadan 123410kaldırarak mümkün olan en küçük olanı bırakabiliriz .

Çünkü (20, 25, 11)sonuç, 5ve gibi oldukça sıkıcıdır 1.

Son olarak, baştaki sıfırlar deneyin cevapları ekarte etmek, (9, 11, 3)verir 91011ki dönüş verimlerinde 91ve 10büyük ve en küçük olarak.

G / Ç ve Kurallar

  • Daha kolay / daha kısa ise, biri büyük ve diğeri en küçük olmak üzere iki programı / işlevi kodlayabilirsiniz; bu durumda puanınız her iki bölümün toplamıdır.
  • Giriş ve çıkış herhangi bir uygun yöntemle verilebilir .
  • Girdinin, dilinizin yerel sayı türüne uygun olduğu varsayılabilir, ancak ne birleştirilmiş sayı ne de çıktının bunu yapacağı varsayılmaz.
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine döndürebilirsiniz.
  • Standart boşluklar yasaktır.
  • Bu bu nedenle her zamanki golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

hane listesi çıktı olarak kabul edilebilir mi?
Rod

Baştaki sıfırları değerlendirirken sahte bir minimum getirecek bir test vakası faydalı olabilir - bence 9, 11, 3olur.
Jonathan Allan

@ Çubuk Evet, rakamların listesi çıktı için uygundur.
AdmBorkBork

@Rod Neden bahsettiğinizi bilmiyorum, açıkça "çıktı" yazdım. ;-)
AdmBorkBork

@JonathanAllan İyi çağrı. Katma.
AdmBorkBork

Yanıtlar:


5

Haskell , 162 bayt

l=length
((m,f)%n)s|n>=l s=[]|n>0,(p,c:r)<-span(/=m(f$take(n+1)s))s=c:((m,id)%(n-l p)$r)|1>0=s
(x#y)z=[p%z$show=<<[x..y]|p<-[(maximum,id),(minimum,filter(>'0'))]]

Çevrimiçi deneyin!

Jafe tarafından açıklanan algoritmayı kullanır. Daha az verimli bir yöntem kullanmak daha kısa olabilir, ancak yazmak daha eğlenceliydi :)

%Operasyon (ne olursa olsun aslında 3 ama) 4 argüman alır: mbir fonksiyonu olduğunu bir listeden seçer "Optimal" üye (ya maximumya minimumbizim istediğimiz bağlı olarak); fbu bir "filtre" fonksiyonudur; nbırakılacak basamak sayısı; ve sdize. İlk olarak n'nin dizede kalan basamak sayısına ( >=güvenlik için kullandım ) eşit olup olmadığını kontrol edip geri kalanını bırakıyoruz s. Aksi takdirde, hala basamakları ( n>0) düşürmemize gerek olup olmadığını kontrol ederiz , sonra spandizemizi üç parçaya ayırmak için kullanırız : pdüşecek basamaklar, cen uygun ulaşılabilir basamak verkalan dize. Bunu, en uygun basamağımızla eşitliği kontrol eden bir öngörü aktararak yapıyoruz. Bu rakamı bulmak n+1için dizenin ilk rakamlarını alırız , filtreleriz ve sonra "seçici" fonksiyonumuza iletiriz. Şimdi sadece optimal rakamımızı veriyoruz ve tekrarlıyoruz, p(düşen basamak sayısı) uzunluğunu çıkarıyoruz n. Filtreleme işlevimizi özyinelemeli çağrıya geçirmediğimize ve bunun yerine onunla değiştirdiğimize dikkat edin id. Bunun nedeni, filtrenin yalnızca minimumilk yinelemeyle ilgili olması durumunda önde gelen 0'ları seçmekten kaçınmaktır . Bundan sonra artık filtreye ihtiyacımız yok.

%için gerçekten sadece bir yardımcı fonksiyonudur #hangi alarak bizim "gerçek" işlevidir x, yve z. Biz sadece bizim fonksiyon dizilerini yineleme ve bunları geçen tekrarlama biraz önlemek için bir liste anlama kullanmak %ile birlikte zve birleştirilmiş dize. Bu dize, (=<<)bu bağlamda çalışan sihirli monad operatörü kullanılarak oluşturulur concatMap.


3

Jöle , 17 bayt

r/VDœcL_¥¥ḷ/ƇVṢ.ị

Çevrimiçi deneyin!

Tüm olasılıkları hesaplar sonra en büyük ve en küçük tutar.

Sol argüman: x,yaralığı oluşturmak için. Sağ argüman: zkaldırılacak rakamlar.

r/VDœcL_¥¥ḷ/ƇVṢ.ị
r/                 Inclusive range from x to y
  V                Concatenate the digits together
   D               Get the resulting digits
         ¥         Dyad:
        ¥            Dyad:
      L                Length of the list of digits in the concatenated number.
       _               Subtract the number of digits to be removed.
    œc               Combinations without replacement. (remove z digits)
            Ƈ      Keep lists of digits that:
          ḷ/       have a positive first element (no leading zeros).
             V     Combine digits into integers. (vectorizes to ldepth 1)
              Ṣ    Sort the numbers
               .ị  Indexes at value 0.5 which yields the first and last elements.

2

Python 2 , 143 bayt

import itertools
s,e,r=input()
l=''.join(map(str,range(s,e+1)))
L=[i for i in itertools.combinations(l,len(l)-r)if'0'<i[0]]
print min(L),max(L)

Çevrimiçi deneyin!

Bu, hedef boyutun (kombinasyon sırası korunur) tüm kombinasyonlarını hesaplayarak ve ondan en küçük / en büyük sayıları alarak çalışır


Oh ... sanırım lol çalışıyor. Aslında bunu deterministik olarak hesaplayan bir program yapmak için çok çalışıyordum.
Don Bin

@RushabhMehta Brute force hesaplamaları hala deterministik, sadece daha yavaş.
dylnan

2

Kömür , 56 bayt veya 21 + 46 35 = 67 56 bayt

≔⪫…·NNωθFN≔⌈EθΦθ⁻λνθθ

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

≔⪫…·NNωθ

Girin xve ykapsayıcı bir aralık oluşturun ve sayıları bir dizeye birleştirin.

FN

Kaldırılacak her basamak için bir kez döngü yapın.

≔⌈EθΦθ⁻λνθ

Geçerli dizeden olası her karakteri kaldırarak oluşturulan dizelerin bir listesini oluşturun ve maksimum değeri alın.

θ

Sonucu yazdırın.

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌊Φ✂θκLυ¹∨κIλ⊞Oυω

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

≔⪫…·NNωθ

Girin xve ykapsayıcı bir aralık oluşturun ve sayıları bir dizeye birleştirin.

F⊕N⊞υω

Girin zve artırın. Daha sonra bu uzunlukta bir liste oluşturmak: zAşağıdaki filtre içinde artırmak gerekir , ancak yalnızca komutları değişkenleri artırmak için izin verilir; PushOperatorlistenin uzunluğunu artıran bir boşluk var .

 θ                      String of digits
Φ                       Filter over characters
         κ              Current index
          Lυ            Length of list i.e. current `z` value
            ¹           Literal 1
       ✂θ               Slice string of digits
      Φ                 Filter over characters
              κ         Outer index
               Iλ       Cast inner character to number
             ∨          Logical OR
     ⌊                  Minimum
   ⁼ι                   Equals the outer character
  ∧              ⊞Oυω   And also push to list i.e. increment `z`
                        Implicitly print

Dilimlenebilir bölgede alt karakter olmadığından emin olarak istenen karakterlere filtre uygulayın. Bölge ilk z+1karakterlerle başlar ( zgerekirse ilk dilimi dilimlemek mümkün olduğundan ) ve tutulan her karakter için bitiş noktası artışları olur. İlk karakter için sıfır seçmemeye özen gösterilir.

Mümkün olan en büyük sayıyı hesaplamak için kullanıldığında daha hızlı algoritma 30 bayttır:

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌈✂θκLυ¹⊞Oυω

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Düzenleme: O zamandan beri her iki sonuç üreten ikinci bir 56 bayt çözüm yukarıdaki iki birleştirmek başardık:

≔⪫…·NNωθF⊕N⊞υω≔⮌υη⟦Φθ∧⁼ι⌈✂θκLυ¹⊞OυωΦθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

≔⪫…·NNωθ

İlk dizeyi oluşturun.

F⊕N⊞υω

z+1Listenin uzunluğu olarak temsil edin.

≔⮌υη

Listeyi tersine çevirerek klonlayın ve sonucu kaydedin.

İki sonucu ayrı satırlara yazdırın. (Bunu yapmanın bir başka yolu, sonuçları gerçek bir \rkarakterle ayırmaktır .)

Φθ∧⁼ι⌈✂θκLυ¹⊞Oυω

Mümkün olan en büyük sayıyı oluşturun.

Φθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

Takip etmek için klonlanmış listeyi kullanarak mümkün olan en küçük sayıyı oluşturun z.


1

Jöle ,  19  18 bayt

rDẎœcL_⁵Ɗ$ị@Ƈ1ḌṢ.ị

Çevrimiçi deneyin!

Çok verimsiz, kesinlikle için gidiş hiçbir nokta 1, 100, 100olarak(19292)=305812874887035355118559193163641366325011573739619723360


1

05AB1E , 16 bayt

ŸSDg³-.Æʒ¬Ā}{Ć`‚

Çevrimiçi deneyin!

Tam program, girişleri şu sırayla okuma: y, x, z . İki karakter listesinin bir listesini çıkarır.

açıklama

ŸSDg³-.Æʒ¬Ā}{Ć`‚    Full program. Inputs: y, x, z.
Ÿ                   Inclusive binary range from x to y. Push [x ... y].
 S                  Dump the digits separately in a list.
  Dg                Duplicate, and use the second copy to get its length.
    ³-              Subtract z from the length.
      .Æ            Retrieve all combinations of length - z elements from the digits.
        ʒ  }        Keep only those that...
         ¬Ā         Don't start with a 0 (head, then Python-style boolean).
            {       Sort the remaining elements.
             Ć      Enclose. Pushes list + list[0] (appends its tail to itself)
              `     Dump all elements separately on the stack.
               ,    Pair, to get the last two, min and max (after enclosing)

Oh, Ć`‚oldukça akıllı, güzel bir cevap!
Kevin Cruijssen

0

Matlab, 95 bayt

function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

Çevrimiçi deneyin!

Min. Ve maks. 1x2 matrisi döndürür.

Nasıl çalışır

% Full code
function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

% The function
function[m]=f(s,e,c),                                                                       end

                     % Creates the range in a single string
                     a=sprintf('%d',s:e);

                                                   % Gets all the combinations
                                                   combnk(a,length(a)-c)

                                         % Converts the string combinations to integers
                                         x=str2num(                     );

                                                                          % Finds min and max
                                                                          m=[min(x),max(x)];
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.