佩斯高尔夫技巧


46

Pyth是一种由Python启发的过程编程语言,由PPCG用户isaacg创建。

您在Pyth打高尔夫球有哪些一般秘诀?我正在寻找可以应用于编码高尔夫球问题的想法,这些想法至少在某些方面是Pyth特有的。

请给每个答案一个提示。

Answers:


25

首先用Python编写代码

Pyth与Python非常相似,因此将Python程序转换为Pyth非常容易。但是,由于Pyth是每命令一个字母的语言,因此有时很难直接编写Pyth。通过首先使用Python编写,一次无需考虑太多(因为Python是一种非常容易编写的语言)。


1
您可能还提到,您仍然可以在Pyth中使用Python语法,因此您可以单独转换程序的某些部分,或者在必要时仅使用python。(就像您在此处所做的一样)
FryAmTheEggman 2014年

@ mbomb007下载Pyth解释器并阅读文档。这是我编写Pyth程序的唯一可靠方法。
贾斯汀

@ mbomb007抱歉;这就是我学习如何编写Pyth的方式(通过源代码查看)。基本上没有关于Pyth的文档。您基本上必须通过反复试验来学习语法。
贾斯汀

22

知道你的变量

Pyth具有3类变量:通用的预初始化变量,基于用户输入的预初始化变量以及在首次使用时隐式生成分配的变量。

通用变量:

b = "\n"
d = " "
k = ""
G = "abcdefghijklmnopqrstuvwxyz"
H = {}                            # (empty dict)
N = '"'
T = 10
Y = []
Z = 0

输入初始化的变量:

Q = eval(input())
z = input()

请注意,只有在代码中的字符串之外使用了关联的变量时,才会在给定程序中运行这些初始化。此外,如果两者都使用Q,则顺序为,则顺序为z

首次使用变量的分配:

JK。如果要将它们初始化为相同的值,则可以使用表达式(例如KJ0,它等同于lengthier)来进行初始化J0K0



12

行尾的字符串不需要用引号引起来。例如:

"Hello, world!

是完全有效的Hello World程序。


确实很明显,这是Google首次使用“ Pyth编程语言”。您是否在esolangs上创建了自己的页面?
theonlygusti 2015年

3
@theonlygusti是的,我做到了。而且,这不是去年10月的第一个结果。
isaacg 2015年

9

使用C为基础的压缩

这实际上是未记录的,字符串上的C实际上不是直接chr-> int,而是基数256->基数10(在一个char字符串上相同)。这在压缩int方面非常有用,我们可以使用以下脚本进行压缩:

sCMjQ256

12345678910,结果为ßÜ>(其中有些不可打印的内容)。

同样,使用整数数组,您可以将它们连接起来,并通过转换为代码点并将其视为基数128来使用大型字符串。

C感谢@xnor向我展示的另一种用法是制作任意大数。天真的方法是:

^TT

但是我们可以通过以下方法将字节做得更好:

CG

这个基数256对整个字母进行反转换。结果156490583352162063278528710879425690470022892627113539022649722=〜1.56e62


现在已添加到文档。
isaacg


8

使用简短的功能...错误...功能

当lambda参数应用于参数mapreduce仅对参数应用一个操作时,可以使用缩写形式MFfMx等同于mfdx,并且fFx与相同.UfbZx。例如,假设我们将一个数字列表作为输入,输出每个数字递增。第一种方法可能是:

mhdQ

但是,可以将其重写为:

hMQ

类似的道理也适用于reduceF。例如,假设计算整数列表的乘积是一个挑战。同样,第一次尝试可能是:

.U*bZQ

但是,使用F,可以缩短为:

*FQ

刮掉三个字节...还不错!


而且您不需要Q,因为当函数缺少输入时就可以对其进行补充*F
Stan Strum

7

使您的Pyth实施保持最新。

我相当定期地改进Pyth,删除不太有用的功能并添加更多有用的功能,因此请留意新功能并定期更新实现的副本。

最近添加的一些功能:(截至10/19/14)

y:充当*2数字,并充当字符串和列表上所有子集的列表。例如:

