Kodla - Karıştır - Kod Çözme


23

Meydan okuma

Göreviniz bir tamsayıyı ASCII karakterleri dizisi olarak kodlamak ve ardından söz konusu dizginin rasgele karıştırılmasından sonra başarıyla kodunu çözmek.

Kodlayıcı ve Kod Çözücü olarak adlandırılacak iki program / fonksiyon yazacaksınız .

Encoder

  • Giriş: [ 0 , 2 31 - 1 ] aralığında bir tam sayı n .[0,2311]
  • Çıktı: Bir dize s arasında ASCII karakterleri (ille yazdırılabilir değil).

şifre çözücü

  • Girdi: rastgele permütasyon s dizesi içinde s .
  • Çıkış: tam sayı n .

puanlama

Let A olmak maksimum uzunluğu arasında s bütün olası değerleri arasında n . Eğer Kodlayıcı olmayan deterministik hareket (izin verilen, aşağıya bakınız), daha sonra A maksimum uzunlukta olacaktır s (muhtemelen oluşabilecek ).

Let LE olmak uzunluğu Encoder bayt ve LD uzunluğu Dekoder bayt.

O zaman puanın A(LE+LD) .

Zafer en düşük puanı sunmaya verilir .

Zaman sınırı

Tek bir test çantası için hem Encoder hem de Kod Çözücünün çalıştırma süresinde 1 dakikalık bir keyfi zaman sınırı var (yani n'nin tek bir değeri ).n

Amaç, belirli dizilere sahip tüm dizileri numaralandırarak kodlamaya kaba kuvvet uygulayan çözümü önlemek. Çözümünüz bundan daha akıllıca bir şey yaparsa, büyük olasılıkla zaman kısıtlamasına uyacak ve geçerli sayılacaktır. Aynı şekilde, n'nin rastgele seçilmiş bazı değerleri için TIO üzerinde çalışıyorsa, geçerli sayılacaktır. Aksi halde, makinemde test edeceğim, ancak çözümünüz saf kaba kuvvet ise neredeyse kesin olarak başarısız olacağını unutmayın.n

kurallar

  • Encoder ve Decoder yazılmalıdır aynı dil .
  • Dekoder zorunluluk çıkışı doğru tamsayı n mümkün olan her permütasyon için s dizesi arasında s tarafından döndürülen Encoder .
  • Encoder ve Decoder vardır değil izin hisse bilgilerine (küresel değişkenler veya dosyaların vasıtasıyla örneğin) herhangi bir şekilde.
  • Çıktısı Encoder gerek yok olmak deterministik (aynı giriş olduğunu n ise farklı çıkış dizeleri üretebilir Encoder birden çok kez çalıştırılır), ancak Dekoder her zaman doğru tamsayı tahmin gerekir n .
  • Kodlayıcı ve Dekoder alıp tamsayı döndürebilir n de , herhangi bir uygun şekilde (örneğin, eğer n=14 , giriş olması için ince 14, "14"ya da [1,4]).
  • Kodlayıcı olabilir dizgesinden s yoluyla baskı üzerine stdout ya ile dönen bir dizi, bir liste / dizi karakter veya aralığında bir tamsayı liste / dizi [0,127] ; O notu Dekoder girdi olarak bir permütasyon alacak s tarafından döndürülen Encoder o dize kabul etmelidir, böylece s de aynı biçimde olarak s .
  • Standart boşluklar yasaktır.
  • Mümkünse, kodunuzun nasıl çalıştığını ve iddia ettiğiniz puanın neden doğru olduğunu açıklayın .

Örnek

n=14 varsayalım .

  • Kodlayıcı alan 14girdi olarak kullanılmaktadır. Çıktısı olabilir "qwerty".
  • Dekoder bir permütasyon alır "qwerty", örneğin, olarak giriş "tweyqr". Çıkması gerekir 14(uygun herhangi bir biçimde).

Kodlayıcı geri olabilir [113,119,101,114,116,121], bu durumda, hem de kod çözücü (örneğin) almış olur [116,119,101,121,113,114].

Kodlayıcı tarafından döndürülen dizenin, yazdırılamayan ASCII karakterleri de içerebileceğini (ancak her zaman aralık dahilinde [0x00, ..., 0x7F]) unutmayın.


Şüphesiz, çıkış uzunluğu sonsuz olamaz, sonsuz bir dizgeyi karıştırmazsınız
H.PWiz

@ H.PWiz Hayır, olamaz, ancak Kodlayıcı deterministik değilse, uzunluk sınırsız olabilir
Delfad0r 23:18

“Kodlayıcı ve Kod Çözücünün herhangi bir şekilde bilgi paylaşmasına izin verilmiyor” Buna yardımcı fonksiyonlar dahil mi? yani N faktörlü artı üçü (rastgele örnek) hesaplayan özel bir işlev
pizzapants184

Kodlayıcımız boş bir dize / liste verebilir mi?
pizzapants184

2
@Kroppeb Evet, kurallar gereği, baytları iki kez saymanız gerektiğini söylüyor. Yine de iki özdeş programla bir sunum yapmakla ilgileniyorum.
Delfad0r

Yanıtlar:


12

Jöle , (17 bayt + 18 bayt) × uzunluk 6 = 210 puan

b36μỤỤ + x + s 3μŒ¿b3U
S: 3_J
S% 3Uḅ3œ? Çḅ36

Çevrimiçi deneyin! (veya ekstra hata ayıklama bilgisi ile)

Belirtilen zafer koşulunu hedef alan bu zorluğa çözüm bulmaya çalışırken, varsayımsal bir alternatif zafer durumuna gitmenin ilginç olacağını düşündüm: , verim için asgari bir maksimum uzunluk verilmiş.

açıklama

Kodlama

Kodlamadaki ilk adım, girişi baz 36 ( b36) olarak göstermektir. 36 6 = 2176782336> 2147483647, bu nedenle sonuçta her biri 0-35 aralığında olan en fazla 6 hane olacak.

Sonra, bunu 6 farklı basamak içeren bir gösterime dönüştürüyoruz . Bunun için birçok olası algoritma vardır, ancak burada kullanılan en küçük basamağa 1, ikinci en küçüke 2, üçüncü en küçüke 3, vb. Eklemektir. Bu, eğer iki rakam aynıysa, bunlardan birinin keyfi olarak daha küçük olduğu ve dolayısıyla farklı olacağı anlamına gelir; ve açıkçası, bu algoritma iki farklı basamağın aynı olmasına neden olamaz. Jelly'te bunu göstermek için, dizini sıralı sırayla almak için ("dizinleri değerlere göre sırala") kullanırız; Bunu tersine çevirmek için, orijinalin her bir elemanını, sıralama düzenine göre etkin bir şekilde eşleştirmek; veµ…+ orijinali yeni listeye eklemek için . Sonuç, giriş numarasının 1-41 aralığında altı farklı basamak olarak gösterilmesidir (minimum 0 + 1, maksimum 35 + 6).

A: o zaman yine bir başka forma bu bölme sıralanmış . Basamak edildi 720 olası permütasyon hangi temsil 720 1 arasında bir sayı ile birlikte, 1-41 aralığı içinde basamak listesini ( Œ¿ve permütasyon sayısı özü ve kriteri sırasıyla sıralayınız.)

Son olarak, 1'den 720'ye kadar olan sayıyı taban 3'e ( b3) dönüştürür, tersine ( U), ve her birini ters divmod (tek değer) kullanarak tek bir ASCII karakterine paketleyerek altı taban 3 hanesini ve altı 1-41 haneyi kodlar karakter modu 3, temel 3 hane, 3'e bölünen değer 1-41 hanedir). Muhtemel sonuç aralığı ASCII aralığımıza uyması için en az (1 × 3) + 0 = 3 ve en fazla (41 × 3) + 2 = 125'dir. Paketleme, her komutun doğru veri üzerinde çalıştığından emin olmak için bir ek ile birlikte ×3ve +birlikte yapılır µ. (Burada bir miktar oyun hilesi var, çünkü permütasyonu çıkarmadan önce 3 ile çarpımı yapıyoruz ; bu, gruplama karakterinde bir bayt harcaması ihtiyacını ortadan kaldırıyor.)

