MATL打高尔夫球的秘诀


20

MATLLuis Mendo创建的一种高尔夫语言。事实证明,MATL具有很高的竞争力,经常击败其他高尔夫球语言,例如Pyth,CJam和Jelly。

在MATL打高尔夫球有哪些有用的技巧?(一如既往,请给每个答案一个提示!)


5
如果您了解一些Matlab / Octave,绝对是一个很大的优势。Matlab 中的打高尔夫球技巧Octave中的打高尔夫球技巧也提供了一些技巧。
瑕疵的

建议:它看起来像accumarrayXQ)可以说是相当强大的(甚至可能超过在MATLAB /倍频程,因为这些长度函数处理有方便的数字代码),但我不知道它不够好,说明具有很好的例子。如果它确实有用,那么有人可以提出一个使用它的想法的答案吗?
sundar-恢复莫妮卡

Answers:


7

了解预定义文字

尽管它们中的一些在复制到剪贴板时会保留信息,但是它们都有预定义的值。

  • F,按0(实际上为False
  • T,按1(实际上为True
  • H,按2(预定义的剪贴板值)
  • I,按3(预定义的剪贴板值)
  • K,按4(预定义的剪贴板值)
  • J,按0 + 1j(预定义的剪贴板值)

不知道我是否涵盖了所有预定义的值。


仅出于完整性考虑(并且如果您想添加到答案中):剪贴板的每个级别L也都有一个预定义的值,但是它们旨在用于特殊用途(而不是通用的通用值)。例如,1Lgives [1 0](用作index 1:end),2Lgives [0 -1 1](用于1:-1:end)。此外,默认情况下函数lO接受0输入01分别产生和
Luis Mendo

我看不出这有什么用...我不能只写4吗?
Cyoce '16

@Cyoce的用途是避免使用空格作为分隔符。如果你要推1的话414是不行的。您需要1 4。或者1K保存一个字节
Luis Mendo

@LuisMendo啊,我明白了。我想我以为是只使用1位数字的方法(不确定为什么)
Cyoce

1
K代替4方便的另一种情况是:1-4意思是:先推1,然后推-4;而1-K意味着:推入1,从堆栈中的下方减去,然后推入4
Luis Mendo

5

&元功能(可选输入/输出规范)

指定传递给函数的输入参数数量的传统方法是使用$元函数

2$:     % Two-input version of :

同样,要指定输出参数的数量,您可以使用#元函数指定输出参数的数量,

2#S     % Two-output version of sort

或者如果传递一个数字,大于的一个函数定义的输出参数的数量,mod(N, numberOfOutputs) + 1输出提供。

4#S     % Get only the second output of sort

您还可以指定逻辑数组作为输入,#以仅检索特定的输出参数。

TFT#u   % Three output version of unique and discard the second output

所有这些输入/输出规范都很方便,但是它们可以非常快速地提高字节数。为了解决这个问题,MATL &17.0.0版本中引入了元功能。此&元功能充当功能的特定输入或输出规范的快捷方式。让我们看看这意味着什么。

在上面的示例中,我们想使用的两个输入版本:(创建等距值的向量)。输入参数to的默认数量:1(从创建一个数组[1...N]),但用户通常会希望指定需要第二个输入的范围的起始值,这是常见的。因此:,我们已将其定义&为的快捷方式2$

10      % Push 10 to the stack
12      % Push 12 to the stack
2$:     % Create an array: [10, 11, 12] 

现在变成以下内容,保存一个字节

10 12 &:

我们如何确定备用参数是多少?

&转换为的输入/输出规范是特定功能的,以便我们优化字节节省。

每个功能帮助说明中的输入/输出参数部分已更新,以指示此替代输入/输出数量(如果有)。输入或输出参数的可能数量显示为一个范围,括号中显示每个参数的默认值。括号内&/字符后会显示可以替换的输入/输出规范。

这是帮助说明的输入/输出参数部分 :

 +- Min-Max range of # of inputs
 |        +----- Alt. Default # of inputs
 |        |
 V        V
1--3 (1 / 2); 1 <--- Possible / Default # of outputs
      ^       
      |       
  Default # of inputs

您如何确定&每种功能的含义?

非常小心。使用StackExchange API,我们能够下载在PPCG挑战中曾经使用过的所有MATL答案。通过解析每个答案,我们便能够确定将每个输入/输出规范用于每个功能的频率。然后,利用这些信息,我们可以客观地确定&元功能应代表每个功能的输入/输出规范。有时没有明确的赢家,因此许多功能目前尚未&定义。

这是我们使用的脚本(不幸的是,它是用MATLAB而不是 MATL 编写的)。

这里是一个直方图的例子$/ #使用


1
此功能由@Suever 建议。最初的&意思是“相对于默认值,输入数量增加1”。事实证明,他的建议有用得多
Luis Mendo

5

熟悉MATL的真实/虚假定义

虽然trueT)和falseF)分别清楚地表示真实和虚假的输出,但广泛认可的真实/虚假定义使我们在MATL中更具灵活性。