pyth -c 'y"abc'
['', 'a', 'b', 'c', 'ab', 'ac', 'bc', 'abc']

ff通常是过滤器命令。现在,当以数字作为第二个参数调用时,它将过滤从该数字开始并以1递增的无限序列,然后返回结果序列的第一个元素。

例如,下面的代码查找超过十亿的最小素数:

pyth -c 'f!tPT^T9'
1000000007

这些看起来像是有用的补充,但是您可以用什么代替旧的yz呢?mvdczd不可能是最短的方法...
丹尼斯2014年

1
@Dennis我淘汰了旧版本,y因为我认为Pyth不需要具有多种超级容易解析的输入格式,例如Python格式。因此,是的,很mvdczd不幸,我认为必须这样做。
isaacg 2014年

@Dennis问题已解决,只需将其添加到r的字符串处理套件中即可。
isaacg 2014年

r看起来非常有用。
丹尼斯

@isaacg对不起,如果这是题外话,但我想知道如何使用@Fdr1 + 1 @ Q2Iq%Qd0d中的根运算来制作因子计算器。当我尝试使用它时,它默认为index含义。有什么办法可以解决此问题?
StardustGogeta

5

函数中的命名参数(不再受支持)

有时,函数中的默认值可能对高尔夫有用。Pyth实际上支持这一点(令我惊讶的是)。例如:

DC=Z1RZ;C;C5

将打印:

1
5

执行此操作时,还可以使用J和K保存字符:

DgJ1K1R+JKg;g2;g2 3

印刷品:

2
3
5

这通常对递归算法很有用。

这不再起作用,但是如果有人想使用旧版本的Pyth打高尔夫球,我就把它留在了这里。


16
哇-甚至我都没有意识到Pyth支持这一点,所以我写了这种语言!
isaacg 2015年

不幸的是,这在Pyth的最新版本中不再起作用。
2015年

是否应该像其他过时的技巧之一一样删除该技巧?如果不是,也许应该用本技巧适用的版本进行标记。
mbomb007

@ mbomb007我一直想找到该版本,但是我太懒了。如果您认为这样更好,请删除它,直到我找到为止。
FryAmTheEggman 2015年

@FryAmTheEggman我认为这取决于您,因为它在标题中说它不受支持。
mbomb007

5

用2个元素元组解包 F

假设您有2个元素元组,J = (a, b)并且想要r(a,b)2个arity函数r。

天真的方法是rhJeJ

完成此r.*J操作的理想方法是使用unpack运算符。

rFJ进行折叠的真正理想方法是使用fold运算符。


仍然可以使用.u吗?.u现在似乎是累计减少。
2016年

.u->。*这是前一段时间所做的更改,但从未进行过更新。
isaacg '16

4

使用简短的算术函数

h:除了返回列表的第一个元素外,它还会增加一个数字,例如hT计算为11。比短+1T

t:这会减少一个数字(不返回列表的末尾),例如,tT求值为9。比短-T1

y:此数字加倍,例如,yT计算为20,比*T2或短+TT


4

使用map生成列表

它基本上等效于python的花式列表理解。使用现有列表或范围来迭代并映射每个值,即使该值无关紧要。

两个例子:

  • 生成8个零的列表。

    mZ8 代替 *8]Z

  • 生成一个0到9之间的5个随机数的列表:

    mOT5 代替 V5~Y]OT)

    第二个自动将列表分配给该列表Y(实际上是将列表附加到Y上),但更=YmOTU5短。


4

EOF的隐式Q

截至今天,这是一个新变化。

Q是自动初始化为评估输入的变量。它被隐式地附加到Pyth程序的末尾,所需的次数使该arity得以解决。要查看如何将其用于打高尔夫球的示例,假设我们要计算输入的Collat​​z函数

编写它的最短方法是这样的:

@,/Q2h*3QQ

但是,由于Qs在文件末尾是隐式的,因此我们可以简单地编写:

@,/Q2h*3

节省2个字节。

请注意,带有非必需参数的函数将不会填充这些参数。例如,c"12 12"不会具有隐式Q,因为c仅需要1个参数。


3

使用reduce重复应用功能。

