Illeggibile , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 byte
L'output è in ordine alfabetico inverso ( za a) ma in base alle regole che sembra essere consentito.
' '' '' ' ' '' '' '''' ' ' '''' ''' "" ' '' '' '' '' ''' "" "" "" ' '' ''" " ' '''" "" ' '' '' ''' "" " ' '' '' '' '' '''" "" " ' '' '' ' ' '' '' '''' " ' '''" " ' '' ' ' '' '' '''' ' ' '''' '''" "" "" "" "' '' '' ''"' ''' ''' "" "' '' '' ' ' '' '' '''' ' ' ''''"' '' ' ' '' '' '' '''' '' '' '' ' ''' "" ' ''' "" " ' '' '' '''" "" ' ''' "" "" "" "' ''" ' '' '' '' '' "' "" ' ''' "" ' '' '' '' "' '' '' '' "' ''"' '' '' '' '' ' ' ''''" ' '''"" "" "" ' '' '' '' ' ' '' ' ' '' '' '' '''' '' '' '''' '' '' ''' "" " ' '' "" "" " ' '' '' '' ' ' '''' '''" " ' '''" "' '' '' ''"' '' '' '' ' ' '''' "" ' ''' "" "" "" " ' '' '' '' ' ' '''' '''" "" "" " ' '''" " ' '''""" ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" "' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "' '' '' ' ' '' '' ''''"' "" ' ''' "" " ' '' '' '' '''" "" "" "" ' ''' "" ' ''' "" " ' '' '''" "" "'"" "" "" "" " ' '' '' '' '''" "" "" " ' '''" "" ' ''' "" "" "" " ' '' '' '' ' '' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' ""' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" " ' '''" "' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '"" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "" "" "' "" ' ''' "" ' '' "' "' '' '' ''" ' ''"' '' "' '' '' ' ' '' '' '' '''' ''" "" ' '' '' '' ''' "" " ' '' '' '' ' ' '''' '''" "" " ' '' '' '''" "" ' ''"" "" ' ''' "" "' '' ' ' '' '' '''' '' '' ' ' ''''"' '' ' ' '' '' '' '''' "" "" "" ' ''' "" ' '' ' ' '''' ' ' '''' ' ' '''' ' ' '''' ' ' '''' " ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' ""' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '" " ' '''" "' '' '' ' ' '' '' '''' '' '' ''"' '' ' ' '' '' '' '''' '' '' '' ' '' '' '' ''' "" "' '' '' '' '' ' ' '' '' '' '''' '' '' ''"' '' '' ''"" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" "" ' '' '' '' ''' "" "" "" " ' '' ' ' '' '' '''' '''" "' '' '' ''"' "" " ' '' '''" "" "" " ' '''" "" ' ''' "" "" "" " ' '''" "" ' '' '' ''' '' "' '' "' '' ''" ' '' '' '' ' ' ''''"' '' "'" ' '' '' '' "' '' '' ''" " ' '' '' '''" " ' '''" "" ' ''' "" "" "" " ' '''" "' ''""" ' ''' "" " ' '''" "" "" "" ' ''' "" ' ''""" ' ''' "" " ' '''" "" "" "" ' ''' "" ' ''"
Spiegazione
Innanzitutto, per avere un'idea di ciò che illeggibile può fare, ecco le sue operazioni di base:
- Hai un nastro infinito di celle intere di dimensioni arbitrarie
- Tu non si dispone di un puntatore di memoria come in Brainfuck; invece, si dereferenziano le celle in base alla loro posizione sul nastro. Ciò significa che è possibile “leggere il valore # 4” o “leggere il valore # (leggere il valore # 4)” (doppia differenza).
- Puoi solo leggere o scrivere celle di memoria (non incrementare / decrementare direttamente come in Brainfuck).
- È possibile incrementare / decrementare i valori all'interno di un'espressione. Così, per incrementare una cella di memoria si deve leggere , incremento , scrittura , o in modo diverso messo:
write(x, inc(read(x))).
- Ci sono loop while e condizionali ternari che possono solo verificare lo zero rispetto a zero.
Questo programma utilizza il nastro come segue. I nomi delle variabili verranno utilizzati nello pseudocodice più avanti in basso. Inoltre, questo documenta la prima versione (che era 1830 byte); vedere le modifiche in fondo per ciò che è cambiato da allora.
- Cella 0: variabile
q
- Cella 1: variabili
a, p,ch
- Cella 2: variabili
hash,v
- Cella 3: variabili
b,r
- Cella 4: variabili
aa,l
- Cella 5: rimane 0 per contrassegnare la "fine" della stringa di cifre decimali
- Celle 6–95: memorizza la stringa di cifre decimali all'indietro
- Celle 96–121: memorizza il numero di voti da detrarre dagli utenti da
a(96) a z(121) (il codice ASCII della lettera meno uno).
- Celle 4657–7380: ricorda quante combinazioni di elettori / votanti sono state incontrate quante volte. Queste celle hanno solo 4 possibili valori:
0= non ancora visto, -1= visto una volta, -2= visto due volte, -3= visto un numero qualsiasi di volte superiore a 2.
L'algoritmo procede essenzialmente come segue:
- Continua a leggere coppie di personaggi
ae b. Calcola il valore hash (a-2)*(a-1)+b-1, che è unico per ogni combinazione di lettere dalla a alla z.
- Controlla la cella di memoria con quel valore di hash (
*hash). In tal caso -3, l'utente è già idoneo alla rimozione dei voti, quindi incrementa *(b-1). Altrimenti, decremento *hash. Se è ora -3 , l'utente è appena diventato idoneo per la rimozione dei voti dopo tre occorrenze, quindi incrementa *(b-1)di 3.
- Dopodiché, passa attraverso i caratteri in ordine inverso (
za a) e visualizza quelli che richiedono i voti dedotti. Ciò richiede una divisione intera manuale per 10 per tradurre il numero in cifre decimali.
Con tutto ciò chiarito, ecco come appare il programma come pseudocodice:
// 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
}
Modifica 1, 1830 → 1796: mi sono reso conto che posso riutilizzare il valore di ritorno di un ciclo while in un punto.
Modifica 2, 1796 → 1791: Il programma risulta leggermente più piccolo se, invece di utilizzare le celle 6–95, memorizzo le cifre decimali nelle celle con numero negativo (da -1 in poi). Come bonus aggiuntivo, il programma non è più limitato a 10⁹⁰ voti!
Modifica 3, 1791 → 1771: Invece di assegnare il risultato di *(ch = l + 95)a v, ora lo assegno a qe quindi sposta l'assegnazione v = qnella condizione while, portando il codice a 1777 byte. Quindi scambiare la posizione di qe vsul nastro perché qora è 1 più comune di v.
Modifica 4, 1771 → 1762: Duh. L'inizializzazione hashsu 1 invece di 0 è più corta di 9 byte. Il codice hash ora è 1 in più, il che non ha importanza.
Modifica 5, 1762 → 1745: se eseguo l'inizializzazione qe rsu 1 invece di 0, devo cospargere alcune -1s in alcuni punti per farlo bene, e tutto sembra annullarsi, tranne per il fatto che il while v { --v; [...] }ciclo ora deve eseguire una iterazione in meno, cosa che posso fare dicendo while --v { [...] }che è più breve di 26 caratteri.
Modifica 6, 1745 → 1736: invece di { r = 1; ++q }, possiamo scrivere q = *((r = 1)+1)+1. Ciò si basa sul fatto che si qtrova nello slot variabile n. 2. Se fosse nello slot n. 1 questo sarebbe ancora più breve, ma l'intero programma sarebbe più lungo nel complesso.
Modifica 7, 1745 → 1727: ripristinato Modifica 6 e invece ha ottenuto il salvataggio incorporando il ciclo più interno mentre nell'espressione che calcola il codice ASCII della cifra, che finisce anche a 1736 byte ... ma poi ha salvato un'istruzione di decremento (9 byte ) cambiando ((++r) - 11) ? r :in (r - 10) ? ++r :.
Modifica 8, 1727 → 1626: rielaborato il calcolo dell'hash. Ora ne usa uno in meno mentre il ciclo. Le posizioni delle celle ora sono ai loro codici ASCII effettivi (non più fuori da 1). Rimescolate le variabili in posizioni diverse sul nastro perché ora si verificano con frequenza diversa.
Modifica 9, 1626 → 1606: allineamento più folle. Il corpo del primo ciclo while ora assomiglia a questo:
// 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)
}
e l'assegnazione delle variabili è ora quasi completamente cambiata.
Modifica 10 1606 → 1577 ho osservato che ae a2sono entrambi a 0 decrementato in cicli while, quindi se potessero accoppiare pcon uno di questi, ma non con ch, non avrei bisogno inizializzare pa 0(che costa 29 byte). Si scopre che posso farlo scambiando pe r. Le ultime variabili assegnate (e la loro frequenza di occorrenza nel codice) sono ora:
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)
nanananananananabatmantest case.