Okunamayan , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 bayt
Çıkış ters alfabetik (içindedir z
için a
) ancak kurallara göre izin verilen görünüyor söyledi.
' '' '' ' ' '' '' '''' ' ' '''' ''' "" ' '' '' '' '' ''' "" "" "" ' '' ''" " ' '''" "" ' '' '' ''' "" " ' '' '' '' '' '''" "" " ' '' '' ' ' '' '' '''' " ' '''" " ' '' ' ' '' '' '''' ' ' '''' '''" "" "" "" "' '' '' ''"' ''' ''' "" "' '' '' ' ' '' '' '''' ' ' ''''"' '' ' ' '' '' '' '''' '' '' '' ' ''' "" ' ''' "" " ' '' '' '''" "" ' ''' "" "" "" "' ''" ' '' '' '' '' "' "" ' ''' "" ' '' '' '' "' '' '' '' "' ''"' '' '' '' '' ' ' ''''" ' '''"" "" "" ' '' '' '' ' ' '' ' ' '' '' '' '''' '' '' '''' '' '' ''' "" " ' '' "" "" " ' '' '' '' ' ' '''' '''" " ' '''" "' '' '' ''"' '' '' '' ' ' '''' "" ' ''' "" "" "" " ' '' '' '' ' ' '''' '''" "" "" " ' '''" " ' '''""" ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" "' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "' '' '' ' ' '' '' ''''"' "" ' ''' "" " ' '' '' '' '''" "" "" "" ' ''' "" ' ''' "" " ' '' '''" "" "'"" "" "" "" " ' '' '' '' '''" "" "" " ' '''" "" ' ''' "" "" "" " ' '' '' '' ' '' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' ""' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" "' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '"" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "" "" "' "" ' ''' "" ' '' "' "' '' '' ''" ' ''"' '' "' '' '' ' ' '' '' '' '''' ''" "" ' '' '' '' ''' "" " ' '' '' '' ' ' '''' '''" "" " ' '' '' '''" "" ' ''"" "" ' ''' "" "' '' ' ' '' '' '''' '' '' ' ' ''''"' '' ' ' '' '' '' '''' "" "" "" ' ''' "" ' '' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' ""' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '" " ' '''" "' '' '' ' ' '' '' '''' '' '' ''"' '' ' ' '' '' '' '''' '' '' '' ' '' '' '' ''' "" "' '' '' '' '' ' ' '' '' '' '''' '' '' ''"' '' '' ''"" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" " ' '' ' ' '' '' '''' '''" "' '' '' ''"' "" " ' '' '''" "" "" " ' '''" "" ' ''' "" "" "" " ' '''" "" ' '' '' ''' '' "' '' "' '' ''" ' '' '' '' ' ' ''''"' '' "'" ' '' '' '' "' '' '' ''" " ' '' '' '''" " ' '''" "" ' ''' "" "" "" " ' '''" "' ''""" ' ''' "" " ' '''" "" "" "" ' ''' "" ' ''""" ' ''' "" " ' '''" "" "" "" ' ''' "" ' ''"
açıklama
İlk olarak, Okunamayan'ın neler yapabileceği hakkında bir fikir edinmek için, temel işlem şudur:
- İsteğe bağlı tamsayı hücrelerin sonsuz bir kaseti var
- Sen do not brainfuck gibi bir bellek işaretçisi var; bunun yerine, hücreleri banttaki konumlarına göre ayırırsınız. Bu, “4 numaralı değeri okuyabilir” veya “5 numaralı değeri okuyabilir (4 numaralı değeri okuyabilir”) (çift değişkenli).
- Sadece bellek hücrelerini okuyabilir veya yazabilirsiniz (Brainfuck'ta olduğu gibi doğrudan artan / azalan değil).
- Bir ifade içindeki değerleri artırabilir / azaltabilirsiniz. Böylece, gerek bir hafıza hücresini artırmak için okumak , artım , yazma koymak farklı ya:
write(x, inc(read(x)))
.
- Sadece sıfıra karşı sıfır olmayanı kontrol edebilen döngüler ve üçlü koşullamalar vardır.
Bu program aşağıdaki gibi bandı kullanır. Değişken isimleri, daha sonra sözde kodda kullanılacaktır. Ayrıca, bu ilk sürümü (1830 bayt idi); o zamandan beri neyin değiştiği ile ilgili düzenlemeleri inceleyin.
- Hücre 0: değişken
q
- Celi 1: değişkenler
a
, p
,ch
- Celi 2: değişkenler
hash
,v
- Celi 3: değişkenler
b
,r
- Celi 4: değişkenler
aa
,l
- Hücre 5: ondalık basamak dizesinin “sonunu” işaretlemek için 0 kalır
- Hücreler 6-95: ondalık basamak dizesini geriye doğru saklar
- Hücreler 96-121: kullanıcılardan
a
(96) ila z
(121) arası kesilecek oy sayısını saklar (mektubun ASCII kodu eksi bir).
- Hücreler 4657-7380: hangi seçmen / seçmen kombinasyonlarına kaç kez rastlandığını hatırlayın. Bu hücrelerin yalnızca 4 olası değeri vardır:
0
= henüz görülmedi, -1
= bir kez görüldü, -2
= iki kez görüldü, -3
= 2'den fazla sayıda görüldü.
Algoritma esasen aşağıdaki şekilde ilerler:
- Karakter çiftlerini okumaya devam edin
a
ve b
. (a-2)*(a-1)+b-1
A-z harflerinin her birleşimi için benzersiz olan hash değerini hesaplayın .
- Bellek hücresini bu değerde (
*hash
) kontrol edin. Eğer öyleyse -3
, kullanıcı oyların kaldırılması için zaten elverişlidir, bu nedenle artış *(b-1)
. Aksi takdirde, azaltma *hash
. E? Er geç -3
, kullanıcı sadece gelmiştir haline üç tekrardan sonra oy kaldırılması uygun, yani artırır *(b-1)
tarafından 3
.
- Bundan sonra, ters sırada (karakterler geçmesi
z
için a
) ve çıkış mahsup oya ihtiyacımız var olanlar. Bu, sayının ondalık basamağa çevrilmesi için manuel tamsayı 10'a bölünmesini gerektirir.
Tüm açıklığa kavuşturulmuş halde programın sahte kod olarak göründüğü gibi:
// Read pairs of characters
while (a = read) + 1 {
b = read
// Calculate hash = (a-1)*(a-2)/2 + b-1
// This also sets a = b-1
hash = 0
while --a {
aa = a
while --aa {
++hash
}
}
while --b {
++a
++hash
}
// If this combination has just been seen for the third time,
// increment *a by 3; if more than third time, increment *a by 1
*a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}
// Loop through the characters z to a
l = 27
while --l { // l loops from 26 to 1 (not 0)
(v = *(ch = l + 95)) ? { // 'a' is ASCII 97, but cell 96
print (ch+1) // print the votee
// Now we need to turn the number v into decimal.
// p points to where we are storing decimal digits.
p = 5
while v {
// Integer division by 10 (q=quotient, r=remainder)
r = (q = 0)
while v {
--v
(++r - 10) ? 1 : {
r = 0
++q
}
}
// Store digit ASCII character
*(++p) = r + 48 // 48 = '0'
v = q
}
// Now output all the digit ASCII characters in reverse order
while *p {
print *(--p + 1)
}
} : 1
}
Düzenleme 1, 1830 → 1796: Bir süre döngüsünün dönüş değerini bir yerde yeniden kullanabileceğimi farkettim.
Düzenleme 2, 1796 → 1791: 6–95 hücrelerini kullanmak yerine, ondalık basamakları negatif numaralı hücrelerde (-1'den sonra) saklarsam programın biraz daha küçük olduğu ortaya çıkar. Ek bir avantaj olarak, program artık 10⁹⁰ oyla sınırlı değil!
Düzenleme 3, 1771 → 1791: Yerine sonucunu atama *(ch = l + 95)
için v
, şimdi atamak q
ve sonra atamayı taşımak v = q
1777 bayt kod alarak iken koşulu içine. Ardından kasetin yerini q
ve v
bandını değiştirin çünkü q
şimdi 1'den daha yaygın v
.
Düzenleme 4, 1771 → 1762: Duh. hash
0 yerine 1 değerine başlatma , 9 bayt daha kısa. Karma kodu artık 1 tane daha, hangisi önemli değil.
Düzenleme 5, 1762 → 1745: Sıfırlarsam q
ve r
0 yerine 1 yaparsam, -1
doğru yapmak için bazı yerlere serpmek zorundayım ve hepsi iptal edilmiş gibi görünüyor - bunun dışında while v { --v; [...] }
döngünün şimdi daha az bir yineleme yapması gerekiyor, söyleyerek yapabileceğim while --v { [...] }
, hangisi 26 karakter daha kısa.
Düzenleme 6, 1745 → 1736: Bunun yerine { r = 1; ++q }
yazabiliriz q = *((r = 1)+1)+1
. Bu q
, değişken 2 numaralı slotta olduğu gerçeğine dayanmaktadır . 1. yuvada olsaydı, bu daha da kısa olurdu, ama o zaman tüm program daha uzun olurdu.
Düzenleme 7, 1745 → 1727: Düzenleme 6 Döndürüldü ve bunun yerine en içteki çevrimi içine sararak kaydetti; bu, 1736 baytta biten ASCII kodunu hesaplayan ifadeye dönüştürdü, ancak daha sonra bir azalma talimatı kaydetti (9 bayt ) değiştirerek ((++r) - 11) ? r :
için (r - 10) ? ++r :
.
Düzenle 8, 1727 → 1626: Karma hesaplamayı elden geçirdi. Şimdi döngü sırasında bir tane daha az kullanır. Hücre konumları şimdi gerçek ASCII kodlarındadır (artık 1 ile kapalı değildir). Değişkenler, bant üzerinde farklı yerlere yerleştirilmişlerdir, çünkü bunlar şimdi farklı frekansta meydana gelmektedir.
Düzenleme 9, 1626 → 1606: Daha fazla çılgın inlining. İlk döngü sırasında ilk vücut şimdi şuna benziyor:
// b = next char
*(b = (hash = read)) = {
// hash = b + (a-1)*(a-2)/2
while (a2 = --a) {
while --a2 {
++hash
}
}
// If this combination has just been seen for the third time,
// increment *b by 3; if more than third time, increment *b by 1
(*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}
ve değişken ataması şimdi neredeyse tamamen değişti.
10 → 1577 1606 düzenleyin: Ben görülmektedir a
ve a2
ben eşleştirmek böylelikle eğer hem while döngüleri 0 olarak azaltılmakta p
olanlar biriyle, ama değil birlikte ch
, ben başlatmak için gerek olmazdı p
için 0
(29 bayt maliyeti). Anlaşılan p
ve bunu değiştirerek yapabilirim r
. En yeni değişken atamaları (ve koddaki oluşum sıklıkları) şimdi:
0 = v (3) (total 3)
1 = hash (6), r (5), ch (2) (total 13)
2 = b (4), q (5) (total 9)
3 = a (3), p (5) (total 8)
4 = a2 (3), l (4) (total 7)
nanananananananabatman
Test durumu için +1 .