Bu arada, temel 3 sayısını tersine çevirme nedeni, 1-41 sayısından daha az sayıya sahip olabilir. (Daha fazlası olamaz; n !> 3 n , 6'nın biraz üzerindedir . En küçük sayı 6'dır.) Jelly, birbirleriyle eşleşmelerini sağlamak için iki farklı uzunluktaki farklı sayıları toplarken etkin olarak izleyen sıfırlar ekler; sondaki sıfırlar sayının yorumunu etkileyecek, ancak lider ters ekstra sıfır bir yere sonunda sağlamak için kullanılır, böylece sıfır olmaz o karışıklık bizim cevap yukarı olmayacak.

Decoding

Kod çözmedeki ilk adım, iki sayının çıkarılmasıdır (temel 3 sayı ve 1-41 sayı). Rakamlarını sırasıyla division ( :3) ve modulo ( %3) ile kolayca alabiliriz , ama hangi sırada olduklarını nasıl bilebiliriz? Peki, 1-41 sayısının rakamları sıralanmıştı ve iki sayının karşılık gelen pozisyonlarındaki rakamlar aynı karakterlerde saklanıyordu; Bu nedenle, 1-41 sayı hanelerinin hangi sırasına karıştırıldığını (göreceli değerlerine bakarak) hesaplayabilir ve base-3 sayısının aynı şekilde karıştırılması gerektiğini biliriz. Aslında, ASCII kodlamamızın karakterleri 1-41 sayısının rakamlarıyla aynı şekilde sıralandığından (hepsi farklıydı ve temel 3 sayısından daha önemliydi),. Böylece her iki ekstraksiyon da başlar , ardından %3veya:3 uygun şekilde.

