Dicas para jogar golfe em Pyth


46

Pyth é uma linguagem de programação procedural inspirada em Python, criada pelo usuário do PPCG isaacg .

Que dicas gerais você tem para jogar golfe em Pyth? Estou procurando idéias que possam ser aplicadas para codificar problemas de golfe em geral que sejam pelo menos um pouco específicos para Pyth.

Uma dica por resposta, por favor.

Respostas:


25

Escreva o código em Python primeiro

Pyth é tão semelhante ao Python que é muito fácil traduzir programas Python para Pyth. No entanto, como Pyth é uma linguagem de letra única por comando, às vezes é difícil escrever Pyth direto. Ao escrever primeiro no Python, há menos coisas a se pensar de cada vez (já que o Python é uma linguagem muito fácil de codificar).


1
Você também pode mencionar que ainda pode usar a sintaxe do Python no Pyth, para converter partes do programa individualmente ou apenas usar o python, se necessário. (Como você fez aqui )
FryAmTheEggman

@ mbomb007 Faça o download do interpretador Pyth e leia os documentos. Essa é a única maneira confiável que eu conheço para escrever um programa Pyth.
24715 Justin

@ mbomb007 Desculpe; foi assim que aprendi a escrever Pyth (olhando o código-fonte). Basicamente, não há documentação sobre Pyth; você basicamente precisa aprender a sintaxe por tentativa e erro.
24715 Justin

22

Conheça suas variáveis

Pyth possui 3 categorias de variáveis: variáveis ​​pré-inicializadas genéricas, variáveis ​​pré-inicializadas com base na entrada do usuário e variáveis ​​que geram implicitamente uma atribuição no primeiro uso.

Variáveis ​​genéricas:

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

Variáveis ​​inicializadas por entrada:

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

Observe que essas inicializações serão executadas apenas em um determinado programa se a variável associada for usada fora de uma sequência no código. Além disso, a ordem é Q, então z, se os dois forem usados.

Atribuição nas variáveis ​​de primeiro uso:

Je K. Se você deseja inicializar os dois com o mesmo valor, pode fazê-lo com uma expressão como KJ0, que é equivalente à mais longa J0K0.


18

Use o intérprete online ainda mais recente para testar suas respostas.

Observe que este é um novo software, portanto pode ser um bug. Por favor, relate quaisquer problemas para mim.


2
Impressionante! Não consegui encontrar isso no google, exatamente o que eu precisava!
theonlygusti

12

As strings no final da linha não precisam de aspas finais. Por exemplo:

"Hello, world!

é um programa Hello World completamente válido.


Muito óbvio, na verdade, é o primeiro resultado do Google para "Pyth programming language". Você criou sua própria página no esolangs?
Theellygusti

3
@theonlygusti Sim, eu fiz. Além disso, não foi o primeiro resultado em outubro passado.
Isaacg

9

Use Cpara compactação básica

Na verdade, isso não é documentado, C em uma string não é realmente chr -> int, mas sim base 256 -> base 10 (que é a mesma em uma string). Isso é extremamente útil na compactação de um int. Podemos usar este script para compactar:

sCMjQ256

Tome 12345678910, resulta em ßÜ>(alguns imprimíveis lá).

Também com uma matriz de entradas, você pode concatená-las e com seqüências grandes convertendo em pontos de código e tratando como número 128 base.

Outro uso de C, obrigado @xnor por me mostrar isso, está criando um número grande e arbitrário. A maneira ingênua é:

^TT

Mas podemos fazer um byte melhor com:

CG

essa base 256 desconverte o alfabeto inteiro. Resultados 156490583352162063278528710879425690470022892627113539022649722= ~ 1.56e62.


Adicionado ao documento agora.
Isaacg


8

Use as funções funcionais curtas ... err ...

Quando o argumento lambda mapou reduceapenas aplica uma operação aos argumentos, você pode usar os formulários abreviados, Me F. fMxé equivalente a mfdxe fFxé a mesma coisa que .UfbZx. Por exemplo, digamos que tomemos uma lista de números como entrada e saída cada um incrementado. Uma primeira abordagem pode ser:

