Советы по игре в гольф в TI-BASIC

26

Какие общие советы у вас есть для игры в гольф в TI-BASIC для калькуляторов серии TI-83/84 +? Я ищу идеи, которые могут быть применены к задачам кода-гольфа и которые, по крайней мере, несколько специфичны для TI-BASIC (например, «удалить комментарии» - это не ответ).

Пожалуйста, оставьте один совет за ответ.

lirtosiast
источник
6
Пожалуйста, всегда указывайте, к какой версии вы обращаетесь!
flawr

Ответы:

22

Ваш калькулятор достаточно умен для определения конца строки, поэтому вы можете опустить немало символов.

:Disp "HELLO WORLD    //is the same as...
:Disp "HELLO WORLD"

For(циклы имеют такой синтаксис - For(variable, start, end, increment), но вы можете опустить приращение, и он будет использовать 1:

:For(A,1,5     //is the same as...
:For(A,1,5,1)

и вы можете опустить завершающие скобки (в конце строк) по всей доске:

:Output(1,1,A
:int(A
:round(A
etc.

Проверено на моем калькуляторе TI-84 Silver Edition

Если вы думаете, что это более чем одна идея (вывод окончаний), я разделю их

Стрейч маньяк
источник
5
.... это просто неправильно 😭
Бета-распад
2
Также попробуйте переписать код, чтобы использовать наименьшее количество закрывающих скобок. Только в последнем выражении каждой строки вы получаете круглые скобки бесплатно, поэтому переместите большинство вложенных операторов в конец. То есть not(iPart(B))+(A=5может быть (A=5)+not(iPart(B.
lirtosiast
4
Это относится ко всему, что требует закрытия, а не только к круглым скобкам (а именно {lists}, "strings"и [[matrices]]). Выражения будут автоматически закрываться, когда вы достигнете новой строки, двоеточия (заменитель новой строки; однако не применяется к строкам, так как они могут содержать двоеточия) или стрелку присваивания переменной ( набирается с помощью кнопки STO ▶ ` ). Такая странная особенность языка.
МИ Райт
14

использование Ans

Если вы будете использовать только выражение в следующей строке, не сохраняйте его в переменной! Специальная переменная Ans - это однобайтовый токен, в котором хранится значение последнего вычисленного выражения. Таким образом:

Xsin(A)->R
Disp R+tanh(R

может быть

Xsin(A)
Disp Ans+tanh(Ans

сохраняя два байта.

lirtosiast
источник
9

Используйте таблицу поиска, закодированную в числах с плавающей точкой

Немного продвинутый совет:

Маленькие справочные таблицы полезны для гольф-кода: очень часто нам нужна функция, которая отображает, например, от 0 до 1, от 1 до 2, от 2 до 1, а все остальное на 0. Однако массивы TI-BASIC не подходят для этого: с одной стороны, они основаны на одном, а с другой, значение не может быть извлечено до тех пор, пока не будет сохранен массив Ansили переменная списка.

В моем ответе здесь , я храню небольшую таблицу поиска в постоянной волшебной в основе 11. Просто перечислите значения , которые вы хотите использовать,

{0,-1,5,-1,-1,2,9,-1,8,6}

преобразовать в полезную форму

{1,0,6,0,0,3,10,0,9,7}

напишите в нужной вам базе (база 11)

.106003A097

и преобразовать в базу 10

-1+int(11fPart(11^Ans.0954191904

Подход кратчайшего массива на 8 байт длиннее!

{1,0,6,0,0,3,10,0,9,7}-1:Ans(X+1

TI-BASIC сохраняет только числа с плавающей запятой до 14 десятичных цифр, поэтому вы можете хранить до 44 битов, но только до 14 десятичных цифр.

Эту технику часто можно усовершенствовать, используя поиск методом грубой силы, чтобы найти магическую константу, а не кодирование по основанию N. Я все еще нахожусь в процессе игры над ответом выше, но легендарный гольфист TI-BASIC Weregoose использовал этот метод для генерации различий между числами, взаимно простыми с 30 (то есть повторяющимся списком 6, 4, 2, 4, 2, 4, 6, 2) в вики / форуме TI-BASIC Разработчик с этим фрагментом:

2+2iPart(3fPart(576e^(fPart(I/8

Магическая константа 576 была найдена с помощью Mathematica, но если у вас нет копии, используйте скрипт на вашем любимом языке.

lirtosiast
источник
5

Положите повторяющиеся выражения уравнения переменных.

EX:

Remainder(randInt(1,9),1
Remainder(randInt(1,9),5
Remainder(randInt(1,9),10

Может быть:

"randInt(1,9→u
Remainder(u,1
Remainder(u,5
Remainder(u,10

Примечание: трудно найти хорошее применение для этого, но это не значит, что вы должны забыть переменные уравнения: P

Источник: http://tibasicdev.wikidot.com/selfmodify

-c4ooo от Омнимага

user1812
источник
В этом примере вы можете сэкономить больше, добавив nк первому выражению вместе с Remainder(функцией.
Конор О'Брайен
5

Пропустить ненужную инициализацию переменной

В настоящее время принято решение разрешить запуск всего кода на новом интерпретаторе. Мы можем воспользоваться этим - все неинициализированные действительные переменные начинаются 0с TI-BASIC и Xminначинаются как возможно полезное значение -10. Так что, если вам когда-нибудь понадобится взять промежуточный итог в программе, которая не принимает входные данные от Ans, или вам действительно нужен всего -10один байт, этот совет может вам помочь.

lirtosiast
источник
Xmax = 10, а Ymin и Ymax ведут себя одинаково, верно? Также есть некоторые другие параметры графика, которые имеют некоторые другие значения, я думаю.
Фабиан Релинг
5

Меньшая генерация списка

Если вам нужен список {1,2,...,N}, где N, скажем, 42, очевидный способ создать его

seq(X,X,1,42. 

Тем не менее, на один байт меньше, чем это аккуратно, используя команду binomcdf((кумулятивное биномиальное распределение).

cumSum(binomcdf(41,0

Это работает только тогда, когда N является константой, поскольку экономия достигается за счет замены N-1 его значением в коде.

Есть два случая, которые позволяют еще более короткий код.

Если у вас уже есть список L1измерения N:

cumSum(1 or L1

Если вы не заботитесь о заказе:

randIntNoRep(1,N     ;random permutation of numbers from 1 to N
lirtosiast
источник
2
Гарантируется, что он на один байт меньше (и тупо медленнее), чем seq(X,X,1,Nдаже когда Nон не постоянен cumSum(1 or rand(N.
Миша Лавров
4

Устранить операторы End для блоков If в конце программы

Сохраняет два байта: один для конца и один для перевода строки. Это также позволяет вам использовать подразумеваемый Disp в последней строке, часто сохраняя дополнительный байт.

[code]
If A>5
Then
Output(1,1,Ans²+Ans+A
Disp 3ln(A
End
//end of program

Может быть:

[code]
If A>5
Then
Output(1,1,Ans²+Ans+A
3ln(A
//end of program
lirtosiast
источник
Следует отметить, что этот совет не работает для блоков цикла. +1 за хороший совет, хотя
Тау
4

Знай свои идиомы

Вот некоторые фрагменты, которые я обычно использую в коде гольф:

  • Преобразовать в истинное значение (0/1): not(not(Ansили Ans and 1. Какой из них использовать, зависит от необходимых скобок.
  • Добавьте одно к значению истины int(e^(Ans. Сохраняет открытую пареню 1+(Ans. Очень полезно, потому что TI-BASIC имеет одноосновные массивы.
  • Карта {0,1}для {1,-1}: cos(πAns. Сохраняет один байт 1-2Ans.

  • Функция знака числа: tanh(ᴇ9Ans
  • Вокруг к положительной бесконечности: -int(-Ans
  • Количество цифр в положительном целом числе: 1+int(log(Ans
  • Комплексный номер к списку {Re,Im}:imag(Ans{i,1

  • Преобразовать строку в список: seq(inString("...",sub(Ans,X,1)),X,1,length(Ans(где ...находится строка поиска)
  • Отрубить первый элемент списка: ΔList(cumSum(Ans
  • Отрубить последний элемент списка: ΔList(cumSum(Ans)-Ans
  • Проверьте, все ли элементы списка L1уникальны:SortA(L1:min(ΔList(L1
  • Поиск числа X в списке (возвращает первое вхождение): 1+sum(not(cumSum(Ans=X
  • Режим списка, когда существует один режим, и список содержит не более 10 элементов: (некрасиво, но коротко): median(Ans,10^(seq(sum(Ans=Ans(X)),X,1,dim(Ans
lirtosiast
источник
Я действительно не понимаю, почему tanh(ᴇ9Ansтот работает.
SuperJedi224
1
@ SuperJedi224 Хорошо, tanh (0 - ноль, а пределы бесконечности слева и справа - -1 и 1. Он экспоненциально приближается к этим значениям, так что за + -17 или около того он находится в пределах ошибки округления + -1. Если абсолютные значения уже больше 17, мы просто используем tanh (один.
lirtosiast
3

Если вы обнаружите, что используете

0→G ;or any other variable
;other lines of code

Затем вы можете использовать (чтобы сохранить байт):

DelVar G;other lines of code

Это происходит потому , что при удалении переменной ( G), она становится его значение по умолчанию, в этом случае 0. Затем вы можете поставить еще одну строку после DelVarоператора, без новой строки . Будьте внимательны при размещении критических контрольных операторов сразу послеDelVar оператора.

(Проверено на TI-84)

Конор О'Брайен
источник
Это редко полезно; переменные по умолчанию инициализируются в 0, и вы можете обнулить Y, выполнив ZStandard.
lirtosiast
@ThomasKwa Это было полезно для меня во многих случаях, особенно. когда требуется перезагрузка во время выполнения.
Конор О'Брайен
2
В коде гольф? Когда? Если вы покажете мне программу, думаю, я смогу оптимизировать DelVar.
Lirtosiast
@ThomasKwa Не xode golf как таковой , скорее программирование на малом дисковом пространстве (TI-83). У меня нет программы прямо сейчас. Я вернусь к вам по этому вопросу.
Конор О'Брайен
1
После нескольких минут размышлений я могу вспомнить пару сценариев, когда DelVar может быть самым коротким, например, после однострочных операторов If.
lirtosiast
3

Какие переменные списка использовать?

При использовании списков избегайте списков L₁по умолчанию L₆в пользу именованных списков с однобуквенными именами: ᶫAчерез ᶫZ(где маленькая буква L).

Либо один стоит два байта для ссылки (хотя L₁это один токен, это двухбайтовый токен), но при сохранении значений в списке вы можете удалить символ, сохранив байт:

{1,2,3,4,5→ᶫA

может быть

{1,2,3,4,5→A

Калькулятор проверяет тип данных выражения при решении, где хранится результат.

Аналогично, Input Aили Prompt Aбудет хранить вᶫA если пользователь вводит список вместо числа.

Несколько других команд могут использоваться без , хотя большинство из них редко используются в гольфе. Например, Matr►list(позволяет удалить его в третьем, четвертом и более высоком аргументах.

Общее правило состоит в том, что если команда принимает имя переменной списка, а не выражение списка , и если нет альтернативного синтаксиса, который мог бы поместить туда переменную другого типа, то команда могла бы работать с отключенным значением.

Это не работает с изменением одной записи списка: 1→ᶫA(3не может быть изменено на1→A(3 .

Конечно, лучшая переменная списка для использования всегда Ans.

Миша лавров
источник
Чего ждать? " Input A" сохраняется, ᶫAесли пользователь входит в список. "Это означает, что многие из моих программ довольно легко ломаются. Тогда хорошо, что у меня все равно не так много Inputпрограмм, в основном у меня есть либо небольшие инструменты без проверки ошибок, либо полные игры, которые используют GetKeyвместо Input.
Фабиан Релинг
1
Если вы действительно заинтересованы в защите своих программ от этого, вы всегда можете сохранить случайное значение Aи проверить, изменилось ли оно после Input A.
Миша Лавров
2

Знайте свои переменные затраты назначения

Если вы используете время Bвыражения -byte N, следует ли назначать его переменной?

Ansстоит 1+Nиспользовать байты (по одному на разрыв строки и по одному на каждый раз, когда он используется, поэтому используйте Ans, когда (B-1)*(N-1)>2. Может быть только один Ansна строку, поэтому попробуйте все значения дляAns которые могут быть полезны.

Реальные переменные (например X) 3+Nбайты стоимости , поэтому используйте их, когда(B-1)*(N-1)>4 .

Перечислите переменные стоимости 3+2Nбайтов, поэтому используйте их, когда(B-2)*(N-1)>5 .

Переменные уравнения наименее полезны: им нужны 4+2Nбайты. Используйте их, когда (B-2)*(N-1)>6.

Min. bytes in an expression to save
 N \ var. | Ans | Real | List | Eqn
------------------------------------
 2           4     5      8      9
 3           3     4      5      6
 4           2     3      4      5

Когда функция вычисляется в виде списка, сохраните ее в виде списка, а не в виде переменной уравнения, подобной u; это экономит один байт.

Имейте в виду, что наличие или отсутствие закрывающих скобок часто может привести к тому, что сохранение выражений будет выгодным, если они переставлены.

Теперь я буду противоречить самому себе и скажу, что в одной строке нужно писать как можно больше кода. Зачем? Обычно, когда в строке длинное повторяющееся выражение, его можно упростить.

lirtosiast
источник
1

int (rand over randInt (

X + int (Yrand равен или меньше байтов, чем randInt (X, Y, поскольку randInt - это 2-байтовый токен. Некоторые потенциальные преимущества:

X + может быть опущен, когда нижняя граница равна 0, сохраняя два байта

X + необходим перед randInt (в любом случае, в определенных ситуациях, например, случайным образом из функции шага, такой как {2,5,8,11}

X + int (Yrand (N может использоваться как randInt (X, Y, N, чтобы сгенерировать список из N случайных чисел).

Инициализация графического экрана

Чтобы использовать такие функции, как Линия (легко с пиксельными координатами, необходимо инициализировать оси графического экрана квадратными пикселями и удалить оси:

AxesOff
84→Xmin
72→Ymax
ZInteger

зажим

min(U,max(L,N

Где N - число или алгоритм, а U и L - верхняя и нижняя границы

Есть N в списке

max(N={X,Y,Z

Подробнее Список математики

L1*L2→L3

instead of

for(A,1,dim(L1
L1(A)*L2(A→L3(A
End

This also works for things like this:
not(L1
L1 and L2

Выход

Disp и текст (могут быть объединены в цепочку, поэтому Disp A, B будет отображать A, а затем B в отдельных строках и текст (28,40, A, B будет печатать A рядом с B в одной строке).

Технология из оптимальной петли движения

Многие из этих оптимизаций являются частью технологии, используемой для перемещения символа по экрану в наименьшем количестве байтов.

http://tibasicdev.wikidot.com/movement

Списки размеров токенов

http://tibasicdev.wikidot.com/tokens

За помощь в подсчете очков

TiKevin83
источник