Поради щодо гольфу в SmileBASIC


11

SmileBASIC заслуговує більшої уваги. Я бачив тут лише 3 користувачів (включаючи мене!), Які надають відповіді на СБ, і хоча це мене не дивує, це мене розчаровує. Це платний язик, а також те, що він є базовим діалектом, безумовно, відмовляє людей, але для тих, хто ним володіє, він насправді досить гнучкий і, що дивно, гольф. Я подумав, що відкрию цю нитку для підказок і подивіться, що виходить.

Я очікую 12Me21 часто відвідувати :)

Відповіді:


11

Замініть string!=""наstring>""

SB дозволяє робити більші / менші порівняння рядків на основі їхніх кодових точок. Однак порожній рядок вважається найменшим наявним рядком.

Тож для ситуацій, коли ви це робите, string!=""ви можете використовувати або string>""або ""<string, оскільки кожен рядок є більшим ""та ""меншим, ніж кожен рядок. Залежно від того, використовуєте ви <чи >залежить від того, чи потрібний оператор пробіл до чи після, щоб бути дійсним синтаксисом, що також може зберегти ваші байти.

Наприклад:

WHILE S$!=""

можна перетворити на

WHILE S$>""

і далі гольфу до

WHILE""<S$

Всі струнні інструменти. Навіть порожні.
равлик_

Ага, гаразд. Має сенс.
Rɪᴋᴇʀ

6

Використовуючи ?, ., @і незакриті рядки

Багато діалектів підтримки BASIC ?для друку, і SB не є винятком. Наявність надзвичайно короткої функції виведення тексту є великою перевагою.

У SmileBASIC .оцінюється до 0.0, тому його можна використовувати замість 0 для економії місця. Наприклад: SPSET 0,21може бутиSPSET.,21 , зберігаючи 1 байт. ( SPSET0,21недійсна, оскільки SPSET0може бути функцією, визначеною користувачем) EXEC.- це надзвичайно короткий спосіб назавжди зробити цикл програми (але він скидає всі ваші змінні, тому він не завжди корисний)

Етикетки (використовуються для GOTO, GOSUBі читанняDATA ) представлені як @LABELв SmileBASIC. Якщо вони використовуються в виразі, вони насправді трактуються як рядки. Наприклад, BGMPLAY"@305C"можна записати якBGMPLAY@305C

Рядки автоматично закриваються в кінці рядка (або в кінці програми). ?"Hello, World!"можна записати як ?"Hello, World!. Це також можна використовувати для того, щоб зробити програми більш читабельними, розділивши їх на кілька ліній без зміни довжини: ?"Meow"BEEP 69можна

?"Meow
BEEP 69

Нічого, використання міток для запуску MML є божевільним. Ніколи б про це не думали, хоча це обмежує ваш набір персонажів.
равлик_

Ще одне місце, яке я використав, це перевірити, чи є шістнадцяткова цифра цифрою чи буквою: @A<POP(H$)коротше ніж "@"<POP(H$)( Aне важливо, він перевіряє лише перший символ, оскільки він ніколи не буде таким самим)
12Me21

3

Використовуйте строкову індексацію замість MID$

Ця MID$функція є загальною функцією у багатьох BASIC, щоб отримати підрядку десь посередині рядка. Однак якщо вам просто потрібно отримати символу в якомусь індексі, використання строкової індексації набагато коротше. Наприклад:

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

Обидва ці друковані C. Струни підтримують індексацію подібної масиву на основі символів, тому якщо вам потрібно перевіряти лише один символ одночасно, це найкращий спосіб зробити це.


Вам слід поговорити про те, як рядки можна змінити таким чином. A$=@AA:A$[2]="BD":A$[0]="":A$[2]="C"
12Me21

Я, мабуть, напишу набір відповідей про те, як рядки - це в основному масиви символів, але ще краще, тому що скласти все це в одне ціле завдання.
равлик_

... або ви могли щось написати;)
равлик_

Я не дуже знайомий з тим, як це працює іншими мовами.
12Me21

