Tipps zum Golfen in SmileBASIC

11

SmileBASIC verdient mehr Aufmerksamkeit. Ich habe hier nur 3 Benutzer gesehen (einschließlich mich selbst!), Die SB-Antworten gegeben haben, und obwohl mich das nicht überrascht, enttäuscht es mich. Es ist eine bezahlte Sprache und ein BASIC-Dialekt, der die Leute sicherlich abschreckt , aber für diejenigen, die es besitzen, ist es tatsächlich ziemlich flexibel und überraschenderweise golffähig. Ich dachte, ich würde diesen Tipp-Thread dafür öffnen und sehen, was auf mich zukommt.

Ich erwarte, dass 12Me21 häufig besucht wird :)

Schnecke_
quelle

Antworten:

11

Ersetzen string!=""durchstring>""

Mit SB können Sie mehr / weniger Vergleiche für Zeichenfolgen basierend auf ihren Codepunkten durchführen. Die leere Zeichenfolge wird jedoch als die kleinste Zeichenfolge betrachtet, die es gibt.

In Situationen, in denen Sie dies tun string!="", können Sie entweder string>""oder verwenden ""<string, da jede Zeichenfolge größer als ""und ""kleiner als jede Zeichenfolge ist. Abhängig davon, ob Sie eine Anweisung verwenden <oder >davon, ob die Anweisung vor oder nach einer gültigen Syntax Leerzeichen benötigt, wodurch Sie auch Bytes sparen können.

Beispielsweise:

WHILE S$!=""

kann in verwandelt werden

WHILE S$>""

und weiter Golf gespielt

WHILE""<S$
Schnecke_
quelle
Alle Saiten sind wahr. Sogar leere.
Schnecke_
Ah, okay. Macht Sinn.
Rɪᴋᴇʀ
6

Mit ?, ., @und nicht geschlossenen Strings

Viele Dialekte von BASIC unterstützen das ?Drucken, und SB ist keine Ausnahme. Eine extrem kurze Textausgabefunktion ist ein großer Vorteil.

Wird in SmileBASIC .ausgewertet 0.0, sodass es anstelle von 0 verwendet werden kann, um Platz zu sparen. Zum Beispiel: SPSET 0,21kann sein SPSET.,21, 1 Byte zu speichern. ( SPSET0,21ist ungültig, weil es SPSET0sich um eine benutzerdefinierte Funktion handeln könnte) EXEC.ist eine extrem kurze Möglichkeit, eine Programmschleife für immer zu erstellen (sie setzt jedoch alle Ihre Variablen zurück, sodass sie nicht immer verwendet werden kann).

Beschriftungen (verwendet für GOTO, GOSUBund Lesen DATA) werden wie @LABELin SmileBASIC dargestellt. Wenn sie in einem Ausdruck verwendet werden, werden sie tatsächlich als Zeichenfolgen behandelt. Zum Beispiel BGMPLAY"@305C"kann geschrieben werden alsBGMPLAY@305C

Zeichenfolgen werden am Ende einer Zeile (oder am Ende des Programms) automatisch geschlossen. ?"Hello, World!"kann geschrieben werden als ?"Hello, World!. Dies kann auch verwendet werden , um Programme zu machen besser lesbar , indem sie in mehrere Zeilen Splitting , ohne die Länge zu ändern: ?"Meow"BEEP 69kann sein

?"Meow
BEEP 69
12Me21
quelle
Wow, die Verwendung von Labels zum Starten von MML ist verrückt. Ich hätte nie daran gedacht, obwohl es Ihren Zeichensatz einschränkt.
Schnecke_
Ein anderer Ort, an dem ich es verwendet habe, war zu überprüfen, ob eine hexadezimale Ziffer eine Zahl oder ein Buchstabe war: @A<POP(H$)ist kürzer als "@"<POP(H$)(das Aspielt keine Rolle, es überprüft immer nur das erste Zeichen, da es niemals dasselbe sein wird)
12Me21
3

Verwenden Sie stattdessen die Zeichenfolgenindizierung MID$

