Yapboz Bir kibrit çöpü çözmek


17

Şaşırtıcı SE'de matematiğin maç çubuklarına yazıldığı "kibrit çöpü sorunları" denen şey vardır ve belirli bir mülkü elde etmek için belirli bir sayıda hareket etmenize izin verilir.

Bu soruda yalnızca 7 segmentli bir görüntü biçiminde temsil edilen tam sayıları ele alacağız. İşte bu formattaki 10 rakamın tümü:

 __          __   __          __    __    __    __    __
|  |     |   __|  __|  |__|  |__   |__      |  |__|  |__|
|__|     |  |__   __|     |   __|  |__|     |  |__|   __|    

Ekranın her bir bölümü, sayının geri kalanından bağımsız olarak hareket ettirilebilen bir "kibrit çubuğu" dur. Kibrit çubukları bölünemez ve yıkılmaz, hiçbir şekilde kırılamaz veya çıkarılamaz.

Yaygın bir bulmaca, taban 10'da verilen bir sayıyı almak ve belirli sayıda hamlede mümkün olan en büyük sayıyı yapmaya çalışmaktır. Bir hareket, bir kibrit çöpünün dolu herhangi bir yuvadan boş bir başka yuvaya bir hareketi olarak kabul edilir. Sayının her iki tarafında yeni rakamlar yapmanıza izin verilir, örneğin 0 77 yapılabilir 3 hamle yapabilir

 __      __  __      __   __      __   __
|  |    |  |        |  |    |       |    |
|__| ,   __|     ,     |      ,     |    |

Bununla birlikte, 2'ye bir yuva yapamaz veya mevcut olanlar arasında yeni yuvalar oluşturamazsınız; örneğin, bir sayının ortasındaki bir 4'ü 11'e çevirmek veya mevcut olanların arasına yeni rakamlar eklemek. Her hareketin uygun bir sayı yapmasına gerek yoktur, ancak nihai sonuç temel 10 yedi segmentli ekranda uygun bir sayı olmalıdır. İstemiyorsanız her hareketi kullanmanıza gerek yoktur. Bu şaşırtıcı üzerinde farklı bir [etiket: kapalı uçlu soru] size olmayabilir yanıtlarınıza herhangi operatörleri (çarpma, üs alma, vs.) ya da matematiksel sabitler (Pi, Graham'ın numarası, vb) kullanın.

Görev

Girdi olarak bir sayı ve birkaç hamle alan ve orijinal sayı üzerinde birçok hamle ile yapılabilecek en büyük sayıyı döndüren bir program veya işlev yazın.

Bu bir sorusudur, bu nedenle cevaplar bayt cinsinden puanlandırılacak, daha az bayt daha iyi olacaktır.

Test Durumları

n, moves -> max
0, 1     -> 9
0, 3     -> 77
0, 4     -> 111
8, 3     -> 74
220, 1   -> 320
220, 2   -> 520
220, 3   -> 7227
220, 4   -> 22111
220, 5   -> 32111
747, 1   -> 747
747, 2   -> 7171
747, 3   -> 7711

İlişkili


5
Ben ... aslında dün gece geç saatlerde çeşitli kibrit çöpü basamakları arasında Levenshtein mesafesini düşünerek kaldı ... Ne garip bir tesadüf: P
ETHproductions

1
Ortada oluşan boş yarıklar sonunda yok sayılabilir mi? Ör.919, 2 -> 991
DanTheMan


buğday sihirbazı, hangi ızgara kullanılıyor?
tuskiomi

@tuskiomi "Ancak 2'ye bir yuva yapamazsınız veya mevcut olanlar arasında yeni yuvalar yapamazsınız"
Post Rock Garf Hunter

Yanıtlar:


7

JavaScript (ES6), 297 286 279 267 bayt

K eğri sözdiziminde girdi alır (s)(k), burada s bir sayı karakteri dizisidir ve k hareket sayısıdır (tamsayı).

s=>k=>(B=(n,b=0)=>n?B(n^n&-n,b+1):b,b=[...p='u"[k,iy#}m'].map(c=>c.charCodeAt()+2),r=[],g=(n,d='')=>n?n>0&&b.map((v,i)=>g(n-B(v),d+i)):r.push(d))(s.reduce((s,c)=>s+B(b[c]),M=0))&&b.map((_,j)=>r.map(n=>M=[...n+p].reduce((t,d,i)=>t+B(b[d]^b[s[i-j]]),0)>k*2|+n<M?M:n))|M