mhdQ

No entanto, isso pode ser reescrito como:

hMQ

Uma coisa semelhante se aplica a reducecom F. Como exemplo, digamos que haja um desafio para calcular o produto de uma lista de números inteiros. Novamente, uma primeira tentativa pode ser:

.U*bZQ

No entanto, com F, isso pode ser reduzido para:

*FQ

Raspa três bytes ... nada mal!


E você não precisa Q, como é complementado quando a função está faltando uma entrada, tornando-se*F
Stan Strum

7

Mantenha sua implementação do Pyth atualizada.

Estou melhorando regularmente o Pyth, removendo recursos menos úteis e adicionando outros mais úteis. Fique de olho nas novidades e atualize sua cópia da implementação regularmente.

Alguns recursos adicionados recentemente: (a partir de 19/10/14)

y: Atua como *2em números e como lista de todos os subconjuntos em cadeias e listas. Por exemplo:

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

f: fnormalmente é o comando de filtro. Agora, quando chamado com um número como seu segundo argumento, ele filtrará a sequência infinita começando com esse número e contando um por um e, em seguida, retornará o primeiro elemento da sequência resultante.

Por exemplo, aqui está o código para encontrar o menor primo de mais de um bilhão:

pyth -c 'f!tPT^T9'
1000000007

Elas parecem adições úteis, mas o que você pode usar em vez das antigas yz? mvdczdnão pode ser o caminho mais curto ...
Dennis

1
@ Dennis yJoguei fora o antigo porque não acho que o Pyth precise ter vários formatos de entrada analisados ​​com facilidade, apenas um, por exemplo, o formato Python. Então, sim, acho mvdczdque terá que fazer, infelizmente.
Isaacg #

@Dennis Problema resolvido, apenas o adicionei ao rconjunto de processamento de strings.
Isaacg #

rparece bastante útil.
Dennis

@isaacg Desculpe se isso não é tópico, mas estou pensando em como usar a operação raiz @em Fdr1 + 1 @ Q2Iq% Qd0d para criar uma calculadora de fatores. Quando tento usá-lo, o padrão é o indexsignificado. Existe alguma maneira de contornar esse comportamento?
StardustGogeta

5

Argumentos nomeados em funções (não são mais suportados)

Às vezes, valores padrão em funções podem ser úteis para jogar golfe. Pyth realmente suporta isso (para minha surpresa). Por exemplo:

DC=Z1RZ;C;C5

Irá imprimir:

1
5

Você também pode usar J e K para salvar caracteres ao fazer isso:

DgJ1K1R+JKg;g2;g2 3

impressões:

2
3
5

Isso geralmente é útil para algoritmos recursivos.

Isso não funciona mais, mas deixei aqui caso alguém queira jogar golfe usando uma versão antiga do Pyth.


16
Uau - Até eu não sabia que Pyth apoiava isso, e escrevi o idioma!
Isaacg

Infelizmente, isso não funciona mais nas versões mais recentes do Pyth.
Isaacg #

Essa dica deve ser excluída como uma das outras dicas desatualizadas? Caso contrário, talvez deva ser marcado com quais versões essa dica se aplica.
Mbomb007

@ mbomb007 Estive querendo encontrar a versão, mas tenho preguiça. Vou excluí-lo se achar melhor assim até que eu o encontre.
FryAmTheEggman

@FryAmTheEggman Acho que depende de você, já que diz no título que não é suportado.
mbomb007

5

Descompactar tuplas de 2 elementos com F

Digamos que você tenha uma tupla de 2 elementos J = (a, b), e deseje r(a,b), para alguma função de 2 áreas r.

A maneira ingênua de fazer isso é rhJeJ.

A maneira mais sofisticada de fazer isso é r.*Jusando o operador desempacotar.

A maneira mais sofisticada de fazer isso é rFJusando o operador fold.


ainda é possível usar .upara isso? .uparece ser cumulativo reduzir agora.
Ven