Die MID$Funktion ist in vielen BASICs eine übliche Funktion, um einen Teilstring von irgendwo in der Mitte eines Strings abzurufen. Wenn Sie das Zeichen jedoch nur an einem Index abrufen müssen, ist die Indizierung von Zeichenfolgen weitaus kürzer. Beispielsweise:

PRINT MID$("ABC",2,1)
PRINT "ABC"[2]

Beide drucken C. Strings unterstützen die Array-ähnliche Indizierung auf Zeichenbasis. Wenn Sie also jeweils nur ein Zeichen überprüfen müssen, ist dies der beste Weg, dies zu tun.

Schnecke_
quelle
Sie sollten darüber sprechen, wie Zeichenfolgen auf diese Weise geändert werden können. A$=@AA:A$[2]="BD":A$[0]="":A$[2]="C"
12Me21
Ich werde wahrscheinlich eine Reihe von Antworten darüber schreiben, wie Strings im Grunde Zeichenarrays sind, aber noch besser, weil es eine ziemliche Aufgabe ist, alles in einem zusammenzufassen.
Schnecke_
... oder du könntest welche schreiben;)
snail_
Ich bin nicht sehr vertraut damit, wie es in anderen Sprachen funktioniert.
12Me21
2

Wann zu verwenden :(oder nicht)

Das :Zeichen wird in SB als Statement-Breaker verwendet. Grundsätzlich verwenden Sie es, um Anweisungen wie folgt in einer Zeile zu stapeln:

PRINT "HELLO!":PRINT "GOODBYE!"

Andernfalls wird Ihre durchschnittliche Aussage durch einen Zeilenumbruch unterbrochen:

PRINT "HELLO!"
PRINT "GOODBYE!"

In der Realität müssen Sie den Doppelpunkt häufig überhaupt nicht verwenden. Solange Anweisungen in syntaktisch gültige Token unterteilt werden können, neigt der Parser dazu, herauszufinden, wann eine endet und die andere beginnt. Das gleiche gilt oft für Leerzeichen.

PRINT"HELLO!"PRINT"GOODBYE!"

Das funktioniert natürlich nicht immer. Es gibt immer mehrdeutige Fälle und ungültige Syntaxen, in denen Sie Anweisungen explizit unterbrechen müssen. Nehmen Sie zum Beispiel:

PRINT "HELLO";END

Das Semikolon bedeutet, dass PRINTerwartet wird, dass ein anderer Ausdruck ausgedruckt wird, es sei denn, die Anweisung bricht dort ab (wir verwenden baumelnde Semikolons, um die neue Zeile zu unterdrücken). Hier ENDwird angenommen, dass es sich trotz eines Schlüsselworts um einen Wert handelt, und es wird versucht, ihn zu drucken in einem Fehler. Daher müssen wir diese Aussage explizit brechen, sei es der Doppelpunkt oder die Newline.

Wenn etwas mehrdeutig erscheint, versuchen Sie es im Allgemeinen, um festzustellen, ob es funktioniert. Wenn dies nicht der Fall ist, brechen Sie die Anweisung. Darüber hinaus wird alles, was zu einer ungültigen Syntax führen würde, nicht korrekt hervorgehoben, wie in 12Me21 erwähnt.

Schnecke_
quelle
2

Verwenden Sie den Syntax-Textmarker!

Der Code-Editor von SmileBASIC verfügt über einen integrierten Syntax-Textmarker, mit dem bestimmt werden kann, ob Code funktioniert oder nicht. Wenn Sie dies beispielsweise versuchen, BEEP0wird es nicht hervorgehoben, da zwischen einer Funktion und einer Ziffer ein Leerzeichen stehen muss. Funktioniert aber BEEP., weil. ist keine Ziffer.

Normalerweise ist Code wie X=7BEEPgültig, da Funktionen nicht mit einer Zahl beginnen können. SB geht davon aus 7und BEEPist getrennt. Jedoch. X=7ENDist NICHT erlaubt (und nicht hervorgehoben), da es versucht, 7E...als Zahl zu interpretieren , aber da nach dem E keine Ziffer steht, schlägt dies fehl und verursacht einen Fehler. Normalerweise ist dies ziemlich schwer herauszufinden, aber mit einem sehr zuverlässigen Syntax-Textmarker ist es viel einfacher zu sagen, was Sie können und was nicht.