1–41 rakamının rakamları hala sıralanmış durumda olsa da, baz 36'nın 0-35 rakamına geri dönmek için çok uygun / ters bir yolumuz var; sadece ilkini 1, 2'yi ikinci, 3'ü üçüncü, vb. Jelly'te bunu _J("çıkarma dizini") ile yapabiliriz.

Bu arada, kod çözmenin diğer dalında, taban 3 sayısının hanelerini tekrar sıraya ( U) geri döndürür ve taban 3'ten ile bir permütasyon endeksine geri dönüştürürüz ḅ3.

İki şubeyi daha sonra birleştirebiliriz œ?Ç; œ?"Bu permütasyon endeksi verilen izin" Çanlamına gelir ve "yukarıdaki çizgiyi uygulamanın sonucu" anlamına gelir, yani Jelly'e her iki satırı da aynı girdi üzerinde ayrı ayrı çalıştırmasını söyleyen şeydir.

Şimdi elimizde olan, orjinal sayının rakamları, üs 36'da (nedeniyle _J) ve ilk sırada (nedeniyle) olduğu için , baz 36'yı tek bir tamsayıya dönüştürmek için œ?basitçe yapabiliriz ḅ36.

yorum

TIO! yukarıdaki link kodlanacak sayı olarak 312699167 kullanır. Tabandaki 36 bu sayıdır [5, 6, 6, 8, 7, 35]ve bu nedenle kodlamanın tüm yönlerini gösterir: 35, sahip olduğumuz 0-127 aralığının sınırını test eder; kopya 6s, orijinal bazda 36 aynı hanelerin çözünürlüğünü test eder; ve rakamların neredeyse (ancak tam değil) sıralanması gerçeği, permütasyon sayısının çok küçük olduğu anlamına gelir; bu, baz 36 sayısından çok daha az rakam verir ve böylece orijinaline eklemeden önce onu tersine çevirme ihtiyacını gösterir.

Buradaki tüm sabitlerin bir araya gelmesi gerçekten çok uygun. 36 6 sadece sadece 2 uyacak şekilde yeterince yüksek bir 31 , 3 6 sadece sadece 6 uyacak şekilde yeterince yüksek bir !, ve (36 + 6) x 3 sadece sadece elimizdeki 128 imkanları dahilinde uygun, yeterince yüksek. (Buradaki son kısıtlama en az kısıtlıdır, çünkü 0-2 aralığındaki karakterleri kullanmak için 1-indeksleme yerine 0-endekslemeyi kullanabiliriz. Yine de, sadece 37 yerine baz olarak kullanmak için yeterli yer bırakabilir. 36'dan.)


9

Jöle , ( 4 3 bayt + 6 5 bayt) × uzunluk 8 = 80 64 puan

b⁴Ä
ṢŻIḅ⁴

Çevrimiçi deneyin!

Jöle , ( 2 1 bayt + 4 3 bayt) × uzunluk 10 = 60 40 puan

Ä
Szi

Çevrimiçi deneyin!

açıklama

1. Çözüm

Bu, diğer cevapların çoğundan farklı bir algoritma kullanıyor. b⁴Diğer cevaplarda olduğu gibi , değeri hexadecimal ( ) olarak kodlayarak başlıyoruz , sonra kümülatif bir toplam ( Ä) alıyoruz . Her girdi açıkça farklı bir çıktı verecektir (çünkü bu işlemlerin her ikisi de geri dönüşümlüdür) ve onaltılık kodlamanın en fazla 7 (en son 8. basamak için) ve 15 (en son 7. için) olan en fazla 8 basamak içereceği göz önüne alındığında son basamaklar), çıkış listesindeki maksimum sayı, 7 + (7 × 15) = 112 olacaktır, bu da soru için gereken 127'den az olacaktır. Ek olarak, çıktının mutlaka sıralı olması gerekir, bu da karışıklığı tersine çevirmemize izin verir.