.u ->. * essa alteração foi feita há um tempo, mas nunca foi atualizada.
Isaacg

4

Use as funções aritméticas curtas

h: Além de retornar o primeiro elemento de uma lista, ele incrementa um número, por exemplo, hTavalia como 11. Mais curto que +1T.

t: Isso diminui um número (exceto o retorno da cauda de uma lista), por exemplo, tTavalia como 9. Mais curto que -T1.

y: Isso dobra um número, por exemplo, yTavalia para 20, menor que *T2ou +TT.


4

Use mappara gerar listas

É basicamente o equivalente à compreensão sofisticada de listas de python. Use uma lista ou um intervalo existente para iterar e mapear cada valor, mesmo que o valor não importe.

Dois exemplos:

  • Gere uma lista de 8 zeros.

    mZ8 ao invés de *8]Z

  • Gere uma lista de 5 números aleatórios entre 0 e 9:

    mOT5 ao invés de V5~Y]OT)

    O segundo atribui automaticamente a lista Y(bem, na verdade, anexa a Y), mas ainda =YmOTU5é mais curto.


4

Q implícito na EOF

Esta é uma nova mudança, a partir de hoje.

Qé a variável que é inicializada automaticamente na entrada avaliada. É implicitamente anexado ao final do programa Pyth, quantas vezes for necessário para que a aridade funcione. Para ver um exemplo de como usar isso no golfe, digamos que queremos calcular a função Collatz da entrada.

A maneira mais curta de escrever é assim:

@,/Q2h*3QQ

No entanto, como os Qs estão implícitos no final do arquivo, podemos simplesmente escrever:

@,/Q2h*3

Salvando 2 bytes.

Observe que funções com argumentos não obrigatórios não terão esses argumentos preenchidos. Por exemplo, c"12 12"não terão implícito Q, pois crequer apenas 1 argumento.


3

Use reduzir para aplicar uma função repetidamente.

Suponha que você precise definir uma variável para alguma função em si e repita um certo número de vezes. Pegue, por exemplo, o problema de encontrar o número 100 posteriormente na Sequência Collatz a partir da entrada. A maneira mais curta de encontrar o próximo número na sequência, se o número inicial for Q, é

@,/Q2h*Q3Q

A maneira mais óbvia de aplicar isso 100 vezes e imprimir o resultado seria

V100=Q@,/Q2h*Q3Q;Q

Faça um loop 100 vezes, atualizando o valor de Q toda vez, depois termine o loop e imprima Q.

Em vez disso, podemos usar uma função de redução que ignora a variável de sequência ( H).

u@,/G2h*G3GU100Q

Este é 2 caracteres mais curtos. São 3 caracteres mais curtos se você estiver tentando fazer um loop quantas vezes houver elementos em uma sequência.


3

Geralmente existem alternativas mais curtas para Qualquer

Quando você deseja descobrir se alguma sequência satisfaz uma condição, você usaria normalmente .Em. Por exemplo, se você deseja descobrir se algum em uma lista é maior que ou igual a 5:

.Emgd5Q

Mas, se ele precisa ser apenas uma verdade / falsey, não verdadeiro / falso, smfuncionaria, já que soma funciona em bools.

smgd5Q

Podemos até fazer um menor, com o ffiltro:

fgT5Q

O último parece realmente feio.

Para .All, a única coisa em que consigo pensar é usar a condição oposta e negá-la para uma economia de um caractere .Am:

!f<T5Q

3

Veja todas as opções de fluxo de controle

Rotações:

F: Para loop. Assim como o Python.

V: Para loop acima de um intervalo. Nem a variável nem o intervalo devem ser fornecidos, portanto, 2 caracteres mais curtos.

W: Enquanto loop. Assim como o Python.

#: Loop infinito enquanto. Escape com erro ou quebra explícita. Recurso exclusivo try ... exceptagora em Pyth.

Funções:

D: Definição geral. Assim como Python.