2

Коли використовувати :(чи ні)

:Символ використовується в якості заяви вимикача в SB. В основному, ви використовуєте його для складання операторів у одному рядку так:

PRINT "HELLO!":PRINT "GOODBYE!"

Інакше ваше середнє твердження порушено новим рядком:

PRINT "HELLO!"
PRINT "GOODBYE!"

Насправді вам часто зовсім не потрібно вживати товсту кишку. Поки заяви можуть бути розбиті на синтаксично допустимі лексеми, аналізатор прагне визначити, коли один закінчується, а інший починається. Те саме часто стосується пробілів.

PRINT"HELLO!"PRINT"GOODBYE!"

Звичайно, це не завжди працює. Завжди є неоднозначні випадки та недійсні синтаксиси, коли вам потрібно чітко порушувати заяви. Візьмемо для прикладу:

PRINT "HELLO";END

Крапка з комою означає , що PRINTочікує інший вираз для роздруківки, якщо не в заяві перерви там (ми використовуємо обірваних точку з коми для придушення нового рядка.) Тут передбачається , ENDмає бути значення, незважаючи на те ключове слово, і намагається надрукувати його, в результаті чого в помилці. Таким чином, ми повинні чітко порушити це твердження, чи то двокрапкою чи новим рядком.

Загалом, якщо щось здається неоднозначним, спробуйте перевірити, чи працює воно. Якщо цього немає, перервіть заяву. Крім того, все, що могло б створити недійсний синтаксис, не виділяється правильно, як було зазначено у 12Me21.


2

Використовуйте виділення синтаксису!

Редактор коду SmileBASIC має вбудований підсвічувач синтаксису, за допомогою якого можна визначити, чи буде код працювати чи ні. Наприклад, якщо ви намагаєтеся зробити BEEP0це, це не виділить його, оскільки між функцією та цифрою повинен бути пробіл. Однак BEEP.працює, тому що. не є цифрою.

Зазвичай код типу X=7BEEPє дійсним, оскільки функції не можуть починатися з числа, тому SB передбачає це 7і BEEPє окремими. Однак. X=7ENDНЕ дозволено (і не виділено), тому що воно намагається інтерпретувати 7E...як число, але оскільки після Е немає цифри, воно виходить з ладу, викликаючи помилку. Зазвичай це було б досить важко зрозуміти, але з дуже надійним підсвічувачем синтаксису набагато простіше сказати, що можна, а що не можна робити.

Мій підсвічувач синтаксису My SmileBASIC розроблений так, щоб (сподіваємось) ідеально відповідати поведінці SB, тому ви можете використовувати його, щоб перевірити, чи код дійсний.

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


1

Уникайте оператора MOD

Оператор модуля дійсно довгий, і його слід уникати, якщо можливо.

Якщо ви отримуєте символи з рядка, можете просто повторити рядок:

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

Іноді ви можете зберегти 1 символ за допомогою AND:

X MOD 4
3AND X

0

Пропускання OUTповернутих значень

Функція OUTформи - це одна з декількома поверненнями; Ви визначаєте змінні, щоб прийняти значення, що повертаються після OUTключового слова. Приклад із використанням DTREAD:

DTREAD OUT yearVar,monthVar,dayVar

Але що робити, якщо ви хочете лише одного зі значень, наприклад, поточного місяця? Ви можете «ігнорувати» решта значень, просто не записуючи жодного імені змінної, щоб прийняти їх! Однак ви повинні залишити комами (окрім випадкового необов'язкового повернення.)

DTREAD OUT ,monthVar,

До яких можна подати гольф

DTREAD OUT,M,

0

Використовуйте LAST()

Тепер, коли SmileBASIC 4 з'явився в Японії, ми можемо перевірити деякі потенційні заощадження на гольфі. Те, що негайно вискакує на мене, - це нова LAST()функція, яка повертає останній індекс масиву чи рядка. Ви можете зберегти один байт.

LEN(v)-1 'old way
LAST(v)  'new way
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.