Test senaryoları


Nasıl?

Şekil verileri ve yardımcı işlevi

  • Dizi b , rakamların şekillerini 7 bit tamsayı olarak tanımlar; burada her bit bir segmenttir:

    7 kademeli

    Örneğin, "7" şekli 0b0100101 = 37'dir.

  • B () yardımcı işlevi , belirli bir sayının ikili gösterimindeki 1 sayısını döndürür:

    B = (n, b = 0) => n ? B(n ^ n & -n, b + 1) : b

Aşama 1

İlk önce giriş numarasında kullanılan kibrit çöpü sayısını sayarız:

s.reduce((s, c) => s + B(b[c]), 0)

Adım 2

Bu değeri , tam olarak bu sayıdaki eşleşme çubuklarıyla oluşturulabilecek tüm sayılarla bir liste r'yi dolduran özyinelemeli g () işlevine iletiriz:

g = (n, d = '') =>
  n ?
    n > 0 &&
    b.map((v, i) => g(n - B(v), d + i))
  :
    r.push(d)

Örneğin, gr (5) yükleyecektir [ '17', '2', '3', '5', '71' ]içine r .

Aşama 3

Biz şimdi en yüksek sayıya seçmek zorunda M de r aslında hamle izin verilen süre içinde, giriş numarasından elde edilebilir k .

Her numara için , n de r kullanımları tam giriş numarası gibi birçok kibrit olarak s , hamle sayısını dönüştürmek için gerekli olan s içine n eşittir yarısı da, her basamak arasında kademeli farkların sayısı.

İki basamak arasındaki segment farkı sayısı x ve y sayısı, b [x] XOR b [y] ' nin ikili gösterimlerindeki 1'lerin sayısı ile verilir .

Son olarak, birkaç olası basamak hizalamasını denememiz gerektiğine dikkat etmek önemlidir, çünkü s'nin ilk basamağı n'nin ilk basamağına eşlenmez . Rakamlar arasındaki geçiş koddaki j değişkeni tarafından verilir .


1

Mathematica, 188 197 200 203 170 174 bayt

NOT: Kod hala bir tür hata. Üzerinde çalışıyorum.

Hata için +30 bayt

(p=PadLeft;q=IntegerDigits;g=Join@@(#~q~2~p~7&/@ToCharacterCode["w$]m.k{% o"][[1+q@#]])&;h=(v=g@#2~#~96-g@i~#~96;Tr@v==0&&Tr@Abs@v<=2#3)&;For[i=10^Tr@g@#,!h[p,##]&&!h[PadRight,##],--i];i)&

Karakter arasında %ve oolmalıdır 0x7Fama SE buna izin vermez. Orijinal kodu kopyalamak için pastebin bağlantısını tıklayabilirsiniz .

6-7'den fazla çubuk olduğunda kod çok zaman alır. ( iTest etmek için başlangıç ​​değerini daha küçük bir sayı olarak değiştirebilirsiniz)

açıklama

gBellek temsil göre (bir liste halinde basamak dönüştürme yardımcı fonksiyonudur burada bu gibi), {1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1}için 220.

h iki sayı arasında sol dolgu ve sağ dolgu ile başa çıkmak için yardımcı bir işlevdir.

fçubuk temsili orijinal sayı ile aynı miktarda olan ve sayı ile karşılaştırıldığında ve miktar ikinci argümandan daha küçük veya eşit olan bir tamsayıyı aramak için 10^Tr@g@#(üst sınırdan) tekrarlar .11 -> 00 -> 1


Sana bir +1 verdim çünkü kazanan cevabın, diğer cevabından çok daha düşük bir skoru olduğunu hiç görmedim. Sanırım bunun nedeni çevrimiçi test seçeneklerinin olmaması. Belki de Mathematica'ya sahip bazı insanlar gelip test edebilir ve iyi çalıştığını doğrulayabilirler, böylece daha fazla oy alabilirsiniz. Ya da birileri mümkünse bunu Octave'ye dönüştürebilir.
geokavel
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.