Selbstvalidierendes dreieckiges Schachbrettprogramm

10

Ein Schachbrettprogramm ist ein Programm, bei dem der Ordnungswert jedes einzelnen Zeichens von gerade bis ungerade wechselt, mit Ausnahme des Zeilenabschlusses (der ein beliebiges Standardzeilenende sein kann).

Ein dreieckiges Programm ist ein Programm, bei dem jede Zeile ein zusätzliches Zeichen als die vorhergehende Zeile enthält, wobei die erste Zeile ein Zeichen enthält. Sie müssen keine leeren Eingaben verarbeiten.

Ihre Aufgabe ist es, ein Programm zu erstellen, das überprüft, ob die angegebene Eingabe diesen Kriterien entspricht, und etwas Wahres ausgibt / zurückgibt, wenn das Programm die Kriterien erfüllt, oder etwas Falsches auf andere Weise.

Ihr Programm muss auch diese Kriterien erfüllen.

Beispiele für gültige Programme

G
`e
@u^
5r{B

^
cB
+$C
VA01

Regeln

  • Ihr Programm kann entweder mit einem ungeraden oder einem geraden Byte beginnen, solange sich die Parität der Zeichen abwechselt.
  • Ihr Programm muss Programme validieren, die entweder mit einem ungeraden oder einem geraden Zeichen beginnen.
  • Bei Unicode-Zeichen müssen die zugrunde liegenden Bytewerte eine abwechselnde Parität aufweisen.
  • Sie können davon ausgehen, dass die Eingabe nur druckbare Zeichen enthält. Wenn Ihr Programm nicht druckbare Dateien enthält, sollte es sich dennoch selbst validieren können.
  • Ihr Programm enthält möglicherweise eine nachfolgende neue Zeile. Dies muss bei Ihrer Validierung nicht berücksichtigt werden, da Sie davon ausgehen können, dass diese vor der Validierung entfernt wurde.
  • Standardlücken sind verboten.
  • Der kürzeste Code in Bytes in jeder Sprache gewinnt.
Dom Hastings
quelle
@MartinEnder Vielen Dank für Ihre Eingabe! Hoffentlich ist das jetzt klar. Sollte ich dies im Zusammenhang damit länger im Sandkasten lassen?
Dom Hastings
1
wechselt die gerade / ungerade sowohl horizontal als auch vertikal? Ich nehme ja von "Schachbrett" an, aber ich sehe nicht, wo Sie das sagen.
Ton Hospel
@ DomHastings Eine Woche scheint in Ordnung zu sein. Wenn Sie nach einigen Tagen kein Feedback erhalten, können Sie im Chat fragen, ob jemand weitere Kommentare hat.
Martin Ender
1
@TonHospel Meine ursprünglichen Beispiele haben dies getan, aber es widersprach meiner Beschreibung, also sollte es für diese Implementierung sein : E\nOE\nOEO. Hoffentlich hilft das!
Dom Hastings
2
Meine Meinung: Lassen Sie die Antworten davon ausgehen, dass die Eingabe nicht mit einem Zeilenumbruch beginnt oder endet.
Lynn

Antworten:

3

Stax , 26 Bytes

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

Führen Sie Testfälle online aus

Ich musste 3 Junk-Charaktere einführen. iist ein No-Op, wenn außerhalb aller Schleifenkonstrukte. ist immer ein No-Op. OSteckt eine 1 unter den Stapel, aber der Wert wird im Programm nicht verwendet.

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

Führen Sie diesen aus

rekursiv
quelle
Hey, ich hoffe, dass dies nicht zu viel mit Ihrem Code zu tun hat, aber Sie können die führende Newline-Validierung löschen.
Dom Hastings
8

C (gcc), 189 Bytes

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; } ␉ ␉ 

Probieren Sie es online aus!

stellt ein Tabulatorzeichen dar (tut mir leid). Beachten Sie, dass es mehrere nachgestellte Leerzeichen / Tabulatoren gibt (es tut mir mehr leid). Das Original mit intakten Tabs wird am besten in vim mit angezeigt :set tabstop=1(Worte können nicht ausdrücken, wie leid es mir tut).

Es ist eine Funktion (aufgerufen f, die bei einem Blick nicht sofort ersichtlich ist), die eine Zeichenfolge als Argument verwendet und entweder 0oder zurückgibt 1.

Ich könnte dies um mindestens eine und wahrscheinlich zwei oder mehr Zeilen reduzieren, aber beachten Sie, dass es gegen Ende immer chaotischer und müheloser wird, vor allem, weil ich mich durch das Schreiben eines so schrecklichen Codes (selbst nach PPCG-Standards) wie ein schlechter Mensch fühlte und ich wollte so schnell wie möglich aufhören.

Die grundlegende Idee dabei ist , Konstruktionen zu vermeiden , dass notwendigerweise das Format brechen ( ++, +=, return, etc.). Wie durch ein Wunder passen wichtige Schlüsselwörter wie for, charund while(die ich letztendlich nicht verwendet habe) zufällig zur alternierenden Paritätsregel. Dann habe ich Leerzeichen (gerade Parität) und Tabulatoren (ungerade Parität) als Auffüllung verwendet, damit der Rest den Regeln entspricht.

Türknauf
quelle
1
Ich hatte nicht erwartet, eine Lösung in C zu sehen!
Dom Hastings
Wenn Sie den Lösungsteil des Programms im TIO isolieren, indem Sie andere Elemente in die Abschnitte "Kopf-" und "Fußzeile" einfügen, können die Benutzer die Anzahl der Bytes leichter überprüfen.
Jakob
4

Haskell , 1080 1033 Bytes

;
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; ; ; 

Probieren Sie es online aus!

Erläuterung

Dies war für Haskell eine interessante Aufgabe.

Parität

Zu Beginn müssen wir feststellen, ob ein Zeichen einen geraden oder einen ungeraden Codepunkt hat. Der normale Weg, dies zu tun, besteht darin, den Codepunkt abzurufen und um 2 zu modifizieren. Wie man jedoch wissen könnte, erfordert das Abrufen des Codepunkts eines Zeichens einen Import, was aufgrund der Quellenbeschränkung bedeutet, dass dies nicht möglich ist gebraucht. Ein erfahrener Haskeller würde denken, Rekursion zu verwenden. Charsind Teil der EnumTypklasse, damit wir ihre Vorgänger und Nachfolger bekommen können. Allerdings predund succist auch beide unbrauchbar , weil sie keine alternative Byteparität tun.

Das lässt uns ziemlich stecken, wir können so gut wie keine Manipulationen mit Zeichen durchführen. Die Lösung hierfür besteht darin, alles fest zu codieren. Wir können (die meisten) geraden Zeichen als Literale darstellen, Chancen, mit denen wir Probleme haben, weil sie 'ungerade sind, so dass sie nicht neben dem Zeichen selbst stehen können, was es dem Literal unmöglich macht, die meisten ungeraden Zeichen auszudrücken. Also codieren wir alle geraden Bytes hart und fügen am Ende einen Catch für alle ungeraden Bytes hinzu.

Das Problem Bytes

Möglicherweise stellen Sie fest, dass es einige gerade Bytes gibt, für die Literale nicht in einfache Anführungszeichen gesetzt werden können. Sie sind die Unprintables, Newlines und \. Wir müssen uns keine Gedanken über nicht druckbare Dateien machen, da wir keine überprüfen müssen, solange wir keine verwenden. Tatsächlich können wir immer noch ungerade nicht druckbare Dateien wie Tabs verwenden, die ich am Ende einfach nicht brauche. Newline kann natürlich ignoriert werden, da es sowieso aus dem Programm entfernt wird. (Wir könnten Newline einfügen, da der Code-Punkt ziemlich praktisch ist, aber wir müssen nicht). Damit bleibt \nun \der Codepunkt 92, der zweckmäßigerweise eine ungerade Zahl gefolgt von einer geraden Zahl ist, also \92zwischen Evens und Odds wechselt, also das Literal'\92'ist vollkommen gültig. Wenn wir später Newline darstellen müssen, werden wir feststellen, dass es zum Glück dieselbe Eigenschaft hat '\10'.

Abstandsprobleme

Um mit dem Schreiben des eigentlichen Codes beginnen zu können, müssen wir in der Lage sein, eine beträchtliche Anzahl von Zeichen in eine einzelne Zeile zu setzen. Um dies zu tun, schrieb ich die Kappe:

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

Die Kappe macht nichts anderes als gültige Haskell. Ich hatte ursprünglich gehofft, Definitionen zu erstellen, die uns später im Code helfen würden, aber das tat es nicht. Es gibt auch einfachere Möglichkeiten, die Obergrenze festzulegen, z. B. Leerzeichen und Semikolons, aber sie speichern auf diese Weise keine Bytes, sodass ich mich nicht darum gekümmert habe, sie zu ändern.

Hardcoder

Jetzt, da ich genug Platz in einer Zeile habe, beginne ich mit der Hardcodierung von Werten. Das ist meistens ziemlich langweilig, aber es gibt ein paar interessante Dinge. Zum einen können wir, sobald die Zeilen noch länger werden ;, mehrere Deklarationen in eine Zeile einfügen, wodurch wir eine Menge Bytes sparen.

Das zweite ist, dass wir gdie Zeilen ein wenig einrücken müssen , da wir nicht immer eine Zeile mit a beginnen können . Jetzt kümmert sich Haskell wirklich um die Einrückung, also wird es sich darüber beschweren. Wenn jedoch die letzte Zeile vor der eingerückten Zeile mit einem Semikolon endet, wird dies zugelassen. Warum? Ich habe nicht die geringste, aber es funktioniert. Wir müssen uns also nur daran erinnern, die Semikolons am Ende der Zeilen zu platzieren.

Funktionsbausteine

Sobald der Hardcoder fertig ist, läuft es reibungslos bis zum Ende des Programms. Wir müssen ein paar einfache Funktionen erstellen. Zuerst baue ich eine Version von drop, genannt i. iunterscheidet sich davon, dropdass wenn wir versuchen, über das Ende der Zeichenfolge hinauszugehen, diese nur zurückgegeben wird "y". iunterscheidet sich von drop auch darin, dass beim Versuch, eine neue Zeile zu löschen, diese zurückgegeben wird "y". Diese sind nützlich, da wir später, wenn wir überprüfen, ob das Programm ein Dreieck ist, zurückkehren können, Falsewenn die letzte Zeile nicht vollständig ist oder wenn Eine Zeile endet früh.

Als nächstes haben wir, kwas tatsächlich bestätigt, dass eine Zeichenfolge dreieckig ist. kist ziemlich einfach, es braucht eine Zahl und eine Zeichenkette . Wenn leer ist, wird es zurückgegeben . Wenn die Zeichenfolge mit einer neuen Zeile beginnt, werden die neue Zeile und Zeichen von vorne entfernt. Es ruft dann erneut mit und der neuen Zeichenfolge auf. Wenn die Zeichenfolge nicht mit einer neuen Zeile beginnt, wird sie zurückgegeben .s s n n + 1nssTruenkn+1False

Wir machen dann einen Alias ​​für k, m. msteht nur kmit 1im ersten Argument, und dem zweiten Argument wird eine neue Zeile vorangestellt.

Als nächstes haben wir o. onimmt eine Zahl und eine Zeichenfolge. Es wird bestimmt, ob sich die Zeichenfolgenbytes (ohne Berücksichtigung von Zeilenumbrüchen) in der Parität abwechseln (unter Verwendung unserer g), beginnend mit der eingegebenen Nummer.

Zuletzt haben wir swelche omit beiden läuft 1und 0wenn es gelingt, verschiebt es sich m. Wenn beide fehlschlagen, wird nur zurückgegeben False. Dies ist die Funktion, die wir wollen. Es stellt fest, dass die Eingabe dreieckig und abwechselnd ist.

Ad-hoc-Garf-Jäger
quelle
1
Eine dreieckige Zeichenfolge beginnt mit einer 1-stelligen Zeile, nicht mit einer leeren Zeile.
Jakob
@ Jakob Ich denke, das ist dumm, aber es war eine einfache Lösung.
Ad-hoc-Garf-Jäger
3

05AB1E , 34 26 Bytes

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

Probieren Sie es online aus!

Nimmt die Eingabe als mehrzeilige Zeichenfolge (Eingabe zwischen "" " ). Erläuterungen folgen später.

Kaldo
quelle
1
Sofern ich die Regeln nicht falsch verstanden habe, muss das Programm in der Lage sein, Eingaben auch beginnend mit einer neuen Zeile zu validieren.
Emigna
@Emigna Ich denke, Ihr Programm muss nur dann in der Lage sein, eine führende Newline zu validieren, wenn es selbst mit einer führenden Newline beginnt.
Ton Hospel
Ich habe keine Ahnung, ob dies korrekt ist (ich bin schrecklich darin, Spezifikationen zu lesen): Probieren Sie es online aus!
Magic Octopus Urn
@MagicOctopusUrn Ihre Antwort sieht für mich in Ordnung aus, aber ich frage mich über die Eingabe: Dürfen wir sie als Array verwenden? In Ihrem Link ist Ihre erste Eingabe ein leeres Leerzeichen, kein Zeilenumbruchzeichen.
Kaldo
1
Hey, ich hoffe, dass dies nicht zu viel mit Ihrem Code zu tun hat, aber Sie können die führende Newline-Validierung löschen.
Dom Hastings
1

Java 10, 209 Bytes

Ein leeres Lambda, das ein iterables oder Array von nimmt byte. Gibt true an, indem normal zurückgegeben wird, false, indem eine Laufzeitausnahme ausgelöst wird. Das Programm erwartet, dass die letzte Zeile ordnungsgemäß beendet wird, dh mit einem Zeilenumbruch endet. Die letzte Zeile des Programms wird ebenfalls beendet.

Alles wird unter UTF-8 ausgeführt, mit der Interpretation, dass "Zeichen" sich auf Unicode-Codepunkte bezieht.

Tabulatoren werden in dieser Ansicht durch Leerzeichen ersetzt.

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*/ }

Probieren Sie es online aus

Hex Dump

Zurücksetzen unter xxd -p -rUnix.

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
        ;
    }
}

fist die erwartete Anzahl von Zeichen in der aktuellen Zeile, hist die Anzahl der Zeichen, die bisher in der aktuellen Zeile gesehen wurden, cist das letzte gesehene Byte und bist, ob aes sich um die neue Zeile handelt.

Die Bedingung a > -65prüft, ob aes sich um das erste Byte in einem Zeichen handelt. Dies funktioniert, weil die Einzelbytezeichen (ASCII) im 8-Bit-Zweierkomplement nicht negativ sind, das erste Byte längerer Zeichen eine binäre Form hat 11xxxxxx(mindestens -64 im Zweierkomplement) und die nicht führenden Bytes in diesen Zeichen von sind die Form 10xxxxxx, höchstens -65 in Zweierkomplement. ( Quelle )

Wenn ein Zeichen das Dreiecks- oder Schachbrettmuster verletzt (dh eine neue Zeile erscheint früh oder spät oder ein Byte der falschen Parität erscheint), wird der linke Zweig des entsprechenden ternären (in Zuordnung zu foder c) aktiviert und die Methode löst eine arithmetische Ausnahme aus.

Jakob
quelle
0

Python 3 (3,4?), 350 Bytes

Eine knifflige Herausforderung für eine Sprache, die sich besonders mit Leerzeichen wie Python 3 befasst. Die Übermittlung wird gedruckt 0oder 1standardisiert und stürzt bei einigen Eingaben ab. Das Programm erwartet, dass die letzte Zeile ordnungsgemäß beendet wird, dh mit einem Zeilenumbruch endet. Die letzte Zeile des Programms wird ebenfalls beendet. UTF-8 wird verwendet, um die Byte-Parität zu überprüfen.

Tabulatoren werden in dieser Ansicht durch Leerzeichen ersetzt.

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

Funktioniert für mich mit Python 3.4.2; funktioniert unter Python 3 unter TIO nicht. Scheint mir ein Fehler in den Dolmetschern von TIO zu sein.

Hex Dump

Zurücksetzen unter xxd -p -rUnix.

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202330313031300a
Jakob
quelle