Kod çözücü için, önce karıştırmayı bir sort ( ) ile tersine çeviririz ; sonra bir sıfır ( Ż) hazırlayarak ve ardışık çiftlerin ( I) farkını alarak kümülatif toplamı ters çevirin ; sonra onaltılık ( ḅ⁴) işlevinden geri dönün .

2. Çözüm

Asıl soru, girdiyi (muhtemelen ondalık) basamakların bir listesi olarak almamıza izin veriyor, bu nedenle temel dönüştürmeyi kaldırarak "hile yapabiliriz; çıkışta kullanılan maksimum sayı 2 + (9 × 9) = 83 olacaktır (aslında 2999999999 aralık dışında olduğu için mümkün olan en düşük giriş 1999999999 olur). Sonuçta ortaya çıkan kodlama, bu problem için kodlamalar gittiği için oldukça korkunçtur, ancak kodlamanın ayrıntılarını aşan, üretmesi çok özlü olma avantajına sahiptir.

Bu cevap, bu problem için benim birincil çözümüm olmadığı için aldatma gibi görünüyor, fakat teknik olarak kurallara uyduğu ve daha iyi bir skor ürettiği için eklemeye değer gibi görünüyor.

yorum

8 uzunluğunun altına düşmek için bazı algoritmalar var, ancak by9 bayt (hile yapmayan) veya ≤5 bayt (hile) olarak bir uzunluk-7 algoritması uygulamanız mümkün görünmüyor, Muhtemelen bunu yapmanın en iyi yolu. (Yine de, sadece eğlence için olsa da, alternatif "kodlamanın uzunluğunu minimize etme" mücadelesi için bir çözüme gidebilirim.)

Bazı çözümlerin aksine, burada temel olarak 16'nın kullanılması kritik değildir; 8 uzunluğundaki bir çözüm için işe yarayacak çok sayıda başka numara var (örneğin 18). İlk çözüm için 16'yı seçtim, çünkü Jelly bunu temsil etmek için 1 baytlık bir yola sahipti ve diğer uygulanabilir bazların programdan çoklu baytları kullanması gerekecekti. Tabii ki, ikinci çözelti, boşluktan istifade etmek için taban olarak 10'u kullanmalıdır.

Bu algoritmayı yazmayı bile tereddüt eden bazı yeni Jelly komutlarını işaret ettiği için @Dennis sayesinde.


3
Äiçin kısa +\, Żkısaltmasıdır 0;.
Dennis,

7

Shakespeare Programlama Dili , 10 * (264 + 494) = 8650 7910 7580

Kodlayıcı: 264 bayt

,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.

Çevrimiçi deneyin!

Kod çözücü: 494

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.

Çevrimiçi deneyin!

Bu bir şeydi.

Kodlayıcı, her basamağı rakam olarak artı on iki rakamın indeksini kodlar. Kod çözücü tüm girişi Ford hafızasına kaydeder ve daha sonra bir sayıcı üzerinde döner, çıkıştan sonra her basamağı * 12 + 10 değerinden daha düşük siler.

Açıklama:

Encoder

,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.

şifre çözücü

,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number

5

Python 2.7, 31 * (52 + 37) = 2759

Kodlayıcı ( 69 52 bayt):

lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]

Kod çözücü ( 41 37 bayt):

lambda s:sum([1<<(ord(c))for c in s])

Sıfır olmayan tüm bitleri giriş numarasına ascii değerleri olarak kaydeder. Ascii karakterinin değeri, ayarlanan bitin konumunu saklar. Örneğin, 'a' değeri 97. bitin ayarlandığı anlamına gelir.

@ Delfad0r sayesinde birkaç geliştirme

Çevrimiçi deneyin!


PPGC'ye Hoşgeldiniz! Sen e = ve d = başında bırakabilirsiniz - anonim işlevler tamamen iyi. Ayrıca, sorun ifadesinin Kodlayıcı'nın karakterler yerine bir tamsayı listesi döndürebileceğini açıkça söylediğini unutmayın , böylece dönüşüm tamsayısı -> karakter-> tamsayısından kaçınabilirsiniz. Ayrıca, 2 bayt n&(1<<i)yerine kullanabilir n&(1<<i)>0ve kaydedebilirsiniz. Son olarak, i(127) için üst sınır çok fazla, 32 yeterli ve 1 byte tasarruf sağlıyor.
Delfad0r

1
Lütfen puanınızı problem beyanındaki Puanlama bölümüne göre belirtin.
Delfad0r