Mein SmileBASIC-Syntax-Textmarker ist so konzipiert, dass er (hoffentlich) perfekt zum Verhalten von SB passt, sodass Sie damit überprüfen können, ob der Code gültig ist.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://12Me21.github.io/sbhighlight3/sbhighlight.js"></script>
		<link rel="stylesheet" type="text/css" href="https://12Me21.github.io/sbhighlight3/style.css">
		<link rel="stylesheet" type="text/css" href="https://12Me21.github.io/external/smilebasicfont.css">
		<script>
			function update(event){
				$code.textContent=$input.innerText;
				//must be innerText since contentedible and textContent are too dumb to understand linebreaks
				//contenteditable adds <br>s which textContent ignores
				//whyyyyy
				applySyntaxHighlighting($code,true);
			}
			
			function setCaretPosition(elem,caretPos){
				if(elem){
					if(elem.createTextRange) {
						var range=elem.createTextRange();
						range.move('character',caretPos);
						range.select();
					}else{
						if(elem.selectionStart){
							elem.focus();
							elem.setSelectionRange(caretPos,caretPos);
						}else
							elem.focus();
					}
				}
			}
		</script>
		<style>
			#editcontainer{
				position: absolute;
			}
			#editcontainer>pre{
				position: absolute;
				left: 0;
				top: 0;
				
			}
			pre.csssucks *{
				color:transparent !important;
				background-color:transparent !important;
				caret-color: white;
			}
			pre.csssucks {
				color:transparent !important;
				background-color:transparent !important;
				caret-color: white;
				border-color:transparent;
				padding-right: 50ch;
			}
		</style>
	</head>
	<body>
		Use SB font:<input type="checkbox" autocomplete="off" onchange="$code.dataset.sbfont=$input.dataset.sbfont=this.checked;update()"></input>
		<button onclick="update()">force update</button>
		<hr>
		<div id="editcontainer">
			<pre id="$code">test</pre>
			<pre id="$input" class="csssucks" contenteditable="true" spellcheck="false" onkeydown="setTimeout(function(){update(event)},2);">test</pre>
		</div>
	</body>
</html>

12Me21
quelle
1

Vermeiden Sie den MOD-Operator

Der Moduloperator ist sehr lang und sollte nach Möglichkeit vermieden werden.

Wenn Sie Zeichen aus einer Zeichenfolge erhalten, können Sie stattdessen einfach die Zeichenfolge wiederholen:

"ABC"[X MOD 3]
("ABC"*9)[X] (assuming X will always be less than 27)

Manchmal können Sie ANDstattdessen 1 Zeichen speichern mit :

X MOD 4
3AND X
12Me21
quelle
0

OUTRückgabewerte weglassen

Eine OUTFormularfunktion ist eine Funktion mit mehreren Rückgaben. Sie geben die Variablen an, die die Rückgabewerte nach dem OUTSchlüsselwort akzeptieren sollen . Ein Beispiel mit DTREAD:

DTREAD OUT yearVar,monthVar,dayVar

Aber was ist, wenn Sie nur einen der Werte wie den aktuellen Monat möchten? Sie können den Rest der Werte "ignorieren", indem Sie einfach keinen Variablennamen schreiben, um sie zu akzeptieren! Sie müssen jedoch die Kommas eingeben (abgesehen von der gelegentlichen optionalen Rückgabe).

DTREAD OUT ,monthVar,

Welches kann weiter Golf gespielt werden

DTREAD OUT,M,
Schnecke_
quelle
0

Verwenden LAST()

Jetzt, da SmileBASIC 4 in Japan erhältlich ist, können wir einige der potenziellen Golfeinsparungen prüfen. Eine, die mir sofort auffällt, ist die neue LAST()Funktion, die den letzten Index eines Arrays oder Strings zurückgibt. Sie können ein Byte speichern.

LEN(v)-1 'old way
LAST(v)  'new way
Schnecke_
quelle