定义指出:

if (x)
    disp("x is truthy");
else
    disp("x is falsy");
end

因此,我们可以编写一个快速的MATL真实/虚假测试,该测试将遍历所有输入并显示它们是真实的还是虚假的

` ? 'truthy' } 'falsey' ]DT

这是在线版本。

这在MATL中意味着什么

这实际上在MATL中(因此在MATLAB和Octave中)转换为,如果条件为非空并且其所有值的实数分量都不为零,则认为该条件为true 。对此应强调两个部分。

  1. 非零:这恰恰意味着不等于零(==)。其中包括正数,负数,非空字符等。您可以通过将给定值转换为logical值(g)轻松进行检查,也可以使用~~

    F           % Falsy
    T           % Truthy
    0           % Falsy
    1           % Truthy
    2           % Truthy
    -1          % Truthy
    'a'         % Truthy
    ' '         % Truthy (ASCII 32)
    char(0)     % Falsy  (ASCII 0)  
    
  2. 所有值:通常,我们认为标量是对还是错,但是在MATL中,我们可以评估标量,行向量,列向量甚至多维矩阵,并且当且仅当每个单个值都是非零(如上定义),否则为假。这里有一些例子来说明

    [1, 1, 1]           % Truthy
    [1, 0, 0]           % Falsey
    [1, 1, 1; 1, 1, 1]  % Truthy
    [1, 0, 1; 1, 1, 1]  % Falsey
    'Hello World'       % Truthy
    

如上所述,一个边缘情况是一个空数组[],该数组总是被认为是虚假的(示例

我怎样才能更好地打高尔夫球?

如果挑战只是提到您的输出应该是真实的还是虚假的,则您可以利用上面的定义将答案减少几个字节。为避免混淆,建议您在答案中包含指向上面的在线真实/虚假测试的链接,以帮助说明MATL真实/虚假值是如何工作的。

几个具体的例子:

  • 答案以结尾A。如果挑战需要truthy或falsy输出和你结束你的答案allA)创建一个标量,你可以删除这个最后一个字节和你的回答将保持正确的(除非输出是[]因为[]false不过[]Atrue)。

  • 确保数组仅包含一个唯一值&=代替un1=。如果数组中的所有值相等,则广播的逐元素相等性比较将得出N x N所有矩阵。如果所有值都不相等,则此矩阵将包含一些0值,因此被认为是虚假的。


4

隐式输入

大多数功能接受一定数量的输入。这些输入取自堆栈的顶部。如果栈顶没有足够的参数,它将从输入中提取剩余的参数。(请参阅文档中的7.3节)我想引用原始解释:

隐式输入可以如下所示:堆栈无限扩展到底部下方,即在位置0,-1,-2,...处,其值最初并未定义,但可以通过隐式输入即时解析。仅在需要时才按需要的顺序从用户询问这些输入。如果同时需要多个输入,则它们遵循正常的堆栈顺序,即,首先输入(扩展)堆栈中最深的输入。


2
隐式输入是@flawr建议的功能
Luis

6
@flawr一定是一个非常聪明的人。:D
瑕疵的

3

逻辑数组通常可以用作数字数组

您通常可以使用“ TF”表示法来代替零和一的数组文字。例如,FTF与相同[0,1,0],仅FTF产生logical值,而不产生double值。这通常不是问题,因为任何算术运算都将逻辑值视为数字。例如,FTFQ给定[1,2,1]Q是“增加1”)。

在某些情况下,数字到二进制的转换可能会更短。例如,[1,0,1]TFT5B是相同的; 再次警告,后两个是logical值。


TF(逻辑)和[1 0](数字)之间的差异用作索引时。logical用作索引的类型数组意味着:选择与相对应的元素T,舍弃与相对应的元素F。因此,[10 20]TF)生产10(选择第一个元素),而[10 20][1 0])生产[10 20](索引[1 0]具有的解释1:end,即选择数组的所有元素)。


3

对于大小为n-1的循环

考虑更换

tnq:"...

td"...

保存最多一个字节或更多


@路易斯是真的!我以为可能需要循环的原始向量,但是在第一种方法中也不可能。将删除该评论。
桑契斯,2016年

但是您不一定要保存1个字节。您可以保存1或2,具体取决于您是否需要@/ X@在循环内。也许您可以说“保存字节”
Luis Mendo

3

将事物从循环后移到循环内,以利用隐式结束

如果循环end语句之后没有任何代码],则可以将其忽略。它们由MATL解析器隐式填充。

因此,如果您可以将内容从循环后移到循环内,则可以保存final ]

作为一个特定的示例,以下代码查找一个数字的阶乘中有多少个尾随零N(请参阅此处):

  • 代码从循环1N
  • 对于每个数字,它都会计算其主要因子,并确定5存在多少次。
  • 答案是出现的累计次数5(之所以有效5,是因为每次出现至少一次2)。

第一个想法是:"@Yf5=]vs(请注意,循环后有一些语句):

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
]      % End for
v      % Concatenate all vectors as a column vector
s      % Sum. Implicitly display

由于v默认情况下将所有堆栈内容串联在一起,因此可以将其移入循环。而且由于加法关联,s也可以移动。那留]在代码的末尾,因此可以省略:"@Yf5=vs

:      % Range from 1 to implicit input
"      % For each number in that vector
  @    %   Push that number
  Yf   %   Vector of prime factors (with repetitions)
  5=   %   True for entries that equal `5`, and `false` for the rest
  v    % Concatenate all vectors so far as a column vector
  s    % Sum. Inplicitly end loop and display

我不知道这种象形文字一样的毛钱,但我可能会在接下来的三个月中花大量时间学习它。
2016年

@ Agawa001 :-)您会发现它与Matlab非常相似。您也可以在此处
路易斯·门多

3

如果堆栈为空,则定义空数值数组的更短方法

要推送空的数字数组,通常使用[]。但是,如果堆栈为空,则可以使用来保存一个字节v。默认情况下,此函数垂直连接所有堆栈内容,因此,如果堆栈为空,则会生成空数组。

例如,您可以在这里看到它的实际效果。


2

与MATLAB或Octave相比,某些功能得到了扩展

如果您来自MATLAB或Octave,则会发现许多MATL函数类似于这些语言中的函数。但是其中许多功能已得到扩展。

例如,考虑MATLAB的reshape函数,该函数在MATL中与相对应 e。代码段reshape([10 20 30 40 50 60], 2, 3)reshape([10 20 30 40 50 60], 2, [])分别表示“重塑行向量[10 20 30 40 50 60成2×3矩阵”或“成2行矩阵与尽可能多的列按需要”。因此,两种情况下的结果都是二维数组

10    30    50
20    40    60

由于大小不兼容,类似reshape([10 20 30 40 50 60], 2, 2)reshape([10 20 30 40 50 60], 5, [])会产生错误。但是,MATL将在第一种情况下删除元素(在线尝试!),或者在第二种情况下用零填充(在线尝试!)以分别生成,

10 30
20 40 

10 60
20  0
30  0
40  0
50  0

与MATLAB对应项相比具有扩展功能的其他函数是(非穷举列表)Ssort),Ybstrsplit),mismember),hhorzcat),vvertcat),Zdgcd),Zmlcm),YScircshift),YAdec2base),ZAbase2dec),Z"blanks)。


1

获取第一个非零元素的索引(如果有)

f函数给出数组所有非零元素的索引。通常,您需要第一个非零元素的索引。那将是f1):应用f并选择其第一个元素。但是,如果原始数组不包含任何非零值,f则会输出一个空数组([]),并且尝试选择其第一个元素将产生错误。

一个常见的,更可靠的要求是,如果存在至少一个获取第一个元素的索引,[]否则。可以在if之后的分支完成此操作f,但这是字节昂贵的。更好的方法是fX<将最小值函数X<应用于的输出fX<当其输入为空数组时,返回一个空数组。

在线尝试!(请注意,根本不会显示一个空数组)。或者在这里查看工作示例。


1

生成范围与给定数组一样长

TL; WR:如果数组仅包含非零元素fn:则使用代替。


通常情况下,需要生成一个数组[1 2 ... L],其中L给定数组的元素数是。做到这一点的标准方法是n:。例如,代码tn:*将数字矢量作为输入,并计算每个条目乘以其索引。

如果保证给定的数组仅包含非零条目(例如,它由正整数组成,或者是具有可打印字符的字符串),则n:可以将替换为f,从而产生具有非零条目索引的数组。因此,上面的代码变为tf*,节省了1个字节。

一些更复杂的例子:123


1

高效定义数字数组文字

在定义数字数组文字时,可以使用以下几种方法来节省字节。链接给出了使用它们的示例答案。这些已使用@Suever创建的分析脚本获得。

串联和预定义文字

对于具有小的数字的阵列可以有时使用级联(功能hv),以及预定义的文本,以避免使用空间作为分隔符:比较[2 4]2 4h并且2Kh,所有这些限定阵列[2 4]。同样,2K1v使用空栈定义[2; 4; 1]实例

数字数组文字中的字母

对于稍大的数字,您可以利用一些字母在数组文字中具有数字含义的事实来节省空间。因此,[3 5 2 7;-4 10 12 5]可以代替使用[IAHC;dX12A]实例

具体来说,在数组文字中,

  • OlH I K具有通常的意义0,...,4
  • A,...,E意思是5,...,9
  • X 手段 10
  • a,... d卑鄙-1,...,-4
  • JG意味着1j-1j
  • P 手段 pi
  • Y 手段 inf
  • N意味着NaN

字符串和连续的差异

对于较大的数字,定义一个字符串并计算其连续的差异(使用d)会有所帮助:[20 10 35 -6]可以使用代替'!5?b\'d。之所以d可行,是因为使用字符的代码点来计算差异。实例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.