假设您需要将变量设置为其自身的某些功能,并重复一定次数。以在输入中后来在Collat​​z序列中找到数字100的问题为例。如果初始编号为Q,则查找序列中下一个编号的最短方法是

@,/Q2h*Q3Q

应用此方法100次并打印结果的最明显方法是

V100=Q@,/Q2h*Q3Q;Q

循环100次,每次更新Q的值,然后结束循环并打印Q。

相反,我们可以使用reduce函数,该函数忽略序列变量(H)。

u@,/G2h*G3GU100Q

这要短2个字符。如果您尝试循环的次数与序列中的元素数相同,则该字符要短3个字符。


3

通常有比Any更短的选择

当您要查找某个序列是否满足条件时,通常可以使用.Em。例如,如果要确定列表中是否有大于或等于5的数字:

.Emgd5Q

但是,如果只需要为真/假,sm而不是真/假,则将起作用,因为sum适用于布尔值。

smgd5Q

我们甚至可以做一个简短f一点:

fgT5Q

最后一个看起来真的很丑。

对于.All,我唯一能想到的就是使用相反的条件并将其取反,得到一个char并保存下来.Am

!f<T5Q

3

查看所有控制流选项

循环:

F:用于循环。就像Python一样。

V:用于循环范围。既不给出变量也不给出范围,因此要短2个字符。

W:While循环。就像Python一样。

#:无限while循环。出现错误或明显中断而逃脱。现在try ... except在Pyth中起作用。

职能:

D:一般定义。就像Python。

L:1个参数,没有赋值函数,类似于Python的lambda,但已命名。函数名称,变量名称和return(R)无需给出,因此要短3个字符。

功能编程:

f:过滤器-选择输入序列的元素,这些元素在输入lambda上返回真实值。

f:大于或等于输入的第一个整数,给出真实的过滤结果。

m:Map-使用输入lambda变换输入序列的元素。

u:减少-折叠输入lambda的输入序列,将累加器初始化为第三个参数。

o:顺序-使用输入lambda作为键的输入序列的旧元素。

通常,对于任何给定的问题,都会有多种可能性,只有通过编写每个解决方案,您才能找出最短的解决方案。


.x最近可以用于try-except块。
mbomb007

@ mbomb007除了块可以忽略,我的意思是可以留空吗?例如:.x{some_statments}{except_block - can this be empty}
Gurupad Mamadapur

@GurupadMamadapur # ... B可以,如果你在表达式中不是这样使用
isaacg

3

切换列表中的两个元素

切换两个元素可能是一项非常昂贵的任务。因此,这是您要使用的两种方法。

Tmp变量方法

在准备过程中,我们定义一个列表Y并用一些数字填充它。目标是切换第二个和第三个元素。

=Y[1 3 5 3 6 7)AGH,1 2

我们只需分配tmp变量J = Q[G],执行第一个列表分配Y[G] = Y[H],然后执行第二个最后一个分配Y[H] = J。这里的技巧是嵌套两个列表分配,因此您不必取消打印,也不必使用两次引用Y

J@YGXXYG@YHHJ

代替

J@YG XYG@YHXYHJ

翻译方法

如果要切换的元素在列表中是唯一的,请使用此方法。真的很短 因此,这次我们切换第一个和第三个元素(值15是唯一的)。

=Y[1 3 5 3 6 7)K,Z2

这将使用列表的翻译功能:

XYm@YdK)

这个翻译代替每个元素Y[0]Y[1]和每一个Y[1]Y[0]。因此,如果值不是唯一的,则会发生坏事。例如K,1 2导致[1, 5, 3, 5, 6, 7]

请注意,如果语句是代码中的最后一条,则右括号是可选的。


3

用调试 <newline>

