Jelly , Jelly kodlamada 309 bayt
“Æ÷“¥s“ɲ“¡µ’;“ịƊ⁴çNṂ‘_\
OḌ;¢*5$%¥/µ“+⁷ż!¤ña¡jIȧƁfvḶg/Ọ=^ƝĠ0Ẇƭ³½N~=.Ɗ°ɗẇ⁵\ɦ*ɠPf⁾?ṾHḣ 2=⁹ƒ!©ƊĠṣƥ®Ƙ0Yƙ>!ȧtƊN0w,$ɠẎ46fẋ⁷(ṣẆm⁾ŻƓṫµsçwṣḂḲd0Ruṛ’ḃ21+\iµØW“&;:' ”;“¡3ȧ%⁾xƑ?{Ñṃ;Ċ70|#%ṭdṃḃ÷ƑĠẏþḢ÷ݳȦṖcẇọqƁe ʠ°oḲVḲ²ụċmvP[ỴẊẋ€kṢ ȯḂ;jɓỴẏeṾ⁴ḳḢ7Ẓ9ġƤṙb€xÇ4ɗ⁻>Ẉm!Ƈ)%Ḃẇ$ġ£7ȧ`ỵẈƘɗ¡Ṃ&|ƙƥ³ẏrṛbḋƙċ⁻ṁƲRṀẹṾ<ñ⁻Ṅ7j^ɓĊ’b58¤ị;0ị@
ḲÇ€t0”@;Ṫ
Çevrimiçi deneyin!
Benim kendi mücadelemde zaman geçirdiğime karar verdim. Jelly'in (ve 8 bit kod sayfasının) kullanımı yalnızca ASCII dillerine göre% 12,5 avantaj sağlar ve Jelly, kısa kodlu yerleşik baz dönüştürme operatörlerine sahip olmasından, ancak tasarrufların çoğundan dolayı bu zorluk için kullanışlıdır. daha iyi bir sıkıştırma algoritmasından kaynaklanmaktadır (bu program her canavar türü için bir bayttan daha az ortalamaya sahiptir).
Algoritma ve açıklama
Kelime tabanlı sınıflandırma
İyi bir puan alabilmek için, girdilerin yapısından diğer girdilerden daha fazla faydalanmak gerektiğine karar verdim. Çok dikkat çeken bir şey, birçok canlının “ sıfat türü ” biçiminde isimleri olmasıdır ; a red dragon
ve a blue dragon
, her ikisi de ejderha türüdür ve bu nedenle görünürler D
. Diğer bazı canavarlar, " türler işi " biçiminde isimlerini içerir orc shaman
; bir tür ork olmak, bu gibi görünür o
. Karmaşık konular ölümsüzdür; a kobold zombie
, hem bir kobold hem de bir zombidir ve son durum NetHack canavar adında önceliklidir, bu yüzden bunu sınıflandırmak isteriz Z
.
Bu nedenle, canavar adlarında görünen kelimeleri şöyle sınıflandırdım: gösterge , uygun canavar sınıfını kuvvetle öneren bir kelimedir (örneğin, canavarın sınıfta olduğunu şiddetle sphere
tavsiye eder e
); Bir belirsiz kelime çok daha az bir öneri yapan bir kelimedir ( lord
çok size değil), ve diğer tüm kelimeler nonwords önemsediğimiz olmadığını. Temel fikir, canavar adındaki kelimelere en baştan geriye doğru bakıp gördüğümüz ilk göstergeyi seçmemiz. Bu nedenle, her canavar adının en az bir gösterge içerdiğinden emin olmak gerekliydi, bu da tamamen belirsiz kelimelerle takip edildi. Bir istisna olarak, benzeyen canavarların isimlerinde görünen kelimeler@
(en büyük grup) hepsi belirsiz olarak sınıflandırılır. Bir göstergeden önce herhangi bir şey görülebilir; örneğin, renk isimleri (örneğin red
) her zaman bir göstergenin isminden daha önce bir adda görünür ve bu yüzden (bir canavarın kimliğini belirlerken asla incelenmemiş oldukları gibi) şifresiz kabul edilir.
Sonunda, bu program diğer programlar gibi bir karma tabloya iniyor. Ancak, tablo tüm canavar isimleri veya canavar isimlerinde görünen tüm kelimeler için girdiler içermez; aksine, sadece göstergeleri içerir. Belirsiz kelimelerin karmaşası tabloda görünmez, ancak boş alanlara atanmalıdır (belirsiz bir sözcük aramaya çalışmak her zaman boş çıkar). Sözcüğü olmayanlar için, kelimenin tabloda görünüp görünmediği ya da karmaşanın çarpışıp çarpışmadığı önemli değildir, çünkü bir sözcüğü arama değerini asla kullanmayız. (Tablo oldukça seyrek, bu yüzden çoğu kelime tabloda görünmüyor, ancak flesh
tablodaki karma çarpışmaların bir sonucu olarak birkaçı var .)
Programın bu bölümünün nasıl çalıştığına dair bazı örnekler:
woodchuck
tek bir sözcük uzunluğundadır (bu nedenle bir göstergedir) ve tablo araması woodchuck
bize istenen cevabı verir r
.
abbot
Ayrıca uzun bir tek kelime, ama bir benziyor @
. Gibi, abbot
belirsiz bir kelime olarak kabul edilir; masa araması boş geliyor ve @
varsayılan olarak bir cevap döndürüyoruz.
vampire lord
Bir göstergeye ( vampire
karşılık gelen V
) ve belirsiz bir kelimeden ( lord
tabloda bulunmayan) oluşur. Bu, her iki kelimeyi de (ters sırada) kontrol edip, doğru cevabı verdiğimiz anlamına gelir V
.
gelatinous cube
kelime olmayan ( karma çarpışma nedeniyle gelatinous
karşılık gelen H
) ve bir göstergeden ( cube
, karşılık gelen b
) oluşur. Sadece tabloda bulunan son sözü aldığımızda, bu b
beklendiği gibi geri döner .
gnome mummy
gnome
karşılık gelen G
ve mummy
karşılık gelen iki göstergeden oluşur M
. Son göstergeyi alıyoruz ve M
istediğimiz şey buydu.
Kelime temelli sınıflandırmanın ele alınmasına ilişkin kod Jelly programının son satırıdır. İşte nasıl çalışıyor:
ḲÇ€t0”@;Ṫ
Ḳ Split on spaces
Ç€ Call function 2 (table lookup) on each entry
t0 Remove trailing zeroes (function 2 returns 0 to mean "not found")
”@; Prepend an @ character
Ṫ Take the last result
İki gerçek durum var; girdi tamamen belirsiz kelimelerden oluşuyorsa t0
, tablo aramalarının tüm çıktısını siler ve @
varsayılan olarak bir sonuç elde ederiz ; Girişte göstergeler varsa t0
, en sağ göstergenin sağındaki herhangi bir şeyi silecek ve Ṫ
bu göstergenin bize karşılık gelen sonucunu verecektir.
Masa sıkıştırma
Tabii ki, girdiyi kelimelere bölmek sorunu kendi başına çözmez; göstergeler ve karşılık gelen canavar sınıfları arasındaki uyuşmazlığı hala kodlamamız gerekiyor (ve belirsiz sözlerden gelen yazışmaların yetersizliği). Bunu yapmak için, 181 giriş kullanılan (181 göstergeye karşılık; bu 378 canavarın üzerinde büyük bir gelişme!) Ve toplam 966 girişin (hash fonksiyonunun 966 çıkış değerine karşılık gelen) seyrek bir tablo oluşturdum. Tablo, programda iki dizenin kullanılmasıyla kodlanmıştır: ilk dize, tablodaki "boşlukların" boyutlarını (giriş içermeyen) belirtir; ve ikinci dize, her girdiye karşılık gelen canavar sınıfını belirtir. Bunların her ikisi de baz dönüşüm yoluyla özlü bir şekilde temsil edilir.
Jelly programında, tablo araması için kod, programın kendisi ile birlikte, ilk satırdan µ
itibaren ikinci satırda gösterilir . Programın bu kısmı şu şekilde çalışıyor:
“…’ḃ21+\iµØW“&;:' ”;“…’b58¤ị;0ị@
“…’ Base 250 representation of the gap sizes
ḃ21 Convert to bijective base 21
+\ Cumulative sum (converts gaps to indexes)
i Find the input in this list
µ Set as the new default for missing arguments
ØW Uppercase + lowercase alphabets (+ junk we ignore)
“&;:' ”; Prepend "&;:' "
“…’ Base 250 representation of the table entries
b58 Convert to base 58
¤ Parse the preceding two lines as a unit
i Use the table to index into the alphabets
;0 Append a zero
i@ Use {the value as of µ} to index into the table
Sıfat tabanı (21), taban (21) gibidir; ancak 21, yasal bir hanedir ve 0 değildir. Bu bizim için daha uygun bir kodlamadır çünkü iki bitişik girişi 1 boşluk olarak sayıyoruz, böylece geçerli dizinleri kümülatif toplamdan bulabiliyoruz. Tablonun değerleri tutan kısmına gelince, 58 benzersiz değere sahibiz, bu yüzden önce 58 ardışık tam sayıya kod çözeriz ve sonra bunları kullanılan gerçek karakterlerle eşleştiren bir arama tablosunu kullanarak tekrar çözeriz. (Bunların çoğu harflerdir, bu yüzden bu ikincil arama tablosuna harf olmayan girdilerle &;:'
başlıyoruz ve sonra sadece büyük ve küçük harfler ile başlayan bir Jelly sabiti ekliyoruz; bu konuda.)
Jelly'in "index not found" sentinel değeri, bir listeye indekslemek için kullanırsanız listenin son öğesini döndürür; bu nedenle, eksik bir girişi belirtmek için daha uygun bir sentinel vermek için arama tablosuna bir sıfır (tablonun çoğu karakterden yapılmış olmasına rağmen bir tamsayı sıfır) ekledim.
Özet fonksiyonu
Programın kalan kısmı karma işlevidir. Bu, yeterince basit bir şekilde başlarOḌ
; bu giriş dizesini ASCII kodlarına dönüştürür ve sonra son kodu, artı 10 kez sonuç kodunu, artı 100'den önceki kodu vb. hesaplar (bunun Jelly'te çok kısa bir gösterimi vardır, çünkü dize → tamsayı dönüştürme işlevi). Bununla birlikte, bu karmaşayı doğrudan bir modül işlemi ile doğrudan indirirsek, oldukça büyük bir masaya ihtiyaç duyarız. Bunun yerine, masayı küçültmek için bir işlemler zinciri ile başladım. Her biri bu şekilde çalışır: biz mevcut karma değerin beşinci gücünü alırız; o zaman modulo değerini bir sabit (hangi sabit kullandığımıza bağlı olarak değiştiririz) değerini azaltırız. Bu zincir (elde edilen masa boyutunu küçültmek için) maliyetinden (işlem zincirini kendisinin kodlaması gerekmesi) iki yoldan daha fazla tasarruf sağlar: tabloyu yapabilirçok daha küçük (966 yerine 3529 den kayıt) ve çoklu aşamalarda kullanılmasının yararlı çarpışmalar (bu kadar olmadı, ama böyle bir çarpışma olduğunu tanıtmak daha fırsat verir: Her iki Death
ve Yeenoghu
karma 806'da için, böylece bize birini kaldırmak için izin Her ikisi de gider gibi, tablodan giriş&
). Burada kullanılan modüller [3529, 2163, 1999, 1739, 1523, 1378, 1246, 1223, 1145, 966]. Bu arada, beşinci güce yükselmenin nedeni, değeri doğrudan alırsanız, boşlukların aynı büyüklükte kalması, üstelik üst üste boşlukları hareket ettirmesi ve tablonun tablonun daha dengeli dağılmasını mümkün kılmasıdır. Yerel asgari düzeyde sıkışıp kalmak yerine zincir (daha eşit dağılmış boşluklar boşluk boyutlarının ters kodlanmasına izin verir). Bu, x ² = (- x ) ² çarpışmalara neden oluyor ve 5'in 3'ten daha iyi çalıştığını önlemek için bu garip bir güç olmalı .
Programın ilk satırı delta kodlamasını kullanarak modül dizisini kodlar:
“…’;“…‘_\
“…’ Compressed integer list encoding, arbitrary sized integers
; Append
“…‘ Compressed integer list encoding, small integers (≤ 249)
_\ Take cumulative differences
Programın geri kalanı, ikinci satırın başlangıcı, hash işlevini uygular:
OḌ;¢*5$%¥/
O Take ASCII codepoints
Ḍ "Convert from decimal", generalized to values outside the range 0-9
;¢ Append the table of moduli from the previous line
/ Then reduce by:
*5$ raising to the power 5 (parsing this as a group)
%¥ and modulusing by the right argument (parsing this as a group, too).
Doğrulama
Bu programın doğru çalıştığını doğrulamak için kullandığım Perl betiği:
use warnings;
use strict;
use utf8;
use IPC::Run qw/run/;
my %monsters = ("Aleax", "A", "Angel", "A", "Arch Priest", "@", "Archon", "A",
"Ashikaga Takauji", "@", "Asmodeus", "&", "Baalzebub", "&", "Chromatic Dragon",
"D", "Croesus", "@", "Cyclops", "H", "Dark One", "@", "Death", "&", "Demogorgon",
"&", "Dispater", "&", "Elvenking", "@", "Famine", "&", "Geryon", "&",
"Grand Master", "@", "Green-elf", "@", "Grey-elf", "@", "Hippocrates", "@",
"Ixoth", "D", "Juiblex", "&", "Keystone Kop", "K", "King Arthur", "@",
"Kop Kaptain", "K", "Kop Lieutenant", "K", "Kop Sergeant", "K", "Lord Carnarvon",
"@", "Lord Sato", "@", "Lord Surtur", "H", "Master Assassin", "@", "Master Kaen",
"@", "Master of Thieves", "@", "Medusa", "@", "Minion of Huhetotl", "&",
"Mordor orc", "o", "Nalzok", "&", "Nazgul", "W", "Neferet the Green", "@", "Norn",
"@", "Olog-hai", "T", "Oracle", "@", "Orcus", "&", "Orion", "@", "Pelias", "@",
"Pestilence", "&", "Scorpius", "s", "Shaman Karnov", "@", "Thoth Amon", "@",
"Twoflower", "@", "Uruk-hai", "o", "Vlad the Impaler", "V", "Wizard of Yendor",
"@", "Woodland-elf", "@", "Yeenoghu", "&", "abbot", "@", "acid blob", "b",
"acolyte", "@", "air elemental", "E", "aligned priest", "@", "ape", "Y",
"apprentice", "@", "arch-lich", "L", "archeologist", "@", "attendant", "@",
"baby black dragon", "D", "baby blue dragon", "D", "baby crocodile", ":",
"baby gray dragon", "D", "baby green dragon", "D", "baby long worm", "w",
"baby orange dragon", "D", "baby purple worm", "w", "baby red dragon", "D",
"baby silver dragon", "D", "baby white dragon", "D", "baby yellow dragon", "D",
"balrog", "&", "baluchitherium", "q", "barbarian", "@", "barbed devil", "&",
"barrow wight", "W", "bat", "B", "black dragon", "D", "black light", "y",
"black naga hatchling", "N", "black naga", "N", "black pudding", "P",
"black unicorn", "u", "blue dragon", "D", "blue jelly", "j", "bone devil", "&",
"brown mold", "F", "brown pudding", "P", "bugbear", "h", "captain", "@",
"carnivorous ape", "Y", "cave spider", "s", "caveman", "@", "cavewoman", "@",
"centipede", "s", "chameleon", ":", "chickatrice", "c", "chieftain", "@",
"clay golem", "'", "cobra", "S", "cockatrice", "c", "couatl", "A", "coyote", "d",
"crocodile", ":", "demilich", "L", "dingo", "d", "disenchanter", "R", "djinni",
"&", "dog", "d", "doppelganger", "@", "dust vortex", "v", "dwarf king", "h",
"dwarf lord", "h", "dwarf mummy", "M", "dwarf zombie", "Z", "dwarf", "h",
"earth elemental", "E", "electric eel", ";", "elf mummy", "M", "elf zombie", "Z",
"elf", "@", "elf-lord", "@", "energy vortex", "v", "erinys", "&", "ettin mummy",
"M", "ettin zombie", "Z", "ettin", "H", "fire ant", "a", "fire elemental", "E",
"fire giant", "H", "fire vortex", "v", "flaming sphere", "e", "flesh golem", "'",
"floating eye", "e", "fog cloud", "v", "forest centaur", "C", "fox", "d",
"freezing sphere", "e", "frost giant", "H", "gargoyle", "g", "garter snake", "S",
"gas spore", "e", "gecko", ":", "gelatinous cube", "b", "ghost", " ", "ghoul",
"Z", "giant ant", "a", "giant bat", "B", "giant beetle", "a", "giant eel", ";",
"giant mimic", "m", "giant mummy", "M", "giant rat", "r", "giant spider", "s",
"giant zombie", "Z", "giant", "H", "glass golem", "'", "glass piercer", "p",
"gnome king", "G", "gnome lord", "G", "gnome mummy", "M", "gnome zombie", "Z",
"gnome", "G", "gnomish wizard", "G", "goblin", "o", "gold golem", "'",
"golden naga hatchling", "N", "golden naga", "N", "gray dragon", "D", "gray ooze",
"P", "gray unicorn", "u", "green dragon", "D", "green mold", "F", "green slime",
"P", "gremlin", "g", "grid bug", "x", "guard", "@", "guardian naga hatchling",
"N", "guardian naga", "N", "guide", "@", "healer", "@", "hell hound pup", "d",
"hell hound", "d", "hezrou", "&", "high priest", "@", "hill giant", "H",
"hill orc", "o", "hobbit", "h", "hobgoblin", "o", "homunculus", "i",
"horned devil", "&", "horse", "u", "housecat", "f", "human mummy", "M",
"human zombie", "Z", "human", "@", "hunter", "@", "ice devil", "&", "ice troll",
"T", "ice vortex", "v", "iguana", ":", "imp", "i", "incubus", "&", "iron golem",
"'", "iron piercer", "p", "jabberwock", "J", "jackal", "d", "jaguar", "f",
"jellyfish", ";", "ki-rin", "A", "killer bee", "a", "kitten", "f", "knight", "@",
"kobold lord", "k", "kobold mummy", "M", "kobold shaman", "k", "kobold zombie",
"Z", "kobold", "k", "kraken", ";", "large cat", "f", "large dog", "d",
"large kobold", "k", "large mimic", "m", "leather golem", "'", "lemure", "i",
"leocrotta", "q", "leprechaun", "l", "lich", "L", "lichen", "F", "lieutenant",
"@", "little dog", "d", "lizard", ":", "long worm", "w", "lurker above", "t",
"lynx", "f", "mail daemon", "&", "manes", "i", "marilith", "&", "master lich",
"L", "master mind flayer", "h", "mastodon", "q", "mind flayer", "h", "minotaur",
"H", "monk", "@", "monkey", "Y", "mountain centaur", "C", "mountain nymph", "n",
"mumak", "q", "nalfeshnee", "&", "neanderthal", "@", "newt", ":", "ninja", "@",
"nurse", "@", "ochre jelly", "j", "ogre king", "O", "ogre lord", "O", "ogre", "O",
"orange dragon", "D", "orc mummy", "M", "orc shaman", "o", "orc zombie", "Z",
"orc", "o", "orc-captain", "o", "owlbear", "Y", "page", "@", "panther", "f",
"paper golem", "'", "piranha", ";", "pit fiend", "&", "pit viper", "S",
"plains centaur", "C", "pony", "u", "priest", "@", "priestess", "@", "prisoner",
"@", "purple worm", "w", "pyrolisk", "c", "python", "S", "quantum mechanic", "Q",
"quasit", "i", "queen bee", "a", "quivering blob", "b", "rabid rat", "r",
"ranger", "@", "raven", "B", "red dragon", "D", "red mold", "F",
"red naga hatchling", "N", "red naga", "N", "rock mole", "r", "rock piercer", "p",
"rock troll", "T", "rogue", "@", "rope golem", "'", "roshi", "@", "rothe", "q",
"rust monster", "R", "salamander", ":", "samurai", "@", "sandestin", "&",
"sasquatch", "Y", "scorpion", "s", "sergeant", "@", "sewer rat", "r", "shade", " ",
"shark", ";", "shocking sphere", "e", "shopkeeper", "@", "shrieker", "F",
"silver dragon", "D", "skeleton", "Z", "small mimic", "m", "snake", "S",
"soldier ant", "a", "soldier", "@", "spotted jelly", "j", "stalker", "E",
"steam vortex", "v", "stone giant", "H", "stone golem", "'", "storm giant", "H",
"straw golem", "'", "student", "@", "succubus", "&", "tengu", "i", "thug", "@",
"tiger", "f", "titan", "H", "titanothere", "q", "tourist", "@", "trapper", "t",
"troll", "T", "umber hulk", "U", "valkyrie", "@", "vampire bat", "B",
"vampire lord", "V", "vampire", "V", "violet fungus", "F", "vrock", "&", "warg",
"d", "warhorse", "u", "warrior", "@", "watch captain", "@", "watchman", "@",
"water demon", "&", "water elemental", "E", "water moccasin", "S", "water nymph",
"n", "water troll", "T", "werejackal", "d", "wererat", "r", "werewolf", "d",
"white dragon", "D", "white unicorn", "u", "winged gargoyle", "g",
"winter wolf cub", "d", "winter wolf", "d", "wizard", "@", "wolf", "d",
"wood golem", "'", "wood nymph", "n", "woodchuck", "r", "wraith", "W", "wumpus",
"q", "xan", "x", "xorn", "X", "yellow dragon", "D", "yellow light", "y",
"yellow mold", "F", "yeti", "Y", "zruty", "z");
for my $monster (sort keys %monsters) {
run ["./jelly", "fu", "monsters.j", $monster], \ "", \my $out;
print "$monster -> \"$out\" (",
($out ne $monsters{$monster} ? "in" : ""), "correct)\n";
}
mail daemon
> _ <