Programma di scacchiera triangolare auto-validante


10

Un programma a scacchiera è un programma in cui il valore ordinale di ogni singolo personaggio si alterna da pari a dispari, escluso il terminatore di linea (che può essere qualsiasi finale di linea standard).

Un programma triangolare è un programma in cui ogni riga ha un carattere aggiuntivo rispetto alla riga precedente, con la prima riga con un carattere. Non è necessario gestire input vuoti.

Il tuo compito è quello di costruire un programma che convalidi che l'input dato aderisca a quei criteri e produca / restituisca qualcosa di vero se il programma soddisfa i criteri, o qualcosa di falso altrimenti.

Anche il tuo programma deve soddisfare questi criteri.

Esempi di programmi validi

G
`e
@u^
5r{B

^
cB
+$C
VA01

Regole

  • Il programma può iniziare con un byte pari o dispari purché la parità dei caratteri si alterni.
  • Il programma deve convalidare i programmi che iniziano con un carattere pari o dispari.
  • Per i caratteri unicode, i valori dei byte sottostanti devono avere parità alternata.
  • Si può presumere che l'input contenga solo caratteri stampabili. Se il tuo programma contiene non stampabili, dovrebbe comunque essere in grado di convalidare se stesso.
  • Il tuo programma può includere una nuova riga finale, ciò non deve essere consentito dalla tua convalida poiché puoi presumere che sia stata rimossa prima della convalida.
  • Sono vietate le scappatoie standard.
  • Vince il codice più breve in byte, in ciascuna lingua.

@MartinEnder Grazie per il tuo contributo! Spero che ora sia chiaro. In relazione a questo, avrei dovuto lasciarlo più a lungo nella sandbox?
Dom Hastings,

1
il pari / dispari alternano sia orizzontale che verticale? Presumo si dalla "scacchiera", ma non vedo dove lo dici.
Ton Hospel

@DomHastings Una settimana sembra a posto. Se dopo qualche giorno non ricevi alcun feedback, puoi chiedere in chat se qualcuno ha altri commenti.
Martin Ender,

1
@TonHospel miei esempi originali fatto questo, ma si contraddicono con la mia descrizione, quindi per questa implementazione, no, dovrebbe essere: E\nOE\nOEO. Spero che aiuti!
Dom Hastings,

2
La mia opinione: lascia che le risposte assumano che l'input non inizi o termini con una nuova riga.
Lynn

Risposte:


3

Stax , 26 byte

L
Y$
i:-
 {2%
*OFyF
%vi =*

Esegui test case online

Ho dovuto introdurre 3 personaggi spazzatura. iè un no-op quando fuori da tutti i costrutti di loop. è sempre una no-op. Oinfila un 1 sotto la parte superiore dello stack, ma il valore non viene utilizzato nel programma.

LY      move input lines into a list and store in Y register
$       flatten
i       no-op
:-      get pairwise differences
{2%*OF  foreach delta, mod by 2, and multiply, then tuck a 1 under the top of stack
yF      foreach line in original input do...
  %v    subtract 1 from length of line
  i=    is equal to iteration index?
  *     multiply

Esegui questo


Ehi, spero che questo non rovini troppo il tuo codice, ma puoi eliminare la convalida della nuova riga principale.
Dom Hastings,

8

C (gcc), 189 byte

j
;l
;b;
d;f␉
(char
␉*␉t) 
{b=*␉t%
2;for␉(␉
j=d=0;j=j
+ 1,␉l=j+ 
1,␉*␉t; ) {
for␉(;l=l- 1
 ;t=t+ 1 )b= 
!b␉,␉d=d+ !(␉*
␉t␉*␉(␉*␉t- 10)
*␉(␉*␉t%2-b) ) ;
d␉|=*␉t- 10;t=t+ 
1 ; }b= !d; } ␉ ␉ 

Provalo online!

rappresenta un carattere di tabulazione (mi dispiace). Nota che ci sono diversi spazi / schede finali (mi dispiace di più). L'originale con le schede intatte viene visualizzato al meglio in vim con :set tabstop=1(le parole non possono esprimere quanto mi dispiaccia).

È una funzione (chiamata f, che non è immediatamente ovvia osservandola) che accetta una stringa come argomento e restituisce 0o 1.

Ho potuto ridurre questo da almeno uno e probabilmente due o più linee, ma nota che ottiene sempre più disordinato e basso sforzo verso la fine, soprattutto perché la scrittura tale codice terribile (anche per gli standard PPCG) è stato facendomi sentire come una persona cattiva e volevo fermarmi il prima possibile.

L'idea di base è quella di evitare costruzioni che necessariamente infrange il formato ( ++, +=, return, ecc). Miracolosamente, parole chiave importanti come for, chare while(che non ho finito per usare) sembrano adattarsi alla regola della parità alternata. Quindi ho usato gli spazi (parità pari) e le schede (parità dispari) come riempimento per adattare il resto alle regole.


1
Non mi aspettavo di vedere una soluzione in C!
Dom Hastings,

Se si isola la parte di soluzione del programma nel TIO inserendo altri elementi nelle sezioni "Intestazione" e "Piè di pagina", è più facile per le persone verificare il conteggio dei byte.
Jakob,

4

Haskell , 1080 1033 byte

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
 g '$' =0;
 g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
 g ',' =0-0-0;
 g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
 g '4' =0-0-0-0-0;
 g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
 g 'B' =0; g 'D' =0-0;
 g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
 g 'R' =0; g 'T' =0-0-0-0;
 g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
 g 'h' =0; g 'j' =0; g 'l' =0;
 g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
 g '~' =0; g y = 1 ;z=0; i(-0)z=z;
 i m('\10':y ) ="y"; ; ; ; ; ; ; ; 
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ; 
i k m ="y"; ; k i [ ] =01<1010101010;
 k m('\10':y ) = k(m + 1 )(i m y ) ; ;
 k m y =01>10; m o = k 1$'\10':o ; ; ; 
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ; 
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
 o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
 o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ; 

Provalo online!

Spiegazione

Questo è stato un compito piuttosto interessante per Haskell.

Parità

Per iniziare abbiamo bisogno di un modo per determinare se un personaggio ha un punto di codice pari o dispari. Il modo normale in cui uno potrebbe fare ciò è ottenere il punto di codice e modificarlo di 2. Tuttavia, come si può essere consapevoli, ottenere il punto di codice di un carattere richiede un'importazione, che a causa della restrizione di origine significa che non può essere Usato. Un Haskeller più esperto potrebbe pensare di ricorrere alla ricorsione. Charfanno parte della Enumtabella dei tipi in modo che possiamo ottenere i loro predecessori e successori. Tuttavia prede succsono anche entrambi inutilizzabili perché non fanno parità byte alternate.

Quindi questo ci lascia piuttosto bloccati che praticamente non possiamo fare alcuna manipolazione con i caratteri. La soluzione a questo è di hardcode tutto. Possiamo rappresentare (la maggior parte) anche i caratteri come valori letterali, probabilità con cui abbiamo problemi perché 'è dispari, quindi non può essere accanto al carattere stesso rendendo impossibile letterale esprimere la maggior parte dei caratteri dispari. Quindi codifichiamo tutti i byte pari e quindi aggiungiamo un fermo tutto per i byte dispari alla fine.

Il problema byte

Si può notare che ci sono alcuni byte pari per i quali non è possibile creare valori letterali racchiudendoli tra virgolette singole. Sono gli stampabili, i newline e \. Non dobbiamo preoccuparci di non stampabili dal momento che non usiamo nessuno di loro che non abbiamo bisogno di verificare. In effetti possiamo ancora usare strani non stampabili, come la scheda, non ne ho bisogno. Newline può essere sagacemente ignorato perché verrà comunque eliminato dal programma. (Potremmo includere newline, perché il suo punto di codice è piuttosto conveniente, ma non è necessario). Questo lascia \, ora \ha il punto di codice 92, che convenientemente è un numero dispari seguito da un numero pari, quindi si \92alterna tra pari e dispari quindi il letterale'\92'è perfettamente valido. Più tardi, quando avremo bisogno di rappresentare newline, noteremo che fortunatamente ha la stessa proprietà '\10'.

Problemi di spaziatura

Ora, per iniziare a scrivere il codice effettivo, dobbiamo essere in grado di mettere un numero considerevole di caratteri su una singola riga. Per fare ciò ho scritto il tappo:

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij

Il cappello non fa altro che essere valido Haskell. Inizialmente avevo sperato di fare delle definizioni che ci avrebbero aiutato nel codice in seguito, ma non è così. Esistono anche modi più semplici per creare il limite, ad esempio spazi bianchi e punti e virgola, ma non salvano byte in questo modo, quindi non mi sono preoccupato di cambiarlo.

Hardcoder

Quindi ora che ho abbastanza spazio su una linea inizio i valori di hardcoding. Questo è per lo più piuttosto noioso, ma ci sono alcune cose di interesse. Per uno, una volta che le linee iniziano a diventare ancora più lunghe, possiamo usare ;per mettere più dichiarazioni su una linea, il che ci fa risparmiare un sacco di byte.

Il secondo è che dal momento che non possiamo sempre iniziare una linea con un gogni tanto dobbiamo indentare un po 'le linee. Ora Haskell si preoccupa davvero del rientro, quindi si lamenterà di questo. Tuttavia, se l'ultima riga prima della riga rientrata termina con un punto e virgola, lo consentirà. Perché? Non ho il più debole, ma funziona. Quindi non ci resta che ricordare di mettere i punti e virgola alla fine delle righe.

Blocchi funzione

Una volta terminato, l'hardcoder naviga senza intoppi fino alla fine del programma. Dobbiamo creare alcune semplici funzioni. Per prima cosa ho creato una versione di drop, chiamata i. iè diverso dal fatto dropche se proviamo a passare oltre la fine della stringa restituisce semplicemente "y". iè diverso da drop anche in quanto se tenta di rilasciare una nuova riga tornerà "y", questi saranno utili perché in seguito quando verificheremo che il programma è un triangolo questo ci permetterà di tornare Falsequando l'ultima riga non è completa, o quando una linea finisce presto.

kknSSTruenkn+1False

Abbiamo poi creare un alias per k, m. mè solo kcon 1nel primo argomento, e una nuova riga anteporre al secondo argomento.

Quindi abbiamo o. oaccetta un numero e una stringa. Determina se i byte di stringa (ignorando le nuove righe) si alternano in parità (usando il nostro g) a partire dal numero di input.

Infine abbiamo quello sche funziona ocon entrambi 1e 0, se uno dei due riesce, si difende m. Se fallisce, ritorna e basta False. Questa è la funzione che vogliamo. Determina che l'ingresso è triangolare e alternato.


1
Una stringa triangolare inizia con una riga di 1 carattere, non una riga vuota.
Jakob,

@Jakob Penso che sia stupido ma è stata una soluzione abbastanza facile.
Ad Hoc Garf Hunter,

3

05AB1E , 34 26 byte

¶
¡D
©€g
´ā´Q
´sJÇÈ
¥Ä{´нP

Provalo online!

Prende l'input come stringa multilinea (input tra "" " ). Le spiegazioni verranno dopo.


1
A meno che non abbia frainteso le regole, il programma deve essere in grado di convalidare l'input anche a partire da una nuova riga.
Emigna,

@Emigna Penso che il tuo programma debba essere in grado di convalidare una nuova linea principale solo se inizia con una nuova linea principale.
Ton Hospel

Non ho idea se questo è corretto (sono terribile a leggere le specifiche): provalo online!
Magic Octopus Urn

@MagicOctopusUrn La tua risposta mi sembra OK, ma mi chiedo l'input: ci è permesso di prenderlo come un array? Nel tuo link, il tuo primo input è uno spazio vuoto, non un carattere newline.
Kaldo

1
Ehi, spero che questo non rovini troppo il tuo codice, ma puoi eliminare la convalida della nuova riga principale.
Dom Hastings,

1

Java 10, 209 byte

Un lambda vuoto che prende un iterabile o una matrice di byte. Indica true restituendo normalmente, false generando un'eccezione di runtime. Il programma prevede che la riga finale venga terminata correttamente, vale a dire termina con un carattere di nuova riga. La riga finale del programma è terminata in modo simile.

Tutto viene eseguito in UTF-8, con l'interpretazione che "carattere" si riferisce ai punti di codice Unicode.

Le schede vengono sostituite con spazi in questa vista.

d
->
{  
long
f= 1,
 h=0 ,
c = - 1
,e ;for 
( byte a:
 d) {var b
=(e = a^10)
<1&e>- 1 ;f=
b?( h ^ f)> 0
?0/0 : f+ 1: f
;h=b?0 :a>-65 ?
h+ 1: h; c =b? c
:c>=0 & ( (c^a )&
1 )<1 ?0/0 :a ; } 
/*1010101010101*/ }

Provalo online

Discarica esadecimale

Ripristina con xxd -p -rsu Unix.

640a2d3e0a7b20090a6c6f6e670a663d20312c0a09683d30092c0a63203d
202d20310a2c65203b666f72090a28096279746520613a0a096429207b76
617209620a3d2865203d20615e3130290a3c3126653e2d2031203b663d0a
623f280968095e0966293e09300a3f302f30093a09662b20313a09660a3b
683d623f30093a613e2d3635203f0a682b20313a09683b2063203d623f20
630a3a633e3d30092609280928635e612029260a3120293c31203f302f30
093a61203b207d200a2f2a313031303130313031303130312a2f207d0a

Ungolfed

d -> {
    long f = 1, h = 0, c = ~h, e;
    for (byte a : d) {
        var b = (e = a^10) < 1 & e > -1;
        f = b ?
            (h^f) > 0 ? 0/0 : f + 1
            : f
        ;
        h = b ? 0 :
            a > -65 ? h + 1 : h
        ;
        c = b ? c :
            c >= 0 & ((c^a) & 1) < 1 ? 0/0 : a
        ;
    }
}

fè il numero previsto di caratteri sulla riga corrente, hè il numero di caratteri visti finora sulla riga corrente, cè l'ultimo byte visto ed bè se aè la nuova riga.

La condizione a > -65verifica se aè il primo byte in un carattere. Questo funziona perché i caratteri a byte singolo (ASCII) non sono negativi nel complemento a 8 bit due, il primo byte di caratteri più lunghi ha forma binaria 11xxxxxx(almeno -64 nel complemento a due) e i byte non iniziali in quei caratteri sono di la forma 10xxxxxx, al massimo -65 nel complemento a due. ( Fonte )

Quando un personaggio viola il modello triangolare o a scacchiera (ovvero una nuova riga appare in anticipo o in ritardo o appare un byte della parità errata), il ramo sinistro del corrispondente ternario (in assegnazione a fo c) si attiva e il metodo genera un'eccezione aritmetica.


0

Python 3 (3.4?), 350 byte

Una sfida difficile per un linguaggio tanto particolare sugli spazi bianchi come Python 3. L'invio viene stampato 0o 1standardizzato e si arresta in modo anomalo per alcuni input. Il programma prevede che la riga finale venga terminata correttamente, vale a dire termina con un carattere di nuova riga. La riga finale del programma è terminata in modo simile. UTF-8 viene utilizzato per verificare la parità di byte.

Le schede vengono sostituite con spazi in questa vista.

0
i\
= 1
t=(#
 '0'*
 0) ;(
g,) =(#
 open (1
, "w"),) 
k = eval (
'p' + 'rin'
 + 't' ) #01
for  a in (#0
open ( 0) ):#0
#01010101010101
 a = a [:- 1 ] #
 if ( len (a )<i\
or len (a )>i ):[\
k('0' ),1 /0] #0101
 i, t= -~i, t+ a #01
(k( 2-len ({(c^i )&1\
 for  i,c in  eval (#0
 "enu"+"m"+"erate")(#01
 eval ( " byte"+"s")( t#
,' u8' ) ) } ) ) ) #01010

Funziona per me con Python 3.4.2; non funziona su nessun Python 3 su TIO. Mi sembra un bug negli interpreti di TIO.

Dump esadecimale

Ripristina con xxd -p -rsu Unix.

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202330313031300a
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.