@ Delfad0r Puanlama şimdi doğru mu? Ve ipuçları için teşekkürler.
Hein Wessels

Bence skor, (52+37)*31=2759en uzun olduğu için 31 bitin tümünün ayarlandığı zamandır.
Jonathan Allan

Enkoder lambda n:[chr(i)*(n&1<<i>0)for i in range(32)]6 bayt kaydetmek olabilir .
mypetlion

5

Stax , skor 8 × (10 + 9) = 152

Enkoder, 10 bayt

Ç·MÉJ'♀τ│½

Koş ve hata ayıkla

16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string

Kodlayıcı dizgiyi artan bir sırada çıkarır.

Kod çözücü, 9 bayt

üL∟n╫k∞‼9

Koş ve hata ayıkla

o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits


5

Python 3 , 8 * (45 + 38) = 664

Kodlayıcı (45 bayt):

lambda n:[16*i+(n>>4*i)%16 for i in range(8)]

Kod çözücü (38 bayt):

lambda l:sum(x%16<<x//16*4 for x in l)

Çevrimiçi deneyin!


1
"For" dan önce boşlukları kaldırabilirsiniz, lambda l:sum(x%16<<x//16*4for x in l)çok iyi çalışıyor :)
FatalError

4
Bu çalışmıyor. Çıktı düz ASCII değil (0..127 aralığında)
GB

2
@ GB benim hatam. Son düzenlememle kırdım. Şimdi geri dönüyor
Curtis Bechtel

kodlayıcıda 3 bayt kaydetme: lambda n:[n>>4*i&15|i<<4for i in range(8)]kod çözücüye 1 kaydetme : lambda l:sum(x%16<<x//16*4for x in l)toplam 632 puan için
Aaron,

4

JavaScript (ES6), 8 * (40 + 32) = 576

08

Kodlayıcı (40 bayt)

E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]

Kod çözücü (32 bayt)

s=>s.map(c=>s|=c%16<<(c/4&~3))|s

gösteri

Çevrimiçi deneyin!

Nasıl?

Giriş, 4 bitlik 4 bit bloğa bölünmüştür ve her blok, 16 olası karakter arasından 1 ile kodlanmıştır. Son bloğun en önemli biti asla ayarlanmaz.

       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0

block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')

4

Jöle , (8 + 9) bayt * 8 maksimum uzunluk = 136

b⁴+J’Ɗ⁴¡

Kodlayıcı (altbilgi, listeyi Python'un netlik için yapacağı şekilde biçimlendirir)

Ṣ_J‘Ɗ⁴¡ḅ⁴

şifre çözücü

Maksimum uzunluğu altıya sahip olmak teorik olarak mümkündür, bu 22 bayt veya daha az olabilir mi?

Σben=0ben=5(127+ben127)=321402081<231-1

Nasıl?

231-17fffffff[7,15,15,15,15,15,15,15][7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]

Kodlayıcı :

b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]

Kod çözücü :

Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234

"onaltılık basamak", elbette. ("onaltılık düz basamağı kullanan rakamlar" daha uzundur ve yalnızca "rakamlar" ondalık basamağı anlamına gelir.)
Outgolfer Erik

Bağlamdan açıkça anlaşılmalıydı, ancak hemen onaltılık basamağa atıfta bulunduğum halde değiştirdim.
Jonathan Allan

Hesaplama işleminiz birer birer kapalı: azami 5 uzunluğa sahip 321402081 ve azami 6 uzunluğa sahip 7177979809 kombinasyonları var.
Anders Kaseorg

@AndersKaseorg oops, öyleyse öyle - bu yüzden maksimum 6 boyuyla mümkün ... oynayabileceğiniz 22 bayt!
Jonathan Allan

4

Shakespeare Programlama Dili , 31 * (472 + 383 379 344) = 26505 26381 25296

Önceki skor: 16909322 * (246 + 217) = 7829016086

Bu hala çok yüksek, ama şu anda düşünebildiğim en düşük seviye.

Encoder:

,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.

Çevrimiçi deneyin!

dekoder:

,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart

Çevrimiçi deneyin!

Temel olarak, dizge ASCII koduyla (n + 1) bir karakter içeriyorsa, nth ikili basamağı ayarlanır.


Kod çözücü için 344 bayt
Jo King

3

Python 3, (208 bayt + 200 bayt) * 6 uzunluk = 2448

Çevrimiçi deneyin! (her ikisini de içerir, ekstra bayt aralarındaki yeni satırdır).

Boş listeyi kullanarak -4 bayt (-24 puan) (daha fazla şeyin 0'dan başlamasını sağlar)

Kodlayıcı (208 bayt)

def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s

Kod çözücü (200 bayt)

def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n

Gözlemler:

  • Kesinlikle artmayan (yani sıralanan) listeler için karıştırma işlemi kayıpsız olarak tersine çevrilebilir.

  • Kesinlikle aynı uzunluktaki artmayan sayısal listeler tamamen Python'da olduğu gibi sipariş edilebilir.

  • Listelenen tüm listelerin toplam bir sırasını oluşturmak için önce listelerin uzunluklarına göre sıralandığını tanımlayabiliriz.

  • Biz listedeki tek geçerli değer elde tamsayılar olduğuna tanımlarsanız Biz bu listelerin bir kesici dizisini oluşturabilir 0için 127kapsayıcı (uzunluğuyla geçerli listelerin sonlu mevcutken yani L).

Strateji:

  • Kodlayıcı: Bir sayı verildiğinde N, Nkesinlikle geçerli olmayan bir liste bulun .

  • Kod Çözücü: Geçerli (karıştırılmış) geçerli bir liste verilirse, sıralayın ve dizini geçerli listelerde döndürün.

Ortak kod açıklaması:

  • T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1

  • nTh- simplex sayısını hesaplayınd

    • Her d=0zaman için1

    • Için d=1, n(uzunluğu olan bir nokta çizgisindeki nokta sayısı n)

    • için d=2,Σben=1nben, (yan uzunluğu olan bir üçgen üçgenindeki nokta sayısı n)

    • için d=3,Σj=1nΣben=1jben, (kenar uzunluğu olan bir tetrahedron içindeki nokta sayısı n)

Kodlayıcı açıklaması:

  • def E(n,h=128): d=l=0, s=[]

  • ngiriş sayısı, bir h"yüksek bir değer" (1 + izin verilen en yüksek sayısı gibi), bir dçıkışı olacaktır uzunluğu olan s, çıkış l"düşük değer" (0 ° C'de başlayan, daha sonra anlatılacak)

  • while n>=T(h,d):, n-=T(h,d),d+=1

  • T(h,d)Geçerli uzunluk dlisteleri vardır ve gerçek bir indeks yerine nlisteye göre indeks [0]*d(endeks 0) olması durumunda hesaplamamız daha kolaydır , nbuna göre azaltın . Bu aynı zamanda dverilen uzunluğu (doğru) olarak ayarlar n.

  • for i in range(d):

  • Etkili: " i+1listedeki inci numara için"

    • Burası açıklayacağım l"düşük değer"

    • Listeye bir numara girildikten sonra, listeye girilebilecek sayıdan daha az sayı yoktur (sıralı tutmak için), llisteye eklenen son numara da öyledir .

    • while n>=T(h-l,d+~i):, n-=T(h-l,d+~i),i+=1

    • Eğer bu "basamak" nile kodlanmayacak kadar büyükse l, o zaman nuygun şekilde ayarlayın ve artırınl

    • s+=[l]

    • Bu "basamakta" nile kodlayın l.

    • Öncelikle, sıradaki hne "basamak" için seçeneklerimiz var , ancak bir kez "rakam" koyduğumuzda (atanmış olan l), bir h-lsonraki "rakam" için seçeneklerle sınırlı kalıyoruz .

    • İlk başta T(h,d)geçerli listeler vardı, fakat lgeriye kalan "hane" d-1sayısını ve sonraki geçerli hane sayısını azaltan bir "hane" ekledik h-l, bundan sonra geçerli liste sayısınıT(h-l,d-1)

Kod çözücü açıklaması:

  • def D(s):, s.sort(), l=0,d=len(s)

  • s(karıştırılmış) giriş listesi, yani s.sort(); l"low value" ( h"high value" sadece 128baytları kaydetme kodundaki değişmez ), nçıkış numarası, duzunluktur.

  • n=sum(T(128,D)for D in range(d))

  • Dizisindeki nnoktaya ayarlayın .[0]*length

  • for i in s:

  • Her hane için:

    • for j in range(l,i):, n+=T(128-j,d-1)

    • Dizisindeki nnoktaya ayarlayın .[...prevdigits, thisdigit, 0...]

      • l=i: "Düşük değeri" en son haneye ayarlayın

      • d-=1: Bir rakam kullandığımızdan beri uzunluğu azaltın

  • return n: nTüm haneler için ayarlandıktan sonra doğru sayıdır; iade etmek.

Açık değilse üzgünüm, ama işte orijinal nongolfed hata ayıklama sürümüm Çevrimiçi deneyin! , boş listeyi kullanmayan, bu sürümde kullanılan tüm numaralardan 1 kapalı


3

Yakut , (36 + 29 bayt) * 8, skor 520

kodlama:

->n{(0..7).map{|x|(n>>x*=4)%16+x*4}}

Çevrimiçi deneyin!

Kod Çözme:

->a{a.sum{|x|x%16<<(x/4&28)}}

Çevrimiçi deneyin!

Nasıl çalışır:

Sayı, 4 bitlik parçalar ve 3 bitlik bir dizin kullanılarak kodlanır.

Kod çözücü giriş dizisini alır ve her ucu tekrar yerine koyar.


3

Kömür , 10 * puan (10 + 15) = 250.

Ondalık kullanır; önceki 16 temel tabanlı çözelti 328 296 264’ü buldu.

Yazdırılamayan karakterlerin çıktısını alabilir. Özellikle, karakter 10, Kömür'e girişi zorlaştırır.

Enkoder, 10 bayt:

⭆⮌S℅⁺Iι×χκ

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

Kod çözücü, 15 bayt:

IΣES×﹪℅ιχXχ÷℅ιχ

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

Tam sayıların bir listesini kullanan sürüm 360 296 (temel 16; ondalık sayı 310 olacaktır):

Enkoder, 19 bayt:

NθIE⁸⁺﹪÷θX¹⁶ι¹⁶×¹⁶ι

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

Kod çözücü, 18 bayt:

IΣEE⁸N×﹪ι¹⁶X¹⁶÷ι¹⁶

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

Yazdırılabilir karakterleri kullanan sürüm 360 (puan 16'da 416 384 368) idi:

Enkoder, 19 bayt:

⭆⮌S℅⁺Iι×χ⁺κ×⁵⊕׳÷κ⁵

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

Kod çözücü, 17 bayt:

Fθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ

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


2

Brachylog , 17 + 18 bayt * 8 uzunluk = 280

Encoder:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ

dekoder:

ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp

Kodlayıcının sonuna hiçbir etkisi olmadan bir p eklenebilir. Kod çözücü (karıştırılmış) sonucu çıktı olarak koyarak ve orijinal sayıyı girişte alarak çalıştırılır.

Eğer (uygun şekilde uygulanmış) bir kümülatif toplam varsa, puan 20'ye düşebilir

Çevrimiçi deneyin!


@ Delfad0r, p'yi kodlayıcıya eklemek, kodlama ve kod çözme için aynı kod olmasını sağlar
Kroppeb

2

05AB1E , skor: (2 + 2 bayt ) * 11 maksimum uzunluk = 44

Kodlayıcı (2 bayt ):

Çevrimiçi deneyin.

Kod çözücü (2 bayt ):

Çevrimiçi deneyin.

Kodlayıcının girişi ve kod çözücünün çıktısı, rakamların bir listesidir.

Arasında Port'un @ ais523 'ın 2 Jelly cevap .

Açıklama:

    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]

{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]

Çünkü opsiyonlar çıkışına a sıfır, çıkış uzunluğu girişi + 1 itibaren uzunluğu231-1 10 basamak uzunluğa sahip, çıktının maksimum uzunluğu 11.


2

Gol> <> , 8 * (14 + 13) = 216

Enkoder Çevrimiçi deneyin! , 14 bayt:

I8FfPSD8*L+o|;

Dekoder Çevrimiçi deneyin! , 13 bayt:

iEh8SD4*2$X*+

Bu, yazdırılamaz ascii karakterleri çıktırabildiğinden, kod çözücüyü karıştırdığından, çıktı / girdideki sayıları kullanan bir sürüm var:

Enkoder Çevrimiçi deneyin! , 14 bayt:

I8FfPSD8*L+N|;

Dekoder Çevrimiçi deneyin! , 13 bayt:

IEh8SD4*2$X*+

Kodlama:

Kodlama, verilen numarayı 8 x 4bit parçalara bölerek çalışır. Bu parçalar daha sonra 3 bit sağa kaydırılır ve öbürün orjinal yeri sonuna 0 ile 7 arasında bir sayı olarak eklenir. Böylece kodlama şöyle görünür:

0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB

2

Perl 6 , 10 * (10 + 12) = 340 220

Encoder:

{^@_ Z~@_}

dekoder:

{.sort X%10}

Çevrimiçi deneyin!

Enkoder işlevi, her basamağı, sayının 0 endeksi ile fermuarlar. Daha sonra kodlayıcı numaraların listesini sıralar ve moduloyu 10'ar, başka bir deyişle, numaranın ikinci basamağı alır.

Toplam 10, çünkü maksimum uzunluk 2 31 -1.


1

Haskell , 10 * (23 + 51) = 740

İşte değerleri kodlayan, karıştıran, kod çözen ve doğrulayan bir program: Çevrimiçi deneyin!

Enkoder, 23 bayt

zipWith((+).(10*))[0..]

Çevrimiçi deneyin!

Kod çözücü, 51 bayt

map snd.sortOn fst.map(`divMod`10)
import Data.List

Çevrimiçi deneyin!

açıklama

Girdiyi ondalık basamak olarak kullanmamıza izin verildiğinden, onu kullanacağız. Kodlayıcı, oluşan her basamağı eşler 10*index + digit, hepsinin digitiçinde olacağını unutmayın, [0..9]böylece yukarıdakileri kullanarak tersine çevirebiliriz divMod. Endeksleri ve rakamları geri yükledikten sonra, yalnızca endekslere göre sıralama ve onlardan kurtulma meselesidir.

Çözümün değerlere kadar çalışması bekleniyor 231-1=2147483647 10 basamak uzunluğunda, bu yüzden aldığımız maksimum kod noktası 99=81<128. Ayrıca her rakam bir "karakter" e dönüştürülecek, bu yüzden en fazla 10 tane olacak.



1

APL (Dyalog Unicode) ,LE+LD=36;bir=8288.

d←{16n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1

Çevrimiçi deneyin! (ödevler ve yeni satır için 5 ekstra bayt içerir).

Kullanımları ⎕IO←0

Nasıl:

(⊢+16×⍳∘≢)16⊥⍣¯1  Encoder; input 1234
          16⊥⍣¯1  Convert input to base 16  4 13 2
      ⍳∘≢           [0..length of the list-1]  0 1 2
   16×              times 16  0 16 32
 ⊢+                 plus the original list  4 29 34

{16n-16×⍳≢n←⍵[⍋⍵]}  Decoder; input   34 4 29
              [⍋⍵]   Grade  up  2 0 1
                    Index  with that list  4 29 34
           n        assign that to n
      16×⍳≢          16×[0..length(n)-1]  0 16 32
    n-               subtract that from n  4 13 2
 16                 Decode from base 16  1234

1

PHP, 8 * (44 + 53) = 776

kodlayıcı, 44 bayt:

for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";

boşlukla ayrılmış tam sayıların listesini yazdırır. İle boru olarak çalıştırın -nR.

4 veri bitiyle (daha düşük uç) ve 3 ağırlık bitiyle (üst uç) maksimum 8 bayt.

Basitçe söylemek gerekirse:
Her onaltılık basamağı kendi karakterine yerleştirin ve basamağın konumunu kaydetmek için baytın üst yarısını kullanın.

örnek:

1457893891( 0x56e5b203) Dönüşecek
0x03, 0x10, 0x22, 0x3b, 0x45, 0x5e, 0x66, 0x75
3 16 34 59 69 94 102 117

kod çözücü, 53 bayt:

while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;

veya

while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;

veya

for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;

tamsayıları komut satırı argümanlarından alır. İle koş -nr.


Onları çevrimiçi deneyin .


0

Python 2,10 * (68 + 54) = 1220

e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))

Çevrimiçi deneyin!

EDIT: Jo King'e göstericiler için teşekkürler - geriye dönük olarak neden 32'ye ofset yaptığımdan emin değilim.

Her yerin konumunu ve değerini, [boşluk] (konum 0, değer 0) NUL bayt 0x0 ile başlayan tek bir karakter olarak kodlar .

Kodunu çözerek:

  • stringi sıralama (Python, karakterleri sıralı değerlerine göre sıralar)
  • her karakteri sıra değerine dönüştürür
  • her sıralı tamsayının son basamağını alır
  • tamsayıları bir dizgeye bağlar
  • birleştirilmiş dizgiyi int'ye geri dönüştürür

Ofsete ihtiyacınız var 32mı? Ayrıca, [-1]olabilir %10doğru yerde, yerine
Jo Kral

0

C (gcc) , 10 x 112 = 1120

c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}

Çevrimiçi deneyin!

Genel değişkenlerim var, ancak iki işlev arasında herhangi bir bilgi aktarmıyorlar. İçin değişken bildirimi c, her iki işlevde de kod uzunluğunda 2 bayt tasarrufu sağlayan kullanılır.

Yalnızca 3 5 baytlık bir ceza için yazdırılabilir ASCII kullanan bir sürüm burada:

c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}

70 puanlık iyileştirmeler için teşekkürler @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.