L: 1 argumento, sem função de atribuição, como o lambda do Python, mas nomeado. O nome da função, o nome da variável e return ( R) não precisam ser fornecidos, portanto, são 3 caracteres mais curtos.

Programação funcional:

f: Filtro - selecione elementos da sequência de entrada que retornam verdade na entrada lambda.

f: Primeiro número inteiro maior ou igual à entrada que fornece o resultado verdadeiro do filtro.

m: Mapa - transforme elementos da sequência de entrada usando a entrada lambda.

u: Reduza a seqüência de entrada dobrada na entrada lambda, inicializando o acumulador para o terceiro argumento.

o: Order - elementos mais antigos da sequência de entrada usando a entrada lambda como chave.

Normalmente, haverá várias possibilidades para qualquer problema, e somente escrevendo soluções de teste com cada uma delas é possível descobrir qual é o mais curto.


.xpode ser usado mais recentemente para blocos try-except.
Mbomb007

@ mbomb007 existe maneira de negligenciar, exceto o bloco, quero dizer, isso pode ser deixado em branco? Por ex: .x{some_statments}{except_block - can this be empty}.
Gurupad Mamadapur

@GurupadMamadapur # ... Bpode ser usado desta forma, se você não está dentro de uma expressão
isaacg

3

Alternando dois elementos em uma lista

Mudar dois elementos pode ser uma tarefa bastante cara. Então, aqui estão duas abordagens que você deseja usar.

Abordagem TMP-variável

Na preparação, definimos uma lista Ye a preenchemos com alguns números. O objetivo é mudar o segundo e o terceiro elemento.

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

Simplesmente atribuímos a variável tmp J = Q[G], fazemos a primeira atribuição da lista Y[G] = Y[H]e, em seguida, a segunda última atribuição Y[H] = J. O truque aqui é aninhar as duas atribuições da lista, para que você não precise suprimir a impressão e não precise usar a referência duas vezes Y.

J@YGXXYG@YHHJ

ao invés de

J@YG XYG@YHXYHJ

Abordagem de tradução

Se os elementos que você deseja alternar forem exclusivos na lista, use esta abordagem. É muito curto. Portanto, desta vez, alternamos o primeiro e o terceiro elemento (os valores 1e 5são únicos).

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

Isso usa a funcionalidade de tradução da lista:

XYm@YdK)

Essa tradução substitui todos os elementos Y[0]por Y[1]e todos Y[1]com Y[0]. Portanto, se os valores não são únicos, coisas ruins acontecem. Por exemplo, K,1 2resulta em [1, 5, 3, 5, 6, 7].

Observe que os parênteses de fechamento são opcionais, se a instrução for a última no seu código.


3

Depurando com <newline>

Se seu código for escrito em um estilo de programação imperativo, é muito fácil depurar, pois você pode imprimir facilmente resultados intermediários. ( link permanente )

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

Mas uma grande quantidade de programas Pyth usa elementos de programação funcional, como mapear, filtrar e reduzir, o que não permite uma impressão tão simples. Mas ainda é possível, usando o \ncomando

O mesmo código usando u(reduzir) seria: ( link permanente )

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

Se você deseja imprimir os valores intermediários, basta inserir \n: ( link permanente )

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

\naimprime aem uma nova linha e retorna a. Assim, você pode inseri-lo em qualquer lugar sem se preocupar em alterar a funcionalidade do programa.


Atualmente, você pode usar a nova linha para isso, que também imprime uma nova linha.
precisa saber é o seguinte

@ Pietu1998 Sim, eu uso o tempo todo. Hora de atualizar a postagem.
Jakube

3

Encontrando o máximo de dois números inteiros

g#

Por exemplo, suponha que você tenha J=5e K=12. Então g#JK= 12 e g#KJ= 12 também.

Isso foi descoberto por @ Pietu1998, que colocou desta maneira:

Não tenho certeza se alguém já o encontrou, mas há uma maneira legal de fazer o máximo (A, B) em 2 bytes, sem a necessidade de usar 3 para eS,AB. g#ABfaz a mesma coisa. (É muito ineficiente, no entanto, uma vez que executa um loop no máximo (1, A-B + 1) vezes. Uma otimização é colocar o número que provavelmente será maior como B.)


@Jakube Isso é verdade. Eu aparentemente misthough algo enquanto digito isso no chat.
PurkkaKoodari 4/16

2

De Pyth joinmétodo

O joinmétodo em Python geralmente pode ser um pouco chato, pois une apenas as strings. Pyth's joiné mais generoso. Ele transforma todos os objetos em seqüências de caracteres por padrão.

Por exemplo, jkUT0123456789ou jb["abc"4,5\f]7

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

Recentemente, foi adicionado ainda mais funcionalidade transformando-a-string - o primeiro argumento é coagido a uma corda, bem como, por exemplo, j2\a\b->"a2b"
isaacg

1

Dizer se um número é um número inteiro

Um truque interessante é usar Invariant para dizer se um número é um número inteiro, como tal:

sI

Isso verifica se o número não muda quando você o trunca, o que não acontece se for um número inteiro.

Por exemplo, você pode usar isso como uma verificação quadrada perfeita:

sI@Q2

1

Usar Pyth embalado

O Pyth empacotado é uma nova "linguagem de programação" que é exatamente a mesma do Pyth, exceto que ele usa 7 bits por caractere em vez de 8 bits por caractere.

Para usá-lo, clone o repositório pyth . O arquivo packed-pyth.pyé o intérprete.

Diga que seu código é "Hello, world!.

Primeiro, coloque-o em um arquivo: echo -n '"Hello, world!' > code.pyth

Em seguida, empacote o código Pyth no arquivo Packed Pyth: python3 packed-pyth.py -p code.pyth code.ppyth

Por fim, execute o código do Packed Pyth: python3 packed-pyth.py code.ppyth

Ao executar o código, você pode fornecer o -dsinalizador para ver qual é o código Pyth que está sendo executado e fornecer uma entrada como um segundo argumento de linha de comando após o arquivo que contém o código.

Parte de cima:

  • O código é mais curto em 1/8.

Desvantagem:

  • Somente ASCII.

  • Nenhuma entrada interativa.

  • Opções de depuração completas não estão disponíveis.

  • Pior relatório de erros.


1
como fizemos no modo de segurança, podemos movê-lo para uma bandeira?
Maltysen # 6/16

Isso é incrível entre: D
Maltysen

@ Maltysen Eu acho que aumentaria a pontuação de bytes em um.
Isaacg #

O Pyth não pode ser embalado ainda mais, pois ele usa apenas ASCII imprimível?
lirtosiast

1

Teste de divisibilidade usando Ie GCD

Isenção de responsabilidade: isso funciona apenas para números inteiros não negativos.

Para verificar se dois números inteiros não negativos são divisíveis, você pode fazer o seguinte:

iI<divisor><dividend>

Se a é divisível por b e a ≥ b ≥ 0 , então mcd (a, b) = b .

Ele não salva necessariamente bytes !%<dividend><divisor>, mas pode trazer uma economia, porque:

  • Você pode ajustar as coisas implícitas no final de um programa Pyth (como desistir Q), ao trabalhar com o dividendo.
  • Você pode usá-lo como um <pfn>, uma vez que é uma função por si só.
  • Ele lida com o módulo por 0.

Tente!


Mais uma vantagem: iIé uma função por si só, enquanto !%não é, então você pode usá-la como uma função de prefixo.
Erik the Outgolfer

@EriktheOutgolfer Obrigado, adicionado à lista de vantagens :)
Mr. Xcoder

0

Atribuindo uma variável a uma função aplicada a si mesma

Se você tem uma função da arity 1 e deseja aplicá-la a uma variável e aplicar a si mesma, pode usar a seguinte sintaxe:

=<function><variable>

Ao invés de:

=<variable><function><variable>

Por exemplo, se você deseja incrementar a variável Z, pode:

=hZ

O que economiza um byte =ZhZ.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.