如果您的代码以命令式编程风格编写,则调试起来非常容易,因为您可以轻松打印中间结果。(永久链接

FN.:Q2                loop
      =Y+-Y-FNhN      some random command
                Y     print intermediate result
                 ;Y   end for loop and print result

但是,大量的Pyth程序使用功能性编程的元素,例如map,filter和reduce,因此无法进行如此简单的打印。但是仍然可以使用\n命令。

使用u(reduce)的相同代码将是:(permalink

u        .:Q2Y   reduce .:Q2, start with G = Y
 +-G-FHhH        random command

如果要打印中间值,只需插入\n:(permalink

u         .:Q2Y   reduce
   \nG             print(G)
 +-\nG-FHhH        random command

\naa在换行符上打印并返回a。因此,您可以将其插入任何地方,而不必担心更改程序的功能。


现在,您可以为此使用换行符,它还会打印换行符。
PurkkaKoodari

@ Pietu1998是的,我一直都在使用它。是时候更新帖子了。
贾库贝

3

查找两个整数中的最大值

g#

例如,假设您有J=5K=12。然后g#JK= 12,也g#KJ= 12。

这是由@ Pietu1998发现的,他这样说:

不知道是否有人已经找到它,但是有一种很酷的方法可以在2个字节中执行max(A,B),而无需将3用于eS,ABg#AB做同样的事情。(但是,由于它最多循环max(1,A-B + 1)次,因此效率非常低。一种优化是将数字可能更大,例如B。)


@Jakube这是真的。在聊天中输入内容时,我显然遗忘了某些内容。
PurkkaKoodari

2

珀斯join

joinPython中的方法通常有点烦人,因为它只连接字符串。Pyth的join比较大方。默认情况下,它将转换字符串中的所有对象。

例如,jkUT给予0123456789jb["abc"4,5\f]7给予

abc
4
(5, 'f')
[7]

最近,添加了更多的转换为字符串的功能-第一个参数也被强制转换为字符串,例如j2\a\b->"a2b"
isaacg

1

判断数字是否为整数

一个巧妙的技巧是使用Invariant来判断数字是否为整数:

sI

这会检查数字在截断时是否没有改变,如果是整数则不会改变。

例如,您可以将其用作完美的方形检查:

sI@Q2

1

使用包装的腐霉

打包的Pyth是一种新的“编程语言”,它与Pyth完全相同,只是它使用每个字符7位而不是每个字符8位。

要使用它,请克隆pyth存储库。该文件packed-pyth.py是解释器。

假设您的代码是"Hello, world!

首先,将其放在文件中: echo -n '"Hello, world!' > code.pyth

接下来,将Pyth代码打包到Packed Pyth文件中: python3 packed-pyth.py -p code.pyth code.ppyth

最后,运行Packed Pyth代码: python3 packed-pyth.py code.ppyth

运行代码时,可以提供-d标志以查看实际正在运行的Pyth代码是什么,并且可以在包含该代码的文件之后提供输入作为第二个命令行参数。

上行空间:

  • 代码短1/8。

缺点:

  • 仅ASCII。

  • 没有互动输入。

  • 完整的调试选项不可用。

  • 更差的错误报告。


1
就像我们为安全模式所做的一样,我们可以将其移动到标志中吗?
Maltysen '16

顺便说一句:D
Maltysen '16

@Maltysen我认为这将使字节分数增加一。
isaacg '16

Pyth仅使用可打印的ASCII,因此不能进一步打包吗?
lirtosiast

1

使用I和GCD进行除数测试

免责声明:适用于非负整数。

要检查两个非负整数是否可被整除,可以执行以下操作:

iI<divisor><dividend>

如果一个是整除b一个≥b≥0 ,则gcd上述(A,B)= B

它不一定会节省字节数!%<dividend><divisor>,但可能会为您节省空间,因为:

  • 使用除数时,您也许可以在Pyth程序结束时调整隐式内容(例如drop Q)。
  • 您可以将其用作<pfn>,因为它本身就是一个函数。
  • 它通过处理模0

试试吧!


另一个优势:iI是一个函数,而!%不是,所以可以将其用作前缀函数。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer谢谢,添加到优点列表中了:)
Xcoder先生17年

0

将变量分配给应用于自身的函数

如果您具有arity 1的功能,并且想要将其应用于变量并应用于自身,则可以使用以下语法:

=<function><variable>

代替:

=<variable><function><variable>

例如,如果要增加变量Z,可以执行以下操作:

=hZ

这样可以节省一个字节=ZhZ

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.